@cleocode/cleo 2026.5.114 → 2026.5.120

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -1388,6 +1388,40 @@ var init_animation_bridge = __esm({
1388
1388
  }
1389
1389
  });
1390
1390
 
1391
+ // packages/cleo/src/cli/output-context.ts
1392
+ function setOutputMode(mode) {
1393
+ currentMode = mode;
1394
+ }
1395
+ function getOutputMode() {
1396
+ return currentMode;
1397
+ }
1398
+ function isOutputMode(value) {
1399
+ return OUTPUT_MODES.includes(value);
1400
+ }
1401
+ var OUTPUT_MODES, currentMode;
1402
+ var init_output_context = __esm({
1403
+ "packages/cleo/src/cli/output-context.ts"() {
1404
+ "use strict";
1405
+ OUTPUT_MODES = ["envelope", "id", "table", "count", "silent"];
1406
+ currentMode = "envelope";
1407
+ }
1408
+ });
1409
+
1410
+ // packages/cleo/src/cli/summary-context.ts
1411
+ function setSummaryMode(on) {
1412
+ currentSummary = on;
1413
+ }
1414
+ function getSummaryMode() {
1415
+ return currentSummary;
1416
+ }
1417
+ var currentSummary;
1418
+ var init_summary_context = __esm({
1419
+ "packages/cleo/src/cli/summary-context.ts"() {
1420
+ "use strict";
1421
+ currentSummary = false;
1422
+ }
1423
+ });
1424
+
1391
1425
  // packages/contracts/src/acceptance-gate-schema.ts
1392
1426
  import { z } from "zod";
1393
1427
  var gateBaseSchema, fileAssertionSchema, testGateSchema, fileGateSchema, commandGateSchema, lintGateSchema, httpGateSchema, manualGateSchema, acceptanceGateSchema, gateResultDetailsSchema, acceptanceGateResultSchema, acceptanceItemSchema, acceptanceArraySchema;
@@ -4248,6 +4282,39 @@ var init_operations_registry = __esm({
4248
4282
  }
4249
4283
  ]
4250
4284
  },
4285
+ {
4286
+ gateway: "mutate",
4287
+ domain: "tasks",
4288
+ operation: "relates.remove",
4289
+ description: "tasks.relates.remove (mutate) \u2014 delete a relation between two tasks. Pass `type` to scope deletion to a single relation kind; omit to remove any type.",
4290
+ tier: 1,
4291
+ idempotent: true,
4292
+ sessionRequired: false,
4293
+ requiredParams: ["taskId", "relatedId"],
4294
+ params: [
4295
+ {
4296
+ name: "taskId",
4297
+ type: "string",
4298
+ required: true,
4299
+ description: "Source task ID",
4300
+ cli: { positional: true }
4301
+ },
4302
+ {
4303
+ name: "relatedId",
4304
+ type: "string",
4305
+ required: true,
4306
+ description: "Target task ID to remove the relation to",
4307
+ cli: { positional: true }
4308
+ },
4309
+ {
4310
+ name: "type",
4311
+ type: "string",
4312
+ required: false,
4313
+ description: "Optional relation type (blocks|related|duplicates|absorbs|fixes|extends|supersedes). Omit to remove any type.",
4314
+ cli: { flag: "type" }
4315
+ }
4316
+ ]
4317
+ },
4251
4318
  // === saga sub-domain (ADR-073 — above-epic grouping tier) ===
4252
4319
  {
4253
4320
  gateway: "mutate",
@@ -8533,6 +8600,39 @@ var init_operations_registry = __esm({
8533
8600
  }
8534
8601
  ]
8535
8602
  },
8603
+ // ── docs.supersede (T10162) ──────────────────────────────────────────────
8604
+ {
8605
+ gateway: "mutate",
8606
+ domain: "docs",
8607
+ operation: "supersede",
8608
+ description: "docs.supersede (mutate) \u2014 atomically flip an older doc to `superseded` and link both rows via the supersedes/superseded_by self-FK pointers (T10162 \xB7 Saga T9855)",
8609
+ tier: 1,
8610
+ idempotent: true,
8611
+ sessionRequired: false,
8612
+ requiredParams: ["oldSlug", "newSlug"],
8613
+ params: [
8614
+ {
8615
+ name: "oldSlug",
8616
+ type: "string",
8617
+ required: true,
8618
+ description: "Slug of the doc being replaced",
8619
+ cli: { positional: true }
8620
+ },
8621
+ {
8622
+ name: "newSlug",
8623
+ type: "string",
8624
+ required: true,
8625
+ description: "Slug of the doc that replaces oldSlug",
8626
+ cli: { positional: true }
8627
+ },
8628
+ {
8629
+ name: "reason",
8630
+ type: "string",
8631
+ required: false,
8632
+ description: "Optional human-readable reason carried back on the response"
8633
+ }
8634
+ ]
8635
+ },
8536
8636
  // ── docs.generate (T798) ─────────────────────────────────────────────────
8537
8637
  {
8538
8638
  gateway: "query",
@@ -8558,6 +8658,55 @@ var init_operations_registry = __esm({
8558
8658
  }
8559
8659
  ]
8560
8660
  },
8661
+ // ── docs.update (T10161 — Epic T10157 / Saga T9855) ──────────────────────
8662
+ {
8663
+ gateway: "mutate",
8664
+ domain: "docs",
8665
+ operation: "update",
8666
+ description: "docs.update (mutate) \u2014 replace blob content for an existing slug while preserving the slug. New sha256 + new attachment row; the old row stays reachable by ID for history. NO supersession edge (use `cleo docs supersede` for that). Audit log entry appended to .cleo/audit/docs-versioning.jsonl (squashed within a 5-min window).",
8667
+ tier: 1,
8668
+ idempotent: false,
8669
+ sessionRequired: false,
8670
+ requiredParams: ["slug"],
8671
+ params: [
8672
+ {
8673
+ name: "slug",
8674
+ type: "string",
8675
+ required: true,
8676
+ description: "Slug of the existing attachment to update"
8677
+ },
8678
+ {
8679
+ name: "file",
8680
+ type: "string",
8681
+ required: false,
8682
+ description: "Path to a local file containing the new content"
8683
+ },
8684
+ {
8685
+ name: "content",
8686
+ type: "string",
8687
+ required: false,
8688
+ description: "Inline UTF-8 content (mutually exclusive with file)"
8689
+ },
8690
+ {
8691
+ name: "message",
8692
+ type: "string",
8693
+ required: false,
8694
+ description: "One-line summary describing the change (recorded in the audit log)"
8695
+ },
8696
+ {
8697
+ name: "status",
8698
+ type: "string",
8699
+ required: false,
8700
+ description: 'Override the new lifecycle status. Defaults to "draft" on every update. Valid: draft|proposed|accepted|superseded|archived|deprecated.'
8701
+ },
8702
+ {
8703
+ name: "attachedBy",
8704
+ type: "string",
8705
+ required: false,
8706
+ description: 'Agent identity that performed the update (defaults to "human")'
8707
+ }
8708
+ ]
8709
+ },
8561
8710
  // ── playbook.* HITL CLI surface (T935) ───────────────────────────────────
8562
8711
  {
8563
8712
  gateway: "mutate",
@@ -12520,6 +12669,174 @@ var init_normalizer = __esm({
12520
12669
  }
12521
12670
  });
12522
12671
 
12672
+ // packages/cleo/src/cli/renderers/output-mode.ts
12673
+ function extractIds(data) {
12674
+ if (data === null || typeof data !== "object") return [];
12675
+ const rec = data;
12676
+ const task = rec["task"];
12677
+ if (task && typeof task === "object") {
12678
+ const id2 = task["id"];
12679
+ if (typeof id2 === "string") return [id2];
12680
+ }
12681
+ const tasks = rec["tasks"];
12682
+ if (Array.isArray(tasks)) {
12683
+ return tasks.map((t) => t && typeof t === "object" ? t["id"] : void 0).filter((id2) => typeof id2 === "string");
12684
+ }
12685
+ const items = rec["items"];
12686
+ if (Array.isArray(items)) {
12687
+ return items.map((t) => t && typeof t === "object" ? t["id"] : void 0).filter((id2) => typeof id2 === "string");
12688
+ }
12689
+ const id = rec["id"];
12690
+ if (typeof id === "string") return [id];
12691
+ return [];
12692
+ }
12693
+ function extractCount(data) {
12694
+ if (data === null || typeof data !== "object") return 0;
12695
+ const rec = data;
12696
+ const total = rec["total"];
12697
+ if (typeof total === "number" && Number.isFinite(total)) return total;
12698
+ const tasks = rec["tasks"];
12699
+ if (Array.isArray(tasks)) return tasks.length;
12700
+ const items = rec["items"];
12701
+ if (Array.isArray(items)) return items.length;
12702
+ if (rec["task"] && typeof rec["task"] === "object") return 1;
12703
+ if (typeof rec["id"] === "string") return 1;
12704
+ return 0;
12705
+ }
12706
+ function truncate(value, max) {
12707
+ if (value.length <= max) return value;
12708
+ return value.slice(0, Math.max(0, max - 1)) + "\u2026";
12709
+ }
12710
+ function renderTableList(tasks) {
12711
+ if (tasks.length === 0) return "No rows.";
12712
+ const COL_TITLE_MAX = 60;
12713
+ const rows = tasks.map((t) => ({
12714
+ id: typeof t["id"] === "string" ? t["id"] : "",
12715
+ status: typeof t["status"] === "string" ? t["status"] : "",
12716
+ priority: typeof t["priority"] === "string" ? t["priority"] : "",
12717
+ title: truncate(typeof t["title"] === "string" ? t["title"] : "", COL_TITLE_MAX)
12718
+ }));
12719
+ const widths = {
12720
+ id: Math.max(2, ...rows.map((r) => r.id.length)),
12721
+ status: Math.max(6, ...rows.map((r) => r.status.length)),
12722
+ priority: Math.max(8, ...rows.map((r) => r.priority.length)),
12723
+ title: Math.max(5, ...rows.map((r) => r.title.length))
12724
+ };
12725
+ const pad = (s, w) => s + " ".repeat(Math.max(0, w - s.length));
12726
+ const header = `${pad("id", widths.id)} ${pad("status", widths.status)} ${pad(
12727
+ "priority",
12728
+ widths.priority
12729
+ )} ${pad("title", widths.title)}`;
12730
+ const sep2 = `${"-".repeat(widths.id)} ${"-".repeat(widths.status)} ${"-".repeat(
12731
+ widths.priority
12732
+ )} ${"-".repeat(widths.title)}`;
12733
+ const body = rows.map(
12734
+ (r) => `${pad(r.id, widths.id)} ${pad(r.status, widths.status)} ${pad(
12735
+ r.priority,
12736
+ widths.priority
12737
+ )} ${pad(r.title, widths.title)}`
12738
+ ).join("\n");
12739
+ return `${header}
12740
+ ${sep2}
12741
+ ${body}`;
12742
+ }
12743
+ function renderTableGeneric(data) {
12744
+ const entries = Object.entries(data);
12745
+ if (entries.length === 0) return "(empty)";
12746
+ const rows = entries.map(([k, v]) => ({
12747
+ field: k,
12748
+ value: v === null || v === void 0 ? "" : typeof v === "object" ? JSON.stringify(v) : String(v)
12749
+ }));
12750
+ const VAL_MAX = 80;
12751
+ for (const r of rows) r.value = truncate(r.value, VAL_MAX);
12752
+ const widths = {
12753
+ field: Math.max(5, ...rows.map((r) => r.field.length)),
12754
+ value: Math.max(5, ...rows.map((r) => r.value.length))
12755
+ };
12756
+ const pad = (s, w) => s + " ".repeat(Math.max(0, w - s.length));
12757
+ const header = `${pad("field", widths.field)} ${pad("value", widths.value)}`;
12758
+ const sep2 = `${"-".repeat(widths.field)} ${"-".repeat(widths.value)}`;
12759
+ const body = rows.map((r) => `${pad(r.field, widths.field)} ${pad(r.value, widths.value)}`).join("\n");
12760
+ return `${header}
12761
+ ${sep2}
12762
+ ${body}`;
12763
+ }
12764
+ function renderSummary2(data) {
12765
+ if (data === null || typeof data !== "object") {
12766
+ return { text: "" };
12767
+ }
12768
+ const rec = data;
12769
+ const tasks = rec["tasks"];
12770
+ if (Array.isArray(tasks)) {
12771
+ return { text: renderSummaryList(tasks) };
12772
+ }
12773
+ const items = rec["items"];
12774
+ if (Array.isArray(items)) {
12775
+ return { text: renderSummaryList(items) };
12776
+ }
12777
+ const task = rec["task"];
12778
+ if (task && typeof task === "object") {
12779
+ return { text: renderSummaryRow(task) };
12780
+ }
12781
+ if (typeof rec["id"] === "string") {
12782
+ return { text: renderSummaryRow(rec) };
12783
+ }
12784
+ return { text: "" };
12785
+ }
12786
+ function renderSummaryRow(record) {
12787
+ const id = typeof record["id"] === "string" ? record["id"] : "";
12788
+ const status = typeof record["status"] === "string" ? record["status"] : "";
12789
+ const title = truncate(typeof record["title"] === "string" ? record["title"] : "", 60);
12790
+ return `${id} [${status}] ${title}`;
12791
+ }
12792
+ function renderSummaryList(rows) {
12793
+ if (rows.length === 0) return "No rows.";
12794
+ const lines = [];
12795
+ for (const row of rows) {
12796
+ if (!row || typeof row !== "object") continue;
12797
+ const rec = row;
12798
+ if (typeof rec["id"] !== "string") continue;
12799
+ lines.push(renderSummaryRow(rec));
12800
+ }
12801
+ return lines.length === 0 ? "No rows." : lines.join("\n");
12802
+ }
12803
+ function renderOutputMode(mode, data) {
12804
+ switch (mode) {
12805
+ case "id": {
12806
+ const ids = extractIds(data);
12807
+ return { text: ids.length === 0 ? "" : ids.join("\n") };
12808
+ }
12809
+ case "count": {
12810
+ return { text: String(extractCount(data)) };
12811
+ }
12812
+ case "table": {
12813
+ if (data && typeof data === "object") {
12814
+ const rec = data;
12815
+ const tasks = rec["tasks"];
12816
+ if (Array.isArray(tasks)) {
12817
+ return { text: renderTableList(tasks) };
12818
+ }
12819
+ const items = rec["items"];
12820
+ if (Array.isArray(items)) {
12821
+ return { text: renderTableList(items) };
12822
+ }
12823
+ return { text: renderTableGeneric(rec) };
12824
+ }
12825
+ return { text: data === null || data === void 0 ? "(empty)" : String(data) };
12826
+ }
12827
+ case "silent": {
12828
+ return { text: null };
12829
+ }
12830
+ case "envelope":
12831
+ throw new Error("renderOutputMode: envelope mode must be handled by caller");
12832
+ }
12833
+ }
12834
+ var init_output_mode = __esm({
12835
+ "packages/cleo/src/cli/renderers/output-mode.ts"() {
12836
+ "use strict";
12837
+ }
12838
+ });
12839
+
12523
12840
  // packages/cleo/src/cli/renderers/index.ts
12524
12841
  var renderers_exports = {};
