@cleocode/cleo 2026.9.24 → 2026.9.26

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.
Files changed (57) hide show
  1. package/dist/cli/index.js +563 -253
  2. package/package.json +13 -13
  3. package/studio-dist/client/_app/immutable/chunks/{CqxUYDwj.js → B2oT_qgu.js} +1 -1
  4. package/studio-dist/client/_app/immutable/chunks/B7RPHy-R.js +1 -0
  5. package/studio-dist/client/_app/immutable/chunks/{iXXfYtUd.js → BhOwHRY9.js} +1 -1
  6. package/studio-dist/client/_app/immutable/chunks/{BeSHW-PI.js → CobI0XAU.js} +1 -1
  7. package/studio-dist/client/_app/immutable/entry/{app.D0MhB1gq.js → app.DaDdqQTe.js} +2 -2
  8. package/studio-dist/client/_app/immutable/entry/start.BjuNqpl1.js +1 -0
  9. package/studio-dist/client/_app/immutable/nodes/{0.CPm_3d_8.js → 0.CKHiZeuP.js} +1 -1
  10. package/studio-dist/client/_app/immutable/nodes/{1.kD8K_ebT.js → 1.CmaYPYrk.js} +1 -1
  11. package/studio-dist/client/_app/immutable/nodes/{15.WEaAYVEy.js → 15.D23qtyoz.js} +1 -1
  12. package/studio-dist/client/_app/immutable/nodes/{16.SxplBCYx.js → 16.Dtt6exbd.js} +1 -1
  13. package/studio-dist/client/_app/immutable/nodes/{17.HawOwgFr.js → 17.CPZ22rBo.js} +1 -1
  14. package/studio-dist/client/_app/immutable/nodes/{18.CU1uc6aV.js → 18.Qm_fekS5.js} +1 -1
  15. package/studio-dist/client/_app/immutable/nodes/{20.Dj3In1mD.js → 20.DjGgB4KD.js} +1 -1
  16. package/studio-dist/client/_app/immutable/nodes/{24.BABzil92.js → 24.CgMoobl_.js} +1 -1
  17. package/studio-dist/client/_app/immutable/nodes/{25.K9V1t9FS.js → 25.DkFAoI4l.js} +2 -2
  18. package/studio-dist/client/_app/immutable/nodes/{26.Ber4zDmK.js → 26.C1oRqB1b.js} +1 -1
  19. package/studio-dist/client/_app/immutable/nodes/{3.CDH1-JKn.js → 3.Cy4T6zbv.js} +1 -1
  20. package/studio-dist/client/_app/version.json +1 -1
  21. package/studio-dist/server/chunks/{0-CzucydBz.js → 0-G8NhADpo.js} +3 -3
  22. package/studio-dist/server/chunks/1-CfXNxnLm.js +9 -0
  23. package/studio-dist/server/chunks/{15-B36yiClS.js → 15-o63WM4MZ.js} +3 -3
  24. package/studio-dist/server/chunks/{16-TEN2Xs7g.js → 16-7h8G4VoG.js} +3 -3
  25. package/studio-dist/server/chunks/{17-CDqPwV0A.js → 17-DcShICKv.js} +3 -3
  26. package/studio-dist/server/chunks/{18-C9SojWQi.js → 18-BER3ZYEh.js} +3 -3
  27. package/studio-dist/server/chunks/{20-D2rDiJCy.js → 20-DErTM2qU.js} +3 -3
  28. package/studio-dist/server/chunks/{24-DFin4XEU.js → 24-BZh7ZC1u.js} +3 -3
  29. package/studio-dist/server/chunks/{25-byalahiX.js → 25-qqsEYb5C.js} +4 -4
  30. package/studio-dist/server/chunks/{26-BctSc53D.js → 26-C424QBHc.js} +3 -3
  31. package/studio-dist/server/chunks/{3-u3g5-V70.js → 3-DDisSHuV.js} +3 -3
  32. package/studio-dist/server/chunks/{_layout.svelte-BkWa8zMq.js → _layout.svelte-DcfphVWO.js} +4 -4
  33. package/studio-dist/server/chunks/{_page.svelte-DdieDDqt.js → _page.svelte-B4hg1b3p.js} +4 -4
  34. package/studio-dist/server/chunks/{_page.svelte-CEoJA3np.js → _page.svelte-BjX_VPfv.js} +3 -3
  35. package/studio-dist/server/chunks/{_page.svelte-DdRs2eQU.js → _page.svelte-C8Ybsn2v.js} +3 -3
  36. package/studio-dist/server/chunks/{_page.svelte-ClYQv-J6.js → _page.svelte-CPdHIklX.js} +5 -5
  37. package/studio-dist/server/chunks/{_page.svelte-SpNaTPY3.js → _page.svelte-CWNRWa2L.js} +3 -3
  38. package/studio-dist/server/chunks/{_page.svelte-D1ImKwNa.js → _page.svelte-DBbdqQsp.js} +3 -3
  39. package/studio-dist/server/chunks/{_page.svelte-Nf_2u2sG.js → _page.svelte-DdaHffLO.js} +3 -3
  40. package/studio-dist/server/chunks/{_page.svelte-D1GgG_0J.js → _page.svelte-DuD1vdhl.js} +3 -3
  41. package/studio-dist/server/chunks/{_page.svelte-Balyz5No.js → _page.svelte-EPu-M4nY.js} +3 -3
  42. package/studio-dist/server/chunks/{_server.ts-BF8dYynr.js → _server.ts-BGuhOntH.js} +3 -3
  43. package/studio-dist/server/chunks/{_server.ts-BFAKIrzM.js → _server.ts-BjIJy4O3.js} +2 -2
  44. package/studio-dist/server/chunks/{_server.ts-10Z9UtEP.js → _server.ts-C4WHkBZ_.js} +3 -3
  45. package/studio-dist/server/chunks/{_server.ts-BNaQ_u-J.js → _server.ts-CmiJfYD5.js} +3 -3
  46. package/studio-dist/server/chunks/{_server.ts-DrRXPeYo.js → _server.ts-wZKCwtFH.js} +3 -3
  47. package/studio-dist/server/chunks/{client-NfsjQdjU.js → client-ARinjJG0.js} +2 -2
  48. package/studio-dist/server/chunks/{dist-b2dqLZbk.js → dist-CLTFgJWk.js} +10 -1
  49. package/studio-dist/server/chunks/{error.svelte-xf-NkEuU.js → error.svelte-m5N9iUFN.js} +3 -3
  50. package/studio-dist/server/chunks/{http-C8NM9yzE.js → http-DKP1pqq1.js} +2 -2
  51. package/studio-dist/server/chunks/{internal-OCcHamz2.js → internal-BF6KxfEH.js} +2 -2
  52. package/studio-dist/server/chunks/{stores-Dyo9kN1m.js → stores-UvZbmzhQ.js} +2 -2
  53. package/studio-dist/server/index.js +1 -1
  54. package/studio-dist/server/manifest.js +17 -17
  55. package/studio-dist/client/_app/immutable/chunks/BmmibeAn.js +0 -1
  56. package/studio-dist/client/_app/immutable/entry/start.Z2uJ5V0K.js +0 -1
  57. package/studio-dist/server/chunks/1-BgfY0ktP.js +0 -9
package/dist/cli/index.js CHANGED
@@ -395,6 +395,16 @@ function resolveFieldContext(opts) {
395
395
  };
396
396
  return resolveFieldExtraction(input2);
397
397
  }
398
+ async function withoutOutputPointer(step) {
399
+ const saved = currentContext;
400
+ const { field: _field, ...rest } = saved;
401
+ currentContext = rest;
402
+ try {
403
+ return await step();
404
+ } finally {
405
+ currentContext = saved;
406
+ }
407
+ }
398
408
  var currentContext;
