@cleocode/cleo 2026.9.21 → 2026.9.23

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 (79) hide show
  1. package/dist/cli/index.js +884 -233
  2. package/package.json +13 -13
  3. package/studio-dist/client/_app/immutable/chunks/CyNL2FJl.js +1 -0
  4. package/studio-dist/client/_app/immutable/chunks/{BAm68yLM.js → DJ4ceMnt.js} +1 -1
  5. package/studio-dist/client/_app/immutable/chunks/{Dm-Z-HM3.js → DlnXUEcN.js} +1 -1
  6. package/studio-dist/client/_app/immutable/chunks/{VBlPNtFM.js → VqMa-FR_.js} +1 -1
  7. package/studio-dist/client/_app/immutable/entry/{app.CAn3fZgZ.js → app.CXLixB0X.js} +2 -2
  8. package/studio-dist/client/_app/immutable/entry/start.C_VLyotS.js +1 -0
  9. package/studio-dist/client/_app/immutable/nodes/{0.DPKG0nUt.js → 0.D34GfsBr.js} +1 -1
  10. package/studio-dist/client/_app/immutable/nodes/{1.C5hwmzhS.js → 1.COzO-K-Z.js} +1 -1
  11. package/studio-dist/client/_app/immutable/nodes/{15.CkAQwL0m.js → 15.CkLwS1y2.js} +1 -1
  12. package/studio-dist/client/_app/immutable/nodes/{16.Bd_23uIv.js → 16.C2MFh329.js} +1 -1
  13. package/studio-dist/client/_app/immutable/nodes/{17.CtZyGphA.js → 17.CLdLJ6ju.js} +1 -1
  14. package/studio-dist/client/_app/immutable/nodes/{18.CIOnp98T.js → 18.ClGsX0an.js} +1 -1
  15. package/studio-dist/client/_app/immutable/nodes/{20.Ba5DRAxg.js → 20.vQtazQa0.js} +1 -1
  16. package/studio-dist/client/_app/immutable/nodes/{24.8bVX9Vmh.js → 24.DLwR4-7S.js} +1 -1
  17. package/studio-dist/client/_app/immutable/nodes/25.DUuYls4x.js +39 -0
  18. package/studio-dist/client/_app/immutable/nodes/{26.fZumF6nO.js → 26.BZ-Sb3tl.js} +1 -1
  19. package/studio-dist/client/_app/immutable/nodes/{3.pmT0DBeN.js → 3.CYwLXdQ4.js} +1 -1
  20. package/studio-dist/client/_app/version.json +1 -1
  21. package/studio-dist/server/chunks/{0-BM8t6VtI.js → 0-BlM3YDpC.js} +3 -3
  22. package/studio-dist/server/chunks/1-DROdkBtZ.js +9 -0
  23. package/studio-dist/server/chunks/{15-CFHLKUmW.js → 15-D4Y9me2S.js} +3 -3
  24. package/studio-dist/server/chunks/{16-tfoYc0dp.js → 16-BNVAfz5X.js} +3 -3
  25. package/studio-dist/server/chunks/{17-C_IrYgVa.js → 17-ByJg8VAI.js} +5 -4
  26. package/studio-dist/server/chunks/{18-BN7k6H6T.js → 18-mcGKywiH.js} +3 -3
  27. package/studio-dist/server/chunks/{2-DXSVVaej.js → 2-DQaIET_o.js} +3 -2
  28. package/studio-dist/server/chunks/{20-zMbfOrDH.js → 20-D4RXMRdA.js} +3 -3
  29. package/studio-dist/server/chunks/{23-CZpFrGp4.js → 23-D2H9OSJf.js} +4 -3
  30. package/studio-dist/server/chunks/{24-CeL43Zy5.js → 24-BZesRs_l.js} +6 -5
  31. package/studio-dist/server/chunks/{25-x4Xarpc5.js → 25-BPtkcHWk.js} +7 -6
  32. package/studio-dist/server/chunks/{26-BtHN2PS0.js → 26-D7qW4CZ3.js} +5 -4
  33. package/studio-dist/server/chunks/{29-6pjLM0Z1.js → 29-d_lZvJg3.js} +3 -2
  34. package/studio-dist/server/chunks/{3-CtS2Tb9q.js → 3-Csrn9tNa.js} +3 -3
  35. package/studio-dist/server/chunks/{30-Dw317sSW.js → 30-BHsj4oeh.js} +3 -2
  36. package/studio-dist/server/chunks/{_layout.svelte-CvTfh8wi.js → _layout.svelte-DtqTR50-.js} +4 -4
  37. package/studio-dist/server/chunks/{_page.svelte-BmmYIPYK.js → _page.svelte-BkrxW4NS.js} +3 -3
  38. package/studio-dist/server/chunks/{_page.svelte-C_tWaWK8.js → _page.svelte-BlDOqWK_.js} +3 -3
  39. package/studio-dist/server/chunks/{_page.svelte-C9sPd8Bb.js → _page.svelte-C9lhMoUX.js} +5 -5
  40. package/studio-dist/server/chunks/{_page.svelte-CCvfJcoQ.js → _page.svelte-Ce2_fPzl.js} +4 -4
  41. package/studio-dist/server/chunks/{_page.svelte-B5rNNTgb.js → _page.svelte-CyGNoYGs.js} +3 -3
  42. package/studio-dist/server/chunks/{_page.svelte-DdSAHPFQ.js → _page.svelte-DESqb1iT.js} +3 -3
  43. package/studio-dist/server/chunks/{_page.svelte-D6Dzqvn1.js → _page.svelte-DTqKOclg.js} +3 -3
  44. package/studio-dist/server/chunks/{_page.svelte-BXtuVcSb.js → _page.svelte-Dj05GrDh.js} +3 -3
  45. package/studio-dist/server/chunks/{_page.svelte-DRNt1JOo.js → _page.svelte-DxctlP-t.js} +3 -3
  46. package/studio-dist/server/chunks/{_server.ts-DQiTiY3E.js → _server.ts-6A72NyG7.js} +3 -2
  47. package/studio-dist/server/chunks/{_server.ts-Js54BBh9.js → _server.ts-B23PRUg6.js} +5 -4
  48. package/studio-dist/server/chunks/{_server.ts--2m_U4SL.js → _server.ts-BCPpAOST.js} +3 -2
  49. package/studio-dist/server/chunks/{_server.ts-C6IDM_3I.js → _server.ts-BKZlM7rp.js} +3 -2
  50. package/studio-dist/server/chunks/{_server.ts-DUl6nxe3.js → _server.ts-BLEs7rDo.js} +5 -4
  51. package/studio-dist/server/chunks/{_server.ts-eLwAnREE.js → _server.ts-BPzV5a4O.js} +3 -3
  52. package/studio-dist/server/chunks/{_server.ts-J17j25VG.js → _server.ts-BRoSUvbn.js} +3 -2
  53. package/studio-dist/server/chunks/{_server.ts-Bl9tMqwZ.js → _server.ts-Bhp29rqm.js} +4 -1
  54. package/studio-dist/server/chunks/{_server.ts--sGLmBsz.js → _server.ts-Br_GCegg.js} +3 -2
  55. package/studio-dist/server/chunks/{_server.ts-DTjKmh4V.js → _server.ts-BtgcmXG8.js} +4 -3
  56. package/studio-dist/server/chunks/{_server.ts-DKFJdXPK.js → _server.ts-CFb-INiV.js} +4 -3
  57. package/studio-dist/server/chunks/{_server.ts-3LzqLzt0.js → _server.ts-CcQ0AQoo.js} +3 -2
  58. package/studio-dist/server/chunks/{_server.ts-BA8Xdegq.js → _server.ts-CqO357sV.js} +3 -2
  59. package/studio-dist/server/chunks/{_server.ts-BfTazvMM.js → _server.ts-D9JYb9Nh.js} +3 -3
  60. package/studio-dist/server/chunks/{_server.ts-CeQolQOK.js → _server.ts-DAJiZh2M.js} +3 -2
  61. package/studio-dist/server/chunks/{_server.ts-C2nYqbd9.js → _server.ts-DJALLGi_.js} +3 -2
  62. package/studio-dist/server/chunks/{_server.ts-C8Z32vuL.js → _server.ts-DQ7VnW5Q.js} +3 -2
  63. package/studio-dist/server/chunks/{_server.ts-DUyeSXbV.js → _server.ts-O5iKqt5Z.js} +3 -2
  64. package/studio-dist/server/chunks/{_server.ts-D6wP5bCh.js → _server.ts-OPrTc7WI.js} +3 -2
  65. package/studio-dist/server/chunks/{client-LLdiye3o.js → client-D4Rhd5ed.js} +2 -2
  66. package/studio-dist/server/chunks/{connections-CWLPjwBP.js → connections-CAJ4ZeCq.js} +3 -2
  67. package/studio-dist/server/chunks/{connections2-DHVs5ytW.js → connections2-DyYEcX2h.js} +6 -1
  68. package/studio-dist/server/chunks/{dist-BvU7NTCZ.js → dist-DafBXQH9.js} +78 -8
  69. package/studio-dist/server/chunks/{error.svelte-Vdi9HF4O.js → error.svelte-BLd3ZRbJ.js} +3 -3
  70. package/studio-dist/server/chunks/{explorer-loader-B_uCSs9_.js → explorer-loader-CP09K03H.js} +2 -2
  71. package/studio-dist/server/chunks/{http-j9xEUElI.js → http-C-8-8Oq_.js} +2 -2
  72. package/studio-dist/server/chunks/{internal-D5m7h-oY.js → internal-DxboZxyS.js} +2 -2
  73. package/studio-dist/server/chunks/{stores-rkKr99O6.js → stores-DFVE4LvP.js} +2 -2
  74. package/studio-dist/server/index.js +1 -1
  75. package/studio-dist/server/manifest.js +35 -35
  76. package/studio-dist/client/_app/immutable/chunks/B0moCQFp.js +0 -1
  77. package/studio-dist/client/_app/immutable/entry/start.DxHadWyO.js +0 -1
  78. package/studio-dist/client/_app/immutable/nodes/25.bGZTIjlV.js +0 -39
  79. package/studio-dist/server/chunks/1-CdIGyFBZ.js +0 -9
package/dist/cli/index.js CHANGED
@@ -1815,7 +1815,7 @@ var init_acceptance_gate_schema = __esm({
1815
1815
  message: "Result cannot precede input capture"
1816
1816
  });
1817
1817
  const executable = ["test", "command", "lint"].includes(result.kind);