12525
12842
  __export(renderers_exports, {
@@ -12535,7 +12852,9 @@ __export(renderers_exports, {
12535
12852
  import { randomUUID } from "node:crypto";
12536
12853
  import {
12537
12854
  drainWarnings,
12855
+ extractByJsonPointer,
12538
12856
  formatSuccess,
12857
+ isJsonPointer,
12539
12858
  metaFooter,
12540
12859
  pagerFooter,
12541
12860
  renderAuditReconstruct,
@@ -12593,7 +12912,8 @@ import {
12593
12912
  renderStop,
12594
12913
  renderTree as renderTree2,
12595
12914
  renderVersion,
12596
- renderWaves
12915
+ renderWaves,
12916
+ serializePointerValue
12597
12917
  } from "@cleocode/core";
12598
12918
  import { applyFieldFilter, extractFieldFromResult } from "@cleocode/lafs";
12599
12919
  import {
@@ -12615,11 +12935,60 @@ function pickDecoratorMetaExtensionsLocal(responseMeta) {
12615
12935
  const out = {};
12616
12936
  if (responseMeta["_nexus"] !== void 0) out["_nexus"] = responseMeta["_nexus"];
12617
12937
  if (responseMeta["deprecated"] !== void 0) out["deprecated"] = responseMeta["deprecated"];
12938
+ if (responseMeta["suggestedNext"] !== void 0) {
12939
+ out["suggestedNext"] = responseMeta["suggestedNext"];
12940
+ }
12941
+ if (responseMeta["projection"] !== void 0) {
12942
+ out["projection"] = responseMeta["projection"];
12943
+ }
12618
12944
  return out;
12619
12945
  }
12946
+ function buildEnvelopeForPointer(data, opts) {
12947
+ const decoratorExt = pickDecoratorMetaExtensionsLocal(opts.responseMeta);
12948
+ const meta = {
12949
+ ...decoratorExt,
12950
+ ...opts.extensions ?? {},
12951
+ operation: opts.operation ?? "cli.output"
12952
+ };
12953
+ if (opts.message) meta["message"] = opts.message;
12954
+ const envelope = {
12955
+ success: true,
12956
+ data,
12957
+ meta
12958
+ };
12959
+ if (opts.page) envelope["page"] = opts.page;
12960
+ return envelope;
12961
+ }
12620
12962
  function cliOutput(data, opts) {
12621
12963
  const ctx = getFormatContext();
12622
12964
  const fieldCtx = getFieldContext();
12965
+ const outputMode = getOutputMode();
12966
+ const summary = getSummaryMode();
12967
+ if (outputMode !== "envelope" && !fieldCtx.field) {
12968
+ const out = renderOutputMode(outputMode, data);
12969
+ if (out.text !== null && out.text.length > 0) {
12970
+ process.stdout.write(out.text + "\n");
12971
+ }
12972
+ return;
12973
+ }
12974
+ if (summary && !fieldCtx.field) {
12975
+ const out = renderSummary2(data);
12976
+ if (out.text !== null && out.text.length > 0) {
12977
+ process.stdout.write(out.text + "\n");
12978
+ }
12979
+ return;
12980
+ }
12981
+ if (fieldCtx.field && isJsonPointer(fieldCtx.field)) {
12982
+ const envelope = buildEnvelopeForPointer(data, opts);
12983
+ const value = extractByJsonPointer(envelope, fieldCtx.field);
12984
+ if (value === void 0) {
12985
+ cliError(`Pointer "${fieldCtx.field}" did not resolve`, 4, { name: "E_FIELD_NOT_FOUND" });
12986
+ process.exit(4);
12987
+ }
12988
+ process.stdout.write(`${serializePointerValue(value)}
12989
+ `);
12990
+ return;
12991
+ }
12623
12992
  if (ctx.format === "human") {
12624
12993
  let dataToRender = data;
12625
12994
  let fieldExtracted = false;
@@ -12769,6 +13138,12 @@ function isHumanOutput() {
12769
13138
  }
12770
13139
  function cliError(message, code, details, meta) {
12771
13140
  const ctx = getFormatContext();
13141
+ const outputMode = getOutputMode();
13142
+ if (outputMode === "silent") {
13143
+ process.stderr.write(`Error: ${message}${code ? ` (${code})` : ""}
13144
+ `);
13145
+ return;
13146
+ }
12772
13147
  if (ctx.format === "human") {
12773
13148
  process.stderr.write(`Error: ${message}${code ? ` (${code})` : ""}
12774
13149
  `);
@@ -12811,8 +13186,11 @@ var init_renderers = __esm({
12811
13186
  "use strict";
12812
13187
  init_field_context();
12813
13188
  init_format_context();
13189
+ init_output_context();
13190
+ init_summary_context();
12814
13191
  init_lafs_validator();
12815
13192
  init_normalizer();
13193
+ init_output_mode();
12816
13194
  renderers = {
12817
13195
  // Task CRUD
12818
13196
  show: renderShow,
@@ -17005,18 +17383,25 @@ import { resolve as resolve2 } from "node:path";
17005
17383
  import { pushWarning } from "@cleocode/core";
17006
17384
  import {
17007
17385
  AUTO_TOKEN,
17386
+ allocateAdrSlug,
17008
17387
  allocateAutoSlugForDispatch,
17388
+ consumeReservedSlug,
17009
17389
  createAttachmentStore,
17010
17390
  createAttachmentStoreV2,
17011
17391
  generateDocsLlmsTxt,
17012
17392
  getCleoDirAbsolute,
17013
17393
  getProjectRoot as getProjectRoot5,
17394
+ isLifecycleStatus,
17014
17395
  memoryObserve as memoryObserve2,
17015
17396
  parseChangesetFrontmatter,
17016
17397
  releaseReservedSlug,
17017
17398
  reserveSlugForDispatch,
17018
17399
  resolveAttachmentBackend,
17019
17400
  SlugCollisionError,
17401
+ SUPERSEDE_NOT_FOUND_CODE,
17402
+ SUPERSEDE_SAME_SLUG_CODE,
17403
+ supersedeDoc,
17404
+ updateDocBySlug,
17020
17405
  validateDocBody,
17021
17406
  writeChangesetEntry
17022
17407
  } from "@cleocode/core/internal";
@@ -17494,6 +17879,7 @@ var init_docs2 = __esm({
17494
17879
  labels: rawLabels,
17495
17880
  attachedBy: rawAttachedBy,
17496
17881
  slug: rawSlug,
17882
+ title: rawTitle,
17497
17883
  type: rawType,
17498
17884
  strict: strictMode
17499
17885
  } = params;
@@ -17601,6 +17987,19 @@ var init_docs2 = __esm({
17601
17987
  if (err.code === "E_FILE_WRITE_FAILED") {
17602
17988
  return lafsError("E_FILE_ERROR", err.message, "add");
17603
17989
  }
17990
+ if (err.code === "E_SLUG_RESERVED") {
17991
+ return {
17992
+ success: false,
17993
+ error: {
17994
+ code: "E_SLUG_RESERVED",
17995
+ message: err.message,
17996
+ details: {
17997
+ suggestions: err.suggestions,
17998
+ aliases: err.aliases
17999
+ }
18000
+ }
18001
+ };
18002
+ }
17604
18003
  return lafsError("E_SSOT_WRITE_FAILED", err.message, "add");
17605
18004
  }
17606
18005
  const changesetPayload = {
@@ -17633,14 +18032,31 @@ var init_docs2 = __esm({
17633
18032
  "add"
17634
18033
  );
17635
18034
  }
18035
+ let adrNumber;
18036
+ if (type2 === "adr" && slug === void 0) {
18037
+ if (typeof rawTitle !== "string" || rawTitle.trim().length === 0) {
18038
+ return lafsError(
18039
+ "E_VALIDATION",
18040
+ "title is required when type=adr and slug is omitted \u2014 the allocator needs a title to assemble adr-NNN-<kebab-title>",
18041
+ "add"
18042
+ );
18043
+ }
18044
+ const allocation = await allocateAdrSlug(getProjectRoot5(), { title: rawTitle });
18045
+ if (!allocation.ok) {
18046
+ return lafsError(allocation.code, allocation.message, "add");
18047
+ }
18048
+ slug = allocation.slug;
18049
+ adrNumber = allocation.number;
18050
+ }
17636
18051
  if (type2 !== void 0 && slug !== void 0) {
17637
18052
  const patternCheck = getDocKindRegistry().validateSlug(type2, slug);
17638
18053
  if (!patternCheck.ok) {
18054
+ if (adrNumber !== void 0) releaseReservedSlug(slug);
17639
18055
  const exampleHint = patternCheck.example ? ` (example: ${patternCheck.example})` : "";
17640
18056
  return lafsError("E_SLUG_PATTERN_MISMATCH", `${patternCheck.error}${exampleHint}`, "add");
17641
18057
  }
17642
18058
  }
17643
- if (slug !== void 0) {
18059
+ if (slug !== void 0 && adrNumber === void 0) {
17644
18060
  const reservation = await reserveSlugForDispatch(getProjectRoot5(), {
17645
18061
  kind: type2 ?? "",
17646
18062
  slug
@@ -17741,6 +18157,7 @@ var init_docs2 = __esm({
17741
18157
  }
17742
18158
  throw err;
17743
18159
  }
18160
+ if (adrNumber !== void 0 && slug !== void 0) consumeReservedSlug(slug);
17744
18161
  let backend = "legacy";
17745
18162
  try {
17746
18163
  const v2 = createAttachmentStoreV2(getProjectRoot5());
@@ -17782,7 +18199,8 @@ var init_docs2 = __esm({
17782
18199
  // Cast: core returns 'llmtxt'|'legacy'; contracts uses 'legacy'|'llmstxt-v2' (T1529)
17783
18200
  attachmentBackend: backend,
17784
18201
  ...slug !== void 0 ? { slug } : {},
17785
- ...type2 !== void 0 ? { type: type2 } : {}
18202
+ ...type2 !== void 0 ? { type: type2 } : {},
18203
+ ...adrNumber !== void 0 ? { adrNumber } : {}
17786
18204
  },
17787
18205
  "add"
17788
18206
  );
@@ -17823,6 +18241,7 @@ var init_docs2 = __esm({
17823
18241
  }
17824
18242
  throw err;
17825
18243
  }
18244
+ if (adrNumber !== void 0 && slug !== void 0) consumeReservedSlug(slug);
17826
18245
  import("@cleocode/core/internal").then(
17827
18246
  ({ ensureLlmtxtNode }) => ensureLlmtxtNode(getProjectRoot5(), meta.sha256, `${ownerType}:${ownerId}`, url)
17828
18247
  ).catch(() => {
@@ -17849,7 +18268,8 @@ var init_docs2 = __esm({
17849
18268
  // Cast: core returns 'llmtxt'|'legacy'; contracts uses 'legacy'|'llmstxt-v2' (T1529)
17850
18269
  attachmentBackend: backend,
17851
18270
  ...slug !== void 0 ? { slug } : {},
17852
- ...type2 !== void 0 ? { type: type2 } : {}
18271
+ ...type2 !== void 0 ? { type: type2 } : {},
18272
+ ...adrNumber !== void 0 ? { adrNumber } : {}
17853
18273
  },
17854
18274
  "add"
17855
18275
  );
@@ -17907,10 +18327,90 @@ var init_docs2 = __esm({
17907
18327
  },
17908
18328
  "remove"
17909
18329
  );
18330
+ },
18331
+ // ── docs.update (T10161 — E12.C4 / Saga T9855) ─────────────────────────────
18332
+ update: async (params) => {
18333
+ const { slug: rawSlug, file: filePath, content: inlineContent, status: rawStatus } = params;
18334
+ if (typeof rawSlug !== "string" || rawSlug.length === 0) {
18335
+ return lafsError("E_INVALID_INPUT", "slug is required", "update");
18336
+ }
18337
+ const hasFile = typeof filePath === "string" && filePath.length > 0;
18338
+ const hasContent = typeof inlineContent === "string";
18339
+ if (hasFile === hasContent) {
18340
+ return lafsError(
18341
+ "E_INVALID_INPUT",
18342
+ "Provide exactly one of --file <path> or --content <text>",
18343
+ "update",
18344
+ 'Use `cleo docs update <slug> --file ./new.md` OR `cleo docs update <slug> --content "..."`.'
18345
+ );
18346
+ }
18347
+ if (rawStatus !== void 0 && !isLifecycleStatus(rawStatus)) {
18348
+ return lafsError(
18349
+ "E_INVALID_INPUT",
18350
+ `status must be one of: draft|proposed|accepted|superseded|archived|deprecated \u2014 got '${String(rawStatus)}'`,
18351
+ "update"
18352
+ );
18353
+ }
18354
+ const projectRoot = getProjectRoot5();
18355
+ const resolvedParams = hasFile ? { ...params, file: resolve2(filePath) } : params;
18356
+ const outcome = await updateDocBySlug(projectRoot, resolvedParams);
18357
+ if (!outcome.ok) {
18358
+ return lafsError(outcome.error.code, outcome.error.message, "update");
18359
+ }
18360
+ return lafsSuccess(
18361
+ {
18362
+ slug: outcome.result.slug,
18363
+ ...outcome.result.type !== null ? { type: outcome.result.type } : {},
18364
+ attachmentId: outcome.result.attachmentId,
18365
+ previousAttachmentId: outcome.result.previousAttachmentId,
18366
+ sha256: outcome.result.sha256,
18367
+ previousSha256: outcome.result.previousSha256,
18368
+ changed: outcome.result.changed,
18369
+ lifecycleStatus: outcome.result.lifecycleStatus,
18370
+ updatedAt: outcome.result.updatedAt,
18371
+ version: outcome.result.version,
18372
+ squashed: outcome.result.squashed
18373
+ },
18374
+ "update"
18375
+ );
18376
+ },
18377
+ // ── docs.supersede ─────────────────────────────────────────────────────────
18378
+ supersede: async (params) => {
18379
+ const { oldSlug, newSlug, reason } = params;
18380
+ if (typeof oldSlug !== "string" || oldSlug.length === 0) {
18381
+ return lafsError("E_INVALID_INPUT", "<oldSlug> is required", "supersede");
18382
+ }
18383
+ if (typeof newSlug !== "string" || newSlug.length === 0) {
18384
+ return lafsError("E_INVALID_INPUT", "<newSlug> is required", "supersede");
18385
+ }
18386
+ try {
18387
+ const result = await supersedeDoc(getProjectRoot5(), {
18388
+ oldSlug,
18389
+ newSlug,
18390
+ ...typeof reason === "string" && reason.length > 0 ? { reason } : {}
18391
+ });
18392
+ const payload = {
18393
+ oldSlug: result.oldSlug,
18394
+ newSlug: result.newSlug,
18395
+ oldAttachmentId: result.oldAttachmentId,
18396
+ newAttachmentId: result.newAttachmentId,
18397
+ supersededAt: result.supersededAt,
18398
+ edgeId: result.edgeId,
18399
+ ...result.reason !== void 0 ? { reason: result.reason } : {}
18400
+ };
18401
+ return lafsSuccess(payload, "supersede");
18402
+ } catch (err) {
18403
+ const code = err && typeof err === "object" && "code" in err && typeof err.code === "number" ? (
18404
+ // Map ExitCode (number) → stable LAFS string code expected by callers.
18405
+ err.code === 4 ? SUPERSEDE_NOT_FOUND_CODE : err.code === 6 ? SUPERSEDE_SAME_SLUG_CODE : "E_INTERNAL"
18406
+ ) : "E_INTERNAL";
18407
+ const message = err instanceof Error ? err.message : "supersede failed";
18408
+ return lafsError(code, message, "supersede");
18409
+ }
17910
18410
  }
17911
18411
  });
17912
18412
  QUERY_OPS3 = /* @__PURE__ */ new Set(["list", "fetch", "generate"]);
17913
- MUTATE_OPS3 = /* @__PURE__ */ new Set(["add", "remove"]);
18413
+ MUTATE_OPS3 = /* @__PURE__ */ new Set(["add", "remove", "update", "supersede"]);
17914
18414
  DocsHandler = class {
17915
18415
  // -----------------------------------------------------------------------
17916
18416
  // Query
@@ -17969,7 +18469,7 @@ var init_docs2 = __esm({
17969
18469
  getSupportedOperations() {
17970
18470
  return {
17971
18471
  query: ["list", "fetch", "generate"],
17972
- mutate: ["add", "remove"]
18472
+ mutate: ["add", "remove", "update", "supersede"]
17973
18473
  };
17974
18474
  }
17975
18475
  };
@@ -20430,6 +20930,9 @@ function pickDecoratorMetaExtensions(responseMeta) {
20430
20930
  const out = {};
20431
20931
  if (responseMeta["_nexus"] !== void 0) out["_nexus"] = responseMeta["_nexus"];
20432
20932
  if (responseMeta["deprecated"] !== void 0) out["deprecated"] = responseMeta["deprecated"];
20933
+ if (responseMeta["suggestedNext"] !== void 0) {
20934
+ out["suggestedNext"] = responseMeta["suggestedNext"];
20935
+ }
20433
20936
  return out;
20434
20937
  }
20435
20938
  function buildNexusMetaExtensions(operation, params = {}) {
@@ -26817,7 +27320,8 @@ async function orchestrateSpawnOp(params) {
26817
27320
  getProjectRoot11(),
26818
27321
  params.tier,
26819
27322
  params.noWorktree,
26820
- params.spawnScope
27323
+ params.spawnScope,
27324
+ params.atomicityScope
26821
27325
  );
26822
27326
  }
26823
27327
  async function orchestrateHandoffOp(params) {
@@ -27654,12 +28158,15 @@ var init_orchestrate2 = __esm({
27654
28158
  );
27655
28159
  const tierRaw = params.tier;
27656
28160
  const tier = tierRaw === 0 || tierRaw === 1 || tierRaw === 2 ? tierRaw : void 0;
28161
+ const atomicityScopeRaw = params.atomicityScope;
28162
+ const atomicityScope = atomicityScopeRaw === "orchestrator-defer" ? "orchestrator-defer" : void 0;
27657
28163
  const p = {
27658
28164
  taskId: params.taskId,
27659
28165
  protocolType: params.protocolType,
27660
28166
  tier,
27661
28167
  noWorktree: params.noWorktree,
27662
- spawnScope: params.spawnScope
28168
+ spawnScope: params.spawnScope,
28169
+ ...atomicityScope ? { atomicityScope } : {}
27663
28170
  };
27664
28171
  return wrapResult(await coreOps2.spawn(p), "mutate", "orchestrate", operation, startTime);
27665
28172
  }
@@ -30092,7 +30599,7 @@ var init_sticky2 = __esm({
30092
30599
  });
30093
30600
 
30094
30601
  // packages/cleo/src/dispatch/domains/tasks.ts
30095
- import { getLogger as getLogger15, getProjectRoot as getProjectRoot18 } from "@cleocode/core";
30602
+ import { getLogger as getLogger15, getProjectRoot as getProjectRoot18, TASKS_SUGGESTED_NEXT_BUILDERS } from "@cleocode/core";
30096
30603
  import { createAttachmentStore as createAttachmentStore4 } from "@cleocode/core/internal";
30097
30604
  import {
30098
30605
  sagaAdd as coreSagaAdd,
@@ -30170,6 +30677,25 @@ async function sagaReconcile(params) {
30170
30677
  "saga.reconcile"
30171
30678
  );
30172
30679
  }
30680
+ function stampSuggestedNext(response, operation, params) {
30681
+ if (!response.success) return response;
30682
+ const builder = TASKS_SUGGESTED_NEXT_BUILDERS[operation];
30683
+ if (!builder) return response;
30684
+ let suggestions;
30685
+ try {
30686
+ suggestions = builder(params, response.data);
30687
+ } catch {
30688
+ return response;
30689
+ }
30690
+ if (suggestions.length === 0) return response;
30691
+ return {
30692
+ ...response,
30693
+ meta: {
30694
+ ...response.meta,
30695
+ suggestedNext: suggestions
30696
+ }
30697
+ };
30698
+ }
30173
30699
  var _tasksTypedHandler, QUERY_OPS11, MUTATE_OPS10, TasksHandler;
30174
30700
  var init_tasks2 = __esm({
30175
30701
  "packages/cleo/src/dispatch/domains/tasks.ts"() {
@@ -30241,7 +30767,9 @@ var init_tasks2 = __esm({
30241
30767
  fields: params.fields,
30242
30768
  verbose: params.verbose,
30243
30769
  // T944/T9072: kind filter
30244
- kind: params.kind
30770
+ kind: params.kind,
30771
+ // T9905: unified urgency surface
30772
+ urgent: params.urgent
30245
30773
  }),
30246
30774
  "find"
30247
30775
  );
@@ -30684,7 +31212,14 @@ var init_tasks2 = __esm({
30684
31212
  operation,
30685
31213
  params ?? {}
30686
31214
  );
30687
- return wrapResult(envelopeToEngineResult(envelope), "query", "tasks", operation, startTime);
31215
+ const response = wrapResult(
31216
+ envelopeToEngineResult(envelope),
31217
+ "query",
31218
+ "tasks",
31219
+ operation,
31220
+ startTime
31221
+ );
31222
+ return stampSuggestedNext(response, operation, params ?? {});
30688
31223
  } catch (error) {
30689
31224
  getLogger15("domain:tasks").error(
30690
31225
  { gateway: "query", domain: "tasks", operation, err: error },
@@ -30771,7 +31306,14 @@ var init_tasks2 = __esm({
30771
31306
  operation,
30772
31307
  params ?? {}
30773
31308
  );
30774
- return wrapResult(envelopeToEngineResult(envelope), "mutate", "tasks", operation, startTime);
31309
+ const response = wrapResult(
31310
+ envelopeToEngineResult(envelope),
31311
+ "mutate",
31312
+ "tasks",
31313
+ operation,
31314
+ startTime
31315
+ );
31316
+ return stampSuggestedNext(response, operation, params ?? {});
30775
31317
  } catch (error) {
30776
31318
  getLogger15("domain:tasks").error(
30777
31319
  { gateway: "mutate", domain: "tasks", operation, err: error },
@@ -32296,6 +32838,88 @@ var init_field_filter = __esm({
32296
32838
  }
32297
32839
  });
32298
32840
 
32841
+ // packages/cleo/src/cli/projection-context.ts
32842
+ function setProjectionOptOut(optOut) {
32843
+ currentOptOut = optOut;
32844
+ }
32845
+ function getProjectionOptOut() {
32846
+ return currentOptOut;
32847
+ }
32848
+ var currentOptOut;
32849
+ var init_projection_context = __esm({
32850
+ "packages/cleo/src/cli/projection-context.ts"() {
32851
+ "use strict";
32852
+ currentOptOut = false;
32853
+ }
32854
+ });
32855
+
32856
+ // packages/cleo/src/dispatch/middleware/mutate-minimal-envelope.ts
32857
+ import {
32858
+ applyMutateProjection,
32859
+ MUTATE_PROJECTION_PLANS,
32860
+ resolveProjectionMode
32861
+ } from "@cleocode/core";
32862
+ function resolveModeFor(req) {
32863
+ const override = req.params?.["_projection"];
32864
+ if (override === "full" || override === "mvi") return override;
32865
+ return resolveProjectionMode(getProjectionOptOut() || void 0);
32866
+ }
32867
+ function createMutateMinimalEnvelope() {
32868
+ return async (req, next) => {
32869
+ const mode = resolveModeFor(req);
32870
+ const opKey = `${req.domain}.${req.operation}`;
32871
+ const hasPlan = MUTATE_PROJECTION_PLANS[opKey] !== void 0;
32872
+ const response = await next();
32873
+ if (!hasPlan) return response;
32874
+ if (response.success && response.data !== void 0) {
32875
+ response.data = applyMutateProjection(response.data, opKey, mode);
32876
+ }
32877
+ response.meta.mutateProjection = mode;
32878
+ return response;
32879
+ };
32880
+ }
32881
+ var init_mutate_minimal_envelope = __esm({
32882
+ "packages/cleo/src/dispatch/middleware/mutate-minimal-envelope.ts"() {
32883
+ "use strict";
32884
+ init_projection_context();
32885
+ }
32886
+ });
32887
+
32888
+ // packages/cleo/src/dispatch/middleware/mvi-record-projection.ts
32889
+ import {
32890
+ applyProjectionPlan,
32891
+ PROJECTION_PLANS,
32892
+ resolveProjectionMode as resolveProjectionMode2
32893
+ } from "@cleocode/core";
32894
+ function resolveModeFor2(req) {
32895
+ const override = req.params?.["_projection"];
32896
+ if (override === "full" || override === "mvi") return override;
32897
+ return resolveProjectionMode2(getProjectionOptOut() || void 0);
32898
+ }
32899
+ function createMviRecordProjection() {
32900
+ return async (req, next) => {
32901
+ const mode = resolveModeFor2(req);
32902
+ if (req.params && "_projection" in req.params) {
32903
+ delete req.params["_projection"];
32904
+ }
32905
+ const opKey = `${req.domain}.${req.operation}`;
32906
+ const hasPlan = PROJECTION_PLANS[opKey] !== void 0;
32907
+ const response = await next();
32908
+ if (!hasPlan) return response;
32909
+ if (response.success && response.data !== void 0) {
32910
+ response.data = applyProjectionPlan(response.data, opKey, mode);
32911
+ }
32912
+ response.meta.projection = mode;
32913
+ return response;
32914
+ };
32915
+ }
32916
+ var init_mvi_record_projection = __esm({
32917
+ "packages/cleo/src/dispatch/middleware/mvi-record-projection.ts"() {
32918
+ "use strict";
32919
+ init_projection_context();
32920
+ }
32921
+ });
32922
+
32299
32923
  // packages/cleo/src/dispatch/lib/security.ts
32300
32924
  import {
32301
32925
  ALL_VALID_STATUSES,
@@ -32503,6 +33127,15 @@ function createCliDispatcher() {
32503
33127
  // T4959: session identity first
32504
33128
  createSanitizer(() => getProjectRoot22()),
32505
33129
  createFieldFilter(),
33130
+ // T9922 (Saga T9855 / E8.3): MVI record projection default for read ops.
33131
+ // Runs AFTER the domain handler returns so it can trim the data payload
33132
+ // before audit + telemetry record byte sizes. Sits before audit so the
33133
+ // audit trail captures the projected (final) bytes.
33134
+ createMviRecordProjection(),
33135
+ // T9931 (Saga T9855 / E9.4): minimal envelopes for mutate ops. Mirror
33136
+ // policy to the read-side projection — sits in the same pre-audit slot
33137
+ // so audit/telemetry record the trimmed bytes.
33138
+ createMutateMinimalEnvelope(),
32506
33139
  createAudit(),
32507
33140
  // T4959: CLI now gets audit trail
32508
33141
  createTelemetry()
@@ -32669,6 +33302,8 @@ var init_cli = __esm({
32669
33302
  init_domains();
32670
33303
  init_audit();
32671
33304
  init_field_filter();
33305
+ init_mutate_minimal_envelope();
33306
+ init_mvi_record_projection();
32672
33307
  init_sanitizer();
32673
33308
  init_session_resolver();
32674
33309
  init_telemetry();
@@ -32864,16 +33499,16 @@ function wrapParseError(rawInput, parseErr, sourceLabel) {
32864
33499
  const snippet2 = rawInput.length > PARSE_ERROR_SNIPPET_MAX_LENGTH ? `${rawInput.slice(0, PARSE_ERROR_SNIPPET_MAX_LENGTH)}\u2026` : rawInput;
32865
33500
  return new Error(`Invalid JSON in ${sourceLabel}: ${parseErr.message} (got: ${snippet2})`);
32866
33501
  }
32867
- function readStdinJson(stdin) {
33502
+ function readStdinJson(stdin2) {
32868
33503
  return new Promise((resolve8, reject) => {
32869
33504
  const chunks = [];
32870
- stdin.on("data", (chunk) => {
33505
+ stdin2.on("data", (chunk) => {
32871
33506
  chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
32872
33507
  });
32873
- stdin.on("error", (err) => {
33508
+ stdin2.on("error", (err) => {
32874
33509
  reject(err);
32875
33510
  });
32876
- stdin.on("end", () => {
33511
+ stdin2.on("end", () => {
32877
33512
  const raw = Buffer.concat(chunks).toString("utf8");
32878
33513
  try {
32879
33514
  resolve8(JSON.parse(raw));
@@ -32883,7 +33518,7 @@ function readStdinJson(stdin) {
32883
33518
  });
32884
33519
  });
32885
33520
  }
32886
- async function collectMutateInput(args, stdin) {
33521
+ async function collectMutateInput(args, stdin2) {
32887
33522
  if (typeof args.params === "string" && args.params.length > 0) {
32888
33523
  try {
32889
33524
  return JSON.parse(args.params);
@@ -32899,8 +33534,8 @@ async function collectMutateInput(args, stdin) {
32899
33534
  throw wrapParseError(raw, err, `--file ${args.file}`);
32900
33535
  }
32901
33536
  }
32902
- if (stdin.isTTY !== true) {
32903
- return readStdinJson(stdin);
33537
+ if (stdin2.isTTY !== true) {
33538
+ return readStdinJson(stdin2);
32904
33539
  }
32905
33540
  if (args.positional !== void 0 && args.positional.length > 0) {
32906
33541
  return args.positional;
@@ -35780,7 +36415,7 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
35780
36415
  try {
35781
36416
  const { existsSync: existsSync19, statSync } = await import("node:fs");
35782
36417
  const { resolve: resolve8, basename, dirname: dirname12 } = await import("node:path");
35783
- const { execFileSync: execFileSync4 } = await import("node:child_process");
36418
+ const { execFileSync: execFileSync5 } = await import("node:child_process");
35784
36419
  const resolvedDir = resolve8(args.dir);
35785
36420
  if (!existsSync19(resolvedDir) || !statSync(resolvedDir).isDirectory()) {
35786
36421
  cliOutput(
@@ -35817,7 +36452,7 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
35817
36452
  const archivePath = resolve8(archiveName);
35818
36453
  const parentDir = dirname12(resolvedDir);
35819
36454
  try {
35820
- execFileSync4("zip", ["-r", archivePath, agentName], {
36455
+ execFileSync5("zip", ["-r", archivePath, agentName], {
35821
36456
  cwd: parentDir,
35822
36457
  encoding: "utf-8",
35823
36458
  timeout: 3e4
@@ -39480,7 +40115,7 @@ var init_changeset = __esm({
39480
40115
  });
39481
40116
  if (!outcome.ok) {
39482
40117
  const err = outcome.error;
39483
- const hint = err.code === "E_SLUG_PATTERN_MISMATCH" && err.example ? `example slug: ${err.example}` : void 0;
40118
+ const hint = err.code === "E_SLUG_PATTERN_MISMATCH" && err.example ? `example slug: ${err.example}` : err.code === "E_SLUG_RESERVED" ? `try: ${err.suggestions.join(", ")}` : void 0;
39484
40119
  cliError(err.message, 6 /* VALIDATION_ERROR */, {
39485
40120
  name: err.code,
39486
40121
  ...hint ? { fix: hint } : {}
@@ -43786,6 +44421,94 @@ var init_strict_args = __esm({
43786
44421
  }
43787
44422
  });
43788
44423
 
44424
+ // packages/cleo/src/cli/commands/docs/graph.ts
44425
+ import {
44426
+ buildDocProvenanceGraph,
44427
+ DocProvenanceRootNotFoundError,
44428
+ renderProvenanceGraphAsDot
44429
+ } from "@cleocode/core/internal";
44430
+ function parseDepth(raw) {
44431
+ if (raw === void 0 || raw === null || raw === "") return 2;
44432
+ const parsed = Number.parseInt(String(raw), 10);
44433
+ if (!Number.isInteger(parsed) || parsed < 0) {
44434
+ cliError(
44435
+ `--depth must be a non-negative integer (got '${String(raw)}')`,
44436
+ 6 /* VALIDATION_ERROR */,
44437
+ { name: "E_VALIDATION" }
44438
+ );
44439
+ process.exit(6 /* VALIDATION_ERROR */);
44440
+ }
44441
+ return parsed;
44442
+ }
44443
+ function parseFormat(raw) {
44444
+ if (raw === void 0 || raw === null || raw === "") return "json";
44445
+ const candidate = String(raw);
44446
+ if (candidate !== "json" && candidate !== "dot") {
44447
+ cliError(`--format must be one of: json|dot \u2014 got '${candidate}'`, 6 /* VALIDATION_ERROR */, {
44448
+ name: "E_VALIDATION"
44449
+ });
44450
+ process.exit(6 /* VALIDATION_ERROR */);
44451
+ }
44452
+ return candidate;
44453
+ }
44454
+ var graphCommand;
44455
+ var init_graph2 = __esm({
44456
+ "packages/cleo/src/cli/commands/docs/graph.ts"() {
44457
+ "use strict";
44458
+ init_src2();
44459
+ init_define_cli_command();
44460
+ init_renderers();
44461
+ graphCommand = defineCommand({
44462
+ meta: {
44463
+ name: "graph",
44464
+ description: "Traverse the docs provenance graph from a root (slug or task ID) and return a typed DocProvenanceResponse envelope. Walks supersedes/superseded-by chains plus cross-entity edges to owning + related tasks. Default depth=2. Pass --format dot for Graphviz output (still wrapped in the envelope under data.dot)."
44465
+ },
44466
+ args: {
44467
+ root: {
44468
+ type: "string",
44469
+ description: "Root identifier \u2014 a canonical doc slug (e.g. adr-078-docs-provenance) or a CLEO task ID (T####). Required.",
44470
+ required: true
44471
+ },
44472
+ depth: {
44473
+ type: "string",
44474
+ description: "Maximum BFS hops from the root (default: 2; minimum: 0)."
44475
+ },
44476
+ format: {
44477
+ type: "string",
44478
+ description: "Output format: json (default) | dot."
44479
+ }
44480
+ },
44481
+ async run({ args }) {
44482
+ const root = String(args.root);
44483
+ const depth = parseDepth(args.depth);
44484
+ const format = parseFormat(args.format);
44485
+ try {
44486
+ const graph = await buildDocProvenanceGraph({ root, depth });
44487
+ const payload = { ...graph };
44488
+ if (format === "dot") {
44489
+ payload["dot"] = renderProvenanceGraphAsDot(graph);
44490
+ }
44491
+ cliOutput(payload, { command: "docs graph", operation: "docs.graph" });
44492
+ } catch (err) {
44493
+ if (err instanceof DocProvenanceRootNotFoundError) {
44494
+ cliError(err.message, 4 /* NOT_FOUND */, {
44495
+ name: "E_DOC_PROVENANCE_ROOT_NOT_FOUND",
44496
+ fix: "Verify the root with `cleo docs list --project --type adr` (or your kind) and pass an existing slug or task ID. Slugs and task IDs are matched against attachments.slug and attachment_refs.owner_id respectively.",
44497
+ details: { root }
44498
+ });
44499
+ process.exit(4 /* NOT_FOUND */);
44500
+ }
44501
+ const message = err instanceof Error ? err.message : String(err);
44502
+ cliError(`docs graph failed: ${message}`, 1 /* GENERAL_ERROR */, {
44503
+ name: "E_DOCS_GRAPH_FAILED"
44504
+ });
44505
+ process.exit(1 /* GENERAL_ERROR */);
44506
+ }
44507
+ }
44508
+ });
44509
+ }
44510
+ });
44511
+
43789
44512
  // packages/cleo/src/viewer/pidfile.ts
43790
44513
  import { mkdir, readFile as readFile3, unlink, writeFile } from "node:fs/promises";
43791
44514
  import { dirname as dirname6, join as join18 } from "node:path";
@@ -44614,7 +45337,6 @@ __export(docs_exports, {
44614
45337
  import { appendFile, mkdir as mkdir2, readdir, readFile as readFile4, writeFile as writeFile2 } from "node:fs/promises";
44615
45338
  import { dirname as dirname8, isAbsolute as isAbsolute2, join as join21, resolve as resolve5 } from "node:path";
44616
45339
  import {
44617
- buildDocsGraph,
44618
45340
  CleoError as CleoError3,
44619
45341
  CounterMismatchError,
44620
45342
  checkSlugSimilarity,
@@ -44623,6 +45345,7 @@ import {
44623
45345
  DEFAULT_SIMILARITY_THRESHOLD,
44624
45346
  detectStrayCleoDb as detectStrayCleoDb2,
44625
45347
  exportDocument,
45348
+ findSimilarDocs,
44626
45349
  getAgentOutputsAbsolute,
44627
45350
  getProjectRoot as getProjectRoot38,
44628
45351
  listDocVersions,
@@ -44728,7 +45451,7 @@ function loadCliRegistry(projectRoot) {
44728
45451
  throw err;
44729
45452
  }
44730
45453
  }
44731
- var addCommand5, listCommand8, fetchCommand, removeCommand2, generateCommand, exportCommand4, searchCommand, mergeCommand, graphCommand, rankCommand, versionsCommand, publishCommand2, publishPrCommand, syncCommand3, statusCommand7, gapCheckCommand, importCommand2, schemaCommand, listTypesCommand, docsCommand;
45454
+ var addCommand5, listCommand8, fetchCommand, removeCommand2, supersedeCommandArgs, supersedeCommand, generateCommand, exportCommand4, searchCommand, findCommand3, mergeCommand, rankCommand, updateCommand, versionsCommand, publishCommand2, publishPrCommand, syncCommand3, statusCommand7, gapCheckCommand, importCommand2, schemaCommand, listTypesCommand, docsCommand;
44732
45455
  var init_docs3 = __esm({
44733
45456
  "packages/cleo/src/cli/commands/docs.ts"() {
44734
45457
  "use strict";
@@ -44738,11 +45461,12 @@ var init_docs3 = __esm({
44738
45461
  init_canon_docs();
44739
45462
  init_strict_args();
44740
45463
  init_renderers();
45464
+ init_graph2();
44741
45465
  init_docs_viewer();
44742
45466
  addCommand5 = defineCommand({
44743
45467
  meta: {
44744
45468
  name: "add",
44745
- description: 'Attach a local file or remote URL to a CLEO entity (task, session, observation). Owner type is inferred from the ID prefix: T### \u2192 task, ses_* \u2192 session, O-* \u2192 observation. Use --slug to set a human-friendly alias (unique per project) (T9636).\n\nPositional arguments:\n <owner-id> Owner entity ID (T###, ses_*, O-*) \u2014 required\n [file] Local file path to attach \u2014 optional when --url is set\n\nNamed arguments:\n --url <url> Remote URL to attach (instead of a local file)\n --desc <text> Free-text description of this attachment\n --labels <csv> Comma-separated labels (e.g. rfc,spec)\n --attached-by <name> Agent identity that created the attachment (default: "human")\n --slug <kebab> Human-friendly alias, unique per project (T9636)\n --type <kind> Taxonomy classification \u2014 run `cleo docs list-types` for kinds\n --allow-similar Bypass the slug-similarity warn \u2014 every bypass is audited\n to .cleo/audit/similar-bypass.jsonl (T10361)\n --strict Enforce body-schema (requiredSections) \u2014 fail with\n E_DOC_SCHEMA_MISMATCH instead of warning (T10160)\n\nValidation behaviors:\n \u2022 Unknown flags \u2192 E_UNKNOWN_FLAG with did-you-mean suggestions (T10359)\n \u2022 Slug collision \u2192 E_SLUG_RESERVED + 3 alternative slugs (T10386)\n \u2022 Near-duplicate slug \u2192 W_SLUG_SIMILAR warning unless --allow-similar (T10361)\n \u2022 TODO(T10360): --type adr will auto-allocate adr-NNN-<title> from a --title flag.'
45469
+ description: 'Attach a local file or remote URL to a CLEO entity (task, session, observation). Owner type is inferred from the ID prefix: T### \u2192 task, ses_* \u2192 session, O-* \u2192 observation. Use --slug to set a human-friendly alias (unique per project) (T9636).\n\nPositional arguments:\n <owner-id> Owner entity ID (T###, ses_*, O-*) \u2014 required\n [file] Local file path to attach \u2014 optional when --url is set\n\nNamed arguments:\n --url <url> Remote URL to attach (instead of a local file)\n --desc <text> Free-text description of this attachment\n --labels <csv> Comma-separated labels (e.g. rfc,spec)\n --attached-by <name> Agent identity that created the attachment (default: "human")\n --slug <kebab> Human-friendly alias, unique per project (T9636)\n --title <text> Human-readable title \u2014 REQUIRED for --type adr when --slug is omitted (T10360)\n --type <kind> Taxonomy classification \u2014 run `cleo docs list-types` for kinds\n --allow-similar Bypass the slug-similarity warn \u2014 every bypass is audited\n to .cleo/audit/similar-bypass.jsonl (T10361)\n --strict Enforce body-schema (requiredSections) \u2014 fail with\n E_DOC_SCHEMA_MISMATCH instead of warning (T10160)\n\nValidation behaviors:\n \u2022 Unknown flags \u2192 E_UNKNOWN_FLAG with did-you-mean suggestions (T10359)\n \u2022 Slug collision \u2192 E_SLUG_RESERVED + 3 alternative slugs (T10386)\n \u2022 Near-duplicate slug \u2192 W_SLUG_SIMILAR warning unless --allow-similar (T10361)\n \u2022 For --type adr without --slug, slug auto-allocates as `adr-NNN-<kebab-title>` via the\n central allocator (T10360 \u2014 closes T10153). --title is required in this case.'
44746
45470
  },
44747
45471
  args: {
44748
45472
  "owner-id": {
@@ -44775,6 +45499,10 @@ var init_docs3 = __esm({
44775
45499
  type: "string",
44776
45500
  description: "Human-friendly kebab-case alias for the attachment, unique per project (T9636). Collision returns E_SLUG_RESERVED with 3 alternative suggestions (legacy E_SLUG_TAKEN aliased under details.aliases for one release \u2014 T10386)."
44777
45501
  },
45502
+ title: {
45503
+ type: "string",
45504
+ description: "Human-readable title used to derive the kebab-slug tail when auto-allocating an ADR slug. REQUIRED when --type adr is set AND --slug is omitted. Slugified via the shared kebabize helper (lowercase, hyphen-separated, diacritics stripped) (T10360)."
45505
+ },
44778
45506
  type: {
44779
45507
  type: "string",
44780
45508
  description: "Taxonomy classification \u2014 run `cleo docs list-types` to enumerate registered kinds (T9637 / T9788)"
@@ -44814,6 +45542,17 @@ var init_docs3 = __esm({
44814
45542
  });
44815
45543
  process.exit(6);
44816
45544
  }
45545
+ if (args.type === "adr" && !args.slug && !args.title) {
45546
+ cliError(
45547
+ "--title <text> is required when --type adr is used without --slug \u2014 the allocator needs a title to assemble adr-NNN-<kebab-title>",
45548
+ 6,
45549
+ {
45550
+ name: "E_VALIDATION",
45551
+ fix: 'Re-run with --title "Adopt Drizzle v1 beta" (or pass --slug adr-042-explicit-name to bypass auto-allocation).'
45552
+ }
45553
+ );
45554
+ process.exit(6);
45555
+ }
44817
45556
  let resolvedFile;
44818
45557
  if (fileArg) {
44819
45558
  const routing = resolveWorktreeRouting2();
@@ -44926,6 +45665,7 @@ var init_docs3 = __esm({
44926
45665
  ...args.labels ? { labels: args.labels } : {},
44927
45666
  ...args["attached-by"] ? { attachedBy: args["attached-by"] } : {},
44928
45667
  ...args.slug ? { slug: args.slug } : {},
45668
+ ...args.title ? { title: args.title } : {},
44929
45669
  ...args.type ? { type: args.type } : {},
44930
45670
  ...args.strict === true ? { strict: true } : {}
44931
45671
  },
@@ -44966,6 +45706,15 @@ var init_docs3 = __esm({
44966
45706
  orderBy: {
44967
45707
  type: "string",
44968
45708
  description: "Sort key: newest (default \u2014 most recent first), sha (ascending hex), slug (alphabetical, slug-less rows last) (T9792)."
45709
+ },
45710
+ // T9922 — MVI record projection opt-out flags (surfaced for --help).
45711
+ verbose: {
45712
+ type: "boolean",
45713
+ description: "Return full attachment records instead of the MVI projection (id + slug + type + kind + sha + size + createdAt). T9922."
45714
+ },
45715
+ full: {
45716
+ type: "boolean",
45717
+ description: "Alias for --verbose. T9922."
44969
45718
  }
44970
45719
  },
44971
45720
  async run({ args }) {
@@ -45032,6 +45781,15 @@ var init_docs3 = __esm({
45032
45781
  type: "positional",
45033
45782
  description: "Attachment ID (att_*) or SHA-256 hex",
45034
45783
  required: true
45784
+ },
45785
+ // T9922 — MVI record projection opt-out flags (surfaced for --help).
45786
+ verbose: {
45787
+ type: "boolean",
45788
+ description: "Return the full attachment metadata block instead of the MVI projection. The byte payload is always returned. T9922."
45789
+ },
45790
+ full: {
45791
+ type: "boolean",
45792
+ description: "Alias for --verbose. T9922."
45035
45793
  }
45036
45794
  },
45037
45795
  async run({ args }) {
@@ -45075,6 +45833,54 @@ var init_docs3 = __esm({
45075
45833
  );
45076
45834
  }
45077
45835
  });
45836
+ supersedeCommandArgs = {
45837
+ oldSlug: {
45838
+ type: "positional",
45839
+ description: "Slug of the doc being replaced",
45840
+ required: true
45841
+ },
45842
+ newSlug: {
45843
+ type: "positional",
45844
+ description: "Slug of the doc that replaces oldSlug",
45845
+ required: true
45846
+ },
45847
+ reason: {
45848
+ type: "string",
45849
+ description: "Optional human-readable reason carried back on the response envelope"
45850
+ }
45851
+ };
45852
+ supersedeCommand = defineCommand({
45853
+ meta: {
45854
+ name: "supersede",
45855
+ description: "Atomically supersede an older doc with a newer one: flips lifecycle_status to 'superseded' on the old row and links both rows via the supersedes/superseded_by FK pointers. All writes commit in a single SQLite transaction."
45856
+ },
45857
+ args: supersedeCommandArgs,
45858
+ async run({ args, rawArgs }) {
45859
+ try {
45860
+ assertKnownFlags(rawArgs, supersedeCommandArgs, "docs supersede");
45861
+ } catch (err) {
45862
+ if (err instanceof UnknownFlagError) {
45863
+ cliError(err.message, 6 /* VALIDATION_ERROR */, { name: "E_VALIDATION" });
45864
+ process.exit(6 /* VALIDATION_ERROR */);
45865
+ }
45866
+ throw err;
45867
+ }
45868
+ const oldSlug = args.oldSlug;
45869
+ const newSlug = args.newSlug;
45870
+ const reason = typeof args.reason === "string" && args.reason.length > 0 ? args.reason : void 0;
45871
+ await dispatchFromCli(
45872
+ "mutate",
45873
+ "docs",
45874
+ "supersede",
45875
+ {
45876
+ oldSlug,
45877
+ newSlug,
45878
+ ...reason !== void 0 ? { reason } : {}
45879
+ },
45880
+ { command: "docs supersede" }
45881
+ );
45882
+ }
45883
+ });
45078
45884
  generateCommand = defineCommand({
45079
45885
  meta: {
45080
45886
  name: "generate",
@@ -45226,6 +46032,102 @@ var init_docs3 = __esm({
45226
46032
  }
45227
46033
  }
45228
46034
  });
46035
+ findCommand3 = defineCommand({
46036
+ meta: {
46037
+ name: "find",
46038
+ description: "Find docs similar to a seed slug via llmtxt/similarity.rankBySimilarity. Pass --similar <slug>; results default to the same DocKind as the seed. Use --all-kinds to rank cross-kind, --threshold to set the minimum cosine score, and --limit to cap the number of returned hits.\n\nNamed arguments:\n --similar <slug> Slug of the seed doc to anchor similarity against (required for now)\n --limit <n> Maximum number of hits to return (default 10)\n --threshold <0..1> Minimum cosine score, hits below are dropped (default 0.5)\n --all-kinds Disable the same-kind filter and rank cross-kind\n --json Emit LAFS JSON envelope (default for non-TTY)"
46039
+ },
46040
+ args: {
46041
+ similar: {
46042
+ type: "string",
46043
+ description: "Slug of the seed doc to anchor similarity against"
46044
+ },
46045
+ limit: {
46046
+ type: "string",
46047
+ description: "Maximum number of hits to return (default: 10)"
46048
+ },
46049
+ threshold: {
46050
+ type: "string",
46051
+ description: "Minimum cosine similarity score in [0, 1] (default: 0.5)"
46052
+ },
46053
+ "all-kinds": {
46054
+ type: "boolean",
46055
+ description: "Disable the same-kind filter and rank across every DocKind"
46056
+ },
46057
+ json: {
46058
+ type: "boolean",
46059
+ description: "Emit LAFS JSON envelope instead of human-readable output"
46060
+ }
46061
+ },
46062
+ async run({ args, rawArgs }) {
46063
+ try {
46064
+ assertKnownFlags(rawArgs, findCommand3.args, "docs find");
46065
+ } catch (err) {
46066
+ if (err instanceof UnknownFlagError) {
46067
+ cliError(err.message, 6 /* VALIDATION_ERROR */, {
46068
+ name: err.code,
46069
+ fix: err.fix,
46070
+ alternatives: err.suggestions.map((s) => ({ action: s, command: s })),
46071
+ details: { flag: err.flag, knownFlags: err.knownFlags }
46072
+ });
46073
+ process.exit(6 /* VALIDATION_ERROR */);
46074
+ }
46075
+ throw err;
46076
+ }
46077
+ const similarSlug = typeof args.similar === "string" ? args.similar.trim() : "";
46078
+ if (similarSlug.length === 0) {
46079
+ cliError("--similar <slug> is required", 6 /* VALIDATION_ERROR */, {
46080
+ name: "E_VALIDATION",
46081
+ fix: "Example: `cleo docs find --similar adr-073-above-epic-naming --limit 5`."
46082
+ });
46083
+ process.exit(6 /* VALIDATION_ERROR */);
46084
+ }
46085
+ let limit;
46086
+ if (typeof args.limit === "string") {
46087
+ const parsed = Number.parseInt(args.limit, 10);
46088
+ if (!Number.isFinite(parsed) || parsed <= 0) {
46089
+ cliError(
46090
+ `--limit must be a positive integer (got "${args.limit}")`,
46091
+ 6 /* VALIDATION_ERROR */,
46092
+ {
46093
+ name: "E_VALIDATION"
46094
+ }
46095
+ );
46096
+ process.exit(6 /* VALIDATION_ERROR */);
46097
+ }
46098
+ limit = parsed;
46099
+ }
46100
+ let threshold;
46101
+ if (typeof args.threshold === "string") {
46102
+ const parsed = Number.parseFloat(args.threshold);
46103
+ if (!Number.isFinite(parsed) || parsed < 0 || parsed > 1) {
46104
+ cliError(
46105
+ `--threshold must be a number in [0, 1] (got "${args.threshold}")`,
46106
+ 6 /* VALIDATION_ERROR */,
46107
+ { name: "E_VALIDATION" }
46108
+ );
46109
+ process.exit(6 /* VALIDATION_ERROR */);
46110
+ }
46111
+ threshold = parsed;
46112
+ }
46113
+ const allKinds = args["all-kinds"] === true;
46114
+ const projectRoot = getProjectRoot38();
46115
+ try {
46116
+ const result = await findSimilarDocs(similarSlug, {
46117
+ ...limit !== void 0 ? { limit } : {},
46118
+ ...threshold !== void 0 ? { threshold } : {},
46119
+ allKinds,
46120
+ projectRoot
46121
+ });
46122
+ cliOutput(result, { command: "docs find", operation: "docs.find" });
46123
+ } catch (err) {
46124
+ const code = err instanceof Error && typeof err.code === "string" ? err.code : "E_DOCS_FIND_FAILED";
46125
+ const message = err instanceof Error ? err.message : String(err);
46126
+ cliError(`docs find failed: ${message}`, 1 /* GENERAL_ERROR */, { name: code });
46127
+ process.exit(1 /* GENERAL_ERROR */);
46128
+ }
46129
+ }
46130
+ });
45229
46131
  mergeCommand = defineCommand({
45230
46132
  meta: {
45231
46133
  name: "merge",
@@ -45284,10 +46186,10 @@ var init_docs3 = __esm({
45284
46186
  }
45285
46187
  }
45286
46188
  });
45287
- graphCommand = defineCommand({
46189
+ rankCommand = defineCommand({
45288
46190
  meta: {
45289
- name: "graph",
45290
- description: "Build a document relationship graph for an entity using llmtxt/graph.buildGraph. Output formats: mermaid (default), dot, json."
46191
+ name: "rank",
46192
+ description: "Rank attachments for an entity by relevance using llmtxt/similarity.rankBySimilarity. Pass --query to use a custom query; otherwise the entity ID anchors the ranking."
45291
46193
  },
45292
46194
  args: {
45293
46195
  for: {
@@ -45295,13 +46197,9 @@ var init_docs3 = __esm({
45295
46197
  description: "Owner entity ID (T###, ses_*, O-*)",
45296
46198
  required: true
45297
46199
  },
45298
- format: {
45299
- type: "string",
45300
- description: "Output format: mermaid | dot | json (default: mermaid)"
45301
- },
45302
- out: {
46200
+ query: {
45303
46201
  type: "string",
45304
- description: "Write graph to this file path"
46202
+ description: "Optional free-text query to rank against (default: owner ID)"
45305
46203
  },
45306
46204
  json: {
45307
46205
  type: "boolean",
@@ -45310,89 +46208,105 @@ var init_docs3 = __esm({
45310
46208
  },
45311
46209
  async run({ args }) {
45312
46210
  const projectRoot = getProjectRoot38();
45313
- const fmt = args.format ?? "mermaid";
45314
46211
  try {
45315
- const result = await buildDocsGraph({ ownerId: String(args.for), projectRoot });
45316
- let output2;
45317
- if (fmt === "dot") {
45318
- const dotLines = ["digraph docs {"];
45319
- for (const node of result.nodes) {
45320
- dotLines.push(` "${node.id}" [label="${node.label}"];`);
45321
- }
45322
- for (const edge of result.edges) {
45323
- dotLines.push(` "${edge.source}" -> "${edge.target}" [label="${edge.relation}"];`);
45324
- }
45325
- dotLines.push("}");
45326
- output2 = dotLines.join("\n");
45327
- } else if (fmt === "json") {
45328
- output2 = JSON.stringify(result, null, 2);
45329
- } else {
45330
- const lines = ["graph LR"];
45331
- for (const edge of result.edges) {
45332
- lines.push(` ${edge.source} -->|${edge.relation}| ${edge.target}`);
45333
- }
45334
- if (result.edges.length === 0) {
45335
- for (const node of result.nodes) {
45336
- lines.push(` ${node.id}["${node.label}"]`);
45337
- }
45338
- }
45339
- output2 = lines.join("\n");
45340
- }
45341
- if (typeof args.out === "string" && args.out.length > 0) {
45342
- const outPath = isAbsolute2(args.out) ? args.out : resolve5(projectRoot, args.out);
45343
- await mkdir2(dirname8(outPath), { recursive: true });
45344
- await writeFile2(outPath, output2, "utf8");
45345
- humanInfo(`Wrote graph to ${outPath}`);
45346
- }
45347
- cliOutput(
45348
- { format: fmt, nodeCount: result.nodes.length, edgeCount: result.edges.length, output: output2 },
45349
- { command: "docs graph", operation: "docs.graph" }
45350
- );
46212
+ const result = await rankDocs({
46213
+ ownerId: String(args.for),
46214
+ query: args.query ?? void 0,
46215
+ projectRoot
46216
+ });
46217
+ cliOutput(result, { command: "docs rank", operation: "docs.rank" });
45351
46218
  } catch (err) {
45352
46219
  const message = err instanceof Error ? err.message : String(err);
45353
- cliError(`docs graph failed: ${message}`, 1 /* GENERAL_ERROR */, {
45354
- name: "E_DOCS_GRAPH_FAILED"
46220
+ cliError(`docs rank failed: ${message}`, 1 /* GENERAL_ERROR */, {
46221
+ name: "E_DOCS_RANK_FAILED"
45355
46222
  });
45356
46223
  process.exit(1 /* GENERAL_ERROR */);
45357
46224
  }
45358
46225
  }
45359
46226
  });
45360
- rankCommand = defineCommand({
46227
+ updateCommand = defineCommand({
45361
46228
  meta: {
45362
- name: "rank",
45363
- description: "Rank attachments for an entity by relevance using llmtxt/similarity.rankBySimilarity. Pass --query to use a custom query; otherwise the entity ID anchors the ranking."
46229
+ name: "update",
46230
+ description: 'Replace blob content for an existing slug while preserving the slug. Pass --file <path> OR --content <text> (exactly one). Defaults --status to "draft" on every update so explicit `accepted` docs get back-pressured to draft on edit. Audit log entry appended to .cleo/audit/docs-versioning.jsonl (squashed within 5 min).\n\nPositional arguments:\n <slug> Slug of the attachment to update (required)\n\nNamed arguments:\n --file <path> Local file containing the new content\n --content <text> Inline UTF-8 content (mutually exclusive with --file)\n --message <text> One-line summary of the change (audit log)\n --status <status> Override lifecycle status \u2014 default "draft"\n --attached-by <name> Agent identity for this revision (default "human")'
45364
46231
  },
45365
46232
  args: {
45366
- for: {
45367
- type: "string",
45368
- description: "Owner entity ID (T###, ses_*, O-*)",
46233
+ slug: {
46234
+ type: "positional",
46235
+ description: "Slug of the attachment to update",
45369
46236
  required: true
45370
46237
  },
45371
- query: {
46238
+ file: {
45372
46239
  type: "string",
45373
- description: "Optional free-text query to rank against (default: owner ID)"
46240
+ description: "Local file containing the new content"
45374
46241
  },
45375
- json: {
45376
- type: "boolean",
45377
- description: "Emit LAFS JSON envelope"
46242
+ content: {
46243
+ type: "string",
46244
+ description: "Inline UTF-8 content (mutually exclusive with --file)"
46245
+ },
46246
+ message: {
46247
+ type: "string",
46248
+ description: "One-line summary of the change (recorded in the audit log)"
46249
+ },
46250
+ status: {
46251
+ type: "string",
46252
+ description: "Lifecycle status to set on the new row. Valid: draft|proposed|accepted|superseded|archived|deprecated. Default: draft."
46253
+ },
46254
+ "attached-by": {
46255
+ type: "string",
46256
+ description: 'Agent identity that performed the update (default: "human")'
45378
46257
  }
45379
46258
  },
45380
- async run({ args }) {
45381
- const projectRoot = getProjectRoot38();
46259
+ async run({ args, rawArgs }) {
45382
46260
  try {
45383
- const result = await rankDocs({
45384
- ownerId: String(args.for),
45385
- query: args.query ?? void 0,
45386
- projectRoot
45387
- });
45388
- cliOutput(result, { command: "docs rank", operation: "docs.rank" });
46261
+ assertKnownFlags(rawArgs, updateCommand.args, "docs update");
45389
46262
  } catch (err) {
45390
- const message = err instanceof Error ? err.message : String(err);
45391
- cliError(`docs rank failed: ${message}`, 1 /* GENERAL_ERROR */, {
45392
- name: "E_DOCS_RANK_FAILED"
46263
+ if (err instanceof UnknownFlagError) {
46264
+ cliError(err.message, 6 /* VALIDATION_ERROR */, {
46265
+ name: err.code,
46266
+ fix: err.fix,
46267
+ alternatives: err.suggestions.map((s) => ({ action: s, command: s })),
46268
+ details: { flag: err.flag, knownFlags: err.knownFlags }
46269
+ });
46270
+ process.exit(6 /* VALIDATION_ERROR */);
46271
+ }
46272
+ throw err;
46273
+ }
46274
+ const slug = String(args.slug);
46275
+ const filePath = typeof args.file === "string" ? args.file : void 0;
46276
+ const inlineContent = typeof args.content === "string" ? args.content : void 0;
46277
+ if (filePath !== void 0 && inlineContent !== void 0) {
46278
+ cliError("--file and --content are mutually exclusive", 6 /* VALIDATION_ERROR */, {
46279
+ name: "E_VALIDATION",
46280
+ fix: "Use `cleo docs update <slug> --file <path>` OR `--content <text>` (not both)."
45393
46281
  });
45394
- process.exit(1 /* GENERAL_ERROR */);
46282
+ process.exit(6 /* VALIDATION_ERROR */);
46283
+ }
46284
+ if (filePath === void 0 && inlineContent === void 0) {
46285
+ cliError("provide --file <path> OR --content <text>", 6 /* VALIDATION_ERROR */, {
46286
+ name: "E_VALIDATION",
46287
+ fix: 'Example: `cleo docs update my-doc --file ./new.md` OR `cleo docs update my-doc --content "..."`.'
46288
+ });
46289
+ process.exit(6 /* VALIDATION_ERROR */);
45395
46290
  }
46291
+ let resolvedFile;
46292
+ if (filePath !== void 0) {
46293
+ const routing = resolveWorktreeRouting2();
46294
+ resolvedFile = resolveWorktreeFilePath(filePath, routing);
46295
+ }
46296
+ await dispatchFromCli(
46297
+ "mutate",
46298
+ "docs",
46299
+ "update",
46300
+ {
46301
+ slug,
46302
+ ...resolvedFile !== void 0 ? { file: resolvedFile } : {},
46303
+ ...inlineContent !== void 0 ? { content: inlineContent } : {},
46304
+ ...typeof args.message === "string" ? { message: args.message } : {},
46305
+ ...typeof args.status === "string" ? { status: args.status } : {},
46306
+ ...typeof args["attached-by"] === "string" ? { attachedBy: args["attached-by"] } : {}
46307
+ },
46308
+ { command: "docs update" }
46309
+ );
45396
46310
  }
45397
46311
  });
45398
46312
  versionsCommand = defineCommand({
@@ -45901,13 +46815,17 @@ var init_docs3 = __esm({
45901
46815
  },
45902
46816
  subCommands: {
45903
46817
  add: addCommand5,
46818
+ update: updateCommand,
45904
46819
  list: listCommand8,
45905
46820
  fetch: fetchCommand,
45906
46821
  remove: removeCommand2,
46822
+ supersede: supersedeCommand,
45907
46823
  generate: generateCommand,
45908
46824
  export: exportCommand4,
46825
+ find: findCommand3,
45909
46826
  search: searchCommand,
45910
46827
  merge: mergeCommand,
46828
+ // T10164 — DocProvenanceResponse-typed graph (`--root <slug>|<taskId>`).
45911
46829
  graph: graphCommand,
45912
46830
  rank: rankCommand,
45913
46831
  versions: versionsCommand,
@@ -46349,6 +47267,7 @@ var ProgressTracker;
46349
47267
  var init_progress = __esm({
46350
47268
  "packages/cleo/src/cli/progress.ts"() {
46351
47269
  "use strict";
47270
+ init_format_context();
46352
47271
  ProgressTracker = class {
46353
47272
  enabled;
46354
47273
  prefix;
@@ -46365,7 +47284,7 @@ var init_progress = __esm({
46365
47284
  * Start the progress tracker.
46366
47285
  */
46367
47286
  start() {
46368
- if (!this.enabled) return;
47287
+ if (!this.enabled || isQuiet()) return;
46369
47288
  this.currentStep = 0;
46370
47289
  stderr.write(`
46371
47290
  ${this.prefix}: Starting...
@@ -46375,7 +47294,7 @@ ${this.prefix}: Starting...
46375
47294
  * Update to a specific step.
46376
47295
  */
46377
47296
  step(index, message) {
46378
- if (!this.enabled) return;
47297
+ if (!this.enabled || isQuiet()) return;
46379
47298
  this.currentStep = index;
46380
47299
  const stepName = this.steps[index] ?? message ?? "Working...";
46381
47300
  const progress = `[${index + 1}/${this.totalSteps}]`;
@@ -46397,7 +47316,7 @@ ${this.prefix}: Starting...
46397
47316
  * one JSON object per CLI invocation (ADR-039 / T927).
46398
47317
  */
46399
47318
  complete(summary) {
46400
- if (!this.enabled) return;
47319
+ if (!this.enabled || isQuiet()) return;
46401
47320
  if (summary) {
46402
47321
  stderr.write(`
46403
47322
  ${this.prefix}: \u2713 ${summary}
@@ -46414,7 +47333,7 @@ ${this.prefix}: \u2713 Complete
46414
47333
  * Report an error.
46415
47334
  */
46416
47335
  error(message) {
46417
- if (!this.enabled) return;
47336
+ if (!this.enabled || isQuiet()) return;
46418
47337
  stderr.write(`
46419
47338
  ${this.prefix}: \u2717 ${message}
46420
47339
 
@@ -48129,10 +49048,10 @@ var init_federation = __esm({
48129
49048
  // packages/cleo/src/cli/commands/find.ts
48130
49049
  var find_exports = {};
48131
49050
  __export(find_exports, {
48132
- findCommand: () => findCommand3
49051
+ findCommand: () => findCommand4
48133
49052
  });
48134
49053
  import { createPage } from "@cleocode/core";
48135
- var findCommand3;
49054
+ var findCommand4;
48136
49055
  var init_find = __esm({
48137
49056
  "packages/cleo/src/cli/commands/find.ts"() {
48138
49057
  "use strict";
@@ -48140,7 +49059,7 @@ var init_find = __esm({
48140
49059
  init_dist();
48141
49060
  init_cli();
48142
49061
  init_renderers();
48143
- findCommand3 = defineCommand({
49062
+ findCommand4 = defineCommand({
48144
49063
  meta: { name: "find", description: "Fuzzy search tasks by title/description" },
48145
49064
  args: {
48146
49065
  query: {
@@ -48159,7 +49078,16 @@ var init_find = __esm({
48159
49078
  limit: { type: "string", description: "Max results (default: 20)" },
48160
49079
  offset: { type: "string", description: "Skip first N results" },
48161
49080
  fields: { type: "string", description: "Comma-separated additional fields to include" },
48162
- verbose: { type: "boolean", description: "Include all task fields", alias: "v" },
49081
+ verbose: {
49082
+ type: "boolean",
49083
+ description: "Return full task records instead of the MVI projection (id + title + status + key metadata). T9922.",
49084
+ alias: "v"
49085
+ },
49086
+ // T9922 — MVI record projection opt-out alias (surfaced for --help).
49087
+ full: {
49088
+ type: "boolean",
49089
+ description: "Alias for --verbose. T9922."
49090
+ },
48163
49091
  /**
48164
49092
  * Filter by task kind axis (T944/T9072).
48165
49093
  * Values: work | research | experiment | bug | spike | release
@@ -48167,6 +49095,20 @@ var init_find = __esm({
48167
49095
  kind: {
48168
49096
  type: "string",
48169
49097
  description: "Filter by kind axis (work|research|experiment|bug|spike|release) \u2014 T944"
49098
+ },
49099
+ /**
49100
+ * Unified urgency surface (T9905).
49101
+ *
49102
+ * Selects tasks where
49103
+ * priority IN ('critical','high') OR severity IN ('P0','P1')
49104
+ *
49105
+ * Combines the two orthogonal urgency axes (priority + severity) into a
49106
+ * single filter so agents don't have to query each axis separately.
49107
+ */
49108
+ urgent: {
49109
+ type: "boolean",
49110
+ description: "Surface urgent work across both axes: priority IN (critical,high) OR severity IN (P0,P1) (T9905)",
49111
+ alias: "u"
48170
49112
  }
48171
49113
  },
48172
49114
  async run({ args }) {
@@ -48184,6 +49126,7 @@ var init_find = __esm({
48184
49126
  if (args.fields !== void 0) params["fields"] = args.fields;
48185
49127
  if (args.verbose !== void 0) params["verbose"] = args.verbose;
48186
49128
  if (args.kind !== void 0) params["kind"] = args.kind;
49129
+ if (args.urgent !== void 0) params["urgent"] = args.urgent;
48187
49130
  const response = await dispatchRaw("query", "tasks", "find", params);
48188
49131
  if (!response.success) {
48189
49132
  handleRawError(response, { command: "find", operation: "tasks.find" });
@@ -48540,7 +49483,7 @@ function applyJsonFlag(jsonFlag) {
48540
49483
  }
48541
49484
  }
48542
49485
  var statusCommand9, resolveCommand, depsCommand2, rawCommand, discoverCommand, searchCommand2, augmentCommand, contextCommand2, impactCommand2, impactFullCommand, clustersCommand, flowsCommand, diffCommand, routeMapCommand, shapeCheckCommand, searchCodeCommand, wikiCommand, hotPathsCommand, hotNodesCommand, coldSymbolsCommand, orphansCommand, queryCommand, initCommand, syncCommand4, reconcileCommand, livingFullContextCommand, livingTaskFootprintCommand, livingBrainAnchorsCommand, livingWhyCommand, livingConduitScanCommand, livingCommand, graphCommand2;
48543
- var init_graph2 = __esm({
49486
+ var init_graph3 = __esm({
48544
49487
  "packages/cleo/src/cli/commands/graph.ts"() {
48545
49488
  "use strict";
48546
49489
  init_dist();
@@ -49604,11 +50547,12 @@ import { join as join26 } from "node:path";
49604
50547
  import { fileURLToPath as fileURLToPath6 } from "node:url";
49605
50548
  import {
49606
50549
  CleoError as CleoError4,
49607
- formatError as formatError4,
49608
50550
  getWorkflowTemplatesDir as getCoreWorkflowTemplatesDir,
49609
50551
  initProject as initProject2,
50552
+ pushWarning as pushWarning5,
49610
50553
  scaffoldWorkflows
49611
50554
  } from "@cleocode/core";
50555
+ import { getTemplatesByKind } from "@cleocode/core/templates/registry";
49612
50556
  function getGitignoreTemplate() {
49613
50557
  try {
49614
50558
  const thisFile = fileURLToPath6(import.meta.url);
@@ -49626,6 +50570,9 @@ function getGitignoreTemplate() {
49626
50570
  function getWorkflowTemplatesDir2() {
49627
50571
  return getCoreWorkflowTemplatesDir();
49628
50572
  }
50573
+ function isWorkflowName(id) {
50574
+ return id === "release-prepare" || id === "release-publish" || id === "release-fanout" || id === "release-rollback";
50575
+ }
49629
50576
  var initCommand2;
49630
50577
  var init_init = __esm({
49631
50578
  "packages/cleo/src/cli/commands/init.ts"() {
@@ -49666,7 +50613,11 @@ var init_init = __esm({
49666
50613
  },
49667
50614
  workflows: {
49668
50615
  type: "boolean",
49669
- description: "Scaffold the release-prepare.yml workflow into .github/workflows/ (T9531).",
50616
+ /**
50617
+ * @deprecated Use `cleo templates install --kind workflow` instead
50618
+ * (T9886 / Saga T9855). Removal target: v2026.7.0. T9888.
50619
+ */
50620
+ description: "[DEPRECATED \u2014 use `cleo templates install --kind workflow`] Scaffold release workflows into .github/workflows/. Will be removed in v2026.7.0.",
49670
50621
  default: false
49671
50622
  },
49672
50623
  "dry-run": {
@@ -49678,11 +50629,23 @@ var init_init = __esm({
49678
50629
  async run({ args }) {
49679
50630
  try {
49680
50631
  if (args.workflows) {
50632
+ pushWarning5({
50633
+ code: "W_INIT_WORKFLOWS_DEPRECATED",
50634
+ message: "[deprecated] cleo init --workflows: use `cleo templates install --kind workflow` instead. This alias will be removed in v2026.7.0.",
50635
+ severity: "warn",
50636
+ deprecated: "cleo init --workflows",
50637
+ replacement: "cleo templates install --kind workflow",
50638
+ removeBy: "v2026.7.0",
50639
+ context: { task: "T9888", saga: "T9855" }
50640
+ });
49681
50641
  const projectRoot = process.cwd();
49682
50642
  const templatesDir = getWorkflowTemplatesDir2();
50643
+ const workflowEntries = getTemplatesByKind("workflow");
50644
+ const templates2 = workflowEntries.map((entry) => entry.id).filter((id) => isWorkflowName(id));
49683
50645
  const result2 = await scaffoldWorkflows({
49684
50646
  projectRoot,
49685
50647
  templatesDir,
50648
+ ...templates2.length > 0 ? { templates: templates2 } : {},
49686
50649
  dryRun: !!args["dry-run"],
49687
50650
  force: !!args.force
49688
50651
  });
@@ -49724,7 +50687,7 @@ var init_init = __esm({
49724
50687
  );
49725
50688
  } catch (err) {
49726
50689
  if (err instanceof CleoError4) {
49727
- cliError(formatError4(err), err.code, { name: "E_INTERNAL" });
50690
+ cliError(`init failed: ${err.message}`, err.code, { name: "E_INTERNAL" });
49728
50691
  process.exit(err.code);
49729
50692
  }
49730
50693
  throw err;
@@ -50495,6 +51458,20 @@ var init_list3 = __esm({
50495
51458
  "parent-id": {
50496
51459
  type: "string",
50497
51460
  description: "Alias for --parent (legacy parentId compatibility)"
51461
+ },
51462
+ // T9922 — MVI record projection opt-out flags (surfaced for --help).
51463
+ verbose: {
51464
+ type: "boolean",
51465
+ description: "Return full task records instead of the MVI projection (id + title + status + key metadata). T9922."
51466
+ },
51467
+ full: {
51468
+ type: "boolean",
51469
+ description: "Alias for --verbose. T9922."
51470
+ },
51471
+ // T9932 — 1-line-per-record summary render. Global flag; parsed by cli/index.ts.
51472
+ summary: {
51473
+ type: "boolean",
51474
+ description: 'Render each task as a single line "<id> [<status>] <title-truncated-60>". Composes with --output: --output {id|table|count|silent} wins. T9932.'
50498
51475
  }
50499
51476
  };
50500
51477
  listCommand11 = defineCommand({
@@ -50727,7 +51704,7 @@ async function resolveDefaultModel(provider) {
50727
51704
  return profile?.defaultModel ?? IMPLICIT_FALLBACK_MODEL;
50728
51705
  }
50729
51706
  async function runLlmStream(opts) {
50730
- const stdout = opts.stdout ?? process.stdout;
51707
+ const stdout2 = opts.stdout ?? process.stdout;
50731
51708
  const stderr2 = opts.stderr ?? process.stderr;
50732
51709
  const session = opts._sessionOverride ?? await buildSession(opts.provider, opts.model ?? await resolveDefaultModel(opts.provider));
50733
51710
  const sendOpts = {
@@ -50738,7 +51715,7 @@ async function runLlmStream(opts) {
50738
51715
  const stream = session.stream(messages, sendOpts);
50739
51716
  for await (const delta of stream) {
50740
51717
  if (delta.text) {
50741
- stdout.write(delta.text);
51718
+ stdout2.write(delta.text);
50742
51719
  }
50743
51720
  if (delta.reasoning && opts.showThink) {
50744
51721
  stderr2.write(delta.reasoning);
@@ -51253,7 +52230,7 @@ var llm_exports = {};
51253
52230
  __export(llm_exports, {
51254
52231
  llmCommand: () => llmCommand
51255
52232
  });
51256
- import { pushWarning as pushWarning5 } from "@cleocode/core";
52233
+ import { pushWarning as pushWarning6 } from "@cleocode/core";
51257
52234
  async function getListProviders() {
51258
52235
  const { listProviders } = await import(
51259
52236
  /* webpackIgnore: true */
@@ -51384,7 +52361,7 @@ var init_llm3 = __esm({
51384
52361
  apiKey = envValue;
51385
52362
  source = "env";
51386
52363
  } else if (typeof a["api-key"] === "string" && a["api-key"]) {
51387
- pushWarning5({
52364
+ pushWarning6({
51388
52365
  code: "W_DEPRECATED_FLAG",
51389
52366
  message: API_KEY_FLAG_DEPRECATION,
51390
52367
  deprecated: "--api-key=<value>",
@@ -51813,7 +52790,7 @@ async function readStdin() {
51813
52790
  process.stdin.on("error", reject);
51814
52791
  });
51815
52792
  }
51816
- var showCommand7, listCommand13, findCommand4, statsCommand3, appendCommand, archiveCommand2, manifestCommand;
52793
+ var showCommand7, listCommand13, findCommand5, statsCommand3, appendCommand, archiveCommand2, manifestCommand;
51817
52794
  var init_manifest3 = __esm({
51818
52795
  "packages/cleo/src/cli/commands/manifest.ts"() {
51819
52796
  "use strict";
@@ -51899,7 +52876,7 @@ var init_manifest3 = __esm({
51899
52876
  );
51900
52877
  }
51901
52878
  });
51902
- findCommand4 = defineCommand({
52879
+ findCommand5 = defineCommand({
51903
52880
  meta: {
51904
52881
  name: "find",
51905
52882
  description: "Full-text search manifest entries"
@@ -52108,7 +53085,7 @@ var init_manifest3 = __esm({
52108
53085
  subCommands: {
52109
53086
  show: showCommand7,
52110
53087
  list: listCommand13,
52111
- find: findCommand4,
53088
+ find: findCommand5,
52112
53089
  stats: statsCommand3,
52113
53090
  append: appendCommand,
52114
53091
  archive: archiveCommand2
@@ -52188,7 +53165,7 @@ function makeMemorySubcommand(opts) {
52188
53165
  }
52189
53166
  });
52190
53167
  }
52191
- var storeCommand, findCommand5, statsCommand4, observeCommand, timelineCommand, fetchCommand2, decisionFindCommand, decisionStoreCommand, linkCommand, traceCommand, relatedCommand, contextCommand3, graphStatsCommand, graphShowCommand, graphNeighborsCommand, graphAddCommand, graphRemoveCommand, reasonWhyCommand, reasonSimilarCommand, searchHybridCommand, codeLinksCommand, codeAutoLinkCommand, codeMemoriesForCodeCommand, codeForMemoryCommand, consolidateCommand, dreamCommand, reflectCommand, dedupScanCommand, importCommand4, doctorCommand3, llmStatusCommand, verifyCommand, pendingVerifyCommand, tierStatsCommand, tierPromoteCommand, tierDemoteCommand, precompactFlushCommand, backfillRunCommand, backfillApproveCommand, backfillRollbackCommand, backfillCommand2, digestCommand, recentCommand, diaryReadCommand, diaryWriteCommand, diaryCommand, watchCommand2, tierCommand, sweepCommand, memoryCommand;
53168
+ var storeCommand, findCommand6, statsCommand4, observeCommand, timelineCommand, fetchCommand2, decisionFindCommand, decisionStoreCommand, linkCommand, traceCommand, relatedCommand, contextCommand3, graphStatsCommand, graphShowCommand, graphNeighborsCommand, graphAddCommand, graphRemoveCommand, reasonWhyCommand, reasonSimilarCommand, searchHybridCommand, codeLinksCommand, codeAutoLinkCommand, codeMemoriesForCodeCommand, codeForMemoryCommand, consolidateCommand, dreamCommand, reflectCommand, dedupScanCommand, importCommand4, doctorCommand3, llmStatusCommand, verifyCommand, pendingVerifyCommand, tierStatsCommand, tierPromoteCommand, tierDemoteCommand, precompactFlushCommand, backfillRunCommand, backfillApproveCommand, backfillRollbackCommand, backfillCommand2, digestCommand, recentCommand, diaryReadCommand, diaryWriteCommand, diaryCommand, watchCommand2, tierCommand, sweepCommand, memoryCommand;
52192
53169
  var init_memory3 = __esm({
52193
53170
  "packages/cleo/src/cli/commands/memory.ts"() {
52194
53171
  "use strict";
@@ -52280,7 +53257,7 @@ var init_memory3 = __esm({
52280
53257
  }
52281
53258
  }
52282
53259
  });
52283
- findCommand5 = defineCommand({
53260
+ findCommand6 = defineCommand({
52284
53261
  meta: {
52285
53262
  name: "find",
52286
53263
  description: "Search BRAIN memory (all tables, or filter by --type pattern|learning)"
@@ -53893,7 +54870,7 @@ data: ${JSON.stringify({ ts: item.ts })}
53893
54870
  meta: { name: "memory", description: "BRAIN memory operations (patterns, learnings)" },
53894
54871
  subCommands: {
53895
54872
  store: storeCommand,
53896
- find: findCommand5,
54873
+ find: findCommand6,
53897
54874
  stats: statsCommand4,
53898
54875
  observe: observeCommand,
53899
54876
  timeline: timelineCommand,
@@ -55375,8 +56352,8 @@ var init_nexus3 = __esm({
55375
56352
  return;
55376
56353
  }
55377
56354
  if (!skipPrompt) {
55378
- const { createInterface: createInterface4 } = await import("node:readline");
55379
- const rl = createInterface4({ input: process.stdin, output: process.stdout });
56355
+ const { createInterface: createInterface5 } = await import("node:readline");
56356
+ const rl = createInterface5({ input: process.stdin, output: process.stdout });
55380
56357
  const confirmed = await new Promise((resolve8) => {
55381
56358
  rl.question(
55382
56359
  `
@@ -56682,7 +57659,9 @@ __export(orchestrate_exports, {
56682
57659
  formatRollupTable: () => formatRollupTable,
56683
57660
  orchestrateCommand: () => orchestrateCommand
56684
57661
  });
57662
+ import { execFileSync as execFileSync3 } from "node:child_process";
56685
57663
  import { orchestration } from "@cleocode/core";
57664
+ import { BUILD_CONFIG as BUILD_CONFIG2 } from "@cleocode/core/internal";
56686
57665
  function formatRollupTable(rollup) {
56687
57666
  const waves = "waves" in rollup ? rollup.waves : [rollup];
56688
57667
  const lines = [];
@@ -56775,9 +57754,34 @@ var init_orchestrate3 = __esm({
56775
57754
  epic: {
56776
57755
  type: "string",
56777
57756
  description: "Epic ID to scope status to"
57757
+ },
57758
+ "merge-queue": {
57759
+ type: "boolean",
57760
+ description: "Show GitHub merge queue depth instead of epic status (T10445)"
56778
57761
  }
56779
57762
  },
56780
57763
  async run({ args }) {
57764
+ if (args["merge-queue"]) {
57765
+ const repo = BUILD_CONFIG2.repository.fullName;
57766
+ let queueDepth = 0;
57767
+ let estimatedWaitMinutes = 0;
57768
+ let blocked = false;
57769
+ let note = "merge queue not enabled";
57770
+ try {
57771
+ const raw = execFileSync3(
57772
+ "gh",
57773
+ ["api", `repos/${repo}/merge-queue`, "--jq", ".entries | length"],
57774
+ { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], timeout: 15e3 }
57775
+ );
57776
+ queueDepth = Number(raw.trim()) || 0;
57777
+ estimatedWaitMinutes = queueDepth * 5;
57778
+ blocked = queueDepth > 10;
57779
+ note = queueDepth > 0 ? "active" : "empty";
57780
+ } catch {
57781
+ }
57782
+ cliOutput({ queueDepth, estimatedWaitMinutes, blocked, note }, { command: "orchestrate" });
57783
+ return;
57784
+ }
56781
57785
  await dispatchFromCli(
56782
57786
  "query",
56783
57787
  "orchestrate",
@@ -56947,6 +57951,10 @@ var init_orchestrate3 = __esm({
56947
57951
  scope: {
56948
57952
  type: "string",
56949
57953
  description: "T9807 sparse-checkout scope: directory prefix to check out in the worktree (cone mode). Example: --scope packages/cleo creates a worktree with only that subtree checked out. Reduces disk usage and checkout time for tasks scoped to a single package."
57954
+ },
57955
+ "orchestrator-defer": {
57956
+ type: "boolean",
57957
+ description: "T9214 atomicity waiver: defer worker file-scope declaration to commit time. Tier-1+ orchestrators only \u2014 records auditable atomicity_waiver in the spawn manifest. Bypasses E_ATOMICITY_NO_SCOPE for worker tasks without explicit AC.files."
56950
57958
  }
56951
57959
  },
56952
57960
  async run({ args }) {
@@ -56957,6 +57965,7 @@ var init_orchestrate3 = __esm({
56957
57965
  tier = parsed;
56958
57966
  }
56959
57967
  }
57968
+ const atomicityScope = args["orchestrator-defer"] ? "orchestrator-defer" : void 0;
56960
57969
  await dispatchFromCli(
56961
57970
  "mutate",
56962
57971
  "orchestrate",
@@ -56966,7 +57975,8 @@ var init_orchestrate3 = __esm({
56966
57975
  protocolType: args.protocol,
56967
57976
  tier,
56968
57977
  noWorktree: args["no-worktree"] === true,
56969
- ...args.scope ? { spawnScope: args.scope } : {}
57978
+ ...args.scope ? { spawnScope: args.scope } : {},
57979
+ ...atomicityScope ? { atomicityScope } : {}
56970
57980
  },
56971
57981
  { command: "orchestrate" }
56972
57982
  );
@@ -57585,7 +58595,7 @@ __export(otel_exports, {
57585
58595
  import {
57586
58596
  CleoError as CleoError5,
57587
58597
  clearOtelData,
57588
- formatError as formatError5,
58598
+ formatError as formatError4,
57589
58599
  getOtelSessions,
57590
58600
  getOtelSpawns,
57591
58601
  getOtelStatus,
@@ -57606,7 +58616,7 @@ var init_otel = __esm({
57606
58616
  cliOutput(result, { command: "otel" });
57607
58617
  } catch (err) {
57608
58618
  if (err instanceof CleoError5) {
57609
- cliError(formatError5(err), err.code, { name: "E_INTERNAL" });
58619
+ cliError(formatError4(err), err.code, { name: "E_INTERNAL" });
57610
58620
  process.exit(err.code);
57611
58621
  }
57612
58622
  throw err;
@@ -57621,7 +58631,7 @@ var init_otel = __esm({
57621
58631
  cliOutput(result, { command: "otel" });
57622
58632
  } catch (err) {
57623
58633
  if (err instanceof CleoError5) {
57624
- cliError(formatError5(err), err.code, { name: "E_INTERNAL" });
58634
+ cliError(formatError4(err), err.code, { name: "E_INTERNAL" });
57625
58635
  process.exit(err.code);
57626
58636
  }
57627
58637
  throw err;
@@ -57649,7 +58659,7 @@ var init_otel = __esm({
57649
58659
  cliOutput(result, { command: "otel" });
57650
58660
  } catch (err) {
57651
58661
  if (err instanceof CleoError5) {
57652
- cliError(formatError5(err), err.code, { name: "E_INTERNAL" });
58662
+ cliError(formatError4(err), err.code, { name: "E_INTERNAL" });
57653
58663
  process.exit(err.code);
57654
58664
  }
57655
58665
  throw err;
@@ -57677,7 +58687,7 @@ var init_otel = __esm({
57677
58687
  cliOutput(result, { command: "otel" });
57678
58688
  } catch (err) {
57679
58689
  if (err instanceof CleoError5) {
57680
- cliError(formatError5(err), err.code, { name: "E_INTERNAL" });
58690
+ cliError(formatError4(err), err.code, { name: "E_INTERNAL" });
57681
58691
  process.exit(err.code);
57682
58692
  }
57683
58693
  throw err;
@@ -57705,7 +58715,7 @@ var init_otel = __esm({
57705
58715
  cliOutput(result, { command: "otel" });
57706
58716
  } catch (err) {
57707
58717
  if (err instanceof CleoError5) {
57708
- cliError(formatError5(err), err.code, { name: "E_INTERNAL" });
58718
+ cliError(formatError4(err), err.code, { name: "E_INTERNAL" });
57709
58719
  process.exit(err.code);
57710
58720
  }
57711
58721
  throw err;
@@ -57720,7 +58730,7 @@ var init_otel = __esm({
57720
58730
  cliOutput(result, { command: "otel" });
57721
58731
  } catch (err) {
57722
58732
  if (err instanceof CleoError5) {
57723
- cliError(formatError5(err), err.code, { name: "E_INTERNAL" });
58733
+ cliError(formatError4(err), err.code, { name: "E_INTERNAL" });
57724
58734
  process.exit(err.code);
57725
58735
  }
57726
58736
  throw err;
@@ -59829,7 +60839,7 @@ __export(research_exports, {
59829
60839
  function generateResearchId() {
59830
60840
  return `res_${Date.now()}`;
59831
60841
  }
59832
- var addCommand10, showCommand11, listCommand21, pendingCommand2, linkCommand2, updateCommand, statsCommand5, linksCommand, archiveCommand3, manifestCommand2, researchCommand;
60842
+ var addCommand10, showCommand11, listCommand21, pendingCommand2, linkCommand2, updateCommand2, statsCommand5, linksCommand, archiveCommand3, manifestCommand2, researchCommand;
59833
60843
  var init_research2 = __esm({
59834
60844
  "packages/cleo/src/cli/commands/research.ts"() {
59835
60845
  "use strict";
@@ -59996,7 +61006,7 @@ var init_research2 = __esm({
59996
61006
  );
59997
61007
  }
59998
61008
  });
59999
- updateCommand = defineCommand({
61009
+ updateCommand2 = defineCommand({
60000
61010
  meta: { name: "update", description: "Update research findings" },
60001
61011
  args: {
60002
61012
  id: {
@@ -60150,7 +61160,7 @@ var init_research2 = __esm({
60150
61160
  list: listCommand21,
60151
61161
  pending: pendingCommand2,
60152
61162
  link: linkCommand2,
60153
- update: updateCommand,
61163
+ update: updateCommand2,
60154
61164
  stats: statsCommand5,
60155
61165
  links: linksCommand,
60156
61166
  archive: archiveCommand3,
@@ -61290,7 +62300,7 @@ import { join as join28 } from "node:path";
61290
62300
  import * as readline2 from "node:readline";
61291
62301
  import { promisify } from "node:util";
61292
62302
  import {
61293
- BUILD_CONFIG as BUILD_CONFIG2,
62303
+ BUILD_CONFIG as BUILD_CONFIG3,
61294
62304
  CleoError as CleoError8,
61295
62305
  checkAllRegisteredProjects as checkAllRegisteredProjects2,
61296
62306
  checkStorageMigration,
@@ -61309,14 +62319,14 @@ async function getCurrentVersion() {
61309
62319
  }
61310
62320
  async function getNpmInstalledVersion() {
61311
62321
  try {
61312
- const { stdout } = await execAsync("npm", [
62322
+ const { stdout: stdout2 } = await execAsync("npm", [
61313
62323
  "ls",
61314
62324
  "-g",
61315
62325
  "@cleocode/cleo",
61316
62326
  "--depth=0",
61317
62327
  "--json"
61318
62328
  ]);
61319
- const data = JSON.parse(stdout);
62329
+ const data = JSON.parse(stdout2);
61320
62330
  return data.dependencies?.["@cleocode/cleo"]?.version ?? null;
61321
62331
  } catch {
61322
62332
  return null;
@@ -61324,19 +62334,19 @@ async function getNpmInstalledVersion() {
61324
62334
  }
61325
62335
  async function getDistTagVersion(tag) {
61326
62336
  try {
61327
- const { stdout } = await execAsync("npm", ["view", `@cleocode/cleo@${tag}`, "version"]);
61328
- const v = stdout.trim();
62337
+ const { stdout: stdout2 } = await execAsync("npm", ["view", `@cleocode/cleo@${tag}`, "version"]);
62338
+ const v = stdout2.trim();
61329
62339
  return v || null;
61330
62340
  } catch {
61331
62341
  if (tag === "latest") {
61332
62342
  try {
61333
- const { stdout } = await execAsync("curl", [
62343
+ const { stdout: stdout2 } = await execAsync("curl", [
61334
62344
  "-sL",
61335
62345
  "--max-time",
61336
62346
  "10",
61337
62347
  `https://api.github.com/repos/${GITHUB_REPO}/releases/latest`
61338
62348
  ]);
61339
- const data = JSON.parse(stdout);
62349
+ const data = JSON.parse(stdout2);
61340
62350
  return data.tag_name?.replace(/^v/, "") ?? null;
61341
62351
  } catch {
61342
62352
  return null;
@@ -61537,7 +62547,7 @@ var init_self_update = __esm({
61537
62547
  init_progress();
61538
62548
  init_renderers();
61539
62549
  execAsync = promisify(execFile);
61540
- GITHUB_REPO = BUILD_CONFIG2.repository.fullName;
62550
+ GITHUB_REPO = BUILD_CONFIG3.repository.fullName;
61541
62551
  selfUpdateCommand = defineCommand({
61542
62552
  meta: {
61543
62553
  name: "self-update",
@@ -61764,10 +62774,13 @@ var init_self_update = __esm({
61764
62774
  // packages/cleo/src/cli/commands/sentient.ts
61765
62775
  var sentient_exports = {};
61766
62776
  __export(sentient_exports, {
62777
+ __setPromptAcceptExecutionForTest: () => __setPromptAcceptExecutionForTest,
62778
+ promptAcceptExecution: () => promptAcceptExecution,
61767
62779
  sentientCommand: () => sentientCommand
61768
62780
  });
61769
62781
  import { join as join29 } from "node:path";
61770
- import { cwd as processCwd3 } from "node:process";
62782
+ import { cwd as processCwd3, stdin, stdout } from "node:process";
62783
+ import { createInterface as createInterface3 } from "node:readline/promises";
61771
62784
  import {
61772
62785
  getSentientDaemonStatus as getSentientDaemonStatus2,
61773
62786
  monitorWorkers,
@@ -61778,6 +62791,12 @@ import {
61778
62791
  stopSentientDaemon,
61779
62792
  WORKER_BUDGET_MS
61780
62793
  } from "@cleocode/core/sentient/daemon.js";
62794
+ import {
62795
+ appendSentientExecuteAudit,
62796
+ executeFixAction,
62797
+ extractFixActionFromNotesJson,
62798
+ parseFixAction
62799
+ } from "@cleocode/core/sentient/execute-action.js";
61781
62800
  import { safeRunProposeTick } from "@cleocode/core/sentient/propose-tick.js";
61782
62801
  import { patchSentientState, readSentientState as readSentientState2 } from "@cleocode/core/sentient/state.js";
61783
62802
  import { safeRunTick } from "@cleocode/core/sentient/tick.js";
@@ -61797,7 +62816,14 @@ function emitFailure3(code, message, _jsonMode, operation) {
61797
62816
  cliError(message, code, { name: code }, operation ? { operation } : void 0);
61798
62817
  process.exit(1);
61799
62818
  }
61800
- var projectArgs2, startSub, stopSub, statusSub, resumeSub, tickSub, proposeListSub, proposeAcceptSub, proposeRejectSub, proposeDiffSub, proposeRunSub, proposeEnableSub, proposeDisableSub, proposeSub, baselineCaptureSub, baselineSub, allowlistListSub, allowlistAddSub, allowlistRemoveSub, allowlistSub, monitorSub, reviewStatusListSub, reviewStatusShowSub, reviewStatusAcceptSub, reviewStatusRejectSub, reviewStatusSub, sentientCommand;
62819
+ function __setPromptAcceptExecutionForTest(next) {
62820
+ const prev = promptAcceptExecution;
62821
+ promptAcceptExecution = next;
62822
+ return () => {
62823
+ promptAcceptExecution = prev;
62824
+ };
62825
+ }
62826
+ var projectArgs2, startSub, stopSub, statusSub, resumeSub, tickSub, proposeListSub, promptAcceptExecution, proposeAcceptSub, proposeRejectSub, proposeDiffSub, proposeRunSub, proposeEnableSub, proposeDisableSub, proposeSub, baselineCaptureSub, baselineSub, allowlistListSub, allowlistAddSub, allowlistRemoveSub, allowlistSub, monitorSub, reviewStatusListSub, reviewStatusShowSub, reviewStatusAcceptSub, reviewStatusRejectSub, reviewStatusSub, sentientCommand;
61801
62827
  var init_sentient3 = __esm({
61802
62828
  "packages/cleo/src/cli/commands/sentient.ts"() {
61803
62829
  "use strict";
@@ -61995,19 +63021,42 @@ Logs: ${logPath}`
61995
63021
  }
61996
63022
  }
61997
63023
  });
63024
+ promptAcceptExecution = async (fixAction) => {
63025
+ const rl = createInterface3({ input: stdin, output: stdout });
63026
+ try {
63027
+ stdout.write(`[sentient] Proposal accepted. fixAction:
63028
+ $ ${fixAction}
63029
+ `);
63030
+ const answer = await rl.question("Execute now? [y/N] ");
63031
+ const normalised = answer.trim().toLowerCase();
63032
+ return normalised === "y" || normalised === "yes";
63033
+ } finally {
63034
+ rl.close();
63035
+ }
63036
+ };
61998
63037
  proposeAcceptSub = defineCommand({
61999
63038
  meta: {
62000
63039
  name: "accept",
62001
- description: "Accept a proposal \u2014 transition proposed \u2192 pending"
63040
+ description: "Accept a proposal \u2014 transition proposed \u2192 pending, optionally execute its fixAction"
62002
63041
  },
62003
63042
  args: {
62004
63043
  ...projectArgs2,
62005
- id: { type: "positional", description: "Proposal task ID", required: true }
63044
+ id: { type: "positional", description: "Proposal task ID", required: true },
63045
+ execute: {
63046
+ type: "boolean",
63047
+ description: "Execute proposal.fixAction without prompting"
63048
+ },
63049
+ "no-execute": {
63050
+ type: "boolean",
63051
+ description: "Skip fixAction execution even if the proposal carries one"
63052
+ }
62006
63053
  },
62007
63054
  async run({ args }) {
62008
63055
  const projectRoot = resolveProjectRoot6(args.project);
62009
63056
  const jsonMode = args.json === true;
62010
63057
  const id = args.id;
63058
+ const forceExecute = args.execute === true;
63059
+ const skipExecute = args["no-execute"] === true;
62011
63060
  try {
62012
63061
  const { getDb: getDb3 } = await import("@cleocode/core/store/sqlite.js");
62013
63062
  const { tasks } = await import("@cleocode/core/store/tasks-schema");
@@ -62034,10 +63083,54 @@ Logs: ${logPath}`
62034
63083
  proposalsAccepted: state.tier2Stats.proposalsAccepted + 1
62035
63084
  }
62036
63085
  });
63086
+ const fixAction = extractFixActionFromNotesJson(existing.notesJson ?? null);
63087
+ let shouldExecute = false;
63088
+ if (fixAction && !skipExecute) {
63089
+ if (forceExecute) {
63090
+ shouldExecute = true;
63091
+ } else {
63092
+ shouldExecute = await promptAcceptExecution(fixAction);
63093
+ }
63094
+ }
63095
+ if (!shouldExecute) {
63096
+ emitSuccess2(
63097
+ {
63098
+ id,
63099
+ status: "pending",
63100
+ acceptedAt: now,
63101
+ executed: false,
63102
+ fixAction: fixAction ?? null
63103
+ },
63104
+ jsonMode,
63105
+ `Proposal ${id} accepted \u2192 pending`
63106
+ );
63107
+ return;
63108
+ }
63109
+ const parsed = parseFixAction(fixAction);
63110
+ if (!parsed.ok) {
63111
+ emitFailure3(parsed.code, parsed.reason, jsonMode);
63112
+ return;
63113
+ }
63114
+ const result = await executeFixAction(parsed, { cwd: projectRoot });
63115
+ await appendSentientExecuteAudit(projectRoot, {
63116
+ proposalId: id,
63117
+ fixAction,
63118
+ exitCode: result.exitCode,
63119
+ durationMs: result.durationMs,
63120
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
63121
+ });
62037
63122
  emitSuccess2(
62038
- { id, status: "pending", acceptedAt: now },
63123
+ {
63124
+ id,
63125
+ status: "pending",
63126
+ acceptedAt: now,
63127
+ executed: true,
63128
+ exitCode: result.exitCode,
63129
+ stderrSnippet: result.stderrSnippet,
63130
+ fixAction
63131
+ },
62039
63132
  jsonMode,
62040
- `Proposal ${id} accepted \u2192 pending`
63133
+ `Proposal ${id} accepted \u2192 pending (fixAction exit=${result.exitCode})`
62041
63134
  );
62042
63135
  } catch (err) {
62043
63136
  const message = err instanceof Error ? err.message : String(err);
@@ -62833,9 +63926,9 @@ async function promptOwnerAuthPassword(sessionName) {
62833
63926
  );
62834
63927
  return null;
62835
63928
  }
62836
- const { createInterface: createInterface4 } = await import("node:readline");
63929
+ const { createInterface: createInterface5 } = await import("node:readline");
62837
63930
  const { deriveOwnerAuthToken } = await import("@cleocode/core/internal");
62838
- const rl = createInterface4({
63931
+ const rl = createInterface5({
62839
63932
  input: process.stdin,
62840
63933
  output: process.stderr,
62841
63934
  terminal: true
@@ -62876,7 +63969,7 @@ async function promptOwnerAuthPassword(sessionName) {
62876
63969
  const token = deriveOwnerAuthToken(sessionName, password);
62877
63970
  return token;
62878
63971
  }
62879
- var startCommand7, endCommand, handoffCommand2, statusCommand14, resumeCommand2, findCommand6, listCommand23, gcCommand2, showCommand13, driftCommand, contextDriftCommand, suspendCommand, recordAssumptionCommand, recordDecisionCommand, decisionLogCommand, adoptCommand, lintCommand, sessionCommand;
63972
+ var startCommand7, endCommand, handoffCommand2, statusCommand14, resumeCommand2, findCommand7, listCommand23, gcCommand2, showCommand13, driftCommand, contextDriftCommand, suspendCommand, recordAssumptionCommand, recordDecisionCommand, decisionLogCommand, adoptCommand, lintCommand, sessionCommand;
62880
63973
  var init_session4 = __esm({
62881
63974
  "packages/cleo/src/cli/commands/session.ts"() {
62882
63975
  "use strict";
@@ -63106,7 +64199,7 @@ var init_session4 = __esm({
63106
64199
  );
63107
64200
  }
63108
64201
  });
63109
- findCommand6 = defineCommand({
64202
+ findCommand7 = defineCommand({
63110
64203
  meta: {
63111
64204
  name: "find",
63112
64205
  description: "Find sessions (lightweight discovery \u2014 minimal fields, low context cost)"
@@ -63469,7 +64562,7 @@ var init_session4 = __esm({
63469
64562
  handoff: handoffCommand2,
63470
64563
  status: statusCommand14,
63471
64564
  resume: resumeCommand2,
63472
- find: findCommand6,
64565
+ find: findCommand7,
63473
64566
  list: listCommand23,
63474
64567
  gc: gcCommand2,
63475
64568
  show: showCommand13,
@@ -63954,9 +65047,27 @@ var init_show2 = __esm({
63954
65047
  showCommand14 = defineCommand({
63955
65048
  meta: {
63956
65049
  name: "show",
63957
- description: "Show full task details by ID (returns complete task record with metadata, verification, lifecycle)"
65050
+ description: "Show task details by ID. MVI-projected (id + title + status + key metadata) by default; pass --verbose / --full to receive the complete record with description, acceptance, verification, evidence, etc. (T9922)"
65051
+ },
65052
+ args: {
65053
+ ...paramsToCittyArgs(getOperationParams("query", "tasks", "show")),
65054
+ // T9922 — MVI record projection opt-out flags. The global parser in
65055
+ // cli/index.ts reads these too; the declarations here surface them in
65056
+ // `cleo show --help` and document the contract for agents.
65057
+ verbose: {
65058
+ type: "boolean",
65059
+ description: "Return the full task record (description, acceptance, verification, evidence) instead of the MVI projection. T9922."
65060
+ },
65061
+ full: {
65062
+ type: "boolean",
65063
+ description: "Alias for --verbose. T9922."
65064
+ },
65065
+ // T9932 — 1-line summary render. Global flag; parsed by cli/index.ts.
65066
+ summary: {
65067
+ type: "boolean",
65068
+ description: 'Render the task as a single line "<id> [<status>] <title-truncated-60>". Composes with --output: --output {id|table|count|silent} wins. T9932.'
65069
+ }
63958
65070
  },
63959
- args: paramsToCittyArgs(getOperationParams("query", "tasks", "show")),
63960
65071
  async run({ args }) {
63961
65072
  await dispatchFromCli(
63962
65073
  "query",
@@ -64078,7 +65189,7 @@ function buildSkillsDoctorAdoptAdapters() {
64078
65189
  }
64079
65190
  };
64080
65191
  }
64081
- var listCommand24, searchCommand4, findCommand7, validateCommand8, infoCommand, installCommand3, uninstallCommand2, enableCommand2, disableCommand2, refreshCommand, dispatchCommand, catalogCommand, precedenceCommand, depsCommand4, doctorBridgeCommand, doctorAdoptOrphansCommand, statsCommand6, importHermesCommand, migrateCommand2, pruneTelemetryCommand, spawnProvidersCommand, doctorDiagnoseCommand, doctorCommand4, proposePatchCommand, skillsCommand2;
65192
+ 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;
64082
65193
  var init_skills2 = __esm({
64083
65194
  "packages/cleo/src/cli/commands/skills.ts"() {
64084
65195
  "use strict";
@@ -64136,7 +65247,7 @@ var init_skills2 = __esm({
64136
65247
  );
64137
65248
  }
64138
65249
  });
64139
- findCommand7 = defineCommand({
65250
+ findCommand8 = defineCommand({
64140
65251
  meta: {
64141
65252
  name: "find",
64142
65253
  description: "Federated skill search across local, canonical, and federation peers"
@@ -64821,7 +65932,7 @@ var init_skills2 = __esm({
64821
65932
  subCommands: {
64822
65933
  list: listCommand24,
64823
65934
  search: searchCommand4,
64824
- find: findCommand7,
65935
+ find: findCommand8,
64825
65936
  validate: validateCommand8,
64826
65937
  info: infoCommand,
64827
65938
  install: installCommand3,
@@ -66139,7 +67250,7 @@ var init_install = __esm({
66139
67250
  });
66140
67251
 
66141
67252
  // packages/cleo/src/cli/commands/templates/list.ts
66142
- import { getTemplateManifest, getTemplatesByKind } from "@cleocode/core/templates/registry";
67253
+ import { getTemplateManifest, getTemplatesByKind as getTemplatesByKind2 } from "@cleocode/core/templates/registry";
66143
67254
  function parseTemplateKind(raw) {
66144
67255
  if (raw === void 0 || raw === "") return null;
66145
67256
  return TEMPLATE_KINDS.includes(raw) ? raw : null;
@@ -66178,7 +67289,7 @@ var init_list4 = __esm({
66178
67289
  process.exit(2 /* INVALID_INPUT */);
66179
67290
  return;
66180
67291
  }
66181
- const entries = kind === null ? getTemplateManifest() : getTemplatesByKind(kind);
67292
+ const entries = kind === null ? getTemplateManifest() : getTemplatesByKind2(kind);
66182
67293
  const result = { kind, entries };
66183
67294
  cliOutput(result, {
66184
67295
  command: "templates-list",
@@ -67286,7 +68397,7 @@ var init_transcript = __esm({
67286
68397
  // packages/cleo/src/cli/commands/update.ts
67287
68398
  var update_exports = {};
67288
68399
  __export(update_exports, {
67289
- updateCommand: () => updateCommand2
68400
+ updateCommand: () => updateCommand3
67290
68401
  });
67291
68402
  import {
67292
68403
  appendSignedSeverityAttestation as appendSignedSeverityAttestation2,
@@ -67297,7 +68408,7 @@ import {
67297
68408
  TASK_PIPELINE_STAGES,
67298
68409
  validateOperationInput as validateOperationInput3
67299
68410
  } from "@cleocode/core";
67300
- var updateCommand2;
68411
+ var updateCommand3;
67301
68412
  var init_update = __esm({
67302
68413
  "packages/cleo/src/cli/commands/update.ts"() {
67303
68414
  "use strict";
@@ -67306,7 +68417,7 @@ var init_update = __esm({
67306
68417
  init_cli();
67307
68418
  init_collect_input();
67308
68419
  init_renderers();
67309
- updateCommand2 = defineCommand({
68420
+ updateCommand3 = defineCommand({
67310
68421
  meta: {
67311
68422
  name: "update",
67312
68423
  description: "Update a task. Safe under concurrent invocation \u2014 retries on SQLITE_BUSY up to 4 attempts (gh#391)."
@@ -67350,7 +68461,7 @@ var init_update = __esm({
67350
68461
  },
67351
68462
  priority: {
67352
68463
  type: "string",
67353
- description: "New priority (critical|high|medium|low)",
68464
+ description: "New priority (critical|high|medium|low). Orthogonal to --severity \u2014 see `cleo find --urgent` for the unified surface (T9905).",
67354
68465
  alias: "p"
67355
68466
  },
67356
68467
  type: {
@@ -67474,7 +68585,7 @@ var init_update = __esm({
67474
68585
  */
67475
68586
  severity: {
67476
68587
  type: "string",
67477
- description: "Severity level (P0|P1|P2|P3) \u2014 valid for any --role (T9073). Orthogonal to priority. Appends signed attestation."
68588
+ description: "Severity level (P0|P1|P2|P3) \u2014 valid for any --kind (T9073). Orthogonal to --priority \u2014 does NOT auto-map (a P0 with priority=medium stays medium). Use `cleo find --urgent` for the unified surface (T9905). Appends signed attestation."
67478
68589
  },
67479
68590
  /**
67480
68591
  * Operator-supplied justification required to override the
@@ -68060,10 +69171,10 @@ var web_exports = {};
68060
69171
  __export(web_exports, {
68061
69172
  webCommand: () => webCommand
68062
69173
  });
68063
- import { execFileSync as execFileSync3, spawn as spawn3 } from "node:child_process";
69174
+ import { execFileSync as execFileSync4, spawn as spawn3 } from "node:child_process";
68064
69175
  import { mkdir as mkdir4, open, readFile as readFile7, rm, stat as stat2, writeFile as writeFile3 } from "node:fs/promises";
68065
69176
  import { join as join34 } from "node:path";
68066
- import { CleoError as CleoError11, formatError as formatError6, getCleoHome as getCleoHome5 } from "@cleocode/core";
69177
+ import { CleoError as CleoError11, formatError as formatError5, getCleoHome as getCleoHome5 } from "@cleocode/core";
68067
69178
  function getWebPaths() {
68068
69179
  const cleoHome = getCleoHome5();
68069
69180
  return {
@@ -68124,7 +69235,7 @@ async function startWebServer(port, host) {
68124
69235
  await stat2(webIndexPath);
68125
69236
  } catch {
68126
69237
  try {
68127
- execFileSync3("pnpm", ["--filter", "@cleocode/studio", "run", "build"], {
69238
+ execFileSync4("pnpm", ["--filter", "@cleocode/studio", "run", "build"], {
68128
69239
  cwd: projectRoot,
68129
69240
  stdio: "ignore"
68130
69241
  });
@@ -68216,7 +69327,7 @@ var init_web = __esm({
68216
69327
  await startWebServer(Number.parseInt(args.port, 10), args.host);
68217
69328
  } catch (err) {
68218
69329
  if (err instanceof CleoError11) {
68219
- console.error(formatError6(err));
69330
+ console.error(formatError5(err));
68220
69331
  process.exit(err.code);
68221
69332
  }
68222
69333
  throw err;
@@ -68260,7 +69371,7 @@ var init_web = __esm({
68260
69371
  cliOutput({ stopped: true }, { command: "web", message: "CLEO Web UI stopped" });
68261
69372
  } catch (err) {
68262
69373
  if (err instanceof CleoError11) {
68263
- console.error(formatError6(err));
69374
+ console.error(formatError5(err));
68264
69375
  process.exit(err.code);
68265
69376
  }
68266
69377
  throw err;
@@ -68313,7 +69424,7 @@ var init_web = __esm({
68313
69424
  await startWebServer(Number.parseInt(args.port, 10), args.host);
68314
69425
  } catch (err) {
68315
69426
  if (err instanceof CleoError11) {
68316
- console.error(formatError6(err));
69427
+ console.error(formatError5(err));
68317
69428
  process.exit(err.code);
68318
69429
  }
68319
69430
  throw err;
@@ -68328,7 +69439,7 @@ var init_web = __esm({
68328
69439
  cliOutput(status, { command: "web" });
68329
69440
  } catch (err) {
68330
69441
  if (err instanceof CleoError11) {
68331
- console.error(formatError6(err));
69442
+ console.error(formatError5(err));
68332
69443
  process.exit(err.code);
68333
69444
  }
68334
69445
  throw err;
@@ -68361,7 +69472,7 @@ var init_web = __esm({
68361
69472
  cliOutput({ url }, { command: "web", message: `Open browser to: ${url}` });
68362
69473
  } catch (err) {
68363
69474
  if (err instanceof CleoError11) {
68364
- console.error(formatError6(err));
69475
+ console.error(formatError5(err));
68365
69476
  process.exit(err.code);
68366
69477
  }
68367
69478
  throw err;
@@ -69126,7 +70237,7 @@ var COMMAND_MANIFEST = [
69126
70237
  exportName: "graphCommand",
69127
70238
  name: "graph",
69128
70239
  description: "Project-scoped code intelligence: symbol graph, impact analysis, clusters, flows",
69129
- load: async () => (await Promise.resolve().then(() => (init_graph2(), graph_exports))).graphCommand
70240
+ load: async () => (await Promise.resolve().then(() => (init_graph3(), graph_exports))).graphCommand
69130
70241
  },
69131
70242
  {
69132
70243
  exportName: "historyCommand",
@@ -69461,7 +70572,7 @@ var COMMAND_MANIFEST = [
69461
70572
  {
69462
70573
  exportName: "showCommand",
69463
70574
  name: "show",
69464
- description: "Show full task details by ID (returns complete task record with metadata, verification, lifecycle)",
70575
+ description: "Show task details by ID. MVI-projected (id + title + status + key metadata) by default; pass --verbose / --full to receive the complete record with description, acceptance, verification, evidence, etc. (T9922)",
69465
70576
  load: async () => (await Promise.resolve().then(() => (init_show2(), show_exports))).showCommand
69466
70577
  },
69467
70578
  {
@@ -69819,6 +70930,10 @@ function resolveFormat(opts, defaults) {
69819
70930
  return resolveOutputFormat(input2);
69820
70931
  }
69821
70932
 
70933
+ // packages/cleo/src/cli/index.ts
70934
+ init_output_context();
70935
+ init_projection_context();
70936
+
69822
70937
  // packages/cleo/src/cli/resolve-subcommand.ts
69823
70938
  async function resolveLazyValue(input2) {
69824
70939
  if (typeof input2 === "function") {
@@ -69846,6 +70961,7 @@ async function resolveSubCommandForHelp(cmd, rawArgs) {
69846
70961
  }
69847
70962
 
69848
70963
  // packages/cleo/src/cli/index.ts
70964
+ init_summary_context();
69849
70965
  {
69850
70966
  const [major] = process.versions.node.split(".").map(Number);
69851
70967
  if (typeof major !== "number" || major < 24) {
@@ -69904,6 +71020,9 @@ alias("pipeline", "phaseCommand");
69904
71020
  async function startCli() {
69905
71021
  const argv = process.argv.slice(2);
69906
71022
  const rawOpts = {};
71023
+ let verboseFlag = false;
71024
+ let outputModeRaw;
71025
+ let summaryFlag = false;
69907
71026
  for (let i = 0; i < argv.length; i++) {
69908
71027
  const arg = argv[i];
69909
71028
  if (arg === "--json") rawOpts["json"] = true;
@@ -69912,6 +71031,9 @@ async function startCli() {
69912
71031
  else if (arg === "--field" && i + 1 < argv.length) rawOpts["field"] = argv[++i];
69913
71032
  else if (arg === "--fields" && i + 1 < argv.length) rawOpts["fields"] = argv[++i];
69914
71033
  else if (arg === "--mvi" && i + 1 < argv.length) rawOpts["mvi"] = argv[++i];
71034
+ else if (arg === "--verbose" || arg === "--full") verboseFlag = true;
71035
+ else if (arg === "--output" && i + 1 < argv.length) outputModeRaw = argv[++i];
71036
+ else if (arg === "--summary") summaryFlag = true;
69915
71037
  }
69916
71038
  const formatResolution = resolveFormat(rawOpts);
69917
71039
  setFormatContext(formatResolution);
@@ -69920,6 +71042,19 @@ async function startCli() {
69920
71042
  fieldResolution.mvi = "minimal";
69921
71043
  }
69922
71044
  setFieldContext(fieldResolution);
71045
+ setProjectionOptOut(verboseFlag || formatResolution.format === "human");
71046
+ if (outputModeRaw !== void 0) {
71047
+ if (!isOutputMode(outputModeRaw)) {
71048
+ process.stderr.write(
71049
+ `Error: invalid --output mode "${outputModeRaw}"
71050
+ Valid modes: envelope, id, table, count, silent
71051
+ `
71052
+ );
71053
+ process.exit(2);
71054
+ }
71055
+ setOutputMode(outputModeRaw);
71056
+ }
71057
+ setSummaryMode(summaryFlag);
69923
71058
  const isHelpOrVersion = argv.length === 0 || argv[0] === "--help" || argv[0] === "-h" || argv[0] === "--version" || argv[0] === "-V" || argv[0] === "help";
69924
71059
  if (argv[0] === "--version" || argv[0] === "-V") {
69925
71060
  const { cliOutput: cliOutput2 } = await Promise.resolve().then(() => (init_renderers(), renderers_exports));
@@ -69927,6 +71062,10 @@ async function startCli() {
69927
71062
  return;
69928
71063
  }
69929
71064
  if (!isHelpOrVersion) {
71065
+ if (rawOpts["quiet"] === true) {
71066
+ const { setLoggerQuiet } = await import("@cleocode/core/internal");
71067
+ setLoggerQuiet(true);
71068
+ }
69930
71069
  await runStartupMaintenance();
69931
71070
  }
69932
71071
  if (!isHelpOrVersion) {