@cleocode/cleo 2026.5.92 → 2026.5.93

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
@@ -1584,6 +1584,390 @@ var init_credentials = __esm({
1584
1584
  }
1585
1585
  });
1586
1586
 
1587
+ // packages/contracts/src/docs-taxonomy.ts
1588
+ import { readFileSync } from "node:fs";
1589
+ import { join } from "node:path";
1590
+ function validateDocKindConfig(raw, source) {
1591
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
1592
+ throw new DocKindConfigError(`${source}: top-level value must be an object`, source);
1593
+ }
1594
+ const obj = raw;
1595
+ if (obj.extensions === void 0) {
1596
+ return {};
1597
+ }
1598
+ if (!Array.isArray(obj.extensions)) {
1599
+ throw new DocKindConfigError(`${source}: 'extensions' must be an array`, source);
1600
+ }
1601
+ const extensions = [];
1602
+ for (let i = 0; i < obj.extensions.length; i++) {
1603
+ const item = obj.extensions[i];
1604
+ extensions.push(validateExtensionEntry(item, source, i));
1605
+ }
1606
+ return { extensions };
1607
+ }
1608
+ function validateExtensionEntry(raw, source, index) {
1609
+ const where = `${source} extensions[${index}]`;
1610
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
1611
+ throw new DocKindConfigError(`${where}: must be an object`, source);
1612
+ }
1613
+ const obj = raw;
1614
+ const kind = requireString(obj, "kind", where, source);
1615
+ if (!/^[a-z][a-z0-9-]*$/.test(kind)) {
1616
+ throw new DocKindConfigError(
1617
+ `${where}: 'kind' must be lowercase kebab-case (got '${kind}')`,
1618
+ source
1619
+ );
1620
+ }
1621
+ const builtinNames = new Set(BUILTIN_DOC_KIND_VALUES);
1622
+ if (builtinNames.has(kind)) {
1623
+ throw new DocKindConfigError(
1624
+ `${where}: kind '${kind}' shadows a built-in \u2014 built-ins cannot be overridden`,
1625
+ source
1626
+ );
1627
+ }
1628
+ const label = requireString(obj, "label", where, source);
1629
+ const description = requireString(obj, "description", where, source);
1630
+ const defaultOwnerKind = requireString(obj, "defaultOwnerKind", where, source);
1631
+ if (defaultOwnerKind !== "task" && defaultOwnerKind !== "session" && defaultOwnerKind !== "observation" && defaultOwnerKind !== "project") {
1632
+ throw new DocKindConfigError(
1633
+ `${where}: 'defaultOwnerKind' must be task|session|observation|project (got '${defaultOwnerKind}')`,
1634
+ source
1635
+ );
1636
+ }
1637
+ const publishDir = requireString(obj, "publishDir", where, source);
1638
+ const requiresEntityId = obj.requiresEntityId;
1639
+ if (typeof requiresEntityId !== "boolean") {
1640
+ throw new DocKindConfigError(`${where}: 'requiresEntityId' must be a boolean`, source);
1641
+ }
1642
+ let entityIdPattern;
1643
+ if (obj.entityIdPattern !== void 0) {
1644
+ if (typeof obj.entityIdPattern !== "string") {
1645
+ throw new DocKindConfigError(`${where}: 'entityIdPattern' must be a string`, source);
1646
+ }
1647
+ if (obj.entityIdPattern.length > DocKindRegistry.SAFE_REGEX_LENGTH_LIMIT) {
1648
+ throw new DocKindConfigError(
1649
+ `${where}: 'entityIdPattern' exceeds ${DocKindRegistry.SAFE_REGEX_LENGTH_LIMIT} chars`,
1650
+ source
1651
+ );
1652
+ }
1653
+ entityIdPattern = obj.entityIdPattern;
1654
+ }
1655
+ if (requiresEntityId && entityIdPattern === void 0) {
1656
+ throw new DocKindConfigError(
1657
+ `${where}: 'entityIdPattern' is required when 'requiresEntityId' is true`,
1658
+ source
1659
+ );
1660
+ }
1661
+ return {
1662
+ kind,
1663
+ label,
1664
+ description,
1665
+ defaultOwnerKind,
1666
+ publishDir,
1667
+ requiresEntityId,
1668
+ ...entityIdPattern !== void 0 ? { entityIdPattern } : {}
1669
+ };
1670
+ }
1671
+ function compileExtension(ext, source) {
1672
+ let entityIdPattern;
1673
+ if (ext.entityIdPattern !== void 0) {
1674
+ try {
1675
+ entityIdPattern = new RegExp(ext.entityIdPattern);
1676
+ } catch (err) {
1677
+ throw new DocKindConfigError(
1678
+ `${source}: invalid regex for kind '${ext.kind}': ${err.message}`,
1679
+ source
1680
+ );
1681
+ }
1682
+ }
1683
+ return {
1684
+ kind: ext.kind,
1685
+ label: ext.label,
1686
+ description: ext.description,
1687
+ defaultOwnerKind: ext.defaultOwnerKind,
1688
+ publishDir: ext.publishDir,
1689
+ requiresEntityId: ext.requiresEntityId,
1690
+ ...entityIdPattern !== void 0 ? { entityIdPattern } : {},
1691
+ isExtension: true
1692
+ };
1693
+ }
1694
+ function requireString(obj, field, where, source) {
1695
+ const value = obj[field];
1696
+ if (typeof value !== "string" || value.length === 0) {
1697
+ throw new DocKindConfigError(`${where}: '${field}' must be a non-empty string`, source);
1698
+ }
1699
+ return value;
1700
+ }
1701
+ function buildSlugExample(meta) {
1702
+ switch (meta.kind) {
1703
+ case "adr":
1704
+ return "adr-001-intro";
1705
+ case "changeset":
1706
+ return "t9788-docs-taxonomy";
1707
+ case "release-note":
1708
+ return "v2026.5.93";
1709
+ case "rcasd":
1710
+ return "t9788-investigation";
1711
+ default:
1712
+ return meta.entityIdPattern?.source;
1713
+ }
1714
+ }
1715
+ var BUILTIN_DOC_KINDS, BUILTIN_DOC_KIND_VALUES, DocKindRegistry, DocKindConfigError;
1716
+ var init_docs_taxonomy = __esm({
1717
+ "packages/contracts/src/docs-taxonomy.ts"() {
1718
+ "use strict";
1719
+ BUILTIN_DOC_KINDS = [
1720
+ {
1721
+ kind: "adr",
1722
+ label: "ADR",
1723
+ description: "Architectural decision record",
1724
+ defaultOwnerKind: "task",
1725
+ publishDir: "docs/adr",
1726
+ requiresEntityId: true,
1727
+ entityIdPattern: /^adr-\d{3,4}-[a-z0-9-]+$/
1728
+ },
1729
+ {
1730
+ kind: "spec",
1731
+ label: "Spec",
1732
+ description: "Technical specification",
1733
+ defaultOwnerKind: "task",
1734
+ publishDir: "docs/spec",
1735
+ requiresEntityId: false
1736
+ },
1737
+ {
1738
+ kind: "research",
1739
+ label: "Research",
1740
+ description: "Investigation / research note",
1741
+ defaultOwnerKind: "task",
1742
+ publishDir: "docs/research",
1743
+ requiresEntityId: false
1744
+ },
1745
+ {
1746
+ kind: "handoff",
1747
+ label: "Handoff",
1748
+ description: "Session / agent handoff",
1749
+ defaultOwnerKind: "session",
1750
+ publishDir: "docs/handoff",
1751
+ requiresEntityId: false
1752
+ },
1753
+ {
1754
+ kind: "note",
1755
+ label: "Note",
1756
+ description: "Agent observation / informal note",
1757
+ defaultOwnerKind: "observation",
1758
+ publishDir: "docs/note",
1759
+ requiresEntityId: false
1760
+ },
1761
+ {
1762
+ kind: "llm-readme",
1763
+ label: "LLM README",
1764
+ description: "Machine-readable README (llms.txt)",
1765
+ defaultOwnerKind: "project",
1766
+ publishDir: ".",
1767
+ requiresEntityId: false
1768
+ },
1769
+ {
1770
+ kind: "changeset",
1771
+ label: "Changeset",
1772
+ description: "Atomic change entry (release-note input)",
1773
+ defaultOwnerKind: "task",
1774
+ publishDir: ".changeset",
1775
+ requiresEntityId: true,
1776
+ entityIdPattern: /^t\d+-[a-z0-9-]+$/
1777
+ },
1778
+ {
1779
+ kind: "release-note",
1780
+ label: "Release Note",
1781
+ description: "Composed release notes",
1782
+ defaultOwnerKind: "project",
1783
+ publishDir: "docs/release",
1784
+ requiresEntityId: true,
1785
+ entityIdPattern: /^v\d{4}\.\d+\.\d+(-[a-z0-9-]+)?$/
1786
+ },
1787
+ {
1788
+ kind: "plan",
1789
+ label: "Plan",
1790
+ description: "Epic / saga decomposition plan",
1791
+ defaultOwnerKind: "task",
1792
+ publishDir: "docs/plan",
1793
+ requiresEntityId: false
1794
+ },
1795
+ {
1796
+ kind: "rcasd",
1797
+ label: "RCASD",
1798
+ description: "Root-cause analysis + scoped delivery",
1799
+ defaultOwnerKind: "task",
1800
+ publishDir: ".cleo/rcasd",
1801
+ requiresEntityId: true,
1802
+ entityIdPattern: /^t\d+(-.+)?$/
1803
+ }
1804
+ ];
1805
+ BUILTIN_DOC_KIND_VALUES = Object.freeze(
1806
+ BUILTIN_DOC_KINDS.map((d) => d.kind)
1807
+ );
1808
+ DocKindRegistry = class _DocKindRegistry {
1809
+ /**
1810
+ * Maximum allowed length of an `entityIdPattern` source string.
1811
+ *
1812
+ * Caps the input surface so a malformed extension config cannot trigger
1813
+ * pathological regex backtracking. 256 chars is far more than any
1814
+ * realistic slug pattern (typical: 30–60 chars).
1815
+ */
1816
+ static SAFE_REGEX_LENGTH_LIMIT = 256;
1817
+ byKind;
1818
+ orderedEntries;
1819
+ /**
1820
+ * Construct a registry from an explicit array of entries.
1821
+ *
1822
+ * Most callers should use {@link DocKindRegistry.load} instead; this
1823
+ * constructor is exposed for tests that want to bypass filesystem I/O.
1824
+ *
1825
+ * @param entries - Pre-validated doc-kind metadata (built-in + extensions).
1826
+ */
1827
+ constructor(entries) {
1828
+ this.orderedEntries = entries;
1829
+ const map2 = /* @__PURE__ */ new Map();
1830
+ for (const entry of entries) {
1831
+ if (!map2.has(entry.kind)) map2.set(entry.kind, entry);
1832
+ }
1833
+ this.byKind = map2;
1834
+ }
1835
+ /**
1836
+ * Load the canonical registry, merging built-ins with extensions from
1837
+ * `<projectRoot>/.cleo/docs-config.json`.
1838
+ *
1839
+ * Missing or unreadable config file → returns the built-in-only registry.
1840
+ * Malformed config (bad JSON, invalid entry, regex too long, etc.) →
1841
+ * throws {@link DocKindConfigError} so the caller can surface a clear
1842
+ * envelope rather than silently dropping extensions.
1843
+ *
1844
+ * @param projectRoot - Absolute path to the repo root.
1845
+ * @throws DocKindConfigError when the config exists but is invalid.
1846
+ */
1847
+ static load(projectRoot) {
1848
+ const configPath = join(projectRoot, ".cleo", "docs-config.json");
1849
+ let raw;
1850
+ try {
1851
+ raw = readFileSync(configPath, "utf-8");
1852
+ } catch {
1853
+ return new _DocKindRegistry(BUILTIN_DOC_KINDS);
1854
+ }
1855
+ let parsed;
1856
+ try {
1857
+ parsed = JSON.parse(raw);
1858
+ } catch (err) {
1859
+ throw new DocKindConfigError(
1860
+ `${configPath}: invalid JSON \u2014 ${err.message}`,
1861
+ configPath
1862
+ );
1863
+ }
1864
+ const config = validateDocKindConfig(parsed, configPath);
1865
+ const extensions = (config.extensions ?? []).map((ext) => compileExtension(ext, configPath));
1866
+ return new _DocKindRegistry([...BUILTIN_DOC_KINDS, ...extensions]);
1867
+ }
1868
+ /**
1869
+ * Build a registry from already-parsed config — bypasses filesystem I/O.
1870
+ *
1871
+ * Used by tests and HTTP-dispatch callers that hand-construct a config
1872
+ * object instead of reading from disk.
1873
+ *
1874
+ * @param config - Parsed config object (or `undefined` for built-ins only).
1875
+ * @param sourceLabel - Optional label used in error messages.
1876
+ * @throws DocKindConfigError when the config object is invalid.
1877
+ */
1878
+ static fromConfig(config, sourceLabel = "<inline-config>") {
1879
+ if (!config) return new _DocKindRegistry(BUILTIN_DOC_KINDS);
1880
+ const validated = validateDocKindConfig(config, sourceLabel);
1881
+ const extensions = (validated.extensions ?? []).map(
1882
+ (ext) => compileExtension(ext, sourceLabel)
1883
+ );
1884
+ return new _DocKindRegistry([...BUILTIN_DOC_KINDS, ...extensions]);
1885
+ }
1886
+ /**
1887
+ * Default registry — built-in kinds only, no extensions.
1888
+ *
1889
+ * Suitable for code paths that never need project-level extensions
1890
+ * (e.g. unit tests, library-mode consumers).
1891
+ */
1892
+ static builtinOnly() {
1893
+ return new _DocKindRegistry(BUILTIN_DOC_KINDS);
1894
+ }
1895
+ /** True when `kind` is registered (built-in OR extension). */
1896
+ has(kind) {
1897
+ return this.byKind.has(kind);
1898
+ }
1899
+ /** Look up metadata for a registered kind. Returns `undefined` on miss. */
1900
+ get(kind) {
1901
+ return this.byKind.get(kind);
1902
+ }
1903
+ /**
1904
+ * List every registered kind, built-ins first then extensions in
1905
+ * declaration order.
1906
+ *
1907
+ * Used by `cleo docs schema` and `cleo docs list-types`.
1908
+ */
1909
+ list() {
1910
+ return this.orderedEntries;
1911
+ }
1912
+ /**
1913
+ * Validate a slug against the registered pattern for `kind`.
1914
+ *
1915
+ * Behaviour:
1916
+ * - Unknown kind → `{ ok: false, error: "unknown kind '<kind>'" }`.
1917
+ * - Known kind with `requiresEntityId === false` → always `{ ok: true }`.
1918
+ * - Known kind with `requiresEntityId === true` and no pattern → defensive
1919
+ * `{ ok: false }` since the registry entry is internally inconsistent.
1920
+ * - Known kind with pattern → tests `slug` against the pattern.
1921
+ *
1922
+ * @param kind - Registered kind id.
1923
+ * @param slug - Slug to validate.
1924
+ * @returns Pass/fail result with a human-readable error on failure.
1925
+ */
1926
+ validateSlug(kind, slug) {
1927
+ const meta = this.byKind.get(kind);
1928
+ if (!meta) {
1929
+ return { ok: false, error: `unknown kind '${kind}'` };
1930
+ }
1931
+ if (!meta.requiresEntityId) {
1932
+ return { ok: true };
1933
+ }
1934
+ if (!meta.entityIdPattern) {
1935
+ return {
1936
+ ok: false,
1937
+ error: `kind '${kind}' requires an entityIdPattern but the registry entry omits one`
1938
+ };
1939
+ }
1940
+ if (!meta.entityIdPattern.test(slug)) {
1941
+ return {
1942
+ ok: false,
1943
+ error: `slug '${slug}' does not match pattern ${meta.entityIdPattern.source} for kind '${kind}'`,
1944
+ example: buildSlugExample(meta)
1945
+ };
1946
+ }
1947
+ return { ok: true };
1948
+ }
1949
+ /**
1950
+ * Map a kind to its `publishDir` (e.g. `'adr'` → `'docs/adr'`).
1951
+ *
1952
+ * Returns `undefined` for unknown kinds — callers decide whether to
1953
+ * fall back to a default (e.g. `'docs/note'`) or surface an error.
1954
+ */
1955
+ publishDirFor(kind) {
1956
+ return this.byKind.get(kind)?.publishDir;
1957
+ }
1958
+ };
1959
+ DocKindConfigError = class extends Error {
1960
+ /** Source identifier — file path on disk, or `<inline-config>` for tests. */
1961
+ source;
1962
+ constructor(message, source) {
1963
+ super(message);
1964
+ this.name = "DocKindConfigError";
1965
+ this.source = source;
1966
+ }
1967
+ };
1968
+ }
1969
+ });
1970
+
1587
1971
  // packages/contracts/src/engine-result.ts