399
409
  var init_field_context = __esm({
400
410
  "packages/cleo/src/cli/field-context.ts"() {
@@ -4968,7 +4978,7 @@ var init_output_contracts_data = __esm({
4968
4978
  // T12503: the optimistic-concurrency version agents pass to --if-match.
4969
4979
  updatedAt: {
4970
4980
  type: ["string", "null"],
4971
- description: "Task version for optimistic concurrency: pass it to `cleo update|complete --if-match`."
4981
+ description: "Task version for optimistic concurrency: pass it to `cleo update|complete --if-match`. A stale version fails with E_CONFLICT (23); E_TASK_RENAMED (26) when sync re-numbered the task you read (details.expected is its new id)."
4972
4982
  },
4973
4983
  // T12502: the human assignee and the agent claim lease are separate.
4974
4984
  assignee: {
@@ -16454,6 +16464,7 @@ var init_exit_codes = __esm({
16454
16464
  ExitCode2[ExitCode2["VERSION_CONFLICT"] = 23] = "VERSION_CONFLICT";
16455
16465
  ExitCode2[ExitCode2["SESSION_UNBOUND"] = 24] = "SESSION_UNBOUND";
16456
16466
  ExitCode2[ExitCode2["WORKTREE_LOCKED"] = 25] = "WORKTREE_LOCKED";
16467
+ ExitCode2[ExitCode2["TASK_RENAMED"] = 26] = "TASK_RENAMED";
16457
16468
  ExitCode2[ExitCode2["SESSION_EXISTS"] = 30] = "SESSION_EXISTS";
16458
16469
  ExitCode2[ExitCode2["SESSION_NOT_FOUND"] = 31] = "SESSION_NOT_FOUND";
16459
16470
  ExitCode2[ExitCode2["SCOPE_CONFLICT"] = 32] = "SCOPE_CONFLICT";
@@ -22728,7 +22739,28 @@ var init_nexus_account = __esm({
22728
22739
  "E_NEXUS_REVOKE_FAILED",
22729
22740
  "E_NEXUS_REQUEST_FAILED",
22730
22741
  "E_NEXUS_NOT_A_PROJECT",
22731
- "E_NEXUS_INVALID_LABEL"
22742
+ "E_NEXUS_INVALID_LABEL",
22743
+ // Device credentials (cleo-nexus device contract §3.3, §4.0.4; T12868).
22744
+ /** No answer from the API (network error or timeout). */
22745
+ "E_NEXUS_UNREACHABLE",
22746
+ /** `cleo login nexus` while a revoke of this device is unconfirmed (§3.3, v2.9). */
22747
+ "E_NEXUS_REVOKE_PENDING",
22748
+ /** The device was signed out (E9, E11): 401 `device-signed-out`. */
22749
+ "E_NEXUS_DEVICE_SIGNED_OUT",
22750
+ /** The device was revoked (E10, E12): 401 `device-revoked`. */
22751
+ "E_NEXUS_DEVICE_REVOKED",
22752
+ /** A credential replaced or revoked elsewhere, or a `rotation-conflict` (R2). */
22753
+ "E_NEXUS_CREDENTIAL_COMPROMISED",
22754
+ /** The device credential lacks the scope (a read-only device): 403 `insufficient-scope`. */
22755
+ "E_NEXUS_INSUFFICIENT_SCOPE",
22756
+ /** A replica attach from a second device: 409 `replica-copied`. */
22757
+ "E_NEXUS_REPLICA_COPIED",
22758
+ /** Another cleo process holds the device file or an upgrade in flight; retry. */
22759
+ "E_NEXUS_BUSY",
22760
+ /** Several accounts hold a device credential on one origin and none was named. */
22761
+ "E_NEXUS_ACCOUNT_AMBIGUOUS",
22762
+ /** An option that needs device credentials (`--read-only`) without `CLEO_NEXUS_DEVICE=1`. */
22763
+ "E_NEXUS_DEVICE_REQUIRED"
22732
22764
  ];
22733
22765
  nexusAccountUserSchema = z25.object({
22734
22766
  id: z25.string(),
@@ -31247,29 +31279,25 @@ var init_memory2 = __esm({
31247
31279
  }
31248
31280
  bindArgs.push(limitVal);
31249
31281
  const whereClause = clauses.join(" AND ");
31250
- let rows = [];
31251
- try {
31252
- const rawRows = nativeDb.prepare(
31253
- `SELECT id, title, text, type, source_session_id, memory_tier, created_at
31254
- FROM brain_observations
31255
- WHERE ${whereClause}
31256
- ORDER BY created_at DESC
31257
- LIMIT ?`
31258
- ).all(...bindArgs);
31259
- rows = rawRows.map((raw) => {
31260
- const r = raw;
31261
- return {
31262
- id: String(r["id"] ?? ""),
31263
- title: r["title"] != null ? String(r["title"]) : null,
31264
- text: String(r["text"] ?? ""),
31265
- type: r["type"] != null ? String(r["type"]) : null,
31266
- source_session_id: r["source_session_id"] != null ? String(r["source_session_id"]) : null,
31267
- memory_tier: r["memory_tier"] != null ? String(r["memory_tier"]) : null,
31268
- created_at: String(r["created_at"] ?? "")
31269
- };
31270
- });
31271
- } catch {
31272
- }
31282
+ const rawRows = nativeDb.prepare(
31283
+ `SELECT id, title, narrative AS text, type, source_session_id, memory_tier, created_at
31284
+ FROM brain_observations
31285
+ WHERE ${whereClause}
31286
+ ORDER BY created_at DESC
31287
+ LIMIT ?`
31288
+ ).all(...bindArgs);
31289
+ const rows = rawRows.map((raw) => {
31290
+ const r = raw;
31291
+ return {
31292
+ id: String(r["id"] ?? ""),
31293
+ title: r["title"] != null ? String(r["title"]) : null,
31294
+ text: String(r["text"] ?? ""),
31295
+ type: r["type"] != null ? String(r["type"]) : null,
31296
+ source_session_id: r["source_session_id"] != null ? String(r["source_session_id"]) : null,
31297
+ memory_tier: r["memory_tier"] != null ? String(r["memory_tier"]) : null,
31298
+ created_at: String(r["created_at"] ?? "")
31299
+ };
31300
+ });
31273
31301
  return wrapResult(
31274
31302
  {
31275
31303
  success: true,
@@ -31305,29 +31333,25 @@ var init_memory2 = __esm({
31305
31333
  startTime
31306
31334
  );
31307
31335
  }
31308
- let rows = [];
31309
- try {
31310
- const rawRows = nativeDb.prepare(
31311
- `SELECT id, title, text, source_session_id, memory_tier, created_at
31312
- FROM brain_observations
31313
- WHERE type = 'diary'
31314
- AND invalid_at IS NULL
31315
- ORDER BY created_at DESC
31316
- LIMIT ?`
31317
- ).all(limitVal);
31318
- rows = rawRows.map((raw) => {
31319
- const r = raw;
31320
- return {
31321
- id: String(r["id"] ?? ""),
31322
- title: r["title"] != null ? String(r["title"]) : null,
31323
- text: String(r["text"] ?? ""),
31324
- source_session_id: r["source_session_id"] != null ? String(r["source_session_id"]) : null,
31325
- memory_tier: r["memory_tier"] != null ? String(r["memory_tier"]) : null,
31326
- created_at: String(r["created_at"] ?? "")
31327
- };
31328
- });
31329
- } catch {
31330
- }
31336
+ const rawRows = nativeDb.prepare(
31337
+ `SELECT id, title, narrative AS text, source_session_id, memory_tier, created_at
31338
+ FROM brain_observations
31339
+ WHERE type = 'diary'
31340
+ AND invalid_at IS NULL
31341
+ ORDER BY created_at DESC
31342
+ LIMIT ?`
31343
+ ).all(limitVal);
31344
+ const rows = rawRows.map((raw) => {
31345
+ const r = raw;
31346
+ return {
31347
+ id: String(r["id"] ?? ""),
31348
+ title: r["title"] != null ? String(r["title"]) : null,
31349
+ text: String(r["text"] ?? ""),
31350
+ source_session_id: r["source_session_id"] != null ? String(r["source_session_id"]) : null,
31351
+ memory_tier: r["memory_tier"] != null ? String(r["memory_tier"]) : null,
31352
+ created_at: String(r["created_at"] ?? "")
31353
+ };
31354
+ });
31331
31355
  return wrapResult(
31332
31356
  {
31333
31357
  success: true,
@@ -31373,28 +31397,24 @@ var init_memory2 = __esm({
31373
31397
  bindArgs.push(cursorParam);
31374
31398
  }
31375
31399
  bindArgs.push(limitVal);
31376
- let rows = [];
31377
- try {
31378
- const rawRows = nativeDb.prepare(
31379
- `SELECT id, title, text, type, memory_tier, created_at
31380
- FROM brain_observations
31381
- WHERE ${clauses.join(" AND ")}
31382
- ORDER BY created_at ASC
31383
- LIMIT ?`
31384
- ).all(...bindArgs);
31385
- rows = rawRows.map((raw) => {
31386
- const r = raw;
31387
- return {
31388
- id: String(r["id"] ?? ""),
31389
- title: r["title"] != null ? String(r["title"]) : null,
31390
- text: String(r["text"] ?? ""),
31391
- type: r["type"] != null ? String(r["type"]) : null,
31392
- memory_tier: r["memory_tier"] != null ? String(r["memory_tier"]) : null,
31393
- created_at: String(r["created_at"] ?? "")
31394
- };
31395
- });
31396
- } catch {
31397
- }
31400
+ const rawRows = nativeDb.prepare(
31401
+ `SELECT id, title, narrative AS text, type, memory_tier, created_at
31402
+ FROM brain_observations
31403
+ WHERE ${clauses.join(" AND ")}
31404
+ ORDER BY created_at ASC
31405
+ LIMIT ?`
31406
+ ).all(...bindArgs);
31407
+ const rows = rawRows.map((raw) => {
31408
+ const r = raw;
31409
+ return {
31410
+ id: String(r["id"] ?? ""),
31411
+ title: r["title"] != null ? String(r["title"]) : null,
31412
+ text: String(r["text"] ?? ""),
31413
+ type: r["type"] != null ? String(r["type"]) : null,
31414
+ memory_tier: r["memory_tier"] != null ? String(r["memory_tier"]) : null,
31415
+ created_at: String(r["created_at"] ?? "")
31416
+ };
31417
+ });
31398
31418
  const nextCursor = rows.length > 0 ? rows[rows.length - 1].created_at : cursorParam ?? null;
31399
31419
  return wrapResult(
31400
31420
  {
@@ -38009,8 +38029,8 @@ async function loadPlaybookByName(name) {
38009
38029
  return null;
38010
38030
  }
38011
38031
  try {
38012
- const { getProjectRoot: getProjectRoot73 } = await import("@cleocode/core/internal");
38013
- const projectRoot = __playbookRuntimeOverrides.projectRoot ?? getProjectRoot73();
38032
+ const { getProjectRoot: getProjectRoot75 } = await import("@cleocode/core/internal");
38033
+ const projectRoot = __playbookRuntimeOverrides.projectRoot ?? getProjectRoot75();
38014
38034
  const resolved = resolvePlaybook(name, {
38015
38035
  projectRoot,
38016
38036
  globalPlaybooksDir: __playbookRuntimeOverrides.globalPlaybooksDir,
@@ -38055,7 +38075,7 @@ async function buildDefaultDispatcher() {
38055
38075
  if (__playbookRuntimeOverrides.dispatcher) return __playbookRuntimeOverrides.dispatcher;
38056
38076
  const { orchestrateSpawnExecute: orchestrateSpawnExecute2 } = await import("@cleocode/runtime/gateway");
38057
38077
  const {
38058
- getProjectRoot: getProjectRoot73,
38078
+ getProjectRoot: getProjectRoot75,
38059
38079
  createToolGuard,
38060
38080
  runSkillNodeOrSpawn,
38061
38081
  maybeCreatePiRunner,
@@ -38063,7 +38083,7 @@ async function buildDefaultDispatcher() {
38063
38083
  hasCantbookProfilePin,
38064
38084
  DEFAULT_DETERMINISTIC_DENIED_COMMANDS
38065
38085
  } = await import("@cleocode/core/internal");
38066
- const projectRoot = getProjectRoot73();
38086
+ const projectRoot = getProjectRoot75();
38067
38087
  const tools = createToolGuard({
38068
38088
  allowedRoots: [projectRoot],
38069
38089
  deniedCommands: DEFAULT_DETERMINISTIC_DENIED_COMMANDS,
@@ -38156,12 +38176,12 @@ async function buildDefaultDeterministicRunner() {
38156
38176
  return void 0;
38157
38177
  }
38158
38178
  const {
38159
- getProjectRoot: getProjectRoot73,
38179
+ getProjectRoot: getProjectRoot75,
38160
38180
  createToolGuard,
38161
38181
  createGuardedDeterministicRunner,
38162
38182
  DEFAULT_DETERMINISTIC_DENIED_COMMANDS
38163
38183
  } = await import("@cleocode/core/internal");
38164
- const projectRoot = getProjectRoot73();
38184
+ const projectRoot = getProjectRoot75();
38165
38185
  const tools = createToolGuard({
38166
38186
  allowedRoots: [projectRoot],
38167
38187
  deniedCommands: DEFAULT_DETERMINISTIC_DENIED_COMMANDS,
@@ -38319,8 +38339,8 @@ var init_playbook2 = __esm({
38319
38339
  projectRoot = __playbookRuntimeOverrides.projectRoot;
38320
38340
  } else {
38321
38341
  try {
38322
- const { getProjectRoot: getProjectRoot73 } = await import("@cleocode/core/internal");
38323
- projectRoot = getProjectRoot73();
38342
+ const { getProjectRoot: getProjectRoot75 } = await import("@cleocode/core/internal");
38343
+ projectRoot = getProjectRoot75();
38324
38344
  } catch {
38325
38345
  projectRoot = void 0;
38326
38346
  }
@@ -38385,14 +38405,14 @@ var init_playbook2 = __esm({
38385
38405
  const deterministicRunner = await buildDefaultDeterministicRunner();
38386
38406
  let result;
38387
38407
  try {
38388
- const { getProjectRoot: getProjectRoot73 } = await import("@cleocode/core/internal");
38408
+ const { getProjectRoot: getProjectRoot75 } = await import("@cleocode/core/internal");
38389
38409
  const opts = {
38390
38410
  db,
38391
38411
  playbook: parsed.definition,
38392
38412
  playbookHash: parsed.sourceHash,
38393
38413
  initialContext,
38394
38414
  dispatcher,
38395
- projectRoot: getProjectRoot73()
38415
+ projectRoot: getProjectRoot75()
38396
38416
  };
38397
38417
  if (deterministicRunner !== void 0) opts.deterministicRunner = deterministicRunner;
38398
38418
  if (__playbookRuntimeOverrides.approvalSecret !== void 0) {
@@ -38751,6 +38771,7 @@ async function orchestratePivotOp(params) {
38751
38771
  else if (code === 38) errorCode = "E_NOT_ACTIVE";
38752
38772
  else if (code === 35) errorCode = "E_TASK_CLAIMED";
38753
38773
  else if (code === 24) errorCode = "E_SESSION_UNBOUND";
38774
+ else if (code === 26) errorCode = "E_TASK_RENAMED";
38754
38775
  const cleo = err instanceof CleoError ? err : void 0;
38755
38776
  return {
38756
38777
  success: false,
@@ -40089,7 +40110,7 @@ async function manifestStatsOp(params) {
40089
40110
  return pipelineManifestStats(params.epicId, getProjectRoot12());
40090
40111
  }
40091
40112
  async function manifestAppendOp(params) {
40092
- return pipelineManifestAppend(params.entry, getProjectRoot12());
40113
+ return pipelineManifestAppend(params.entry, getProjectRoot12(), { requireExistingTasks: true });
40093
40114
  }
40094
40115
  async function manifestArchiveOp(params) {
40095
40116
  return pipelineManifestArchive(params.beforeDate, getProjectRoot12());
@@ -45730,11 +45751,11 @@ var init_security = __esm({
45730
45751
  });
45731
45752
 
45732
45753
  // packages/cleo/src/dispatch/middleware/sanitizer.ts
45733
- function createSanitizer(getProjectRoot73) {
45754
+ function createSanitizer(getProjectRoot75) {
45734
45755
  return async (req, next) => {
45735
45756
  if (req.params) {
45736
45757
  try {
45737
- const root = getProjectRoot73 ? getProjectRoot73() : void 0;
45758
+ const root = getProjectRoot75 ? getProjectRoot75() : void 0;
45738
45759
  req.params = sanitizeParams(req.params, root, {
45739
45760
  domain: req.domain,
45740
45761
  operation: req.operation
@@ -45836,14 +45857,14 @@ var init_session_resolver = __esm({
45836
45857
  });
45837
45858
 
45838
45859
  // packages/cleo/src/dispatch/middleware/store-write-guard.ts
45839
- function createStoreWriteGuard(getProjectRoot73) {
45860
+ function createStoreWriteGuard(getProjectRoot75) {
45840
45861
  return async (req, next) => {
45841
45862
  if (req.gateway !== "mutate" || ALLOWED_WHILE_READ_ONLY.has(`${req.domain}.${req.operation}`)) {
45842
45863
  return next();
45843
45864
  }
45844
45865
  let projectRoot;
45845
45866
  try {
45846
- projectRoot = getProjectRoot73();
45867
+ projectRoot = getProjectRoot75();
45847
45868
  } catch {
45848
45869
  return next();
45849
45870
  }
@@ -46270,6 +46291,7 @@ var init_cli = __esm({
46270
46291
  E_CONFLICT: 23,
46271
46292
  E_SESSION_UNBOUND: 24,
46272
46293
  E_WORKTREE_LOCKED: 25,
46294
+ E_TASK_RENAMED: 26,
46273
46295
  E_TWIN_COLLAPSE_FAILED: 55,
46274
46296
  E_SESSION_EXISTS: 30,
46275
46297
  E_SESSION_NOT_FOUND: 31,
@@ -50625,7 +50647,7 @@ function nexusApiUrlArg(args) {
50625
50647
  function failNexus(err, operation) {
50626
50648
  const code = err instanceof Error && "code" in err && typeof err.code === "string" ? err.code : void 0;
50627
50649
  const fix = err instanceof Error && "fix" in err && typeof err.fix === "string" ? err.fix : void 0;
50628
- const exitCode = code === "E_NEXUS_INVALID_API_URL" || code === "E_NEXUS_INVALID_LABEL" ? 6 : 1;
50650
+ const exitCode = code === "E_NEXUS_INVALID_API_URL" || code === "E_NEXUS_INVALID_LABEL" || code === "E_NEXUS_DEVICE_REQUIRED" ? 6 : 1;
50629
50651
  cliError(
50630
50652
  err instanceof Error ? err.message : String(err),
50631
50653
  exitCode,
@@ -50643,16 +50665,52 @@ async function runNexusLogin(args, openBrowser2) {
50643
50665
  /* webpackIgnore: true */
50644
50666
  "@cleocode/core/cloud/nexus-auth.js"
50645
50667
  );
50668
+ const { isNexusDeviceEnabled } = await import(
50669
+ /* webpackIgnore: true */
50670
+ "@cleocode/core/cloud/nexus-device.js"
50671
+ );
50646
50672
  const noBrowser = negatedFlag(args, "browser");
50673
+ const hooks2 = {
50674
+ apiUrl: nexusApiUrlArg(args),
50675
+ onCode: (code) => {
50676
+ writeDeviceCodePrompt(code, SERVICE_NAME);
50677
+ if (!noBrowser) openBrowser2(code.verificationUriComplete ?? code.verificationUri);
50678
+ },
50679
+ onPending: writeDeviceCodePending
50680
+ };
50681
+ const readOnly = args["read-only"] === true;
50682
+ const name = typeof args["name"] === "string" && args["name"] !== "" ? args["name"] : void 0;
50683
+ if (readOnly && !isNexusDeviceEnabled()) {
50684
+ throw Object.assign(
50685
+ new Error(
50686
+ "--read-only needs device credentials, which are not enabled; nothing was signed in"
50687
+ ),
50688
+ {
50689
+ code: "E_NEXUS_DEVICE_REQUIRED",
50690
+ fix: "set CLEO_NEXUS_DEVICE=1 to enrol a read-only device, or log in without --read-only"
50691
+ }
50692
+ );
50693
+ }
50647
50694
  try {
50648
- const result = await loginToNexus({
50649
- apiUrl: nexusApiUrlArg(args),
50650
- onCode: (code) => {
50651
- writeDeviceCodePrompt(code, SERVICE_NAME);
50652
- if (!noBrowser) openBrowser2(code.verificationUriComplete ?? code.verificationUri);
50653
- },
50654
- onPending: writeDeviceCodePending
50655
- });
50695
+ let result;
50696
+ if (isNexusDeviceEnabled()) {
50697
+ const { loginToNexusDevice } = await import(
50698
+ /* webpackIgnore: true */
50699
+ "@cleocode/core/cloud/nexus-enrol.js"
50700
+ );
50701
+ result = await loginToNexusDevice({
50702
+ ...hooks2,
50703
+ readOnly,
50704
+ ...name !== void 0 ? { name } : {}
50705
+ });
50706
+ } else {
50707
+ if (name !== void 0) {
50708
+ process.stderr.write(
50709
+ "warning: --name needs device credentials (CLEO_NEXUS_DEVICE=1); ignored\n"
50710
+ );
50711
+ }
50712
+ result = await loginToNexus(hooks2);
50713
+ }
50656
50714
  writeDeviceCodeApproved(SERVICE_NAME);
50657
50715
  for (const warning of result.warnings) process.stderr.write(`warning: ${warning}
50658
50716
  `);
@@ -50665,7 +50723,8 @@ async function runNexusLogin(args, openBrowser2) {
50665
50723
  function nexusLoginSummary(r) {
50666
50724
  const who = r.user?.email ?? "your account";
50667
50725
  const org = r.organization ? ` (${r.organization.name})` : "";
50668
- return `Signed in to ${r.apiUrl} as ${who}${org}.`;
50726
+ const device = r.device ? ` This machine is device ${r.device.deviceId}${r.device.name ? ` (${r.device.name})` : ""}, profile ${r.device.profile ?? "unknown"}.` : "";
50727
+ return `Signed in to ${r.apiUrl} as ${who}${org}.${device}`;
50669
50728
  }
50670
50729
  var SERVICE_NAME, NEXUS_API_URL_ARG;
50671
50730
  var init_nexus_account_cli = __esm({
@@ -51554,6 +51613,14 @@ var init_login = __esm({
51554
51613
  description: "Open the verification URL in a browser (nexus). --no-browser only prints it (SSH, containers).",
51555
51614
  default: true
51556
51615
  },
51616
+ "read-only": {
51617
+ type: "boolean",
51618
+ description: "nexus with CLEO_NEXUS_DEVICE=1: enrol this machine with the read-only device profile (account, devices and project reads only). Refused without CLEO_NEXUS_DEVICE=1."
51619
+ },
51620
+ name: {
51621
+ type: "string",
51622
+ description: "nexus with CLEO_NEXUS_DEVICE=1: device name shown on cleocode.dev (default: OS, arch and a short id; never the hostname)."
51623
+ },
51557
51624
  auth: {
51558
51625
  type: "string",
51559
51626
  description: "Auth method: 'oauth' (browser) or 'api_key'. Inferred from the provider when omitted."
@@ -52858,14 +52925,14 @@ var init_backup = __esm({
52858
52925
  return;
52859
52926
  }
52860
52927
  const { exportPortableBundle, PortableBundleError } = await import("@cleocode/core/store/portable-bundle.js");
52861
- const { getProjectRoot: getProjectRoot73 } = await import("@cleocode/core");
52928
+ const { getProjectRoot: getProjectRoot75 } = await import("@cleocode/core");
52862
52929
  const passphrase = args.encrypt === true ? await resolvePassphrase() : void 0;
52863
52930
  if (args.encrypt === true && passphrase === void 0) return;
52864
52931
  const encSuffix = args.encrypt === true ? "enc." : "";
52865
52932
  try {
52866
52933
  const result = await exportPortableBundle({
52867
52934
  scope,
52868
- projectRoot: scope === "project" || scope === "all" ? getProjectRoot73() : void 0,
52935
+ projectRoot: scope === "project" || scope === "all" ? getProjectRoot75() : void 0,
52869
52936
  outputPath: args.out ?? `./${args.name}.${encSuffix}cleobundle.tar.gz`,
52870
52937
  encrypt: args.encrypt === true,
52871
52938
  passphrase,
@@ -52922,12 +52989,12 @@ var init_backup = __esm({
52922
52989
  );
52923
52990
  return;
52924
52991
  }
52925
- const { getProjectRoot: getProjectRoot73, getCleoHome: getCleoHome8, getCleoVersion } = await import("@cleocode/core");
52992
+ const { getProjectRoot: getProjectRoot75, getCleoHome: getCleoHome8, getCleoVersion } = await import("@cleocode/core");
52926
52993
  const { BundleError, cleanupStaging, unpackBundle } = await import("@cleocode/core/store/backup-unpack.js");
52927
52994
  const { regenerateConfigJson, regenerateProjectContextJson, regenerateProjectInfoJson } = await import("@cleocode/core/store/regenerators.js");
52928
52995
  const { regenerateAndCompare } = await import("@cleocode/core/store/restore-json-merge.js");
52929
52996
  const { buildConflictReport, writeConflictReport } = await import("@cleocode/core/store/restore-conflict-report.js");
52930
- const projectRoot = getProjectRoot73();
52997
+ const projectRoot = getProjectRoot75();
52931
52998
  const { assertOwnerStoreRewriteConfirmed } = await import("@cleocode/core/store/worktree-isolation-guard.js");
52932
52999
  try {
52933
53000
  assertOwnerStoreRewriteConfirmed("backup import", path2.join(projectRoot, ".cleo"), {
@@ -58465,12 +58532,12 @@ var init_decide2 = __esm({
58465
58532
  decideBenchCommand = defineCommand({
58466
58533
  meta: {
58467
58534
  name: "bench",
58468
- description: "System One accuracy benchmark (T12495): build a labelled dataset from this project's own history (duplicate task pairs, explicitly typed observations, superseding decisions; redacted), write a stratified spot-check sample for the owner, then compare providers against each site's heuristic with batched calls (provider cache off, 30s or longer deadline): accuracy, precision, recall, F1, false-positive rate, p50/p95 latency, cost and fallbacks, mean and spread over --runs. A hard total cap (--max-usd, default 5) is checked before every batch; the run stops cleanly at it. Profiles resolve from CLEO_DECIDE_PROFILE_<NAME>_KEY/_URL/_MODEL or the stored provider kind. --sample-only never contacts a provider."
58535
+ description: "System One accuracy benchmark (T12495): build a labelled dataset from this project's own history (duplicate task pairs, explicitly typed observations, superseding decisions; redacted), write a stratified spot-check sample for the owner, then compare providers against each site's heuristic with batched calls (provider cache off, 30s or longer deadline): accuracy, precision, recall, F1, false-positive rate, p50/p95 latency, cost and fallbacks, mean and spread over --runs. A hard total cap (--max-usd, default 5) is checked before every batch; the run stops cleanly at it. Each --profiles entry is a System One profile (cleo decide profiles): an id <provider>/<name> (e.g. layahost/work), or a bare provider meaning its active profile, else <provider>/default; a default URL resolves to the provider preset. A name no profile holds falls back to CLEO_DECIDE_PROFILE_<NAME>_KEY (plus _URL, _MODEL, _PROVIDER) for a one-off key. An unknown name fails listing the stored profiles (keys masked). --sample-only never contacts a provider."
58469
58536
  },
58470
58537
  args: {
58471
58538
  profiles: {
58472
58539
  type: "string",
58473
- description: "Comma list of provider profiles to compare, e.g. layahost,jev"
58540
+ description: "Comma list of profiles to compare: <provider>/<name> ids or bare providers, e.g. layahost/work,jev"
58474
58541
  },
58475
58542
  sites: {
58476
58543
  type: "string",
@@ -63120,12 +63187,74 @@ var init_docs3 = __esm({
63120
63187
  }
63121
63188
  });
63122
63189
 
63190
+ // packages/cleo/src/cli/commands/doctor-ac-bindings.ts
63191
+ var doctor_ac_bindings_exports = {};
63192
+ __export(doctor_ac_bindings_exports, {
63193
+ doctorAcBindingsCommand: () => doctorAcBindingsCommand
63194
+ });
63195
+ import { scanOrphanAcBindings } from "@cleocode/core/doctor/orphan-ac-bindings.js";
63196
+ import { getProjectRoot as getProjectRoot41 } from "@cleocode/core/paths.js";
63197
+ var doctorAcBindingsCommand;
63198
+ var init_doctor_ac_bindings = __esm({
63199
+ "packages/cleo/src/cli/commands/doctor-ac-bindings.ts"() {
63200
+ "use strict";
63201
+ init_src2();
63202
+ init_define_cli_command();
63203
+ init_renderers();
63204
+ doctorAcBindingsCommand = defineCommand({
63205
+ meta: {
63206
+ name: "ac-bindings",
63207
+ description: "Report evidence bindings whose acceptance criterion no longer exists (dangling tasks_evidence_ac_bindings rows). Read-only unless --fix is given; --fix removes them, recording each removed row in the task audit log (ac.bindings.pruned)."
63208
+ },
63209
+ args: {
63210
+ fix: {
63211
+ type: "boolean",
63212
+ description: "Delete the orphan bindings in one transaction, after writing each row to the task audit log so binding history (alias-drift detection) is kept."
63213
+ },
63214
+ limit: {
63215
+ type: "string",
63216
+ description: "Maximum orphan rows echoed in the report (default 50; counts are exact)"
63217
+ },
63218
+ json: { type: "boolean", description: "Output as JSON" },
63219
+ human: { type: "boolean", description: "Force human-readable output" },
63220
+ quiet: { type: "boolean", description: "Suppress non-essential output" }
63221
+ },
63222
+ async run({ args }) {
63223
+ let limit;
63224
+ if (typeof args.limit === "string") {
63225
+ if (!/^\d+$/.test(args.limit.trim())) {
63226
+ cliError(
63227
+ `--limit must be a non-negative integer (got '${args.limit}')`,
63228
+ 6 /* VALIDATION_ERROR */,
63229
+ { name: "E_VALIDATION" }
63230
+ );
63231
+ return;
63232
+ }
63233
+ limit = Number.parseInt(args.limit, 10);
63234
+ }
63235
+ const report = await scanOrphanAcBindings(getProjectRoot41(), {
63236
+ fix: args.fix === true,
63237
+ limit
63238
+ });
63239
+ cliOutput(report, {
63240
+ command: "doctor",
63241
+ operation: "doctor.ac-bindings.run"
63242
+ });
63243
+ const unresolved = report.orphanCount > report.removed;
63244
+ if (unresolved && (process.exitCode === void 0 || process.exitCode === 0)) {
63245
+ process.exitCode = 1;
63246
+ }
63247
+ }
63248
+ });
63249
+ }
63250
+ });
63251
+
63123
63252
  // packages/cleo/src/cli/commands/doctor-acceptance-drift.ts
63124
63253
  var doctor_acceptance_drift_exports = {};
63125
63254
  __export(doctor_acceptance_drift_exports, {
63126
63255
  doctorAcceptanceDriftCommand: () => doctorAcceptanceDriftCommand
63127
63256
  });
63128
- import { getProjectRoot as getProjectRoot41 } from "@cleocode/core";
63257
+ import { getProjectRoot as getProjectRoot42 } from "@cleocode/core";
63129
63258
  import {
63130
63259
  scanAcceptanceDrift,
63131
63260
  writeAcceptanceDriftBaseline
@@ -63155,7 +63284,7 @@ var init_doctor_acceptance_drift = __esm({
63155
63284
  quiet: { type: "boolean", description: "Suppress non-essential output" }
63156
63285
  },
63157
63286
  async run(ctx) {
63158
- const result = scanAcceptanceDrift(getProjectRoot41());
63287
+ const result = scanAcceptanceDrift(getProjectRoot42());
63159
63288
  cliOutput(result, {
63160
63289
  command: "doctor",
63161
63290
  operation: "doctor.acceptance-drift.run"
@@ -63179,7 +63308,7 @@ __export(doctor_credentials_exports, {
63179
63308
  doctorCredentialsCommand: () => doctorCredentialsCommand
63180
63309
  });
63181
63310
  import { join as join22 } from "node:path";
63182
- import { getCleoHome as getCleoHome5, getProjectRoot as getProjectRoot42 } from "@cleocode/core/paths.js";
63311
+ import { getCleoHome as getCleoHome5, getProjectRoot as getProjectRoot43 } from "@cleocode/core/paths.js";
63183
63312
  import {
63184
63313
  auditAgentRegistryKeys,
63185
63314
  migrateProjectCredentialsAtRoot
@@ -63206,7 +63335,7 @@ var init_doctor_credentials = __esm({
63206
63335
  },
63207
63336
  async run({ args }) {
63208
63337
  const dryRun = args.fix !== true;
63209
- const result = await migrateProjectCredentialsAtRoot(getProjectRoot42(), { dryRun });
63338
+ const result = await migrateProjectCredentialsAtRoot(getProjectRoot43(), { dryRun });
63210
63339
  const agents = await auditAgentRegistryKeys(join22(getCleoHome5(), "cleo.db"), { dryRun });
63211
63340
  cliOutput(
63212
63341
  {
@@ -63241,12 +63370,26 @@ __export(doctor_db_substrate_exports, {
63241
63370
  doctorDbSubstrateCommand: () => doctorDbSubstrateCommand
63242
63371
  });
63243
63372
  import { dirname as dirname9 } from "node:path";
63244
- import { getProjectRoot as getProjectRoot43, pushWarning as pushWarning4 } from "@cleocode/core";
63373
+ import { getProjectRoot as getProjectRoot44, pushWarning as pushWarning4 } from "@cleocode/core";
63245
63374
  import { surveyDbSubstrate, surveyFleetDbSubstrate } from "@cleocode/core/doctor/db-substrate.js";
63375
+ import { NexusRegistryReadError } from "@cleocode/core/nexus/registry-errors.js";
63246
63376
  import { listRegistryParentRoots } from "@cleocode/core/nexus/registry-roots.js";
63247
63377
  async function defaultFleetRoots() {
63248
63378
  const roots = await listRegistryParentRoots();
63249
- return roots.length > 0 ? roots : [dirname9(getProjectRoot43())];
63379
+ return roots.length > 0 ? roots : [dirname9(getProjectRoot44())];
63380
+ }
63381
+ function reportRegistryReadError(error) {
63382
+ cliError(
63383
+ error.message,
63384
+ error.code,
63385
+ {
63386
+ name: error.codeName,
63387
+ fix: `Pass \`--fleet-root <dir>\` to survey without the registry. ${error.fix ?? ""}`.trim(),
63388
+ details: error.details
63389
+ },
63390
+ { operation: "doctor.db-substrate.run" }
63391
+ );
63392
+ process.exitCode = error.code;
63250
63393
  }
63251
63394
  function pushSubstrateWarnings(result) {
63252
63395
  for (const warning of result.warnings) {
@@ -63384,10 +63527,21 @@ var init_doctor_db_substrate = __esm({
63384
63527
  cwd: process.cwd(),
63385
63528
  confirmOwnerStore: args["confirm-owner-store"] === true
63386
63529
  };
63387
- const result = isFleet ? surveyFleetDbSubstrate(
63388
- typeof args["fleet-root"] === "string" && args["fleet-root"].length > 0 ? args["fleet-root"] : await defaultFleetRoots(),
63389
- options
63390
- ) : surveyDbSubstrate(getProjectRoot43(), options);
63530
+ let fleetRoots;
63531
+ if (isFleet) {
63532
+ if (typeof args["fleet-root"] === "string" && args["fleet-root"].length > 0) {
63533
+ fleetRoots = args["fleet-root"];
63534
+ } else {
63535
+ try {
63536
+ fleetRoots = await defaultFleetRoots();
63537
+ } catch (error) {
63538
+ if (!(error instanceof NexusRegistryReadError)) throw error;
63539
+ reportRegistryReadError(error);
63540
+ return;
63541
+ }
63542
+ }
63543
+ }
63544
+ const result = fleetRoots !== void 0 ? surveyFleetDbSubstrate(fleetRoots, options) : surveyDbSubstrate(getProjectRoot44(), options);
63391
63545
  pushSubstrateWarnings(result);
63392
63546
  pushPerDbWarnings(result);
63393
63547
  cliOutput(result, {
@@ -63402,6 +63556,40 @@ var init_doctor_db_substrate = __esm({
63402
63556
  }
63403
63557
  });
63404
63558
 
63559
+ // packages/cleo/src/cli/commands/doctor-dep-cycles.ts
63560
+ var doctor_dep_cycles_exports = {};
63561
+ __export(doctor_dep_cycles_exports, {
63562
+ doctorDepCyclesCommand: () => doctorDepCyclesCommand
63563
+ });
63564
+ import { scanDependencyCycles } from "@cleocode/core/doctor/dependency-cycles.js";
63565
+ import { getProjectRoot as getProjectRoot45 } from "@cleocode/core/paths.js";
63566
+ var doctorDepCyclesCommand;
63567
+ var init_doctor_dep_cycles = __esm({
63568
+ "packages/cleo/src/cli/commands/doctor-dep-cycles.ts"() {
63569
+ "use strict";
63570
+ init_define_cli_command();
63571
+ init_renderers();
63572
+ doctorDepCyclesCommand = defineCommand({
63573
+ meta: {
63574
+ name: "dep-cycles",
63575
+ description: "Report task dependency cycles already stored (edges written before the T12886 cycle guard) with a repair plan: the edges whose removal breaks every cycle, each with its `cleo update <id> --remove-depends <dep>` command. Read-only; never removes an edge."
63576
+ },
63577
+ args: {
63578
+ json: { type: "boolean", description: "Output as JSON" },
63579
+ human: { type: "boolean", description: "Force human-readable output" },
63580
+ quiet: { type: "boolean", description: "Suppress non-essential output" }
63581
+ },
63582
+ async run() {
63583
+ const report = await scanDependencyCycles(getProjectRoot45());
63584
+ cliOutput(report, { command: "doctor", operation: "doctor.dep-cycles.run" });
63585
+ if (report.cycleCount > 0 && (process.exitCode === void 0 || process.exitCode === 0)) {
63586
+ process.exitCode = 2;
63587
+ }
63588
+ }
63589
+ });
63590
+ }
63591
+ });
63592
+
63405
63593
  // packages/cleo/src/cli/commands/doctor-exodus-residue.ts
63406
63594
  var doctor_exodus_residue_exports = {};
63407
63595
  __export(doctor_exodus_residue_exports, {
@@ -63719,7 +63907,7 @@ var doctor_legacy_backups_exports = {};
63719
63907
  __export(doctor_legacy_backups_exports, {
63720
63908
  doctorLegacyBackupsCommand: () => doctorLegacyBackupsCommand
63721
63909
  });
63722
- import { getProjectRoot as getProjectRoot44 } from "@cleocode/core";
63910
+ import { getProjectRoot as getProjectRoot46 } from "@cleocode/core";
63723
63911
  import { pruneLegacyBackups, scanLegacyBackups } from "@cleocode/core/doctor/legacy-backups.js";
63724
63912
  function parsePositiveInt(raw, fallback) {
63725
63913
  if (raw === void 0 || raw === null) return fallback;
@@ -63763,7 +63951,7 @@ var init_doctor_legacy_backups = __esm({
63763
63951
  async run({ args }) {
63764
63952
  const softRetentionDays = parsePositiveInt(args["soft-retention-days"], 30);
63765
63953
  const hardRetentionDays = parsePositiveInt(args["hard-retention-days"], 90);
63766
- const projectRoot = getProjectRoot44();
63954
+ const projectRoot = getProjectRoot46();
63767
63955
  let result;
63768
63956
  if (args.prune === true) {
63769
63957
  const dryRun = args["dry-run"] !== false;
@@ -63829,7 +64017,7 @@ var doctor_malformed_ids_exports = {};
63829
64017
  __export(doctor_malformed_ids_exports, {
63830
64018
  doctorMalformedIdsCommand: () => doctorMalformedIdsCommand
63831
64019
  });
63832
- import { getProjectRoot as getProjectRoot45 } from "@cleocode/core";
64020
+ import { getProjectRoot as getProjectRoot47 } from "@cleocode/core";
63833
64021
  import { scanMalformedTaskIds } from "@cleocode/core/doctor/malformed-task-ids.js";
63834
64022
  var doctorMalformedIdsCommand;
63835
64023
  var init_doctor_malformed_ids = __esm({
@@ -63852,7 +64040,7 @@ var init_doctor_malformed_ids = __esm({
63852
64040
  quiet: { type: "boolean", description: "Suppress non-essential output" }
63853
64041
  },
63854
64042
  async run({ args }) {
63855
- const report = await scanMalformedTaskIds(getProjectRoot45(), { fix: args.fix === true });
64043
+ const report = await scanMalformedTaskIds(getProjectRoot47(), { fix: args.fix === true });
63856
64044
  cliOutput(report, {
63857
64045
  command: "doctor",
63858
64046
  operation: "doctor.malformed-ids.run"
@@ -63873,12 +64061,13 @@ __export(doctor_manifest_rows_exports, {
63873
64061
  });
63874
64062
  import {
63875
64063
  listMalformedManifestRows,
64064
+ listManifestIdentityProblems,
63876
64065
  MANIFEST_ROW_APPLY_COMMAND,
63877
64066
  MANIFEST_ROW_REPAIR_COMMAND,
63878
64067
  repairMalformedManifestRows,
63879
64068
  rollbackManifestRepair
63880
64069
  } from "@cleocode/core/memory/pipeline-manifest-sqlite.js";
63881
- import { getProjectRoot as getProjectRoot46 } from "@cleocode/core/paths.js";
64070
+ import { getProjectRoot as getProjectRoot48 } from "@cleocode/core/paths.js";
63882
64071
  var doctorManifestRowsCommand;
63883
64072
  var init_doctor_manifest_rows = __esm({
63884
64073
  "packages/cleo/src/cli/commands/doctor-manifest-rows.ts"() {
@@ -63888,7 +64077,7 @@ var init_doctor_manifest_rows = __esm({
63888
64077
  doctorManifestRowsCommand = defineCommand({
63889
64078
  meta: {
63890
64079
  name: "manifest-rows",
63891
- description: "List manifest rows whose metadata violates the stored field contract. --repair shows the plan (writes nothing); --repair --apply moves each bad field under _malformed (nothing lost) with a receipt; --rollback <receipt> undoes it."
64080
+ description: "List manifest rows whose metadata violates the stored field contract, and (read-only) rows with an invalid id, linked task id or file reference. --repair shows the plan (writes nothing); --repair --apply moves each bad field under _malformed (nothing lost) with a receipt; --rollback <receipt> undoes it."
63892
64081
  },
63893
64082
  args: {
63894
64083
  repair: {
@@ -63909,7 +64098,7 @@ var init_doctor_manifest_rows = __esm({
63909
64098
  quiet: { type: "boolean", description: "Suppress non-essential output" }
63910
64099
  },
63911
64100
  async run({ args }) {
63912
- const projectRoot = getProjectRoot46();
64101
+ const projectRoot = getProjectRoot48();
63913
64102
  if (typeof args.rollback === "string" && args.rollback !== "") {
63914
64103
  const result = await rollbackManifestRepair(args.rollback, projectRoot);
63915
64104
  cliOutput(result, { command: "doctor", operation: "doctor.manifest-rows.rollback" });
@@ -63928,11 +64117,13 @@ var init_doctor_manifest_rows = __esm({
63928
64117
  return;
63929
64118
  }
63930
64119
  const rows = await listMalformedManifestRows(projectRoot);
64120
+ const identity = await listManifestIdentityProblems(projectRoot);
63931
64121
  cliOutput(
63932
- { rows, repair: rows.length > 0 ? MANIFEST_ROW_REPAIR_COMMAND : null },
64122
+ { rows, repair: rows.length > 0 ? MANIFEST_ROW_REPAIR_COMMAND : null, identity },
63933
64123
  { command: "doctor", operation: "doctor.manifest-rows.run" }
63934
64124
  );
63935
- if (rows.length > 0 && (process.exitCode === void 0 || process.exitCode === 0)) {
64125
+ const invalidIdentity = identity.some((r) => r.issues.some((i) => i.code === "E_VALIDATION"));
64126
+ if ((rows.length > 0 || invalidIdentity) && (process.exitCode === void 0 || process.exitCode === 0)) {
63936
64127
  process.exitCode = 1;
63937
64128
  }
63938
64129
  }
@@ -64009,7 +64200,7 @@ var doctor_nexus_residency_exports = {};
64009
64200
  __export(doctor_nexus_residency_exports, {
64010
64201
  doctorNexusResidencyCommand: () => doctorNexusResidencyCommand
64011
64202
  });
64012
- import { getCleoHome as getCleoHome6, getProjectRoot as getProjectRoot47 } from "@cleocode/core";
64203
+ import { getCleoHome as getCleoHome6, getProjectRoot as getProjectRoot49 } from "@cleocode/core";
64013
64204
  import { scanNexusSchemaResidency } from "@cleocode/core/doctor/nexus-schema-residency.js";
64014
64205
  var doctorNexusResidencyCommand;
64015
64206
  var init_doctor_nexus_residency = __esm({
@@ -64028,7 +64219,7 @@ var init_doctor_nexus_residency = __esm({
64028
64219
  quiet: { type: "boolean", description: "Suppress non-essential output" }
64029
64220
  },
64030
64221
  async run() {
64031
- const result = scanNexusSchemaResidency(getProjectRoot47(), getCleoHome6());
64222
+ const result = scanNexusSchemaResidency(getProjectRoot49(), getCleoHome6());
64032
64223
  cliOutput(result, {
64033
64224
  command: "doctor",
64034
64225
  operation: "doctor.nexus-residency.run"
@@ -64046,7 +64237,7 @@ var doctor_project_identity_exports = {};
64046
64237
  __export(doctor_project_identity_exports, {
64047
64238
  doctorProjectIdentityCommand: () => doctorProjectIdentityCommand
64048
64239
  });
64049
- import { getProjectRoot as getProjectRoot48 } from "@cleocode/core";
64240
+ import { getProjectRoot as getProjectRoot50 } from "@cleocode/core";
64050
64241
  import {
64051
64242
  inspectProjectIdentity,
64052
64243
  inspectProjectNameDrift,
@@ -64071,7 +64262,7 @@ var init_doctor_project_identity = __esm({
64071
64262
  quiet: { type: "boolean", description: "Suppress non-essential output" }
64072
64263
  },
64073
64264
  async run({ args }) {
64074
- const projectRoot = getProjectRoot48();
64265
+ const projectRoot = getProjectRoot50();
64075
64266
  if (!args.resolve) {
64076
64267
  const report = inspectProjectIdentity(projectRoot);
64077
64268
  const nameDrift = await inspectProjectNameDrift(projectRoot);
@@ -64104,6 +64295,7 @@ import {
64104
64295
  RegistryRepairError,
64105
64296
  rollbackProjectRegistryRepair
64106
64297
  } from "@cleocode/core/doctor/projects.js";
64298
+ import { NexusRegistryReadError as NexusRegistryReadError2 } from "@cleocode/core/nexus/registry-errors.js";
64107
64299
  var positiveInt, doctorRegistryCommand;
64108
64300
  var init_doctor_projects_registry = __esm({
64109
64301
  "packages/cleo/src/cli/commands/doctor-projects-registry.ts"() {
@@ -64157,6 +64349,16 @@ var init_doctor_projects_registry = __esm({
64157
64349
  if ((report.findings.some((f) => f.kind !== "other-device") || report.ambiguousAliases.length > 0) && (process.exitCode ?? 0) === 0)
64158
64350
  process.exitCode = 1;
64159
64351
  } catch (error) {
64352
+ if (error instanceof NexusRegistryReadError2) {
64353
+ cliError(
64354
+ error.message,
64355
+ error.code,
64356
+ { name: error.codeName, fix: error.fix, details: error.details },
64357
+ { operation }
64358
+ );
64359
+ process.exitCode = error.code;
64360
+ return;
64361
+ }
64160
64362
  const code = error instanceof RegistryRepairError ? error.code : "E_DOCTOR_PROJECTS_FAILED";
64161
64363
  const exitCode = code === "E_NOT_FOUND" ? 4 : 1;
64162
64364
  cliError(
@@ -64198,6 +64400,17 @@ function deriveExitCode(summary, ignoreUnreachable) {
64198
64400
  return 0;
64199
64401
  }
64200
64402
  function printDoctorProjectsReport(report, opts, nameLookup) {
64403
+ if (report.registryError) {
64404
+ const { registryError } = report;
64405
+ cliError(
64406
+ registryError.message,
64407
+ registryError.exitCode,
64408
+ { name: registryError.code, fix: registryError.fix, details: { report } },
64409
+ { operation: "doctor.projects" }
64410
+ );
64411
+ process.exitCode = registryError.exitCode;
64412
+ return;
64413
+ }
64201
64414
  const { summary } = report;
64202
64415
  const exitCode = deriveExitCode(summary, opts.ignoreUnreachable === true);
64203
64416
  process.exitCode = exitCode;
@@ -64250,13 +64463,15 @@ async function runDoctorProjects(opts = {}) {
64250
64463
  includeGlobal: opts.skipGlobal !== true
64251
64464
  });
64252
64465
  const nameLookup = /* @__PURE__ */ new Map();
64253
- try {
64254
- const { nexusList } = await import("@cleocode/core/internal");
64255
- const rows = await nexusList();
64256
- for (const row of rows) {
64257
- nameLookup.set(row.hash, row.name);
64466
+ if (!report.registryError) {
64467
+ try {
64468
+ const { nexusList } = await import("@cleocode/core/internal");
64469
+ const rows = await nexusList();
64470
+ for (const row of rows) {
64471
+ nameLookup.set(row.hash, row.name);
64472
+ }
64473
+ } catch {
64258
64474
  }
64259
- } catch {
64260
64475
  }
64261
64476
  printDoctorProjectsReport(report, opts, nameLookup);
64262
64477
  return report;
@@ -64586,7 +64801,7 @@ var doctor_repair_exports = {};
64586
64801
  __export(doctor_repair_exports, {
64587
64802
  doctorRepairCommand: () => doctorRepairCommand
64588
64803
  });
64589
- import { getLogger as getLogger21, getProjectRoot as getProjectRoot49 } from "@cleocode/core";
64804
+ import { getLogger as getLogger21, getProjectRoot as getProjectRoot51 } from "@cleocode/core";
64590
64805
  import { repairMalformedDbs } from "@cleocode/core/store/repair-malformed-dbs.js";
64591
64806
  var doctorRepairCommand;
64592
64807
  var init_doctor_repair = __esm({
@@ -64635,7 +64850,7 @@ var init_doctor_repair = __esm({
64635
64850
  return;
64636
64851
  }
64637
64852
  const result = repairMalformedDbs({
64638
- projectRoot: getProjectRoot49(),
64853
+ projectRoot: getProjectRoot51(),
64639
64854
  roles: roleArg.length > 0 ? [roleArg] : void 0,
64640
64855
  dryRun,
64641
64856
  logger: getLogger21("doctor-repair"),
@@ -64837,7 +65052,7 @@ var doctor_superseded_store_exports = {};
64837
65052
  __export(doctor_superseded_store_exports, {
64838
65053
  doctorSupersededStoreCommand: () => doctorSupersededStoreCommand
64839
65054
  });
64840
- import { getProjectRoot as getProjectRoot50 } from "@cleocode/core";
65055
+ import { getProjectRoot as getProjectRoot52 } from "@cleocode/core";
64841
65056
  import { scanSupersededStores } from "@cleocode/core/doctor/superseded-store.js";
64842
65057
  import { reconcileSupersededStores } from "@cleocode/core/store/exodus/index.js";
64843
65058
  var doctorSupersededStoreCommand;
@@ -64870,7 +65085,7 @@ var init_doctor_superseded_store = __esm({
64870
65085
  },
64871
65086
  async run({ args }) {
64872
65087
  if (args.reconcile === true) {
64873
- const receipt = await reconcileSupersededStores(getProjectRoot50(), {
65088
+ const receipt = await reconcileSupersededStores(getProjectRoot52(), {
64874
65089
  dryRun: args["dry-run"] === true,
64875
65090
  additive: args.additive === true
64876
65091
  });
@@ -64892,7 +65107,7 @@ var init_doctor_superseded_store = __esm({
64892
65107
  );
64893
65108
  return;
64894
65109
  }
64895
- const result = scanSupersededStores(getProjectRoot50());
65110
+ const result = scanSupersededStores(getProjectRoot52());
64896
65111
  cliOutput(result, {
64897
65112
  command: "doctor",
64898
65113
  operation: "doctor.superseded-store.run"
@@ -64988,11 +65203,12 @@ __export(doctor_twin_collapse_exports, {
64988
65203
  import {
64989
65204
  inspectProjectTwinCollapse,
64990
65205
  recoverTwinCollapse,
65206
+ releaseProjectTwinCollapseSnapshot,
64991
65207
  retryTwinCollapse,
64992
65208
  rollbackTwinCollapse
64993
65209
  } from "@cleocode/core/doctor/twin-collapse.js";
64994
65210
  import { CleoError as CleoError8 } from "@cleocode/core/errors";
64995
- import { getProjectRoot as getProjectRoot51 } from "@cleocode/core/paths.js";
65211
+ import { getProjectRoot as getProjectRoot53 } from "@cleocode/core/paths.js";
64996
65212
  function reportTwinCollapseError(error, retry) {
64997
65213
  if (retry && !(error instanceof CleoError8)) throw error;
64998
65214
  const message = error instanceof Error ? error.message : String(error);
@@ -65005,6 +65221,15 @@ function reportTwinCollapseError(error, retry) {
65005
65221
  });
65006
65222
  process.exitCode = error instanceof CleoError8 ? error.code : 1;
65007
65223
  }
65224
+ function twinCollapseActions(args) {
65225
+ const named = (key) => typeof args[key] === "string" && args[key].length > 0;
65226
+ return [
65227
+ args.recover === true ? "--recover" : "",
65228
+ named("release-snapshot") ? "--release-snapshot" : "",
65229
+ named("rollback") ? "--rollback" : "",
65230
+ args.retry === true ? "--retry" : ""
65231
+ ].filter(Boolean);
65232
+ }
65008
65233
  var doctorTwinCollapseCommand;
65009
65234
  var init_doctor_twin_collapse = __esm({
65010
65235
  "packages/cleo/src/cli/commands/doctor-twin-collapse.ts"() {
@@ -65014,7 +65239,7 @@ var init_doctor_twin_collapse = __esm({
65014
65239
  doctorTwinCollapseCommand = defineCommand({
65015
65240
  meta: {
65016
65241
  name: "twin-collapse",
65017
- description: "Report the twin collapses (bare schema_meta / sticky_tags kept in step with their prefixed twins): state, last failure, snapshot path and space needed. --retry re-runs them."
65242
+ description: "Report the twin collapses (bare schema_meta / sticky_tags kept in step with their prefixed twins): state, last failure, snapshot path and space needed. --retry re-runs them; --recover restores what 2026.9.21 dropped; --release-snapshot lets a checked snapshot rotate."
65018
65243
  },
65019
65244
  args: {
65020
65245
  retry: {
@@ -65029,10 +65254,22 @@ var init_doctor_twin_collapse = __esm({
65029
65254
  type: "boolean",
65030
65255
  description: "With --recover: print the plan, write nothing"
65031
65256
  },
65257
+ "pin-snapshot": {
65258
+ type: "boolean",
65259
+ description: "With --recover: pin an unpinned pre-collapse snapshot (its .meta.json sidecar only) before applying"
65260
+ },
65032
65261
  rollback: {
65033
65262
  type: "string",
65034
65263
  description: "Undo one --recover apply by its receipt id (twin_collapse_recovery:<recoveredAt>)"
65035
65264
  },
65265
+ "release-snapshot": {
65266
+ type: "string",
65267
+ description: "Release a pre-collapse snapshot (backup id, e.g. migration-20260928-153200) after a verified recovery or a no-recovery-needed check, so it rotates normally. Needs --confirm; --dry-run shows the bytes reclaimed"
65268
+ },
65269
+ confirm: {
65270
+ type: "boolean",
65271
+ description: "With --release-snapshot: the owner's decision to release (obtained by the calling agent; the CLI never prompts)"
65272
+ },
65036
65273
  "confirm-owner-store": {
65037
65274
  type: "boolean",
65038
65275
  description: "From a git worktree: allow --recover, --rollback or --retry to write the owning project's live store"
@@ -65042,8 +65279,18 @@ var init_doctor_twin_collapse = __esm({
65042
65279
  quiet: { type: "boolean", description: "Suppress non-essential output" }
65043
65280
  },
65044
65281
  async run({ args }) {
65045
- const projectRoot = getProjectRoot51();
65282
+ const projectRoot = getProjectRoot53();
65046
65283
  const guard = { cwd: process.cwd(), confirmOwnerStore: args["confirm-owner-store"] === true };
65284
+ const actions = twinCollapseActions(args);
65285
+ if (actions.length > 1) {
65286
+ cliError(
65287
+ `E_INVALID_INPUT: ${actions.join(" and ")} are separate actions; run them one at a time (--recover before --release-snapshot)`,
65288
+ "E_INVALID_INPUT",
65289
+ { name: "Error", fix: "cleo doctor twin-collapse --recover --dry-run" }
65290
+ );
65291
+ process.exitCode = 2;
65292
+ return;
65293
+ }
65047
65294
  try {
65048
65295
  if (typeof args.rollback === "string" && args.rollback.length > 0) {
65049
65296
  const result = await rollbackTwinCollapse(projectRoot, args.rollback, guard);
@@ -65053,10 +65300,27 @@ var init_doctor_twin_collapse = __esm({
65053
65300
  );
65054
65301
  return;
65055
65302
  }
65303
+ if (typeof args["release-snapshot"] === "string" && args["release-snapshot"].length > 0) {
65304
+ const result = await releaseProjectTwinCollapseSnapshot(
65305
+ projectRoot,
65306
+ args["release-snapshot"],
65307
+ {
65308
+ ...guard,
65309
+ dryRun: args["dry-run"] === true,
65310
+ confirm: args.confirm === true
65311
+ }
65312
+ );
65313
+ cliOutput(
65314
+ { kind: "generic", ...result },
65315
+ { command: "doctor", operation: "doctor.twin-collapse.release-snapshot" }
65316
+ );
65317
+ return;
65318
+ }
65056
65319
  if (args.recover === true) {
65057
65320
  const result = await recoverTwinCollapse(projectRoot, {
65058
65321
  ...guard,
65059
- dryRun: args["dry-run"] === true
65322
+ dryRun: args["dry-run"] === true,
65323
+ pinSnapshot: args["pin-snapshot"] === true
65060
65324
  });
65061
65325
  cliOutput(
65062
65326
  { kind: "generic", ...result },
@@ -65093,7 +65357,7 @@ __export(doctor_worktree_stores_exports, {
65093
65357
  doctorWorktreeStoresCommand: () => doctorWorktreeStoresCommand
65094
65358
  });
65095
65359
  import { scanWorktreeStores } from "@cleocode/core/doctor/worktree-stores.js";
65096
- import { getProjectRoot as getProjectRoot52, resolveStoreOwnerRoot } from "@cleocode/core/paths.js";
65360
+ import { getProjectRoot as getProjectRoot54, resolveStoreOwnerRoot } from "@cleocode/core/paths.js";
65097
65361
  var doctorWorktreeStoresCommand;
65098
65362
  var init_doctor_worktree_stores = __esm({
65099
65363
  "packages/cleo/src/cli/commands/doctor-worktree-stores.ts"() {
@@ -65115,7 +65379,7 @@ var init_doctor_worktree_stores = __esm({
65115
65379
  quiet: { type: "boolean", description: "Suppress non-essential output" }
65116
65380
  },
65117
65381
  async run({ args }) {
65118
- const projectRoot = resolveStoreOwnerRoot(getProjectRoot52());
65382
+ const projectRoot = resolveStoreOwnerRoot(getProjectRoot54());
65119
65383
  const result = scanWorktreeStores(projectRoot, { skipCompare: args["skip-compare"] === true });
65120
65384
  cliOutput(result, {
65121
65385
  command: "doctor",
@@ -65267,7 +65531,7 @@ import {
65267
65531
  resumePreparedKnowledgeRepair,
65268
65532
  runKnowledgeDoctor as runKnowledgeDoctor2
65269
65533
  } from "@cleocode/core/doctor/knowledge.js";
65270
- import { getProjectRoot as getProjectRoot53 } from "@cleocode/core/paths.js";
65534
+ import { getProjectRoot as getProjectRoot55 } from "@cleocode/core/paths.js";
65271
65535
  var doctorKnowledgeSubcommand;
65272
65536
  var init_doctor_knowledge = __esm({
65273
65537
  "packages/cleo/src/cli/commands/doctor-knowledge.ts"() {
@@ -65342,7 +65606,7 @@ var init_doctor_knowledge = __esm({
65342
65606
  },
65343
65607
  async run({ args }) {
65344
65608
  const startedAt = Date.now();
65345
- const root = getProjectRoot53();
65609
+ const root = getProjectRoot55();
65346
65610
  let context;
65347
65611
  let pending;
65348
65612
  try {
@@ -65510,7 +65774,7 @@ import { join as join24 } from "node:path";
65510
65774
  import {
65511
65775
  ensureGlobalAgentRegistryDb,
65512
65776
  getGlobalAgentRegistryNativeDb,
65513
- getProjectRoot as getProjectRoot54,
65777
+ getProjectRoot as getProjectRoot56,
65514
65778
  installAgentFromCant
65515
65779
  } from "@cleocode/core/internal";
65516
65780
  function sha256Hex(bytes) {
@@ -65698,7 +65962,7 @@ var init_migrate_agents_v2 = __esm({
65698
65962
  }
65699
65963
  },
65700
65964
  async run({ args }) {
65701
- const projectRoot = getProjectRoot54();
65965
+ const projectRoot = getProjectRoot56();
65702
65966
  const verbose = args.quiet !== true;
65703
65967
  if (verbose) {
65704
65968
  humanInfo("Scanning .cleo/cant/agents/ and .cleo/agents/ for unregistered agents...");
@@ -65742,7 +66006,7 @@ __export(doctor_exports, {
65742
66006
  });
65743
66007
  import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync5 } from "node:fs";
65744
66008
  import { join as join25 } from "node:path";
65745
- import { getProjectRoot as getProjectRoot55, pushWarning as pushWarning5 } from "@cleocode/core";
66009
+ import { getProjectRoot as getProjectRoot57, pushWarning as pushWarning5 } from "@cleocode/core";
65746
66010
  import { renderInvariantAuditLines } from "@cleocode/core/doctor/invariant-audit-render.js";
65747
66011
  import {
65748
66012
  quarantineRogueCleoDir,
@@ -65858,9 +66122,11 @@ var init_doctor = __esm({
65858
66122
  init_subcommand_guard();
65859
66123
  init_progress();
65860
66124
  init_renderers();
66125
+ init_doctor_ac_bindings();
65861
66126
  init_doctor_acceptance_drift();
65862
66127
  init_doctor_credentials();
65863
66128
  init_doctor_db_substrate();
66129
+ init_doctor_dep_cycles();
65864
66130
  init_doctor_exodus();
65865
66131
  init_doctor_exodus_residue();
65866
66132
  init_doctor_fk_check();
@@ -65925,6 +66191,10 @@ var init_doctor = __esm({
65925
66191
  "split-brain": doctorSplitBrainCommand,
65926
66192
  // T12157 — the two acceptance stores (json column vs text+child rows) must agree
65927
66193
  "acceptance-drift": doctorAcceptanceDriftCommand,
66194
+ // T12790 — evidence bindings whose AC row is gone (no FK): report + --fix (audited)
66195
+ "ac-bindings": doctorAcBindingsCommand,
66196
+ // T12886 — stored task dependency cycles + repair plan (read-only)
66197
+ "dep-cycles": doctorDepCyclesCommand,
65928
66198
  // T12158 — tables nexus resolves by bare name must actually live where it assumes
65929
66199
  "nexus-residency": doctorNexusResidencyCommand,
65930
66200
  // T12113 (gh#1222) — evidence-tool semaphore holders + orphan reaping
@@ -66143,7 +66413,7 @@ var init_doctor = __esm({
66143
66413
  const { join: pathJoin } = await import("node:path");
66144
66414
  const { existsSync: existsSync22 } = await import("node:fs");
66145
66415
  const { detectAndHealCoreWorktreeLeak } = await import("@cleocode/worktree");
66146
- const projectRoot = getProjectRoot55();
66416
+ const projectRoot = getProjectRoot57();
66147
66417
  let gitRoot = projectRoot;
66148
66418
  try {
66149
66419
  gitRoot = execFile2("git", ["rev-parse", "--show-toplevel"], {
@@ -66195,7 +66465,7 @@ var init_doctor = __esm({
66195
66465
  }
66196
66466
  if (args.brain) {
66197
66467
  const { computeBrainHealthDashboard } = await import("@cleocode/core/memory/brain-health-dashboard.js");
66198
- const projectRoot = getProjectRoot55();
66468
+ const projectRoot = getProjectRoot57();
66199
66469
  const dashboard = await computeBrainHealthDashboard(projectRoot);
66200
66470
  cliOutput(dashboard, { command: "doctor", operation: "doctor.brain" });
66201
66471
  if (dashboard.hasP0Failure) {
@@ -66204,7 +66474,7 @@ var init_doctor = __esm({
66204
66474
  return;
66205
66475
  }
66206
66476
  if (args["scan-test-fixtures-in-prod"]) {
66207
- const projectRoot = getProjectRoot55();
66477
+ const projectRoot = getProjectRoot57();
66208
66478
  const matches = await scanTestFixturesInProd(projectRoot);
66209
66479
  const dryRun = args["dry-run"] !== false && args.quarantine !== true;
66210
66480
  const quarantined = !dryRun && matches.length > 0 ? await quarantineTestFixtures(projectRoot, matches) : void 0;
@@ -66292,7 +66562,7 @@ var init_doctor = __esm({
66292
66562
  progress.complete("Comprehensive diagnostics complete");
66293
66563
  } else if (args["scan-rogue-cleo-dirs"]) {
66294
66564
  progress.step(0, "Scanning for rogue .cleo/ directories");
66295
- const projectRoot = getProjectRoot55();
66565
+ const projectRoot = getProjectRoot57();
66296
66566
  const reports = scanRogueCleoDirs(projectRoot);
66297
66567
  progress.complete(
66298
66568
  `Found ${reports.length} rogue .cleo/ director${reports.length === 1 ? "y" : "ies"}`
@@ -66301,7 +66571,7 @@ var init_doctor = __esm({
66301
66571
  } else if (args["quarantine-rogue-cleo-dirs"]) {
66302
66572
  const isDryRun = args["dry-run"] === true;
66303
66573
  progress.step(0, `${isDryRun ? "[DRY RUN] " : ""}Scanning for rogue .cleo/ directories`);
66304
- const projectRoot = getProjectRoot55();
66574
+ const projectRoot = getProjectRoot57();
66305
66575
  const reports = scanRogueCleoDirs(projectRoot);
66306
66576
  if (reports.length === 0) {
66307
66577
  progress.complete("No rogue .cleo/ directories found \u2014 nothing to quarantine");
@@ -66355,7 +66625,7 @@ var init_doctor = __esm({
66355
66625
  const { detectAndRemoveLegacyGlobalFiles, detectAndRemoveStrayProjectNexus } = await import("@cleocode/core/store/cleanup-legacy.js");
66356
66626
  const { getCleoHome: getCleoHome8 } = await import("@cleocode/core");
66357
66627
  const cleoHome = getCleoHome8();
66358
- const projectRoot = getProjectRoot55();
66628
+ const projectRoot = getProjectRoot57();
66359
66629
  const legacyResult = detectAndRemoveLegacyGlobalFiles(cleoHome);
66360
66630
  const strayResult = detectAndRemoveStrayProjectNexus(projectRoot);
66361
66631
  const isDryRun = args["dry-run"] === true;
@@ -66388,7 +66658,7 @@ var init_doctor = __esm({
66388
66658
  } else if (args["audit-worktree-orphans"]) {
66389
66659
  progress.step(0, "Comprehensive worktree anomaly audit (T9808 / council D009)");
66390
66660
  const { auditWorktreeOrphansComprehensive, scanWorktreeOrphansBudgeted } = await import("@cleocode/core/doctor/worktree-orphans.js");
66391
- const projectRoot = getProjectRoot55();
66661
+ const projectRoot = getProjectRoot57();
66392
66662
  const timeoutSecs = args["timeout"] !== void 0 ? Number.parseInt(String(args["timeout"]), 10) : 30;
66393
66663
  const timeoutMs = Number.isFinite(timeoutSecs) && timeoutSecs > 0 ? timeoutSecs * 1e3 : 3e4;
66394
66664
  const maxEntriesPerLevel = args["max-entries-per-level"] !== void 0 ? Number.parseInt(String(args["max-entries-per-level"]), 10) : 500;
@@ -66445,7 +66715,7 @@ var init_doctor = __esm({
66445
66715
  `${isDryRun ? "[DRY RUN] " : ""}Scanning + pruning worktree-orphan .cleo/ directories`
66446
66716
  );
66447
66717
  const { pruneWorktreeOrphans, scanWorktreeOrphansBudgeted } = await import("@cleocode/core/doctor/worktree-orphans.js");
66448
- const projectRoot = getProjectRoot55();
66718
+ const projectRoot = getProjectRoot57();
66449
66719
  const timeoutSecs = args["timeout"] !== void 0 ? Number.parseInt(String(args["timeout"]), 10) : 30;
66450
66720
  const timeoutMs = Number.isFinite(timeoutSecs) && timeoutSecs > 0 ? timeoutSecs * 1e3 : 3e4;
66451
66721
  const maxEntriesPerLevel = args["max-entries-per-level"] !== void 0 ? Number.parseInt(String(args["max-entries-per-level"]), 10) : 500;
@@ -66524,7 +66794,7 @@ var init_doctor = __esm({
66524
66794
  `${isDryRun ? "[DRY RUN] " : ""}Migrating .cleo/worktree-include \u2192 .worktreeinclude`
66525
66795
  );
66526
66796
  const { migrateWorktreeIncludeFile } = await import("@cleocode/core");
66527
- const projectRoot = getProjectRoot55();
66797
+ const projectRoot = getProjectRoot57();
66528
66798
  const result = await migrateWorktreeIncludeFile(projectRoot, { dryRun: isDryRun });
66529
66799
  progress.complete(`Migration ${result.action}`);
66530
66800
  cliOutput(result, { command: "doctor", operation: "doctor.migrate-worktree-include" });
@@ -66543,7 +66813,7 @@ var init_doctor = __esm({
66543
66813
  const stepLabel = isFocusedAlias ? "Auditing Saga hierarchy for ADR-073 invariants" : "Walking central INVARIANTS_REGISTRY";
66544
66814
  progress.step(0, stepLabel);
66545
66815
  const { auditInvariantRegistry } = await import("@cleocode/core/doctor/invariant-audit.js");
66546
- const projectRoot = getProjectRoot55();
66816
+ const projectRoot = getProjectRoot57();
66547
66817
  const result = await auditInvariantRegistry(projectRoot, { adrFilter });
66548
66818
  const operation = isFocusedAlias ? "doctor.audit-sagas" : "doctor.audit-invariants";
66549
66819
  const summary = `Invariant audit complete \u2014 ${result.totalCount} entries walked, ${result.errorCount} error / ${result.warningCount} warning / ${result.infoCount} info violation(s), ${result.notApplicableCount} not-applicable, ${result.documentedCount} documented`;
@@ -66565,7 +66835,7 @@ var init_doctor = __esm({
66565
66835
  { command: "doctor", operation: "admin.health" }
66566
66836
  );
66567
66837
  try {
66568
- const projectRoot = getProjectRoot55();
66838
+ const projectRoot = getProjectRoot57();
66569
66839
  const conflicts = readMigrationConflicts(projectRoot);
66570
66840
  if (conflicts.length > 0) {
66571
66841
  progress.complete(
@@ -66596,7 +66866,7 @@ var init_doctor = __esm({
66596
66866
  progress.complete("Health check complete");
66597
66867
  }
66598
66868
  try {
66599
- const projectRoot = getProjectRoot55();
66869
+ const projectRoot = getProjectRoot57();
66600
66870
  const { auditSagaHierarchy } = await import("@cleocode/core/doctor/saga-audit.js");
66601
66871
  const sagaAudit = await auditSagaHierarchy(projectRoot);
66602
66872
  if (sagaAudit.sagas.length === 0) {
@@ -66623,6 +66893,26 @@ Saga Hierarchy (${sagaAudit.sagas.length} saga(s), ${sagaAudit.count} violation(
66623
66893
  humanLine(`
66624
66894
  Saga Hierarchy: audit skipped (${msg})`);
66625
66895
  }
66896
+ try {
66897
+ const { scanDependencyCycles: scanDependencyCycles2 } = await import("@cleocode/core/doctor/dependency-cycles.js");
66898
+ const cycles = await scanDependencyCycles2(getProjectRoot57());
66899
+ humanLine(
66900
+ `
66901
+ Dependency cycles: ${cycles.cycleCount} (${cycles.edgeCount} edge(s) checked)`
66902
+ );
66903
+ for (const c of cycles.components) humanLine(` ${c.cycle.join(" \u2192 ")}`);
66904
+ if (cycles.repairPlan.length > 0) {
66905
+ humanLine(" Repair plan (review first; `cleo doctor dep-cycles` for JSON):");
66906
+ for (const r of cycles.repairPlan) humanLine(` ${r.command}`);
66907
+ }
66908
+ if (cycles.cycleCount > 0 && (process.exitCode === void 0 || process.exitCode === 0)) {
66909
+ process.exitCode = 2;
66910
+ }
66911
+ } catch (err) {
66912
+ const msg = err instanceof Error ? err.message : String(err);
66913
+ humanLine(`
66914
+ Dependency cycles: check skipped (${msg})`);
66915
+ }
66626
66916
  }
66627
66917
  } catch (err) {
66628
66918
  progress.error("Health check failed");
@@ -66644,7 +66934,7 @@ async function batchEntry(taskId, result, args) {
66644
66934
  return { taskId, completed: false, error: code, message, next: fix };
66645
66935
  }
66646
66936
  const params = completeDispatchParams({ ...args, taskId, "if-match": void 0 });
66647
- const done = await dispatchRaw("mutate", "tasks", "complete", params);
66937
+ const done = await withoutOutputPointer(() => dispatchRaw("mutate", "tasks", "complete", params));
66648
66938
  const recordedGates = result.data.recordedGates;
66649
66939
  if (done.success) return { taskId, recordedGates, completed: true };
66650
66940
  const failure = { error: "E_DONE_BLOCKED", message: done.error?.message, next: done.error?.fix };
@@ -66680,6 +66970,7 @@ var init_done = __esm({
66680
66970
  "packages/cleo/src/cli/commands/done.ts"() {
66681
66971
  "use strict";
66682
66972
  init_cli();
66973
+ init_field_context();
66683
66974
  init_define_cli_command();
66684
66975
  init_renderers();
66685
66976
  init_complete();
@@ -66715,8 +67006,8 @@ var init_done = __esm({
66715
67006
  process.exitCode = 2;
66716
67007
  return;
66717
67008
  }
66718
- const { getProjectRoot: getProjectRoot73 } = await import("@cleocode/core/paths.js");
66719
- const options = { projectRoot: getProjectRoot73(), ...parsed.options };
67009
+ const { getProjectRoot: getProjectRoot75 } = await import("@cleocode/core/paths.js");
67010
+ const options = { projectRoot: getProjectRoot75(), ...parsed.options };
66720
67011
  const requested = [
66721
67012
  ...new Set([args.taskId, ...args._ ?? []].map(String))
66722
67013
  ];
@@ -66766,11 +67057,13 @@ var init_done = __esm({
66766
67057
  process.exitCode = recorded.error.exitCode ?? 1;
66767
67058
  return;
66768
67059
  }
66769
- const completed = await dispatchRaw(
66770
- "mutate",
66771
- "tasks",
66772
- "complete",
66773
- completeDispatchParams({ ...args, "if-match": void 0 })
67060
+ const completed = await withoutOutputPointer(
67061
+ () => dispatchRaw(
67062
+ "mutate",
67063
+ "tasks",
67064
+ "complete",
67065
+ completeDispatchParams({ ...args, "if-match": void 0 })
67066
+ )
66774
67067
  );
66775
67068
  if (!completed.success) {
66776
67069
  const details = {
@@ -68076,7 +68369,7 @@ __export(gateway_exports, {
68076
68369
  gatewayOpenapiSubCommand: () => gatewayOpenapiSubCommand
68077
68370
  });
68078
68371
  import { resolve as resolve8 } from "node:path";
68079
- import { generateOpenApi, getProjectRoot as getProjectRoot56 } from "@cleocode/core";
68372
+ import { generateOpenApi, getProjectRoot as getProjectRoot58 } from "@cleocode/core";
68080
68373
  var gatewayOpenapiSubCommand, gatewayCommand;
68081
68374
  var init_gateway = __esm({
68082
68375
  "packages/cleo/src/cli/commands/gateway.ts"() {
@@ -68108,7 +68401,7 @@ var init_gateway = __esm({
68108
68401
  const pathCount = Object.keys(doc.paths).length;
68109
68402
  if (typeof args.out === "string" && args.out.length > 0) {
68110
68403
  const { writeFileSync: writeFileSync8 } = await import("node:fs");
68111
- const target = resolve8(getProjectRoot56(), args.out);
68404
+ const target = resolve8(getProjectRoot58(), args.out);
68112
68405
  writeFileSync8(target, json2, "utf8");
68113
68406
  cliOutput(
68114
68407
  { out: target, pathCount, version: doc.info.version, openapi: doc.openapi },
@@ -68569,7 +68862,7 @@ var go_exports = {};
68569
68862
  __export(go_exports, {
68570
68863
  goCommand: () => goCommand
68571
68864
  });
68572
- import { getProjectRoot as getProjectRoot57, go } from "@cleocode/core";
68865
+ import { getProjectRoot as getProjectRoot59, go } from "@cleocode/core";
68573
68866
  var goCommand;
68574
68867
  var init_go = __esm({
68575
68868
  "packages/cleo/src/cli/commands/go.ts"() {
@@ -68595,7 +68888,7 @@ var init_go = __esm({
68595
68888
  }
68596
68889
  },
68597
68890
  async run({ args }) {
68598
- const projectRoot = getProjectRoot57();
68891
+ const projectRoot = getProjectRoot59();
68599
68892
  const { getCurrentSessionId, resolveBoundSessionId } = await import("@cleocode/core/internal");
68600
68893
  let sessionId = getCurrentSessionId(projectRoot) ?? void 0;
68601
68894
  if (sessionId === void 0) {
@@ -68623,7 +68916,7 @@ var goal_exports = {};
68623
68916
  __export(goal_exports, {
68624
68917
  goalCommand: () => goalCommand
68625
68918
  });
68626
- import { getProjectRoot as getProjectRoot58, goal } from "@cleocode/core";
68919
+ import { getProjectRoot as getProjectRoot60, goal } from "@cleocode/core";
68627
68920
  function resolveGoalKind(task) {
68628
68921
  if (typeof task === "string" && task.length > 0) {
68629
68922
  if (!isValidGoalTargetTaskId(task)) {
@@ -68670,7 +68963,7 @@ var init_goal2 = __esm({
68670
68963
  }
68671
68964
  const record = await goal.createGoal(
68672
68965
  { goalKind: kindResult.kind, intent, turnBudget: resolveTurnBudget(args.turns) },
68673
- getProjectRoot58()
68966
+ getProjectRoot60()
68674
68967
  );
68675
68968
  cliOutput(record, { command: "goal set", operation: "goal.set" });
68676
68969
  }
@@ -68681,7 +68974,7 @@ var init_goal2 = __esm({
68681
68974
  description: "Show the current agent's active goal (per-agent scoped)."
68682
68975
  },
68683
68976
  async run() {
68684
- const record = await goal.getActiveGoal(getProjectRoot58());
68977
+ const record = await goal.getActiveGoal(getProjectRoot60());
68685
68978
  cliOutput(record ?? { active: null }, { command: "goal status", operation: "goal.status" });
68686
68979
  }
68687
68980
  });
@@ -68703,7 +68996,7 @@ var init_goal2 = __esm({
68703
68996
  });
68704
68997
  return;
68705
68998
  }
68706
- const cwd = getProjectRoot58();
68999
+ const cwd = getProjectRoot60();
68707
69000
  const parent = await goal.getActiveGoal(cwd);
68708
69001
  if (!parent) {
68709
69002
  cliError(
@@ -68751,7 +69044,7 @@ var init_goal2 = __esm({
68751
69044
  });
68752
69045
  return;
68753
69046
  }
68754
- const cwd = getProjectRoot58();
69047
+ const cwd = getProjectRoot60();
68755
69048
  const result = await goal.advanceGoalWithPersist(goalId, { cwd });
68756
69049
  if (!result) {
68757
69050
  cliError(`Goal '${goalId}' not found.`, 4 /* NOT_FOUND */, { name: "E_NOT_FOUND" });
@@ -68776,7 +69069,7 @@ var init_goal2 = __esm({
68776
69069
  });
68777
69070
  return;
68778
69071
  }
68779
- const cwd = getProjectRoot58();
69072
+ const cwd = getProjectRoot60();
68780
69073
  const active = await goal.getActiveGoal(cwd);
68781
69074
  if (!active) {
68782
69075
  cliError(
@@ -69823,7 +70116,7 @@ var hygiene_exports = {};
69823
70116
  __export(hygiene_exports, {
69824
70117
  hygieneCommand: () => hygieneCommand
69825
70118
  });
69826
- import { getProjectRoot as getProjectRoot59 } from "@cleocode/core";
70119
+ import { getProjectRoot as getProjectRoot61 } from "@cleocode/core";
69827
70120
  import { runSpawnReadinessHygieneCli } from "@cleocode/core/hygiene/validate-spawn-readiness.js";
69828
70121
  var hygieneCommand;
69829
70122
  var init_hygiene = __esm({
@@ -69852,7 +70145,7 @@ var init_hygiene = __esm({
69852
70145
  }
69853
70146
  },
69854
70147
  async run({ args }) {
69855
- const projectRoot = args["project-root"] || getProjectRoot59() || process.cwd();
70148
+ const projectRoot = args["project-root"] || getProjectRoot61() || process.cwd();
69856
70149
  const worktreePath = args["worktree-path"];
69857
70150
  await runSpawnReadinessHygieneCli(projectRoot, worktreePath);
69858
70151
  }
@@ -71195,7 +71488,7 @@ var llm_cost_exports = {};
71195
71488
  __export(llm_cost_exports, {
71196
71489
  costCommand: () => costCommand
71197
71490
  });
71198
- import { getProjectRoot as getProjectRoot60 } from "@cleocode/core/internal";
71491
+ import { getProjectRoot as getProjectRoot62 } from "@cleocode/core/internal";
71199
71492
  import { computeCost } from "@cleocode/core/llm/usage-pricing";
71200
71493
  function resolveSessionId(raw) {
71201
71494
  if (raw === "current") {
@@ -71268,7 +71561,7 @@ var init_llm_cost = __esm({
71268
71561
  process.exit(6);
71269
71562
  }
71270
71563
  const sessionId = resolveSessionId(rawSessionId);
71271
- const projectRoot = getProjectRoot60(process.cwd());
71564
+ const projectRoot = getProjectRoot62(process.cwd());
71272
71565
  let breakdown;
71273
71566
  try {
71274
71567
  breakdown = await loadSessionCostBreakdown(projectRoot, sessionId);
@@ -72657,7 +72950,7 @@ var memory_exports = {};
72657
72950
  __export(memory_exports, {
72658
72951
  memoryCommand: () => memoryCommand
72659
72952
  });
72660
- import { getProjectRoot as getProjectRoot61 } from "@cleocode/core";
72953
+ import { getProjectRoot as getProjectRoot63 } from "@cleocode/core";
72661
72954
  import {
72662
72955
  getBrainDb as getBrainDb2,
72663
72956
  getDreamStatus,
@@ -73615,7 +73908,7 @@ var init_memory3 = __esm({
73615
73908
  },
73616
73909
  args: {},
73617
73910
  async run() {
73618
- const root = getProjectRoot61();
73911
+ const root = getProjectRoot63();
73619
73912
  try {
73620
73913
  const result = await runConsolidation(root);
73621
73914
  cliOutput(result, { command: "memory-consolidate", operation: "memory.consolidate" });
@@ -73639,7 +73932,7 @@ var init_memory3 = __esm({
73639
73932
  }
73640
73933
  },
73641
73934
  async run({ args }) {
73642
- const root = getProjectRoot61();
73935
+ const root = getProjectRoot63();
73643
73936
  if (args.status) {
73644
73937
  try {
73645
73938
  const status = await getDreamStatus(root);
@@ -73676,7 +73969,7 @@ var init_memory3 = __esm({
73676
73969
  }
73677
73970
  },
73678
73971
  async run({ args }) {
73679
- const root = getProjectRoot61();
73972
+ const root = getProjectRoot63();
73680
73973
  try {
73681
73974
  const { runObserver, runReflector } = await import("@cleocode/core/memory");
73682
73975
  const observerResult = await runObserver(root, args.session, {
@@ -73716,7 +74009,7 @@ var init_memory3 = __esm({
73716
74009
  }
73717
74010
  },
73718
74011
  async run({ args }) {
73719
- const root = getProjectRoot61();
74012
+ const root = getProjectRoot63();
73720
74013
  await getBrainDb2(root);
73721
74014
  const { getBrainNativeDb: getBrainNativeDb3 } = await import("@cleocode/core/internal");
73722
74015
  const nativeDb = getBrainNativeDb3();
@@ -73754,7 +74047,7 @@ var init_memory3 = __esm({
73754
74047
  },
73755
74048
  async run({ args }) {
73756
74049
  const core2 = await import("@cleocode/core/internal");
73757
- const nexusDb = await core2.getNexusDb(getProjectRoot61());
74050
+ const nexusDb = await core2.getNexusDb(getProjectRoot63());
73758
74051
  const result = args.restore ? await core2.restorePrunedTraits(
73759
74052
  nexusDb,
73760
74053
  String(args.restore),
@@ -73784,7 +74077,7 @@ var init_memory3 = __esm({
73784
74077
  return;
73785
74078
  }
73786
74079
  const core2 = await import("@cleocode/core/internal");
73787
- const nexusDb = await core2.getNexusDb(getProjectRoot61());
74080
+ const nexusDb = await core2.getNexusDb(getProjectRoot63());
73788
74081
  const previous = await core2.setUserProfileTraitScope(nexusDb, String(args.key), scope);
73789
74082
  if (previous === null) {
73790
74083
  cliError(`No user-profile trait "${args.key}"`, "E_NOT_FOUND", { name: "E_NOT_FOUND" });
@@ -73808,7 +74101,7 @@ var init_memory3 = __esm({
73808
74101
  }
73809
74102
  },
73810
74103
  async run({ args }) {
73811
- const root = getProjectRoot61();
74104
+ const root = getProjectRoot63();
73812
74105
  try {
73813
74106
  await getBrainDb2(root);
73814
74107
  const { totalDuplicateRows, groups } = await scanDuplicateEntries();
@@ -73854,7 +74147,7 @@ var init_memory3 = __esm({
73854
74147
  async run({ args }) {
73855
74148
  const sourceDir = args.from;
73856
74149
  const isDryRun = !!args["dry-run"];
73857
- const projectRoot = getProjectRoot61();
74150
+ const projectRoot = getProjectRoot63();
73858
74151
  try {
73859
74152
  const result = await importMemoryFiles({
73860
74153
  sourceDir,
@@ -74005,7 +74298,7 @@ var init_memory3 = __esm({
74005
74298
  },
74006
74299
  args: {},
74007
74300
  async run() {
74008
- const root = getProjectRoot61();
74301
+ const root = getProjectRoot63();
74009
74302
  try {
74010
74303
  await getBrainDb2(root);
74011
74304
  const result = await getTierStats(root);
@@ -74048,7 +74341,7 @@ var init_memory3 = __esm({
74048
74341
  }
74049
74342
  },
74050
74343
  async run({ args }) {
74051
- const root = getProjectRoot61();
74344
+ const root = getProjectRoot63();
74052
74345
  const targetTier = args.to;
74053
74346
  const reason = args.reason;
74054
74347
  const validTiers = ["medium", "long"];
@@ -74114,7 +74407,7 @@ var init_memory3 = __esm({
74114
74407
  }
74115
74408
  },
74116
74409
  async run({ args }) {
74117
- const root = getProjectRoot61();
74410
+ const root = getProjectRoot63();
74118
74411
  const targetTier = args.to;
74119
74412
  const reason = args.reason;
74120
74413
  const validTiers = ["short", "medium"];
@@ -74587,7 +74880,7 @@ var migrate_claude_mem_exports = {};
74587
74880
  __export(migrate_claude_mem_exports, {
74588
74881
  migrateClaudeMemCommand: () => migrateClaudeMemCommand
74589
74882
  });
74590
- import { getProjectRoot as getProjectRoot62, migrateClaudeMem } from "@cleocode/core/internal";
74883
+ import { getProjectRoot as getProjectRoot64, migrateClaudeMem } from "@cleocode/core/internal";
74591
74884
  import { ingestLooseAgentOutputs, ingestRcasdDirectories } from "@cleocode/core/memory";
74592
74885
  import { getDb as getDb2 } from "@cleocode/core/store/sqlite";
74593
74886
  var storageCommand, claudeMemCommand, manifestIngestCommand, migrateClaudeMemCommand;
@@ -74650,7 +74943,7 @@ var init_migrate_claude_mem = __esm({
74650
74943
  }
74651
74944
  },
74652
74945
  async run({ args }) {
74653
- const root = getProjectRoot62();
74946
+ const root = getProjectRoot64();
74654
74947
  try {
74655
74948
  const result = await migrateClaudeMem(root, {
74656
74949
  sourcePath: args.source,
@@ -74699,7 +74992,7 @@ var init_migrate_claude_mem = __esm({
74699
74992
  }
74700
74993
  },
74701
74994
  async run({ args }) {
74702
- const projectRoot = getProjectRoot62();
74995
+ const projectRoot = getProjectRoot64();
74703
74996
  try {
74704
74997
  const db = await getDb2(projectRoot);
74705
74998
  const rcasdFlag = Boolean(args.rcasd);
@@ -74817,7 +75110,7 @@ __export(nexus_exports, {
74817
75110
  import { statSync as statSync2 } from "node:fs";
74818
75111
  import { appendFile as appendFile2, mkdir as mkdir5 } from "node:fs/promises";
74819
75112
  import path4 from "node:path";
74820
- import { getProjectRoot as getProjectRoot63 } from "@cleocode/core";
75113
+ import { getProjectRoot as getProjectRoot65 } from "@cleocode/core";
74821
75114
  import { getSymbolImpact } from "@cleocode/core/nexus";
74822
75115
  import { runNexusAnalysis } from "@cleocode/core/nexus/analyze-orchestrator.js";
74823
75116
  import {
@@ -74988,7 +75281,7 @@ var init_nexus3 = __esm({
74988
75281
  async run({ args }) {
74989
75282
  applyJsonFlag2(args.json);
74990
75283
  const projectIdOverride = args["project-id"];
74991
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
75284
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot65();
74992
75285
  const startTime = Date.now();
74993
75286
  if (args.path) {
74994
75287
  let isDir = false;
@@ -75048,7 +75341,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648), so the coun
75048
75341
  process.exitCode = 2 /* INVALID_INPUT */;
75049
75342
  return;
75050
75343
  }
75051
- const currentRoot = getProjectRoot63();
75344
+ const currentRoot = getProjectRoot65();
75052
75345
  if (args.path && path4.resolve(repoPath) !== path4.resolve(currentRoot)) {
75053
75346
  cliError(
75054
75347
  `nexus status cannot report on '${repoPath}' from this project.
@@ -75602,7 +75895,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
75602
75895
  applyJsonFlag2(args.json);
75603
75896
  const startTime = Date.now();
75604
75897
  const projectIdOverride = args["project-id"];
75605
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
75898
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot65();
75606
75899
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
75607
75900
  const response = await dispatchRaw("query", "nexus", "clusters", { projectId, repoPath });
75608
75901
  const durationMs = Date.now() - startTime;
@@ -75646,7 +75939,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
75646
75939
  applyJsonFlag2(args.json);
75647
75940
  const startTime = Date.now();
75648
75941
  const projectIdOverride = args["project-id"];
75649
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
75942
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot65();
75650
75943
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
75651
75944
  const response = await dispatchRaw("query", "nexus", "flows", { projectId, repoPath });
75652
75945
  const durationMs = Date.now() - startTime;
@@ -75689,7 +75982,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
75689
75982
  void appendDeprecationTelemetry("nexus.context", "cleo graph context");
75690
75983
  const startTime = Date.now();
75691
75984
  const projectIdOverride = args["project-id"];
75692
- const repoPath = getProjectRoot63();
75985
+ const repoPath = getProjectRoot65();
75693
75986
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
75694
75987
  const limit = parseInt(args.limit, 10);
75695
75988
  const symbolName = args.symbol;
@@ -75752,7 +76045,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
75752
76045
  const startTime = Date.now();
75753
76046
  const whyFlag = !!args.why;
75754
76047
  const projectIdOverride = args["project-id"];
75755
- const repoPath = getProjectRoot63();
76048
+ const repoPath = getProjectRoot65();
75756
76049
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
75757
76050
  const maxDepth = Math.min(parseInt(args.depth, 10), 5);
75758
76051
  const symbolName = args.symbol;
@@ -75856,7 +76149,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
75856
76149
  const projectIdOverride = args["project-id"];
75857
76150
  const full = !!args.full;
75858
76151
  const ctx = getFormatContext();
75859
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
76152
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot65();
75860
76153
  if (args.incremental)
75861
76154
  humanWarn(
75862
76155
  "[nexus] --incremental is deprecated and has no effect: incremental is the default."
@@ -75986,7 +76279,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
75986
76279
  async run({ args }) {
75987
76280
  applyJsonFlag2(args.json);
75988
76281
  const startTime = Date.now();
75989
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
76282
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot65();
75990
76283
  const name = args.name;
75991
76284
  const response = await dispatchRaw("mutate", "nexus", "projects.register", {
75992
76285
  path: repoPath,
@@ -76505,7 +76798,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
76505
76798
  applyJsonFlag2(args.json);
76506
76799
  const startTime = Date.now();
76507
76800
  const projectIdOverride = args["project-id"];
76508
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
76801
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot65();
76509
76802
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
76510
76803
  const response = await dispatchRaw("mutate", "nexus", "refresh-bridge", {
76511
76804
  repoPath,
@@ -76611,7 +76904,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
76611
76904
  async run({ args }) {
76612
76905
  applyJsonFlag2(args.json);
76613
76906
  const startTime = Date.now();
76614
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
76907
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot65();
76615
76908
  const projectIdOverride = args["project-id"];
76616
76909
  const beforeRef = args.before ?? "HEAD~1";
76617
76910
  const afterRef = args.after ?? "HEAD";
@@ -76729,7 +77022,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
76729
77022
  applyJsonFlag2(args.json);
76730
77023
  const startTime = Date.now();
76731
77024
  const projectIdOverride = args["project-id"];
76732
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
77025
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot65();
76733
77026
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
76734
77027
  const response = await dispatchRaw("query", "nexus", "route-map", { projectId });
76735
77028
  const durationMs = Date.now() - startTime;
@@ -76785,7 +77078,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
76785
77078
  const startTime = Date.now();
76786
77079
  const routeSymbol = args.routeSymbol;
76787
77080
  const projectIdOverride = args["project-id"];
76788
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
77081
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot65();
76789
77082
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
76790
77083
  const response = await dispatchRaw("query", "nexus", "shape-check", { routeSymbol, projectId });
76791
77084
  const durationMs = Date.now() - startTime;
@@ -77181,7 +77474,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
77181
77474
  async run({ args }) {
77182
77475
  applyJsonFlag2(args.json);
77183
77476
  const startTime = Date.now();
77184
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
77477
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot65();
77185
77478
  const projectIdOverride = args["project-id"];
77186
77479
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
77187
77480
  const response = await dispatchRaw("mutate", "nexus", "contracts-sync", {
@@ -77291,7 +77584,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
77291
77584
  async run({ args }) {
77292
77585
  applyJsonFlag2(args.json);
77293
77586
  const startTime = Date.now();
77294
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
77587
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot65();
77295
77588
  const projectId = Buffer.from(repoPath).toString("base64url").slice(0, 32);
77296
77589
  const response = await dispatchRaw("mutate", "nexus", "contracts-link-tasks", {
77297
77590
  projectId,
@@ -77375,7 +77668,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
77375
77668
  const isIncremental = !!args.incremental;
77376
77669
  try {
77377
77670
  const result = await runNexusWiki({
77378
- projectRoot: getProjectRoot63(),
77671
+ projectRoot: getProjectRoot65(),
77379
77672
  outputDir,
77380
77673
  communityFilter,
77381
77674
  incremental: isIncremental
@@ -77725,7 +78018,7 @@ __export(orchestrate_exports, {
77725
78018
  });
77726
78019
  import { execFileSync as execFileSync5 } from "node:child_process";
77727
78020
  import { orchestration } from "@cleocode/core";
77728
- import { BUILD_CONFIG as BUILD_CONFIG2, getProjectRoot as getProjectRoot64 } from "@cleocode/core/internal";
78021
+ import { BUILD_CONFIG as BUILD_CONFIG2, getProjectRoot as getProjectRoot66 } from "@cleocode/core/internal";
77729
78022
  function formatRollupTable(rollup) {
77730
78023
  const waves = "waves" in rollup ? rollup.waves : [rollup];
77731
78024
  const lines = [];
@@ -77868,7 +78161,7 @@ var init_orchestrate3 = __esm({
77868
78161
  },
77869
78162
  async run({ args }) {
77870
78163
  const rateWindowHours = args.window !== void 0 ? Number.parseFloat(String(args.window)) : void 0;
77871
- const metrics = await orchestration.collectOrchestrateDashboard(getProjectRoot64(), {
78164
+ const metrics = await orchestration.collectOrchestrateDashboard(getProjectRoot66(), {
77872
78165
  ...rateWindowHours !== void 0 && Number.isFinite(rateWindowHours) && rateWindowHours > 0 ? { rateWindowHours } : {}
77873
78166
  });
77874
78167
  cliOutput(metrics, {
@@ -79328,7 +79621,7 @@ __export(project_exports, {
79328
79621
  import { resolve as resolve9 } from "node:path";
79329
79622
  import {
79330
79623
  CleoError as CleoError11,
79331
- getProjectRoot as getProjectRoot65,
79624
+ getProjectRoot as getProjectRoot67,
79332
79625
  moveProject,
79333
79626
  projectLifecycle,
79334
79627
  renameProject,
@@ -79350,7 +79643,7 @@ function emitEngineFailure(error, operation) {
79350
79643
  }
79351
79644
  function resolveRootOrFail(operation) {
79352
79645
  try {
79353
- return getProjectRoot65();
79646
+ return getProjectRoot67();
79354
79647
  } catch (err) {
79355
79648
  const code = err instanceof CleoError11 && typeof err.details?.["code"] === "string" ? err.details["code"] : "E_NOT_CLEO_PROJECT";
79356
79649
  emitEngineFailure(
@@ -80178,7 +80471,7 @@ var refresh_memory_exports = {};
80178
80471
  __export(refresh_memory_exports, {
80179
80472
  refreshMemoryCommand: () => refreshMemoryCommand
80180
80473
  });
80181
- import { getProjectRoot as getProjectRoot66 } from "@cleocode/core";
80474
+ import { getProjectRoot as getProjectRoot68 } from "@cleocode/core";
80182
80475
  var refreshMemoryCommand;
80183
80476
  var init_refresh_memory = __esm({
80184
80477
  "packages/cleo/src/cli/commands/refresh-memory.ts"() {
@@ -80191,7 +80484,7 @@ var init_refresh_memory = __esm({
80191
80484
  description: "Regenerate .cleo/memory-bridge.md from brain.db"
80192
80485
  },
80193
80486
  async run() {
80194
- const projectDir = getProjectRoot66();
80487
+ const projectDir = getProjectRoot68();
80195
80488
  const { writeMemoryBridge } = await import("@cleocode/core/internal");
80196
80489
  const result = await writeMemoryBridge(projectDir);
80197
80490
  if (result.written) {
@@ -81777,7 +82070,7 @@ import fs3 from "node:fs";
81777
82070
  import path5 from "node:path";
81778
82071
  import {
81779
82072
  CleoError as CleoError13,
81780
- getProjectRoot as getProjectRoot67,
82073
+ getProjectRoot as getProjectRoot69,
81781
82074
  getTaskAccessor as getTaskAccessor3,
81782
82075
  parseConflictReport,
81783
82076
  setAtPath
@@ -81798,7 +82091,7 @@ var init_restore = __esm({
81798
82091
  description: "Apply manually-resolved conflicts from .cleo/restore-conflicts.md"
81799
82092
  },
81800
82093
  async run() {
81801
- const projectRoot = getProjectRoot67();
82094
+ const projectRoot = getProjectRoot69();
81802
82095
  const reportPath = path5.join(projectRoot, CLEO_DIR_NAME3, RESTORE_CONFLICTS_MD);
81803
82096
  if (!fs3.existsSync(reportPath)) {
81804
82097
  humanLine("No pending restore conflicts. Nothing to finalize.");
@@ -82727,8 +83020,8 @@ var init_saga = __esm({
82727
83020
  }
82728
83021
  },
82729
83022
  async run({ args }) {
82730
- const { sagas: sagas2, getProjectRoot: getProjectRoot73 } = await import("@cleocode/core");
82731
- const projectRoot = getProjectRoot73();
83023
+ const { sagas: sagas2, getProjectRoot: getProjectRoot75 } = await import("@cleocode/core");
83024
+ const projectRoot = getProjectRoot75();
82732
83025
  const sagaId = typeof args.sagaId === "string" && args.sagaId.length > 0 ? args.sagaId : void 0;
82733
83026
  const result = await sagas2.sagaNext(projectRoot, { sagaId });
82734
83027
  cliOutput(result.success ? result.data : result, { command: "saga", operation: "saga.next" });
@@ -84559,7 +84852,7 @@ var sequence_exports = {};
84559
84852
  __export(sequence_exports, {
84560
84853
  sequenceCommand: () => sequenceCommand
84561
84854
  });
84562
- import { getProjectRoot as getProjectRoot68 } from "@cleocode/core/internal";
84855
+ import { getProjectRoot as getProjectRoot70 } from "@cleocode/core/internal";
84563
84856
  var showCommand12, checkCommand7, repairCommand3, sequenceCommand;
84564
84857
  var init_sequence = __esm({
84565
84858
  "packages/cleo/src/cli/commands/sequence.ts"() {
@@ -84595,7 +84888,7 @@ var init_sequence = __esm({
84595
84888
  meta: { name: "repair", description: "Reset counter to max + 1 if behind" },
84596
84889
  async run() {
84597
84890
  const { repairSequence } = await import("@cleocode/core/internal");
84598
- const projectRoot = getProjectRoot68();
84891
+ const projectRoot = getProjectRoot70();
84599
84892
  const repair = await repairSequence(projectRoot);
84600
84893
  const result = {
84601
84894
  repaired: repair.repaired,
@@ -85192,8 +85485,8 @@ var init_session4 = __esm({
85192
85485
  "audit-scope": { type: "string", description: "Audit log scope (global|local)" }
85193
85486
  },
85194
85487
  async run({ args }) {
85195
- const { detectSessionDrift, getProjectRoot: getProjectRoot73 } = await import("@cleocode/core");
85196
- const projectRoot = await getProjectRoot73();
85488
+ const { detectSessionDrift, getProjectRoot: getProjectRoot75 } = await import("@cleocode/core");
85489
+ const projectRoot = await getProjectRoot75();
85197
85490
  const scope = args["audit-scope"] === "local" ? "local" : "global";
85198
85491
  const report = await detectSessionDrift({ projectRoot, auditScope: scope });
85199
85492
  cliOutput(report, { command: "session drift", operation: "session.drift" });
@@ -87894,13 +88187,13 @@ var init_telemetry2 = __esm({
87894
88187
  // packages/cleo/src/cli/commands/templates/lib.ts
87895
88188
  import { readFileSync as readFileSync13 } from "node:fs";
87896
88189
  import { isAbsolute as isAbsolute3, resolve as resolve10 } from "node:path";
87897
- import { getProjectRoot as getProjectRoot69 } from "@cleocode/core";
88190
+ import { getProjectRoot as getProjectRoot71 } from "@cleocode/core";
87898
88191
  import { resolveSourcePathAbsolute } from "@cleocode/core/templates/registry";
87899
88192
  function resolveProjectRoot6(raw) {
87900
88193
  if (typeof raw === "string" && raw.length > 0) {
87901
88194
  return isAbsolute3(raw) ? raw : resolve10(process.cwd(), raw);
87902
88195
  }
87903
- return getProjectRoot69();
88196
+ return getProjectRoot71();
87904
88197
  }
87905
88198
  function readTemplateSource(entry) {
87906
88199
  const sourceAbsolute = resolveSourcePathAbsolute(entry);
@@ -88684,7 +88977,7 @@ __export(token_exports, {
88684
88977
  tokenCommand: () => tokenCommand
88685
88978
  });
88686
88979
  import { readFileSync as readFileSync17 } from "node:fs";
88687
- import { getProjectRoot as getProjectRoot70, measureTokenExchange, recordTokenExchange as recordTokenExchange2 } from "@cleocode/core/internal";
88980
+ import { getProjectRoot as getProjectRoot72, measureTokenExchange, recordTokenExchange as recordTokenExchange2 } from "@cleocode/core/internal";
88688
88981
  function readPayload(args, textKey, fileKey) {
88689
88982
  const text = args[textKey];
88690
88983
  const file = args[fileKey];
@@ -88848,7 +89141,7 @@ var init_token = __esm({
88848
89141
  domain: args.domain,
88849
89142
  operation: args.operation
88850
89143
  };
88851
- const result = args.record ? await recordTokenExchange2(getProjectRoot70(), input2) : await measureTokenExchange(input2);
89144
+ const result = args.record ? await recordTokenExchange2(getProjectRoot72(), input2) : await measureTokenExchange(input2);
88852
89145
  cliOutput(result, {
88853
89146
  command: "token",
88854
89147
  operation: args.record ? "admin.token.record" : "token.estimate"
@@ -88884,7 +89177,7 @@ __export(transcript_exports, {
88884
89177
  });
88885
89178
  import { homedir as homedir3 } from "node:os";
88886
89179
  import { join as join35 } from "node:path";
88887
- import { getProjectRoot as getProjectRoot71 } from "@cleocode/core";
89180
+ import { getProjectRoot as getProjectRoot73 } from "@cleocode/core";
88888
89181
  import {
88889
89182
  parseDurationMs,
88890
89183
  pruneTranscripts,
@@ -88914,7 +89207,7 @@ var init_transcript = __esm({
88914
89207
  async run({ args }) {
88915
89208
  if (args.pending) {
88916
89209
  try {
88917
- const projectRoot = getProjectRoot71();
89210
+ const projectRoot = getProjectRoot73();
88918
89211
  const { scanPendingTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
88919
89212
  const pending = await scanPendingTranscripts(projectRoot);
88920
89213
  cliOutput(
@@ -89011,7 +89304,7 @@ var init_transcript = __esm({
89011
89304
  async run({ args }) {
89012
89305
  const tier = args.tier ?? "warm";
89013
89306
  const dryRun = args["dry-run"] ?? false;
89014
- const projectRoot = getProjectRoot71();
89307
+ const projectRoot = getProjectRoot73();
89015
89308
  try {
89016
89309
  const { extractTranscript } = await import("@cleocode/core/memory/transcript-extractor.js");
89017
89310
  const { findSessionTranscriptPath, listAllTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
@@ -89127,7 +89420,7 @@ var init_transcript = __esm({
89127
89420
  const dryRun = args["dry-run"] ?? false;
89128
89421
  const olderThanHours = args["older-than-hours"] ? Number.parseInt(args["older-than-hours"], 10) : 24;
89129
89422
  const limit = args.limit ? Number.parseInt(args.limit, 10) : void 0;
89130
- const projectRoot = getProjectRoot71();
89423
+ const projectRoot = getProjectRoot73();
89131
89424
  try {
89132
89425
  const { extractTranscript } = await import("@cleocode/core/memory/transcript-extractor.js");
89133
89426
  const { listAllTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
@@ -91065,9 +91358,9 @@ var init_verify = __esm({
91065
91358
  return;
91066
91359
  }
91067
91360
  const { recordTaskDone } = await import("@cleocode/core/tasks/done-record.js");
91068
- const { getProjectRoot: getProjectRoot73 } = await import("@cleocode/core/paths.js");
91361
+ const { getProjectRoot: getProjectRoot75 } = await import("@cleocode/core/paths.js");
91069
91362
  const r = await recordTaskDone(args.taskId, {
91070
- projectRoot: getProjectRoot73(),
91363
+ projectRoot: getProjectRoot75(),
91071
91364
  ...parsed.options,
91072
91365
  ...args.agent ? { agent: args.agent } : {}
91073
91366
  });
@@ -91490,9 +91783,9 @@ var init_workgraph2 = __esm({
91490
91783
  },
91491
91784
  async run({ args }) {
91492
91785
  const { generatePlanningDoc } = await import("@cleocode/core/workgraph");
91493
- const { getProjectRoot: getProjectRoot73 } = await import("@cleocode/core");
91786
+ const { getProjectRoot: getProjectRoot75 } = await import("@cleocode/core");
91494
91787
  const { cliOutput: cliOutput2 } = await Promise.resolve().then(() => (init_renderers(), renderers_exports));
91495
- const projectRoot = getProjectRoot73();
91788
+ const projectRoot = getProjectRoot75();
91496
91789
  const audience = String(args.audience) === "agent" ? "agent" : "maintainer";
91497
91790
  const result = await generatePlanningDoc(projectRoot, {
91498
91791
  sagaId: String(args.sagaId),
@@ -91509,9 +91802,9 @@ var init_workgraph2 = __esm({
91509
91802
  async run() {
91510
91803
  const { validateWorkGraphStructure } = await import("@cleocode/core/workgraph");
91511
91804
  const { taskList: taskList2 } = await import("@cleocode/core/internal");
91512
- const { getProjectRoot: getProjectRoot73 } = await import("@cleocode/core");
91805
+ const { getProjectRoot: getProjectRoot75 } = await import("@cleocode/core");
91513
91806
  const { cliOutput: cliOutput2 } = await Promise.resolve().then(() => (init_renderers(), renderers_exports));
91514
- const projectRoot = getProjectRoot73();
91807
+ const projectRoot = getProjectRoot75();
91515
91808
  const listResult = await taskList2(projectRoot, { limit: 5e3 });
91516
91809
  const tasks = listResult.success ? listResult.data?.tasks ?? [] : [];
91517
91810
  const nodes = tasks.map((t) => ({
@@ -91530,9 +91823,9 @@ var init_workgraph2 = __esm({
91530
91823
  description: "One-shot saga-to-saga workgraph dashboard (tracking checklist)"
91531
91824
  },
91532
91825
  async run() {
91533
- const { sagas: sagas2, getProjectRoot: getProjectRoot73 } = await import("@cleocode/core");
91826
+ const { sagas: sagas2, getProjectRoot: getProjectRoot75 } = await import("@cleocode/core");
91534
91827
  const { cliOutput: cliOutput2 } = await Promise.resolve().then(() => (init_renderers(), renderers_exports));
91535
- const projectRoot = getProjectRoot73();
91828
+ const projectRoot = getProjectRoot75();
91536
91829
  const listResult = await sagas2.sagaList(projectRoot);
91537
91830
  if (!listResult.success) {
91538
91831
  cliOutput2(listResult, { command: "workgraph", operation: "workgraph.status" });
@@ -91598,7 +91891,7 @@ __export(worktree_exports, {
91598
91891
  worktreeCommand: () => worktreeCommand
91599
91892
  });
91600
91893
  import readline4 from "node:readline";
91601
- import { getProjectRoot as getProjectRoot72, listWorktrees as listWorktrees2 } from "@cleocode/core/internal";
91894
+ import { getProjectRoot as getProjectRoot74, listWorktrees as listWorktrees2 } from "@cleocode/core/internal";
91602
91895
  async function promptYesNo2(question) {
91603
91896
  return new Promise((resolve13) => {
91604
91897
  const rl = readline4.createInterface({ input: process.stdin, output: process.stdout });
@@ -91703,7 +91996,7 @@ var init_worktree3 = __esm({
91703
91996
  const staleDays = staleDaysRaw !== void 0 ? Number.parseInt(staleDaysRaw, 10) : void 0;
91704
91997
  const idleDaysRaw = typeof args["idle-days"] === "string" ? args["idle-days"] : void 0;
91705
91998
  const idleDays = idleDaysRaw !== void 0 ? Number.parseInt(idleDaysRaw, 10) : void 0;
91706
- const projectRoot = getProjectRoot72();
91999
+ const projectRoot = getProjectRoot74();
91707
92000
  const listResult = await listWorktrees2({
91708
92001
  projectRoot,
91709
92002
  ...staleDays !== void 0 && !Number.isNaN(staleDays) ? { staleDays } : {}
@@ -91962,6 +92255,16 @@ function cittyErrorFix(code) {
91962
92255
  return `Run 'cleo <command> --help' to see required arguments.`;
91963
92256
  }
91964
92257
 
92258
+ // packages/cleo/src/cli/cleo-error-like.ts
92259
+ function asCleoErrorLike(err) {
92260
+ if (!(err instanceof Error)) return null;
92261
+ const candidate = err;
92262
+ return typeof candidate.code === "number" && Number.isInteger(candidate.code) && typeof candidate.toLAFSError === "function" ? candidate : null;
92263
+ }
92264
+ function cleoErrorCodeName(typed) {
92265
+ return typeof typed.codeName === "string" && typed.codeName.length > 0 ? typed.codeName : typed.toLAFSError().code;
92266
+ }
92267
+
91965
92268
  // packages/cleo/src/cli/index.ts
91966
92269
  init_describe_context();
91967
92270
  init_field_context();
@@ -92287,6 +92590,12 @@ var COMMAND_MANIFEST = [
92287
92590
  description: "Canonical six-verb docs path: add, update, fetch, list, remove, publish. ",
92288
92591
  load: async () => (await Promise.resolve().then(() => (init_docs3(), docs_exports))).docsCommand
92289
92592
  },
92593
+ {
92594
+ exportName: "doctorAcBindingsCommand",
92595
+ name: "ac-bindings",
92596
+ description: "Report evidence bindings whose acceptance criterion no longer exists (dangling ",
92597
+ load: async () => (await Promise.resolve().then(() => (init_doctor_ac_bindings(), doctor_ac_bindings_exports))).doctorAcBindingsCommand
92598
+ },
92290
92599
  {
92291
92600
  exportName: "doctorAcceptanceDriftCommand",
92292
92601
  name: "acceptance-drift",
@@ -92305,6 +92614,12 @@ var COMMAND_MANIFEST = [
92305
92614
  description: "Walk every DB in the inventory + report integrity, row counts, orphan dirs. ",
92306
92615
  load: async () => (await Promise.resolve().then(() => (init_doctor_db_substrate(), doctor_db_substrate_exports))).doctorDbSubstrateCommand
92307
92616
  },
92617
+ {
92618
+ exportName: "doctorDepCyclesCommand",
92619
+ name: "dep-cycles",
92620
+ description: "Report task dependency cycles already stored (edges written before the T12886 cycle ",
92621
+ load: async () => (await Promise.resolve().then(() => (init_doctor_dep_cycles(), doctor_dep_cycles_exports))).doctorDepCyclesCommand
92622
+ },
92308
92623
  {
92309
92624
  exportName: "doctorExodusResidueCommand",
92310
92625
  name: "exodus-residue",
@@ -92350,7 +92665,7 @@ var COMMAND_MANIFEST = [
92350
92665
  {
92351
92666
  exportName: "doctorManifestRowsCommand",
92352
92667
  name: "manifest-rows",
92353
- description: "List manifest rows whose metadata violates the stored field contract. --repair shows the plan (writes nothing); --repair --apply moves each bad field under _malformed (nothing lost) with a receipt; --rollback <receipt> undoes it.",
92668
+ description: "List manifest rows whose metadata violates the stored field contract, and (read-only) rows with an invalid id, linked task id or file reference. --repair shows the plan (writes nothing); --repair --apply moves each bad field under _malformed (nothing lost) with a receipt; --rollback <receipt> undoes it.",
92354
92669
  load: async () => (await Promise.resolve().then(() => (init_doctor_manifest_rows(), doctor_manifest_rows_exports))).doctorManifestRowsCommand
92355
92670
  },
92356
92671
  {
@@ -93548,11 +93863,6 @@ Valid modes: ${validModes.join(", ")}
93548
93863
  const dispatchArgv = describeFlag && !isHelpOrVersion ? [...normalizedArgv, "__cleo_describe__"] : normalizedArgv;
93549
93864
  await runMainWithLafsEnvelope(main, dispatchArgv, customShowUsage);
93550
93865
  }
93551
- function asCleoErrorLike(err) {
93552
- if (!(err instanceof Error) || err.name !== "CleoError") return null;
93553
- const candidate = err;
93554
- return typeof candidate.code === "number" && typeof candidate.toLAFSError === "function" ? candidate : null;
93555
- }
93556
93866
  function asCittyCliError(value) {
93557
93867
  if (!(value instanceof Error)) return null;
93558
93868
  if (value.name !== "CLIError") return null;
@@ -93632,7 +93942,7 @@ async function runMainWithLafsEnvelope(cmd, rawArgs, showUsage2) {
93632
93942
  const typed = asCleoErrorLike(err);
93633
93943
  if (typed) {
93634
93944
  cliError2(typed.message, typed.code, {
93635
- name: typed.toLAFSError().code,
93945
+ name: cleoErrorCodeName(typed),
93636
93946
  fix: typed.fix,
93637
93947
  alternatives: typed.alternatives,
93638
93948
  details: typed.details
@@ -93658,7 +93968,7 @@ async function runStartupMaintenance() {
93658
93968
  detectAndRemoveStrayProjectNexus,
93659
93969
  getGlobalSalt,
93660
93970
  getLogger: getLogger22,
93661
- getProjectRoot: getProjectRoot73,
93971
+ getProjectRoot: getProjectRoot75,
93662
93972
  isCleanupMarkerSet,
93663
93973
  isMissingProjectError,
93664
93974
  migrateSignaldockToConduit,
@@ -93668,7 +93978,7 @@ async function runStartupMaintenance() {
93668
93978
  } = await import("@cleocode/core/internal");
93669
93979
  let projectRootForCleanup = "";
93670
93980
  try {
93671
- projectRootForCleanup = getProjectRoot73();
93981
+ projectRootForCleanup = getProjectRoot75();
93672
93982
  } catch {
93673
93983
  }
93674
93984
  if (!isCleanupMarkerSet(CLI_VERSION, projectRootForCleanup)) {
@@ -93688,7 +93998,7 @@ async function runStartupMaintenance() {
93688
93998
  const isInitInvocation = process.argv.slice(2).some((a) => a === "init");
93689
93999
  if (!isInitInvocation) {
93690
94000
  try {
93691
- const _projectRootForMigration = getProjectRoot73();
94001
+ const _projectRootForMigration = getProjectRoot75();
93692
94002
  if (needsSignaldockToConduitMigration(_projectRootForMigration)) {
93693
94003
  const migrationResult = await migrateSignaldockToConduit(_projectRootForMigration);
93694
94004
  if (migrationResult.status === "failed") {