1818
- if (executable && !binding.invocation)
1818
+ if (executable && !binding.invocation && result.result !== "error")
1819
1819
  context.addIssue({
1820
1820
  code: "custom",
1821
1821
  path: ["binding", "invocation"],
@@ -6330,12 +6330,21 @@ var init_operations_registry = __esm({
6330
6330
  gateway: "query",
6331
6331
  domain: "tasks",
6332
6332
  operation: "history",
6333
- description: "Show task work history (time tracked per task)",
6333
+ description: "Show task work history; with taskId, the task audit trail; with ranking, who changed its priority/severity/kind/depends and why (T12693)",
6334
6334
  tier: 1,
6335
6335
  idempotent: true,
6336
6336
  sessionRequired: false,
6337
6337
  requiredParams: [],
6338
- params: []
6338
+ params: [
6339
+ { name: "taskId", type: "string", required: false, description: "Task to show history for" },
6340
+ { name: "limit", type: "number", required: false, description: "Maximum entries" },
6341
+ {
6342
+ name: "ranking",
6343
+ type: "boolean",
6344
+ required: false,
6345
+ description: "Only ranking-input changes (actor, session, reason, before/after)"
6346
+ }
6347
+ ]
6339
6348
  },
6340
6349
  {
6341
6350
  gateway: "query",
@@ -8830,6 +8839,32 @@ var init_operations_registry = __esm({
8830
8839
  ],
8831
8840
  outputSchema: OUTPUT_CONTRACTS["tasks.assignee"]
8832
8841
  },
8842
+ {
8843
+ gateway: "mutate",
8844
+ domain: "tasks",
8845
+ operation: "ranking.revert",
8846
+ description: "tasks.ranking.revert (mutate) \u2014 undo one recorded ranking change (priority/severity/kind/depends) as a new audited change (T12693, D11161)",
8847
+ tier: 1,
8848
+ idempotent: false,
8849
+ sessionRequired: false,
8850
+ requiredParams: ["entryId"],
8851
+ params: [
8852
+ {
8853
+ name: "entryId",
8854
+ type: "string",
8855
+ required: true,
8856
+ description: "ranking_changed audit row id (cleo history ranking <taskId>)",
8857
+ cli: { positional: true }
8858
+ },
8859
+ { name: "reason", type: "string", required: false, description: "Why it is reverted" },
8860
+ {
8861
+ name: "force",
8862
+ type: "boolean",
8863
+ required: false,
8864
+ description: "Revert even though a field changed again since"
8865
+ }
8866
+ ]
8867
+ },
8833
8868
  {
8834
8869
  gateway: "mutate",
8835
8870
  domain: "tasks",
@@ -13753,7 +13788,7 @@ var init_operations_registry = __esm({
13753
13788
  type: "string",
13754
13789
  required: false,
13755
13790
  enum: DOCS_LIFECYCLE_STATUSES,
13756
- description: `Override the new lifecycle status. Defaults to "draft" on every update. Valid: ${DOCS_LIFECYCLE_STATUSES.join("|")}.`
13791
+ description: `Override the new lifecycle status. Defaults to "draft" on every update. Alone (no file or content) it changes only the lifecycle status. Valid: ${DOCS_LIFECYCLE_STATUSES.join("|")}.`
13757
13792
  },
13758
13793
  {
13759
13794
  name: "dryRun",
@@ -16545,6 +16580,14 @@ function validateEvidenceForGate(gate, atoms) {
16545
16580
  hint: formatGateRequirementHint(gate)
16546
16581
  };
16547
16582
  }
16583
+ function parsePrReference(payload) {
16584
+ const match = /^(\d+)(?:@(\d+))?$/.exec(payload);
16585
+ if (!match) return null;
16586
+ const first = Number(match[1]);
16587
+ const second = match[2] === void 0 ? null : Number(match[2]);
16588
+ if (first <= 0 || second !== null && (second <= 0 || second === first)) return null;
16589
+ return second === null ? { prNumber: first } : { prNumber: second, componentPrNumber: first };
16590
+ }
16548
16591
  function parseEvidenceString(raw) {
16549
16592
  if (!raw || typeof raw !== "string") {
16550
16593
  throw new EvidenceParseError(
@@ -16603,26 +16646,16 @@ function parseEvidenceString(raw) {
16603
16646
  atoms.push({ kind: "decision", decisionId: payload });
16604
16647
  break;
16605
16648
  }
16606
- case "pr": {
16607
- const prNumber = Number(payload);
16608
- if (!Number.isInteger(prNumber) || prNumber <= 0) {
16609
- throw new EvidenceParseError(
16610
- `pr atom requires a positive integer PR number, got "${payload}" in "${chunk}"`,
16611
- "Use format: pr:<number> e.g. pr:357"
16612
- );
16613
- }
16614
- atoms.push({ kind: "pr", prNumber });
16615
- break;
16616
- }
16649
+ case "pr":
16617
16650
  case "ci": {
16618
- const prNumber = Number(payload);
16619
- if (!Number.isInteger(prNumber) || prNumber <= 0) {
16651
+ const ref = parsePrReference(payload);
16652
+ if (!ref) {
16620
16653
  throw new EvidenceParseError(
16621
- `ci atom requires a positive integer PR number, got "${payload}" in "${chunk}"`,
16622
- "Use format: ci:<number> e.g. ci:357"
16654
+ `${kind} atom requires a positive integer PR number, got "${payload}" in "${chunk}"`,
16655
+ `Use format: ${kind}:<number> e.g. ${kind}:357, or ${kind}:<component>@<integration> e.g. ${kind}:356@357`
16623
16656
  );
16624
16657
  }
16625
- atoms.push({ kind: "ci", prNumber });
16658
+ atoms.push(kind === "pr" ? { kind: "pr", ...ref } : { kind: "ci", ...ref });
16626
16659
  break;
16627
16660
  }
16628
16661
  case "loc-drop": {
@@ -16811,11 +16844,13 @@ var init_evidence_atom_schema = __esm({
16811
16844
  });
16812
16845
  prAtomSchema = z10.object({
16813
16846
  kind: z10.literal("pr"),
16814
- prNumber: z10.number().int().positive("pr atom requires a positive integer PR number")
16847
+ prNumber: z10.number().int().positive("pr atom requires a positive integer PR number"),
16848
+ componentPrNumber: z10.number().int().positive().optional()
16815
16849
  });
16816
16850
  ciAtomSchema = z10.object({
16817
16851
  kind: z10.literal("ci"),
16818
- prNumber: z10.number().int().positive("ci atom requires a positive integer PR number")
16852
+ prNumber: z10.number().int().positive("ci atom requires a positive integer PR number"),
16853
+ componentPrNumber: z10.number().int().positive().optional()
16819
16854
  });
16820
16855
  locDropAtomSchema = z10.object({
16821
16856
  kind: z10.literal("loc-drop"),
@@ -16866,7 +16901,10 @@ var init_evidence_atom_schema = __esm({
16866
16901
  ["commit", "note"],
16867
16902
  ["decision", "files"],
16868
16903
  ["decision", "note"],
16869
- ["pr", "files"]
16904
+ ["pr", "files"],
16905
+ // T12689: a deletion-only PR (no bytes to hash). Contextual validation
16906
+ // accepts this only when every change the PR made is a deletion.
16907
+ ["pr", "note"]
16870
16908
  ]
16871
16909
  },
16872
16910
  testsPassed: { oneOf: [["test-run"], ["tool"], ["ci"]] },
@@ -22280,7 +22318,7 @@ var init_collection_keys = __esm({
22280
22318
 
22281
22319
  // packages/contracts/src/decide.ts
22282
22320
  import { z as z24 } from "zod";
22283
- var DECISION_QUESTION_TYPES, DECISION_OUTCOME_SOURCES, DECISION_REQUEST_LIMITS, decisionQuestionTypeSchema, decisionOutcomeSourceSchema, decisionInstructionsSchema, unitIntervalSchema, decisionStateSchema, noulDecisionQuestionSchema, choiceDecisionQuestionSchema, scoreDecisionQuestionSchema, decisionQuestionSchema, decisionRequestSchema, noulDecisionAnswerSchema, choiceDecisionAnswerSchema, scoreDecisionAnswerSchema, decisionAnswerSchema, decisionOutcomeSchema, decisionProviderConfigSchema;
22321
+ var DECISION_QUESTION_TYPES, DECISION_OUTCOME_SOURCES, DECISION_REQUEST_LIMITS, DECISION_PROVIDER_KINDS, LAYAHOST_BASE_URL, LAYAHOST_DEFAULT_MODEL, JEV_MINIMUM_CAPABILITIES, decisionQuestionTypeSchema, decisionOutcomeSourceSchema, decisionInstructionsSchema, unitIntervalSchema, decisionStateSchema, noulDecisionQuestionSchema, choiceDecisionQuestionSchema, scoreDecisionQuestionSchema, decisionQuestionSchema, decisionRequestSchema, noulDecisionAnswerSchema, choiceDecisionAnswerSchema, scoreDecisionAnswerSchema, decisionAnswerSchema, decisionOutcomeSchema, decisionProviderKindSchema, decisionProviderConfigSchema;
22284
22322
  var init_decide = __esm({
22285
22323
  "packages/contracts/src/decide.ts"() {
22286
22324
  "use strict";
@@ -22304,6 +22342,15 @@ var init_decide = __esm({
22304
22342
  /** Maximum number of levels on a `score` question's scale. */
22305
22343
  maxScoreLevels: 10
22306
22344
  };
22345
+ DECISION_PROVIDER_KINDS = ["layahost", "jev"];
22346
+ LAYAHOST_BASE_URL = "https://layahost.com";
22347
+ LAYAHOST_DEFAULT_MODEL = "laya-auto";
22348
+ JEV_MINIMUM_CAPABILITIES = {
22349
+ wire: "jev-systemone/1",
22350
+ maxQuestionsPerRequest: 32,
22351
+ maxStateChars: 32e3,
22352
+ reportsCost: "usd"
22353
+ };
22307
22354
  decisionQuestionTypeSchema = z24.enum(DECISION_QUESTION_TYPES);
22308
22355
  decisionOutcomeSourceSchema = z24.enum(DECISION_OUTCOME_SOURCES);
22309
22356
  decisionInstructionsSchema = z24.union([z24.string(), z24.record(z24.string(), z24.json())]);
@@ -22341,6 +22388,8 @@ var init_decide = __esm({
22341
22388
  ]);
22342
22389
  decisionRequestSchema = z24.object({
22343
22390
  model: z24.string().min(1).optional(),
22391
+ lang: z24.string().regex(/^[a-z]{2,3}(-[A-Za-z0-9]{2,8})?$/).optional(),
22392
+ cache: z24.boolean().optional(),
22344
22393
  state: decisionStateSchema,
22345
22394
  questions: z24.record(z24.string().min(1), decisionQuestionSchema).refine(
22346
22395
  (questions) => {
@@ -22381,14 +22430,29 @@ var init_decide = __esm({
22381
22430
  requestId: z24.string().min(1).optional(),
22382
22431
  latencyMs: z24.number().nonnegative(),
22383
22432
  costUsd: z24.number().nonnegative().optional(),
22433
+ costMicros: z24.number().int().nonnegative().optional(),
22434
+ balanceMicros: z24.number().int().optional(),
22435
+ checkpoint: z24.string().min(1).optional(),
22384
22436
  inputTokens: z24.number().int().nonnegative().optional()
22385
22437
  });
22438
+ decisionProviderKindSchema = z24.enum(DECISION_PROVIDER_KINDS);
22386
22439
  decisionProviderConfigSchema = z24.object({
22387
- baseUrl: z24.url()
22440
+ baseUrl: z24.url(),
22441
+ provider: decisionProviderKindSchema.optional()
22388
22442
  });
22389
22443
  }
22390
22444
  });
22391
22445
 
22446
+ // packages/contracts/src/decide-sites.ts
22447
+ var DECISION_RUNGS, DECISION_SITE_MODES;
22448
+ var init_decide_sites = __esm({
22449
+ "packages/contracts/src/decide-sites.ts"() {
22450
+ "use strict";
22451
+ DECISION_RUNGS = ["rule", "system-one", "generative", "agent", "owner"];
22452
+ DECISION_SITE_MODES = ["off", "shadow", "on"];
22453
+ }
22454
+ });
22455
+
22392
22456
  // packages/contracts/src/task-id.ts
22393
22457
  function isTaskId(value) {
22394
22458
  return typeof value === "string" && TASK_ID_REGEX.test(value);
@@ -22468,8 +22532,11 @@ __export(src_exports, {
22468
22532
  DAEMON_IPC_PROTOCOL_VERSION: () => SUPERVISOR_IPC_PROTOCOL_VERSION,
22469
22533
  DB_INVENTORY: () => DB_INVENTORY,
22470
22534
  DECISION_OUTCOME_SOURCES: () => DECISION_OUTCOME_SOURCES,
22535
+ DECISION_PROVIDER_KINDS: () => DECISION_PROVIDER_KINDS,
22471
22536
  DECISION_QUESTION_TYPES: () => DECISION_QUESTION_TYPES,
22472
22537
  DECISION_REQUEST_LIMITS: () => DECISION_REQUEST_LIMITS,
22538
+ DECISION_RUNGS: () => DECISION_RUNGS,
22539
+ DECISION_SITE_MODES: () => DECISION_SITE_MODES,
22473
22540
  DEFAULT_IDENTITY_FIELD: () => DEFAULT_IDENTITY_FIELD,
22474
22541
  DEFAULT_RESOURCE_RETRY_AFTER_MS: () => DEFAULT_RESOURCE_RETRY_AFTER_MS,
22475
22542
  DOCS_LIFECYCLE_STATUSES: () => DOCS_LIFECYCLE_STATUSES,
@@ -22527,7 +22594,10 @@ __export(src_exports, {
22527
22594
  INVARIANTS_REGISTRY: () => INVARIANTS_REGISTRY,
22528
22595
  ISOLATION_ENV_KEYS: () => ISOLATION_ENV_KEYS,
22529
22596
  ImpactSchema: () => ImpactSchema,
22597
+ JEV_MINIMUM_CAPABILITIES: () => JEV_MINIMUM_CAPABILITIES,
22530
22598
  KIND_LIFECYCLE_REQUIREMENTS: () => KIND_LIFECYCLE_REQUIREMENTS,
22599
+ LAYAHOST_BASE_URL: () => LAYAHOST_BASE_URL,
22600
+ LAYAHOST_DEFAULT_MODEL: () => LAYAHOST_DEFAULT_MODEL,
22531
22601
  LEASE_IPC_MESSAGE_KINDS: () => LEASE_IPC_MESSAGE_KINDS,
22532
22602
  LEASE_IPC_PROTOCOL_VERSION: () => LEASE_IPC_PROTOCOL_VERSION,
22533
22603
  LEASE_IPC_REQUEST_KINDS: () => LEASE_IPC_REQUEST_KINDS,
@@ -22733,6 +22803,7 @@ __export(src_exports, {
22733
22803
  decisionOutcomeSchema: () => decisionOutcomeSchema,
22734
22804
  decisionOutcomeSourceSchema: () => decisionOutcomeSourceSchema,
22735
22805
  decisionProviderConfigSchema: () => decisionProviderConfigSchema,
22806
+ decisionProviderKindSchema: () => decisionProviderKindSchema,
22736
22807
  decisionQuestionSchema: () => decisionQuestionSchema,
22737
22808
  decisionQuestionTypeSchema: () => decisionQuestionTypeSchema,
22738
22809
  decisionRequestSchema: () => decisionRequestSchema,
@@ -23011,6 +23082,7 @@ var init_src2 = __esm({
23011
23082
  init_caamp_markers();
23012
23083
  init_collection_keys();
23013
23084
  init_decide();
23085
+ init_decide_sites();
23014
23086
  init_task_id();
23015
23087
  }
23016
23088
  });
@@ -25254,7 +25326,13 @@ var init_admin2 = __esm({
25254
25326
  return lafsError("E_INVALID_INPUT", "backupId is required", "backup.mutate");
25255
25327
  }
25256
25328
  try {
25257
- const data = restoreBackup(projectRoot, { backupId, force: params.force });
25329
+ const data = restoreBackup(projectRoot, {
25330
+ backupId,
25331
+ force: params.force,
25332
+ confirmOwnerStore: params.confirmOwnerStore,
25333
+ // T12680: the invocation directory; core never falls back to it.
25334
+ cwd: process.cwd()
25335
+ });
25258
25336
  return lafsSuccess(data, "backup.mutate");
25259
25337
  } catch (err) {
25260
25338
  return lafsError(
@@ -25270,7 +25348,12 @@ var init_admin2 = __esm({
25270
25348
  return lafsError("E_INVALID_INPUT", "file is required", "backup.mutate");
25271
25349
  }
25272
25350
  try {
25273
- const data = await fileRestore(projectRoot, file, { dryRun: params.dryRun });
25351
+ const data = await fileRestore(projectRoot, file, {
25352
+ dryRun: params.dryRun,
25353
+ confirmOwnerStore: params.confirmOwnerStore,
25354
+ // T12680: the invocation directory; core never falls back to it.
25355
+ cwd: process.cwd()
25356
+ });
25274
25357
  return lafsSuccess(data, "backup.mutate");
25275
25358
  } catch (err) {
25276
25359
  return lafsError(
@@ -28765,14 +28848,23 @@ Recovery command: cleo docs update {slug} --file <your-file>`;
28765
28848
  }
28766
28849
  const hasFile = typeof filePath === "string" && filePath.length > 0;
28767
28850
  const hasContent = typeof inlineContent === "string";
28768
- if (hasFile === hasContent) {
28851
+ const statusOnly = !hasFile && !hasContent;
28852
+ if (hasFile && hasContent) {
28769
28853
  return lafsError(
28770
28854
  "E_INVALID_INPUT",
28771
- "Provide exactly one of --file <path> or --content <text>",
28855
+ "--file and --content are mutually exclusive",
28772
28856
  "update",
28773
28857
  'Use `cleo docs update <slug> --file ./new.md` OR `cleo docs update <slug> --content "..."`.'
28774
28858
  );
28775
28859
  }
28860
+ if (statusOnly && rawStatus === void 0) {
28861
+ return lafsError(
28862
+ "E_INVALID_INPUT",
28863
+ "Provide --file <path>, --content <text>, or --status <status> alone",
28864
+ "update",
28865
+ 'Use `--file ./new.md`, `--content "..."`, or `cleo docs update <slug> --status accepted` to change only the lifecycle status.'
28866
+ );
28867
+ }
28776
28868
  if (rawStatus !== void 0 && !isLifecycleStatus(rawStatus)) {
28777
28869
  return lafsError(
28778
28870
  "E_INVALID_INPUT",
@@ -28793,28 +28885,32 @@ Recovery command: cleo docs update {slug} --file <your-file>`;
28793
28885
  );
28794
28886
  }
28795
28887
  let backend = "llmtxt";
28796
- try {
28797
- const blobMirror = createAttachmentBlobStore(getProjectRoot5());
28798
- const updatedBytes = hasFile ? new Uint8Array(await readFile(resolve2(filePath))) : new Uint8Array(Buffer.from(inlineContent, "utf-8"));
28799
- const contentType = hasFile ? mimeFromPath(resolve2(filePath)) : "text/plain";
28800
- const store = createAttachmentStore();
28801
- const rows = await store.listAllInProject(projectRoot);
28802
- const ownerIds = Array.from(
28803
- new Set(
28804
- rows.filter((row) => row.metadata.id === outcome.result.attachmentId).map((row) => row.ownerId)
28805
- )
28806
- );
28807
- const mirrorOwnerIds = ownerIds.length > 0 ? ownerIds : [`slug:${outcome.result.slug}`];
28808
- for (const mirrorOwnerId of mirrorOwnerIds) {
28809
- const mirrorResult = await blobMirror.put(mirrorOwnerId, {
28810
- name: outcome.result.slug,
28811
- data: updatedBytes,
28812
- contentType
28813
- });
28814
- backend = mirrorResult.backend;
28815
- }
28816
- } catch {
28888
+ if (statusOnly) {
28817
28889
  backend = await currentAttachmentBackend();
28890
+ } else {
28891
+ try {
28892
+ const blobMirror = createAttachmentBlobStore(getProjectRoot5());
28893
+ const updatedBytes = hasFile ? new Uint8Array(await readFile(resolve2(filePath))) : new Uint8Array(Buffer.from(inlineContent, "utf-8"));
28894
+ const contentType = hasFile ? mimeFromPath(resolve2(filePath)) : "text/plain";
28895
+ const store = createAttachmentStore();
28896
+ const rows = await store.listAllInProject(projectRoot);
28897
+ const ownerIds = Array.from(
28898
+ new Set(
28899
+ rows.filter((row) => row.metadata.id === outcome.result.attachmentId).map((row) => row.ownerId)
28900
+ )
28901
+ );
28902
+ const mirrorOwnerIds = ownerIds.length > 0 ? ownerIds : [`slug:${outcome.result.slug}`];
28903
+ for (const mirrorOwnerId of mirrorOwnerIds) {
28904
+ const mirrorResult = await blobMirror.put(mirrorOwnerId, {
28905
+ name: outcome.result.slug,
28906
+ data: updatedBytes,
28907
+ contentType
28908
+ });
28909
+ backend = mirrorResult.backend;
28910
+ }
28911
+ } catch {
28912
+ backend = await currentAttachmentBackend();
28913
+ }
28818
28914
  }
28819
28915
  try {
28820
28916
  writeAuditEntry(getProjectRoot5(), {
@@ -37574,8 +37670,8 @@ async function loadPlaybookByName(name) {
37574
37670
  return null;
37575
37671
  }
37576
37672
  try {
37577
- const { getProjectRoot: getProjectRoot72 } = await import("@cleocode/core/internal");
37578
- const projectRoot = __playbookRuntimeOverrides.projectRoot ?? getProjectRoot72();
37673
+ const { getProjectRoot: getProjectRoot73 } = await import("@cleocode/core/internal");
37674
+ const projectRoot = __playbookRuntimeOverrides.projectRoot ?? getProjectRoot73();
37579
37675
  const resolved = resolvePlaybook(name, {
37580
37676
  projectRoot,
37581
37677
  globalPlaybooksDir: __playbookRuntimeOverrides.globalPlaybooksDir,
@@ -37620,7 +37716,7 @@ async function buildDefaultDispatcher() {
37620
37716
  if (__playbookRuntimeOverrides.dispatcher) return __playbookRuntimeOverrides.dispatcher;
37621
37717
  const { orchestrateSpawnExecute: orchestrateSpawnExecute2 } = await import("@cleocode/runtime/gateway");
37622
37718
  const {
37623
- getProjectRoot: getProjectRoot72,
37719
+ getProjectRoot: getProjectRoot73,
37624
37720
  createToolGuard,
37625
37721
  runSkillNodeOrSpawn,
37626
37722
  maybeCreatePiRunner,
@@ -37628,7 +37724,7 @@ async function buildDefaultDispatcher() {
37628
37724
  hasCantbookProfilePin,
37629
37725
  DEFAULT_DETERMINISTIC_DENIED_COMMANDS
37630
37726
  } = await import("@cleocode/core/internal");
37631
- const projectRoot = getProjectRoot72();
37727
+ const projectRoot = getProjectRoot73();
37632
37728
  const tools = createToolGuard({
37633
37729
  allowedRoots: [projectRoot],
37634
37730
  deniedCommands: DEFAULT_DETERMINISTIC_DENIED_COMMANDS,
@@ -37721,12 +37817,12 @@ async function buildDefaultDeterministicRunner() {
37721
37817
  return void 0;
37722
37818
  }
37723
37819
  const {
37724
- getProjectRoot: getProjectRoot72,
37820
+ getProjectRoot: getProjectRoot73,
37725
37821
  createToolGuard,
37726
37822
  createGuardedDeterministicRunner,
37727
37823
  DEFAULT_DETERMINISTIC_DENIED_COMMANDS
37728
37824
  } = await import("@cleocode/core/internal");
37729
- const projectRoot = getProjectRoot72();
37825
+ const projectRoot = getProjectRoot73();
37730
37826
  const tools = createToolGuard({
37731
37827
  allowedRoots: [projectRoot],
37732
37828
  deniedCommands: DEFAULT_DETERMINISTIC_DENIED_COMMANDS,
@@ -37884,8 +37980,8 @@ var init_playbook2 = __esm({
37884
37980
  projectRoot = __playbookRuntimeOverrides.projectRoot;
37885
37981
  } else {
37886
37982
  try {
37887
- const { getProjectRoot: getProjectRoot72 } = await import("@cleocode/core/internal");
37888
- projectRoot = getProjectRoot72();
37983
+ const { getProjectRoot: getProjectRoot73 } = await import("@cleocode/core/internal");
37984
+ projectRoot = getProjectRoot73();
37889
37985
  } catch {
37890
37986
  projectRoot = void 0;
37891
37987
  }
@@ -37950,14 +38046,14 @@ var init_playbook2 = __esm({
37950
38046
  const deterministicRunner = await buildDefaultDeterministicRunner();
37951
38047
  let result;
37952
38048
  try {
37953
- const { getProjectRoot: getProjectRoot72 } = await import("@cleocode/core/internal");
38049
+ const { getProjectRoot: getProjectRoot73 } = await import("@cleocode/core/internal");
37954
38050
  const opts = {
37955
38051
  db,
37956
38052
  playbook: parsed.definition,
37957
38053
  playbookHash: parsed.sourceHash,
37958
38054
  initialContext,
37959
38055
  dispatcher,
37960
- projectRoot: getProjectRoot72()
38056
+ projectRoot: getProjectRoot73()
37961
38057
  };
37962
38058
  if (deterministicRunner !== void 0) opts.deterministicRunner = deterministicRunner;
37963
38059
  if (__playbookRuntimeOverrides.approvalSecret !== void 0) {
@@ -38229,7 +38325,10 @@ async function orchestrateContextOp(params) {
38229
38325
  return orchestrateContext(params.epicId, getProjectRoot11());
38230
38326
  }
38231
38327
  async function orchestrateWavesOp(params) {
38232
- return orchestrateWaves(params.epicId, getProjectRoot11(), { via: params.via });
38328
+ return orchestrateWaves(params.epicId, getProjectRoot11(), {
38329
+ via: params.via,
38330
+ ...params.hideCompleted === true ? { hideCompleted: true } : {}
38331
+ });
38233
38332
  }
38234
38333
  async function orchestratePlanOp(params) {
38235
38334
  return orchestratePlan({
@@ -39048,7 +39147,8 @@ var init_orchestrate2 = __esm({
39048
39147
  const wavesVia = wavesViaRaw === "parent" || wavesViaRaw === "saga" || wavesViaRaw === "both" ? wavesViaRaw : void 0;
39049
39148
  const p = {
39050
39149
  epicId: params.epicId,
39051
- ...wavesVia !== void 0 && { via: wavesVia }
39150
+ ...wavesVia !== void 0 && { via: wavesVia },
39151
+ ...params.hideCompleted === true && { hideCompleted: true }
39052
39152
  };
39053
39153
  return wrapResult(await coreOps2.waves(p), "query", "orchestrate", operation, startTime);
39054
39154
  }
@@ -42150,6 +42250,8 @@ import {
42150
42250
  taskList,
42151
42251
  taskNext,
42152
42252
  taskPlan,
42253
+ taskRankingHistory,
42254
+ taskRankingRevert,
42153
42255
  taskReconcileScope,
42154
42256
  taskRelates as taskRelates2,
42155
42257
  taskRelatesAdd,
@@ -42427,6 +42529,12 @@ var init_tasks3 = __esm({
42427
42529
  },
42428
42530
  history: async (params) => {
42429
42531
  const projectRoot = getProjectRoot19();
42532
+ if (params.taskId && params.ranking) {
42533
+ return wrapCoreResult(
42534
+ await taskRankingHistory(projectRoot, params.taskId, params.limit),
42535
+ "history"
42536
+ );
42537
+ }
42430
42538
  if (params.taskId) {
42431
42539
  return wrapCoreResult(await taskHistory(projectRoot, params.taskId, params.limit), "history");
42432
42540
  }
@@ -42638,6 +42746,19 @@ var init_tasks3 = __esm({
42638
42746
  "relates.add"
42639
42747
  );
42640
42748
  },
42749
+ "ranking.revert": async (params) => {
42750
+ if (!params.entryId) {
42751
+ return lafsError("E_INVALID_INPUT", "entryId is required", "ranking.revert");
42752
+ }
42753
+ return wrapCoreResult(
42754
+ await taskRankingRevert(getProjectRoot19(), {
42755
+ entryId: params.entryId,
42756
+ ...params.reason !== void 0 ? { reason: params.reason } : {},
42757
+ ...params.force ? { force: true } : {}
42758
+ }),
42759
+ "ranking.revert"
42760
+ );
42761
+ },
42641
42762
  "relates.add-batch": async (params) => {
42642
42763
  const projectRoot = getProjectRoot19();
42643
42764
  return wrapCoreResult(await taskRelatesAddBatch(projectRoot, params), "relates.add-batch");
@@ -42745,6 +42866,8 @@ var init_tasks3 = __esm({
42745
42866
  // OperationDef registered in @cleocode/contracts operations-registry.
42746
42867
  "relates.add-batch",
42747
42868
  "relates.remove",
42869
+ // T12693 (D11161) — undo one audited ranking change.
42870
+ "ranking.revert",
42748
42871
  "start",
42749
42872
  "stop",
42750
42873
  "sync.reconcile",
@@ -43039,6 +43162,7 @@ var init_tasks3 = __esm({
43039
43162
  "assignee",
43040
43163
  "relates.add",
43041
43164
  "relates.remove",
43165
+ "ranking.revert",
43042
43166
  "start",
43043
43167
  "stop",
43044
43168
  "sync.reconcile",
@@ -45129,6 +45253,9 @@ var init_mutate_minimal_envelope = __esm({
45129
45253
  "duplicate",
45130
45254
  "acceptanceCriteriaIds",
45131
45255
  "autoCompleted",
45256
+ // T12660: `cleo complete` reports a cleared focus pointer + next ready task.
45257
+ "focusCleared",
45258
+ "nextSuggested",
45132
45259
  "cascadeDeleted",
45133
45260
  // T10599 add-batch dry-run semantics exposed by the projected mutate
45134
45261
  // envelope. Keep these pointer-addressable for --field consumers.
@@ -45217,11 +45344,11 @@ var init_security = __esm({
45217
45344
  });
45218
45345
 
45219
45346
  // packages/cleo/src/dispatch/middleware/sanitizer.ts
45220
- function createSanitizer(getProjectRoot72) {
45347
+ function createSanitizer(getProjectRoot73) {
45221
45348
  return async (req, next) => {
45222
45349
  if (req.params) {
45223
45350
  try {
45224
- const root = getProjectRoot72 ? getProjectRoot72() : void 0;
45351
+ const root = getProjectRoot73 ? getProjectRoot73() : void 0;
45225
45352
  req.params = sanitizeParams(req.params, root, {
45226
45353
  domain: req.domain,
45227
45354
  operation: req.operation
@@ -45323,14 +45450,14 @@ var init_session_resolver = __esm({
45323
45450
  });
45324
45451
 
45325
45452
  // packages/cleo/src/dispatch/middleware/store-write-guard.ts
45326
- function createStoreWriteGuard(getProjectRoot72) {
45453
+ function createStoreWriteGuard(getProjectRoot73) {
45327
45454
  return async (req, next) => {
45328
45455
  if (req.gateway !== "mutate" || ALLOWED_WHILE_READ_ONLY.has(`${req.domain}.${req.operation}`)) {
45329
45456
  return next();
45330
45457
  }
45331
45458
  let projectRoot;
45332
45459
  try {
45333
- projectRoot = getProjectRoot72();
45460
+ projectRoot = getProjectRoot73();
45334
45461
  } catch {
45335
45462
  return next();
45336
45463
  }
@@ -45433,7 +45560,7 @@ function ensureCaampLibrary() {
45433
45560
  const req = createRequire(import.meta.url);
45434
45561
  const skillsPkgJson = req.resolve("@cleocode/skills/package.json");
45435
45562
  const candidate = dirname2(skillsPkgJson);
45436
- if (existsSync5(join8(candidate, "skills.json"))) {
45563
+ if (existsSync5(join8(candidate, "skills", "manifest.json"))) {
45437
45564
  skillsRoot = candidate;
45438
45565
  }
45439
45566
  } catch {
@@ -45442,7 +45569,7 @@ function ensureCaampLibrary() {
45442
45569
  const thisFile = fileURLToPath(import.meta.url);
45443
45570
  const packageRoot = join8(dirname2(thisFile), "..", "..", "..", "..", "..");
45444
45571
  const candidate = join8(packageRoot, "packages", "skills");
45445
- if (existsSync5(join8(candidate, "skills.json"))) {
45572
+ if (existsSync5(join8(candidate, "skills", "manifest.json"))) {
45446
45573
  skillsRoot = candidate;
45447
45574
  }
45448
45575
  }
@@ -50046,11 +50173,15 @@ var init_list2 = __esm({
50046
50173
  // packages/cleo/src/cli/lib/readline-wizard-io.ts
50047
50174
  import { stdin as input, stdout as output } from "node:process";
50048
50175
  import * as readline from "node:readline/promises";
50176
+ import { Writable } from "node:stream";
50049
50177
  import { WizardFatalError, WizardInterruptError } from "@cleocode/core/setup";
50050
50178
  function stripBracketedPaste(raw) {
50051
50179
  return raw.replace(/\x1b\[200~/g, "").replace(/\x1b\[201~/g, "").trim();
50052
50180
  }
50053
- var SETUP_STDIN_CLOSED_CODE, StdinClosedError, ReadlineWizardIO;
50181
+ function streamIsTTY(stream) {
50182
+ return "isTTY" in stream && stream.isTTY === true;
50183
+ }
50184
+ var SETUP_STDIN_CLOSED_CODE, StdinClosedError, SECRET_ECHO_REFUSED_MESSAGE, MutableOutput, ReadlineWizardIO;
50054
50185
  var init_readline_wizard_io = __esm({
50055
50186
  "packages/cleo/src/cli/lib/readline-wizard-io.ts"() {
50056
50187
  "use strict";
@@ -50070,6 +50201,38 @@ var init_readline_wizard_io = __esm({
50070
50201
  return err instanceof _StdinClosedError;
50071
50202
  }
50072
50203
  };
50204
+ SECRET_ECHO_REFUSED_MESSAGE = 'Refusing to read a secret: stdin is a terminal but terminal mode is off, so the key would be echoed. Pipe it instead: printf %s "$KEY" | cleo decide config --provider layahost --key-stdin (or cleo llm add <provider> --api-key-stdin).';
50205
+ MutableOutput = class extends Writable {
50206
+ /** @param target - Stream that receives writes while unmuted. */
50207
+ constructor(target) {
50208
+ super();
50209
+ this.target = target;
50210
+ this.isTTY = "isTTY" in target && target.isTTY === true;
50211
+ }
50212
+ target;
50213
+ /** When true, writes are dropped. */
50214
+ muted = false;
50215
+ /** Mirrors the wrapped stream: readline enables terminal mode (and echo) from it. */
50216
+ isTTY;
50217
+ /** Terminal width of the wrapped stream, when it reports one. */
50218
+ get columns() {
50219
+ return "columns" in this.target && typeof this.target.columns === "number" ? this.target.columns : void 0;
50220
+ }
50221
+ /** Forward a chunk unless muted. */
50222
+ _write(chunk, encoding, callback) {
50223
+ if (this.muted) {
50224
+ callback();
50225
+ return;
50226
+ }
50227
+ const done = () => callback();
50228
+ if (typeof chunk === "string") this.target.write(chunk, encoding, done);
50229
+ else this.target.write(chunk, done);
50230
+ }
50231
+ /** Write straight to the wrapped stream, bypassing the mute. */
50232
+ writeUnmuted(text) {
50233
+ this.target.write(text);
50234
+ }
50235
+ };
50073
50236
  ReadlineWizardIO = class {
50074
50237
  /**
50075
50238
  * Underlying readline interface.
@@ -50081,6 +50244,10 @@ var init_readline_wizard_io = __esm({
50081
50244
  * @internal
50082
50245
  */
50083
50246
  rl;
50247
+ /** The stream readline echoes into; muted while a secret is typed. */
50248
+ output;
50249
+ /** Whether the input stream is a TTY (the terminal echoes unless readline owns it). */
50250
+ inputIsTTY;
50084
50251
  /** AbortController aborted when stdin closes — surfaced as {@link StdinClosedError}. */
50085
50252
  eofController;
50086
50253
  /**
@@ -50096,11 +50263,22 @@ var init_readline_wizard_io = __esm({
50096
50263
  *
50097
50264
  * @param inStream - Input stream; defaults to `process.stdin`.
50098
50265
  * @param outStream - Output stream passed to readline for terminal-echo
50099
- * purposes only; informational output goes to stderr.
50266
+ * purposes only; informational output goes to stderr. CLI commands pass
50267
+ * `process.stderr` so prompts never reach a redirected stdout.
50268
+ * @param options - See {@link ReadlineWizardIOOptions}; terminal mode
50269
+ * defaults to the input stream's `isTTY`.
50100
50270
  */
50101
- constructor(inStream = input, outStream = output) {
50271
+ constructor(inStream = input, outStream = output, options = {}) {
50102
50272
  this.eofController = new AbortController();
50103
- this.rl = readline.createInterface({ input: inStream, output: outStream });
50273
+ this.output = new MutableOutput(outStream);
50274
+ this.inputIsTTY = streamIsTTY(inStream);
50275
+ this.rl = readline.createInterface({
50276
+ input: inStream,
50277
+ output: this.output,
50278
+ terminal: options.terminal ?? this.inputIsTTY,
50279
+ // No history: a secret must never be recallable with Up-arrow.
50280
+ historySize: 0
50281
+ });
50104
50282
  this.rl.on("close", () => {
50105
50283
  if (!this.eofController.signal.aborted) {
50106
50284
  this.eofController.abort(new StdinClosedError());
@@ -50151,6 +50329,48 @@ var init_readline_wizard_io = __esm({
50151
50329
  this.rethrowEof(err);
50152
50330
  }
50153
50331
  }
50332
+ /**
50333
+ * Ask for a secret without echoing it: the question is written, then the
50334
+ * output stream is muted until the answer is submitted. Bracketed-paste
50335
+ * markers are stripped like {@link prompt}. The answer is removed from
50336
+ * readline's history afterwards.
50337
+ *
50338
+ * @param question - The question, e.g. `API key:`.
50339
+ * @returns The trimmed answer; `''` when none was given.
50340
+ * @throws Error with {@link SECRET_ECHO_REFUSED_MESSAGE} when stdin is a
50341
+ * terminal but terminal mode is off (the terminal would echo the key).
50342
+ * @task T12714
50343
+ */
50344
+ async secret(question) {
50345
+ if (this.inputIsTTY && !this.rl.terminal) throw new Error(SECRET_ECHO_REFUSED_MESSAGE);
50346
+ this.output.writeUnmuted(`${question} `);
50347
+ this.output.muted = true;
50348
+ let raw;
50349
+ try {
50350
+ raw = await this.rl.question("", { signal: this.eofController.signal });
50351
+ return stripBracketedPaste(raw);
50352
+ } catch (err) {
50353
+ return this.rethrowEof(err);
50354
+ } finally {
50355
+ this.output.muted = false;
50356
+ this.output.writeUnmuted("\n");
50357
+ if (raw !== void 0) this.scrubHistory(raw);
50358
+ }
50359
+ }
50360
+ /**
50361
+ * Remove every history entry equal to `line`. `history` is a runtime field
50362
+ * of `readline.Interface` that `@types/node` does not declare, so it is
50363
+ * read reflectively and checked before use.
50364
+ *
50365
+ * @param line - The exact line readline recorded.
50366
+ */
50367
+ scrubHistory(line) {
50368
+ const history = Reflect.get(this.rl, "history");
50369
+ if (!Array.isArray(history)) return;
50370
+ for (let i = history.length - 1; i >= 0; i--) {
50371
+ if (history[i] === line) history.splice(i, 1);
50372
+ }
50373
+ }
50154
50374
  async confirm(question, defaultValue) {
50155
50375
  const hint = defaultValue === void 0 ? "[y/n]" : defaultValue ? "[Y/n]" : "[y/N]";
50156
50376
  let raw;
@@ -50693,7 +50913,7 @@ async function resolveApiKey(args, io) {
50693
50913
  return args["api-key"];
50694
50914
  }
50695
50915
  if (process.stdin.isTTY) {
50696
- return (await io.prompt("API key:")).trim();
50916
+ return (await io.secret("API key (input hidden):")).trim();
50697
50917
  }
50698
50918
  return "";
50699
50919
  }
@@ -52114,14 +52334,14 @@ var init_backup = __esm({
52114
52334
  return;
52115
52335
  }
52116
52336
  const { exportPortableBundle, PortableBundleError } = await import("@cleocode/core/store/portable-bundle.js");
52117
- const { getProjectRoot: getProjectRoot72 } = await import("@cleocode/core");
52337
+ const { getProjectRoot: getProjectRoot73 } = await import("@cleocode/core");
52118
52338
  const passphrase = args.encrypt === true ? await resolvePassphrase() : void 0;
52119
52339
  if (args.encrypt === true && passphrase === void 0) return;
52120
52340
  const encSuffix = args.encrypt === true ? "enc." : "";
52121
52341
  try {
52122
52342
  const result = await exportPortableBundle({
52123
52343
  scope,
52124
- projectRoot: scope === "project" || scope === "all" ? getProjectRoot72() : void 0,
52344
+ projectRoot: scope === "project" || scope === "all" ? getProjectRoot73() : void 0,
52125
52345
  outputPath: args.out ?? `./${args.name}.${encSuffix}cleobundle.tar.gz`,
52126
52346
  encrypt: args.encrypt === true,
52127
52347
  passphrase,
@@ -52166,12 +52386,12 @@ var init_backup = __esm({
52166
52386
  await portableImport(bundlePath, args.target, collectFlagValues(rawArgs, "map"), args.force);
52167
52387
  return;
52168
52388
  }
52169
- const { getProjectRoot: getProjectRoot72, getCleoHome: getCleoHome8, getCleoVersion } = await import("@cleocode/core");
52389
+ const { getProjectRoot: getProjectRoot73, getCleoHome: getCleoHome8, getCleoVersion } = await import("@cleocode/core");
52170
52390
  const { BundleError, cleanupStaging, unpackBundle } = await import("@cleocode/core/store/backup-unpack.js");
52171
52391
  const { regenerateConfigJson, regenerateProjectContextJson, regenerateProjectInfoJson } = await import("@cleocode/core/store/regenerators.js");
52172
52392
  const { regenerateAndCompare } = await import("@cleocode/core/store/restore-json-merge.js");
52173
52393
  const { buildConflictReport, writeConflictReport } = await import("@cleocode/core/store/restore-conflict-report.js");
52174
- const projectRoot = getProjectRoot72();
52394
+ const projectRoot = getProjectRoot73();
52175
52395
  if (args.force !== true) {
52176
52396
  const existing = checkForExistingData(projectRoot, getCleoHome8());
52177
52397
  if (existing.length > 0) {
@@ -54316,6 +54536,52 @@ var init_check3 = __esm({
54316
54536
  task: "T12648",
54317
54537
  script: "scripts/lint-emitted-skills.mjs",
54318
54538
  description: "Every skill code emits is installable (ratchet)"
54539
+ },
54540
+ {
54541
+ // T12649: gate 14's command/flag rules applied to every canonical
54542
+ // skill. Core-tier skills are zero-tolerance; others ratchet.
54543
+ id: "gate-31",
54544
+ task: "T12649",
54545
+ script: "scripts/lint-skill-commands.mjs",
54546
+ description: "Every cleo command a skill teaches exists and is runnable"
54547
+ },
54548
+ {
54549
+ // T12124 (gh#1256): skills declare the code they document in
54550
+ // metadata.covers. Here: every core/LOOM skill declares live covers;
54551
+ // CI adds the PR diff check (--base).
54552
+ id: "gate-32",
54553
+ task: "T12124",
54554
+ script: "scripts/lint-skill-coverage.mjs",
54555
+ description: "Skills declare live metadata.covers (PR diff checked in CI)"
54556
+ },
54557
+ {
54558
+ // T9148 / T12124: ct-cleo stays a thin pointer — ratcheted.
54559
+ id: "gate-33",
54560
+ task: "T12124",
54561
+ script: "scripts/check-ct-cleo-thin.mjs",
54562
+ description: "ct-cleo SKILL.md does not grow (thin-pointer ratchet)"
54563
+ },
54564
+ {
54565
+ // T12704: an ES module has no `require`. A bare `require()` throws
54566
+ // under Node while vitest supplies one, so tests stay green and the
54567
+ // shipped build fails, usually inside a swallowing `try`: the docs
54568
+ // audit wrote nothing, two doctor checks never ran, and no
54569
+ // .worktreeinclude glob ever copied.
54570
+ id: "gate-34",
54571
+ task: "T12704",
54572
+ script: "scripts/lint-no-esm-bare-require.mjs",
54573
+ description: "No bare require() in ESM package sources"
54574
+ },
54575
+ {
54576
+ // T12663: every model call site is a registered decision site
54577
+ // (spec system-one-integration §3.5, D11158): decide()/askSiteDecision
54578
+ // name a registry id, LLM entry points live in registered files of a
54579
+ // generative/agent rung, a System One site runs `on` only with go-live
54580
+ // evidence, and chokepoint bypasses are baselined per file.
54581
+ id: "gate-35",
54582
+ task: "T12663",
54583
+ script: "scripts/lint-model-call-sites.mjs",
54584
+ description: "Every model call site is a registered decision site (ratchet)"
54319
54585
  }
54320
54586
  ];
54321
54587
  const scriptArgs = strict ? ["--strict"] : ["--check"];
@@ -55001,6 +55267,8 @@ var init_complete = __esm({
55001
55267
  if (Array.isArray(unblockedTasks) && unblockedTasks.length > 0) {
55002
55268
  output2["unblockedTasks"] = unblockedTasks;
55003
55269
  }
55270
+ if (typeof data?.focusCleared === "boolean") output2["focusCleared"] = data.focusCleared;
55271
+ if (data?.nextSuggested !== void 0) output2["nextSuggested"] = data.nextSuggested;
55004
55272
  const worktreeAutoComplete = data?.worktreeAutoComplete;
55005
55273
  if (worktreeAutoComplete && typeof worktreeAutoComplete === "object") {
55006
55274
  output2["worktreeAutoComplete"] = worktreeAutoComplete;
@@ -55451,7 +55719,7 @@ var init_conduit3 = __esm({
55451
55719
  args: {
55452
55720
  topic: {
55453
55721
  type: "string",
55454
- description: 'Topic name to publish to (e.g. "epic-T1149.wave-T1253")',
55722
+ description: 'Topic name to publish to (e.g. "epic-T1149.wave-2")',
55455
55723
  required: true
55456
55724
  },
55457
55725
  kind: {
@@ -55536,7 +55804,7 @@ var init_conduit3 = __esm({
55536
55804
  args: {
55537
55805
  topic: {
55538
55806
  type: "string",
55539
- description: 'Topic name to poll (e.g. "epic-T1149.wave-T1253")',
55807
+ description: 'Topic name to poll (e.g. "epic-T1149.wave-2")',
55540
55808
  required: true
55541
55809
  },
55542
55810
  limit: {
@@ -57336,8 +57604,14 @@ import {
57336
57604
  clearDecideConfig,
57337
57605
  configureDecide,
57338
57606
  describeDecideCredentials,
57339
- probeDecideProvider
57607
+ listDecisionSites,
57608
+ parseDecisionProviderKind,
57609
+ probeDecideProvider,
57610
+ resetDecideBudget,
57611
+ runDecideWizard,
57612
+ SpendResetRefusedError
57340
57613
  } from "@cleocode/core/decide/index.js";
57614
+ import { WizardInterruptError as WizardInterruptError2 } from "@cleocode/core/setup";
57341
57615
  async function readSecretFromStdin() {
57342
57616
  if (process.stdin.isTTY) return "";
57343
57617
  process.stdin.setEncoding("utf-8");
@@ -57349,41 +57623,81 @@ function failValidation(message, operation, fix) {
57349
57623
  cliError(message, 6 /* VALIDATION_ERROR */, { name: "E_VALIDATION", fix }, { operation });
57350
57624
  process.exitCode = 6 /* VALIDATION_ERROR */;
57351
57625
  }
57352
- var CONFIG_FIX, decideConfigCommand, decideStatusCommand, decideAskCommand, decideCommand;
57626
+ async function runConfigWizard(op) {
57627
+ const io = new ReadlineWizardIO(process.stdin, process.stderr);
57628
+ try {
57629
+ cliOutput(await runDecideWizard(io), { command: "decide", operation: op });
57630
+ } catch (err) {
57631
+ if (err instanceof WizardInterruptError2) {
57632
+ process.stderr.write("System One setup cancelled.\n");
57633
+ process.exitCode = 130;
57634
+ return;
57635
+ }
57636
+ failValidation(err instanceof Error ? err.message : "setup failed", op, CONFIG_FIX);
57637
+ } finally {
57638
+ io.close();
57639
+ }
57640
+ }
57641
+ function oneOf(value, allowed) {
57642
+ return allowed.find((a) => a === value);
57643
+ }
57644
+ var CONFIG_FIX, decideConfigCommand, decideStatusCommand, decideAskCommand, decideSitesCommand, decideBudgetResetCommand, decideBudgetCommand, decideCommand;
57353
57645
  var init_decide2 = __esm({
57354
57646
  "packages/cleo/src/cli/commands/decide.ts"() {
57355
57647
  "use strict";
57356
57648
  init_src2();
57357
57649
  init_define_cli_command();
57650
+ init_readline_wizard_io();
57358
57651
  init_renderers();
57359
- CONFIG_FIX = 'printf %s "$KEY" | cleo decide config --url https://provider.example --key-stdin';
57652
+ CONFIG_FIX = 'printf %s "$KEY" | cleo decide config --provider layahost --key-stdin';
57360
57653
  decideConfigCommand = defineCommand({
57361
57654
  meta: {
57362
57655
  name: "config",
57363
- description: "Store the decision provider API URL and key (0600 file in the CLEO home). Prefer --key-stdin so the key stays out of shell history. No flags shows the current settings (key masked)."
57656
+ description: "Store the decision provider, API key and model (0600 file in the CLEO home), then probe it and detect its capabilities. --provider layahost (default) needs only the key; --provider jev needs --url. Prefer --key-stdin so the key stays out of shell history. No flags on a terminal runs the setup wizard (the key is typed hidden); no flags without a terminal shows the current settings (key masked)."
57364
57657
  },
57365
57658
  args: {
57366
- url: { type: "string", description: "Provider API base URL, e.g. https://layahost.com" },
57659
+ provider: {
57660
+ type: "string",
57661
+ description: `Provider: ${DECISION_PROVIDER_KINDS.join("|")} (layahost: fixed URL, model laya-auto; jev: custom URL, required)`
57662
+ },
57663
+ url: {
57664
+ type: "string",
57665
+ description: "Provider API base URL: overrides the layahost default; required for jev"
57666
+ },
57367
57667
  key: {
57368
57668
  type: "string",
57369
57669
  description: "API key. Visible in the process list (ps) and shell history; prefer --key-stdin"
57370
57670
  },
57371
57671
  "key-stdin": { type: "boolean", description: "Read the API key from stdin (recommended)" },
57372
- model: { type: "string", description: "Optional default model; omitted \u2192 provider listing" },
57672
+ model: {
57673
+ type: "string",
57674
+ description: "Default model; omitted \u2192 the stored model, the preset (layahost: laya-auto) or the first listed (jev)"
57675
+ },
57373
57676
  clear: { type: "boolean", description: "Remove the stored URL, key and model" }
57374
57677
  },
57375
57678
  async run({ args }) {
57376
57679
  const op = "decide.config";
57377
57680
  if (args.clear === true)
57378
57681
  return cliOutput(await clearDecideConfig(), { command: "decide", operation: op });
57682
+ const provider = parseDecisionProviderKind(args.provider);
57683
+ if (args.provider !== void 0 && provider === void 0) {
57684
+ return failValidation(`unknown provider '${args.provider}'`, op, CONFIG_FIX);
57685
+ }
57379
57686
  const apiKey = args["key-stdin"] === true ? await readSecretFromStdin() : args.key;
57380
57687
  if (args["key-stdin"] === true && !apiKey)
57381
57688
  return failValidation("--key-stdin set but stdin is empty or a TTY", op, CONFIG_FIX);
57382
- if (args.url === void 0 && apiKey === void 0 && args.model === void 0) {
57689
+ const noSettings = provider === void 0 && args.url === void 0 && apiKey === void 0 && args.model === void 0;
57690
+ if (noSettings && process.stdin.isTTY && process.stderr.isTTY) return runConfigWizard(op);
57691
+ if (noSettings) {
57383
57692
  return cliOutput(describeDecideCredentials(), { command: "decide", operation: op });
57384
57693
  }
57385
57694
  try {
57386
- const result = await configureDecide({ baseUrl: args.url, apiKey, model: args.model });
57695
+ const result = await configureDecide({
57696
+ provider,
57697
+ baseUrl: args.url,
57698
+ apiKey,
57699
+ model: args.model
57700
+ });
57387
57701
  cliOutput(result, { command: "decide", operation: op });
57388
57702
  } catch (err) {
57389
57703
  failValidation(err instanceof Error ? err.message : "invalid settings", op, CONFIG_FIX);
@@ -57393,7 +57707,7 @@ var init_decide2 = __esm({
57393
57707
  decideStatusCommand = defineCommand({
57394
57708
  meta: {
57395
57709
  name: "status",
57396
- description: "Probe the decision provider (GET {url}/v1/models, short timeout): reachable, unauthorized, unconfigured or unreachable. Exits 1 unless reachable."
57710
+ description: "Probe the decision provider (GET {url}/v1/models, short timeout): reachable, unauthorized, key_limit_reached (the key monthly limit), unconfigured or unreachable. Also reports the registered sites count, the provider capabilities and balance (GET /v1/usage, refreshed at most every 10 minutes) and month-to-date spend against decide.budget.monthlyMicros. Exits 1 unless reachable."
57397
57711
  },
57398
57712
  args: {
57399
57713
  "timeout-ms": { type: "string", description: "Probe timeout in ms (default 3000)" }
@@ -57421,15 +57735,95 @@ var init_decide2 = __esm({
57421
57735
  cliOutput(result, { command: "decide", operation: "decide.ask" });
57422
57736
  }
57423
57737
  });
57738
+ decideSitesCommand = defineCommand({
57739
+ meta: {
57740
+ name: "sites",
57741
+ description: "List the System One integration decision sites: rung, ladder, fallback, owner escalation, configured and effective mode, go-live evidence and last-7-day activity. A site that uses System One is effectively off while no provider is configured."
57742
+ },
57743
+ args: {
57744
+ rung: {
57745
+ type: "string",
57746
+ description: `Only sites with this primary rung (${DECISION_RUNGS.join("|")})`
57747
+ },
57748
+ mode: {
57749
+ type: "string",
57750
+ description: `Only sites with this effective mode (${DECISION_SITE_MODES.join("|")})`
57751
+ },
57752
+ id: { type: "string", description: "Only the site with this id" },
57753
+ evidence: { type: "boolean", description: "Only sites with recorded go-live evidence" }
57754
+ },
57755
+ async run({ args }) {
57756
+ const op = "decide.sites";
57757
+ const rung = oneOf(args.rung, DECISION_RUNGS);
57758
+ if (args.rung !== void 0 && rung === void 0) {
57759
+ return failValidation(
57760
+ `unknown rung '${args.rung}'`,
57761
+ op,
57762
+ `--rung ${DECISION_RUNGS.join("|")}`
57763
+ );
57764
+ }
57765
+ const mode = oneOf(args.mode, DECISION_SITE_MODES);
57766
+ if (args.mode !== void 0 && mode === void 0) {
57767
+ return failValidation(
57768
+ `unknown mode '${args.mode}'`,
57769
+ op,
57770
+ `--mode ${DECISION_SITE_MODES.join("|")}`
57771
+ );
57772
+ }
57773
+ const result = await listDecisionSites({
57774
+ rung,
57775
+ mode,
57776
+ id: args.id,
57777
+ evidenceOnly: args.evidence === true
57778
+ });
57779
+ cliOutput(result, { command: "decide", operation: op });
57780
+ }
57781
+ });
57782
+ decideBudgetResetCommand = defineCommand({
57783
+ meta: {
57784
+ name: "reset",
57785
+ description: "Repair a corrupt System One spend ledger (<cleoHome>/decide/spend.json): start a fresh one for this month, moving the old file aside as a receipt. Refuses a readable ledger unless --force; month-to-date spend is always kept when readable, so a reset never lifts a reached cap."
57786
+ },
57787
+ args: {
57788
+ force: {
57789
+ type: "boolean",
57790
+ description: "Reset a ledger that is not corrupt (keeps month-to-date spend; clears in-flight reservations and the key-limit stop)"
57791
+ }
57792
+ },
57793
+ async run({ args }) {
57794
+ const op = "decide.budget.reset";
57795
+ try {
57796
+ const receipt = await resetDecideBudget(void 0, { force: args.force === true });
57797
+ cliOutput(receipt, { command: "decide", operation: op });
57798
+ } catch (err) {
57799
+ if (!(err instanceof SpendResetRefusedError)) throw err;
57800
+ failValidation(err.message, op, "cleo decide status");
57801
+ }
57802
+ }
57803
+ });
57804
+ decideBudgetCommand = defineCommand({
57805
+ meta: {
57806
+ name: "budget",
57807
+ description: "System One monthly spend cap (decide.budget.monthlyMicros): budget reset"
57808
+ },
57809
+ subCommands: { reset: decideBudgetResetCommand },
57810
+ async run({ cmd, rawArgs }) {
57811
+ const firstArg = rawArgs?.find((a) => !a.startsWith("-"));
57812
+ if (firstArg && cmd.subCommands && firstArg in cmd.subCommands) return;
57813
+ await showUsage(cmd);
57814
+ }
57815
+ });
57424
57816
  decideCommand = defineCommand({
57425
57817
  meta: {
57426
57818
  name: "decide",
57427
- description: "Typed-decision (System One) provider: decide config (API URL + key), decide status (reachability probe), decide ask (one debug question). Unconfigured means heuristics answer."
57819
+ description: "System One integration (typed decisions): decide config (provider + API key; wizard on a terminal), decide status (reachability probe), decide ask (one debug question), decide sites (the registered decision sites). Unconfigured means heuristics answer."
57428
57820
  },
57429
57821
  subCommands: {
57430
57822
  config: decideConfigCommand,
57431
57823
  status: decideStatusCommand,
57432
- ask: decideAskCommand
57824
+ ask: decideAskCommand,
57825
+ sites: decideSitesCommand,
57826
+ budget: decideBudgetCommand
57433
57827
  },
57434
57828
  async run({ cmd, rawArgs }) {
57435
57829
  const firstArg = rawArgs?.find((a) => !a.startsWith("-"));
@@ -61248,11 +61642,15 @@ var init_docs3 = __esm({
61248
61642
  });
61249
61643
  process.exit(6 /* VALIDATION_ERROR */);
61250
61644
  }
61251
- if (filePath === void 0 && inlineContent === void 0) {
61252
- cliError("provide --file <path> OR --content <text>", 6 /* VALIDATION_ERROR */, {
61253
- name: "E_VALIDATION",
61254
- fix: 'Example: `cleo docs update my-doc --file ./new.md` OR `cleo docs update my-doc --content "..."`.'
61255
- });
61645
+ if (filePath === void 0 && inlineContent === void 0 && typeof args.status !== "string") {
61646
+ cliError(
61647
+ "provide --file <path>, --content <text>, or --status <status> alone",
61648
+ 6 /* VALIDATION_ERROR */,
61649
+ {
61650
+ name: "E_VALIDATION",
61651
+ fix: 'Example: `cleo docs update my-doc --file ./new.md`, `--content "..."`, or `cleo docs update my-doc --status accepted` to change only the lifecycle status.'
61652
+ }
61653
+ );
61256
61654
  process.exit(6 /* VALIDATION_ERROR */);
61257
61655
  }
61258
61656
  let resolvedFile;
@@ -62719,6 +63117,80 @@ var init_doctor_malformed_ids = __esm({
62719
63117
  }
62720
63118
  });
62721
63119
 
63120
+ // packages/cleo/src/cli/commands/doctor-manifest-rows.ts
63121
+ var doctor_manifest_rows_exports = {};
63122
+ __export(doctor_manifest_rows_exports, {
63123
+ doctorManifestRowsCommand: () => doctorManifestRowsCommand
63124
+ });
63125
+ import {
63126
+ listMalformedManifestRows,
63127
+ MANIFEST_ROW_APPLY_COMMAND,
63128
+ MANIFEST_ROW_REPAIR_COMMAND,
63129
+ repairMalformedManifestRows,
63130
+ rollbackManifestRepair
63131
+ } from "@cleocode/core/memory/pipeline-manifest-sqlite.js";
63132
+ import { getProjectRoot as getProjectRoot46 } from "@cleocode/core/paths.js";
63133
+ var doctorManifestRowsCommand;
63134
+ var init_doctor_manifest_rows = __esm({
63135
+ "packages/cleo/src/cli/commands/doctor-manifest-rows.ts"() {
63136
+ "use strict";
63137
+ init_define_cli_command();
63138
+ init_renderers();
63139
+ doctorManifestRowsCommand = defineCommand({
63140
+ meta: {
63141
+ name: "manifest-rows",
63142
+ 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."
63143
+ },
63144
+ args: {
63145
+ repair: {
63146
+ type: "boolean",
63147
+ description: "Plan the repair of every malformed row; writes nothing"
63148
+ },
63149
+ apply: {
63150
+ type: "boolean",
63151
+ description: "Write the repair (writes a receipt first); implies --repair"
63152
+ },
63153
+ "dry-run": {
63154
+ type: "boolean",
63155
+ description: "Plan only (the default for --repair); overrides --apply"
63156
+ },
63157
+ rollback: { type: "string", description: "Undo a repair from its receipt file" },
63158
+ json: { type: "boolean", description: "Output as JSON" },
63159
+ human: { type: "boolean", description: "Force human-readable output" },
63160
+ quiet: { type: "boolean", description: "Suppress non-essential output" }
63161
+ },
63162
+ async run({ args }) {
63163
+ const projectRoot = getProjectRoot46();
63164
+ if (typeof args.rollback === "string" && args.rollback !== "") {
63165
+ const result = await rollbackManifestRepair(args.rollback, projectRoot);
63166
+ cliOutput(result, { command: "doctor", operation: "doctor.manifest-rows.rollback" });
63167
+ return;
63168
+ }
63169
+ if (args.repair === true || args.apply === true) {
63170
+ const apply = args.apply === true && args["dry-run"] !== true;
63171
+ const receipt = await repairMalformedManifestRows(projectRoot, { dryRun: !apply });
63172
+ cliOutput(
63173
+ apply ? receipt : { ...receipt, apply: receipt.changes.length > 0 ? MANIFEST_ROW_APPLY_COMMAND : null },
63174
+ {
63175
+ command: "doctor",
63176
+ operation: apply ? "doctor.manifest-rows.apply" : "doctor.manifest-rows.plan"
63177
+ }
63178
+ );
63179
+ return;
63180
+ }
63181
+ const rows = await listMalformedManifestRows(projectRoot);
63182
+ cliOutput(
63183
+ { rows, repair: rows.length > 0 ? MANIFEST_ROW_REPAIR_COMMAND : null },
63184
+ { command: "doctor", operation: "doctor.manifest-rows.run" }
63185
+ );
63186
+ if (rows.length > 0 && (process.exitCode === void 0 || process.exitCode === 0)) {
63187
+ process.exitCode = 1;
63188
+ }
63189
+ }
63190
+ });
63191
+ }
63192
+ });
63193
+
62722
63194
  // packages/cleo/src/cli/commands/doctor-memory-guard.ts
62723
63195
  var doctor_memory_guard_exports = {};
62724
63196
  __export(doctor_memory_guard_exports, {
@@ -62788,7 +63260,7 @@ var doctor_nexus_residency_exports = {};
62788
63260
  __export(doctor_nexus_residency_exports, {
62789
63261
  doctorNexusResidencyCommand: () => doctorNexusResidencyCommand
62790
63262
  });
62791
- import { getCleoHome as getCleoHome6, getProjectRoot as getProjectRoot46 } from "@cleocode/core";
63263
+ import { getCleoHome as getCleoHome6, getProjectRoot as getProjectRoot47 } from "@cleocode/core";
62792
63264
  import { scanNexusSchemaResidency } from "@cleocode/core/doctor/nexus-schema-residency.js";
62793
63265
  var doctorNexusResidencyCommand;
62794
63266
  var init_doctor_nexus_residency = __esm({
@@ -62807,7 +63279,7 @@ var init_doctor_nexus_residency = __esm({
62807
63279
  quiet: { type: "boolean", description: "Suppress non-essential output" }
62808
63280
  },
62809
63281
  async run() {
62810
- const result = scanNexusSchemaResidency(getProjectRoot46(), getCleoHome6());
63282
+ const result = scanNexusSchemaResidency(getProjectRoot47(), getCleoHome6());
62811
63283
  cliOutput(result, {
62812
63284
  command: "doctor",
62813
63285
  operation: "doctor.nexus-residency.run"
@@ -62825,7 +63297,7 @@ var doctor_project_identity_exports = {};
62825
63297
  __export(doctor_project_identity_exports, {
62826
63298
  doctorProjectIdentityCommand: () => doctorProjectIdentityCommand
62827
63299
  });
62828
- import { getProjectRoot as getProjectRoot47 } from "@cleocode/core";
63300
+ import { getProjectRoot as getProjectRoot48 } from "@cleocode/core";
62829
63301
  import {
62830
63302
  inspectProjectIdentity,
62831
63303
  resolveProjectIdentity
@@ -62849,7 +63321,7 @@ var init_doctor_project_identity = __esm({
62849
63321
  quiet: { type: "boolean", description: "Suppress non-essential output" }
62850
63322
  },
62851
63323
  async run({ args }) {
62852
- const projectRoot = getProjectRoot47();
63324
+ const projectRoot = getProjectRoot48();
62853
63325
  if (!args.resolve) {
62854
63326
  const report = inspectProjectIdentity(projectRoot);
62855
63327
  cliOutput(report, { command: "doctor", operation: "doctor.project-identity.inspect" });
@@ -63359,7 +63831,7 @@ var doctor_repair_exports = {};
63359
63831
  __export(doctor_repair_exports, {
63360
63832
  doctorRepairCommand: () => doctorRepairCommand
63361
63833
  });
63362
- import { getLogger as getLogger21, getProjectRoot as getProjectRoot48 } from "@cleocode/core";
63834
+ import { getLogger as getLogger21, getProjectRoot as getProjectRoot49 } from "@cleocode/core";
63363
63835
  import { repairMalformedDbs } from "@cleocode/core/store/repair-malformed-dbs.js";
63364
63836
  var doctorRepairCommand;
63365
63837
  var init_doctor_repair = __esm({
@@ -63403,7 +63875,7 @@ var init_doctor_repair = __esm({
63403
63875
  return;
63404
63876
  }
63405
63877
  const result = repairMalformedDbs({
63406
- projectRoot: getProjectRoot48(),
63878
+ projectRoot: getProjectRoot49(),
63407
63879
  roles: roleArg.length > 0 ? [roleArg] : void 0,
63408
63880
  dryRun,
63409
63881
  logger: getLogger21("doctor-repair")
@@ -63602,7 +64074,7 @@ var doctor_superseded_store_exports = {};
63602
64074
  __export(doctor_superseded_store_exports, {
63603
64075
  doctorSupersededStoreCommand: () => doctorSupersededStoreCommand
63604
64076
  });
63605
- import { getProjectRoot as getProjectRoot49 } from "@cleocode/core";
64077
+ import { getProjectRoot as getProjectRoot50 } from "@cleocode/core";
63606
64078
  import { scanSupersededStores } from "@cleocode/core/doctor/superseded-store.js";
63607
64079
  import { reconcileSupersededStores } from "@cleocode/core/store/exodus/index.js";
63608
64080
  var doctorSupersededStoreCommand;
@@ -63635,7 +64107,7 @@ var init_doctor_superseded_store = __esm({
63635
64107
  },
63636
64108
  async run({ args }) {
63637
64109
  if (args.reconcile === true) {
63638
- const receipt = await reconcileSupersededStores(getProjectRoot49(), {
64110
+ const receipt = await reconcileSupersededStores(getProjectRoot50(), {
63639
64111
  dryRun: args["dry-run"] === true,
63640
64112
  additive: args.additive === true
63641
64113
  });
@@ -63657,7 +64129,7 @@ var init_doctor_superseded_store = __esm({
63657
64129
  );
63658
64130
  return;
63659
64131
  }
63660
- const result = scanSupersededStores(getProjectRoot49());
64132
+ const result = scanSupersededStores(getProjectRoot50());
63661
64133
  cliOutput(result, {
63662
64134
  command: "doctor",
63663
64135
  operation: "doctor.superseded-store.run"
@@ -63755,7 +64227,7 @@ import {
63755
64227
  retryTwinCollapse
63756
64228
  } from "@cleocode/core/doctor/twin-collapse.js";
63757
64229
  import { CleoError as CleoError7 } from "@cleocode/core/errors";
63758
- import { getProjectRoot as getProjectRoot50 } from "@cleocode/core/paths.js";
64230
+ import { getProjectRoot as getProjectRoot51 } from "@cleocode/core/paths.js";
63759
64231
  var doctorTwinCollapseCommand;
63760
64232
  var init_doctor_twin_collapse = __esm({
63761
64233
  "packages/cleo/src/cli/commands/doctor-twin-collapse.ts"() {
@@ -63777,7 +64249,7 @@ var init_doctor_twin_collapse = __esm({
63777
64249
  quiet: { type: "boolean", description: "Suppress non-essential output" }
63778
64250
  },
63779
64251
  async run({ args }) {
63780
- const projectRoot = getProjectRoot50();
64252
+ const projectRoot = getProjectRoot51();
63781
64253
  if (args.retry === true) {
63782
64254
  try {
63783
64255
  const receipts = await retryTwinCollapse(projectRoot);
@@ -63813,7 +64285,7 @@ __export(doctor_worktree_stores_exports, {
63813
64285
  doctorWorktreeStoresCommand: () => doctorWorktreeStoresCommand
63814
64286
  });
63815
64287
  import { scanWorktreeStores } from "@cleocode/core/doctor/worktree-stores.js";
63816
- import { getProjectRoot as getProjectRoot51, resolveStoreOwnerRoot } from "@cleocode/core/paths.js";
64288
+ import { getProjectRoot as getProjectRoot52, resolveStoreOwnerRoot } from "@cleocode/core/paths.js";
63817
64289
  var doctorWorktreeStoresCommand;
63818
64290
  var init_doctor_worktree_stores = __esm({
63819
64291
  "packages/cleo/src/cli/commands/doctor-worktree-stores.ts"() {
@@ -63835,7 +64307,7 @@ var init_doctor_worktree_stores = __esm({
63835
64307
  quiet: { type: "boolean", description: "Suppress non-essential output" }
63836
64308
  },
63837
64309
  async run({ args }) {
63838
- const projectRoot = resolveStoreOwnerRoot(getProjectRoot51());
64310
+ const projectRoot = resolveStoreOwnerRoot(getProjectRoot52());
63839
64311
  const result = scanWorktreeStores(projectRoot, { skipCompare: args["skip-compare"] === true });
63840
64312
  cliOutput(result, {
63841
64313
  command: "doctor",
@@ -63987,7 +64459,7 @@ import {
63987
64459
  resumePreparedKnowledgeRepair,
63988
64460
  runKnowledgeDoctor as runKnowledgeDoctor2
63989
64461
  } from "@cleocode/core/doctor/knowledge.js";
63990
- import { getProjectRoot as getProjectRoot52 } from "@cleocode/core/paths.js";
64462
+ import { getProjectRoot as getProjectRoot53 } from "@cleocode/core/paths.js";
63991
64463
  var doctorKnowledgeSubcommand;
63992
64464
  var init_doctor_knowledge = __esm({
63993
64465
  "packages/cleo/src/cli/commands/doctor-knowledge.ts"() {
@@ -64062,7 +64534,7 @@ var init_doctor_knowledge = __esm({
64062
64534
  },
64063
64535
  async run({ args }) {
64064
64536
  const startedAt = Date.now();
64065
- const root = getProjectRoot52();
64537
+ const root = getProjectRoot53();
64066
64538
  let context;
64067
64539
  let pending;
64068
64540
  try {
@@ -64230,7 +64702,7 @@ import { join as join24 } from "node:path";
64230
64702
  import {
64231
64703
  ensureGlobalAgentRegistryDb,
64232
64704
  getGlobalAgentRegistryNativeDb,
64233
- getProjectRoot as getProjectRoot53,
64705
+ getProjectRoot as getProjectRoot54,
64234
64706
  installAgentFromCant
64235
64707
  } from "@cleocode/core/internal";
64236
64708
  function sha256Hex(bytes) {
@@ -64418,7 +64890,7 @@ var init_migrate_agents_v2 = __esm({
64418
64890
  }
64419
64891
  },
64420
64892
  async run({ args }) {
64421
- const projectRoot = getProjectRoot53();
64893
+ const projectRoot = getProjectRoot54();
64422
64894
  const verbose = args.quiet !== true;
64423
64895
  if (verbose) {
64424
64896
  humanInfo("Scanning .cleo/cant/agents/ and .cleo/agents/ for unregistered agents...");
@@ -64462,7 +64934,7 @@ __export(doctor_exports, {
64462
64934
  });
64463
64935
  import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync5 } from "node:fs";
64464
64936
  import { join as join25 } from "node:path";
64465
- import { getProjectRoot as getProjectRoot54, pushWarning as pushWarning5 } from "@cleocode/core";
64937
+ import { getProjectRoot as getProjectRoot55, pushWarning as pushWarning5 } from "@cleocode/core";
64466
64938
  import { renderInvariantAuditLines } from "@cleocode/core/doctor/invariant-audit-render.js";
64467
64939
  import {
64468
64940
  quarantineRogueCleoDir,
@@ -64589,6 +65061,7 @@ var init_doctor = __esm({
64589
65061
  init_doctor_legacy_backups();
64590
65062
  init_doctor_legacy_reaper();
64591
65063
  init_doctor_malformed_ids();
65064
+ init_doctor_manifest_rows();
64592
65065
  init_doctor_memory_guard();
64593
65066
  init_doctor_nexus_residency();
64594
65067
  init_doctor_project_identity();
@@ -64622,6 +65095,8 @@ var init_doctor = __esm({
64622
65095
  "legacy-reaper": doctorLegacyReaperCommand,
64623
65096
  // T12128 — task ids that fail the write-path validator
64624
65097
  "malformed-ids": doctorMalformedIdsCommand,
65098
+ // T12686 — manifest rows whose metadata violates the stored field contract (+ --repair/--rollback)
65099
+ "manifest-rows": doctorManifestRowsCommand,
64625
65100
  // T12095 — pre-dual-scope store files still on disk under their old LIVE names
64626
65101
  "superseded-store": doctorSupersededStoreCommand,
64627
65102
  // T12535 — twin collapses (bare schema_meta / sticky_tags → prefixed twins): report + --retry
@@ -64860,7 +65335,7 @@ var init_doctor = __esm({
64860
65335
  const { join: pathJoin } = await import("node:path");
64861
65336
  const { existsSync: existsSync22 } = await import("node:fs");
64862
65337
  const { detectAndHealCoreWorktreeLeak } = await import("@cleocode/worktree");
64863
- const projectRoot = getProjectRoot54();
65338
+ const projectRoot = getProjectRoot55();
64864
65339
  let gitRoot = projectRoot;
64865
65340
  try {
64866
65341
  gitRoot = execFile2("git", ["rev-parse", "--show-toplevel"], {
@@ -64912,7 +65387,7 @@ var init_doctor = __esm({
64912
65387
  }
64913
65388
  if (args.brain) {
64914
65389
  const { computeBrainHealthDashboard } = await import("@cleocode/core/memory/brain-health-dashboard.js");
64915
- const projectRoot = getProjectRoot54();
65390
+ const projectRoot = getProjectRoot55();
64916
65391
  const dashboard = await computeBrainHealthDashboard(projectRoot);
64917
65392
  cliOutput(dashboard, { command: "doctor", operation: "doctor.brain" });
64918
65393
  if (dashboard.hasP0Failure) {
@@ -64921,7 +65396,7 @@ var init_doctor = __esm({
64921
65396
  return;
64922
65397
  }
64923
65398
  if (args["scan-test-fixtures-in-prod"]) {
64924
- const projectRoot = getProjectRoot54();
65399
+ const projectRoot = getProjectRoot55();
64925
65400
  const matches = await scanTestFixturesInProd(projectRoot);
64926
65401
  const dryRun = args["dry-run"] !== false && args.quarantine !== true;
64927
65402
  const quarantined = !dryRun && matches.length > 0 ? await quarantineTestFixtures(projectRoot, matches) : void 0;
@@ -65009,7 +65484,7 @@ var init_doctor = __esm({
65009
65484
  progress.complete("Comprehensive diagnostics complete");
65010
65485
  } else if (args["scan-rogue-cleo-dirs"]) {
65011
65486
  progress.step(0, "Scanning for rogue .cleo/ directories");
65012
- const projectRoot = getProjectRoot54();
65487
+ const projectRoot = getProjectRoot55();
65013
65488
  const reports = scanRogueCleoDirs(projectRoot);
65014
65489
  progress.complete(
65015
65490
  `Found ${reports.length} rogue .cleo/ director${reports.length === 1 ? "y" : "ies"}`
@@ -65018,7 +65493,7 @@ var init_doctor = __esm({
65018
65493
  } else if (args["quarantine-rogue-cleo-dirs"]) {
65019
65494
  const isDryRun = args["dry-run"] === true;
65020
65495
  progress.step(0, `${isDryRun ? "[DRY RUN] " : ""}Scanning for rogue .cleo/ directories`);
65021
- const projectRoot = getProjectRoot54();
65496
+ const projectRoot = getProjectRoot55();
65022
65497
  const reports = scanRogueCleoDirs(projectRoot);
65023
65498
  if (reports.length === 0) {
65024
65499
  progress.complete("No rogue .cleo/ directories found \u2014 nothing to quarantine");
@@ -65072,7 +65547,7 @@ var init_doctor = __esm({
65072
65547
  const { detectAndRemoveLegacyGlobalFiles, detectAndRemoveStrayProjectNexus } = await import("@cleocode/core/store/cleanup-legacy.js");
65073
65548
  const { getCleoHome: getCleoHome8 } = await import("@cleocode/core");
65074
65549
  const cleoHome = getCleoHome8();
65075
- const projectRoot = getProjectRoot54();
65550
+ const projectRoot = getProjectRoot55();
65076
65551
  const legacyResult = detectAndRemoveLegacyGlobalFiles(cleoHome);
65077
65552
  const strayResult = detectAndRemoveStrayProjectNexus(projectRoot);
65078
65553
  const isDryRun = args["dry-run"] === true;
@@ -65105,7 +65580,7 @@ var init_doctor = __esm({
65105
65580
  } else if (args["audit-worktree-orphans"]) {
65106
65581
  progress.step(0, "Comprehensive worktree anomaly audit (T9808 / council D009)");
65107
65582
  const { auditWorktreeOrphansComprehensive, scanWorktreeOrphansBudgeted } = await import("@cleocode/core/doctor/worktree-orphans.js");
65108
- const projectRoot = getProjectRoot54();
65583
+ const projectRoot = getProjectRoot55();
65109
65584
  const timeoutSecs = args["timeout"] !== void 0 ? Number.parseInt(String(args["timeout"]), 10) : 30;
65110
65585
  const timeoutMs = Number.isFinite(timeoutSecs) && timeoutSecs > 0 ? timeoutSecs * 1e3 : 3e4;
65111
65586
  const maxEntriesPerLevel = args["max-entries-per-level"] !== void 0 ? Number.parseInt(String(args["max-entries-per-level"]), 10) : 500;
@@ -65162,7 +65637,7 @@ var init_doctor = __esm({
65162
65637
  `${isDryRun ? "[DRY RUN] " : ""}Scanning + pruning worktree-orphan .cleo/ directories`
65163
65638
  );
65164
65639
  const { pruneWorktreeOrphans, scanWorktreeOrphansBudgeted } = await import("@cleocode/core/doctor/worktree-orphans.js");
65165
- const projectRoot = getProjectRoot54();
65640
+ const projectRoot = getProjectRoot55();
65166
65641
  const timeoutSecs = args["timeout"] !== void 0 ? Number.parseInt(String(args["timeout"]), 10) : 30;
65167
65642
  const timeoutMs = Number.isFinite(timeoutSecs) && timeoutSecs > 0 ? timeoutSecs * 1e3 : 3e4;
65168
65643
  const maxEntriesPerLevel = args["max-entries-per-level"] !== void 0 ? Number.parseInt(String(args["max-entries-per-level"]), 10) : 500;
@@ -65241,7 +65716,7 @@ var init_doctor = __esm({
65241
65716
  `${isDryRun ? "[DRY RUN] " : ""}Migrating .cleo/worktree-include \u2192 .worktreeinclude`
65242
65717
  );
65243
65718
  const { migrateWorktreeIncludeFile } = await import("@cleocode/core");
65244
- const projectRoot = getProjectRoot54();
65719
+ const projectRoot = getProjectRoot55();
65245
65720
  const result = await migrateWorktreeIncludeFile(projectRoot, { dryRun: isDryRun });
65246
65721
  progress.complete(`Migration ${result.action}`);
65247
65722
  cliOutput(result, { command: "doctor", operation: "doctor.migrate-worktree-include" });
@@ -65260,7 +65735,7 @@ var init_doctor = __esm({
65260
65735
  const stepLabel = isFocusedAlias ? "Auditing Saga hierarchy for ADR-073 invariants" : "Walking central INVARIANTS_REGISTRY";
65261
65736
  progress.step(0, stepLabel);
65262
65737
  const { auditInvariantRegistry } = await import("@cleocode/core/doctor/invariant-audit.js");
65263
- const projectRoot = getProjectRoot54();
65738
+ const projectRoot = getProjectRoot55();
65264
65739
  const result = await auditInvariantRegistry(projectRoot, { adrFilter });
65265
65740
  const operation = isFocusedAlias ? "doctor.audit-sagas" : "doctor.audit-invariants";
65266
65741
  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`;
@@ -65282,7 +65757,7 @@ var init_doctor = __esm({
65282
65757
  { command: "doctor", operation: "admin.health" }
65283
65758
  );
65284
65759
  try {
65285
- const projectRoot = getProjectRoot54();
65760
+ const projectRoot = getProjectRoot55();
65286
65761
  const conflicts = readMigrationConflicts(projectRoot);
65287
65762
  if (conflicts.length > 0) {
65288
65763
  progress.complete(
@@ -65313,7 +65788,7 @@ var init_doctor = __esm({
65313
65788
  progress.complete("Health check complete");
65314
65789
  }
65315
65790
  try {
65316
- const projectRoot = getProjectRoot54();
65791
+ const projectRoot = getProjectRoot55();
65317
65792
  const { auditSagaHierarchy } = await import("@cleocode/core/doctor/saga-audit.js");
65318
65793
  const sagaAudit = await auditSagaHierarchy(projectRoot);
65319
65794
  if (sagaAudit.sagas.length === 0) {
@@ -65428,8 +65903,8 @@ var init_done = __esm({
65428
65903
  process.exitCode = 2;
65429
65904
  return;
65430
65905
  }
65431
- const { getProjectRoot: getProjectRoot72 } = await import("@cleocode/core/paths.js");
65432
- const options = { projectRoot: getProjectRoot72(), ...parsed.options };
65906
+ const { getProjectRoot: getProjectRoot73 } = await import("@cleocode/core/paths.js");
65907
+ const options = { projectRoot: getProjectRoot73(), ...parsed.options };
65433
65908
  const requested = [
65434
65909
  ...new Set([args.taskId, ...args._ ?? []].map(String))
65435
65910
  ];
@@ -66774,7 +67249,7 @@ __export(gateway_exports, {
66774
67249
  gatewayOpenapiSubCommand: () => gatewayOpenapiSubCommand
66775
67250
  });
66776
67251
  import { resolve as resolve8 } from "node:path";
66777
- import { generateOpenApi, getProjectRoot as getProjectRoot55 } from "@cleocode/core";
67252
+ import { generateOpenApi, getProjectRoot as getProjectRoot56 } from "@cleocode/core";
66778
67253
  var gatewayOpenapiSubCommand, gatewayCommand;
66779
67254
  var init_gateway = __esm({
66780
67255
  "packages/cleo/src/cli/commands/gateway.ts"() {
@@ -66806,7 +67281,7 @@ var init_gateway = __esm({
66806
67281
  const pathCount = Object.keys(doc.paths).length;
66807
67282
  if (typeof args.out === "string" && args.out.length > 0) {
66808
67283
  const { writeFileSync: writeFileSync8 } = await import("node:fs");
66809
- const target = resolve8(getProjectRoot55(), args.out);
67284
+ const target = resolve8(getProjectRoot56(), args.out);
66810
67285
  writeFileSync8(target, json2, "utf8");
66811
67286
  cliOutput(
66812
67287
  { out: target, pathCount, version: doc.info.version, openapi: doc.openapi },
@@ -67267,7 +67742,7 @@ var go_exports = {};
67267
67742
  __export(go_exports, {
67268
67743
  goCommand: () => goCommand
67269
67744
  });
67270
- import { getProjectRoot as getProjectRoot56, go } from "@cleocode/core";
67745
+ import { getProjectRoot as getProjectRoot57, go } from "@cleocode/core";
67271
67746
  var goCommand;
67272
67747
  var init_go = __esm({
67273
67748
  "packages/cleo/src/cli/commands/go.ts"() {
@@ -67293,7 +67768,7 @@ var init_go = __esm({
67293
67768
  }
67294
67769
  },
67295
67770
  async run({ args }) {
67296
- const projectRoot = getProjectRoot56();
67771
+ const projectRoot = getProjectRoot57();
67297
67772
  const { getCurrentSessionId, resolveBoundSessionId } = await import("@cleocode/core/internal");
67298
67773
  let sessionId = getCurrentSessionId(projectRoot) ?? void 0;
67299
67774
  if (sessionId === void 0) {
@@ -67321,7 +67796,7 @@ var goal_exports = {};
67321
67796
  __export(goal_exports, {
67322
67797
  goalCommand: () => goalCommand
67323
67798
  });
67324
- import { getProjectRoot as getProjectRoot57, goal } from "@cleocode/core";
67799
+ import { getProjectRoot as getProjectRoot58, goal } from "@cleocode/core";
67325
67800
  function resolveGoalKind(task) {
67326
67801
  if (typeof task === "string" && task.length > 0) {
67327
67802
  if (!isValidGoalTargetTaskId(task)) {
@@ -67368,7 +67843,7 @@ var init_goal2 = __esm({
67368
67843
  }
67369
67844
  const record = await goal.createGoal(
67370
67845
  { goalKind: kindResult.kind, intent, turnBudget: resolveTurnBudget(args.turns) },
67371
- getProjectRoot57()
67846
+ getProjectRoot58()
67372
67847
  );
67373
67848
  cliOutput(record, { command: "goal set", operation: "goal.set" });
67374
67849
  }
@@ -67379,7 +67854,7 @@ var init_goal2 = __esm({
67379
67854
  description: "Show the current agent's active goal (per-agent scoped)."
67380
67855
  },
67381
67856
  async run() {
67382
- const record = await goal.getActiveGoal(getProjectRoot57());
67857
+ const record = await goal.getActiveGoal(getProjectRoot58());
67383
67858
  cliOutput(record ?? { active: null }, { command: "goal status", operation: "goal.status" });
67384
67859
  }
67385
67860
  });
@@ -67401,7 +67876,7 @@ var init_goal2 = __esm({
67401
67876
  });
67402
67877
  return;
67403
67878
  }
67404
- const cwd = getProjectRoot57();
67879
+ const cwd = getProjectRoot58();
67405
67880
  const parent = await goal.getActiveGoal(cwd);
67406
67881
  if (!parent) {
67407
67882
  cliError(
@@ -67449,7 +67924,7 @@ var init_goal2 = __esm({
67449
67924
  });
67450
67925
  return;
67451
67926
  }
67452
- const cwd = getProjectRoot57();
67927
+ const cwd = getProjectRoot58();
67453
67928
  const result = await goal.advanceGoalWithPersist(goalId, { cwd });
67454
67929
  if (!result) {
67455
67930
  cliError(`Goal '${goalId}' not found.`, 4 /* NOT_FOUND */, { name: "E_NOT_FOUND" });
@@ -67474,7 +67949,7 @@ var init_goal2 = __esm({
67474
67949
  });
67475
67950
  return;
67476
67951
  }
67477
- const cwd = getProjectRoot57();
67952
+ const cwd = getProjectRoot58();
67478
67953
  const active = await goal.getActiveGoal(cwd);
67479
67954
  if (!active) {
67480
67955
  cliError(
@@ -68404,7 +68879,7 @@ var history_exports = {};
68404
68879
  __export(history_exports, {
68405
68880
  historyCommand: () => historyCommand
68406
68881
  });
68407
- var logCommand, workCommand2, historyCommand;
68882
+ var logCommand, workCommand2, rankingCommand, revertCommand, historyCommand;
68408
68883
  var init_history = __esm({
68409
68884
  "packages/cleo/src/cli/commands/history.ts"() {
68410
68885
  "use strict";
@@ -68452,11 +68927,60 @@ var init_history = __esm({
68452
68927
  await dispatchFromCli("query", "tasks", "history", {}, { command: "history" });
68453
68928
  }
68454
68929
  });
68930
+ rankingCommand = defineCommand({
68931
+ meta: {
68932
+ name: "ranking",
68933
+ description: "Who changed a task's priority, severity, kind or depends \u2014 actor, session, reason, before/after (D11161)"
68934
+ },
68935
+ args: {
68936
+ taskId: { type: "positional", description: "Task ID", required: true },
68937
+ limit: { type: "string", description: "Maximum entries (default 50)" }
68938
+ },
68939
+ async run({ args }) {
68940
+ await dispatchFromCli(
68941
+ "query",
68942
+ "tasks",
68943
+ "history",
68944
+ {
68945
+ taskId: String(args.taskId),
68946
+ ranking: true,
68947
+ ...args.limit !== void 0 ? { limit: Number.parseInt(String(args.limit), 10) } : {}
68948
+ },
68949
+ { command: "history" }
68950
+ );
68951
+ }
68952
+ });
68953
+ revertCommand = defineCommand({
68954
+ meta: {
68955
+ name: "revert",
68956
+ description: "Undo one ranking change (an entry id from `cleo history ranking`); refused if a field changed again since, unless --force"
68957
+ },
68958
+ args: {
68959
+ entryId: { type: "positional", description: "ranking_changed entry id", required: true },
68960
+ reason: { type: "string", description: "Why it is reverted (recorded)" },
68961
+ force: { type: "boolean", description: "Revert even though a field changed again since" }
68962
+ },
68963
+ async run({ args }) {
68964
+ await dispatchFromCli(
68965
+ "mutate",
68966
+ "tasks",
68967
+ "ranking.revert",
68968
+ {
68969
+ entryId: String(args.entryId),
68970
+ ...args.reason !== void 0 ? { reason: String(args.reason) } : {},
68971
+ ...args.force === true ? { force: true } : {}
68972
+ },
68973
+ { command: "history" }
68974
+ );
68975
+ }
68976
+ });
68455
68977
  historyCommand = defineCommand({
68456
68978
  meta: { name: "history", description: "Completion timeline and productivity analytics" },
68457
68979
  subCommands: {
68458
68980
  log: logCommand,
68459
- work: workCommand2
68981
+ work: workCommand2,
68982
+ ranking: rankingCommand,
68983
+ revert: revertCommand
68460
68984
  },
68461
68985
  async run({ cmd, rawArgs }) {
68462
68986
  const firstArg = rawArgs?.find((a) => !a.startsWith("-"));
@@ -68472,7 +68996,7 @@ var hygiene_exports = {};
68472
68996
  __export(hygiene_exports, {
68473
68997
  hygieneCommand: () => hygieneCommand
68474
68998
  });
68475
- import { getProjectRoot as getProjectRoot58 } from "@cleocode/core";
68999
+ import { getProjectRoot as getProjectRoot59 } from "@cleocode/core";
68476
69000
  import { runSpawnReadinessHygieneCli } from "@cleocode/core/hygiene/validate-spawn-readiness.js";
68477
69001
  var hygieneCommand;
68478
69002
  var init_hygiene = __esm({
@@ -68501,7 +69025,7 @@ var init_hygiene = __esm({
68501
69025
  }
68502
69026
  },
68503
69027
  async run({ args }) {
68504
- const projectRoot = args["project-root"] || getProjectRoot58() || process.cwd();
69028
+ const projectRoot = args["project-root"] || getProjectRoot59() || process.cwd();
68505
69029
  const worktreePath = args["worktree-path"];
68506
69030
  await runSpawnReadinessHygieneCli(projectRoot, worktreePath);
68507
69031
  }
@@ -69844,7 +70368,7 @@ var llm_cost_exports = {};
69844
70368
  __export(llm_cost_exports, {
69845
70369
  costCommand: () => costCommand
69846
70370
  });
69847
- import { getProjectRoot as getProjectRoot59 } from "@cleocode/core/internal";
70371
+ import { getProjectRoot as getProjectRoot60 } from "@cleocode/core/internal";
69848
70372
  import { computeCost } from "@cleocode/core/llm/usage-pricing";
69849
70373
  function resolveSessionId(raw) {
69850
70374
  if (raw === "current") {
@@ -69917,7 +70441,7 @@ var init_llm_cost = __esm({
69917
70441
  process.exit(6);
69918
70442
  }
69919
70443
  const sessionId = resolveSessionId(rawSessionId);
69920
- const projectRoot = getProjectRoot59(process.cwd());
70444
+ const projectRoot = getProjectRoot60(process.cwd());
69921
70445
  let breakdown;
69922
70446
  try {
69923
70447
  breakdown = await loadSessionCostBreakdown(projectRoot, sessionId);
@@ -71252,7 +71776,7 @@ var memory_exports = {};
71252
71776
  __export(memory_exports, {
71253
71777
  memoryCommand: () => memoryCommand
71254
71778
  });
71255
- import { getProjectRoot as getProjectRoot60 } from "@cleocode/core";
71779
+ import { getProjectRoot as getProjectRoot61 } from "@cleocode/core";
71256
71780
  import {
71257
71781
  getBrainDb as getBrainDb2,
71258
71782
  getDreamStatus,
@@ -72210,7 +72734,7 @@ var init_memory3 = __esm({
72210
72734
  },
72211
72735
  args: {},
72212
72736
  async run() {
72213
- const root = getProjectRoot60();
72737
+ const root = getProjectRoot61();
72214
72738
  try {
72215
72739
  const result = await runConsolidation(root);
72216
72740
  cliOutput(result, { command: "memory-consolidate", operation: "memory.consolidate" });
@@ -72234,7 +72758,7 @@ var init_memory3 = __esm({
72234
72758
  }
72235
72759
  },
72236
72760
  async run({ args }) {
72237
- const root = getProjectRoot60();
72761
+ const root = getProjectRoot61();
72238
72762
  if (args.status) {
72239
72763
  try {
72240
72764
  const status = await getDreamStatus(root);
@@ -72271,7 +72795,7 @@ var init_memory3 = __esm({
72271
72795
  }
72272
72796
  },
72273
72797
  async run({ args }) {
72274
- const root = getProjectRoot60();
72798
+ const root = getProjectRoot61();
72275
72799
  try {
72276
72800
  const { runObserver, runReflector } = await import("@cleocode/core/memory");
72277
72801
  const observerResult = await runObserver(root, args.session, {
@@ -72311,7 +72835,7 @@ var init_memory3 = __esm({
72311
72835
  }
72312
72836
  },
72313
72837
  async run({ args }) {
72314
- const root = getProjectRoot60();
72838
+ const root = getProjectRoot61();
72315
72839
  await getBrainDb2(root);
72316
72840
  const { getBrainNativeDb: getBrainNativeDb3 } = await import("@cleocode/core/internal");
72317
72841
  const nativeDb = getBrainNativeDb3();
@@ -72349,7 +72873,7 @@ var init_memory3 = __esm({
72349
72873
  },
72350
72874
  async run({ args }) {
72351
72875
  const core2 = await import("@cleocode/core/internal");
72352
- const nexusDb = await core2.getNexusDb(getProjectRoot60());
72876
+ const nexusDb = await core2.getNexusDb(getProjectRoot61());
72353
72877
  const result = args.restore ? await core2.restorePrunedTraits(
72354
72878
  nexusDb,
72355
72879
  String(args.restore),
@@ -72379,7 +72903,7 @@ var init_memory3 = __esm({
72379
72903
  return;
72380
72904
  }
72381
72905
  const core2 = await import("@cleocode/core/internal");
72382
- const nexusDb = await core2.getNexusDb(getProjectRoot60());
72906
+ const nexusDb = await core2.getNexusDb(getProjectRoot61());
72383
72907
  const previous = await core2.setUserProfileTraitScope(nexusDb, String(args.key), scope);
72384
72908
  if (previous === null) {
72385
72909
  cliError(`No user-profile trait "${args.key}"`, "E_NOT_FOUND", { name: "E_NOT_FOUND" });
@@ -72403,7 +72927,7 @@ var init_memory3 = __esm({
72403
72927
  }
72404
72928
  },
72405
72929
  async run({ args }) {
72406
- const root = getProjectRoot60();
72930
+ const root = getProjectRoot61();
72407
72931
  try {
72408
72932
  await getBrainDb2(root);
72409
72933
  const { totalDuplicateRows, groups } = await scanDuplicateEntries();
@@ -72449,7 +72973,7 @@ var init_memory3 = __esm({
72449
72973
  async run({ args }) {
72450
72974
  const sourceDir = args.from;
72451
72975
  const isDryRun = !!args["dry-run"];
72452
- const projectRoot = getProjectRoot60();
72976
+ const projectRoot = getProjectRoot61();
72453
72977
  try {
72454
72978
  const result = await importMemoryFiles({
72455
72979
  sourceDir,
@@ -72600,7 +73124,7 @@ var init_memory3 = __esm({
72600
73124
  },
72601
73125
  args: {},
72602
73126
  async run() {
72603
- const root = getProjectRoot60();
73127
+ const root = getProjectRoot61();
72604
73128
  try {
72605
73129
  await getBrainDb2(root);
72606
73130
  const result = await getTierStats(root);
@@ -72643,7 +73167,7 @@ var init_memory3 = __esm({
72643
73167
  }
72644
73168
  },
72645
73169
  async run({ args }) {
72646
- const root = getProjectRoot60();
73170
+ const root = getProjectRoot61();
72647
73171
  const targetTier = args.to;
72648
73172
  const reason = args.reason;
72649
73173
  const validTiers = ["medium", "long"];
@@ -72709,7 +73233,7 @@ var init_memory3 = __esm({
72709
73233
  }
72710
73234
  },
72711
73235
  async run({ args }) {
72712
- const root = getProjectRoot60();
73236
+ const root = getProjectRoot61();
72713
73237
  const targetTier = args.to;
72714
73238
  const reason = args.reason;
72715
73239
  const validTiers = ["short", "medium"];
@@ -73182,7 +73706,7 @@ var migrate_claude_mem_exports = {};
73182
73706
  __export(migrate_claude_mem_exports, {
73183
73707
  migrateClaudeMemCommand: () => migrateClaudeMemCommand
73184
73708
  });
73185
- import { getProjectRoot as getProjectRoot61, migrateClaudeMem } from "@cleocode/core/internal";
73709
+ import { getProjectRoot as getProjectRoot62, migrateClaudeMem } from "@cleocode/core/internal";
73186
73710
  import { ingestLooseAgentOutputs, ingestRcasdDirectories } from "@cleocode/core/memory";
73187
73711
  import { getDb as getDb2 } from "@cleocode/core/store/sqlite";
73188
73712
  var storageCommand, claudeMemCommand, manifestIngestCommand, migrateClaudeMemCommand;
@@ -73245,7 +73769,7 @@ var init_migrate_claude_mem = __esm({
73245
73769
  }
73246
73770
  },
73247
73771
  async run({ args }) {
73248
- const root = getProjectRoot61();
73772
+ const root = getProjectRoot62();
73249
73773
  try {
73250
73774
  const result = await migrateClaudeMem(root, {
73251
73775
  sourcePath: args.source,
@@ -73294,7 +73818,7 @@ var init_migrate_claude_mem = __esm({
73294
73818
  }
73295
73819
  },
73296
73820
  async run({ args }) {
73297
- const projectRoot = getProjectRoot61();
73821
+ const projectRoot = getProjectRoot62();
73298
73822
  try {
73299
73823
  const db = await getDb2(projectRoot);
73300
73824
  const rcasdFlag = Boolean(args.rcasd);
@@ -73412,7 +73936,7 @@ __export(nexus_exports, {
73412
73936
  import { statSync as statSync2 } from "node:fs";
73413
73937
  import { appendFile as appendFile2, mkdir as mkdir5 } from "node:fs/promises";
73414
73938
  import path4 from "node:path";
73415
- import { getProjectRoot as getProjectRoot62 } from "@cleocode/core";
73939
+ import { getProjectRoot as getProjectRoot63 } from "@cleocode/core";
73416
73940
  import { getSymbolImpact } from "@cleocode/core/nexus";
73417
73941
  import { runNexusAnalysis } from "@cleocode/core/nexus/analyze-orchestrator.js";
73418
73942
  import {
@@ -73583,7 +74107,7 @@ var init_nexus3 = __esm({
73583
74107
  async run({ args }) {
73584
74108
  applyJsonFlag2(args.json);
73585
74109
  const projectIdOverride = args["project-id"];
73586
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot62();
74110
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
73587
74111
  const startTime = Date.now();
73588
74112
  if (args.path) {
73589
74113
  let isDir = false;
@@ -73643,7 +74167,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648), so the coun
73643
74167
  process.exitCode = 2 /* INVALID_INPUT */;
73644
74168
  return;
73645
74169
  }
73646
- const currentRoot = getProjectRoot62();
74170
+ const currentRoot = getProjectRoot63();
73647
74171
  if (args.path && path4.resolve(repoPath) !== path4.resolve(currentRoot)) {
73648
74172
  cliError(
73649
74173
  `nexus status cannot report on '${repoPath}' from this project.
@@ -74197,7 +74721,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
74197
74721
  applyJsonFlag2(args.json);
74198
74722
  const startTime = Date.now();
74199
74723
  const projectIdOverride = args["project-id"];
74200
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot62();
74724
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
74201
74725
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
74202
74726
  const response = await dispatchRaw("query", "nexus", "clusters", { projectId, repoPath });
74203
74727
  const durationMs = Date.now() - startTime;
@@ -74241,7 +74765,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
74241
74765
  applyJsonFlag2(args.json);
74242
74766
  const startTime = Date.now();
74243
74767
  const projectIdOverride = args["project-id"];
74244
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot62();
74768
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
74245
74769
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
74246
74770
  const response = await dispatchRaw("query", "nexus", "flows", { projectId, repoPath });
74247
74771
  const durationMs = Date.now() - startTime;
@@ -74284,7 +74808,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
74284
74808
  void appendDeprecationTelemetry("nexus.context", "cleo graph context");
74285
74809
  const startTime = Date.now();
74286
74810
  const projectIdOverride = args["project-id"];
74287
- const repoPath = getProjectRoot62();
74811
+ const repoPath = getProjectRoot63();
74288
74812
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
74289
74813
  const limit = parseInt(args.limit, 10);
74290
74814
  const symbolName = args.symbol;
@@ -74347,7 +74871,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
74347
74871
  const startTime = Date.now();
74348
74872
  const whyFlag = !!args.why;
74349
74873
  const projectIdOverride = args["project-id"];
74350
- const repoPath = getProjectRoot62();
74874
+ const repoPath = getProjectRoot63();
74351
74875
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
74352
74876
  const maxDepth = Math.min(parseInt(args.depth, 10), 5);
74353
74877
  const symbolName = args.symbol;
@@ -74434,11 +74958,15 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
74434
74958
  },
74435
74959
  full: {
74436
74960
  type: "boolean",
74437
- description: "Parse every file instead of reusing unchanged files (default: incremental, falling back to full with a stated reason)"
74961
+ description: "Parse every file instead of reusing unchanged files (default: incremental, falling back to full with a stated reason). Also re-binds a moved project's graph (same project id, old recorded root) to the live root"
74438
74962
  },
74439
74963
  incremental: {
74440
74964
  type: "boolean",
74441
74965
  description: "Deprecated no-op: incremental analysis is now the default (use --full to rebuild)"
74966
+ },
74967
+ "drop-missing-repositories": {
74968
+ type: "boolean",
74969
+ description: "Drop included repositories that are missing on disk instead of refusing (the default keeps the previous graph). Dropped paths are reported with a one-command restore"
74442
74970
  }
74443
74971
  },
74444
74972
  async run({ args }) {
@@ -74447,7 +74975,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
74447
74975
  const projectIdOverride = args["project-id"];
74448
74976
  const full = !!args.full;
74449
74977
  const ctx = getFormatContext();
74450
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot62();
74978
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
74451
74979
  if (args.incremental)
74452
74980
  humanWarn(
74453
74981
  "[nexus] --incremental is deprecated and has no effect: incremental is the default."
@@ -74459,6 +74987,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
74459
74987
  repoPath,
74460
74988
  projectIdOverride,
74461
74989
  full,
74990
+ dropMissingRepositories: args["drop-missing-repositories"] === true,
74462
74991
  includedRepositories: args["include-repositories"]?.split(",").map((entry) => entry.trim()).filter(Boolean),
74463
74992
  onProgress: ctx.format === "json" ? void 0 : (current, total, filePath) => {
74464
74993
  if (current % 50 === 0 || current === total) {
@@ -74469,6 +74998,14 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
74469
74998
  });
74470
74999
  humanInfo(`[nexus] nexus-bridge.md refreshed at ${repoPath}/.cleo/nexus-bridge.md`);
74471
75000
  humanInfo("[nexus] Project registered/updated in multi-project registry.");
75001
+ if (result.droppedRepositories)
75002
+ humanWarn(
75003
+ `[nexus] DROPPED missing included repositories: ${result.droppedRepositories.paths.join(", ")}. Restore them once they exist again: ${result.droppedRepositories.restoreCommand}`
75004
+ );
75005
+ if (result.rebind)
75006
+ humanInfo(
75007
+ `[nexus] Re-bound graph for ${result.rebind.projectId}: ${result.rebind.oldRoot} -> ${result.rebind.newRoot}`
75008
+ );
74472
75009
  humanInfo(
74473
75010
  `[nexus] Mode: ${result.summary.mode} \u2014 ${result.summary.reason} (parsed ${result.summary.parsedFiles}, reused ${result.summary.reusedFiles})`
74474
75011
  );
@@ -74484,7 +75021,10 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
74484
75021
  relationCount: result.relationCount,
74485
75022
  fileCount: result.fileCount,
74486
75023
  durationMs: result.durationMs,
74487
- assessment: result.assessment
75024
+ assessment: result.assessment,
75025
+ // T12659: receipt of a moved project's graph re-bound to the live root.
75026
+ ...result.rebind ? { rebind: result.rebind } : {},
75027
+ ...result.droppedRepositories ? { droppedRepositories: result.droppedRepositories } : {}
74488
75028
  },
74489
75029
  {
74490
75030
  command: "nexus-analyze",
@@ -74565,7 +75105,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
74565
75105
  async run({ args }) {
74566
75106
  applyJsonFlag2(args.json);
74567
75107
  const startTime = Date.now();
74568
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot62();
75108
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
74569
75109
  const name = args.name;
74570
75110
  const response = await dispatchRaw("mutate", "nexus", "projects.register", {
74571
75111
  path: repoPath,
@@ -75017,7 +75557,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
75017
75557
  applyJsonFlag2(args.json);
75018
75558
  const startTime = Date.now();
75019
75559
  const projectIdOverride = args["project-id"];
75020
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot62();
75560
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
75021
75561
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
75022
75562
  const response = await dispatchRaw("mutate", "nexus", "refresh-bridge", {
75023
75563
  repoPath,
@@ -75123,7 +75663,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
75123
75663
  async run({ args }) {
75124
75664
  applyJsonFlag2(args.json);
75125
75665
  const startTime = Date.now();
75126
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot62();
75666
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
75127
75667
  const projectIdOverride = args["project-id"];
75128
75668
  const beforeRef = args.before ?? "HEAD~1";
75129
75669
  const afterRef = args.after ?? "HEAD";
@@ -75241,7 +75781,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
75241
75781
  applyJsonFlag2(args.json);
75242
75782
  const startTime = Date.now();
75243
75783
  const projectIdOverride = args["project-id"];
75244
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot62();
75784
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
75245
75785
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
75246
75786
  const response = await dispatchRaw("query", "nexus", "route-map", { projectId });
75247
75787
  const durationMs = Date.now() - startTime;
@@ -75297,7 +75837,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
75297
75837
  const startTime = Date.now();
75298
75838
  const routeSymbol = args.routeSymbol;
75299
75839
  const projectIdOverride = args["project-id"];
75300
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot62();
75840
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
75301
75841
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
75302
75842
  const response = await dispatchRaw("query", "nexus", "shape-check", { routeSymbol, projectId });
75303
75843
  const durationMs = Date.now() - startTime;
@@ -75693,7 +76233,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
75693
76233
  async run({ args }) {
75694
76234
  applyJsonFlag2(args.json);
75695
76235
  const startTime = Date.now();
75696
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot62();
76236
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
75697
76237
  const projectIdOverride = args["project-id"];
75698
76238
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
75699
76239
  const response = await dispatchRaw("mutate", "nexus", "contracts-sync", {
@@ -75803,7 +76343,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
75803
76343
  async run({ args }) {
75804
76344
  applyJsonFlag2(args.json);
75805
76345
  const startTime = Date.now();
75806
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot62();
76346
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot63();
75807
76347
  const projectId = Buffer.from(repoPath).toString("base64url").slice(0, 32);
75808
76348
  const response = await dispatchRaw("mutate", "nexus", "contracts-link-tasks", {
75809
76349
  projectId,
@@ -75887,7 +76427,7 @@ The code-intelligence graph is project-scoped (ADR-090 \xB7 T11648): one store p
75887
76427
  const isIncremental = !!args.incremental;
75888
76428
  try {
75889
76429
  const result = await runNexusWiki({
75890
- projectRoot: getProjectRoot62(),
76430
+ projectRoot: getProjectRoot63(),
75891
76431
  outputDir,
75892
76432
  communityFilter,
75893
76433
  incremental: isIncremental
@@ -76237,7 +76777,7 @@ __export(orchestrate_exports, {
76237
76777
  });
76238
76778
  import { execFileSync as execFileSync5 } from "node:child_process";
76239
76779
  import { orchestration } from "@cleocode/core";
76240
- import { BUILD_CONFIG as BUILD_CONFIG2, getProjectRoot as getProjectRoot63 } from "@cleocode/core/internal";
76780
+ import { BUILD_CONFIG as BUILD_CONFIG2, getProjectRoot as getProjectRoot64 } from "@cleocode/core/internal";
76241
76781
  function formatRollupTable(rollup) {
76242
76782
  const waves = "waves" in rollup ? rollup.waves : [rollup];
76243
76783
  const lines = [];
@@ -76292,7 +76832,7 @@ var init_orchestrate3 = __esm({
76292
76832
  },
76293
76833
  wave: {
76294
76834
  type: "string",
76295
- description: "Filter to a single wave id (0-indexed)"
76835
+ description: "Filter to one wave, numbered from 1 as `cleo orchestrate waves` prints it (the n of topic epic-<id>.wave-<n>)"
76296
76836
  },
76297
76837
  json: {
76298
76838
  type: "boolean",
@@ -76380,7 +76920,7 @@ var init_orchestrate3 = __esm({
76380
76920
  },
76381
76921
  async run({ args }) {
76382
76922
  const rateWindowHours = args.window !== void 0 ? Number.parseFloat(String(args.window)) : void 0;
76383
- const metrics = await orchestration.collectOrchestrateDashboard(getProjectRoot63(), {
76923
+ const metrics = await orchestration.collectOrchestrateDashboard(getProjectRoot64(), {
76384
76924
  ...rateWindowHours !== void 0 && Number.isFinite(rateWindowHours) && rateWindowHours > 0 ? { rateWindowHours } : {}
76385
76925
  });
76386
76926
  cliOutput(metrics, {
@@ -76507,7 +77047,7 @@ var init_orchestrate3 = __esm({
76507
77047
  wavesCommand2 = defineCommand({
76508
77048
  meta: {
76509
77049
  name: "waves",
76510
- description: "Compute dependency waves for an epic. When the epic is a Saga (label='saga', ADR-073), per-member wave plans are merged by index (wave N across all members \u2192 one unified wave N)."
77050
+ description: "Compute dependency waves for an epic. Wave numbers are stable: a finished wave keeps its number and is listed as completed (--hide-completed omits it). When the epic is a Saga (label='saga', ADR-073), per-member wave plans are merged by index (wave N across all members \u2192 one unified wave N)."
76511
77051
  },
76512
77052
  args: {
76513
77053
  epicId: {
@@ -76518,6 +77058,10 @@ var init_orchestrate3 = __esm({
76518
77058
  via: {
76519
77059
  type: "string",
76520
77060
  description: "Traversal mode (gh-390/ADR-073): 'parent' walks parentId only, 'saga' walks task_relations.type='groups' only, 'both' (default) auto-detects saga-labeled epics."
77061
+ },
77062
+ "hide-completed": {
77063
+ type: "boolean",
77064
+ description: "Omit finished waves. Wave numbers are stable, so the remaining waves keep their numbers (the n of topic epic-<id>.wave-<n>)"
76521
77065
  }
76522
77066
  },
76523
77067
  async run({ args }) {
@@ -76527,7 +77071,8 @@ var init_orchestrate3 = __esm({
76527
77071
  "waves",
76528
77072
  {
76529
77073
  epicId: args.epicId,
76530
- ...args.via !== void 0 && { via: args.via }
77074
+ ...args.via !== void 0 && { via: args.via },
77075
+ ...args["hide-completed"] === true && { hideCompleted: true }
76531
77076
  },
76532
77077
  { command: "orchestrate" }
76533
77078
  );
@@ -77825,7 +78370,7 @@ __export(project_exports, {
77825
78370
  import { resolve as resolve9 } from "node:path";
77826
78371
  import {
77827
78372
  CleoError as CleoError10,
77828
- getProjectRoot as getProjectRoot64,
78373
+ getProjectRoot as getProjectRoot65,
77829
78374
  moveProject,
77830
78375
  projectLifecycle,
77831
78376
  renameProject,
@@ -77847,7 +78392,7 @@ function emitEngineFailure(error, operation) {
77847
78392
  }
77848
78393
  function resolveRootOrFail(operation) {
77849
78394
  try {
77850
- return getProjectRoot64();
78395
+ return getProjectRoot65();
77851
78396
  } catch (err) {
77852
78397
  const code = err instanceof CleoError10 && typeof err.details?.["code"] === "string" ? err.details["code"] : "E_NOT_CLEO_PROJECT";
77853
78398
  emitEngineFailure(
@@ -78633,7 +79178,7 @@ var refresh_memory_exports = {};
78633
79178
  __export(refresh_memory_exports, {
78634
79179
  refreshMemoryCommand: () => refreshMemoryCommand
78635
79180
  });
78636
- import { getProjectRoot as getProjectRoot65 } from "@cleocode/core";
79181
+ import { getProjectRoot as getProjectRoot66 } from "@cleocode/core";
78637
79182
  var refreshMemoryCommand;
78638
79183
  var init_refresh_memory = __esm({
78639
79184
  "packages/cleo/src/cli/commands/refresh-memory.ts"() {
@@ -78646,7 +79191,7 @@ var init_refresh_memory = __esm({
78646
79191
  description: "Regenerate .cleo/memory-bridge.md from brain.db"
78647
79192
  },
78648
79193
  async run() {
78649
- const projectDir = getProjectRoot65();
79194
+ const projectDir = getProjectRoot66();
78650
79195
  const { writeMemoryBridge } = await import("@cleocode/core/internal");
78651
79196
  const result = await writeMemoryBridge(projectDir);
78652
79197
  if (result.written) {
@@ -80232,7 +80777,7 @@ import fs3 from "node:fs";
80232
80777
  import path5 from "node:path";
80233
80778
  import {
80234
80779
  CleoError as CleoError12,
80235
- getProjectRoot as getProjectRoot66,
80780
+ getProjectRoot as getProjectRoot67,
80236
80781
  getTaskAccessor as getTaskAccessor3,
80237
80782
  parseConflictReport,
80238
80783
  setAtPath
@@ -80253,7 +80798,7 @@ var init_restore = __esm({
80253
80798
  description: "Apply manually-resolved conflicts from .cleo/restore-conflicts.md"
80254
80799
  },
80255
80800
  async run() {
80256
- const projectRoot = getProjectRoot66();
80801
+ const projectRoot = getProjectRoot67();
80257
80802
  const reportPath = path5.join(projectRoot, CLEO_DIR_NAME3, RESTORE_CONFLICTS_MD);
80258
80803
  if (!fs3.existsSync(reportPath)) {
80259
80804
  humanLine("No pending restore conflicts. Nothing to finalize.");
@@ -80342,6 +80887,11 @@ var init_restore = __esm({
80342
80887
  type: "string",
80343
80888
  description: "Backup scope to restore from: project or global (default: project)",
80344
80889
  default: "project"
80890
+ },
80891
+ "confirm-owner-store": {
80892
+ type: "boolean",
80893
+ description: "From inside a git worktree: allow overwriting the owning project's LIVE store (refused without it)",
80894
+ default: false
80345
80895
  }
80346
80896
  },
80347
80897
  async run({ args }) {
@@ -80352,7 +80902,8 @@ var init_restore = __esm({
80352
80902
  action: "restore.file",
80353
80903
  file: fileName,
80354
80904
  dryRun: args["dry-run"] || void 0,
80355
- scope
80905
+ scope,
80906
+ confirmOwnerStore: args["confirm-owner-store"] || void 0
80356
80907
  });
80357
80908
  if (!response.success) {
80358
80909
  const code = ExitCode[response.error?.code] ?? 1 /* GENERAL_ERROR */;
@@ -80616,7 +81167,7 @@ var init_restore = __esm({
80616
81167
  // packages/cleo/src/cli/commands/revert.ts
80617
81168
  var revert_exports = {};
80618
81169
  __export(revert_exports, {
80619
- revertCommand: () => revertCommand
81170
+ revertCommand: () => revertCommand2
80620
81171
  });
80621
81172
  import { readFile as readFile8 } from "node:fs/promises";
80622
81173
  import { join as join29 } from "node:path";
@@ -80684,14 +81235,14 @@ async function loadOwnerPubkeys(projectRoot) {
80684
81235
  return /* @__PURE__ */ new Set();
80685
81236
  }
80686
81237
  }
80687
- var OWNER_PUBKEYS_FILE, revertCommand;
81238
+ var OWNER_PUBKEYS_FILE, revertCommand2;
80688
81239
  var init_revert = __esm({
80689
81240
  "packages/cleo/src/cli/commands/revert.ts"() {
80690
81241
  "use strict";
80691
81242
  init_dist();
80692
81243
  init_renderers();
80693
81244
  OWNER_PUBKEYS_FILE = ".cleo/owner-pubkeys.json";
80694
- revertCommand = defineCommand({
81245
+ revertCommand2 = defineCommand({
80695
81246
  meta: {
80696
81247
  name: "revert",
80697
81248
  description: "Owner kill-switch: squash-revert all sentient merge commits from a receipt ID"
@@ -81176,8 +81727,8 @@ var init_saga = __esm({
81176
81727
  }
81177
81728
  },
81178
81729
  async run({ args }) {
81179
- const { sagas: sagas2, getProjectRoot: getProjectRoot72 } = await import("@cleocode/core");
81180
- const projectRoot = getProjectRoot72();
81730
+ const { sagas: sagas2, getProjectRoot: getProjectRoot73 } = await import("@cleocode/core");
81731
+ const projectRoot = getProjectRoot73();
81181
81732
  const sagaId = typeof args.sagaId === "string" && args.sagaId.length > 0 ? args.sagaId : void 0;
81182
81733
  const result = await sagas2.sagaNext(projectRoot, { sagaId });
81183
81734
  cliOutput(result.success ? result.data : result, { command: "saga", operation: "saga.next" });
@@ -83008,7 +83559,7 @@ var sequence_exports = {};
83008
83559
  __export(sequence_exports, {
83009
83560
  sequenceCommand: () => sequenceCommand
83010
83561
  });
83011
- import { getProjectRoot as getProjectRoot67 } from "@cleocode/core/internal";
83562
+ import { getProjectRoot as getProjectRoot68 } from "@cleocode/core/internal";
83012
83563
  var showCommand12, checkCommand7, repairCommand3, sequenceCommand;
83013
83564
  var init_sequence = __esm({
83014
83565
  "packages/cleo/src/cli/commands/sequence.ts"() {
@@ -83044,7 +83595,7 @@ var init_sequence = __esm({
83044
83595
  meta: { name: "repair", description: "Reset counter to max + 1 if behind" },
83045
83596
  async run() {
83046
83597
  const { repairSequence } = await import("@cleocode/core/internal");
83047
- const projectRoot = getProjectRoot67();
83598
+ const projectRoot = getProjectRoot68();
83048
83599
  const repair = await repairSequence(projectRoot);
83049
83600
  const result = {
83050
83601
  repaired: repair.repaired,
@@ -83641,8 +84192,8 @@ var init_session4 = __esm({
83641
84192
  "audit-scope": { type: "string", description: "Audit log scope (global|local)" }
83642
84193
  },
83643
84194
  async run({ args }) {
83644
- const { detectSessionDrift, getProjectRoot: getProjectRoot72 } = await import("@cleocode/core");
83645
- const projectRoot = await getProjectRoot72();
84195
+ const { detectSessionDrift, getProjectRoot: getProjectRoot73 } = await import("@cleocode/core");
84196
+ const projectRoot = await getProjectRoot73();
83646
84197
  const scope = args["audit-scope"] === "local" ? "local" : "global";
83647
84198
  const report = await detectSessionDrift({ projectRoot, auditScope: scope });
83648
84199
  cliOutput(report, { command: "session drift", operation: "session.drift" });
@@ -83902,7 +84453,8 @@ import {
83902
84453
  createDefaultWizardRunner,
83903
84454
  mergeConfigJson,
83904
84455
  printWhoamiSummaryAndOfferTui,
83905
- WizardInterruptError as WizardInterruptError2
84456
+ SetupConfigJsonError,
84457
+ WizardInterruptError as WizardInterruptError3
83906
84458
  } from "@cleocode/core/setup";
83907
84459
  function buildWizardOptions(args) {
83908
84460
  const out = {};
@@ -84060,12 +84612,12 @@ var init_setup = __esm({
84060
84612
  setupCommand2 = defineCommand({
84061
84613
  meta: {
84062
84614
  name: "setup",
84063
- description: "Interactive setup wizard \u2014 runs all 8 sections in canonical order (identity \u2192 llm \u2192 sentient \u2192 harness \u2192 brain \u2192 project-conventions \u2192 integrations \u2192 verification). Use --section <name> for a single section, --non-interactive with section-specific flags to configure without prompts, --config-json for fully scripted setup, or --reset to reconfigure already-set sections."
84615
+ description: "Interactive setup wizard \u2014 runs every section in canonical order (llm \u2192 system-one \u2192 models-roles \u2192 identity \u2192 sentient \u2192 project-conventions \u2192 harness \u2192 brain \u2192 integrations \u2192 telemetry \u2192 verification); system-one is optional. Use --section <name> for a single section, --non-interactive with section-specific flags to configure without prompts, --config-json for fully scripted setup, or --reset to reconfigure already-set sections."
84064
84616
  },
84065
84617
  args: {
84066
84618
  section: {
84067
84619
  type: "string",
84068
- description: "Run only one named section. Valid: llm | models-roles | identity | sentient | harness | brain | project-conventions | integrations | verification"
84620
+ description: "Run only one named section. Valid: llm | system-one | models-roles | identity | sentient | harness | brain | project-conventions | integrations | telemetry | verification"
84069
84621
  },
84070
84622
  "non-interactive": {
84071
84623
  type: "boolean",
@@ -84145,20 +84697,24 @@ var init_setup = __esm({
84145
84697
  }
84146
84698
  },
84147
84699
  async run({ args }) {
84148
- const io = new ReadlineWizardIO();
84700
+ const io = new ReadlineWizardIO(process.stdin, process.stderr);
84149
84701
  let result;
84150
84702
  try {
84151
84703
  result = await runSetup(args, io);
84152
84704
  } catch (err) {
84153
84705
  io.close();
84154
- if (err instanceof WizardInterruptError2 || err?.isWizardInterruptError) {
84706
+ if (err instanceof WizardInterruptError3 || err?.isWizardInterruptError) {
84155
84707
  process.stderr.write("Setup interrupted. Run 'cleo setup' to continue.\n");
84156
84708
  process.exit(130);
84157
84709
  }
84158
- if (err instanceof WizardInterruptError2) {
84710
+ if (err instanceof WizardInterruptError3) {
84159
84711
  process.stderr.write("Setup interrupted. Run 'cleo setup' to continue.\n");
84160
84712
  process.exit(130);
84161
84713
  }
84714
+ if (err instanceof SetupConfigJsonError) {
84715
+ cliError(err.message, 6, { name: err.codeName, fix: err.fix });
84716
+ process.exit(6);
84717
+ }
84162
84718
  if (StdinClosedError.is(err)) {
84163
84719
  cliError(err.message, 1, {
84164
84720
  name: err.codeName,
@@ -84359,8 +84915,11 @@ __export(skills_exports, {
84359
84915
  import {
84360
84916
  AgentsSkillsRealDirError,
84361
84917
  skills as coreSkills,
84918
+ restoreBundledSkillQuarantine,
84919
+ runBundledSkillPrune,
84362
84920
  runDoctorAdopt,
84363
- runDoctorBridge
84921
+ runDoctorBridge,
84922
+ unkeepBundledSkill
84364
84923
  } from "@cleocode/core";
84365
84924
  function buildSkillsDoctorAdoptAdapters() {
84366
84925
  return {
@@ -84388,10 +84947,11 @@ function buildSkillsDoctorAdoptAdapters() {
84388
84947
  }
84389
84948
  };
84390
84949
  }
84391
- var listCommand24, searchCommand4, findCommand8, validateCommand8, infoCommand, installCommand3, uninstallCommand2, enableCommand2, disableCommand2, refreshCommand, dispatchCommand, catalogCommand, precedenceCommand, depsCommand4, doctorBridgeCommand, doctorAdoptOrphansCommand, statsCommand6, importHermesCommand, migrateCommand2, pruneTelemetryCommand, spawnProvidersCommand, doctorDiagnoseCommand, doctorCommand4, proposePatchCommand, skillsCommand2;
84950
+ var listCommand24, searchCommand4, findCommand8, validateCommand8, infoCommand, installCommand3, uninstallCommand2, enableCommand2, disableCommand2, refreshCommand, dispatchCommand, catalogCommand, precedenceCommand, depsCommand4, doctorBridgeCommand, doctorAdoptOrphansCommand, doctorPruneCommand, doctorRestoreCommand, statsCommand6, importHermesCommand, migrateCommand2, pruneTelemetryCommand, spawnProvidersCommand, doctorDiagnoseCommand, doctorCommand4, proposePatchCommand, skillsCommand2;
84392
84951
  var init_skills2 = __esm({
84393
84952
  "packages/cleo/src/cli/commands/skills.ts"() {
84394
84953
  "use strict";
84954
+ init_src2();
84395
84955
  init_dist();
84396
84956
  init_cli();
84397
84957
  init_subcommand_guard();
@@ -84481,11 +85041,14 @@ var init_skills2 = __esm({
84481
85041
  }
84482
85042
  });
84483
85043
  validateCommand8 = defineCommand({
84484
- meta: { name: "validate", description: "Validate skill against protocol" },
85044
+ meta: {
85045
+ name: "validate",
85046
+ description: "Validate a SKILL.md; exits non-zero with findings. Every skill is checked against the Agent Skills standard (valid YAML; name and description present, well-formed, no tags). A CLEO bundled skill (packages/skills/skills, or an installed copy of one) must also meet the CLEO frontmatter contract gate 29 enforces: metadata.version X.Y.Z, metadata.tier, metadata.install, no top-level tier/core/category, name equal to its directory."
85047
+ },
84485
85048
  args: {
84486
85049
  "skill-name": {
84487
85050
  type: "positional",
84488
- description: "Skill name to validate",
85051
+ description: "Skill name, skill directory, or SKILL.md path",
84489
85052
  required: true
84490
85053
  }
84491
85054
  },
@@ -84827,6 +85390,86 @@ var init_skills2 = __esm({
84827
85390
  }
84828
85391
  }
84829
85392
  });
85393
+ doctorPruneCommand = defineCommand({
85394
+ meta: {
85395
+ name: "prune",
85396
+ description: "Quarantine bundled skills CLEO no longer installs (internal/retired), only where its install ledger proves ownership"
85397
+ },
85398
+ args: {
85399
+ "dry-run": {
85400
+ type: "boolean",
85401
+ description: "List what would be quarantined or kept; move nothing"
85402
+ },
85403
+ json: { type: "boolean", description: "Output as JSON (default)" },
85404
+ human: { type: "boolean", description: "Output in human-readable format" }
85405
+ },
85406
+ async run({ args }) {
85407
+ try {
85408
+ const receipt = await runBundledSkillPrune({ dryRun: args["dry-run"] === true });
85409
+ if (!receipt) {
85410
+ cliError("bundled @cleocode/skills not found", "E_NOT_FOUND", void 0, {
85411
+ operation: "skills.doctor.prune"
85412
+ });
85413
+ process.exit(4);
85414
+ }
85415
+ cliOutput(receipt, { command: "skills doctor prune", operation: "skills.doctor.prune" });
85416
+ } catch (error) {
85417
+ cliError(
85418
+ error instanceof Error ? error.message : String(error),
85419
+ "E_INTERNAL_ERROR",
85420
+ void 0,
85421
+ {
85422
+ operation: "skills.doctor.prune"
85423
+ }
85424
+ );
85425
+ process.exit(1);
85426
+ }
85427
+ }
85428
+ });
85429
+ doctorRestoreCommand = defineCommand({
85430
+ meta: {
85431
+ name: "restore",
85432
+ description: "List skill quarantines, or restore one by id (reverses cleo skills doctor prune). A restored skill is kept: prune never takes it again. --unkeep <name> hands it back to CLEO only when its files still hash exactly to the copy that was restored; a changed copy stays kept."
85433
+ },
85434
+ args: {
85435
+ id: { type: "positional", required: false, description: "Quarantine id (omit to list)" },
85436
+ unkeep: {
85437
+ type: "string",
85438
+ description: "Kept skill name to hand back to CLEO (only if unchanged since it was restored)"
85439
+ },
85440
+ json: { type: "boolean", description: "Output as JSON (default)" },
85441
+ human: { type: "boolean", description: "Output in human-readable format" }
85442
+ },
85443
+ async run({ args }) {
85444
+ try {
85445
+ if (typeof args.unkeep === "string" && args.unkeep !== "") {
85446
+ const outcome = await unkeepBundledSkill(args.unkeep);
85447
+ if (!outcome.unkept) {
85448
+ cliError(outcome.reason, 6 /* VALIDATION_ERROR */, {
85449
+ name: "E_VALIDATION",
85450
+ details: outcome
85451
+ });
85452
+ process.exit(6 /* VALIDATION_ERROR */);
85453
+ }
85454
+ cliOutput(outcome, { command: "skills doctor restore", operation: "skills.doctor.unkeep" });
85455
+ return;
85456
+ }
85457
+ const id = typeof args.id === "string" && args.id !== "" ? args.id : void 0;
85458
+ const result = await restoreBundledSkillQuarantine(id);
85459
+ cliOutput(result, { command: "skills doctor restore", operation: "skills.doctor.restore" });
85460
+ } catch (error) {
85461
+ cliError(
85462
+ error instanceof Error ? error.message : String(error),
85463
+ "E_INTERNAL_ERROR",
85464
+ void 0,
85465
+ {
85466
+ operation: "skills.doctor.restore"
85467
+ }
85468
+ );
85469
+ process.exit(1);
85470
+ }
85471
+ }
85472
+ });
84830
85473
  statsCommand6 = defineCommand({
84831
85474
  meta: {
84832
85475
  name: "stats",
@@ -85012,12 +85655,14 @@ var init_skills2 = __esm({
85012
85655
  doctorCommand4 = defineCommand({
85013
85656
  meta: {
85014
85657
  name: "doctor",
85015
- description: "Skill-store health checks (diagnose, bridge, adopt-orphans)"
85658
+ description: "Skill-store health checks (diagnose, bridge, adopt-orphans, prune, restore)"
85016
85659
  },
85017
85660
  subCommands: {
85018
85661
  diagnose: doctorDiagnoseCommand,
85019
85662
  bridge: doctorBridgeCommand,
85020
- "adopt-orphans": doctorAdoptOrphansCommand
85663
+ "adopt-orphans": doctorAdoptOrphansCommand,
85664
+ prune: doctorPruneCommand,
85665
+ restore: doctorRestoreCommand
85021
85666
  },
85022
85667
  async run({ cmd, rawArgs }) {
85023
85668
  if (isSubCommandDispatch(rawArgs, cmd.subCommands)) return;
@@ -86231,13 +86876,13 @@ var init_telemetry2 = __esm({
86231
86876
  // packages/cleo/src/cli/commands/templates/lib.ts
86232
86877
  import { readFileSync as readFileSync13 } from "node:fs";
86233
86878
  import { isAbsolute as isAbsolute3, resolve as resolve10 } from "node:path";
86234
- import { getProjectRoot as getProjectRoot68 } from "@cleocode/core";
86879
+ import { getProjectRoot as getProjectRoot69 } from "@cleocode/core";
86235
86880
  import { resolveSourcePathAbsolute } from "@cleocode/core/templates/registry";
86236
86881
  function resolveProjectRoot6(raw) {
86237
86882
  if (typeof raw === "string" && raw.length > 0) {
86238
86883
  return isAbsolute3(raw) ? raw : resolve10(process.cwd(), raw);
86239
86884
  }
86240
- return getProjectRoot68();
86885
+ return getProjectRoot69();
86241
86886
  }
86242
86887
  function readTemplateSource(entry) {
86243
86888
  const sourceAbsolute = resolveSourcePathAbsolute(entry);
@@ -87021,7 +87666,7 @@ __export(token_exports, {
87021
87666
  tokenCommand: () => tokenCommand
87022
87667
  });
87023
87668
  import { readFileSync as readFileSync17 } from "node:fs";
87024
- import { getProjectRoot as getProjectRoot69, measureTokenExchange, recordTokenExchange as recordTokenExchange2 } from "@cleocode/core/internal";
87669
+ import { getProjectRoot as getProjectRoot70, measureTokenExchange, recordTokenExchange as recordTokenExchange2 } from "@cleocode/core/internal";
87025
87670
  function readPayload(args, textKey, fileKey) {
87026
87671
  const text = args[textKey];
87027
87672
  const file = args[fileKey];
@@ -87185,7 +87830,7 @@ var init_token = __esm({
87185
87830
  domain: args.domain,
87186
87831
  operation: args.operation
87187
87832
  };
87188
- const result = args.record ? await recordTokenExchange2(getProjectRoot69(), input2) : await measureTokenExchange(input2);
87833
+ const result = args.record ? await recordTokenExchange2(getProjectRoot70(), input2) : await measureTokenExchange(input2);
87189
87834
  cliOutput(result, {
87190
87835
  command: "token",
87191
87836
  operation: args.record ? "admin.token.record" : "token.estimate"
@@ -87221,7 +87866,7 @@ __export(transcript_exports, {
87221
87866
  });
87222
87867
  import { homedir as homedir3 } from "node:os";
87223
87868
  import { join as join35 } from "node:path";
87224
- import { getProjectRoot as getProjectRoot70 } from "@cleocode/core";
87869
+ import { getProjectRoot as getProjectRoot71 } from "@cleocode/core";
87225
87870
  import {
87226
87871
  parseDurationMs,
87227
87872
  pruneTranscripts,
@@ -87251,7 +87896,7 @@ var init_transcript = __esm({
87251
87896
  async run({ args }) {
87252
87897
  if (args.pending) {
87253
87898
  try {
87254
- const projectRoot = getProjectRoot70();
87899
+ const projectRoot = getProjectRoot71();
87255
87900
  const { scanPendingTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
87256
87901
  const pending = await scanPendingTranscripts(projectRoot);
87257
87902
  cliOutput(
@@ -87348,7 +87993,7 @@ var init_transcript = __esm({
87348
87993
  async run({ args }) {
87349
87994
  const tier = args.tier ?? "warm";
87350
87995
  const dryRun = args["dry-run"] ?? false;
87351
- const projectRoot = getProjectRoot70();
87996
+ const projectRoot = getProjectRoot71();
87352
87997
  try {
87353
87998
  const { extractTranscript } = await import("@cleocode/core/memory/transcript-extractor.js");
87354
87999
  const { findSessionTranscriptPath, listAllTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
@@ -87464,7 +88109,7 @@ var init_transcript = __esm({
87464
88109
  const dryRun = args["dry-run"] ?? false;
87465
88110
  const olderThanHours = args["older-than-hours"] ? Number.parseInt(args["older-than-hours"], 10) : 24;
87466
88111
  const limit = args.limit ? Number.parseInt(args.limit, 10) : void 0;
87467
- const projectRoot = getProjectRoot70();
88112
+ const projectRoot = getProjectRoot71();
87468
88113
  try {
87469
88114
  const { extractTranscript } = await import("@cleocode/core/memory/transcript-extractor.js");
87470
88115
  const { listAllTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
@@ -88843,7 +89488,7 @@ var init_update = __esm({
88843
89488
  */
88844
89489
  reason: {
88845
89490
  type: "string",
88846
- description: "Operator override reason for AC-immutability guard (required to mutate --acceptance once stage >= implementation; T1590)"
89491
+ description: "Why this change is made. Recorded on the audit row of any priority/severity/kind/depends change (D11161; see `cleo history ranking <id>`), and required to mutate --acceptance once stage >= implementation (T1590)"
88847
89492
  },
88848
89493
  /**
88849
89494
  * Waiver for the critical-priority dependency declaration requirement.
@@ -89398,9 +90043,9 @@ var init_verify = __esm({
89398
90043
  return;
89399
90044
  }
89400
90045
  const { recordTaskDone } = await import("@cleocode/core/tasks/done-record.js");
89401
- const { getProjectRoot: getProjectRoot72 } = await import("@cleocode/core/paths.js");
90046
+ const { getProjectRoot: getProjectRoot73 } = await import("@cleocode/core/paths.js");
89402
90047
  const r = await recordTaskDone(args.taskId, {
89403
- projectRoot: getProjectRoot72(),
90048
+ projectRoot: getProjectRoot73(),
89404
90049
  ...parsed.options,
89405
90050
  ...args.agent ? { agent: args.agent } : {}
89406
90051
  });
@@ -89823,9 +90468,9 @@ var init_workgraph2 = __esm({
89823
90468
  },
89824
90469
  async run({ args }) {
89825
90470
  const { generatePlanningDoc } = await import("@cleocode/core/workgraph");
89826
- const { getProjectRoot: getProjectRoot72 } = await import("@cleocode/core");
90471
+ const { getProjectRoot: getProjectRoot73 } = await import("@cleocode/core");
89827
90472
  const { cliOutput: cliOutput2 } = await Promise.resolve().then(() => (init_renderers(), renderers_exports));
89828
- const projectRoot = getProjectRoot72();
90473
+ const projectRoot = getProjectRoot73();
89829
90474
  const audience = String(args.audience) === "agent" ? "agent" : "maintainer";
89830
90475
  const result = await generatePlanningDoc(projectRoot, {
89831
90476
  sagaId: String(args.sagaId),
@@ -89842,9 +90487,9 @@ var init_workgraph2 = __esm({
89842
90487
  async run() {
89843
90488
  const { validateWorkGraphStructure } = await import("@cleocode/core/workgraph");
89844
90489
  const { taskList: taskList2 } = await import("@cleocode/core/internal");
89845
- const { getProjectRoot: getProjectRoot72 } = await import("@cleocode/core");
90490
+ const { getProjectRoot: getProjectRoot73 } = await import("@cleocode/core");
89846
90491
  const { cliOutput: cliOutput2 } = await Promise.resolve().then(() => (init_renderers(), renderers_exports));
89847
- const projectRoot = getProjectRoot72();
90492
+ const projectRoot = getProjectRoot73();
89848
90493
  const listResult = await taskList2(projectRoot, { limit: 5e3 });
89849
90494
  const tasks = listResult.success ? listResult.data?.tasks ?? [] : [];
89850
90495
  const nodes = tasks.map((t) => ({
@@ -89863,9 +90508,9 @@ var init_workgraph2 = __esm({
89863
90508
  description: "One-shot saga-to-saga workgraph dashboard (tracking checklist)"
89864
90509
  },
89865
90510
  async run() {
89866
- const { sagas: sagas2, getProjectRoot: getProjectRoot72 } = await import("@cleocode/core");
90511
+ const { sagas: sagas2, getProjectRoot: getProjectRoot73 } = await import("@cleocode/core");
89867
90512
  const { cliOutput: cliOutput2 } = await Promise.resolve().then(() => (init_renderers(), renderers_exports));
89868
- const projectRoot = getProjectRoot72();
90513
+ const projectRoot = getProjectRoot73();
89869
90514
  const listResult = await sagas2.sagaList(projectRoot);
89870
90515
  if (!listResult.success) {
89871
90516
  cliOutput2(listResult, { command: "workgraph", operation: "workgraph.status" });
@@ -89931,7 +90576,7 @@ __export(worktree_exports, {
89931
90576
  worktreeCommand: () => worktreeCommand
89932
90577
  });
89933
90578
  import readline4 from "node:readline";
89934
- import { getProjectRoot as getProjectRoot71, listWorktrees as listWorktrees2 } from "@cleocode/core/internal";
90579
+ import { getProjectRoot as getProjectRoot72, listWorktrees as listWorktrees2 } from "@cleocode/core/internal";
89935
90580
  async function promptYesNo2(question) {
89936
90581
  return new Promise((resolve13) => {
89937
90582
  const rl = readline4.createInterface({ input: process.stdin, output: process.stdout });
@@ -90036,7 +90681,7 @@ var init_worktree3 = __esm({
90036
90681
  const staleDays = staleDaysRaw !== void 0 ? Number.parseInt(staleDaysRaw, 10) : void 0;
90037
90682
  const idleDaysRaw = typeof args["idle-days"] === "string" ? args["idle-days"] : void 0;
90038
90683
  const idleDays = idleDaysRaw !== void 0 ? Number.parseInt(idleDaysRaw, 10) : void 0;
90039
- const projectRoot = getProjectRoot71();
90684
+ const projectRoot = getProjectRoot72();
90040
90685
  const listResult = await listWorktrees2({
90041
90686
  projectRoot,
90042
90687
  ...staleDays !== void 0 && !Number.isNaN(staleDays) ? { staleDays } : {}
@@ -90557,7 +91202,7 @@ var COMMAND_MANIFEST = [
90557
91202
  {
90558
91203
  exportName: "decideCommand",
90559
91204
  name: "decide",
90560
- description: "Typed-decision (System One) provider: decide config (API URL + key), decide status (reachability probe), decide ask (one debug question). Unconfigured means heuristics answer.",
91205
+ description: "System One integration (typed decisions): decide config (provider + API key; wizard on a terminal), decide status (reachability probe), decide ask (one debug question), decide sites (the registered decision sites). Unconfigured means heuristics answer.",
90561
91206
  load: async () => (await Promise.resolve().then(() => (init_decide2(), decide_exports))).decideCommand
90562
91207
  },
90563
91208
  {
@@ -90680,6 +91325,12 @@ var COMMAND_MANIFEST = [
90680
91325
  description: "Report task rows whose id is not a valid task identifier \u2014 rows that `cleo list` returns ",
90681
91326
  load: async () => (await Promise.resolve().then(() => (init_doctor_malformed_ids(), doctor_malformed_ids_exports))).doctorMalformedIdsCommand
90682
91327
  },
91328
+ {
91329
+ exportName: "doctorManifestRowsCommand",
91330
+ name: "manifest-rows",
91331
+ 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.",
91332
+ load: async () => (await Promise.resolve().then(() => (init_doctor_manifest_rows(), doctor_manifest_rows_exports))).doctorManifestRowsCommand
91333
+ },
90683
91334
  {
90684
91335
  exportName: "doctorMemoryGuardCommand",
90685
91336
  name: "memory-guard",
@@ -91235,7 +91886,7 @@ var COMMAND_MANIFEST = [
91235
91886
  {
91236
91887
  exportName: "setupCommand",
91237
91888
  name: "setup",
91238
- description: "Interactive setup wizard \u2014 runs all 8 sections in canonical order (identity \u2192 llm \u2192 sentient \u2192 harness \u2192 brain \u2192 project-conventions \u2192 integrations \u2192 verification). Use --section <name> for a single section, --non-interactive with section-specific flags to configure without prompts, --config-json for fully scripted setup, or --reset to reconfigure already-set sections.",
91889
+ description: "Interactive setup wizard \u2014 runs every section in canonical order (llm \u2192 system-one \u2192 models-roles \u2192 identity \u2192 sentient \u2192 project-conventions \u2192 harness \u2192 brain \u2192 integrations \u2192 telemetry \u2192 verification); system-one is optional. Use --section <name> for a single section, --non-interactive with section-specific flags to configure without prompts, --config-json for fully scripted setup, or --reset to reconfigure already-set sections.",
91239
91890
  load: async () => (await Promise.resolve().then(() => (init_setup(), setup_exports))).setupCommand
91240
91891
  },
91241
91892
  {
@@ -91971,7 +92622,7 @@ async function runStartupMaintenance() {
91971
92622
  detectAndRemoveStrayProjectNexus,
91972
92623
  getGlobalSalt,
91973
92624
  getLogger: getLogger22,
91974
- getProjectRoot: getProjectRoot72,
92625
+ getProjectRoot: getProjectRoot73,
91975
92626
  isCleanupMarkerSet,
91976
92627
  migrateSignaldockToConduit,
91977
92628
  needsSignaldockToConduitMigration,
@@ -91980,7 +92631,7 @@ async function runStartupMaintenance() {
91980
92631
  } = await import("@cleocode/core/internal");
91981
92632
  let projectRootForCleanup = "";
91982
92633
  try {
91983
- projectRootForCleanup = getProjectRoot72();
92634
+ projectRootForCleanup = getProjectRoot73();
91984
92635
  } catch {
91985
92636
  }
91986
92637
  if (!isCleanupMarkerSet(CLI_VERSION, projectRootForCleanup)) {
@@ -92000,7 +92651,7 @@ async function runStartupMaintenance() {
92000
92651
  const isInitInvocation = process.argv.slice(2).some((a) => a === "init");
92001
92652
  if (!isInitInvocation) {
92002
92653
  try {
92003
- const _projectRootForMigration = getProjectRoot72();
92654
+ const _projectRootForMigration = getProjectRoot73();
92004
92655
  if (needsSignaldockToConduitMigration(_projectRootForMigration)) {
92005
92656
  const migrationResult = await migrateSignaldockToConduit(_projectRootForMigration);
92006
92657
  if (migrationResult.status === "failed") {