1588
1972
  var init_engine_result = __esm({
1589
1973
  "packages/contracts/src/engine-result.ts"() {
@@ -1839,6 +2223,7 @@ var init_dialectic = __esm({
1839
2223
  var init_docs = __esm({
1840
2224
  "packages/contracts/src/operations/docs.ts"() {
1841
2225
  "use strict";
2226
+ init_docs_taxonomy();
1842
2227
  }
1843
2228
  });
1844
2229
 
@@ -2990,6 +3375,7 @@ var init_src2 = __esm({
2990
3375
  init_branch_lock();
2991
3376
  init_changesets();
2992
3377
  init_credentials();
3378
+ init_docs_taxonomy();
2993
3379
  init_engine_result();
2994
3380
  init_errors();
2995
3381
  init_evidence_record_schema();
@@ -6003,6 +6389,24 @@ var init_registry = __esm({
6003
6389
  requiredParams: [],
6004
6390
  params: []
6005
6391
  },
6392
+ {
6393
+ gateway: "query",
6394
+ domain: "session",
6395
+ operation: "lint",
6396
+ description: "session.lint (query) \u2014 agent-accountability harness: flag raw-md writes to canonical doc paths in a transcript (T9797)",
6397
+ tier: 1,
6398
+ idempotent: true,
6399
+ sessionRequired: false,
6400
+ requiredParams: ["transcript"],
6401
+ params: [
6402
+ {
6403
+ name: "transcript",
6404
+ type: "string",
6405
+ required: true,
6406
+ description: "Absolute path to the *.jsonl session transcript to lint"
6407
+ }
6408
+ ]
6409
+ },
6006
6410
  {
6007
6411
  gateway: "query",
6008
6412
  domain: "orchestrate",
@@ -6899,6 +7303,25 @@ var init_registry = __esm({
6899
7303
  requiredParams: [],
6900
7304
  params: []
6901
7305
  },
7306
+ // T9796: Docs canon-routing CI gate — block raw *.md writes that bypass SSoT
7307
+ {
7308
+ gateway: "query",
7309
+ domain: "check",
7310
+ operation: "canon.docs",
7311
+ description: "check.canon.docs (query) \u2014 CI gate: rejects new *.md files that bypass the docs SSoT (.cleo/canon.yml routing). Scans git diff additions against rawMdPaths whose owning DocKind has rawMdAllowed:false.",
7312
+ tier: 1,
7313
+ idempotent: true,
7314
+ sessionRequired: false,
7315
+ requiredParams: [],
7316
+ params: [
7317
+ {
7318
+ name: "baseRef",
7319
+ type: "string",
7320
+ required: false,
7321
+ description: "Git revision to diff against (default: origin/main)"
7322
+ }
7323
+ ]
7324
+ },
6902
7325
  // T065: Agent workflow compliance telemetry
6903
7326
  {
6904
7327
  gateway: "query",
@@ -13246,9 +13669,10 @@ function lafsSuccess(data, _operation, extra) {
13246
13669
  ...extra?.page ? { page: extra.page } : {}
13247
13670
  };
13248
13671
  }
13249
- function lafsError(code, message, _operation, fix) {
13672
+ function lafsError(code, message, _operation, fix, details) {
13250
13673
  const error = { code, message };
13251
13674
  if (fix !== void 0) error.fix = fix;
13675
+ if (details !== void 0) error.details = details;
13252
13676
  return {
13253
13677
  success: false,
13254
13678
  error
@@ -14126,8 +14550,8 @@ var smoke_provider_exports = {};
14126
14550
  __export(smoke_provider_exports, {
14127
14551
  smokeProvider: () => smokeProvider
14128
14552
  });
14129
- import { existsSync, readFileSync } from "node:fs";
14130
- import { join } from "node:path";
14553
+ import { existsSync, readFileSync as readFileSync2 } from "node:fs";
14554
+ import { join as join2 } from "node:path";
14131
14555
  function isLocal(dbPath, projectCleoDir, cleoHome) {
14132
14556
  return dbPath.startsWith(projectCleoDir) || dbPath.startsWith(cleoHome);
14133
14557
  }
@@ -14135,7 +14559,7 @@ function classifySpawn(spawnSrcPath) {
14135
14559
  if (!existsSync(spawnSrcPath)) return "no";
14136
14560
  let src;
14137
14561
  try {
14138
- src = readFileSync(spawnSrcPath, "utf-8");
14562
+ src = readFileSync2(spawnSrcPath, "utf-8");
14139
14563
  } catch {
14140
14564
  return "no";
14141
14565
  }
@@ -14147,7 +14571,7 @@ function countHookEvents(hooksSrcPath, canonicalEvents) {
14147
14571
  if (!existsSync(hooksSrcPath)) return 0;
14148
14572
  let src;
14149
14573
  try {
14150
- src = readFileSync(hooksSrcPath, "utf-8");
14574
+ src = readFileSync2(hooksSrcPath, "utf-8");
14151
14575
  } catch {
14152
14576
  return 0;
14153
14577
  }
@@ -14158,10 +14582,10 @@ function countHookEvents(hooksSrcPath, canonicalEvents) {
14158
14582
  return count;
14159
14583
  }
14160
14584
  function buildReport(partial) {
14161
- const sep = "\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550";
14585
+ const sep2 = "\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550";
14162
14586
  const lines = [
14163
14587
  `CLEO Smoke Probe \u2014 provider: ${partial.providerId}`,
14164
- sep,
14588
+ sep2,
14165
14589
  ` Adapter loaded: ${partial.adapterLoaded ? "yes" : "no"}`
14166
14590
  ];
14167
14591
  for (const db of partial.dbChecks) {
@@ -14193,7 +14617,7 @@ async function smokeProvider(providerId) {
14193
14617
  }
14194
14618
  })();
14195
14619
  const monorepoRoot = projectRoot;
14196
- const adapterDistPath = join(
14620
+ const adapterDistPath = join2(
14197
14621
  monorepoRoot,
14198
14622
  "packages",
14199
14623
  "adapters",
@@ -14223,9 +14647,9 @@ async function smokeProvider(providerId) {
14223
14647
  }
14224
14648
  }
14225
14649
  const cleoHome = coreInternal.getCleoHome();
14226
- const projectCleoDir = join(projectRoot, CLEO_DIR_NAME);
14650
+ const projectCleoDir = join2(projectRoot, CLEO_DIR_NAME);
14227
14651
  const taskDbPath = coreInternal.getTaskPath(projectRoot);
14228
- const brainPath = join(projectCleoDir, BRAIN_DB_FILENAME);
14652
+ const brainPath = join2(projectCleoDir, BRAIN_DB_FILENAME);
14229
14653
  const conduitDbPath = coreInternal.getConduitDbPath(projectRoot);
14230
14654
  const nexusDbPath = coreInternal.getNexusDbPath();
14231
14655
  const dbChecks = [
@@ -14245,7 +14669,7 @@ async function smokeProvider(providerId) {
14245
14669
  } catch {
14246
14670
  canonicalEvents = [];
14247
14671
  }
14248
- const hooksSrcPath = join(
14672
+ const hooksSrcPath = join2(
14249
14673
  monorepoRoot,
14250
14674
  "packages",
14251
14675
  "adapters",
@@ -14255,7 +14679,7 @@ async function smokeProvider(providerId) {
14255
14679
  "hooks.ts"
14256
14680
  );
14257
14681
  const hooksDeclared = countHookEvents(hooksSrcPath, canonicalEvents);
14258
- const spawnSrcPath = join(
14682
+ const spawnSrcPath = join2(
14259
14683
  monorepoRoot,
14260
14684
  "packages",
14261
14685
  "adapters",
@@ -15553,11 +15977,11 @@ var canon_exports = {};
15553
15977
  __export(canon_exports, {
15554
15978
  runCanonCheck: () => runCanonCheck
15555
15979
  });
15556
- import { readFileSync as readFileSync2 } from "node:fs";
15557
- import { join as join2 } from "node:path";
15980
+ import { readFileSync as readFileSync3 } from "node:fs";
15981
+ import { join as join3 } from "node:path";
15558
15982
  function readLines(filePath) {
15559
15983
  try {
15560
- return readFileSync2(filePath, "utf8").split("\n");
15984
+ return readFileSync3(filePath, "utf8").split("\n");
15561
15985
  } catch {
15562
15986
  return [];
15563
15987
  }
@@ -15607,11 +16031,11 @@ function countOperations(registryFilePath) {
15607
16031
  }
15608
16032
  function runCanonCheck(params) {
15609
16033
  const { projectRoot } = params;
15610
- const typesFile = join2(projectRoot, "packages/cleo/src/dispatch/types.ts");
15611
- const registryFile = join2(projectRoot, "packages/cleo/src/dispatch/registry.ts");
15612
- const archGuide = join2(projectRoot, "docs/concepts/CLEO-ARCHITECTURE-GUIDE.md");
15613
- const visionDoc = join2(projectRoot, "docs/concepts/CLEO-VISION.md");
15614
- const constitution = join2(projectRoot, "docs/specs/CLEO-OPERATION-CONSTITUTION.md");
16034
+ const typesFile = join3(projectRoot, "packages/cleo/src/dispatch/types.ts");
16035
+ const registryFile = join3(projectRoot, "packages/cleo/src/dispatch/registry.ts");
16036
+ const archGuide = join3(projectRoot, "docs/concepts/CLEO-ARCHITECTURE-GUIDE.md");
16037
+ const visionDoc = join3(projectRoot, "docs/concepts/CLEO-VISION.md");
16038
+ const constitution = join3(projectRoot, "docs/specs/CLEO-OPERATION-CONSTITUTION.md");
15615
16039
  const domainsInCode = countCanonicalDomains(typesFile);
15616
16040
  const operationsInCode = countOperations(registryFile);
15617
16041
  const excludedSet = new Set(EXCLUDED_FILENAMES);
@@ -15681,6 +16105,150 @@ var init_canon = __esm({
15681
16105
  }
15682
16106
  });
15683
16107
 
16108
+ // packages/cleo/src/dispatch/domains/check/canon-docs.ts
16109
+ var canon_docs_exports = {};
16110
+ __export(canon_docs_exports, {
16111
+ loadCanonRegistry: () => loadCanonRegistry,
16112
+ runCanonDocsCheck: () => runCanonDocsCheck
16113
+ });
16114
+ import { execSync } from "node:child_process";
16115
+ import { existsSync as existsSync2, readFileSync as readFileSync4 } from "node:fs";
16116
+ import { join as join4, sep } from "node:path";
16117
+ import { parse as parseYaml } from "yaml";
16118
+ function normaliseDir(dir) {
16119
+ const slashed = dir.split(sep).join("/");
16120
+ return slashed.endsWith("/") ? slashed : `${slashed}/`;
16121
+ }
16122
+ function listAddedMarkdownFiles(projectRoot, baseRef) {
16123
+ try {
16124
+ const out = execSync(`git diff --diff-filter=A --name-only ${baseRef}...HEAD`, {
16125
+ cwd: projectRoot,
16126
+ encoding: "utf8",
16127
+ stdio: ["pipe", "pipe", "pipe"]
16128
+ });
16129
+ return out.split("\n").map((line) => line.trim()).filter((line) => line.length > 0 && line.endsWith(".md"));
16130
+ } catch {
16131
+ return [];
16132
+ }
16133
+ }
16134
+ function validateCanonRegistry(raw, source) {
16135
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
16136
+ throw new Error(`${source}: top-level value must be an object`);
16137
+ }
16138
+ const obj = raw;
16139
+ const version = obj["version"];
16140
+ if (typeof version !== "number" || version !== 1) {
16141
+ throw new Error(`${source}: 'version' must be the integer 1 (got ${String(version)})`);
16142
+ }
16143
+ const kindsRaw = obj["kinds"];
16144
+ if (kindsRaw === null || typeof kindsRaw !== "object" || Array.isArray(kindsRaw)) {
16145
+ throw new Error(`${source}: 'kinds' must be an object`);
16146
+ }
16147
+ const kinds = {};
16148
+ for (const [kindId, entryRaw] of Object.entries(kindsRaw)) {
16149
+ kinds[kindId] = validateKindEntry(kindId, entryRaw, source);
16150
+ }
16151
+ return { version, kinds };
16152
+ }
16153
+ function validateKindEntry(kindId, raw, source) {
16154
+ const where = `${source} kinds.${kindId}`;
16155
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
16156
+ throw new Error(`${where}: must be an object`);
16157
+ }
16158
+ const obj = raw;
16159
+ const canonicalHome = obj["canonicalHome"];
16160
+ if (canonicalHome !== "ssot" && canonicalHome !== "ssot-first") {
16161
+ throw new Error(
16162
+ `${where}: 'canonicalHome' must be 'ssot' or 'ssot-first' (got ${String(canonicalHome)})`
16163
+ );
16164
+ }
16165
+ const publishMirror = obj["publishMirror"];
16166
+ if (typeof publishMirror !== "string" || publishMirror.length === 0) {
16167
+ throw new Error(`${where}: 'publishMirror' must be a non-empty string`);
16168
+ }
16169
+ const rawMdAllowed = obj["rawMdAllowed"];
16170
+ if (typeof rawMdAllowed !== "boolean") {
16171
+ throw new Error(`${where}: 'rawMdAllowed' must be a boolean`);
16172
+ }
16173
+ const rawMdPathsRaw = obj["rawMdPaths"];
16174
+ let rawMdPaths;
16175
+ if (rawMdPathsRaw !== void 0) {
16176
+ if (!Array.isArray(rawMdPathsRaw)) {
16177
+ throw new Error(`${where}: 'rawMdPaths' must be an array`);
16178
+ }
16179
+ for (const p of rawMdPathsRaw) {
16180
+ if (typeof p !== "string" || p.length === 0) {
16181
+ throw new Error(`${where}: 'rawMdPaths' entries must be non-empty strings`);
16182
+ }
16183
+ }
16184
+ rawMdPaths = rawMdPathsRaw;
16185
+ }
16186
+ return {
16187
+ canonicalHome,
16188
+ publishMirror,
16189
+ rawMdAllowed,
16190
+ ...rawMdPaths !== void 0 ? { rawMdPaths } : {}
16191
+ };
16192
+ }
16193
+ function loadCanonRegistry(projectRoot) {
16194
+ const path6 = join4(projectRoot, ".cleo", "canon.yml");
16195
+ if (!existsSync2(path6)) {
16196
+ return void 0;
16197
+ }
16198
+ const text = readFileSync4(path6, "utf8");
16199
+ const parsed = parseYaml(text);
16200
+ return validateCanonRegistry(parsed, path6);
16201
+ }
16202
+ function runCanonDocsCheck(params) {
16203
+ const { projectRoot, baseRef = "origin/main", candidateFiles } = params;
16204
+ const registry = loadCanonRegistry(projectRoot);
16205
+ if (!registry) {
16206
+ return {
16207
+ passed: true,
16208
+ baseRef,
16209
+ scanned: 0,
16210
+ violations: [],
16211
+ mode: "no-canon"
16212
+ };
16213
+ }
16214
+ const blockingPaths = [];
16215
+ for (const [kind, entry] of Object.entries(registry.kinds)) {
16216
+ if (entry.rawMdAllowed) continue;
16217
+ if (!entry.rawMdPaths || entry.rawMdPaths.length === 0) continue;
16218
+ for (const p of entry.rawMdPaths) {
16219
+ blockingPaths.push({ dir: normaliseDir(p), kind });
16220
+ }
16221
+ }
16222
+ const candidates = candidateFiles ?? listAddedMarkdownFiles(projectRoot, baseRef);
16223
+ const violations = [];
16224
+ for (const file of candidates) {
16225
+ const normalised = file.split(sep).join("/");
16226
+ for (const { dir, kind } of blockingPaths) {
16227
+ if (normalised.startsWith(dir)) {
16228
+ violations.push({
16229
+ file: normalised,
16230
+ kind,
16231
+ matchedPath: dir,
16232
+ fix: `cleo docs add <taskId> ${normalised} --type ${kind}`
16233
+ });
16234
+ break;
16235
+ }
16236
+ }
16237
+ }
16238
+ return {
16239
+ passed: violations.length === 0,
16240
+ baseRef,
16241
+ scanned: candidates.length,
16242
+ violations,
16243
+ mode: "enforced"
16244
+ };
16245
+ }
16246
+ var init_canon_docs = __esm({
16247
+ "packages/cleo/src/dispatch/domains/check/canon-docs.ts"() {
16248
+ "use strict";
16249
+ }
16250
+ });
16251
+
15684
16252
  // packages/cleo/src/dispatch/domains/check.ts
15685
16253
  import {
15686
16254
  checkArchiveStats,
@@ -16132,6 +16700,35 @@ var init_check = __esm({
16132
16700
  const result = runCanonCheck2({ projectRoot });
16133
16701
  return lafsSuccess(result, "canon");
16134
16702
  },
16703
+ "canon.docs": async (params) => {
16704
+ const projectRoot = getProjectRoot3();
16705
+ const { runCanonDocsCheck: runCanonDocsCheck2 } = await Promise.resolve().then(() => (init_canon_docs(), canon_docs_exports));
16706
+ try {
16707
+ const result = runCanonDocsCheck2({
16708
+ projectRoot,
16709
+ ...params.baseRef !== void 0 ? { baseRef: params.baseRef } : {},
16710
+ ...params.candidateFiles !== void 0 ? { candidateFiles: params.candidateFiles } : {}
16711
+ });
16712
+ if (!result.passed) {
16713
+ const firstFix = result.violations[0]?.fix ?? "cleo docs add ...";
16714
+ const fileList = result.violations.map((v) => `${v.file} (kind=${v.kind})`).join(", ");
16715
+ return lafsError(
16716
+ "E_CANON_VIOLATION",
16717
+ `Docs canon violation: ${result.violations.length} raw *.md addition(s) bypass the SSoT \u2014 ${fileList}`,
16718
+ "canon.docs",
16719
+ `Route through SSoT instead: ${firstFix}`,
16720
+ { result }
16721
+ );
16722
+ }
16723
+ return lafsSuccess(result, "canon.docs");
16724
+ } catch (err) {
16725
+ return lafsError(
16726
+ "E_CANON_INVALID",
16727
+ err instanceof Error ? err.message : String(err),
16728
+ "canon.docs"
16729
+ );
16730
+ }
16731
+ },
16135
16732
  "workflow.compliance": async (params) => {
16136
16733
  const projectRoot = getProjectRoot3();
16137
16734
  try {
@@ -16251,7 +16848,9 @@ var init_check = __esm({
16251
16848
  ...envelope.success ? { data: envelope.data } : {
16252
16849
  error: {
16253
16850
  code: envelope.error?.code !== void 0 ? String(envelope.error.code) : "E_INTERNAL",
16254
- message: envelope.error?.message ?? "Unknown error"
16851
+ message: envelope.error?.message ?? "Unknown error",
16852
+ ...envelope.error?.fix !== void 0 ? { fix: envelope.error.fix } : {},
16853
+ ...envelope.error?.details !== void 0 ? { details: envelope.error.details } : {}
16255
16854
  }
16256
16855
  }
16257
16856
  };
@@ -16310,6 +16909,7 @@ var init_check = __esm({
16310
16909
  "grade.list",
16311
16910
  "chain.validate",
16312
16911
  "canon",
16912
+ "canon.docs",
16313
16913
  "verify.explain"
16314
16914
  ],
16315
16915
  mutate: ["compliance.record", "compliance.sync", "test.run", "gate.set"]
@@ -16908,6 +17508,23 @@ import {
16908
17508
  resolveAttachmentBackend,
16909
17509
  SlugCollisionError
16910
17510
  } from "@cleocode/core/internal";
17511
+ function getDocKindRegistry() {
17512
+ const root = getProjectRoot5();
17513
+ const cached = _registryCache.get(root);
17514
+ if (cached) return cached;
17515
+ try {
17516
+ const registry = DocKindRegistry.load(root);
17517
+ _registryCache.set(root, registry);
17518
+ return registry;
17519
+ } catch {
17520
+ const fallback = DocKindRegistry.builtinOnly();
17521
+ _registryCache.set(root, fallback);
17522
+ return fallback;
17523
+ }
17524
+ }
17525
+ function registeredKindValues() {
17526
+ return getDocKindRegistry().list().map((d) => d.kind);
17527
+ }
16911
17528
  function inferOwnerType(ownerId) {
16912
17529
  if (/^T\d+$/i.test(ownerId)) return "task";
16913
17530
  if (ownerId.startsWith("ses_")) return "session";
@@ -16954,7 +17571,35 @@ function validateSlug(raw) {
16954
17571
  return { valid: true };
16955
17572
  }
16956
17573
  function validateDocsType(raw) {
16957
- return typeof raw === "string" && DOCS_TYPE_VALUES.includes(raw);
17574
+ if (typeof raw !== "string") return false;
17575
+ return getDocKindRegistry().has(raw);
17576
+ }
17577
+ function registeredKindList() {
17578
+ return registeredKindValues().join("|");
17579
+ }
17580
+ function normaliseOrderBy(raw) {
17581
+ if (raw === "sha" || raw === "slug" || raw === "newest") return raw;
17582
+ return "newest";
17583
+ }
17584
+ function resolveListLimit(raw) {
17585
+ if (typeof raw === "number" && Number.isFinite(raw)) {
17586
+ if (raw <= 0) return Number.POSITIVE_INFINITY;
17587
+ return Math.floor(raw);
17588
+ }
17589
+ return DOCS_LIST_DEFAULT_LIMIT;
17590
+ }
17591
+ function compareByOrderBy(orderBy) {
17592
+ if (orderBy === "sha") return (a, b) => a.sha256.localeCompare(b.sha256);
17593
+ if (orderBy === "slug") {
17594
+ return (a, b) => {
17595
+ const left = a.slug ?? "";
17596
+ const right = b.slug ?? "";
17597
+ if (!left && right) return 1;
17598
+ if (left && !right) return -1;
17599
+ return left.localeCompare(right);
17600
+ };
17601
+ }
17602
+ return (a, b) => b.createdAt.localeCompare(a.createdAt);
16958
17603
  }
16959
17604
  function docsEnvelopeToResponse(envelope, gateway, operation, startTime) {
16960
17605
  if (!envelope.success) {
@@ -16971,64 +17616,74 @@ function docsEnvelopeToResponse(envelope, gateway, operation, startTime) {
16971
17616
  };
16972
17617
  }
16973
17618
  let attachmentBackend;
17619
+ let hint;
16974
17620
  let responseData = envelope.data;
16975
17621
  if (responseData !== null && responseData !== void 0 && typeof responseData === "object") {
16976
17622
  const dataObj = responseData;
16977
- if ("attachmentBackend" in dataObj && dataObj["attachmentBackend"] !== void 0) {
16978
- attachmentBackend = dataObj["attachmentBackend"];
16979
- const { attachmentBackend: _lifted, ...cleanData } = dataObj;
16980
- responseData = cleanData;
17623
+ let cleanedData = dataObj;
17624
+ let cleaned = false;
17625
+ if ("attachmentBackend" in cleanedData && cleanedData["attachmentBackend"] !== void 0) {
17626
+ attachmentBackend = cleanedData["attachmentBackend"];
17627
+ const { attachmentBackend: _lifted, ...rest } = cleanedData;
17628
+ cleanedData = rest;
17629
+ cleaned = true;
17630
+ }
17631
+ if ("hint" in cleanedData && typeof cleanedData["hint"] === "string") {
17632
+ hint = cleanedData["hint"];
17633
+ }
17634
+ if (cleaned) {
17635
+ responseData = cleanedData;
16981
17636
  }
16982
17637
  }
16983
17638
  return {
16984
17639
  meta: {
16985
17640
  ...dispatchMeta(gateway, "docs", operation, startTime),
16986
- ...attachmentBackend !== void 0 ? { attachmentBackend } : {}
17641
+ ...attachmentBackend !== void 0 ? { attachmentBackend } : {},
17642
+ ...hint !== void 0 ? { hint } : {}
16987
17643
  },
16988
17644
  success: true,
16989
17645
  data: responseData
16990
17646
  };
16991
17647
  }
16992
- var DOCS_TYPE_VALUES, SLUG_PATTERN, SLUG_MAX_LEN, _docsTypedHandler, QUERY_OPS3, MUTATE_OPS3, DocsHandler;
17648
+ var DOCS_LIST_DEFAULT_LIMIT, _registryCache, SLUG_PATTERN, SLUG_MAX_LEN, _docsTypedHandler, QUERY_OPS3, MUTATE_OPS3, DocsHandler;
16993
17649
  var init_docs2 = __esm({
16994
17650
  "packages/cleo/src/dispatch/domains/docs.ts"() {
16995
17651
  "use strict";
17652
+ init_src2();
16996
17653
  init_typed();
16997
17654
  init_base();
16998
17655
  init_meta2();
16999
- DOCS_TYPE_VALUES = [
17000
- "spec",
17001
- "adr",
17002
- "research",
17003
- "handoff",
17004
- "note",
17005
- "llm-readme"
17006
- ];
17656
+ DOCS_LIST_DEFAULT_LIMIT = 50;
17657
+ _registryCache = /* @__PURE__ */ new Map();
17007
17658
  SLUG_PATTERN = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
17008
17659
  SLUG_MAX_LEN = 80;
17009
17660
  _docsTypedHandler = defineTypedHandler("docs", {
17010
17661
  // ── docs.list ──────────────────────────────────────────────────────────────
17011
17662
  list: async (params) => {
17012
17663
  const ownerId = params.task ?? params.session ?? params.observation;
17013
- const isProjectScope = params.project === true;
17014
- if (!ownerId && !isProjectScope) {
17015
- return lafsError(
17016
- "E_INVALID_INPUT",
17017
- "Provide one of --task, --session, --observation, or --project to scope the list.",
17018
- "list"
17019
- );
17020
- }
17664
+ const explicitProject = params.project === true;
17665
+ const isProjectScope = explicitProject || !ownerId;
17021
17666
  let typeFilter;
17022
17667
  if (params.type !== void 0) {
17023
17668
  if (!validateDocsType(params.type)) {
17024
17669
  return lafsError(
17025
17670
  "E_INVALID_TYPE",
17026
- `type must be one of: ${DOCS_TYPE_VALUES.join("|")} \u2014 got '${String(params.type)}'`,
17671
+ `type must be one of: ${registeredKindList()} \u2014 got '${String(params.type)}'`,
17027
17672
  "list"
17028
17673
  );
17029
17674
  }
17030
17675
  typeFilter = params.type;
17031
17676
  }
17677
+ const effectiveLimit = resolveListLimit(params.limit);
17678
+ const orderBy = normaliseOrderBy(params.orderBy);
17679
+ const comparator = compareByOrderBy(orderBy);
17680
+ const autoPromoted = isProjectScope && !explicitProject;
17681
+ const hintParts = [];
17682
+ if (autoPromoted) {
17683
+ hintParts.push(
17684
+ "no scope set \u2014 defaulted to --project. Pass --task <id>, --session <id>, or --observation <id> for a narrower listing."
17685
+ );
17686
+ }
17032
17687
  const store = createAttachmentStore();
17033
17688
  const backend = await resolveAttachmentBackend();
17034
17689
  if (isProjectScope) {
@@ -17036,28 +17691,50 @@ var init_docs2 = __esm({
17036
17691
  void 0,
17037
17692
  typeFilter !== void 0 ? { type: typeFilter } : void 0
17038
17693
  );
17694
+ const projected = rows.map(({ metadata: m, slug, type: type2, ownerId: oid, ownerType: ot }) => ({
17695
+ id: m.id,
17696
+ sha256: `${m.sha256.slice(0, 8)}\u2026`,
17697
+ // T9792 — keep the full sha256 for stable cross-row sorting; the
17698
+ // displayed truncated form is preserved on the wire field above.
17699
+ _sortSha: m.sha256,
17700
+ kind: m.attachment.kind,
17701
+ mime: m.attachment.kind === "local-file" || m.attachment.kind === "blob" ? m.attachment.mime : m.attachment.mime ?? "\u2014",
17702
+ size: m.attachment.kind === "local-file" || m.attachment.kind === "blob" ? m.attachment.size : void 0,
17703
+ description: m.attachment.description,
17704
+ labels: m.attachment.labels,
17705
+ createdAt: m.createdAt,
17706
+ refCount: m.refCount,
17707
+ ...slug ? { slug } : {},
17708
+ ...type2 ? { type: type2 } : {},
17709
+ ownerId: oid,
17710
+ ownerType: ot
17711
+ }));
17712
+ projected.sort(
17713
+ (a, b) => comparator(
17714
+ { sha256: a._sortSha, slug: a.slug, createdAt: a.createdAt },
17715
+ { sha256: b._sortSha, slug: b.slug, createdAt: b.createdAt }
17716
+ )
17717
+ );
17718
+ const totalCount = projected.length;
17719
+ const sliced = Number.isFinite(effectiveLimit) ? projected.slice(0, effectiveLimit) : projected;
17720
+ const truncated = totalCount > sliced.length;
17721
+ if (truncated) {
17722
+ hintParts.push(
17723
+ `showing ${sliced.length} of ${totalCount} \u2014 pass --limit <N> to widen or page further.`
17724
+ );
17725
+ }
17039
17726
  return lafsSuccess(
17040
17727
  {
17041
17728
  ownerId: "",
17042
17729
  ownerType: "task",
17043
17730
  project: true,
17044
17731
  ...typeFilter !== void 0 ? { type: typeFilter } : {},
17045
- count: rows.length,
17046
- attachments: rows.map(({ metadata: m, slug, type: type2, ownerId: oid, ownerType: ot }) => ({
17047
- id: m.id,
17048
- sha256: `${m.sha256.slice(0, 8)}\u2026`,
17049
- kind: m.attachment.kind,
17050
- mime: m.attachment.kind === "local-file" || m.attachment.kind === "blob" ? m.attachment.mime : m.attachment.mime ?? "\u2014",
17051
- size: m.attachment.kind === "local-file" || m.attachment.kind === "blob" ? m.attachment.size : void 0,
17052
- description: m.attachment.description,
17053
- labels: m.attachment.labels,
17054
- createdAt: m.createdAt,
17055
- refCount: m.refCount,
17056
- ...slug ? { slug } : {},
17057
- ...type2 ? { type: type2 } : {},
17058
- ownerId: oid,
17059
- ownerType: ot
17060
- })),
17732
+ count: sliced.length,
17733
+ ...truncated ? { totalCount } : {},
17734
+ limit: Number.isFinite(effectiveLimit) ? effectiveLimit : 0,
17735
+ orderBy,
17736
+ ...hintParts.length > 0 ? { hint: hintParts.join(" ") } : {},
17737
+ attachments: sliced.map(({ _sortSha: _drop, ...row }) => row),
17061
17738
  attachmentBackend: backend
17062
17739
  },
17063
17740
  "list"
@@ -17074,25 +17751,45 @@ var init_docs2 = __esm({
17074
17751
  if (typeFilter !== void 0 && type2 !== typeFilter) continue;
17075
17752
  enriched.push({ meta: m, slug, type: type2 });
17076
17753
  }
17754
+ const projectedOwner = enriched.map(({ meta: m, slug, type: type2 }) => ({
17755
+ id: m.id,
17756
+ sha256: `${m.sha256.slice(0, 8)}\u2026`,
17757
+ _sortSha: m.sha256,
17758
+ kind: m.attachment.kind,
17759
+ mime: m.attachment.kind === "local-file" || m.attachment.kind === "blob" ? m.attachment.mime : m.attachment.mime ?? "\u2014",
17760
+ size: m.attachment.kind === "local-file" || m.attachment.kind === "blob" ? m.attachment.size : void 0,
17761
+ description: m.attachment.description,
17762
+ labels: m.attachment.labels,
17763
+ createdAt: m.createdAt,
17764
+ refCount: m.refCount,
17765
+ ...slug ? { slug } : {},
17766
+ ...type2 ? { type: type2 } : {}
17767
+ }));
17768
+ projectedOwner.sort(
17769
+ (a, b) => comparator(
17770
+ { sha256: a._sortSha, slug: a.slug, createdAt: a.createdAt },
17771
+ { sha256: b._sortSha, slug: b.slug, createdAt: b.createdAt }
17772
+ )
17773
+ );
17774
+ const totalCountOwner = projectedOwner.length;
17775
+ const slicedOwner = Number.isFinite(effectiveLimit) ? projectedOwner.slice(0, effectiveLimit) : projectedOwner;
17776
+ const truncatedOwner = totalCountOwner > slicedOwner.length;
17777
+ if (truncatedOwner) {
17778
+ hintParts.push(
17779
+ `showing ${slicedOwner.length} of ${totalCountOwner} \u2014 pass --limit <N> to widen or page further.`
17780
+ );
17781
+ }
17077
17782
  return lafsSuccess(
17078
17783
  {
17079
17784
  ownerId: scopedOwner,
17080
17785
  ownerType,
17081
17786
  ...typeFilter !== void 0 ? { type: typeFilter } : {},
17082
- count: enriched.length,
17083
- attachments: enriched.map(({ meta: m, slug, type: type2 }) => ({
17084
- id: m.id,
17085
- sha256: `${m.sha256.slice(0, 8)}\u2026`,
17086
- kind: m.attachment.kind,
17087
- mime: m.attachment.kind === "local-file" || m.attachment.kind === "blob" ? m.attachment.mime : m.attachment.mime ?? "\u2014",
17088
- size: m.attachment.kind === "local-file" || m.attachment.kind === "blob" ? m.attachment.size : void 0,
17089
- description: m.attachment.description,
17090
- labels: m.attachment.labels,
17091
- createdAt: m.createdAt,
17092
- refCount: m.refCount,
17093
- ...slug ? { slug } : {},
17094
- ...type2 ? { type: type2 } : {}
17095
- })),
17787
+ count: slicedOwner.length,
17788
+ ...truncatedOwner ? { totalCount: totalCountOwner } : {},
17789
+ limit: Number.isFinite(effectiveLimit) ? effectiveLimit : 0,
17790
+ orderBy,
17791
+ ...hintParts.length > 0 ? { hint: hintParts.join(" ") } : {},
17792
+ attachments: slicedOwner.map(({ _sortSha: _drop, ...row }) => row),
17096
17793
  // Cast: core returns 'llmtxt'|'legacy'; contracts uses 'legacy'|'llmstxt-v2' (drift T1529)
17097
17794
  attachmentBackend: backend
17098
17795
  },
@@ -17293,12 +17990,19 @@ var init_docs2 = __esm({
17293
17990
  if (!validateDocsType(rawType)) {
17294
17991
  return lafsError(
17295
17992
  "E_INVALID_TYPE",
17296
- `type must be one of: ${DOCS_TYPE_VALUES.join("|")} \u2014 got '${String(rawType)}'`,
17993
+ `type must be one of: ${registeredKindList()} \u2014 got '${String(rawType)}'`,
17297
17994
  "add"
17298
17995
  );
17299
17996
  }
17300
17997
  type2 = rawType;
17301
17998
  }
17999
+ if (type2 !== void 0 && slug !== void 0) {
18000
+ const patternCheck = getDocKindRegistry().validateSlug(type2, slug);
18001
+ if (!patternCheck.ok) {
18002
+ const exampleHint = patternCheck.example ? ` (example: ${patternCheck.example})` : "";
18003
+ return lafsError("E_SLUG_PATTERN_MISMATCH", `${patternCheck.error}${exampleHint}`, "add");
18004
+ }
18005
+ }
17302
18006
  const extras = {};
17303
18007
  if (slug !== void 0) extras.slug = slug;
17304
18008
  if (type2 !== void 0) extras.type = type2;
@@ -24342,7 +25046,7 @@ var init_parser = __esm({
24342
25046
  });
24343
25047
 
24344
25048
  // packages/playbooks/src/migrate-e4.ts
24345
- import { readFileSync as readFileSync3, writeFileSync } from "node:fs";
25049
+ import { readFileSync as readFileSync5, writeFileSync } from "node:fs";
24346
25050
  function validatePlaybookCompliance(source) {
24347
25051
  let parsed;
24348
25052
  try {
@@ -24408,7 +25112,7 @@ function migratePlaybook(source) {
24408
25112
  return dump(raw, { lineWidth: 100, noRefs: true });
24409
25113
  }
24410
25114
  function migratePlaybookFile(filePath, dryRun = false) {
24411
- const source = readFileSync3(filePath, "utf8");
25115
+ const source = readFileSync5(filePath, "utf8");
24412
25116
  const before = validatePlaybookCompliance(source);
24413
25117
  if (!before.parses) {
24414
25118
  return {
@@ -24760,7 +25464,7 @@ var init_state = __esm({
24760
25464
 
24761
25465
  // packages/playbooks/src/runtime.ts
24762
25466
  import { appendFileSync, mkdirSync } from "node:fs";
24763
- import { dirname, join as join3 } from "node:path";
25467
+ import { dirname, join as join5 } from "node:path";
24764
25468
  function buildEdgeIndex(def) {
24765
25469
  const outgoing = /* @__PURE__ */ new Map();
24766
25470
  const incoming = /* @__PURE__ */ new Map();
@@ -24928,7 +25632,7 @@ function resolveEdge(fromId, toId, edges) {
24928
25632
  function auditContractViolation(projectRoot, runId, nodeId, field, key, playbookName) {
24929
25633
  if (!projectRoot) return;
24930
25634
  try {
24931
- const filePath = join3(projectRoot, ".cleo", "audit", "contract-violations.jsonl");
25635
+ const filePath = join5(projectRoot, ".cleo", "audit", "contract-violations.jsonl");
24932
25636
  mkdirSync(dirname(filePath), { recursive: true });
24933
25637
  const entry = JSON.stringify({
24934
25638
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -25383,9 +26087,9 @@ var init_src3 = __esm({
25383
26087
  });
25384
26088
 
25385
26089
  // packages/cleo/src/dispatch/domains/playbook.ts
25386
- import { existsSync as existsSync2, readFileSync as readFileSync4 } from "node:fs";
26090
+ import { existsSync as existsSync3, readFileSync as readFileSync6 } from "node:fs";
25387
26091
  import { homedir } from "node:os";
25388
- import { dirname as dirname2, join as join4, resolve as resolvePath } from "node:path";
26092
+ import { dirname as dirname2, join as join6, resolve as resolvePath } from "node:path";
25389
26093
  import { fileURLToPath } from "node:url";
25390
26094
  import { listPlaybooks, PlaybookNotFoundError, resolvePlaybook } from "@cleocode/core";
25391
26095
  function normalizeListStatus(raw) {
@@ -25414,7 +26118,7 @@ function resolvePlaybookDirs() {
25414
26118
  if (__playbookRuntimeOverrides.playbookBaseDirs) {
25415
26119
  return __playbookRuntimeOverrides.playbookBaseDirs;
25416
26120
  }
25417
- const globalDir = join4(homedir(), ".local", "share", "cleo", "playbooks");
26121
+ const globalDir = join6(homedir(), ".local", "share", "cleo", "playbooks");
25418
26122
  const here = dirname2(fileURLToPath(import.meta.url));
25419
26123
  const sourceStarter = resolvePath(here, "..", "..", "..", "..", "playbooks", "starter");
25420
26124
  const bundledStarter = resolvePath(here, "..", "..", "..", "playbooks", "starter");
@@ -25425,16 +26129,16 @@ async function loadPlaybookByName(name) {
25425
26129
  const candidates = resolvePlaybookDirs();
25426
26130
  const fileName = name.endsWith(".cantbook") ? name : `${name}.cantbook`;
25427
26131
  for (const dir of candidates) {
25428
- const full = join4(dir, fileName);
25429
- if (existsSync2(full)) {
25430
- return { sourcePath: full, source: readFileSync4(full, "utf8") };
26132
+ const full = join6(dir, fileName);
26133
+ if (existsSync3(full)) {
26134
+ return { sourcePath: full, source: readFileSync6(full, "utf8") };
25431
26135
  }
25432
26136
  }
25433
26137
  return null;
25434
26138
  }
25435
26139
  try {
25436
- const { getProjectRoot: getProjectRoot43 } = await import("@cleocode/core/internal");
25437
- const projectRoot = __playbookRuntimeOverrides.projectRoot ?? getProjectRoot43();
26140
+ const { getProjectRoot: getProjectRoot44 } = await import("@cleocode/core/internal");
26141
+ const projectRoot = __playbookRuntimeOverrides.projectRoot ?? getProjectRoot44();
25438
26142
  const resolved = resolvePlaybook(name, {
25439
26143
  projectRoot,
25440
26144
  globalPlaybooksDir: __playbookRuntimeOverrides.globalPlaybooksDir,
@@ -25478,8 +26182,8 @@ async function acquireDb() {
25478
26182
  async function buildDefaultDispatcher() {
25479
26183
  if (__playbookRuntimeOverrides.dispatcher) return __playbookRuntimeOverrides.dispatcher;
25480
26184
  const { orchestrateSpawnExecute: orchestrateSpawnExecute2 } = await Promise.resolve().then(() => (init_engine(), engine_exports));
25481
- const { getProjectRoot: getProjectRoot43 } = await import("@cleocode/core/internal");
25482
- const projectRoot = getProjectRoot43();
26185
+ const { getProjectRoot: getProjectRoot44 } = await import("@cleocode/core/internal");
26186
+ const projectRoot = getProjectRoot44();
25483
26187
  return {
25484
26188
  async dispatch(input2) {
25485
26189
  try {
@@ -25609,11 +26313,11 @@ var init_playbook2 = __esm({
25609
26313
  let sourcePath;
25610
26314
  if (file) {
25611
26315
  const resolved = resolvePath(file);
25612
- if (!existsSync2(resolved)) {
26316
+ if (!existsSync3(resolved)) {
25613
26317
  return lafsError("E_NOT_FOUND", `playbook file not found: ${resolved}`, "validate");
25614
26318
  }
25615
26319
  sourcePath = resolved;
25616
- source = readFileSync4(resolved, "utf8");
26320
+ source = readFileSync6(resolved, "utf8");
25617
26321
  } else {
25618
26322
  const loaded = await loadPlaybookByName(name);
25619
26323
  if (loaded === null) {
@@ -25669,8 +26373,8 @@ var init_playbook2 = __esm({
25669
26373
  projectRoot = __playbookRuntimeOverrides.projectRoot;
25670
26374
  } else {
25671
26375
  try {
25672
- const { getProjectRoot: getProjectRoot43 } = await import("@cleocode/core/internal");
25673
- projectRoot = getProjectRoot43();
26376
+ const { getProjectRoot: getProjectRoot44 } = await import("@cleocode/core/internal");
26377
+ projectRoot = getProjectRoot44();
25674
26378
  } catch {
25675
26379
  projectRoot = void 0;
25676
26380
  }
@@ -25734,14 +26438,14 @@ var init_playbook2 = __esm({
25734
26438
  const dispatcher = await buildDefaultDispatcher();
25735
26439
  let result;
25736
26440
  try {
25737
- const { getProjectRoot: getProjectRoot43 } = await import("@cleocode/core/internal");
26441
+ const { getProjectRoot: getProjectRoot44 } = await import("@cleocode/core/internal");
25738
26442
  const opts = {
25739
26443
  db,
25740
26444
  playbook: parsed.definition,
25741
26445
  playbookHash: parsed.sourceHash,
25742
26446
  initialContext,
25743
26447
  dispatcher,
25744
- projectRoot: getProjectRoot43()
26448
+ projectRoot: getProjectRoot44()
25745
26449
  };
25746
26450
  if (__playbookRuntimeOverrides.approvalSecret !== void 0) {
25747
26451
  opts.approvalSecret = __playbookRuntimeOverrides.approvalSecret;
@@ -26103,16 +26807,16 @@ async function orchestrateRejectOp(params) {
26103
26807
  async function orchestrateClassify(request, context, projectRoot) {
26104
26808
  try {
26105
26809
  const { getCleoCantWorkflowsDir } = await import("@cleocode/core/internal");
26106
- const { readFileSync: readFileSync18, readdirSync: readdirSync4, existsSync: existsSync17 } = await import("node:fs");
26107
- const { join: join33 } = await import("node:path");
26810
+ const { readFileSync: readFileSync20, readdirSync: readdirSync4, existsSync: existsSync18 } = await import("node:fs");
26811
+ const { join: join35 } = await import("node:path");
26108
26812
  const workflowsDir = getCleoCantWorkflowsDir();
26109
26813
  const combined = `${request} ${context ?? ""}`.toLowerCase();
26110
26814
  const matches = [];
26111
- if (existsSync17(workflowsDir)) {
26815
+ if (existsSync18(workflowsDir)) {
26112
26816
  const files = readdirSync4(workflowsDir).filter((f) => f.endsWith(".cant"));
26113
26817
  for (const file of files) {
26114
26818
  try {
26115
- const src = readFileSync18(join33(workflowsDir, file), "utf-8");
26819
+ const src = readFileSync20(join35(workflowsDir, file), "utf-8");
26116
26820
  const teamMatch = /^team\s+(\S+):/m.exec(src);
26117
26821
  if (!teamMatch) continue;
26118
26822
  const teamName = teamMatch[1];
@@ -26127,12 +26831,12 @@ async function orchestrateClassify(request, context, projectRoot) {
26127
26831
  }
26128
26832
  }
26129
26833
  }
26130
- const localCantDir = join33(projectRoot, CLEO_DIR_NAME, WORKFLOWS_SUBDIR);
26131
- if (existsSync17(localCantDir)) {
26834
+ const localCantDir = join35(projectRoot, CLEO_DIR_NAME, WORKFLOWS_SUBDIR);
26835
+ if (existsSync18(localCantDir)) {
26132
26836
  const files = readdirSync4(localCantDir).filter((f) => f.endsWith(".cant"));
26133
26837
  for (const file of files) {
26134
26838
  try {
26135
- const src = readFileSync18(join33(localCantDir, file), "utf-8");
26839
+ const src = readFileSync20(join35(localCantDir, file), "utf-8");
26136
26840
  const teamMatch = /^team\s+(\S+):/m.exec(src);
26137
26841
  if (!teamMatch) continue;
26138
26842
  const teamName = teamMatch[1];
@@ -28584,7 +29288,13 @@ var init_session_context = __esm({
28584
29288
  });
28585
29289
 
28586
29290
  // packages/cleo/src/dispatch/domains/session.ts
28587
- import { getDb, getLogger as getLogger13, getProjectRoot as getProjectRoot15, sessions } from "@cleocode/core/internal";
29291
+ import {
29292
+ getDb,
29293
+ getLogger as getLogger13,
29294
+ getProjectRoot as getProjectRoot15,
29295
+ lintSessionForCanonViolations,
29296
+ sessions
29297
+ } from "@cleocode/core/internal";
28588
29298
  import { eq } from "drizzle-orm";
28589
29299
  async function sessionStatusOp() {
28590
29300
  return sessionStatus(getProjectRoot15());
@@ -28644,6 +29354,49 @@ async function sessionRecordDecisionOp(params) {
28644
29354
  async function sessionRecordAssumptionOp(params) {
28645
29355
  return sessionRecordAssumption(getProjectRoot15(), params);
28646
29356
  }
29357
+ async function sessionLintOp(params) {
29358
+ if (!params.transcript) {
29359
+ return {
29360
+ success: false,
29361
+ error: { code: "E_INVALID_INPUT", message: "transcript is required" }
29362
+ };
29363
+ }
29364
+ try {
29365
+ const result = lintSessionForCanonViolations({
29366
+ transcriptPath: params.transcript,
29367
+ projectRoot: getProjectRoot15()
29368
+ });
29369
+ const wireResult = {
29370
+ transcriptPath: result.transcriptPath,
29371
+ sessionId: result.sessionId,
29372
+ passed: result.passed,
29373
+ scanned: result.scanned,
29374
+ // Clone to drop readonly modifiers for the wire shape.
29375
+ violations: result.violations.map((v) => ({
29376
+ sessionId: v.sessionId,
29377
+ toolUseId: v.toolUseId,
29378
+ tool: v.tool,
29379
+ path: v.path,
29380
+ docKind: v.docKind,
29381
+ matchedPath: v.matchedPath,
29382
+ kind: v.kind,
29383
+ evidence: v.evidence,
29384
+ fix: v.fix
29385
+ })),
29386
+ warnings: [...result.warnings],
29387
+ mode: result.mode
29388
+ };
29389
+ return { success: true, data: wireResult };
29390
+ } catch (err) {
29391
+ return {
29392
+ success: false,
29393
+ error: {
29394
+ code: "E_CANON_INVALID",
29395
+ message: err instanceof Error ? err.message : String(err)
29396
+ }
29397
+ };
29398
+ }
29399
+ }
28647
29400
  async function storeSessionOwnerAuthToken(projectRoot, sessionId, token) {
28648
29401
  const db = await getDb(projectRoot);
28649
29402
  db.update(sessions).set({ ownerAuthToken: token }).where(eq(sessions.id, sessionId)).run();
@@ -28671,7 +29424,8 @@ var init_session3 = __esm({
28671
29424
  suspend: sessionSuspendOp,
28672
29425
  gc: sessionGcOp,
28673
29426
  "record.decision": sessionRecordDecisionOp,
28674
- "record.assumption": sessionRecordAssumptionOp
29427
+ "record.assumption": sessionRecordAssumptionOp,
29428
+ lint: sessionLintOp
28675
29429
  };
28676
29430
  _sessionTypedHandler = defineTypedHandler("session", {
28677
29431
  // -------------------------------------------------------------------------
@@ -28862,6 +29616,23 @@ var init_session3 = __esm({
28862
29616
  return lafsError("E_INTERNAL", "record.assumption returned no data", "record.assumption");
28863
29617
  }
28864
29618
  return wrapCoreResult(result, "record.assumption");
29619
+ },
29620
+ // T9797 — agent-accountability harness. Returns a LAFS envelope whose
29621
+ // `data` is a SessionLintResult; `error` is set on E_INVALID_INPUT
29622
+ // (missing transcript) or E_CANON_INVALID (malformed canon.yml).
29623
+ lint: async (params) => {
29624
+ const result = await coreOps6.lint(params);
29625
+ if (!result.success) {
29626
+ return lafsError(
29627
+ String(result.error?.code ?? "E_INTERNAL"),
29628
+ result.error?.message ?? "Unknown error",
29629
+ "lint"
29630
+ );
29631
+ }
29632
+ if (!result.data) {
29633
+ return lafsError("E_INTERNAL", "session.lint returned no data", "lint");
29634
+ }
29635
+ return lafsSuccess(result.data, "lint");
28865
29636
  }
28866
29637
  });
28867
29638
  QUERY_OPS8 = /* @__PURE__ */ new Set([
@@ -28872,7 +29643,8 @@ var init_session3 = __esm({
28872
29643
  "decision.log",
28873
29644
  "context.drift",
28874
29645
  "handoff.show",
28875
- "briefing.show"
29646
+ "briefing.show",
29647
+ "lint"
28876
29648
  ]);
28877
29649
  MUTATE_OPS8 = /* @__PURE__ */ new Set([
28878
29650
  "start",
@@ -30976,8 +31748,8 @@ var init_defaults = __esm({
30976
31748
  });
30977
31749
 
30978
31750
  // packages/cleo/src/dispatch/lib/config-loader.ts
30979
- import { existsSync as existsSync3, readFileSync as readFileSync5 } from "fs";
30980
- import { join as join5 } from "path";
31751
+ import { existsSync as existsSync4, readFileSync as readFileSync7 } from "fs";
31752
+ import { join as join7 } from "path";
30981
31753
  function loadFromEnv(key) {
30982
31754
  const envKey = `${ENV_PREFIX}${key.toUpperCase()}`;
30983
31755
  return process.env[envKey];
@@ -30998,12 +31770,12 @@ function parseEnvValue(key, value) {
30998
31770
  }
30999
31771
  function loadFromFile(projectRoot) {
31000
31772
  const root = projectRoot || process.cwd();
31001
- const configPath = join5(root, CLEO_DIR_NAME, CONFIG_JSON);
31002
- if (!existsSync3(configPath)) {
31773
+ const configPath = join7(root, CLEO_DIR_NAME, CONFIG_JSON);
31774
+ if (!existsSync4(configPath)) {
31003
31775
  return {};
31004
31776
  }
31005
31777
  try {
31006
- const content = readFileSync5(configPath, "utf-8");
31778
+ const content = readFileSync7(configPath, "utf-8");
31007
31779
  const config = JSON.parse(content);
31008
31780
  const result = {};
31009
31781
  if (config.lifecycleEnforcement) {
@@ -31346,11 +32118,11 @@ var init_security = __esm({
31346
32118
  });
31347
32119
 
31348
32120
  // packages/cleo/src/dispatch/middleware/sanitizer.ts
31349
- function createSanitizer(getProjectRoot43) {
32121
+ function createSanitizer(getProjectRoot44) {
31350
32122
  return async (req, next) => {
31351
32123
  if (req.params) {
31352
32124
  try {
31353
- const root = getProjectRoot43 ? getProjectRoot43() : void 0;
32125
+ const root = getProjectRoot44 ? getProjectRoot44() : void 0;
31354
32126
  req.params = sanitizeParams(req.params, root, {
31355
32127
  domain: req.domain,
31356
32128
  operation: req.operation
@@ -31470,9 +32242,9 @@ __export(cli_exports, {
31470
32242
  resetCliDispatcher: () => resetCliDispatcher
31471
32243
  });
31472
32244
  import { randomUUID as randomUUID5 } from "node:crypto";
31473
- import { existsSync as existsSync4 } from "node:fs";
32245
+ import { existsSync as existsSync5 } from "node:fs";
31474
32246
  import { createRequire } from "node:module";
31475
- import { dirname as dirname4, join as join6 } from "node:path";
32247
+ import { dirname as dirname4, join as join8 } from "node:path";
31476
32248
  import { fileURLToPath as fileURLToPath3 } from "node:url";
31477
32249
  import { catalog, registerSkillLibraryFromPath } from "@cleocode/caamp";
31478
32250
  import { autoRecordDispatchTokenUsage, getProjectRoot as getProjectRoot21, hooks } from "@cleocode/core/internal";
@@ -31484,16 +32256,16 @@ function ensureCaampLibrary() {
31484
32256
  const req = createRequire(import.meta.url);
31485
32257
  const skillsPkgJson = req.resolve("@cleocode/skills/package.json");
31486
32258
  const candidate = dirname4(skillsPkgJson);
31487
- if (existsSync4(join6(candidate, "skills.json"))) {
32259
+ if (existsSync5(join8(candidate, "skills.json"))) {
31488
32260
  skillsRoot = candidate;
31489
32261
  }
31490
32262
  } catch {
31491
32263
  }
31492
32264
  if (!skillsRoot) {
31493
32265
  const thisFile = fileURLToPath3(import.meta.url);
31494
- const packageRoot = join6(dirname4(thisFile), "..", "..", "..", "..", "..");
31495
- const candidate = join6(packageRoot, "packages", "skills");
31496
- if (existsSync4(join6(candidate, "skills.json"))) {
32266
+ const packageRoot = join8(dirname4(thisFile), "..", "..", "..", "..", "..");
32267
+ const candidate = join8(packageRoot, "packages", "skills");
32268
+ if (existsSync5(join8(candidate, "skills.json"))) {
31497
32269
  skillsRoot = candidate;
31498
32270
  }
31499
32271
  }
@@ -31723,7 +32495,10 @@ var init_cli = __esm({
31723
32495
  E_INVALID_OPERATION: 2,
31724
32496
  E_MISSING_PARAMS: 2,
31725
32497
  E_NO_HANDLER: 1,
31726
- E_INTERNAL: 1
32498
+ E_INTERNAL: 1,
32499
+ // T9796 — docs canon CI gate: violation = fail-build, invalid = tool-error.
32500
+ E_CANON_VIOLATION: 1,
32501
+ E_CANON_INVALID: 2
31727
32502
  };
31728
32503
  _dispatcher = null;
31729
32504
  }
@@ -31885,7 +32660,7 @@ var add_batch_exports = {};
31885
32660
  __export(add_batch_exports, {
31886
32661
  addBatchCommand: () => addBatchCommand
31887
32662
  });
31888
- import { existsSync as existsSync5, readFileSync as readFileSync6 } from "node:fs";
32663
+ import { existsSync as existsSync6, readFileSync as readFileSync8 } from "node:fs";
31889
32664
  var addBatchCommand;
31890
32665
  var init_add_batch = __esm({
31891
32666
  "packages/cleo/src/cli/commands/add-batch.ts"() {
@@ -31934,7 +32709,7 @@ var init_add_batch = __esm({
31934
32709
  return;
31935
32710
  }
31936
32711
  } else {
31937
- if (!existsSync5(filePath)) {
32712
+ if (!existsSync6(filePath)) {
31938
32713
  cliError(
31939
32714
  `File not found: ${filePath}`,
31940
32715
  "E_NOT_FOUND",
@@ -31947,7 +32722,7 @@ var init_add_batch = __esm({
31947
32722
  process.exit(2);
31948
32723
  return;
31949
32724
  }
31950
- raw = readFileSync6(filePath, "utf-8");
32725
+ raw = readFileSync8(filePath, "utf-8");
31951
32726
  }
31952
32727
  let tasks;
31953
32728
  try {
@@ -33304,12 +34079,12 @@ var init_agent = __esm({
33304
34079
  transportConfig: {},
33305
34080
  isActive: true
33306
34081
  });
33307
- const { existsSync: existsSync17, mkdirSync: mkdirSync7, writeFileSync: writeFileSync7 } = await import("node:fs");
33308
- const { join: join33 } = await import("node:path");
33309
- const cantDir = join33(CLEO_DIR_NAME, AGENTS_SUBDIR);
33310
- const cantPath = join33(cantDir, `${agentId}.cant`);
34082
+ const { existsSync: existsSync18, mkdirSync: mkdirSync7, writeFileSync: writeFileSync7 } = await import("node:fs");
34083
+ const { join: join35 } = await import("node:path");
34084
+ const cantDir = join35(CLEO_DIR_NAME, AGENTS_SUBDIR);
34085
+ const cantPath = join35(cantDir, `${agentId}.cant`);
33311
34086
  let cantScaffolded = false;
33312
- if (!existsSync17(cantPath)) {
34087
+ if (!existsSync18(cantPath)) {
33313
34088
  mkdirSync7(cantDir, { recursive: true });
33314
34089
  const role = classification ?? "specialist";
33315
34090
  const cantContent = `---
@@ -33369,7 +34144,7 @@ agent ${agentId}:
33369
34144
  data: {
33370
34145
  agentId: credential.agentId,
33371
34146
  displayName: credential.displayName,
33372
- cantFile: cantScaffolded ? cantPath : existsSync17(cantPath) ? cantPath : null,
34147
+ cantFile: cantScaffolded ? cantPath : existsSync18(cantPath) ? cantPath : null,
33373
34148
  cantScaffolded
33374
34149
  }
33375
34150
  },
@@ -33490,8 +34265,8 @@ agent ${agentId}:
33490
34265
  const { AgentRegistryAccessor } = await import("@cleocode/core/agents");
33491
34266
  const { getDb: getDb3 } = await import("@cleocode/core/internal");
33492
34267
  const { createRuntime } = await import("@cleocode/runtime");
33493
- const { existsSync: existsSync17, readFileSync: readFileSync18 } = await import("node:fs");
33494
- const { join: join33 } = await import("node:path");
34268
+ const { existsSync: existsSync18, readFileSync: readFileSync20 } = await import("node:fs");
34269
+ const { join: join35 } = await import("node:path");
33495
34270
  await getDb3();
33496
34271
  const registry = new AgentRegistryAccessor(getProjectRoot23());
33497
34272
  const credential = await registry.get(args.agentId);
@@ -33511,9 +34286,9 @@ agent ${agentId}:
33511
34286
  }
33512
34287
  let profile = null;
33513
34288
  let cantValidation = null;
33514
- const cantPath = args.cant ?? join33(CLEO_DIR_NAME, AGENTS_SUBDIR, `${args.agentId}.cant`);
33515
- if (existsSync17(cantPath)) {
33516
- profile = readFileSync18(cantPath, "utf-8");
34289
+ const cantPath = args.cant ?? join35(CLEO_DIR_NAME, AGENTS_SUBDIR, `${args.agentId}.cant`);
34290
+ if (existsSync18(cantPath)) {
34291
+ profile = readFileSync20(cantPath, "utf-8");
33517
34292
  try {
33518
34293
  const cantModule = await import("@cleocode/cant");
33519
34294
  const validate = "validate" in cantModule ? cantModule.validate : null;
@@ -34044,8 +34819,8 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
34044
34819
  const { AgentRegistryAccessor } = await import("@cleocode/core/agents");
34045
34820
  const { getDb: getDb3 } = await import("@cleocode/core/internal");
34046
34821
  const { createRuntime } = await import("@cleocode/runtime");
34047
- const { existsSync: existsSync17 } = await import("node:fs");
34048
- const { join: join33 } = await import("node:path");
34822
+ const { existsSync: existsSync18 } = await import("node:fs");
34823
+ const { join: join35 } = await import("node:path");
34049
34824
  const { execFile: execFile2 } = await import("node:child_process");
34050
34825
  const { promisify: promisify2 } = await import("node:util");
34051
34826
  const execFileAsync = promisify2(execFile2);
@@ -34065,8 +34840,8 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
34065
34840
  }
34066
34841
  await registry.update(args.agentId, { isActive: true });
34067
34842
  await registry.markUsed(args.agentId);
34068
- const cantPath = join33(CLEO_DIR_NAME, AGENTS_SUBDIR, `${args.agentId}.cant`);
34069
- const hasProfile = existsSync17(cantPath);
34843
+ const cantPath = join35(CLEO_DIR_NAME, AGENTS_SUBDIR, `${args.agentId}.cant`);
34844
+ const hasProfile = existsSync18(cantPath);
34070
34845
  const runtime = await createRuntime(registry, {
34071
34846
  agentId: args.agentId,
34072
34847
  pollIntervalMs: 5e3,
@@ -34924,11 +35699,11 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
34924
35699
  async run({ args }) {
34925
35700
  let tempDir = null;
34926
35701
  try {
34927
- const { existsSync: existsSync17, mkdirSync: mkdirSync7, statSync, readdirSync: readdirSync4, copyFileSync } = await import("node:fs");
34928
- const { join: join33, basename, resolve: resolve9, extname } = await import("node:path");
35702
+ const { existsSync: existsSync18, mkdirSync: mkdirSync7, statSync, readdirSync: readdirSync4, copyFileSync } = await import("node:fs");
35703
+ const { join: join35, basename, resolve: resolve9, extname } = await import("node:path");
34929
35704
  const { tmpdir: tmpdir2 } = await import("node:os");
34930
35705
  const resolvedPath = resolve9(args.path);
34931
- if (!existsSync17(resolvedPath)) {
35706
+ if (!existsSync18(resolvedPath)) {
34932
35707
  cliOutput(
34933
35708
  {
34934
35709
  success: false,
@@ -34949,7 +35724,7 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
34949
35724
  cantPath = resolvedPath;
34950
35725
  } else if (stat3.isFile() && ext === ".cantz") {
34951
35726
  const { execFileSync: execFileSync5 } = await import("node:child_process");
34952
- tempDir = join33(tmpdir2(), `cleo-agent-install-${Date.now()}`);
35727
+ tempDir = join35(tmpdir2(), `cleo-agent-install-${Date.now()}`);
34953
35728
  mkdirSync7(tempDir, { recursive: true });
34954
35729
  try {
34955
35730
  execFileSync5("unzip", ["-o", "-q", resolvedPath, "-d", tempDir], {
@@ -34971,7 +35746,7 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
34971
35746
  return;
34972
35747
  }
34973
35748
  const topLevel = readdirSync4(tempDir).filter(
34974
- (entry) => statSync(join33(tempDir, entry)).isDirectory()
35749
+ (entry) => statSync(join35(tempDir, entry)).isDirectory()
34975
35750
  );
34976
35751
  if (topLevel.length !== 1) {
34977
35752
  cliOutput(
@@ -34988,8 +35763,8 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
34988
35763
  return;
34989
35764
  }
34990
35765
  const agentName = topLevel[0];
34991
- const personaPath = join33(tempDir, agentName, "persona.cant");
34992
- if (!existsSync17(personaPath)) {
35766
+ const personaPath = join35(tempDir, agentName, "persona.cant");
35767
+ if (!existsSync18(personaPath)) {
34993
35768
  cliOutput(
34994
35769
  {
34995
35770
  success: false,
@@ -35003,12 +35778,12 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
35003
35778
  process.exitCode = 6;
35004
35779
  return;
35005
35780
  }
35006
- cantPath = join33(tempDir, `${agentName}.cant`);
35781
+ cantPath = join35(tempDir, `${agentName}.cant`);
35007
35782
  copyFileSync(personaPath, cantPath);
35008
35783
  } else if (stat3.isDirectory()) {
35009
35784
  const agentName = basename(resolvedPath);
35010
- const personaPath = join33(resolvedPath, "persona.cant");
35011
- if (!existsSync17(personaPath)) {
35785
+ const personaPath = join35(resolvedPath, "persona.cant");
35786
+ if (!existsSync18(personaPath)) {
35012
35787
  cliOutput(
35013
35788
  {
35014
35789
  success: false,
@@ -35022,9 +35797,9 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
35022
35797
  process.exitCode = 6;
35023
35798
  return;
35024
35799
  }
35025
- tempDir = join33(tmpdir2(), `cleo-agent-install-${Date.now()}`);
35800
+ tempDir = join35(tmpdir2(), `cleo-agent-install-${Date.now()}`);
35026
35801
  mkdirSync7(tempDir, { recursive: true });
35027
- cantPath = join33(tempDir, `${agentName}.cant`);
35802
+ cantPath = join35(tempDir, `${agentName}.cant`);
35028
35803
  copyFileSync(personaPath, cantPath);
35029
35804
  } else {
35030
35805
  cliOutput(
@@ -35143,11 +35918,11 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
35143
35918
  },
35144
35919
  async run({ args }) {
35145
35920
  try {
35146
- const { existsSync: existsSync17, statSync } = await import("node:fs");
35921
+ const { existsSync: existsSync18, statSync } = await import("node:fs");
35147
35922
  const { resolve: resolve9, basename, dirname: dirname13 } = await import("node:path");
35148
35923
  const { execFileSync: execFileSync5 } = await import("node:child_process");
35149
35924
  const resolvedDir = resolve9(args.dir);
35150
- if (!existsSync17(resolvedDir) || !statSync(resolvedDir).isDirectory()) {
35925
+ if (!existsSync18(resolvedDir) || !statSync(resolvedDir).isDirectory()) {
35151
35926
  cliOutput(
35152
35927
  {
35153
35928
  success: false,
@@ -35161,9 +35936,9 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
35161
35936
  process.exitCode = 4;
35162
35937
  return;
35163
35938
  }
35164
- const { join: join33 } = await import("node:path");
35165
- const personaPath = join33(resolvedDir, "persona.cant");
35166
- if (!existsSync17(personaPath)) {
35939
+ const { join: join35 } = await import("node:path");
35940
+ const personaPath = join35(resolvedDir, "persona.cant");
35941
+ if (!existsSync18(personaPath)) {
35167
35942
  cliOutput(
35168
35943
  {
35169
35944
  success: false,
@@ -35210,7 +35985,7 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
35210
35985
  if (entry.isFile()) {
35211
35986
  fileCount++;
35212
35987
  } else if (entry.isDirectory()) {
35213
- countFiles(join33(dirPath, entry.name));
35988
+ countFiles(join35(dirPath, entry.name));
35214
35989
  }
35215
35990
  }
35216
35991
  };
@@ -35279,8 +36054,8 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
35279
36054
  },
35280
36055
  async run({ args }) {
35281
36056
  try {
35282
- const { existsSync: existsSync17, mkdirSync: mkdirSync7, writeFileSync: writeFileSync7 } = await import("node:fs");
35283
- const { join: join33 } = await import("node:path");
36057
+ const { existsSync: existsSync18, mkdirSync: mkdirSync7, writeFileSync: writeFileSync7 } = await import("node:fs");
36058
+ const { join: join35 } = await import("node:path");
35284
36059
  const { homedir: homedir8 } = await import("node:os");
35285
36060
  const name = args.name;
35286
36061
  const role = args.role;
@@ -35340,13 +36115,13 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
35340
36115
  let targetRoot;
35341
36116
  if (isGlobal) {
35342
36117
  const home = homedir8();
35343
- const xdgData = process.env["XDG_DATA_HOME"] ?? join33(home, ".local", "share");
35344
- targetRoot = join33(xdgData, "cleo", "cant", "agents");
36118
+ const xdgData = process.env["XDG_DATA_HOME"] ?? join35(home, ".local", "share");
36119
+ targetRoot = join35(xdgData, "cleo", "cant", "agents");
35345
36120
  } else {
35346
- targetRoot = join33(getProjectRoot23(), CLEO_DIR_NAME, CANT_AGENTS_SUBDIR);
36121
+ targetRoot = join35(getProjectRoot23(), CLEO_DIR_NAME, CANT_AGENTS_SUBDIR);
35347
36122
  }
35348
- const agentDir = join33(targetRoot, name);
35349
- if (existsSync17(agentDir)) {
36123
+ const agentDir = join35(targetRoot, name);
36124
+ if (existsSync18(agentDir)) {
35350
36125
  cliOutput(
35351
36126
  {
35352
36127
  success: false,
@@ -35370,29 +36145,29 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
35370
36145
  domain,
35371
36146
  parent
35372
36147
  });
35373
- writeFileSync7(join33(agentDir, "persona.cant"), personaContent, "utf-8");
36148
+ writeFileSync7(join35(agentDir, "persona.cant"), personaContent, "utf-8");
35374
36149
  const manifest = generateManifest({ name, role, tier, domain });
35375
36150
  writeFileSync7(
35376
- join33(agentDir, "manifest.json"),
36151
+ join35(agentDir, "manifest.json"),
35377
36152
  `${JSON.stringify(manifest, null, 2)}
35378
36153
  `,
35379
36154
  "utf-8"
35380
36155
  );
35381
36156
  const createdFiles = [
35382
- join33(agentDir, "persona.cant"),
35383
- join33(agentDir, "manifest.json")
36157
+ join35(agentDir, "persona.cant"),
36158
+ join35(agentDir, "manifest.json")
35384
36159
  ];
35385
36160
  if (team) {
35386
36161
  const teamConfigContent = generateTeamConfig(name, role, team);
35387
- writeFileSync7(join33(agentDir, "team-config.cant"), teamConfigContent, "utf-8");
35388
- createdFiles.push(join33(agentDir, "team-config.cant"));
36162
+ writeFileSync7(join35(agentDir, "team-config.cant"), teamConfigContent, "utf-8");
36163
+ createdFiles.push(join35(agentDir, "team-config.cant"));
35389
36164
  }
35390
36165
  if (seedBrain) {
35391
- const expertiseDir = join33(agentDir, "expertise");
36166
+ const expertiseDir = join35(agentDir, "expertise");
35392
36167
  mkdirSync7(expertiseDir, { recursive: true });
35393
36168
  const seedContent = generateMentalModelSeed(name, role, domain);
35394
- writeFileSync7(join33(expertiseDir, "mental-model-seed.md"), seedContent, "utf-8");
35395
- createdFiles.push(join33(expertiseDir, "mental-model-seed.md"));
36169
+ writeFileSync7(join35(expertiseDir, "mental-model-seed.md"), seedContent, "utf-8");
36170
+ createdFiles.push(join35(expertiseDir, "mental-model-seed.md"));
35396
36171
  try {
35397
36172
  const { execFile: execFile2 } = await import("node:child_process");
35398
36173
  const { promisify: promisify2 } = await import("node:util");
@@ -35491,17 +36266,17 @@ Task ${args.taskId} reassigned to you by ${active.agentId}. Run: cleo show ${arg
35491
36266
  },
35492
36267
  async run({ args }) {
35493
36268
  try {
35494
- const { existsSync: existsSync17, readFileSync: readFileSync18, mkdirSync: mkdirSync7 } = await import("node:fs");
35495
- const { resolve: resolve9, join: join33 } = await import("node:path");
36269
+ const { existsSync: existsSync18, readFileSync: readFileSync20, mkdirSync: mkdirSync7 } = await import("node:fs");
36270
+ const { resolve: resolve9, join: join35 } = await import("node:path");
35496
36271
  const specPath = resolve9(args.spec);
35497
- if (!existsSync17(specPath)) {
36272
+ if (!existsSync18(specPath)) {
35498
36273
  cliError(`spec file not found: ${specPath}`, 4, { name: "E_NOT_FOUND" });
35499
36274
  process.exitCode = 4;
35500
36275
  return;
35501
36276
  }
35502
- const specContent = readFileSync18(specPath, "utf-8");
36277
+ const specContent = readFileSync20(specPath, "utf-8");
35503
36278
  const projectRoot = getProjectRoot23();
35504
- const outputDir = args["output-dir"] ? resolve9(args["output-dir"]) : join33(projectRoot, ".cleo", "cant", "agents");
36279
+ const outputDir = args["output-dir"] ? resolve9(args["output-dir"]) : join35(projectRoot, ".cleo", "cant", "agents");
35505
36280
  mkdirSync7(outputDir, { recursive: true });
35506
36281
  if (args["dry-run"]) {
35507
36282
  cliOutput(
@@ -36102,9 +36877,9 @@ var init_consent = __esm({
36102
36877
  });
36103
36878
 
36104
36879
  // packages/cleo/src/cli/commands/auth/list.ts
36105
- import { existsSync as existsSync6 } from "node:fs";
36880
+ import { existsSync as existsSync7 } from "node:fs";
36106
36881
  import { homedir as homedir2 } from "node:os";
36107
- import { join as join7 } from "node:path";
36882
+ import { join as join9 } from "node:path";
36108
36883
  function formatExpiry(expiresAt) {
36109
36884
  if (expiresAt == null) return "never";
36110
36885
  const remaining = expiresAt - Date.now();
@@ -36181,8 +36956,8 @@ var init_list = __esm({
36181
36956
  const p = a2.provider.localeCompare(b.provider);
36182
36957
  return p !== 0 ? p : a2.label.localeCompare(b.label);
36183
36958
  });
36184
- const claudeCredsPath = join7(homedir2(), ".claude", ".credentials.json");
36185
- const hint = existsSync6(claudeCredsPath) && entries.every((e) => e.source !== "claude-code") ? "Hint: Claude Code OAuth detected at ~/.claude/.credentials.json but consent is off. Run `cleo auth consent --enable-claude-code` to seed it into the pool." : null;
36959
+ const claudeCredsPath = join9(homedir2(), ".claude", ".credentials.json");
36960
+ const hint = existsSync7(claudeCredsPath) && entries.every((e) => e.source !== "claude-code") ? "Hint: Claude Code OAuth detected at ~/.claude/.credentials.json but consent is off. Run `cleo auth consent --enable-claude-code` to seed it into the pool." : null;
36186
36961
  cliOutput(
36187
36962
  { entries, ...hint !== null ? { hint } : {} },
36188
36963
  {
@@ -36196,8 +36971,8 @@ var init_list = __esm({
36196
36971
  });
36197
36972
 
36198
36973
  // packages/cleo/src/cli/commands/auth/migrate-project-secrets.ts
36199
- import { existsSync as existsSync7, readFileSync as readFileSync7, writeFileSync as writeFileSync2 } from "node:fs";
36200
- import { join as join8 } from "node:path";
36974
+ import { existsSync as existsSync8, readFileSync as readFileSync9, writeFileSync as writeFileSync2 } from "node:fs";
36975
+ import { join as join10 } from "node:path";
36201
36976
  import { createInterface } from "node:readline";
36202
36977
  function resolveProjectRootArg(arg) {
36203
36978
  if (typeof arg === "string" && arg.length > 0) return arg;
@@ -36205,7 +36980,7 @@ function resolveProjectRootArg(arg) {
36205
36980
  }
36206
36981
  function projectConfigPath(projectRoot) {
36207
36982
  const cleoDir = process.env["CLEO_DIR"] ?? ".cleo";
36208
- return join8(projectRoot, cleoDir, "config.json");
36983
+ return join10(projectRoot, cleoDir, "config.json");
36209
36984
  }
36210
36985
  function extractApiKeyEntries(config) {
36211
36986
  if (!config || typeof config !== "object") return [];
@@ -36263,7 +37038,7 @@ async function promptYesNo(question) {
36263
37038
  }
36264
37039
  async function runMigrateProjectSecrets(opts) {
36265
37040
  const configPath = projectConfigPath(opts.projectRoot);
36266
- if (!existsSync7(configPath)) {
37041
+ if (!existsSync8(configPath)) {
36267
37042
  return {
36268
37043
  configPath,
36269
37044
  backupPath: null,
@@ -36272,7 +37047,7 @@ async function runMigrateProjectSecrets(opts) {
36272
37047
  dryRun: opts.dryRun
36273
37048
  };
36274
37049
  }
36275
- const raw = readFileSync7(configPath, "utf-8");
37050
+ const raw = readFileSync9(configPath, "utf-8");
36276
37051
  let parsed;
36277
37052
  try {
36278
37053
  parsed = JSON.parse(raw);
@@ -37119,9 +37894,9 @@ var init_backup = __esm({
37119
37894
  async run({ args }) {
37120
37895
  const scope = args.scope;
37121
37896
  const { packBundle } = await import("@cleocode/core/store/backup-pack.js");
37122
- const { getProjectRoot: getProjectRoot43 } = await import("@cleocode/core");
37897
+ const { getProjectRoot: getProjectRoot44 } = await import("@cleocode/core");
37123
37898
  const includesProject = scope === "project" || scope === "all";
37124
- const projectRoot = includesProject ? getProjectRoot43() : void 0;
37899
+ const projectRoot = includesProject ? getProjectRoot44() : void 0;
37125
37900
  let passphrase;
37126
37901
  if (args.encrypt === true) {
37127
37902
  passphrase = process.env["CLEO_BACKUP_PASSPHRASE"];
@@ -37197,12 +37972,12 @@ var init_backup = __esm({
37197
37972
  },
37198
37973
  async run({ args }) {
37199
37974
  const bundlePath = args.bundle;
37200
- const { getProjectRoot: getProjectRoot43, getCleoHome: getCleoHome6, getCleoVersion } = await import("@cleocode/core");
37975
+ const { getProjectRoot: getProjectRoot44, getCleoHome: getCleoHome6, getCleoVersion } = await import("@cleocode/core");
37201
37976
  const { BundleError, cleanupStaging, unpackBundle } = await import("@cleocode/core/store/backup-unpack.js");
37202
37977
  const { regenerateConfigJson, regenerateProjectContextJson, regenerateProjectInfoJson } = await import("@cleocode/core/store/regenerators.js");
37203
37978
  const { regenerateAndCompare } = await import("@cleocode/core/store/restore-json-merge.js");
37204
37979
  const { buildConflictReport, writeConflictReport } = await import("@cleocode/core/store/restore-conflict-report.js");
37205
- const projectRoot = getProjectRoot43();
37980
+ const projectRoot = getProjectRoot44();
37206
37981
  if (args.force !== true) {
37207
37982
  const existing = checkForExistingData(projectRoot, getCleoHome6());
37208
37983
  if (existing.length > 0) {
@@ -37802,13 +38577,13 @@ var briefing_exports = {};
37802
38577
  __export(briefing_exports, {
37803
38578
  briefingCommand: () => briefingCommand
37804
38579
  });
37805
- import { existsSync as existsSync8, readFileSync as readFileSync8 } from "node:fs";
37806
- import { join as join9 } from "node:path";
38580
+ import { existsSync as existsSync9, readFileSync as readFileSync10 } from "node:fs";
38581
+ import { join as join11 } from "node:path";
37807
38582
  import { pushWarning } from "@cleocode/core";
37808
38583
  import { resolveLegacyCleoDir } from "@cleocode/paths";
37809
38584
  function resolveInjectionTemplatePath() {
37810
38585
  const xdgConfig = resolveLegacyCleoDir(process.env["XDG_CONFIG_HOME"]);
37811
- return join9(xdgConfig, "templates", "CLEO-INJECTION.md");
38586
+ return join11(xdgConfig, "templates", "CLEO-INJECTION.md");
37812
38587
  }
37813
38588
  function extractSection(content, sectionName) {
37814
38589
  const openTag = `<!-- CLEO-INJECTION:section=${sectionName} -->`;
@@ -37835,7 +38610,7 @@ function renderForAdapter(sectionName, content, format) {
37835
38610
  }
37836
38611
  async function runBriefingInject(sectionName, formatStr) {
37837
38612
  const templatePath = resolveInjectionTemplatePath();
37838
- if (!existsSync8(templatePath)) {
38613
+ if (!existsSync9(templatePath)) {
37839
38614
  pushWarning({
37840
38615
  code: "W_TEMPLATE_INJECT_FAILED",
37841
38616
  message: `CLEO-INJECTION.md not found at ${templatePath}`
@@ -37852,7 +38627,7 @@ async function runBriefingInject(sectionName, formatStr) {
37852
38627
  process.exitCode = 1;
37853
38628
  return;
37854
38629
  }
37855
- const content = readFileSync8(templatePath, "utf-8");
38630
+ const content = readFileSync10(templatePath, "utf-8");
37856
38631
  const section = extractSection(content, sectionName);
37857
38632
  if (section === null) {
37858
38633
  const available = INJECTION_SECTION_NAMES.join(", ");
@@ -38014,7 +38789,7 @@ __export(caamp_exports, {
38014
38789
  caampCommand: () => caampCommand
38015
38790
  });
38016
38791
  import { homedir as homedir3 } from "node:os";
38017
- import { join as join10 } from "node:path";
38792
+ import { join as join12 } from "node:path";
38018
38793
  var dedupeCommand, caampCommand;
38019
38794
  var init_caamp = __esm({
38020
38795
  "packages/cleo/src/cli/commands/caamp.ts"() {
@@ -38051,18 +38826,18 @@ var init_caamp = __esm({
38051
38826
  } else {
38052
38827
  const home = homedir3();
38053
38828
  filePaths = [
38054
- join10(home, ".agents", "AGENTS.md"),
38829
+ join12(home, ".agents", "AGENTS.md"),
38055
38830
  // project-level AGENTS.md in cwd
38056
- join10(process.cwd(), "AGENTS.md")
38831
+ join12(process.cwd(), "AGENTS.md")
38057
38832
  ];
38058
38833
  }
38059
38834
  if (args["dry-run"]) {
38060
38835
  const { parseCaampBlocks } = await import("@cleocode/caamp");
38061
- const { existsSync: existsSync17 } = await import("node:fs");
38836
+ const { existsSync: existsSync18 } = await import("node:fs");
38062
38837
  const { readFile: readFile7 } = await import("node:fs/promises");
38063
38838
  const dryResults = [];
38064
38839
  for (const filePath of filePaths) {
38065
- if (!existsSync17(filePath)) {
38840
+ if (!existsSync18(filePath)) {
38066
38841
  dryResults.push({ filePath, exists: false, blockCount: 0, wouldRemove: 0 });
38067
38842
  continue;
38068
38843
  }
@@ -38160,13 +38935,13 @@ var cant_exports = {};
38160
38935
  __export(cant_exports, {
38161
38936
  cantCommand: () => cantCommand
38162
38937
  });
38163
- import { existsSync as existsSync9, mkdirSync as mkdirSync2, readFileSync as readFileSync9, writeFileSync as writeFileSync3 } from "node:fs";
38164
- import { dirname as dirname5, isAbsolute, join as join11, resolve as resolve4 } from "node:path";
38938
+ import { existsSync as existsSync10, mkdirSync as mkdirSync2, readFileSync as readFileSync11, writeFileSync as writeFileSync3 } from "node:fs";
38939
+ import { dirname as dirname5, isAbsolute, join as join13, resolve as resolve4 } from "node:path";
38165
38940
  function resolveFilePath(file) {
38166
38941
  return isAbsolute(file) ? file : resolve4(process.cwd(), file);
38167
38942
  }
38168
38943
  function ensureExists(filePath, operation) {
38169
- if (existsSync9(filePath)) return true;
38944
+ if (existsSync10(filePath)) return true;
38170
38945
  cliError(`File not found: ${filePath}`, "E_FILE_READ");
38171
38946
  process.exitCode = 3;
38172
38947
  if (process.env["CLEO_DEBUG"]) humanWarn(`(operation: ${operation})`);
@@ -38316,7 +39091,7 @@ var init_cant = __esm({
38316
39091
  if (!ensureExists(filePath, "cant.migrate")) return;
38317
39092
  try {
38318
39093
  const mod = await loadMigrateEngine();
38319
- const content = readFileSync9(filePath, "utf-8");
39094
+ const content = readFileSync11(filePath, "utf-8");
38320
39095
  const result = mod.migrateMarkdown(content, filePath, {
38321
39096
  write: isWrite,
38322
39097
  verbose: isVerbose,
@@ -38326,7 +39101,7 @@ var init_cant = __esm({
38326
39101
  const projectRoot = process.cwd();
38327
39102
  let written = 0;
38328
39103
  for (const outputFile of result.outputFiles) {
38329
- const outputPath = isAbsolute(outputFile.path) ? outputFile.path : join11(projectRoot, outputFile.path);
39104
+ const outputPath = isAbsolute(outputFile.path) ? outputFile.path : join13(projectRoot, outputFile.path);
38330
39105
  mkdirSync2(dirname5(outputPath), { recursive: true });
38331
39106
  writeFileSync3(outputPath, outputFile.content, "utf-8");
38332
39107
  written++;
@@ -38382,7 +39157,7 @@ var chain_exports = {};
38382
39157
  __export(chain_exports, {
38383
39158
  chainCommand: () => chainCommand
38384
39159
  });
38385
- import { readFileSync as readFileSync10 } from "node:fs";
39160
+ import { readFileSync as readFileSync12 } from "node:fs";
38386
39161
  var showCommand3, listCommand5, addCommand3, instantiateCommand, advanceCommand, chainCommand;
38387
39162
  var init_chain = __esm({
38388
39163
  "packages/cleo/src/cli/commands/chain.ts"() {
@@ -38424,7 +39199,7 @@ var init_chain = __esm({
38424
39199
  }
38425
39200
  },
38426
39201
  async run({ args }) {
38427
- const chainJson = JSON.parse(readFileSync10(args.file, "utf-8"));
39202
+ const chainJson = JSON.parse(readFileSync12(args.file, "utf-8"));
38428
39203
  await dispatchFromCli(
38429
39204
  "mutate",
38430
39205
  "pipeline",
@@ -38500,6 +39275,142 @@ var init_chain = __esm({
38500
39275
  }
38501
39276
  });
38502
39277
 
39278
+ // packages/cleo/src/cli/commands/changeset.ts
39279
+ var changeset_exports = {};
39280
+ __export(changeset_exports, {
39281
+ changesetCommand: () => changesetCommand
39282
+ });
39283
+ import { changesets, getProjectRoot as getProjectRoot27 } from "@cleocode/core";
39284
+ function isValidKind(raw) {
39285
+ return typeof raw === "string" && CHANGESET_KINDS.includes(raw);
39286
+ }
39287
+ function parseTasksFlag(raw) {
39288
+ if (typeof raw !== "string" || raw.length === 0) return void 0;
39289
+ const tasks = raw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
39290
+ return tasks.length > 0 ? tasks : void 0;
39291
+ }
39292
+ function parsePrsFlag(raw) {
39293
+ if (typeof raw !== "string" || raw.length === 0) return void 0;
39294
+ const numbers = [];
39295
+ for (const segment of raw.split(",")) {
39296
+ const trimmed = segment.trim();
39297
+ if (trimmed.length === 0) continue;
39298
+ const n = Number.parseInt(trimmed, 10);
39299
+ if (Number.isFinite(n) && n > 0) numbers.push(n);
39300
+ }
39301
+ return numbers.length > 0 ? numbers : void 0;
39302
+ }
39303
+ var addCommand4, changesetCommand;
39304
+ var init_changeset = __esm({
39305
+ "packages/cleo/src/cli/commands/changeset.ts"() {
39306
+ "use strict";
39307
+ init_src2();
39308
+ init_dist();
39309
+ init_renderers();
39310
+ addCommand4 = defineCommand({
39311
+ meta: {
39312
+ name: "add",
39313
+ description: "Author a task-anchored changeset entry. Dual-writes to .changeset/<slug>.md AND the docs SSoT blob store. Slug must match /^t\\d+-[a-z0-9-]+$/ (e.g. t9793-changeset-ssot-integration)."
39314
+ },
39315
+ args: {
39316
+ slug: {
39317
+ type: "string",
39318
+ description: "Filename slug (sans .md). Must match /^t\\d+-[a-z0-9-]+$/. Example: t9793-changeset-ssot-integration",
39319
+ required: true
39320
+ },
39321
+ tasks: {
39322
+ type: "string",
39323
+ description: "Comma-separated CLEO task IDs (T####). Example: T9793,T9788",
39324
+ required: true
39325
+ },
39326
+ kind: {
39327
+ type: "string",
39328
+ description: `Type of change: ${CHANGESET_KINDS.join(" | ")}`,
39329
+ required: true
39330
+ },
39331
+ summary: {
39332
+ type: "string",
39333
+ description: "One-line user-facing description of the change",
39334
+ required: true
39335
+ },
39336
+ prs: {
39337
+ type: "string",
39338
+ description: "Comma-separated PR numbers, when known. Example: 349,357"
39339
+ },
39340
+ notes: {
39341
+ type: "string",
39342
+ description: "Optional longer-form markdown body (becomes the file body)"
39343
+ },
39344
+ breaking: {
39345
+ type: "string",
39346
+ description: "Migration note. REQUIRED when --kind is `breaking`."
39347
+ },
39348
+ "attached-by": {
39349
+ type: "string",
39350
+ description: "Agent identity recorded on the SSoT row (default: cleo-changeset)"
39351
+ }
39352
+ },
39353
+ async run({ args }) {
39354
+ if (!isValidKind(args.kind)) {
39355
+ cliError(`--kind must be one of: ${CHANGESET_KINDS.join(" | ")} \u2014 got '${args.kind}'`, 6, {
39356
+ name: "E_VALIDATION",
39357
+ fix: `cleo changeset add --kind feat ... (or one of: ${CHANGESET_KINDS.join(", ")})`
39358
+ });
39359
+ process.exit(6);
39360
+ }
39361
+ const kind = args.kind;
39362
+ const tasks = parseTasksFlag(args.tasks);
39363
+ if (!tasks) {
39364
+ cliError("--tasks must contain at least one task ID", 6, { name: "E_VALIDATION" });
39365
+ process.exit(6);
39366
+ }
39367
+ const prs = parsePrsFlag(args.prs);
39368
+ const entry = {
39369
+ id: String(args.slug),
39370
+ tasks,
39371
+ kind,
39372
+ summary: String(args.summary),
39373
+ ...prs !== void 0 ? { prs } : {},
39374
+ ...typeof args.notes === "string" && args.notes.length > 0 ? { notes: args.notes } : {},
39375
+ ...typeof args.breaking === "string" && args.breaking.length > 0 ? { breaking: args.breaking } : {}
39376
+ };
39377
+ const projectRoot = getProjectRoot27();
39378
+ const outcome = await changesets.writeChangesetEntry(entry, {
39379
+ projectRoot,
39380
+ ...typeof args["attached-by"] === "string" && args["attached-by"].length > 0 ? { attachedBy: args["attached-by"] } : {}
39381
+ });
39382
+ if (!outcome.ok) {
39383
+ const err = outcome.error;
39384
+ const hint = err.code === "E_SLUG_PATTERN_MISMATCH" && err.example ? `example slug: ${err.example}` : void 0;
39385
+ cliError(err.message, 6 /* VALIDATION_ERROR */, {
39386
+ name: err.code,
39387
+ ...hint ? { fix: hint } : {}
39388
+ });
39389
+ process.exit(6 /* VALIDATION_ERROR */);
39390
+ }
39391
+ const result = outcome.result;
39392
+ humanInfo(`Wrote ${result.filePath}`);
39393
+ humanInfo(`Wrote SSoT blob ${result.attachmentId} (sha=${result.sha256.slice(0, 12)}\u2026)`);
39394
+ cliOutput(result, { command: "changeset add", operation: "changeset.add" });
39395
+ }
39396
+ });
39397
+ changesetCommand = defineCommand({
39398
+ meta: {
39399
+ name: "changeset",
39400
+ description: "Author task-anchored changeset entries that dual-write to .changeset/*.md AND the docs SSoT blob store (T9793)."
39401
+ },
39402
+ subCommands: {
39403
+ add: addCommand4
39404
+ },
39405
+ async run({ cmd, rawArgs }) {
39406
+ const firstArg = rawArgs?.find((a) => !a.startsWith("-"));
39407
+ if (firstArg && cmd.subCommands && firstArg in cmd.subCommands) return;
39408
+ await showUsage(cmd);
39409
+ }
39410
+ });
39411
+ }
39412
+ });
39413
+
38503
39414
  // packages/cleo/src/cli/lib/registry-args.ts
38504
39415
  function getOperationParams(gateway, domain, operation) {
38505
39416
  const def = OPERATIONS.find(
@@ -38520,7 +39431,7 @@ var check_exports = {};
38520
39431
  __export(check_exports, {
38521
39432
  checkCommand: () => checkCommand
38522
39433
  });
38523
- var SUPPORTED_PROTOCOL_TYPES, checkSchemaCommand, checkCoherenceCommand, checkTaskCommand, checkOutputCommand, checkChainValidateCommand, checkCanonCommand, checkProtocolCommand, checkProvenanceCommand, checkCommand;
39434
+ var SUPPORTED_PROTOCOL_TYPES, checkSchemaCommand, checkCoherenceCommand, checkTaskCommand, checkOutputCommand, checkChainValidateCommand, checkCanonDocsCommand, checkCanonCommand, checkProtocolCommand, checkProvenanceCommand, checkCommand;
38524
39435
  var init_check2 = __esm({
38525
39436
  "packages/cleo/src/cli/commands/check.ts"() {
38526
39437
  "use strict";
@@ -38609,10 +39520,10 @@ var init_check2 = __esm({
38609
39520
  }
38610
39521
  },
38611
39522
  async run({ args }) {
38612
- const { readFileSync: readFileSync18 } = await import("node:fs");
39523
+ const { readFileSync: readFileSync20 } = await import("node:fs");
38613
39524
  let chain;
38614
39525
  try {
38615
- chain = JSON.parse(readFileSync18(args.file, "utf8"));
39526
+ chain = JSON.parse(readFileSync20(args.file, "utf8"));
38616
39527
  } catch (err) {
38617
39528
  const message = err instanceof Error ? err.message : String(err);
38618
39529
  cliError(`Failed to read or parse chain file: ${message}`, 2, {
@@ -38630,9 +39541,35 @@ var init_check2 = __esm({
38630
39541
  );
38631
39542
  }
38632
39543
  });
39544
+ checkCanonDocsCommand = defineCommand({
39545
+ meta: {
39546
+ name: "docs",
39547
+ description: "CI gate: block raw *.md writes that bypass the docs SSoT (T9796)"
39548
+ },
39549
+ args: {
39550
+ base: {
39551
+ type: "string",
39552
+ description: "Git ref to diff against (default: origin/main)"
39553
+ }
39554
+ },
39555
+ async run({ args }) {
39556
+ await dispatchFromCli(
39557
+ "query",
39558
+ "check",
39559
+ "canon.docs",
39560
+ { baseRef: args.base },
39561
+ { command: "check", operation: "check.canon.docs" }
39562
+ );
39563
+ }
39564
+ });
38633
39565
  checkCanonCommand = defineCommand({
38634
39566
  meta: { name: "canon", description: "CI gate: detect canon drift between docs and live code" },
38635
- async run() {
39567
+ subCommands: {
39568
+ docs: checkCanonDocsCommand
39569
+ },
39570
+ async run({ cmd, rawArgs }) {
39571
+ const firstArg = rawArgs?.find((a) => !a.startsWith("-"));
39572
+ if (firstArg && cmd.subCommands && firstArg in cmd.subCommands) return;
38636
39573
  await dispatchFromCli("query", "check", "canon", {}, { command: "check" });
38637
39574
  }
38638
39575
  });
@@ -38800,7 +39737,7 @@ var init_check2 = __esm({
38800
39737
  }
38801
39738
  },
38802
39739
  async run({ args }) {
38803
- const { execSync } = await import("node:child_process");
39740
+ const { execSync: execSync2 } = await import("node:child_process");
38804
39741
  const since = args.since;
38805
39742
  const branch = args.branch || "HEAD";
38806
39743
  const strict = Boolean(args.strict);
@@ -38808,7 +39745,7 @@ var init_check2 = __esm({
38808
39745
  const range = since ? `${since}..${branch}` : branch;
38809
39746
  let logOutput;
38810
39747
  try {
38811
- logOutput = execSync(`git log --no-merges --pretty=format:"%H %s" -n ${limit} ${range}`, {
39748
+ logOutput = execSync2(`git log --no-merges --pretty=format:"%H %s" -n ${limit} ${range}`, {
38812
39749
  encoding: "utf8",
38813
39750
  stdio: ["pipe", "pipe", "pipe"]
38814
39751
  });
@@ -39084,9 +40021,9 @@ var init_code = __esm({
39084
40021
  async run({ args }) {
39085
40022
  await requireTreeSitter();
39086
40023
  const { smartOutline } = await import("@cleocode/core/internal");
39087
- const { join: join33 } = await import("node:path");
40024
+ const { join: join35 } = await import("node:path");
39088
40025
  const root = process.cwd();
39089
- const absPath = args.file.startsWith("/") ? args.file : join33(root, args.file);
40026
+ const absPath = args.file.startsWith("/") ? args.file : join35(root, args.file);
39090
40027
  const result = smartOutline(absPath, root);
39091
40028
  if (result.errors.length > 0 && result.symbols.length === 0) {
39092
40029
  cliError(result.errors.join(", "), 1, { name: "E_OUTLINE_FAILED" });
@@ -39177,9 +40114,9 @@ var init_code = __esm({
39177
40114
  async run({ args }) {
39178
40115
  await requireTreeSitter();
39179
40116
  const { smartUnfold } = await import("@cleocode/core/internal");
39180
- const { join: join33 } = await import("node:path");
40117
+ const { join: join35 } = await import("node:path");
39181
40118
  const root = process.cwd();
39182
- const absPath = args.file.startsWith("/") ? args.file : join33(root, args.file);
40119
+ const absPath = args.file.startsWith("/") ? args.file : join35(root, args.file);
39183
40120
  const result = smartUnfold(absPath, args.symbol, root);
39184
40121
  if (!result.found) {
39185
40122
  const errs = result.errors.length > 0 ? `: ${result.errors.join(", ")}` : "";
@@ -40298,7 +41235,7 @@ var curator_exports = {};
40298
41235
  __export(curator_exports, {
40299
41236
  curatorCommand: () => curatorCommand
40300
41237
  });
40301
- import { join as join12 } from "node:path";
41238
+ import { join as join14 } from "node:path";
40302
41239
  import { getCleoHome } from "@cleocode/paths";
40303
41240
  async function loadCurator() {
40304
41241
  return import("@cleocode/core/sentient/curator.js");
@@ -40328,7 +41265,7 @@ var init_curator = __esm({
40328
41265
  try {
40329
41266
  const { runCuratorTick } = await loadCurator();
40330
41267
  const { readCuratorConfig } = await loadDaemon();
40331
- const configPath = join12(getCleoHome(), "config.json");
41268
+ const configPath = join14(getCleoHome(), "config.json");
40332
41269
  const cfg = await readCuratorConfig(configPath);
40333
41270
  const result = await runCuratorTick({
40334
41271
  dryRun: args["dry-run"] === true,
@@ -40369,7 +41306,7 @@ var init_curator = __esm({
40369
41306
  async run() {
40370
41307
  try {
40371
41308
  const { readCuratorConfig, curatorCronExpression } = await loadDaemon();
40372
- const configPath = join12(getCleoHome(), "config.json");
41309
+ const configPath = join14(getCleoHome(), "config.json");
40373
41310
  const cfg = await readCuratorConfig(configPath);
40374
41311
  cliOutput(
40375
41312
  {
@@ -40443,8 +41380,8 @@ var daemon_exports = {};
40443
41380
  __export(daemon_exports, {
40444
41381
  daemonCommand: () => daemonCommand
40445
41382
  });
40446
- import { existsSync as existsSync10 } from "node:fs";
40447
- import { join as join13 } from "node:path";
41383
+ import { existsSync as existsSync11 } from "node:fs";
41384
+ import { join as join15 } from "node:path";
40448
41385
  import { fileURLToPath as fileURLToPath4 } from "node:url";
40449
41386
  import { getGCDaemonStatus, spawnGCDaemon, stopGCDaemon } from "@cleocode/core/gc/daemon.js";
40450
41387
  import {
@@ -40510,9 +41447,9 @@ async function showDaemonStatus(cleoDir, projectRoot) {
40510
41447
  }
40511
41448
  function resolveDaemonInstallerScript() {
40512
41449
  const filePath = fileURLToPath4(import.meta.url);
40513
- const candidate1 = join13(filePath, "..", "..", "..", "scripts", "install-daemon-service.mjs");
40514
- if (existsSync10(candidate1)) return candidate1;
40515
- const candidate2 = join13(
41450
+ const candidate1 = join15(filePath, "..", "..", "..", "scripts", "install-daemon-service.mjs");
41451
+ if (existsSync11(candidate1)) return candidate1;
41452
+ const candidate2 = join15(
40516
41453
  filePath,
40517
41454
  "..",
40518
41455
  "..",
@@ -40584,13 +41521,13 @@ var init_daemon = __esm({
40584
41521
  {
40585
41522
  pid,
40586
41523
  cleoDir,
40587
- logs: join13(cleoDir, "logs", "gc.log"),
41524
+ logs: join15(cleoDir, "logs", "gc.log"),
40588
41525
  message: `GC daemon started (PID ${pid})`
40589
41526
  },
40590
41527
  {
40591
41528
  command: "daemon",
40592
41529
  operation: "daemon.start",
40593
- message: `GC daemon started (PID ${pid}) \u2014 Logs: ${join13(cleoDir, "logs", "gc.log")}`
41530
+ message: `GC daemon started (PID ${pid}) \u2014 Logs: ${join15(cleoDir, "logs", "gc.log")}`
40594
41531
  }
40595
41532
  );
40596
41533
  } catch (err) {
@@ -41219,12 +42156,12 @@ var detect_drift_exports = {};
41219
42156
  __export(detect_drift_exports, {
41220
42157
  detectDriftCommand: () => detectDriftCommand
41221
42158
  });
41222
- import { existsSync as existsSync11, readdirSync, readFileSync as readFileSync11 } from "node:fs";
41223
- import { dirname as dirname6, join as join14 } from "node:path";
42159
+ import { existsSync as existsSync12, readdirSync, readFileSync as readFileSync13 } from "node:fs";
42160
+ import { dirname as dirname6, join as join16 } from "node:path";
41224
42161
  function findProjectRoot() {
41225
42162
  let currentDir = process.cwd();
41226
42163
  while (currentDir !== "/") {
41227
- if (existsSync11(join14(currentDir, "package.json"))) {
42164
+ if (existsSync12(join16(currentDir, "package.json"))) {
41228
42165
  return currentDir;
41229
42166
  }
41230
42167
  const parent = dirname6(currentDir);
@@ -41248,11 +42185,11 @@ var init_detect_drift = __esm({
41248
42185
  },
41249
42186
  async run() {
41250
42187
  const projectRoot = findProjectRoot();
41251
- const isCleoRepo = existsSync11(join14(projectRoot, "packages", "cleo", "src"));
41252
- const cleoSrcRoot = isCleoRepo ? join14(projectRoot, "packages", "cleo", "src") : join14(projectRoot, "src");
42188
+ const isCleoRepo = existsSync12(join16(projectRoot, "packages", "cleo", "src"));
42189
+ const cleoSrcRoot = isCleoRepo ? join16(projectRoot, "packages", "cleo", "src") : join16(projectRoot, "src");
41253
42190
  const safeRead = (filePath) => {
41254
42191
  try {
41255
- return readFileSync11(filePath, "utf-8");
42192
+ return readFileSync13(filePath, "utf-8");
41256
42193
  } catch {
41257
42194
  return "";
41258
42195
  }
@@ -41263,8 +42200,8 @@ var init_detect_drift = __esm({
41263
42200
  checks: [],
41264
42201
  recommendations: []
41265
42202
  };
41266
- const injPath = join14(projectRoot, CLEO_DIR_NAME, TEMPLATES_SUBDIR, CLEO_INJECTION_MD);
41267
- if (existsSync11(injPath)) {
42203
+ const injPath = join16(projectRoot, CLEO_DIR_NAME, TEMPLATES_SUBDIR, CLEO_INJECTION_MD);
42204
+ if (existsSync12(injPath)) {
41268
42205
  const content = safeRead(injPath);
41269
42206
  userResult.checks.push({
41270
42207
  name: "Agent injection",
@@ -41315,10 +42252,10 @@ var init_detect_drift = __esm({
41315
42252
  }
41316
42253
  };
41317
42254
  try {
41318
- const specPath = join14(projectRoot, "docs", "specs", "CLEO-OPERATION-CONSTITUTION.md");
41319
- const registryPath = join14(cleoSrcRoot, "dispatch", "registry.ts");
41320
- const dispatchDomainsDir = join14(cleoSrcRoot, "dispatch", "domains");
41321
- if (!existsSync11(specPath)) {
42255
+ const specPath = join16(projectRoot, "docs", "specs", "CLEO-OPERATION-CONSTITUTION.md");
42256
+ const registryPath = join16(cleoSrcRoot, "dispatch", "registry.ts");
42257
+ const dispatchDomainsDir = join16(cleoSrcRoot, "dispatch", "domains");
42258
+ if (!existsSync12(specPath)) {
41322
42259
  addCheck("Gateway-to-spec sync", "fail", "CLEO-OPERATION-CONSTITUTION.md missing", [
41323
42260
  {
41324
42261
  severity: "error",
@@ -41328,7 +42265,7 @@ var init_detect_drift = __esm({
41328
42265
  recommendation: "Create docs/specs/CLEO-OPERATION-CONSTITUTION.md with canonical operation definitions"
41329
42266
  }
41330
42267
  ]);
41331
- } else if (!existsSync11(registryPath) || !existsSync11(dispatchDomainsDir)) {
42268
+ } else if (!existsSync12(registryPath) || !existsSync12(dispatchDomainsDir)) {
41332
42269
  addCheck("Gateway-to-spec sync", "fail", "Dispatch registry or domains missing", [
41333
42270
  {
41334
42271
  severity: "error",
@@ -41386,9 +42323,9 @@ var init_detect_drift = __esm({
41386
42323
  ]);
41387
42324
  }
41388
42325
  try {
41389
- const cliDir = join14(cleoSrcRoot, "cli", "commands");
41390
- const coreDir = isCleoRepo ? join14(projectRoot, "packages", "core", "src") : join14(projectRoot, "src", "core");
41391
- if (!existsSync11(cliDir)) {
42326
+ const cliDir = join16(cleoSrcRoot, "cli", "commands");
42327
+ const coreDir = isCleoRepo ? join16(projectRoot, "packages", "core", "src") : join16(projectRoot, "src", "core");
42328
+ if (!existsSync12(cliDir)) {
41392
42329
  addCheck("CLI-to-core sync", "fail", "CLI commands directory missing", [
41393
42330
  {
41394
42331
  severity: "error",
@@ -41397,7 +42334,7 @@ var init_detect_drift = __esm({
41397
42334
  recommendation: "Verify TypeScript source structure is intact"
41398
42335
  }
41399
42336
  ]);
41400
- } else if (!existsSync11(coreDir)) {
42337
+ } else if (!existsSync12(coreDir)) {
41401
42338
  addCheck("CLI-to-core sync", "fail", "Core directory missing", [
41402
42339
  {
41403
42340
  severity: "error",
@@ -41414,8 +42351,8 @@ var init_detect_drift = __esm({
41414
42351
  addCheck("CLI-to-core sync", "fail", `Error: ${getErrorMessage(e)}`);
41415
42352
  }
41416
42353
  try {
41417
- const domainsDir = join14(cleoSrcRoot, "dispatch", "domains");
41418
- if (!existsSync11(domainsDir)) {
42354
+ const domainsDir = join16(cleoSrcRoot, "dispatch", "domains");
42355
+ if (!existsSync12(domainsDir)) {
41419
42356
  addCheck("Domain handler coverage", "fail", "Dispatch domains directory missing", [
41420
42357
  {
41421
42358
  severity: "error",
@@ -41432,8 +42369,8 @@ var init_detect_drift = __esm({
41432
42369
  addCheck("Domain handler coverage", "fail", `Error: ${getErrorMessage(e)}`);
41433
42370
  }
41434
42371
  try {
41435
- const matrixPath = join14(cleoSrcRoot, "dispatch", "lib", "capability-matrix.ts");
41436
- if (!existsSync11(matrixPath)) {
42372
+ const matrixPath = join16(cleoSrcRoot, "dispatch", "lib", "capability-matrix.ts");
42373
+ if (!existsSync12(matrixPath)) {
41437
42374
  addCheck("Capability matrix", "fail", "Capability matrix missing", [
41438
42375
  {
41439
42376
  severity: "error",
@@ -41449,8 +42386,8 @@ var init_detect_drift = __esm({
41449
42386
  addCheck("Capability matrix", "fail", `Error: ${getErrorMessage(e)}`);
41450
42387
  }
41451
42388
  try {
41452
- const schemaPath = join14(projectRoot, "src", "store", "schema.ts");
41453
- if (!existsSync11(schemaPath)) {
42389
+ const schemaPath = join16(projectRoot, "src", "store", "schema.ts");
42390
+ if (!existsSync12(schemaPath)) {
41454
42391
  addCheck("Schema validation", "fail", "Schema definition missing", [
41455
42392
  {
41456
42393
  severity: "error",
@@ -41484,10 +42421,10 @@ var init_detect_drift = __esm({
41484
42421
  addCheck("Schema validation", "fail", `Error: ${getErrorMessage(e)}`);
41485
42422
  }
41486
42423
  try {
41487
- const visionPath = join14(projectRoot, "docs", "concepts", "CLEO-VISION.md");
41488
- const specPath = join14(projectRoot, "docs", "specs", "CLEO-PORTABLE-PROJECT-BRAIN-SPEC.md");
42424
+ const visionPath = join16(projectRoot, "docs", "concepts", "CLEO-VISION.md");
42425
+ const specPath = join16(projectRoot, "docs", "specs", "CLEO-PORTABLE-PROJECT-BRAIN-SPEC.md");
41489
42426
  const issues = [];
41490
- if (!existsSync11(visionPath)) {
42427
+ if (!existsSync12(visionPath)) {
41491
42428
  issues.push({
41492
42429
  severity: "error",
41493
42430
  category: "vision",
@@ -41496,7 +42433,7 @@ var init_detect_drift = __esm({
41496
42433
  recommendation: "Create docs/concepts/CLEO-VISION.md with project vision"
41497
42434
  });
41498
42435
  }
41499
- if (!existsSync11(specPath)) {
42436
+ if (!existsSync12(specPath)) {
41500
42437
  issues.push({
41501
42438
  severity: "error",
41502
42439
  category: "spec",
@@ -41540,8 +42477,8 @@ var init_detect_drift = __esm({
41540
42477
  addCheck("Canonical identity", "fail", `Error: ${getErrorMessage(e)}`);
41541
42478
  }
41542
42479
  try {
41543
- const injectionPath = join14(projectRoot, CLEO_DIR_NAME, TEMPLATES_SUBDIR, CLEO_INJECTION_MD);
41544
- if (!existsSync11(injectionPath)) {
42480
+ const injectionPath = join16(projectRoot, CLEO_DIR_NAME, TEMPLATES_SUBDIR, CLEO_INJECTION_MD);
42481
+ if (!existsSync12(injectionPath)) {
41545
42482
  addCheck("Agent injection", "fail", "Agent injection template missing", [
41546
42483
  {
41547
42484
  severity: "error",
@@ -41570,8 +42507,8 @@ var init_detect_drift = __esm({
41570
42507
  addCheck("Agent injection", "fail", `Error: ${getErrorMessage(e)}`);
41571
42508
  }
41572
42509
  try {
41573
- const exitCodesPath = join14(cleoSrcRoot, "dispatch", "lib", "exit-codes.ts");
41574
- if (!existsSync11(exitCodesPath)) {
42510
+ const exitCodesPath = join16(cleoSrcRoot, "dispatch", "lib", "exit-codes.ts");
42511
+ if (!existsSync12(exitCodesPath)) {
41575
42512
  addCheck("Exit codes", "fail", "Exit codes definition missing", [
41576
42513
  {
41577
42514
  severity: "error",
@@ -41741,10 +42678,10 @@ var init_diagnostics2 = __esm({
41741
42678
 
41742
42679
  // packages/cleo/src/viewer/pidfile.ts
41743
42680
  import { mkdir, readFile as readFile2, unlink, writeFile } from "node:fs/promises";
41744
- import { dirname as dirname7, join as join15 } from "node:path";
42681
+ import { dirname as dirname7, join as join17 } from "node:path";
41745
42682
  import { getCleoHome as getCleoHome2 } from "@cleocode/core/internal";
41746
42683
  function viewerPidFilePath() {
41747
- return join15(getCleoHome2(), "viewer.pid");
42684
+ return join17(getCleoHome2(), "viewer.pid");
41748
42685
  }
41749
42686
  async function writeViewerPidFile(record) {
41750
42687
  const path6 = viewerPidFilePath();
@@ -41844,11 +42781,11 @@ var init_port_allocator = __esm({
41844
42781
  // packages/cleo/src/viewer/server.ts
41845
42782
  import { createReadStream } from "node:fs";
41846
42783
  import { stat } from "node:fs/promises";
41847
- import { dirname as dirname8, join as join16, normalize, resolve as resolve5 } from "node:path";
42784
+ import { dirname as dirname8, join as join18, normalize, resolve as resolve5 } from "node:path";
41848
42785
  import { fileURLToPath as fileURLToPath5 } from "node:url";
41849
42786
  import {
41850
42787
  createAttachmentStore as createAttachmentStore2,
41851
- getProjectRoot as getProjectRoot27,
42788
+ getProjectRoot as getProjectRoot28,
41852
42789
  searchAllProjectDocs
41853
42790
  } from "@cleocode/core/internal";
41854
42791
  function getViewerAssetsDir() {
@@ -41883,7 +42820,7 @@ function inferTitle(markdown, fallback) {
41883
42820
  }
41884
42821
  async function serveStatic(res, assetsDir, relPath) {
41885
42822
  const safeRel = normalize(relPath).replace(/^[\\/]+/, "");
41886
- const absPath = join16(assetsDir, safeRel);
42823
+ const absPath = join18(assetsDir, safeRel);
41887
42824
  const resolvedAssets = resolve5(assetsDir) + "/";
41888
42825
  const resolvedAbs = resolve5(absPath);
41889
42826
  if (`${resolvedAbs}/`.indexOf(resolvedAssets) !== 0 && resolvedAbs !== resolve5(assetsDir)) {
@@ -41908,7 +42845,7 @@ async function serveStatic(res, assetsDir, relPath) {
41908
42845
  }
41909
42846
  }
41910
42847
  function buildViewerHandler(opts = {}) {
41911
- const projectRoot = opts.projectRoot ?? getProjectRoot27();
42848
+ const projectRoot = opts.projectRoot ?? getProjectRoot28();
41912
42849
  const assetsDir = getViewerAssetsDir();
41913
42850
  const store = createAttachmentStore2();
41914
42851
  return async (req, res) => {
@@ -42084,12 +43021,12 @@ var init_server = __esm({
42084
43021
  // packages/cleo/src/cli/commands/docs-viewer.ts
42085
43022
  import { spawn } from "node:child_process";
42086
43023
  import { open as fsOpen } from "node:fs/promises";
42087
- import { join as join17 } from "node:path";
43024
+ import { join as join19 } from "node:path";
42088
43025
  import { fileURLToPath as fileURLToPath6 } from "node:url";
42089
- import { getCleoHome as getCleoHome3, getProjectRoot as getProjectRoot28 } from "@cleocode/core";
43026
+ import { getCleoHome as getCleoHome3, getProjectRoot as getProjectRoot29 } from "@cleocode/core";
42090
43027
  function getCleoBinPath() {
42091
43028
  const thisFile = fileURLToPath6(import.meta.url);
42092
- return join17(thisFile, "..", "..", "index.js");
43029
+ return join19(thisFile, "..", "..", "index.js");
42093
43030
  }
42094
43031
  async function waitForExit(pid, timeoutMs, intervalMs = 100) {
42095
43032
  const deadline = Date.now() + timeoutMs;
@@ -42118,7 +43055,7 @@ function openInBrowser(url) {
42118
43055
  }
42119
43056
  }
42120
43057
  async function spawnDetachedServer(opts) {
42121
- const logFile = join17(getCleoHome3(), "viewer.log");
43058
+ const logFile = join19(getCleoHome3(), "viewer.log");
42122
43059
  const handle = await fsOpen(logFile, "a").catch(() => null);
42123
43060
  const stdio = handle ? ["ignore", handle.fd, handle.fd] : ["ignore", "ignore", "ignore"];
42124
43061
  const args = [
@@ -42137,7 +43074,7 @@ async function spawnDetachedServer(opts) {
42137
43074
  detached: true,
42138
43075
  stdio,
42139
43076
  env: { ...process.env, [DETACHED_CHILD_ENV]: "1" },
42140
- cwd: getProjectRoot28()
43077
+ cwd: getProjectRoot29()
42141
43078
  });
42142
43079
  child.unref();
42143
43080
  if (handle) await handle.close();
@@ -42289,7 +43226,7 @@ var init_docs_viewer = __esm({
42289
43226
  pid: process.pid,
42290
43227
  port: handle.port,
42291
43228
  host: handle.host,
42292
- projectRoot: getProjectRoot28(),
43229
+ projectRoot: getProjectRoot29(),
42293
43230
  startedAt: Date.now()
42294
43231
  };
42295
43232
  await writeViewerPidFile(record);
@@ -42565,17 +43502,17 @@ __export(docs_exports, {
42565
43502
  docsCommand: () => docsCommand
42566
43503
  });
42567
43504
  import { appendFile, mkdir as mkdir2, readdir, readFile as readFile3, writeFile as writeFile2 } from "node:fs/promises";
42568
- import { dirname as dirname9, isAbsolute as isAbsolute2, join as join18, resolve as resolve6 } from "node:path";
43505
+ import { dirname as dirname9, isAbsolute as isAbsolute2, join as join20, resolve as resolve6 } from "node:path";
42569
43506
  import {
42570
43507
  buildDocsGraph,
42571
43508
  CleoError as CleoError3,
42572
43509
  CounterMismatchError,
42573
- createDocsAccessor,
43510
+ createAttachmentStoreDocsAccessor,
42574
43511
  exportDocument,
42575
- formatError as formatError5,
42576
43512
  getAgentOutputsAbsolute,
42577
- getProjectRoot as getProjectRoot29,
43513
+ getProjectRoot as getProjectRoot30,
42578
43514
  listDocVersions,
43515
+ makeClassifierForScanRoot,
42579
43516
  mergeDocs,
42580
43517
  publishDocs,
42581
43518
  publishDocsAsPr,
@@ -42589,7 +43526,7 @@ import {
42589
43526
  syncFromGit
42590
43527
  } from "@cleocode/core/internal";
42591
43528
  async function getScriptNames(projectRoot) {
42592
- const scriptsDir = join18(projectRoot, "scripts");
43529
+ const scriptsDir = join20(projectRoot, "scripts");
42593
43530
  try {
42594
43531
  const files = await readdir(scriptsDir);
42595
43532
  return files.filter((f) => f.endsWith(".sh")).map((f) => f.replace(".sh", "")).sort();
@@ -42598,7 +43535,7 @@ async function getScriptNames(projectRoot) {
42598
43535
  }
42599
43536
  }
42600
43537
  async function getIndexedCommands(projectRoot) {
42601
- const indexPath = join18(projectRoot, "docs", "commands", "COMMANDS-INDEX.json");
43538
+ const indexPath = join20(projectRoot, "docs", "commands", "COMMANDS-INDEX.json");
42602
43539
  const index = await readJson(indexPath);
42603
43540
  if (!index) return [];
42604
43541
  return index.commands.map((c) => c.name).sort();
@@ -42631,7 +43568,7 @@ async function runGapCheck(_projectRoot, filterId) {
42631
43568
  const reviewFiles = files.filter((f) => f.endsWith(".md"));
42632
43569
  for (const file of reviewFiles) {
42633
43570
  if (filterId && !file.includes(filterId)) continue;
42634
- const filePath = join18(reviewDir, file);
43571
+ const filePath = join20(reviewDir, file);
42635
43572
  const content = await readFile3(filePath, "utf-8");
42636
43573
  const taskMatch = file.match(/^(T\d+)/);
42637
43574
  const taskId = taskMatch ? taskMatch[1] : "UNKNOWN";
@@ -42650,7 +43587,32 @@ async function runGapCheck(_projectRoot, filterId) {
42650
43587
  }
42651
43588
  return results;
42652
43589
  }
42653
- var addCommand4, listCommand7, fetchCommand, removeCommand2, generateCommand, exportCommand4, searchCommand, mergeCommand, graphCommand, rankCommand, versionsCommand, publishCommand2, publishPrCommand, syncCommand3, statusCommand7, gapCheckCommand, importCommand2, docsCommand;
43590
+ function toWireKind(meta) {
43591
+ return {
43592
+ kind: meta.kind,
43593
+ label: meta.label,
43594
+ description: meta.description,
43595
+ defaultOwnerKind: meta.defaultOwnerKind,
43596
+ publishDir: meta.publishDir,
43597
+ requiresEntityId: meta.requiresEntityId,
43598
+ ...meta.entityIdPattern ? { entityIdPattern: meta.entityIdPattern.source } : {},
43599
+ isExtension: meta.isExtension === true
43600
+ };
43601
+ }
43602
+ function loadCliRegistry(projectRoot) {
43603
+ try {
43604
+ return { registry: DocKindRegistry.load(projectRoot) };
43605
+ } catch (err) {
43606
+ if (err instanceof DocKindConfigError) {
43607
+ return {
43608
+ registry: DocKindRegistry.builtinOnly(),
43609
+ configError: { source: err.source, message: err.message }
43610
+ };
43611
+ }
43612
+ throw err;
43613
+ }
43614
+ }
43615
+ var addCommand5, listCommand7, fetchCommand, removeCommand2, generateCommand, exportCommand4, searchCommand, mergeCommand, graphCommand, rankCommand, versionsCommand, publishCommand2, publishPrCommand, syncCommand3, statusCommand7, gapCheckCommand, importCommand2, schemaCommand, listTypesCommand, docsCommand;
42654
43616
  var init_docs3 = __esm({
42655
43617
  "packages/cleo/src/cli/commands/docs.ts"() {
42656
43618
  "use strict";
@@ -42659,7 +43621,7 @@ var init_docs3 = __esm({
42659
43621
  init_cli();
42660
43622
  init_renderers();
42661
43623
  init_docs_viewer();
42662
- addCommand4 = defineCommand({
43624
+ addCommand5 = defineCommand({
42663
43625
  meta: {
42664
43626
  name: "add",
42665
43627
  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)."
@@ -42697,7 +43659,7 @@ var init_docs3 = __esm({
42697
43659
  },
42698
43660
  type: {
42699
43661
  type: "string",
42700
- description: "Taxonomy classification: spec|adr|research|handoff|note|llm-readme (T9637)"
43662
+ description: "Taxonomy classification \u2014 run `cleo docs list-types` to enumerate registered kinds (T9637 / T9788)"
42701
43663
  }
42702
43664
  },
42703
43665
  async run({ args }) {
@@ -42732,7 +43694,7 @@ var init_docs3 = __esm({
42732
43694
  listCommand7 = defineCommand({
42733
43695
  meta: {
42734
43696
  name: "list",
42735
- description: "List attachments. Provide exactly one of --task, --session, --observation, or --project. --type filters across any scope (T9637/T9638)."
43697
+ description: "List attachments. With no scope flag, defaults to project scope and surfaces a hint to narrow with --task, --session, or --observation. --type filters across any scope (T9637/T9638). --limit <N> (default 50) and --orderBy <newest|sha|slug> (default newest) control the browsing window (T9792)."
42736
43698
  },
42737
43699
  args: {
42738
43700
  task: {
@@ -42749,11 +43711,19 @@ var init_docs3 = __esm({
42749
43711
  },
42750
43712
  project: {
42751
43713
  type: "boolean",
42752
- description: "List ALL attachments in the project (T9638). Mutually exclusive with --task/--session/--observation."
43714
+ description: "List ALL attachments in the project (T9638). Mutually exclusive with --task/--session/--observation. Implicit default when no scope is set (T9792)."
42753
43715
  },
42754
43716
  type: {
42755
43717
  type: "string",
42756
43718
  description: "Filter by classification: spec|adr|research|handoff|note|llm-readme (T9637)"
43719
+ },
43720
+ limit: {
43721
+ type: "string",
43722
+ description: "Maximum number of rows to return (default 50, <=0 for unlimited). When the limit truncates the result set the response carries a hint + totalCount (T9792)."
43723
+ },
43724
+ orderBy: {
43725
+ type: "string",
43726
+ description: "Sort key: newest (default \u2014 most recent first), sha (ascending hex), slug (alphabetical, slug-less rows last) (T9792)."
42757
43727
  }
42758
43728
  },
42759
43729
  async run({ args }) {
@@ -42762,19 +43732,37 @@ var init_docs3 = __esm({
42762
43732
  const observation = args.observation ?? void 0;
42763
43733
  const project = args.project === true;
42764
43734
  const type2 = args.type ?? void 0;
42765
- const scopeCount = [task, session, observation].filter(Boolean).length + (project ? 1 : 0);
42766
- if (scopeCount === 0) {
42767
- cliError("provide one of --task <id>, --session <id>, --observation <id>, or --project", 6, {
42768
- name: "E_VALIDATION"
42769
- });
42770
- process.exit(6);
42771
- }
42772
- if (scopeCount > 1) {
43735
+ const limitRaw = args.limit ?? void 0;
43736
+ const orderByRaw = args.orderBy ?? void 0;
43737
+ const ownerCount = [task, session, observation].filter(Boolean).length;
43738
+ if (ownerCount + (project ? 1 : 0) > 1) {
42773
43739
  cliError("--task, --session, --observation, and --project are mutually exclusive", 6, {
42774
43740
  name: "E_VALIDATION"
42775
43741
  });
42776
43742
  process.exit(6);
42777
43743
  }
43744
+ let limit;
43745
+ if (limitRaw !== void 0) {
43746
+ const parsed = Number.parseInt(String(limitRaw), 10);
43747
+ if (Number.isNaN(parsed)) {
43748
+ cliError(`--limit must be an integer \u2014 got '${String(limitRaw)}'`, 6, {
43749
+ name: "E_VALIDATION"
43750
+ });
43751
+ process.exit(6);
43752
+ }
43753
+ limit = parsed;
43754
+ }
43755
+ let orderBy;
43756
+ if (orderByRaw !== void 0) {
43757
+ const candidate = String(orderByRaw);
43758
+ if (candidate !== "newest" && candidate !== "sha" && candidate !== "slug") {
43759
+ cliError(`--orderBy must be one of: newest|sha|slug \u2014 got '${candidate}'`, 6, {
43760
+ name: "E_VALIDATION"
43761
+ });
43762
+ process.exit(6);
43763
+ }
43764
+ orderBy = candidate;
43765
+ }
42778
43766
  await dispatchFromCli(
42779
43767
  "query",
42780
43768
  "docs",
@@ -42784,7 +43772,9 @@ var init_docs3 = __esm({
42784
43772
  ...session ? { session } : {},
42785
43773
  ...observation ? { observation } : {},
42786
43774
  ...project ? { project: true } : {},
42787
- ...type2 ? { type: type2 } : {}
43775
+ ...type2 ? { type: type2 } : {},
43776
+ ...limit !== void 0 ? { limit } : {},
43777
+ ...orderBy !== void 0 ? { orderBy } : {}
42788
43778
  },
42789
43779
  { command: "docs list" }
42790
43780
  );
@@ -42906,7 +43896,7 @@ var init_docs3 = __esm({
42906
43896
  const taskId = String(args.task);
42907
43897
  const includeAttachments = args["include-attachments"] !== false;
42908
43898
  const includeMemoryRefs = args["include-memory-refs"] === true;
42909
- const projectRoot = getProjectRoot29();
43899
+ const projectRoot = getProjectRoot30();
42910
43900
  try {
42911
43901
  const result = await exportDocument({
42912
43902
  taskId,
@@ -42936,10 +43926,9 @@ var init_docs3 = __esm({
42936
43926
  }
42937
43927
  } catch (err) {
42938
43928
  const message = err instanceof Error ? err.message : String(err);
42939
- cliOutput(
42940
- formatError5(new CleoError3(1 /* GENERAL_ERROR */, `docs export failed: ${message}`)),
42941
- { command: "docs export", operation: "docs.export" }
42942
- );
43929
+ cliError(`docs export failed: ${message}`, 1 /* GENERAL_ERROR */, {
43930
+ name: "E_DOCS_EXPORT_FAILED"
43931
+ });
42943
43932
  process.exit(1 /* GENERAL_ERROR */);
42944
43933
  }
42945
43934
  }
@@ -42973,7 +43962,7 @@ var init_docs3 = __esm({
42973
43962
  }
42974
43963
  },
42975
43964
  async run({ args }) {
42976
- const projectRoot = getProjectRoot29();
43965
+ const projectRoot = getProjectRoot30();
42977
43966
  const limit = args.limit ? Number.parseInt(String(args.limit), 10) : 10;
42978
43967
  try {
42979
43968
  const result = args.owner ? await searchDocs2(String(args.query), {
@@ -42988,10 +43977,9 @@ var init_docs3 = __esm({
42988
43977
  cliOutput(result, { command: "docs search", operation: "docs.search" });
42989
43978
  } catch (err) {
42990
43979
  const message = err instanceof Error ? err.message : String(err);
42991
- cliOutput(
42992
- formatError5(new CleoError3(1 /* GENERAL_ERROR */, `docs search failed: ${message}`)),
42993
- { command: "docs search", operation: "docs.search" }
42994
- );
43980
+ cliError(`docs search failed: ${message}`, 1 /* GENERAL_ERROR */, {
43981
+ name: "E_DOCS_SEARCH_FAILED"
43982
+ });
42995
43983
  process.exit(1 /* GENERAL_ERROR */);
42996
43984
  }
42997
43985
  }
@@ -43030,7 +44018,7 @@ var init_docs3 = __esm({
43030
44018
  }
43031
44019
  },
43032
44020
  async run({ args }) {
43033
- const projectRoot = getProjectRoot29();
44021
+ const projectRoot = getProjectRoot30();
43034
44022
  const rawStrategy = args.strategy ?? "three-way";
43035
44023
  const strategy = rawStrategy === "cherry-pick" || rawStrategy === "multi-diff" ? rawStrategy : "three-way";
43036
44024
  try {
@@ -43047,10 +44035,9 @@ var init_docs3 = __esm({
43047
44035
  cliOutput(result, { command: "docs merge", operation: "docs.merge" });
43048
44036
  } catch (err) {
43049
44037
  const message = err instanceof Error ? err.message : String(err);
43050
- cliOutput(
43051
- formatError5(new CleoError3(1 /* GENERAL_ERROR */, `docs merge failed: ${message}`)),
43052
- { command: "docs merge", operation: "docs.merge" }
43053
- );
44038
+ cliError(`docs merge failed: ${message}`, 1 /* GENERAL_ERROR */, {
44039
+ name: "E_DOCS_MERGE_FAILED"
44040
+ });
43054
44041
  process.exit(1 /* GENERAL_ERROR */);
43055
44042
  }
43056
44043
  }
@@ -43080,7 +44067,7 @@ var init_docs3 = __esm({
43080
44067
  }
43081
44068
  },
43082
44069
  async run({ args }) {
43083
- const projectRoot = getProjectRoot29();
44070
+ const projectRoot = getProjectRoot30();
43084
44071
  const fmt = args.format ?? "mermaid";
43085
44072
  try {
43086
44073
  const result = await buildDocsGraph({ ownerId: String(args.for), projectRoot });
@@ -43121,10 +44108,9 @@ var init_docs3 = __esm({
43121
44108
  );
43122
44109
  } catch (err) {
43123
44110
  const message = err instanceof Error ? err.message : String(err);
43124
- cliOutput(
43125
- formatError5(new CleoError3(1 /* GENERAL_ERROR */, `docs graph failed: ${message}`)),
43126
- { command: "docs graph", operation: "docs.graph" }
43127
- );
44111
+ cliError(`docs graph failed: ${message}`, 1 /* GENERAL_ERROR */, {
44112
+ name: "E_DOCS_GRAPH_FAILED"
44113
+ });
43128
44114
  process.exit(1 /* GENERAL_ERROR */);
43129
44115
  }
43130
44116
  }
@@ -43150,7 +44136,7 @@ var init_docs3 = __esm({
43150
44136
  }
43151
44137
  },
43152
44138
  async run({ args }) {
43153
- const projectRoot = getProjectRoot29();
44139
+ const projectRoot = getProjectRoot30();
43154
44140
  try {
43155
44141
  const result = await rankDocs({
43156
44142
  ownerId: String(args.for),
@@ -43160,10 +44146,9 @@ var init_docs3 = __esm({
43160
44146
  cliOutput(result, { command: "docs rank", operation: "docs.rank" });
43161
44147
  } catch (err) {
43162
44148
  const message = err instanceof Error ? err.message : String(err);
43163
- cliOutput(
43164
- formatError5(new CleoError3(1 /* GENERAL_ERROR */, `docs rank failed: ${message}`)),
43165
- { command: "docs rank", operation: "docs.rank" }
43166
- );
44149
+ cliError(`docs rank failed: ${message}`, 1 /* GENERAL_ERROR */, {
44150
+ name: "E_DOCS_RANK_FAILED"
44151
+ });
43167
44152
  process.exit(1 /* GENERAL_ERROR */);
43168
44153
  }
43169
44154
  }
@@ -43189,7 +44174,7 @@ var init_docs3 = __esm({
43189
44174
  }
43190
44175
  },
43191
44176
  async run({ args }) {
43192
- const projectRoot = getProjectRoot29();
44177
+ const projectRoot = getProjectRoot30();
43193
44178
  try {
43194
44179
  const result = await listDocVersions({
43195
44180
  ownerId: String(args.for),
@@ -43199,10 +44184,9 @@ var init_docs3 = __esm({
43199
44184
  cliOutput(result, { command: "docs versions", operation: "docs.versions" });
43200
44185
  } catch (err) {
43201
44186
  const message = err instanceof Error ? err.message : String(err);
43202
- cliOutput(
43203
- formatError5(new CleoError3(1 /* GENERAL_ERROR */, `docs versions failed: ${message}`)),
43204
- { command: "docs versions", operation: "docs.versions" }
43205
- );
44187
+ cliError(`docs versions failed: ${message}`, 1 /* GENERAL_ERROR */, {
44188
+ name: "E_DOCS_VERSIONS_FAILED"
44189
+ });
43206
44190
  process.exit(1 /* GENERAL_ERROR */);
43207
44191
  }
43208
44192
  }
@@ -43233,7 +44217,7 @@ var init_docs3 = __esm({
43233
44217
  }
43234
44218
  },
43235
44219
  async run({ args }) {
43236
- const projectRoot = getProjectRoot29();
44220
+ const projectRoot = getProjectRoot30();
43237
44221
  try {
43238
44222
  const result = await publishDocs({
43239
44223
  ownerId: String(args.for),
@@ -43357,7 +44341,7 @@ var init_docs3 = __esm({
43357
44341
  },
43358
44342
  async run({ args }) {
43359
44343
  if (args.from) {
43360
- const projectRoot = getProjectRoot29();
44344
+ const projectRoot = getProjectRoot30();
43361
44345
  const ownerId = args.for ?? void 0;
43362
44346
  if (!ownerId) {
43363
44347
  cliError(
@@ -43405,7 +44389,7 @@ var init_docs3 = __esm({
43405
44389
  }
43406
44390
  } catch (err) {
43407
44391
  if (err instanceof CleoError3) {
43408
- cliError(formatError5(err), err.code, { name: "E_DOCS_FAILED" });
44392
+ cliError(err.message, err.code, { name: "E_DOCS_SYNC_FAILED" });
43409
44393
  process.exit(err.code);
43410
44394
  }
43411
44395
  throw err;
@@ -43424,7 +44408,7 @@ var init_docs3 = __esm({
43424
44408
  }
43425
44409
  },
43426
44410
  async run() {
43427
- const projectRoot = getProjectRoot29();
44411
+ const projectRoot = getProjectRoot30();
43428
44412
  try {
43429
44413
  const result = await statusDocs({ projectRoot });
43430
44414
  cliOutput(result, { command: "docs status", operation: "docs.status" });
@@ -43473,7 +44457,7 @@ var init_docs3 = __esm({
43473
44457
  }
43474
44458
  } catch (err) {
43475
44459
  if (err instanceof CleoError3) {
43476
- cliError(formatError5(err), err.code, { name: "E_DOCS_FAILED" });
44460
+ cliError(err.message, err.code, { name: "E_DOCS_GAP_CHECK_FAILED" });
43477
44461
  process.exit(err.code);
43478
44462
  }
43479
44463
  throw err;
@@ -43509,7 +44493,7 @@ var init_docs3 = __esm({
43509
44493
  }
43510
44494
  },
43511
44495
  async run({ args }) {
43512
- const projectRoot = getProjectRoot29();
44496
+ const projectRoot = getProjectRoot30();
43513
44497
  const dirArg = String(args.dir);
43514
44498
  const scanRoot = isAbsolute2(dirArg) ? dirArg : resolve6(projectRoot, dirArg);
43515
44499
  const dryRun = args["dry-run"] === true;
@@ -43523,16 +44507,17 @@ var init_docs3 = __esm({
43523
44507
  })}
43524
44508
  `;
43525
44509
  try {
43526
- await mkdir2(join18(projectRoot, ".cleo", "audit"), { recursive: true });
44510
+ await mkdir2(join20(projectRoot, ".cleo", "audit"), { recursive: true });
43527
44511
  await appendFile(
43528
- join18(projectRoot, ".cleo", "audit", "import-force-bypass.jsonl"),
44512
+ join20(projectRoot, ".cleo", "audit", "import-force-bypass.jsonl"),
43529
44513
  auditLine,
43530
44514
  "utf-8"
43531
44515
  );
43532
44516
  } catch {
43533
44517
  }
43534
44518
  }
43535
- const accessor = createDocsAccessor(projectRoot);
44519
+ const accessor = createAttachmentStoreDocsAccessor(projectRoot);
44520
+ const classify = makeClassifierForScanRoot(scanRoot, projectRoot);
43536
44521
  try {
43537
44522
  const result = await runDocsImport({
43538
44523
  root: scanRoot,
@@ -43540,7 +44525,8 @@ var init_docs3 = __esm({
43540
44525
  dryRun,
43541
44526
  force,
43542
44527
  manifestPath,
43543
- auditDir: projectRoot
44528
+ auditDir: projectRoot,
44529
+ classify
43544
44530
  });
43545
44531
  cliOutput(
43546
44532
  {
@@ -43569,13 +44555,110 @@ var init_docs3 = __esm({
43569
44555
  }
43570
44556
  }
43571
44557
  });
44558
+ schemaCommand = defineCommand({
44559
+ meta: {
44560
+ name: "schema",
44561
+ description: "Emit the canonical doc-kind taxonomy registry (built-ins + project extensions) as a LAFS envelope. The schema is the single source of truth for the --type values accepted by `cleo docs add` and the publish-dir layout used by `cleo docs publish-pr`. See `cleo docs list-types` for the human-readable form (T9788)."
44562
+ },
44563
+ args: {
44564
+ "include-counts": {
44565
+ type: "boolean",
44566
+ description: "Include per-kind attachment counts from the project SSoT"
44567
+ }
44568
+ },
44569
+ async run({ args }) {
44570
+ const projectRoot = getProjectRoot30();
44571
+ const { registry, configError } = loadCliRegistry(projectRoot);
44572
+ const kinds = registry.list().map(toWireKind);
44573
+ const extensionsCount = kinds.filter((k) => k.isExtension).length;
44574
+ let counts2;
44575
+ if (args["include-counts"]) {
44576
+ counts2 = {};
44577
+ const { createAttachmentStore: createAttachmentStore3 } = await import("@cleocode/core/internal");
44578
+ const store = createAttachmentStore3();
44579
+ for (const k of kinds) counts2[k.kind] = 0;
44580
+ try {
44581
+ const rows = await store.listAllInProject(projectRoot);
44582
+ for (const row of rows) {
44583
+ const key = row.type;
44584
+ if (key && key in counts2) counts2[key] = (counts2[key] ?? 0) + 1;
44585
+ }
44586
+ } catch {
44587
+ }
44588
+ }
44589
+ cliOutput(
44590
+ {
44591
+ version: 1,
44592
+ builtinsCount: kinds.length - extensionsCount,
44593
+ extensionsCount,
44594
+ kinds,
44595
+ ...counts2 ? { counts: counts2 } : {},
44596
+ ...configError ? { configError } : {}
44597
+ },
44598
+ { command: "docs schema", operation: "docs.schema" }
44599
+ );
44600
+ }
44601
+ });
44602
+ listTypesCommand = defineCommand({
44603
+ meta: {
44604
+ name: "list-types",
44605
+ description: "List every registered doc kind with its label, publish directory, and slug-pattern requirement. Use --counts to include per-kind attachment counts from the project SSoT (T9788)."
44606
+ },
44607
+ args: {
44608
+ counts: {
44609
+ type: "boolean",
44610
+ description: "Include per-kind attachment counts from the project SSoT"
44611
+ }
44612
+ },
44613
+ async run({ args }) {
44614
+ const projectRoot = getProjectRoot30();
44615
+ const { registry, configError } = loadCliRegistry(projectRoot);
44616
+ const kinds = registry.list().map(toWireKind);
44617
+ let counts2;
44618
+ if (args.counts) {
44619
+ counts2 = {};
44620
+ const { createAttachmentStore: createAttachmentStore3 } = await import("@cleocode/core/internal");
44621
+ const store = createAttachmentStore3();
44622
+ for (const k of kinds) counts2[k.kind] = 0;
44623
+ try {
44624
+ const rows2 = await store.listAllInProject(projectRoot);
44625
+ for (const row of rows2) {
44626
+ const key = row.type;
44627
+ if (key && key in counts2) counts2[key] = (counts2[key] ?? 0) + 1;
44628
+ }
44629
+ } catch {
44630
+ }
44631
+ }
44632
+ const rows = kinds.map((k) => ({
44633
+ kind: k.kind,
44634
+ label: k.label,
44635
+ ...counts2 ? { count: counts2[k.kind] ?? 0 } : {},
44636
+ requiresEntityId: k.requiresEntityId,
44637
+ publishDir: k.publishDir,
44638
+ isExtension: k.isExtension
44639
+ }));
44640
+ cliOutput(
44641
+ {
44642
+ version: 1,
44643
+ total: rows.length,
44644
+ rows,
44645
+ ...configError ? { configError } : {}
44646
+ },
44647
+ {
44648
+ command: "docs list-types",
44649
+ operation: "docs.list-types",
44650
+ message: configError ? `loaded built-ins only \u2014 ${configError.message}` : void 0
44651
+ }
44652
+ );
44653
+ }
44654
+ });
43572
44655
  docsCommand = defineCommand({
43573
44656
  meta: {
43574
44657
  name: "docs",
43575
44658
  description: "Documentation attachment management (add/list/fetch/remove), llmtxt primitives (search/merge/graph/rank/versions/publish), PR publishing (publish-pr), drift detection (sync/status/gap-check), legacy .md migration (import), and a local web viewer (serve/open/stop/viewer-status)"
43576
44659
  },
43577
44660
  subCommands: {
43578
- add: addCommand4,
44661
+ add: addCommand5,
43579
44662
  list: listCommand7,
43580
44663
  fetch: fetchCommand,
43581
44664
  remove: removeCommand2,
@@ -43592,6 +44675,9 @@ var init_docs3 = __esm({
43592
44675
  status: statusCommand7,
43593
44676
  "gap-check": gapCheckCommand,
43594
44677
  import: importCommand2,
44678
+ // T9788 — canonical doc-kind taxonomy discovery surface.
44679
+ schema: schemaCommand,
44680
+ "list-types": listTypesCommand,
43595
44681
  ...docsViewerSubcommands
43596
44682
  },
43597
44683
  async run({ cmd, rawArgs }) {
@@ -43877,9 +44963,9 @@ __export(migrate_agents_v2_exports, {
43877
44963
  walkAgentsDir: () => walkAgentsDir
43878
44964
  });
43879
44965
  import { createHash as createHash2 } from "node:crypto";
43880
- import { appendFileSync as appendFileSync2, existsSync as existsSync12, mkdirSync as mkdirSync3, readdirSync as readdirSync2, readFileSync as readFileSync12 } from "node:fs";
43881
- import { join as join19 } from "node:path";
43882
- import { getProjectRoot as getProjectRoot30, installAgentFromCant } from "@cleocode/core/internal";
44966
+ import { appendFileSync as appendFileSync2, existsSync as existsSync13, mkdirSync as mkdirSync3, readdirSync as readdirSync2, readFileSync as readFileSync14 } from "node:fs";
44967
+ import { join as join21 } from "node:path";
44968
+ import { getProjectRoot as getProjectRoot31, installAgentFromCant } from "@cleocode/core/internal";
43883
44969
  import { openCleoDb } from "@cleocode/core/store/open-cleo-db";
43884
44970
  function sha256Hex(bytes) {
43885
44971
  return createHash2("sha256").update(bytes).digest("hex");
@@ -43898,15 +44984,15 @@ function extractAgentName(source) {
43898
44984
  return headerMatch[1] ?? null;
43899
44985
  }
43900
44986
  function appendAuditLog(projectRoot, entry) {
43901
- const auditPath = join19(projectRoot, AUDIT_LOG_RELATIVE);
43902
- const auditDir = join19(auditPath, "..");
43903
- if (!existsSync12(auditDir)) {
44987
+ const auditPath = join21(projectRoot, AUDIT_LOG_RELATIVE);
44988
+ const auditDir = join21(auditPath, "..");
44989
+ if (!existsSync13(auditDir)) {
43904
44990
  mkdirSync3(auditDir, { recursive: true });
43905
44991
  }
43906
44992
  appendFileSync2(auditPath, JSON.stringify(entry) + "\n", "utf8");
43907
44993
  }
43908
44994
  function walkAgentsDir(db, scanDir, projectRoot, summary, verbose) {
43909
- if (!existsSync12(scanDir)) return;
44995
+ if (!existsSync13(scanDir)) return;
43910
44996
  let files;
43911
44997
  try {
43912
44998
  files = readdirSync2(scanDir).filter((f) => f.endsWith(".cant"));
@@ -43917,12 +45003,12 @@ function walkAgentsDir(db, scanDir, projectRoot, summary, verbose) {
43917
45003
  return;
43918
45004
  }
43919
45005
  for (const filename of files) {
43920
- const cantPath = join19(scanDir, filename);
45006
+ const cantPath = join21(scanDir, filename);
43921
45007
  const relPath = cantPath.replace(`${projectRoot}/`, "");
43922
45008
  let sourceBytes;
43923
45009
  let sourceText;
43924
45010
  try {
43925
- sourceBytes = readFileSync12(cantPath);
45011
+ sourceBytes = readFileSync14(cantPath);
43926
45012
  sourceText = sourceBytes.toString("utf8");
43927
45013
  } catch (err) {
43928
45014
  const msg = err instanceof Error ? err.message : String(err);
@@ -44014,9 +45100,9 @@ async function runMigrateAgentsV2(projectRoot, verbose = true) {
44014
45100
  const { db: _sdDb } = await openCleoDb("signaldock");
44015
45101
  const db = _sdDb;
44016
45102
  try {
44017
- const canonicalDir = join19(projectRoot, ".cleo", "cant", "agents");
45103
+ const canonicalDir = join21(projectRoot, ".cleo", "cant", "agents");
44018
45104
  walkAgentsDir(db, canonicalDir, projectRoot, summary, verbose);
44019
- const legacyDir = join19(projectRoot, ".cleo", "agents");
45105
+ const legacyDir = join21(projectRoot, ".cleo", "agents");
44020
45106
  walkAgentsDir(db, legacyDir, projectRoot, summary, verbose);
44021
45107
  } finally {
44022
45108
  db.close();
@@ -44024,11 +45110,11 @@ async function runMigrateAgentsV2(projectRoot, verbose = true) {
44024
45110
  return summary;
44025
45111
  }
44026
45112
  function readMigrationConflicts(projectRoot) {
44027
- const auditPath = join19(projectRoot, AUDIT_LOG_RELATIVE);
44028
- if (!existsSync12(auditPath)) return [];
45113
+ const auditPath = join21(projectRoot, AUDIT_LOG_RELATIVE);
45114
+ if (!existsSync13(auditPath)) return [];
44029
45115
  let raw;
44030
45116
  try {
44031
- raw = readFileSync12(auditPath, "utf8");
45117
+ raw = readFileSync14(auditPath, "utf8");
44032
45118
  } catch {
44033
45119
  return [];
44034
45120
  }
@@ -44066,7 +45152,7 @@ var init_migrate_agents_v2 = __esm({
44066
45152
  }
44067
45153
  },
44068
45154
  async run({ args }) {
44069
- const projectRoot = getProjectRoot30();
45155
+ const projectRoot = getProjectRoot31();
44070
45156
  const verbose = args.quiet !== true;
44071
45157
  if (verbose) {
44072
45158
  humanInfo("Scanning .cleo/cant/agents/ and .cleo/agents/ for unregistered agents...");
@@ -44109,8 +45195,8 @@ __export(doctor_exports, {
44109
45195
  doctorCommand: () => doctorCommand2
44110
45196
  });
44111
45197
  import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "node:fs";
44112
- import { join as join20 } from "node:path";
44113
- import { getProjectRoot as getProjectRoot31 } from "@cleocode/core";
45198
+ import { join as join22 } from "node:path";
45199
+ import { getProjectRoot as getProjectRoot32 } from "@cleocode/core";
44114
45200
  import {
44115
45201
  quarantineRogueCleoDir,
44116
45202
  scanRogueCleoDirs
@@ -44148,8 +45234,8 @@ async function scanTestFixturesInProd(projectRoot) {
44148
45234
  }
44149
45235
  async function quarantineTestFixtures(projectRoot, matches) {
44150
45236
  if (matches.length === 0) return 0;
44151
- const cleoDir = join20(projectRoot, ".cleo");
44152
- const quarantineDir = join20(
45237
+ const cleoDir = join22(projectRoot, ".cleo");
45238
+ const quarantineDir = join22(
44153
45239
  cleoDir,
44154
45240
  "quarantine",
44155
45241
  `fixture-scan-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}`
@@ -44157,7 +45243,7 @@ async function quarantineTestFixtures(projectRoot, matches) {
44157
45243
  mkdirSync4(quarantineDir, { recursive: true });
44158
45244
  const manifest = matches.map((m) => ({ ...m, quarantinedAt: (/* @__PURE__ */ new Date()).toISOString() }));
44159
45245
  writeFileSync4(
44160
- join20(quarantineDir, "manifest.jsonl"),
45246
+ join22(quarantineDir, "manifest.jsonl"),
44161
45247
  manifest.map((m) => JSON.stringify(m)).join("\n") + "\n"
44162
45248
  );
44163
45249
  const { getNativeDb } = await import("@cleocode/core/store/sqlite.js");
@@ -44279,6 +45365,23 @@ var init_doctor = __esm({
44279
45365
  type: "boolean",
44280
45366
  description: "Audit orphaned agent worktree directories and report what cleo gc --worktrees would remove (T9043)"
44281
45367
  },
45368
+ /**
45369
+ * T9790: list orphan `.cleo/` directories under
45370
+ * `<projectRoot>/.claude/worktrees/` with full provenance. Read-only.
45371
+ */
45372
+ "audit-worktree-orphans": {
45373
+ type: "boolean",
45374
+ description: "List orphan .cleo/ directories under .claude/worktrees/ (T9790, fallout from T9550/T9580)"
45375
+ },
45376
+ /**
45377
+ * T9790: archive then remove every orphan reported by
45378
+ * `--audit-worktree-orphans`. Combine with `--dry-run` to preview
45379
+ * without touching the filesystem.
45380
+ */
45381
+ "prune-worktree-orphans": {
45382
+ type: "boolean",
45383
+ description: "Archive then remove orphan .cleo/ directories under .claude/worktrees/ (T9790)"
45384
+ },
44282
45385
  "audit-temp": {
44283
45386
  type: "boolean",
44284
45387
  description: "Audit orphaned CLEO-generated temp directories and report what cleo gc --temp would remove (T9043)"
@@ -44336,7 +45439,7 @@ var init_doctor = __esm({
44336
45439
  try {
44337
45440
  if (args.brain) {
44338
45441
  const { computeBrainHealthDashboard } = await import("@cleocode/core/memory/brain-health-dashboard.js");
44339
- const projectRoot = getProjectRoot31();
45442
+ const projectRoot = getProjectRoot32();
44340
45443
  const dashboard = await computeBrainHealthDashboard(projectRoot);
44341
45444
  cliOutput(dashboard, { command: "doctor", operation: "doctor.brain" });
44342
45445
  if (dashboard.hasP0Failure) {
@@ -44345,7 +45448,7 @@ var init_doctor = __esm({
44345
45448
  return;
44346
45449
  }
44347
45450
  if (args["scan-test-fixtures-in-prod"]) {
44348
- const projectRoot = getProjectRoot31();
45451
+ const projectRoot = getProjectRoot32();
44349
45452
  const matches = await scanTestFixturesInProd(projectRoot);
44350
45453
  const dryRun = args["dry-run"] !== false && args.quarantine !== true;
44351
45454
  const quarantined = !dryRun && matches.length > 0 ? await quarantineTestFixtures(projectRoot, matches) : void 0;
@@ -44433,7 +45536,7 @@ var init_doctor = __esm({
44433
45536
  progress.complete("Comprehensive diagnostics complete");
44434
45537
  } else if (args["scan-rogue-cleo-dirs"]) {
44435
45538
  progress.step(0, "Scanning for rogue .cleo/ directories");
44436
- const projectRoot = getProjectRoot31();
45539
+ const projectRoot = getProjectRoot32();
44437
45540
  const reports = scanRogueCleoDirs(projectRoot);
44438
45541
  progress.complete(
44439
45542
  `Found ${reports.length} rogue .cleo/ director${reports.length === 1 ? "y" : "ies"}`
@@ -44442,7 +45545,7 @@ var init_doctor = __esm({
44442
45545
  } else if (args["quarantine-rogue-cleo-dirs"]) {
44443
45546
  const isDryRun = args["dry-run"] === true;
44444
45547
  progress.step(0, `${isDryRun ? "[DRY RUN] " : ""}Scanning for rogue .cleo/ directories`);
44445
- const projectRoot = getProjectRoot31();
45548
+ const projectRoot = getProjectRoot32();
44446
45549
  const reports = scanRogueCleoDirs(projectRoot);
44447
45550
  if (reports.length === 0) {
44448
45551
  progress.complete("No rogue .cleo/ directories found \u2014 nothing to quarantine");
@@ -44496,7 +45599,7 @@ var init_doctor = __esm({
44496
45599
  const { detectAndRemoveLegacyGlobalFiles, detectAndRemoveStrayProjectNexus } = await import("@cleocode/core/store/cleanup-legacy.js");
44497
45600
  const { getCleoHome: getCleoHome6 } = await import("@cleocode/core");
44498
45601
  const cleoHome = getCleoHome6();
44499
- const projectRoot = getProjectRoot31();
45602
+ const projectRoot = getProjectRoot32();
44500
45603
  const legacyResult = detectAndRemoveLegacyGlobalFiles(cleoHome);
44501
45604
  const strayResult = detectAndRemoveStrayProjectNexus(projectRoot);
44502
45605
  const isDryRun = args["dry-run"] === true;
@@ -44526,6 +45629,62 @@ var init_doctor = __esm({
44526
45629
  if (checkResult.details?.["orphans"] && checkResult.details["orphans"].length > 0 && (process.exitCode === void 0 || process.exitCode === 0)) {
44527
45630
  process.exitCode = 2;
44528
45631
  }
45632
+ } else if (args["audit-worktree-orphans"]) {
45633
+ progress.step(0, "Scanning for worktree-orphan .cleo/ directories");
45634
+ const { scanWorktreeOrphans } = await import("@cleocode/core/doctor/worktree-orphans.js");
45635
+ const projectRoot = getProjectRoot32();
45636
+ const orphans = await scanWorktreeOrphans(projectRoot);
45637
+ progress.complete(`Found ${orphans.length} orphan${orphans.length === 1 ? "" : "s"}`);
45638
+ cliOutput(
45639
+ { projectRoot, orphans, count: orphans.length },
45640
+ { command: "doctor", operation: "doctor.audit-worktree-orphans" }
45641
+ );
45642
+ if (orphans.length > 0 && (process.exitCode === void 0 || process.exitCode === 0)) {
45643
+ process.exitCode = 2;
45644
+ }
45645
+ } else if (args["prune-worktree-orphans"]) {
45646
+ const isDryRun = args["dry-run"] === true;
45647
+ progress.step(
45648
+ 0,
45649
+ `${isDryRun ? "[DRY RUN] " : ""}Scanning + pruning worktree-orphan .cleo/ directories`
45650
+ );
45651
+ const { pruneWorktreeOrphans, scanWorktreeOrphans } = await import("@cleocode/core/doctor/worktree-orphans.js");
45652
+ const projectRoot = getProjectRoot32();
45653
+ const orphans = await scanWorktreeOrphans(projectRoot);
45654
+ if (orphans.length === 0) {
45655
+ progress.complete("No worktree orphans found \u2014 nothing to prune");
45656
+ cliOutput(
45657
+ {
45658
+ projectRoot,
45659
+ dryRun: isDryRun,
45660
+ archivePath: null,
45661
+ pruned: [],
45662
+ rejected: [],
45663
+ totalSizeBytes: 0
45664
+ },
45665
+ { command: "doctor", operation: "doctor.prune-worktree-orphans" }
45666
+ );
45667
+ return;
45668
+ }
45669
+ const archiveDir = join22(projectRoot, ".cleo", "backups");
45670
+ const auditLogPath = join22(projectRoot, ".cleo", "audit", "worktree-prune.jsonl");
45671
+ const result = await pruneWorktreeOrphans(orphans, {
45672
+ archiveDir,
45673
+ auditLogPath,
45674
+ dryRun: isDryRun,
45675
+ projectRoot
45676
+ });
45677
+ const verb = isDryRun ? "Would prune" : "Pruned";
45678
+ progress.complete(
45679
+ `${verb} ${result.pruned.length} orphan${result.pruned.length === 1 ? "" : "s"}${result.rejected.length > 0 ? `, ${result.rejected.length} rejected` : ""}`
45680
+ );
45681
+ cliOutput(
45682
+ { projectRoot, ...result },
45683
+ { command: "doctor", operation: "doctor.prune-worktree-orphans" }
45684
+ );
45685
+ if (result.rejected.length > 0) {
45686
+ process.exitCode = 1;
45687
+ }
44529
45688
  } else if (args["audit-temp"]) {
44530
45689
  progress.step(0, "Auditing orphaned CLEO temp directories");
44531
45690
  const { auditOrphanTempDirs } = await import("@cleocode/core/gc/index.js");
@@ -44545,7 +45704,7 @@ var init_doctor = __esm({
44545
45704
  { command: "doctor", operation: "admin.health" }
44546
45705
  );
44547
45706
  try {
44548
- const projectRoot = getProjectRoot31();
45707
+ const projectRoot = getProjectRoot32();
44549
45708
  const conflicts = readMigrationConflicts(projectRoot);
44550
45709
  if (conflicts.length > 0) {
44551
45710
  progress.complete(
@@ -44610,7 +45769,7 @@ __export(event_exports, {
44610
45769
  orchestratorCommand: () => orchestratorCommand
44611
45770
  });
44612
45771
  import { readdir as readdir2 } from "node:fs/promises";
44613
- import { join as join21 } from "node:path";
45772
+ import { join as join23 } from "node:path";
44614
45773
  import { cwd as processCwd } from "node:process";
44615
45774
  import { appendEvent } from "@cleocode/core/events/event-bus.js";
44616
45775
  function resolveProjectRoot3(arg) {
@@ -44733,7 +45892,7 @@ var init_event = __esm({
44733
45892
  const agentIdFilter = args.agent;
44734
45893
  const showAll = args.all === true;
44735
45894
  const lines = parseInt(args.lines ?? "20", 10);
44736
- const eventsDir = join21(projectRoot, ".cleo", "agent-events");
45895
+ const eventsDir = join23(projectRoot, ".cleo", "agent-events");
44737
45896
  try {
44738
45897
  let files = [];
44739
45898
  try {
@@ -44770,8 +45929,8 @@ var init_event = __esm({
44770
45929
  }
44771
45930
  for (const file of filesToTail) {
44772
45931
  const agentId = file.replace(".jsonl", "");
44773
- const { readFileSync: readFileSync18 } = await import("node:fs");
44774
- const content = readFileSync18(join21(eventsDir, file), "utf-8");
45932
+ const { readFileSync: readFileSync20 } = await import("node:fs");
45933
+ const content = readFileSync20(join23(eventsDir, file), "utf-8");
44775
45934
  const eventLines = content.trim().split("\n").filter(Boolean);
44776
45935
  const tail = eventLines.slice(-lines);
44777
45936
  if (jsonMode) {
@@ -44841,7 +46000,7 @@ var init_event = __esm({
44841
46000
  const epicFilter = args.epic;
44842
46001
  const follow = args.follow === true;
44843
46002
  const lines = parseInt(args.lines ?? "50", 10);
44844
- const eventsDir = join21(projectRoot, ".cleo", "agent-events");
46003
+ const eventsDir = join23(projectRoot, ".cleo", "agent-events");
44845
46004
  let files = [];
44846
46005
  try {
44847
46006
  const entries = await readdir2(eventsDir);
@@ -44866,8 +46025,8 @@ var init_event = __esm({
44866
46025
  const printAgentLog = async (file) => {
44867
46026
  const agentId = file.replace(".jsonl", "");
44868
46027
  try {
44869
- const { readFileSync: readFileSync18 } = await import("node:fs");
44870
- const content = readFileSync18(join21(eventsDir, file), "utf-8");
46028
+ const { readFileSync: readFileSync20 } = await import("node:fs");
46029
+ const content = readFileSync20(join23(eventsDir, file), "utf-8");
44871
46030
  const eventLines = content.trim().split("\n").filter(Boolean);
44872
46031
  const tail = eventLines.slice(-lines);
44873
46032
  if (jsonMode) {
@@ -45160,7 +46319,7 @@ __export(federation_exports, {
45160
46319
  federationCommand: () => federationCommand
45161
46320
  });
45162
46321
  import { skills } from "@cleocode/core";
45163
- var addFederationPeer, listFederationPeers, removeFederationPeer, addCommand5, removeCommand3, listCommand8, federationCommand;
46322
+ var addFederationPeer, listFederationPeers, removeFederationPeer, addCommand6, removeCommand3, listCommand8, federationCommand;
45164
46323
  var init_federation = __esm({
45165
46324
  "packages/cleo/src/cli/commands/federation.ts"() {
45166
46325
  "use strict";
@@ -45168,7 +46327,7 @@ var init_federation = __esm({
45168
46327
  init_dist();
45169
46328
  init_renderers();
45170
46329
  ({ addFederationPeer, listFederationPeers, removeFederationPeer } = skills);
45171
- addCommand5 = defineCommand({
46330
+ addCommand6 = defineCommand({
45172
46331
  meta: {
45173
46332
  name: "add",
45174
46333
  description: "Add (or update) a federation peer in ~/.cleo/federation.json"
@@ -45268,7 +46427,7 @@ var init_federation = __esm({
45268
46427
  description: "Federation peer management: add, remove, list trusted peers"
45269
46428
  },
45270
46429
  subCommands: {
45271
- add: addCommand5,
46430
+ add: addCommand6,
45272
46431
  remove: removeCommand3,
45273
46432
  list: listCommand8
45274
46433
  },
@@ -45370,7 +46529,7 @@ __export(gc_exports, {
45370
46529
  gcCommand: () => gcCommand
45371
46530
  });
45372
46531
  import { homedir as homedir4, tmpdir } from "node:os";
45373
- import { join as join22 } from "node:path";
46532
+ import { join as join24 } from "node:path";
45374
46533
  import { pruneOrphanTempDirs, pruneOrphanWorktrees } from "@cleocode/core/gc/cleanup.js";
45375
46534
  import { runGC } from "@cleocode/core/gc/runner.js";
45376
46535
  import { readGCState } from "@cleocode/core/gc/state.js";
@@ -45453,7 +46612,7 @@ var init_gc = __esm({
45453
46612
  },
45454
46613
  async run({ args }) {
45455
46614
  const cleoDir = resolveLegacyCleoDir3(args["cleo-dir"]);
45456
- const statePath = join22(cleoDir, "gc-state.json");
46615
+ const statePath = join24(cleoDir, "gc-state.json");
45457
46616
  try {
45458
46617
  const state = await readGCState(statePath);
45459
46618
  const diskStr = state.lastDiskUsedPct !== null ? `${state.lastDiskUsedPct.toFixed(1)}%` : "unknown";
@@ -45506,8 +46665,8 @@ var init_gc = __esm({
45506
46665
  }
45507
46666
  },
45508
46667
  async run({ args }) {
45509
- const xdgData = process.env["XDG_DATA_HOME"] ?? join22(homedir4(), ".local", "share");
45510
- const worktreesRoot = args["worktrees-root"] ?? join22(xdgData, "cleo", "worktrees");
46668
+ const xdgData = process.env["XDG_DATA_HOME"] ?? join24(homedir4(), ".local", "share");
46669
+ const worktreesRoot = args["worktrees-root"] ?? join24(xdgData, "cleo", "worktrees");
45511
46670
  const projectHash = args["project-hash"];
45512
46671
  const dryRun = args["dry-run"];
45513
46672
  const preserveRaw = args["preserve-tasks"];
@@ -45617,13 +46776,13 @@ __export(generate_changelog_exports, {
45617
46776
  generateChangelogCommand: () => generateChangelogCommand
45618
46777
  });
45619
46778
  import { execFileSync as execFileSync2 } from "node:child_process";
45620
- import { existsSync as existsSync13, mkdirSync as mkdirSync5, readFileSync as readFileSync13, writeFileSync as writeFileSync5 } from "node:fs";
45621
- import { dirname as dirname10, join as join23 } from "node:path";
45622
- import { CleoError as CleoError4, formatError as formatError6, getConfigPath, getProjectRoot as getProjectRoot32 } from "@cleocode/core";
46779
+ import { existsSync as existsSync14, mkdirSync as mkdirSync5, readFileSync as readFileSync15, writeFileSync as writeFileSync5 } from "node:fs";
46780
+ import { dirname as dirname10, join as join25 } from "node:path";
46781
+ import { CleoError as CleoError4, getConfigPath, getProjectRoot as getProjectRoot33, pushWarning as pushWarning2 } from "@cleocode/core";
45623
46782
  function getChangelogSource(cwd) {
45624
46783
  const configPath = getConfigPath(cwd);
45625
46784
  try {
45626
- const config = JSON.parse(readFileSync13(configPath, "utf-8"));
46785
+ const config = JSON.parse(readFileSync15(configPath, "utf-8"));
45627
46786
  return config?.release?.changelog?.source ?? "CHANGELOG.md";
45628
46787
  } catch {
45629
46788
  return "CHANGELOG.md";
@@ -45632,7 +46791,7 @@ function getChangelogSource(cwd) {
45632
46791
  function getEnabledPlatforms(cwd) {
45633
46792
  const configPath = getConfigPath(cwd);
45634
46793
  try {
45635
- const config = JSON.parse(readFileSync13(configPath, "utf-8"));
46794
+ const config = JSON.parse(readFileSync15(configPath, "utf-8"));
45636
46795
  const outputs = config?.release?.changelog?.outputs ?? [];
45637
46796
  return outputs.filter((o) => o.enabled);
45638
46797
  } catch {
@@ -45650,7 +46809,7 @@ function getDefaultOutputPath(platform) {
45650
46809
  }
45651
46810
  }
45652
46811
  function getGitHubRepoSlug(cwd) {
45653
- const projectRoot = getProjectRoot32(cwd);
46812
+ const projectRoot = getProjectRoot33(cwd);
45654
46813
  try {
45655
46814
  const remoteUrl = execFileSync2("git", ["remote", "get-url", "origin"], {
45656
46815
  cwd: projectRoot,
@@ -45779,15 +46938,28 @@ var init_generate_changelog = __esm({
45779
46938
  },
45780
46939
  async run({ args }) {
45781
46940
  try {
46941
+ pushWarning2({
46942
+ code: "W_DEPRECATED_COMMAND",
46943
+ message: "`cleo generate-changelog` is deprecated. Use `cleo changeset add` (T9793) + the aggregator (T9759 composer) instead.",
46944
+ severity: "warn",
46945
+ deprecated: "cleo generate-changelog",
46946
+ replacement: "cleo changeset add",
46947
+ removeBy: "v2026.6.0",
46948
+ context: {
46949
+ registryId: "generate-changelog-renderer",
46950
+ task: "T9795",
46951
+ saga: "T9787"
46952
+ }
46953
+ });
45782
46954
  const limit = Number(args.limit ?? 15);
45783
46955
  const targetPlatform = args.platform;
45784
46956
  const dryRun = args["dry-run"] === true;
45785
46957
  const sourceFile = getChangelogSource();
45786
- const sourcePath = join23(getProjectRoot32(), sourceFile);
45787
- if (!existsSync13(sourcePath)) {
46958
+ const sourcePath = join25(getProjectRoot33(), sourceFile);
46959
+ if (!existsSync14(sourcePath)) {
45788
46960
  throw new CleoError4(4 /* NOT_FOUND */, `Changelog source not found: ${sourcePath}`);
45789
46961
  }
45790
- const sourceContent = readFileSync13(sourcePath, "utf-8");
46962
+ const sourceContent = readFileSync15(sourcePath, "utf-8");
45791
46963
  const repoSlug = getGitHubRepoSlug();
45792
46964
  const results = [];
45793
46965
  if (targetPlatform) {
@@ -45796,7 +46968,7 @@ var init_generate_changelog = __esm({
45796
46968
  const outputPath = platformConfig?.path ?? getDefaultOutputPath(targetPlatform);
45797
46969
  const content = generateForPlatform(targetPlatform, sourceContent, repoSlug, limit);
45798
46970
  if (!dryRun) {
45799
- const fullPath = join23(getProjectRoot32(), outputPath);
46971
+ const fullPath = join25(getProjectRoot33(), outputPath);
45800
46972
  mkdirSync5(dirname10(fullPath), { recursive: true });
45801
46973
  writeFileSync5(fullPath, content, "utf-8");
45802
46974
  }
@@ -45817,7 +46989,7 @@ var init_generate_changelog = __esm({
45817
46989
  limit
45818
46990
  );
45819
46991
  if (!dryRun) {
45820
- const fullPath = join23(getProjectRoot32(), platformConfig.path);
46992
+ const fullPath = join25(getProjectRoot33(), platformConfig.path);
45821
46993
  mkdirSync5(dirname10(fullPath), { recursive: true });
45822
46994
  writeFileSync5(fullPath, content, "utf-8");
45823
46995
  }
@@ -45839,10 +47011,16 @@ var init_generate_changelog = __esm({
45839
47011
  );
45840
47012
  } catch (err) {
45841
47013
  if (err instanceof CleoError4) {
45842
- cliError(formatError6(err), err.code, { name: "E_INTERNAL" });
47014
+ cliError(`generate-changelog failed: ${err.message}`, err.code, {
47015
+ name: "E_GENERATE_CHANGELOG_FAILED"
47016
+ });
45843
47017
  process.exit(err.code);
45844
47018
  }
45845
- throw err;
47019
+ const message = err instanceof Error ? err.message : String(err);
47020
+ cliError(`generate-changelog failed: ${message}`, 1 /* GENERAL_ERROR */, {
47021
+ name: "E_GENERATE_CHANGELOG_FAILED"
47022
+ });
47023
+ process.exit(1 /* GENERAL_ERROR */);
45846
47024
  }
45847
47025
  }
45848
47026
  });
@@ -46957,24 +48135,24 @@ __export(init_exports, {
46957
48135
  getWorkflowTemplatesDir: () => getWorkflowTemplatesDir,
46958
48136
  initCommand: () => initCommand2
46959
48137
  });
46960
- import { existsSync as existsSync14, readFileSync as readFileSync14 } from "node:fs";
46961
- import { dirname as dirname11, join as join24, resolve as resolve7 } from "node:path";
48138
+ import { existsSync as existsSync15, readFileSync as readFileSync16 } from "node:fs";
48139
+ import { dirname as dirname11, join as join26, resolve as resolve7 } from "node:path";
46962
48140
  import { fileURLToPath as fileURLToPath7 } from "node:url";
46963
48141
  import {
46964
48142
  CleoError as CleoError5,
46965
- formatError as formatError7,
48143
+ formatError as formatError5,
46966
48144
  initProject as initProject2,
46967
48145
  scaffoldWorkflows
46968
48146
  } from "@cleocode/core";
46969
48147
  function getGitignoreTemplate() {
46970
48148
  try {
46971
48149
  const thisFile = fileURLToPath7(import.meta.url);
46972
- const packageRoot = join24(thisFile, "..", "..", "..", "..");
46973
- const localTemplatePath = join24(packageRoot, "templates", "cleo-gitignore");
46974
- const monorepoTemplatePath = join24(packageRoot, "..", "..", "templates", "cleo-gitignore");
46975
- const templatePath = existsSync14(localTemplatePath) ? localTemplatePath : monorepoTemplatePath;
46976
- if (existsSync14(templatePath)) {
46977
- return readFileSync14(templatePath, "utf-8");
48150
+ const packageRoot = join26(thisFile, "..", "..", "..", "..");
48151
+ const localTemplatePath = join26(packageRoot, "templates", "cleo-gitignore");
48152
+ const monorepoTemplatePath = join26(packageRoot, "..", "..", "templates", "cleo-gitignore");
48153
+ const templatePath = existsSync15(localTemplatePath) ? localTemplatePath : monorepoTemplatePath;
48154
+ if (existsSync15(templatePath)) {
48155
+ return readFileSync16(templatePath, "utf-8");
46978
48156
  }
46979
48157
  } catch {
46980
48158
  }
@@ -46983,7 +48161,7 @@ function getGitignoreTemplate() {
46983
48161
  function getWorkflowTemplatesDir() {
46984
48162
  const thisFile = fileURLToPath7(import.meta.url);
46985
48163
  const packageRoot = resolve7(dirname11(thisFile), "..", "..", "..", "..");
46986
- return join24(packageRoot, "templates", "workflows");
48164
+ return join26(packageRoot, "templates", "workflows");
46987
48165
  }
46988
48166
  var initCommand2;
46989
48167
  var init_init = __esm({
@@ -47083,7 +48261,7 @@ var init_init = __esm({
47083
48261
  );
47084
48262
  } catch (err) {
47085
48263
  if (err instanceof CleoError5) {
47086
- cliError(formatError7(err), err.code, { name: "E_INTERNAL" });
48264
+ cliError(formatError5(err), err.code, { name: "E_INTERNAL" });
47087
48265
  process.exit(err.code);
47088
48266
  }
47089
48267
  throw err;
@@ -47898,7 +49076,7 @@ var llm_cost_exports = {};
47898
49076
  __export(llm_cost_exports, {
47899
49077
  costCommand: () => costCommand
47900
49078
  });
47901
- import { getProjectRoot as getProjectRoot33 } from "@cleocode/core/internal";
49079
+ import { getProjectRoot as getProjectRoot34 } from "@cleocode/core/internal";
47902
49080
  import { computeCost } from "@cleocode/core/llm/usage-pricing";
47903
49081
  function resolveSessionId(raw) {
47904
49082
  if (raw === "current") {
@@ -47971,7 +49149,7 @@ var init_llm_cost = __esm({
47971
49149
  process.exit(6);
47972
49150
  }
47973
49151
  const sessionId = resolveSessionId(rawSessionId);
47974
- const projectRoot = getProjectRoot33(process.cwd());
49152
+ const projectRoot = getProjectRoot34(process.cwd());
47975
49153
  let breakdown;
47976
49154
  try {
47977
49155
  breakdown = await loadSessionCostBreakdown(projectRoot, sessionId);
@@ -48612,7 +49790,7 @@ var llm_exports = {};
48612
49790
  __export(llm_exports, {
48613
49791
  llmCommand: () => llmCommand
48614
49792
  });
48615
- import { pushWarning as pushWarning2 } from "@cleocode/core";
49793
+ import { pushWarning as pushWarning3 } from "@cleocode/core";
48616
49794
  async function getListProviders() {
48617
49795
  const { listProviders } = await import(
48618
49796
  /* webpackIgnore: true */
@@ -48646,7 +49824,7 @@ function makeLlmSubcommand(opts) {
48646
49824
  }
48647
49825
  });
48648
49826
  }
48649
- var API_KEY_FLAG_DEPRECATION, addCommand6, listCommand11, removeCommand4, useCommand, profileCommand, testCommand, whoamiCommand, listProvidersCommand, contextEnginesListCommand, contextEnginesCommand, loginCommand, refreshCatalogCommand, llmCommand;
49827
+ var API_KEY_FLAG_DEPRECATION, addCommand7, listCommand11, removeCommand4, useCommand, profileCommand, testCommand, whoamiCommand, listProvidersCommand, contextEnginesListCommand, contextEnginesCommand, loginCommand, refreshCatalogCommand, llmCommand;
48650
49828
  var init_llm3 = __esm({
48651
49829
  "packages/cleo/src/cli/commands/llm.ts"() {
48652
49830
  "use strict";
@@ -48658,7 +49836,7 @@ var init_llm3 = __esm({
48658
49836
  init_llm_refresh_catalog();
48659
49837
  init_llm_stream();
48660
49838
  API_KEY_FLAG_DEPRECATION = "[warning] --api-key exposes the secret to 'ps' listings and shell history. Prefer --api-key-stdin or --api-key-env=NAME for production use.";
48661
- addCommand6 = defineCommand({
49839
+ addCommand7 = defineCommand({
48662
49840
  meta: {
48663
49841
  name: "add",
48664
49842
  // Help text lists --api-key-stdin first (recommended path) and
@@ -48743,7 +49921,7 @@ var init_llm3 = __esm({
48743
49921
  apiKey = envValue;
48744
49922
  source = "env";
48745
49923
  } else if (typeof a["api-key"] === "string" && a["api-key"]) {
48746
- pushWarning2({
49924
+ pushWarning3({
48747
49925
  code: "W_DEPRECATED_FLAG",
48748
49926
  message: API_KEY_FLAG_DEPRECATION,
48749
49927
  deprecated: "--api-key=<value>",
@@ -49071,7 +50249,7 @@ var init_llm3 = __esm({
49071
50249
  description: "Manage LLM credentials, role profiles, and resolver diagnostics"
49072
50250
  },
49073
50251
  subCommands: {
49074
- add: addCommand6,
50252
+ add: addCommand7,
49075
50253
  "context-engines": contextEnginesCommand,
49076
50254
  cost: costCommand,
49077
50255
  list: listCommand11,
@@ -49519,10 +50697,10 @@ __export(memory_exports, {
49519
50697
  memoryCommand: () => memoryCommand
49520
50698
  });
49521
50699
  import { createHash as createHash3 } from "node:crypto";
49522
- import { existsSync as existsSync15, mkdirSync as mkdirSync6, readdirSync as readdirSync3, readFileSync as readFileSync15, writeFileSync as writeFileSync6 } from "node:fs";
50700
+ import { existsSync as existsSync16, mkdirSync as mkdirSync6, readdirSync as readdirSync3, readFileSync as readFileSync17, writeFileSync as writeFileSync6 } from "node:fs";
49523
50701
  import { homedir as homedir5 } from "node:os";
49524
- import { join as join25 } from "node:path";
49525
- import { getProjectRoot as getProjectRoot34 } from "@cleocode/core";
50702
+ import { join as join27 } from "node:path";
50703
+ import { getProjectRoot as getProjectRoot35 } from "@cleocode/core";
49526
50704
  import {
49527
50705
  getBrainDb as getBrainDb2,
49528
50706
  getDreamStatus,
@@ -49564,8 +50742,8 @@ ${body}`).digest("hex").slice(0, 16);
49564
50742
  }
49565
50743
  function loadImportHashes(stateFile) {
49566
50744
  try {
49567
- if (!existsSync15(stateFile)) return /* @__PURE__ */ new Set();
49568
- const raw = readFileSync15(stateFile, "utf-8");
50745
+ if (!existsSync16(stateFile)) return /* @__PURE__ */ new Set();
50746
+ const raw = readFileSync17(stateFile, "utf-8");
49569
50747
  const parsed = JSON.parse(raw);
49570
50748
  return new Set(parsed.hashes);
49571
50749
  } catch {
@@ -49574,7 +50752,7 @@ function loadImportHashes(stateFile) {
49574
50752
  }
49575
50753
  function saveImportHashes(stateFile, hashes) {
49576
50754
  const dir = stateFile.slice(0, stateFile.lastIndexOf("/"));
49577
- if (!existsSync15(dir)) mkdirSync6(dir, { recursive: true });
50755
+ if (!existsSync16(dir)) mkdirSync6(dir, { recursive: true });
49578
50756
  writeFileSync6(stateFile, JSON.stringify({ hashes: [...hashes] }, null, 2), "utf-8");
49579
50757
  }
49580
50758
  function makeMemorySubcommand(opts) {
@@ -50489,7 +51667,7 @@ var init_memory3 = __esm({
50489
51667
  },
50490
51668
  args: {},
50491
51669
  async run() {
50492
- const root = getProjectRoot34();
51670
+ const root = getProjectRoot35();
50493
51671
  try {
50494
51672
  const result = await runConsolidation(root);
50495
51673
  cliOutput(result, { command: "memory-consolidate", operation: "memory.consolidate" });
@@ -50513,7 +51691,7 @@ var init_memory3 = __esm({
50513
51691
  }
50514
51692
  },
50515
51693
  async run({ args }) {
50516
- const root = getProjectRoot34();
51694
+ const root = getProjectRoot35();
50517
51695
  if (args.status) {
50518
51696
  try {
50519
51697
  const status = await getDreamStatus(root);
@@ -50550,7 +51728,7 @@ var init_memory3 = __esm({
50550
51728
  }
50551
51729
  },
50552
51730
  async run({ args }) {
50553
- const root = getProjectRoot34();
51731
+ const root = getProjectRoot35();
50554
51732
  try {
50555
51733
  const { runObserver, runReflector } = await import("@cleocode/core/memory");
50556
51734
  const observerResult = await runObserver(root, args.session, {
@@ -50590,7 +51768,7 @@ var init_memory3 = __esm({
50590
51768
  }
50591
51769
  },
50592
51770
  async run({ args }) {
50593
- const root = getProjectRoot34();
51771
+ const root = getProjectRoot35();
50594
51772
  try {
50595
51773
  await getBrainDb2(root);
50596
51774
  const { totalDuplicateRows, groups } = await scanDuplicateEntries();
@@ -50634,16 +51812,16 @@ var init_memory3 = __esm({
50634
51812
  }
50635
51813
  },
50636
51814
  async run({ args }) {
50637
- const sourceDir = args.from ?? join25(homedir5(), ".claude", "projects", "-mnt-projects-cleocode", "memory");
51815
+ const sourceDir = args.from ?? join27(homedir5(), ".claude", "projects", "-mnt-projects-cleocode", "memory");
50638
51816
  const isDryRun = !!args["dry-run"];
50639
- const projectRoot = getProjectRoot34();
50640
- const stateFile = join25(projectRoot, CLEO_DIR_NAME, MIGRATE_MEMORY_HASHES_JSON);
50641
- if (!existsSync15(sourceDir)) {
51817
+ const projectRoot = getProjectRoot35();
51818
+ const stateFile = join27(projectRoot, CLEO_DIR_NAME, MIGRATE_MEMORY_HASHES_JSON);
51819
+ if (!existsSync16(sourceDir)) {
50642
51820
  cliError(`Source directory not found: ${sourceDir}`, "E_NOT_FOUND", { name: "E_NOT_FOUND" });
50643
51821
  process.exit(1);
50644
51822
  return;
50645
51823
  }
50646
- const files = readdirSync3(sourceDir).filter((f) => f.endsWith(".md") && f !== "MEMORY.md").map((f) => join25(sourceDir, f));
51824
+ const files = readdirSync3(sourceDir).filter((f) => f.endsWith(".md") && f !== "MEMORY.md").map((f) => join27(sourceDir, f));
50647
51825
  const importedHashes = isDryRun ? /* @__PURE__ */ new Set() : loadImportHashes(stateFile);
50648
51826
  const stats = { total: files.length, imported: 0, skipped: 0, errors: 0 };
50649
51827
  const importedEntries = [];
@@ -50652,7 +51830,7 @@ var init_memory3 = __esm({
50652
51830
  for (const filePath of files) {
50653
51831
  const fileName = filePath.split("/").pop() ?? filePath;
50654
51832
  try {
50655
- const raw = readFileSync15(filePath, "utf-8");
51833
+ const raw = readFileSync17(filePath, "utf-8");
50656
51834
  if (!raw.trim()) {
50657
51835
  stats.skipped++;
50658
51836
  skippedEntries.push({ file: fileName, reason: "empty file" });
@@ -50849,7 +52027,7 @@ var init_memory3 = __esm({
50849
52027
  },
50850
52028
  args: {},
50851
52029
  async run() {
50852
- const root = getProjectRoot34();
52030
+ const root = getProjectRoot35();
50853
52031
  try {
50854
52032
  await getBrainDb2(root);
50855
52033
  const result = await getTierStats(root);
@@ -50892,7 +52070,7 @@ var init_memory3 = __esm({
50892
52070
  }
50893
52071
  },
50894
52072
  async run({ args }) {
50895
- const root = getProjectRoot34();
52073
+ const root = getProjectRoot35();
50896
52074
  const targetTier = args.to;
50897
52075
  const reason = args.reason;
50898
52076
  const validTiers = ["medium", "long"];
@@ -50958,7 +52136,7 @@ var init_memory3 = __esm({
50958
52136
  }
50959
52137
  },
50960
52138
  async run({ args }) {
50961
- const root = getProjectRoot34();
52139
+ const root = getProjectRoot35();
50962
52140
  const targetTier = args.to;
50963
52141
  const reason = args.reason;
50964
52142
  const validTiers = ["short", "medium"];
@@ -51426,7 +52604,7 @@ var migrate_claude_mem_exports = {};
51426
52604
  __export(migrate_claude_mem_exports, {
51427
52605
  migrateClaudeMemCommand: () => migrateClaudeMemCommand
51428
52606
  });
51429
- import { getProjectRoot as getProjectRoot35, migrateClaudeMem } from "@cleocode/core/internal";
52607
+ import { getProjectRoot as getProjectRoot36, migrateClaudeMem } from "@cleocode/core/internal";
51430
52608
  import { ingestLooseAgentOutputs, ingestRcasdDirectories } from "@cleocode/core/memory";
51431
52609
  import { getDb as getDb2 } from "@cleocode/core/store/sqlite";
51432
52610
  var storageCommand, claudeMemCommand, manifestIngestCommand, migrateClaudeMemCommand;
@@ -51489,7 +52667,7 @@ var init_migrate_claude_mem = __esm({
51489
52667
  }
51490
52668
  },
51491
52669
  async run({ args }) {
51492
- const root = getProjectRoot35();
52670
+ const root = getProjectRoot36();
51493
52671
  try {
51494
52672
  const result = await migrateClaudeMem(root, {
51495
52673
  sourcePath: args.source,
@@ -51538,7 +52716,7 @@ var init_migrate_claude_mem = __esm({
51538
52716
  }
51539
52717
  },
51540
52718
  async run({ args }) {
51541
- const projectRoot = getProjectRoot35();
52719
+ const projectRoot = getProjectRoot36();
51542
52720
  try {
51543
52721
  const db = await getDb2(projectRoot);
51544
52722
  const rcasdFlag = Boolean(args.rcasd);
@@ -51642,7 +52820,7 @@ __export(nexus_exports, {
51642
52820
  import { appendFile as appendFile2, mkdir as mkdir3 } from "node:fs/promises";
51643
52821
  import { homedir as homedir6 } from "node:os";
51644
52822
  import path4 from "node:path";
51645
- import { getProjectRoot as getProjectRoot36 } from "@cleocode/core";
52823
+ import { getProjectRoot as getProjectRoot37 } from "@cleocode/core";
51646
52824
  import { generateGexf, getSymbolImpact } from "@cleocode/core/nexus";
51647
52825
  async function appendDeprecationTelemetry(op, replacement) {
51648
52826
  try {
@@ -51754,7 +52932,7 @@ var init_nexus4 = __esm({
51754
52932
  async run({ args }) {
51755
52933
  applyJsonFlag2(args.json);
51756
52934
  const projectIdOverride = args["project-id"];
51757
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot36();
52935
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot37();
51758
52936
  const startTime = Date.now();
51759
52937
  try {
51760
52938
  const [{ getNexusDb, nexusSchema }, { getIndexStats }] = await Promise.all([
@@ -52269,7 +53447,7 @@ var init_nexus4 = __esm({
52269
53447
  applyJsonFlag2(args.json);
52270
53448
  const startTime = Date.now();
52271
53449
  const projectIdOverride = args["project-id"];
52272
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot36();
53450
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot37();
52273
53451
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
52274
53452
  const response = await dispatchRaw("query", "nexus", "clusters", { projectId, repoPath });
52275
53453
  const durationMs = Date.now() - startTime;
@@ -52313,7 +53491,7 @@ var init_nexus4 = __esm({
52313
53491
  applyJsonFlag2(args.json);
52314
53492
  const startTime = Date.now();
52315
53493
  const projectIdOverride = args["project-id"];
52316
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot36();
53494
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot37();
52317
53495
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
52318
53496
  const response = await dispatchRaw("query", "nexus", "flows", { projectId, repoPath });
52319
53497
  const durationMs = Date.now() - startTime;
@@ -52356,7 +53534,7 @@ var init_nexus4 = __esm({
52356
53534
  void appendDeprecationTelemetry("nexus.context", "cleo graph context");
52357
53535
  const startTime = Date.now();
52358
53536
  const projectIdOverride = args["project-id"];
52359
- const repoPath = getProjectRoot36();
53537
+ const repoPath = getProjectRoot37();
52360
53538
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
52361
53539
  const limit = parseInt(args.limit, 10);
52362
53540
  const symbolName = args.symbol;
@@ -52419,7 +53597,7 @@ var init_nexus4 = __esm({
52419
53597
  const startTime = Date.now();
52420
53598
  const whyFlag = !!args.why;
52421
53599
  const projectIdOverride = args["project-id"];
52422
- const repoPath = getProjectRoot36();
53600
+ const repoPath = getProjectRoot37();
52423
53601
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
52424
53602
  const maxDepth = Math.min(parseInt(args.depth, 10), 5);
52425
53603
  const symbolName = args.symbol;
@@ -52491,7 +53669,7 @@ var init_nexus4 = __esm({
52491
53669
  const projectIdOverride = args["project-id"];
52492
53670
  const isIncremental = !!args.incremental;
52493
53671
  const ctx = getFormatContext();
52494
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot36();
53672
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot37();
52495
53673
  humanInfo(`[nexus] Analyzing: ${repoPath}${isIncremental ? " (incremental)" : ""}`);
52496
53674
  try {
52497
53675
  const [{ getNexusDb, nexusSchema }, { runPipeline }, { eq: eq2 }] = await Promise.all([
@@ -52643,7 +53821,7 @@ var init_nexus4 = __esm({
52643
53821
  async run({ args }) {
52644
53822
  applyJsonFlag2(args.json);
52645
53823
  const startTime = Date.now();
52646
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot36();
53824
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot37();
52647
53825
  const name = args.name;
52648
53826
  const response = await dispatchRaw("mutate", "nexus", "projects.register", {
52649
53827
  path: repoPath,
@@ -53001,7 +54179,7 @@ var init_nexus4 = __esm({
53001
54179
  applyJsonFlag2(args.json);
53002
54180
  const startTime = Date.now();
53003
54181
  const projectIdOverride = args["project-id"];
53004
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot36();
54182
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot37();
53005
54183
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
53006
54184
  const response = await dispatchRaw("mutate", "nexus", "refresh-bridge", {
53007
54185
  repoPath,
@@ -53150,7 +54328,7 @@ var init_nexus4 = __esm({
53150
54328
  async run({ args }) {
53151
54329
  applyJsonFlag2(args.json);
53152
54330
  const startTime = Date.now();
53153
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot36();
54331
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot37();
53154
54332
  const projectIdOverride = args["project-id"];
53155
54333
  const beforeRef = args.before ?? "HEAD~1";
53156
54334
  const afterRef = args.after ?? "HEAD";
@@ -53268,7 +54446,7 @@ var init_nexus4 = __esm({
53268
54446
  applyJsonFlag2(args.json);
53269
54447
  const startTime = Date.now();
53270
54448
  const projectIdOverride = args["project-id"];
53271
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot36();
54449
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot37();
53272
54450
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
53273
54451
  const response = await dispatchRaw("query", "nexus", "route-map", { projectId });
53274
54452
  const durationMs = Date.now() - startTime;
@@ -53324,7 +54502,7 @@ var init_nexus4 = __esm({
53324
54502
  const startTime = Date.now();
53325
54503
  const routeSymbol = args.routeSymbol;
53326
54504
  const projectIdOverride = args["project-id"];
53327
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot36();
54505
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot37();
53328
54506
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
53329
54507
  const response = await dispatchRaw("query", "nexus", "shape-check", { routeSymbol, projectId });
53330
54508
  const durationMs = Date.now() - startTime;
@@ -53714,7 +54892,7 @@ var init_nexus4 = __esm({
53714
54892
  async run({ args }) {
53715
54893
  applyJsonFlag2(args.json);
53716
54894
  const startTime = Date.now();
53717
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot36();
54895
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot37();
53718
54896
  const projectIdOverride = args["project-id"];
53719
54897
  const projectId = projectIdOverride ?? Buffer.from(repoPath).toString("base64url").slice(0, 32);
53720
54898
  const response = await dispatchRaw("mutate", "nexus", "contracts-sync", {
@@ -53818,7 +54996,7 @@ var init_nexus4 = __esm({
53818
54996
  async run({ args }) {
53819
54997
  applyJsonFlag2(args.json);
53820
54998
  const startTime = Date.now();
53821
- const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot36();
54999
+ const repoPath = args.path ? path4.resolve(args.path) : getProjectRoot37();
53822
55000
  const projectId = Buffer.from(repoPath).toString("base64url").slice(0, 32);
53823
55001
  const response = await dispatchRaw("mutate", "nexus", "contracts-link-tasks", {
53824
55002
  projectId,
@@ -53894,7 +55072,7 @@ var init_nexus4 = __esm({
53894
55072
  async run({ args }) {
53895
55073
  applyJsonFlag2(args.json);
53896
55074
  const startTime = Date.now();
53897
- const outputDir = args.output ?? path4.join(getProjectRoot36(), ".cleo", "wiki");
55075
+ const outputDir = args.output ?? path4.join(getProjectRoot37(), ".cleo", "wiki");
53898
55076
  const communityFilter = args.community ?? void 0;
53899
55077
  const isIncremental = !!args.incremental;
53900
55078
  let loomProvider = null;
@@ -53918,11 +55096,11 @@ var init_nexus4 = __esm({
53918
55096
  }
53919
55097
  try {
53920
55098
  const { generateNexusWikiIndex } = await import("@cleocode/core/nexus/wiki-index.js");
53921
- const result = await generateNexusWikiIndex(outputDir, getProjectRoot36(), {
55099
+ const result = await generateNexusWikiIndex(outputDir, getProjectRoot37(), {
53922
55100
  communityFilter,
53923
55101
  incremental: isIncremental,
53924
55102
  loomProvider,
53925
- projectRoot: getProjectRoot36()
55103
+ projectRoot: getProjectRoot37()
53926
55104
  });
53927
55105
  const durationMs = Date.now() - startTime;
53928
55106
  if (!result.success) {
@@ -55144,7 +56322,7 @@ __export(otel_exports, {
55144
56322
  import {
55145
56323
  CleoError as CleoError6,
55146
56324
  clearOtelData,
55147
- formatError as formatError8,
56325
+ formatError as formatError6,
55148
56326
  getOtelSessions,
55149
56327
  getOtelSpawns,
55150
56328
  getOtelStatus,
@@ -55165,7 +56343,7 @@ var init_otel = __esm({
55165
56343
  cliOutput(result, { command: "otel" });
55166
56344
  } catch (err) {
55167
56345
  if (err instanceof CleoError6) {
55168
- cliError(formatError8(err), err.code, { name: "E_INTERNAL" });
56346
+ cliError(formatError6(err), err.code, { name: "E_INTERNAL" });
55169
56347
  process.exit(err.code);
55170
56348
  }
55171
56349
  throw err;
@@ -55180,7 +56358,7 @@ var init_otel = __esm({
55180
56358
  cliOutput(result, { command: "otel" });
55181
56359
  } catch (err) {
55182
56360
  if (err instanceof CleoError6) {
55183
- cliError(formatError8(err), err.code, { name: "E_INTERNAL" });
56361
+ cliError(formatError6(err), err.code, { name: "E_INTERNAL" });
55184
56362
  process.exit(err.code);
55185
56363
  }
55186
56364
  throw err;
@@ -55208,7 +56386,7 @@ var init_otel = __esm({
55208
56386
  cliOutput(result, { command: "otel" });
55209
56387
  } catch (err) {
55210
56388
  if (err instanceof CleoError6) {
55211
- cliError(formatError8(err), err.code, { name: "E_INTERNAL" });
56389
+ cliError(formatError6(err), err.code, { name: "E_INTERNAL" });
55212
56390
  process.exit(err.code);
55213
56391
  }
55214
56392
  throw err;
@@ -55236,7 +56414,7 @@ var init_otel = __esm({
55236
56414
  cliOutput(result, { command: "otel" });
55237
56415
  } catch (err) {
55238
56416
  if (err instanceof CleoError6) {
55239
- cliError(formatError8(err), err.code, { name: "E_INTERNAL" });
56417
+ cliError(formatError6(err), err.code, { name: "E_INTERNAL" });
55240
56418
  process.exit(err.code);
55241
56419
  }
55242
56420
  throw err;
@@ -55264,7 +56442,7 @@ var init_otel = __esm({
55264
56442
  cliOutput(result, { command: "otel" });
55265
56443
  } catch (err) {
55266
56444
  if (err instanceof CleoError6) {
55267
- cliError(formatError8(err), err.code, { name: "E_INTERNAL" });
56445
+ cliError(formatError6(err), err.code, { name: "E_INTERNAL" });
55268
56446
  process.exit(err.code);
55269
56447
  }
55270
56448
  throw err;
@@ -55279,7 +56457,7 @@ var init_otel = __esm({
55279
56457
  cliOutput(result, { command: "otel" });
55280
56458
  } catch (err) {
55281
56459
  if (err instanceof CleoError6) {
55282
- cliError(formatError8(err), err.code, { name: "E_INTERNAL" });
56460
+ cliError(formatError6(err), err.code, { name: "E_INTERNAL" });
55283
56461
  process.exit(err.code);
55284
56462
  }
55285
56463
  throw err;
@@ -56320,7 +57498,7 @@ var refresh_memory_exports = {};
56320
57498
  __export(refresh_memory_exports, {
56321
57499
  refreshMemoryCommand: () => refreshMemoryCommand
56322
57500
  });
56323
- import { getProjectRoot as getProjectRoot37 } from "@cleocode/core";
57501
+ import { getProjectRoot as getProjectRoot38 } from "@cleocode/core";
56324
57502
  var refreshMemoryCommand;
56325
57503
  var init_refresh_memory = __esm({
56326
57504
  "packages/cleo/src/cli/commands/refresh-memory.ts"() {
@@ -56333,7 +57511,7 @@ var init_refresh_memory = __esm({
56333
57511
  description: "Regenerate .cleo/memory-bridge.md from brain.db"
56334
57512
  },
56335
57513
  async run() {
56336
- const projectDir = getProjectRoot37();
57514
+ const projectDir = getProjectRoot38();
56337
57515
  const { writeMemoryBridge } = await import("@cleocode/core/internal");
56338
57516
  const result = await writeMemoryBridge(projectDir);
56339
57517
  if (result.written) {
@@ -56351,7 +57529,7 @@ var relates_exports = {};
56351
57529
  __export(relates_exports, {
56352
57530
  relatesCommand: () => relatesCommand
56353
57531
  });
56354
- var suggestCommand2, addCommand7, discoverCommand3, removeCommand5, listCommand17, relatesCommand;
57532
+ var suggestCommand2, addCommand8, discoverCommand3, removeCommand5, listCommand17, relatesCommand;
56355
57533
  var init_relates = __esm({
56356
57534
  "packages/cleo/src/cli/commands/relates.ts"() {
56357
57535
  "use strict";
@@ -56382,7 +57560,7 @@ var init_relates = __esm({
56382
57560
  cliOutput(response.data ?? {}, { command: "relates" });
56383
57561
  }
56384
57562
  });
56385
- addCommand7 = defineCommand({
57563
+ addCommand8 = defineCommand({
56386
57564
  meta: {
56387
57565
  name: "add",
56388
57566
  description: "Add a relates entry to a task. Valid types: blocks|related|duplicates|absorbs|fixes|extends|supersedes"
@@ -56495,7 +57673,7 @@ var init_relates = __esm({
56495
57673
  },
56496
57674
  subCommands: {
56497
57675
  suggest: suggestCommand2,
56498
- add: addCommand7,
57676
+ add: addCommand8,
56499
57677
  remove: removeCommand5,
56500
57678
  discover: discoverCommand3,
56501
57679
  list: listCommand17
@@ -56515,7 +57693,7 @@ __export(release_exports, {
56515
57693
  SHIP_DEPRECATION_NOTICE: () => SHIP_DEPRECATION_NOTICE,
56516
57694
  releaseCommand: () => releaseCommand
56517
57695
  });
56518
- import { pushWarning as pushWarning3, release as release2 } from "@cleocode/core";
57696
+ import { pushWarning as pushWarning4, release as release2 } from "@cleocode/core";
56519
57697
  var SHIP_DEPRECATION_NOTICE, shipCommand, listCommand18, showCommand10, cancelCommand2, changelogCommand, rollbackCommand, rollbackFullCommand, prStatusCommand, channelCommand, planCommand3, openCommand2, reconcileCommand4, releaseCommand;
56520
57698
  var init_release3 = __esm({
56521
57699
  "packages/cleo/src/cli/commands/release.ts"() {
@@ -56546,7 +57724,7 @@ var init_release3 = __esm({
56546
57724
  }
56547
57725
  },
56548
57726
  async run({ args }) {
56549
- pushWarning3({
57727
+ pushWarning4({
56550
57728
  code: "W_DEPRECATED_COMMAND",
56551
57729
  message: SHIP_DEPRECATION_NOTICE,
56552
57730
  deprecated: "cleo release ship",
@@ -56642,6 +57820,19 @@ var init_release3 = __esm({
56642
57820
  }
56643
57821
  },
56644
57822
  async run({ args }) {
57823
+ pushWarning4({
57824
+ code: "W_DEPRECATED_COMMAND",
57825
+ message: "`cleo release changelog <tag>` is deprecated. Use `cleo release plan <version> --epic <id>` (T9525) plus the T9759 LLM composer.",
57826
+ severity: "warn",
57827
+ deprecated: "cleo release changelog",
57828
+ replacement: "cleo release plan",
57829
+ removeBy: "v2026.6.0",
57830
+ context: {
57831
+ registryId: "cleo-release-changelog-verb-git-log",
57832
+ task: "T9795",
57833
+ saga: "T9787"
57834
+ }
57835
+ });
56645
57836
  const sinceTag = typeof args["sinceTag"] === "string" && args["sinceTag"].length > 0 ? args["sinceTag"] : typeof args["since"] === "string" && args["since"].length > 0 ? args["since"] : void 0;
56646
57837
  if (sinceTag === void 0) {
56647
57838
  cliError(
@@ -57294,14 +58485,14 @@ var req_exports = {};
57294
58485
  __export(req_exports, {
57295
58486
  reqCommand: () => reqCommand
57296
58487
  });
57297
- var addCommand8, listCommand19, migrateCommand, reqCommand;
58488
+ var addCommand9, listCommand19, migrateCommand, reqCommand;
57298
58489
  var init_req = __esm({
57299
58490
  "packages/cleo/src/cli/commands/req.ts"() {
57300
58491
  "use strict";
57301
58492
  init_dist();
57302
58493
  init_cli();
57303
58494
  init_renderers();
57304
- addCommand8 = defineCommand({
58495
+ addCommand9 = defineCommand({
57305
58496
  meta: {
57306
58497
  name: "add",
57307
58498
  description: "Add a typed AcceptanceGate (with REQ-ID) to a task's acceptance array"
@@ -57381,7 +58572,7 @@ var init_req = __esm({
57381
58572
  reqCommand = defineCommand({
57382
58573
  meta: { name: "req", description: "Manage REQ-ID-addressable acceptance gates on tasks" },
57383
58574
  subCommands: {
57384
- add: addCommand8,
58575
+ add: addCommand9,
57385
58576
  list: listCommand19,
57386
58577
  migrate: migrateCommand
57387
58578
  },
@@ -57402,14 +58593,14 @@ __export(research_exports, {
57402
58593
  function generateResearchId() {
57403
58594
  return `res_${Date.now()}`;
57404
58595
  }
57405
- var addCommand9, showCommand11, listCommand20, pendingCommand2, linkCommand2, updateCommand, statsCommand5, linksCommand, archiveCommand3, manifestCommand2, researchCommand;
58596
+ var addCommand10, showCommand11, listCommand20, pendingCommand2, linkCommand2, updateCommand, statsCommand5, linksCommand, archiveCommand3, manifestCommand2, researchCommand;
57406
58597
  var init_research2 = __esm({
57407
58598
  "packages/cleo/src/cli/commands/research.ts"() {
57408
58599
  "use strict";
57409
58600
  init_dist();
57410
58601
  init_cli();
57411
58602
  init_renderers();
57412
- addCommand9 = defineCommand({
58603
+ addCommand10 = defineCommand({
57413
58604
  meta: { name: "add", description: "Add a research entry" },
57414
58605
  args: {
57415
58606
  task: {
@@ -57718,7 +58909,7 @@ var init_research2 = __esm({
57718
58909
  researchCommand = defineCommand({
57719
58910
  meta: { name: "research", description: "Research commands and manifest operations" },
57720
58911
  subCommands: {
57721
- add: addCommand9,
58912
+ add: addCommand10,
57722
58913
  show: showCommand11,
57723
58914
  list: listCommand20,
57724
58915
  pending: pendingCommand2,
@@ -57746,7 +58937,7 @@ __export(restore_exports, {
57746
58937
  });
57747
58938
  import fs3 from "node:fs";
57748
58939
  import path5 from "node:path";
57749
- import { CleoError as CleoError8, getProjectRoot as getProjectRoot38, getTaskAccessor as getTaskAccessor3 } from "@cleocode/core";
58940
+ import { CleoError as CleoError8, getProjectRoot as getProjectRoot39, getTaskAccessor as getTaskAccessor3 } from "@cleocode/core";
57750
58941
  function parseMarkdownValue(raw) {
57751
58942
  const trimmed = raw.trim();
57752
58943
  if (trimmed === "_(not present)_" || trimmed === "") return void 0;
@@ -57866,7 +59057,7 @@ var init_restore = __esm({
57866
59057
  description: "Apply manually-resolved conflicts from .cleo/restore-conflicts.md"
57867
59058
  },
57868
59059
  async run() {
57869
- const projectRoot = getProjectRoot38();
59060
+ const projectRoot = getProjectRoot39();
57870
59061
  const reportPath = path5.join(projectRoot, CLEO_DIR_NAME, RESTORE_CONFLICTS_MD);
57871
59062
  if (!fs3.existsSync(reportPath)) {
57872
59063
  humanLine("No pending restore conflicts. Nothing to finalize.");
@@ -58232,7 +59423,7 @@ __export(revert_exports, {
58232
59423
  revertCommand: () => revertCommand
58233
59424
  });
58234
59425
  import { readFile as readFile4 } from "node:fs/promises";
58235
- import { join as join26 } from "node:path";
59426
+ import { join as join28 } from "node:path";
58236
59427
  import { cwd as processCwd2 } from "node:process";
58237
59428
  import { E_RECEIPT_NOT_FOUND } from "@cleocode/core/sentient/chain-walker.js";
58238
59429
  import { SENTIENT_STATE_FILE } from "@cleocode/core/sentient/daemon.js";
@@ -58285,7 +59476,7 @@ async function loadOwnerAttestation(attestationFilePath) {
58285
59476
  return obj;
58286
59477
  }
58287
59478
  async function loadOwnerPubkeys(projectRoot) {
58288
- const path6 = join26(projectRoot, OWNER_PUBKEYS_FILE);
59479
+ const path6 = join28(projectRoot, OWNER_PUBKEYS_FILE);
58289
59480
  try {
58290
59481
  const raw = await readFile4(path6, "utf-8");
58291
59482
  const parsed = JSON.parse(raw);
@@ -58369,7 +59560,7 @@ var init_revert = __esm({
58369
59560
  if (attestation && allowedPubkeys.size > 0 && !allowedPubkeys.has(attestation.ownerPubkey)) {
58370
59561
  emitFailure2(
58371
59562
  E_OWNER_ATTESTATION_REQUIRED,
58372
- `Attestation pubkey "${attestation.ownerPubkey}" is not in the owner allowlist at ${join26(projectRoot, OWNER_PUBKEYS_FILE)}`,
59563
+ `Attestation pubkey "${attestation.ownerPubkey}" is not in the owner allowlist at ${join28(projectRoot, OWNER_PUBKEYS_FILE)}`,
58373
59564
  jsonMode
58374
59565
  );
58375
59566
  }
@@ -58422,7 +59613,7 @@ ${lines}`
58422
59613
  identity,
58423
59614
  includeHuman
58424
59615
  });
58425
- const statePath = join26(projectRoot, SENTIENT_STATE_FILE);
59616
+ const statePath = join28(projectRoot, SENTIENT_STATE_FILE);
58426
59617
  const state = await readSentientState(statePath);
58427
59618
  emitSuccess(
58428
59619
  {
@@ -58563,7 +59754,7 @@ var saga_exports = {};
58563
59754
  __export(saga_exports, {
58564
59755
  sagaCommand: () => sagaCommand
58565
59756
  });
58566
- var createCommand3, addCommand10, listCommand21, membersCommand, rollupCommand2, sagaCommand;
59757
+ var createCommand3, addCommand11, listCommand21, membersCommand, rollupCommand2, sagaCommand;
58567
59758
  var init_saga = __esm({
58568
59759
  "packages/cleo/src/cli/commands/saga.ts"() {
58569
59760
  "use strict";
@@ -58606,7 +59797,7 @@ var init_saga = __esm({
58606
59797
  );
58607
59798
  }
58608
59799
  });
58609
- addCommand10 = defineCommand({
59800
+ addCommand11 = defineCommand({
58610
59801
  meta: {
58611
59802
  name: "add",
58612
59803
  description: "Link a member Epic to a Saga (writes task_relations type=groups)"
@@ -58691,7 +59882,7 @@ var init_saga = __esm({
58691
59882
  },
58692
59883
  subCommands: {
58693
59884
  create: createCommand3,
58694
- add: addCommand10,
59885
+ add: addCommand11,
58695
59886
  list: listCommand21,
58696
59887
  members: membersCommand,
58697
59888
  rollup: rollupCommand2
@@ -58708,7 +59899,7 @@ var init_saga = __esm({
58708
59899
  // packages/cleo/src/cli/commands/schema.ts
58709
59900
  var schema_exports = {};
58710
59901
  __export(schema_exports, {
58711
- schemaCommand: () => schemaCommand
59902
+ schemaCommand: () => schemaCommand2
58712
59903
  });
58713
59904
  import { describeOperation } from "@cleocode/lafs";
58714
59905
  function resolveOperationDef(operationArg) {
@@ -58724,7 +59915,7 @@ function resolveOperationDef(operationArg) {
58724
59915
  const operation = operationArg.slice(dotIdx + 1);
58725
59916
  return OPERATIONS.find((op) => op.domain === domain && op.operation === operation) ?? null;
58726
59917
  }
58727
- var schemaCommand;
59918
+ var schemaCommand2;
58728
59919
  var init_schema = __esm({
58729
59920
  "packages/cleo/src/cli/commands/schema.ts"() {
58730
59921
  "use strict";
@@ -58732,7 +59923,7 @@ var init_schema = __esm({
58732
59923
  init_registry();
58733
59924
  init_format_context();
58734
59925
  init_renderers();
58735
- schemaCommand = defineCommand({
59926
+ schemaCommand2 = defineCommand({
58736
59927
  meta: {
58737
59928
  name: "schema",
58738
59929
  description: "Introspect a CLEO operation: show params, types, enums, and declared gates"
@@ -58804,7 +59995,7 @@ __export(self_update_exports, {
58804
59995
  });
58805
59996
  import { execFile } from "node:child_process";
58806
59997
  import { readFile as readFile5 } from "node:fs/promises";
58807
- import { join as join27 } from "node:path";
59998
+ import { join as join29 } from "node:path";
58808
59999
  import * as readline2 from "node:readline";
58809
60000
  import { promisify } from "node:util";
58810
60001
  import {
@@ -58819,7 +60010,7 @@ import {
58819
60010
  async function getCurrentVersion() {
58820
60011
  const cleoHome = getCleoHome4();
58821
60012
  try {
58822
- const content = await readFile5(join27(cleoHome, "VERSION"), "utf-8");
60013
+ const content = await readFile5(join29(cleoHome, "VERSION"), "utf-8");
58823
60014
  return (content.split("\n")[0] ?? "unknown").trim();
58824
60015
  } catch {
58825
60016
  return "unknown";
@@ -58873,7 +60064,7 @@ async function writeRuntimeVersionMetadata(mode, source, version) {
58873
60064
  ];
58874
60065
  await import("node:fs/promises").then(
58875
60066
  ({ writeFile: writeFile4, mkdir: mkdir5 }) => mkdir5(cleoHome, { recursive: true }).then(
58876
- () => writeFile4(join27(cleoHome, "VERSION"), `${lines.join("\n")}
60067
+ () => writeFile4(join29(cleoHome, "VERSION"), `${lines.join("\n")}
58877
60068
  `, "utf-8")
58878
60069
  )
58879
60070
  );
@@ -59284,7 +60475,7 @@ var sentient_exports = {};
59284
60475
  __export(sentient_exports, {
59285
60476
  sentientCommand: () => sentientCommand
59286
60477
  });
59287
- import { join as join28 } from "node:path";
60478
+ import { join as join30 } from "node:path";
59288
60479
  import { cwd as processCwd3 } from "node:process";
59289
60480
  import {
59290
60481
  getSentientDaemonStatus as getSentientDaemonStatus2,
@@ -59359,7 +60550,7 @@ var init_sentient3 = __esm({
59359
60550
  return;
59360
60551
  }
59361
60552
  if (dryRun) {
59362
- const statePath2 = join28(projectRoot, SENTIENT_STATE_FILE2);
60553
+ const statePath2 = join30(projectRoot, SENTIENT_STATE_FILE2);
59363
60554
  const outcome = await safeRunTick({ projectRoot, statePath: statePath2, dryRun: true });
59364
60555
  emitSuccess2(
59365
60556
  { dryRun: true, outcome },
@@ -59475,7 +60666,7 @@ Logs: ${logPath}`
59475
60666
  const jsonMode = args.json === true;
59476
60667
  const dryRun = args["dry-run"] === true;
59477
60668
  try {
59478
- const statePath = join28(projectRoot, SENTIENT_STATE_FILE2);
60669
+ const statePath = join30(projectRoot, SENTIENT_STATE_FILE2);
59479
60670
  const outcome = await safeRunTick({ projectRoot, statePath, dryRun });
59480
60671
  emitSuccess2(
59481
60672
  { outcome, dryRun },
@@ -59544,7 +60735,7 @@ Logs: ${logPath}`
59544
60735
  return;
59545
60736
  }
59546
60737
  await db.update(tasks).set({ status: "pending", updatedAt: now }).where(eq2(tasks.id, id)).run();
59547
- const statePath = join28(projectRoot, SENTIENT_STATE_FILE2);
60738
+ const statePath = join30(projectRoot, SENTIENT_STATE_FILE2);
59548
60739
  const state = await readSentientState2(statePath);
59549
60740
  await patchSentientState(statePath, {
59550
60741
  tier2Stats: {
@@ -59596,7 +60787,7 @@ Logs: ${logPath}`
59596
60787
  return;
59597
60788
  }
59598
60789
  await db.update(tasks).set({ status: "cancelled", cancellationReason: reason, cancelledAt: now, updatedAt: now }).where(eq2(tasks.id, id)).run();
59599
- const statePath = join28(projectRoot, SENTIENT_STATE_FILE2);
60790
+ const statePath = join30(projectRoot, SENTIENT_STATE_FILE2);
59600
60791
  const state = await readSentientState2(statePath);
59601
60792
  await patchSentientState(statePath, {
59602
60793
  tier2Stats: {
@@ -59641,7 +60832,7 @@ Logs: ${logPath}`
59641
60832
  const projectRoot = resolveProjectRoot6(args.project);
59642
60833
  const jsonMode = args.json === true;
59643
60834
  try {
59644
- const statePath = join28(projectRoot, SENTIENT_STATE_FILE2);
60835
+ const statePath = join30(projectRoot, SENTIENT_STATE_FILE2);
59645
60836
  const outcome = await safeRunProposeTick({ projectRoot, statePath });
59646
60837
  emitSuccess2(
59647
60838
  { outcome },
@@ -59661,7 +60852,7 @@ Logs: ${logPath}`
59661
60852
  const projectRoot = resolveProjectRoot6(args.project);
59662
60853
  const jsonMode = args.json === true;
59663
60854
  try {
59664
- const statePath = join28(projectRoot, SENTIENT_STATE_FILE2);
60855
+ const statePath = join30(projectRoot, SENTIENT_STATE_FILE2);
59665
60856
  const updated = await patchSentientState(statePath, { tier2Enabled: true });
59666
60857
  emitSuccess2({ tier2Enabled: updated.tier2Enabled }, jsonMode, "Tier-2 proposals enabled");
59667
60858
  } catch (err) {
@@ -59680,7 +60871,7 @@ Logs: ${logPath}`
59680
60871
  const projectRoot = resolveProjectRoot6(args.project);
59681
60872
  const jsonMode = args.json === true;
59682
60873
  try {
59683
- const statePath = join28(projectRoot, SENTIENT_STATE_FILE2);
60874
+ const statePath = join30(projectRoot, SENTIENT_STATE_FILE2);
59684
60875
  const updated = await patchSentientState(statePath, { tier2Enabled: false });
59685
60876
  emitSuccess2({ tier2Enabled: updated.tier2Enabled }, jsonMode, "Tier-2 proposals disabled");
59686
60877
  } catch (err) {
@@ -59711,7 +60902,7 @@ Logs: ${logPath}`
59711
60902
  const projectRoot = resolveProjectRoot6(args.project);
59712
60903
  const jsonMode = args.json === true;
59713
60904
  try {
59714
- const statePath = join28(projectRoot, SENTIENT_STATE_FILE2);
60905
+ const statePath = join30(projectRoot, SENTIENT_STATE_FILE2);
59715
60906
  const state = await readSentientState2(statePath);
59716
60907
  emitSuccess2(
59717
60908
  {
@@ -60269,7 +61460,7 @@ var sequence_exports = {};
60269
61460
  __export(sequence_exports, {
60270
61461
  sequenceCommand: () => sequenceCommand
60271
61462
  });
60272
- import { getProjectRoot as getProjectRoot39 } from "@cleocode/core/internal";
61463
+ import { getProjectRoot as getProjectRoot40 } from "@cleocode/core/internal";
60273
61464
  var showCommand12, checkCommand6, repairCommand, sequenceCommand;
60274
61465
  var init_sequence = __esm({
60275
61466
  "packages/cleo/src/cli/commands/sequence.ts"() {
@@ -60305,7 +61496,7 @@ var init_sequence = __esm({
60305
61496
  meta: { name: "repair", description: "Reset counter to max + 1 if behind" },
60306
61497
  async run() {
60307
61498
  const { repairSequence } = await import("@cleocode/core/internal");
60308
- const projectRoot = getProjectRoot39();
61499
+ const projectRoot = getProjectRoot40();
60309
61500
  const repair = await repairSequence(projectRoot);
60310
61501
  const result = {
60311
61502
  repaired: repair.repaired,
@@ -60394,7 +61585,7 @@ async function promptOwnerAuthPassword(sessionName) {
60394
61585
  const token = deriveOwnerAuthToken(sessionName, password);
60395
61586
  return token;
60396
61587
  }
60397
- var startCommand7, endCommand, handoffCommand2, statusCommand14, resumeCommand2, findCommand6, listCommand22, gcCommand2, showCommand13, driftCommand, contextDriftCommand, suspendCommand, recordAssumptionCommand, recordDecisionCommand, decisionLogCommand, sessionCommand;
61588
+ var startCommand7, endCommand, handoffCommand2, statusCommand14, resumeCommand2, findCommand6, listCommand22, gcCommand2, showCommand13, driftCommand, contextDriftCommand, suspendCommand, recordAssumptionCommand, recordDecisionCommand, decisionLogCommand, lintCommand, sessionCommand;
60398
61589
  var init_session4 = __esm({
60399
61590
  "packages/cleo/src/cli/commands/session.ts"() {
60400
61591
  "use strict";
@@ -60748,8 +61939,8 @@ var init_session4 = __esm({
60748
61939
  "audit-scope": { type: "string", description: "Audit log scope (global|local)" }
60749
61940
  },
60750
61941
  async run({ args }) {
60751
- const { detectSessionDrift, getProjectRoot: getProjectRoot43 } = await import("@cleocode/core");
60752
- const projectRoot = await getProjectRoot43();
61942
+ const { detectSessionDrift, getProjectRoot: getProjectRoot44 } = await import("@cleocode/core");
61943
+ const projectRoot = await getProjectRoot44();
60753
61944
  const scope = args["audit-scope"] === "local" ? "local" : "global";
60754
61945
  const report = await detectSessionDrift({ projectRoot, auditScope: scope });
60755
61946
  cliOutput(report, { command: "session drift", operation: "session.drift" });
@@ -60915,6 +62106,28 @@ var init_session4 = __esm({
60915
62106
  );
60916
62107
  }
60917
62108
  });
62109
+ lintCommand = defineCommand({
62110
+ meta: {
62111
+ name: "lint",
62112
+ description: "Flag raw-md writes to canonical doc paths in a session transcript (T9797 \xB7 agent-accountability)"
62113
+ },
62114
+ args: {
62115
+ transcript: {
62116
+ type: "string",
62117
+ description: "Absolute path to the *.jsonl transcript to scan",
62118
+ required: true
62119
+ }
62120
+ },
62121
+ async run({ args }) {
62122
+ await dispatchFromCli(
62123
+ "query",
62124
+ "session",
62125
+ "lint",
62126
+ { transcript: args.transcript },
62127
+ { command: "session", operation: "session.lint" }
62128
+ );
62129
+ }
62130
+ });
60918
62131
  sessionCommand = defineCommand({
60919
62132
  meta: { name: "session", description: "Manage work sessions" },
60920
62133
  subCommands: {
@@ -60933,7 +62146,8 @@ var init_session4 = __esm({
60933
62146
  suspend: suspendCommand,
60934
62147
  "record-assumption": recordAssumptionCommand,
60935
62148
  "record-decision": recordDecisionCommand,
60936
- "decision-log": decisionLogCommand
62149
+ "decision-log": decisionLogCommand,
62150
+ lint: lintCommand
60937
62151
  },
60938
62152
  async run({ cmd, rawArgs }) {
60939
62153
  const firstArg = rawArgs?.find((a) => !a.startsWith("-"));
@@ -62768,7 +63982,7 @@ __export(sticky_exports, {
62768
63982
  stickyCommand: () => stickyCommand
62769
63983
  });
62770
63984
  import { CleoError as CleoError10 } from "@cleocode/core";
62771
- var addCommand11, listCommand24, showCommand15, convertCommand, archiveCommand4, purgeCommand2, stickyCommand;
63985
+ var addCommand12, listCommand24, showCommand15, convertCommand, archiveCommand4, purgeCommand2, stickyCommand;
62772
63986
  var init_sticky3 = __esm({
62773
63987
  "packages/cleo/src/cli/commands/sticky.ts"() {
62774
63988
  "use strict";
@@ -62776,7 +63990,7 @@ var init_sticky3 = __esm({
62776
63990
  init_dist();
62777
63991
  init_cli();
62778
63992
  init_renderers();
62779
- addCommand11 = defineCommand({
63993
+ addCommand12 = defineCommand({
62780
63994
  meta: { name: "add", description: "Create a new sticky note" },
62781
63995
  args: {
62782
63996
  content: {
@@ -63058,8 +64272,8 @@ var init_sticky3 = __esm({
63058
64272
  description: "Manage sticky notes - quick project-wide ephemeral captures"
63059
64273
  },
63060
64274
  subCommands: {
63061
- add: addCommand11,
63062
- jot: addCommand11,
64275
+ add: addCommand12,
64276
+ jot: addCommand12,
63063
64277
  list: listCommand24,
63064
64278
  ls: listCommand24,
63065
64279
  show: showCommand15,
@@ -63189,10 +64403,10 @@ var init_sync = __esm({
63189
64403
  }
63190
64404
  },
63191
64405
  async run({ args }) {
63192
- const { readFileSync: readFileSync18 } = await import("node:fs");
64406
+ const { readFileSync: readFileSync20 } = await import("node:fs");
63193
64407
  let externalTasks;
63194
64408
  try {
63195
- externalTasks = JSON.parse(readFileSync18(args.file, "utf8"));
64409
+ externalTasks = JSON.parse(readFileSync20(args.file, "utf8"));
63196
64410
  } catch (err) {
63197
64411
  const message = err instanceof Error ? err.message : String(err);
63198
64412
  cliError(`Failed to read or parse external tasks file: ${message}`, 2, {
@@ -63578,12 +64792,12 @@ var token_exports = {};
63578
64792
  __export(token_exports, {
63579
64793
  tokenCommand: () => tokenCommand
63580
64794
  });
63581
- import { readFileSync as readFileSync16 } from "node:fs";
63582
- import { getProjectRoot as getProjectRoot40, measureTokenExchange, recordTokenExchange as recordTokenExchange2 } from "@cleocode/core/internal";
64795
+ import { readFileSync as readFileSync18 } from "node:fs";
64796
+ import { getProjectRoot as getProjectRoot41, measureTokenExchange, recordTokenExchange as recordTokenExchange2 } from "@cleocode/core/internal";
63583
64797
  function readPayload(args, textKey, fileKey) {
63584
64798
  const text = args[textKey];
63585
64799
  const file = args[fileKey];
63586
- if (file) return readFileSync16(file, "utf-8");
64800
+ if (file) return readFileSync18(file, "utf-8");
63587
64801
  return text;
63588
64802
  }
63589
64803
  var filterArgs, summaryCommand3, listCommand25, showCommand16, deleteCommand3, clearCommand2, estimateCommand, tokenCommand;
@@ -63743,7 +64957,7 @@ var init_token = __esm({
63743
64957
  domain: args.domain,
63744
64958
  operation: args.operation
63745
64959
  };
63746
- const result = args.record ? await recordTokenExchange2(getProjectRoot40(), input2) : await measureTokenExchange(input2);
64960
+ const result = args.record ? await recordTokenExchange2(getProjectRoot41(), input2) : await measureTokenExchange(input2);
63747
64961
  cliOutput(result, {
63748
64962
  command: "token",
63749
64963
  operation: args.record ? "admin.token.record" : "token.estimate"
@@ -63778,8 +64992,8 @@ __export(transcript_exports, {
63778
64992
  transcriptCommand: () => transcriptCommand
63779
64993
  });
63780
64994
  import { homedir as homedir7 } from "node:os";
63781
- import { join as join29 } from "node:path";
63782
- import { getProjectRoot as getProjectRoot41 } from "@cleocode/core";
64995
+ import { join as join31 } from "node:path";
64996
+ import { getProjectRoot as getProjectRoot42 } from "@cleocode/core";
63783
64997
  import {
63784
64998
  parseDurationMs,
63785
64999
  pruneTranscripts,
@@ -63809,7 +65023,7 @@ var init_transcript = __esm({
63809
65023
  async run({ args }) {
63810
65024
  if (args.pending) {
63811
65025
  try {
63812
- const projectRoot = getProjectRoot41();
65026
+ const projectRoot = getProjectRoot42();
63813
65027
  const { scanPendingTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
63814
65028
  const pending = await scanPendingTranscripts(projectRoot);
63815
65029
  cliOutput(
@@ -63832,7 +65046,7 @@ var init_transcript = __esm({
63832
65046
  }
63833
65047
  return;
63834
65048
  }
63835
- const projectsDir = args["projects-dir"] ?? join29(homedir7(), ".claude", "projects");
65049
+ const projectsDir = args["projects-dir"] ?? join31(homedir7(), ".claude", "projects");
63836
65050
  try {
63837
65051
  const result = await scanTranscripts(projectsDir);
63838
65052
  cliOutput(
@@ -63906,7 +65120,7 @@ var init_transcript = __esm({
63906
65120
  async run({ args }) {
63907
65121
  const tier = args.tier ?? "warm";
63908
65122
  const dryRun = args["dry-run"] ?? false;
63909
- const projectRoot = getProjectRoot41();
65123
+ const projectRoot = getProjectRoot42();
63910
65124
  try {
63911
65125
  const { extractTranscript } = await import("@cleocode/core/memory/transcript-extractor.js");
63912
65126
  const { findSessionTranscriptPath, listAllTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
@@ -64018,7 +65232,7 @@ var init_transcript = __esm({
64018
65232
  const dryRun = args["dry-run"] ?? false;
64019
65233
  const olderThanHours = args["older-than-hours"] ? Number.parseInt(args["older-than-hours"], 10) : 24;
64020
65234
  const limit = args.limit ? Number.parseInt(args.limit, 10) : void 0;
64021
- const projectRoot = getProjectRoot41();
65235
+ const projectRoot = getProjectRoot42();
64022
65236
  try {
64023
65237
  const { extractTranscript } = await import("@cleocode/core/memory/transcript-extractor.js");
64024
65238
  const { listAllTranscripts } = await import("@cleocode/core/memory/transcript-scanner.js");
@@ -64138,7 +65352,7 @@ var init_transcript = __esm({
64138
65352
  process.exit(2);
64139
65353
  return;
64140
65354
  }
64141
- const projectsDir = args["projects-dir"] ?? join29(homedir7(), ".claude", "projects");
65355
+ const projectsDir = args["projects-dir"] ?? join31(homedir7(), ".claude", "projects");
64142
65356
  try {
64143
65357
  const pruneResult = await pruneTranscripts({
64144
65358
  olderThanMs,
@@ -64803,15 +66017,15 @@ __export(web_exports, {
64803
66017
  });
64804
66018
  import { execFileSync as execFileSync4, spawn as spawn3 } from "node:child_process";
64805
66019
  import { mkdir as mkdir4, open, readFile as readFile6, rm, stat as stat2, writeFile as writeFile3 } from "node:fs/promises";
64806
- import { join as join30 } from "node:path";
64807
- import { CleoError as CleoError12, formatError as formatError9, getCleoHome as getCleoHome5 } from "@cleocode/core";
66020
+ import { join as join32 } from "node:path";
66021
+ import { CleoError as CleoError12, formatError as formatError7, getCleoHome as getCleoHome5 } from "@cleocode/core";
64808
66022
  function getWebPaths() {
64809
66023
  const cleoHome = getCleoHome5();
64810
66024
  return {
64811
- pidFile: join30(cleoHome, "web-server.pid"),
64812
- configFile: join30(cleoHome, "web-server.json"),
64813
- logDir: join30(cleoHome, "logs"),
64814
- logFile: join30(cleoHome, "logs", "web-server.log")
66025
+ pidFile: join32(cleoHome, "web-server.pid"),
66026
+ configFile: join32(cleoHome, "web-server.json"),
66027
+ logDir: join32(cleoHome, "logs"),
66028
+ logFile: join32(cleoHome, "logs", "web-server.log")
64815
66029
  };
64816
66030
  }
64817
66031
  function isProcessRunning(pid) {
@@ -64850,7 +66064,7 @@ async function startWebServer(port, host) {
64850
66064
  throw new CleoError12(1 /* GENERAL_ERROR */, `Server already running (PID: ${status.pid})`);
64851
66065
  }
64852
66066
  const projectRoot = process.env["CLEO_ROOT"] ?? process.cwd();
64853
- const studioDir = process.env["CLEO_STUDIO_DIR"] ?? join30(projectRoot, "packages", "studio", "build");
66067
+ const studioDir = process.env["CLEO_STUDIO_DIR"] ?? join32(projectRoot, "packages", "studio", "build");
64854
66068
  await mkdir4(logDir, { recursive: true });
64855
66069
  await writeFile3(
64856
66070
  configFile,
@@ -64860,7 +66074,7 @@ async function startWebServer(port, host) {
64860
66074
  startedAt: (/* @__PURE__ */ new Date()).toISOString()
64861
66075
  })
64862
66076
  );
64863
- const webIndexPath = join30(studioDir, "index.js");
66077
+ const webIndexPath = join32(studioDir, "index.js");
64864
66078
  try {
64865
66079
  await stat2(webIndexPath);
64866
66080
  } catch {
@@ -64957,7 +66171,7 @@ var init_web = __esm({
64957
66171
  await startWebServer(Number.parseInt(args.port, 10), args.host);
64958
66172
  } catch (err) {
64959
66173
  if (err instanceof CleoError12) {
64960
- console.error(formatError9(err));
66174
+ console.error(formatError7(err));
64961
66175
  process.exit(err.code);
64962
66176
  }
64963
66177
  throw err;
@@ -65001,7 +66215,7 @@ var init_web = __esm({
65001
66215
  cliOutput({ stopped: true }, { command: "web", message: "CLEO Web UI stopped" });
65002
66216
  } catch (err) {
65003
66217
  if (err instanceof CleoError12) {
65004
- console.error(formatError9(err));
66218
+ console.error(formatError7(err));
65005
66219
  process.exit(err.code);
65006
66220
  }
65007
66221
  throw err;
@@ -65054,7 +66268,7 @@ var init_web = __esm({
65054
66268
  await startWebServer(Number.parseInt(args.port, 10), args.host);
65055
66269
  } catch (err) {
65056
66270
  if (err instanceof CleoError12) {
65057
- console.error(formatError9(err));
66271
+ console.error(formatError7(err));
65058
66272
  process.exit(err.code);
65059
66273
  }
65060
66274
  throw err;
@@ -65069,7 +66283,7 @@ var init_web = __esm({
65069
66283
  cliOutput(status, { command: "web" });
65070
66284
  } catch (err) {
65071
66285
  if (err instanceof CleoError12) {
65072
- console.error(formatError9(err));
66286
+ console.error(formatError7(err));
65073
66287
  process.exit(err.code);
65074
66288
  }
65075
66289
  throw err;
@@ -65102,7 +66316,7 @@ var init_web = __esm({
65102
66316
  cliOutput({ url }, { command: "web", message: `Open browser to: ${url}` });
65103
66317
  } catch (err) {
65104
66318
  if (err instanceof CleoError12) {
65105
- console.error(formatError9(err));
66319
+ console.error(formatError7(err));
65106
66320
  process.exit(err.code);
65107
66321
  }
65108
66322
  throw err;
@@ -65133,7 +66347,7 @@ __export(worktree_exports, {
65133
66347
  worktreeCommand: () => worktreeCommand
65134
66348
  });
65135
66349
  import readline4 from "node:readline";
65136
- import { getProjectRoot as getProjectRoot42, listWorktrees as listWorktrees2 } from "@cleocode/core/internal";
66350
+ import { getProjectRoot as getProjectRoot43, listWorktrees as listWorktrees2 } from "@cleocode/core/internal";
65137
66351
  async function promptYesNo2(question) {
65138
66352
  return new Promise((resolve9) => {
65139
66353
  const rl = readline4.createInterface({ input: process.stdin, output: process.stdout });
@@ -65232,7 +66446,7 @@ var init_worktree3 = __esm({
65232
66446
  const yes = args["yes"] === true;
65233
66447
  const staleDaysRaw = typeof args["days"] === "string" ? args["days"] : void 0;
65234
66448
  const staleDays = staleDaysRaw !== void 0 ? Number.parseInt(staleDaysRaw, 10) : void 0;
65235
- const projectRoot = getProjectRoot42();
66449
+ const projectRoot = getProjectRoot43();
65236
66450
  const listResult = await listWorktrees2({
65237
66451
  projectRoot,
65238
66452
  ...staleDays !== void 0 && !Number.isNaN(staleDays) ? { staleDays } : {}
@@ -65366,8 +66580,8 @@ var init_worktree3 = __esm({
65366
66580
  init_dist();
65367
66581
  init_field_context();
65368
66582
  init_format_context();
65369
- import { readFileSync as readFileSync17 } from "node:fs";
65370
- import { dirname as dirname12, join as join32 } from "node:path";
66583
+ import { readFileSync as readFileSync19 } from "node:fs";
66584
+ import { dirname as dirname12, join as join34 } from "node:path";
65371
66585
  import { fileURLToPath as fileURLToPath8 } from "node:url";
65372
66586
 
65373
66587
  // packages/cleo/src/cli/generated/command-manifest.ts
@@ -65504,6 +66718,12 @@ var COMMAND_MANIFEST = [
65504
66718
  description: "WarpChain pipeline management (tier-2 orchestrator)",
65505
66719
  load: async () => (await Promise.resolve().then(() => (init_chain(), chain_exports))).chainCommand
65506
66720
  },
66721
+ {
66722
+ exportName: "changesetCommand",
66723
+ name: "changeset",
66724
+ description: "Author task-anchored changeset entries that dual-write to ",
66725
+ load: async () => (await Promise.resolve().then(() => (init_changeset(), changeset_exports))).changesetCommand
66726
+ },
65507
66727
  {
65508
66728
  exportName: "checkCommand",
65509
66729
  name: "check",
@@ -66492,14 +67712,14 @@ function didYouMean(input2, candidates, maxDistance = 2) {
66492
67712
  }
66493
67713
 
66494
67714
  // packages/cleo/src/cli/lib/first-run-detection.ts
66495
- import { existsSync as existsSync16 } from "node:fs";
66496
- import { join as join31 } from "node:path";
67715
+ import { existsSync as existsSync17 } from "node:fs";
67716
+ import { join as join33 } from "node:path";
66497
67717
  async function detectFirstRun() {
66498
67718
  const envKey = process.env["ANTHROPIC_API_KEY"];
66499
67719
  if (typeof envKey === "string" && envKey.length > 0) return false;
66500
67720
  const { getCleoPlatformPaths } = await import("@cleocode/paths");
66501
- const configPath = join31(getCleoPlatformPaths().config, "config.json");
66502
- if (existsSync16(configPath)) return false;
67721
+ const configPath = join33(getCleoPlatformPaths().config, "config.json");
67722
+ if (existsSync17(configPath)) return false;
66503
67723
  try {
66504
67724
  const { getCredentialPool } = await import("@cleocode/core/llm/credential-pool.js");
66505
67725
  const pool = getCredentialPool();
@@ -66613,8 +67833,8 @@ Or via NodeSource: https://github.com/nodesource/distributions
66613
67833
  }
66614
67834
  }
66615
67835
  function getPackageVersion() {
66616
- const pkgPath = join32(dirname12(fileURLToPath8(import.meta.url)), "../../package.json");
66617
- const pkg = JSON.parse(readFileSync17(pkgPath, "utf-8"));
67836
+ const pkgPath = join34(dirname12(fileURLToPath8(import.meta.url)), "../../package.json");
67837
+ const pkg = JSON.parse(readFileSync19(pkgPath, "utf-8"));
66618
67838
  return pkg.version;
66619
67839
  }
66620
67840
  var CLI_VERSION = getPackageVersion();
@@ -66766,7 +67986,7 @@ async function runStartupMaintenance() {
66766
67986
  detectAndRemoveStrayProjectNexus,
66767
67987
  getGlobalSalt,
66768
67988
  getLogger: getLogger20,
66769
- getProjectRoot: getProjectRoot43,
67989
+ getProjectRoot: getProjectRoot44,
66770
67990
  isCleanupMarkerSet,
66771
67991
  migrateSignaldockToConduit,
66772
67992
  needsSignaldockToConduitMigration,
@@ -66775,7 +67995,7 @@ async function runStartupMaintenance() {
66775
67995
  } = await import("@cleocode/core/internal");
66776
67996
  let projectRootForCleanup = "";
66777
67997
  try {
66778
- projectRootForCleanup = getProjectRoot43();
67998
+ projectRootForCleanup = getProjectRoot44();
66779
67999
  } catch {
66780
68000
  }
66781
68001
  if (!isCleanupMarkerSet(CLI_VERSION, projectRootForCleanup)) {
@@ -66795,7 +68015,7 @@ async function runStartupMaintenance() {
66795
68015
  const isInitInvocation = process.argv.slice(2).some((a) => a === "init");
66796
68016
  if (!isInitInvocation) {
66797
68017
  try {
66798
- const _projectRootForMigration = getProjectRoot43();
68018
+ const _projectRootForMigration = getProjectRoot44();
66799
68019
  if (needsSignaldockToConduitMigration(_projectRootForMigration)) {
66800
68020
  const migrationResult = migrateSignaldockToConduit(_projectRootForMigration);
66801
68021
  if (migrationResult.status === "failed") {