@cleocode/cleo 2026.5.125 → 2026.5.127
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 +1604 -298
- package/dist/cli/index.js.map +3 -3
- package/package.json +11 -11
package/dist/cli/index.js
CHANGED
|
@@ -5170,7 +5170,7 @@ var init_operations_registry = __esm({
|
|
|
5170
5170
|
}
|
|
5171
5171
|
]
|
|
5172
5172
|
},
|
|
5173
|
-
// === saga sub-domain (ADR-
|
|
5173
|
+
// === saga sub-domain (ADR-088 PM-Core V2 — canonical containment tier) ===
|
|
5174
5174
|
{
|
|
5175
5175
|
gateway: "mutate",
|
|
5176
5176
|
domain: "tasks",
|
|
@@ -5319,8 +5319,10 @@ var init_operations_registry = __esm({
|
|
|
5319
5319
|
]
|
|
5320
5320
|
},
|
|
5321
5321
|
{
|
|
5322
|
-
// T10117
|
|
5322
|
+
// [LEGACY T10117] Detach I5-violating parentId and re-attach via task_relations
|
|
5323
5323
|
// type=groups (ADR-073 §1.2 invariant I5). Idempotent.
|
|
5324
|
+
// PM-Core V2 (ADR-088): parent_id is canonical containment; this repair
|
|
5325
|
+
// direction is the inverse of the canonical model.
|
|
5324
5326
|
gateway: "mutate",
|
|
5325
5327
|
domain: "tasks",
|
|
5326
5328
|
operation: "saga.repair",
|
|
@@ -5369,7 +5371,11 @@ var init_operations_registry = __esm({
|
|
|
5369
5371
|
]
|
|
5370
5372
|
},
|
|
5371
5373
|
{
|
|
5372
|
-
// T10637
|
|
5374
|
+
// [LEGACY T10637] Pre-ADR-088 migration: convert parent_id-based Saga
|
|
5375
|
+
// membership to groups relations. PM-Core V2 (ADR-088) canonicalizes
|
|
5376
|
+
// parent_id as the sole containment edge. This operation is retained
|
|
5377
|
+
// for historical reference; its migration direction is the opposite
|
|
5378
|
+
// of the PM-Core V2 canonical model.
|
|
5373
5379
|
// Converts Epics whose parent_id points to a type='saga' task into proper
|
|
5374
5380
|
// groups relations. Non-Epic tasks are documented as conflicts.
|
|
5375
5381
|
gateway: "mutate",
|
|
@@ -9548,6 +9554,45 @@ var init_operations_registry = __esm({
|
|
|
9548
9554
|
}
|
|
9549
9555
|
]
|
|
9550
9556
|
},
|
|
9557
|
+
// ── docs.llm-output (T11137) — unified LLM output surface ──────────────────
|
|
9558
|
+
{
|
|
9559
|
+
gateway: "query",
|
|
9560
|
+
domain: "docs",
|
|
9561
|
+
operation: "llm-output",
|
|
9562
|
+
description: "docs.llm-output (query) \u2014 unified LLM output: task export (rich Markdown) or attachment-bundle (llms.txt). Replaces `docs export` and `docs generate`.",
|
|
9563
|
+
tier: 1,
|
|
9564
|
+
idempotent: true,
|
|
9565
|
+
sessionRequired: false,
|
|
9566
|
+
requiredParams: ["for"],
|
|
9567
|
+
params: [
|
|
9568
|
+
{ name: "for", type: "string", required: true, description: "Target entity ID" },
|
|
9569
|
+
{
|
|
9570
|
+
name: "mode",
|
|
9571
|
+
type: "string",
|
|
9572
|
+
required: false,
|
|
9573
|
+
description: "Output mode: task-export|attachment-bundle (auto-detected)"
|
|
9574
|
+
},
|
|
9575
|
+
{ name: "out", type: "string", required: false, description: "Output file path" },
|
|
9576
|
+
{
|
|
9577
|
+
name: "includeAttachments",
|
|
9578
|
+
type: "boolean",
|
|
9579
|
+
required: false,
|
|
9580
|
+
description: "Include attachment manifest (task-export)"
|
|
9581
|
+
},
|
|
9582
|
+
{
|
|
9583
|
+
name: "includeMemoryRefs",
|
|
9584
|
+
type: "boolean",
|
|
9585
|
+
required: false,
|
|
9586
|
+
description: "Include memory refs (task-export)"
|
|
9587
|
+
},
|
|
9588
|
+
{
|
|
9589
|
+
name: "attach",
|
|
9590
|
+
type: "boolean",
|
|
9591
|
+
required: false,
|
|
9592
|
+
description: "Save as llms-txt attachment (attachment-bundle)"
|
|
9593
|
+
}
|
|
9594
|
+
]
|
|
9595
|
+
},
|
|
9551
9596
|
// ── docs.update (T10161 — Epic T10157 / Saga T9855) ──────────────────────
|
|
9552
9597
|
{
|
|
9553
9598
|
gateway: "mutate",
|
|
@@ -13588,6 +13633,511 @@ var init_tasks2 = __esm({
|
|
|
13588
13633
|
}
|
|
13589
13634
|
});
|
|
13590
13635
|
|
|
13636
|
+
// packages/contracts/src/taxonomy.ts
|
|
13637
|
+
var BUILTIN_TAXONOMY_TAGS, CANONICAL_TAG_VALUES, _TAG_BY_ID, ADHOC_TO_CANONICAL, TAGS_BY_AXIS, CANONICAL_TYPE_TAGS, CANONICAL_DOMAIN_TAGS, CANONICAL_DOC_KIND_TAGS, TaxonomyError, TaxonomyRegistry;
|
|
13638
|
+
var init_taxonomy = __esm({
|
|
13639
|
+
"packages/contracts/src/taxonomy.ts"() {
|
|
13640
|
+
"use strict";
|
|
13641
|
+
BUILTIN_TAXONOMY_TAGS = [
|
|
13642
|
+
// ─── Domain tags ───────────────────────────────────────────────
|
|
13643
|
+
{
|
|
13644
|
+
tag: "architecture",
|
|
13645
|
+
label: "Architecture",
|
|
13646
|
+
description: "Cross-cutting architectural decisions, patterns, and subsystem-level concerns",
|
|
13647
|
+
axes: ["domain", "type"],
|
|
13648
|
+
adhocAliases: ["architecture"]
|
|
13649
|
+
},
|
|
13650
|
+
{
|
|
13651
|
+
tag: "cli",
|
|
13652
|
+
label: "CLI",
|
|
13653
|
+
description: "Command-line interface, dispatch, and command infrastructure",
|
|
13654
|
+
axes: ["domain"],
|
|
13655
|
+
adhocAliases: ["cli"]
|
|
13656
|
+
},
|
|
13657
|
+
{
|
|
13658
|
+
tag: "core",
|
|
13659
|
+
label: "Core",
|
|
13660
|
+
description: "Core engine, shared utilities, and foundational modules",
|
|
13661
|
+
axes: ["domain"],
|
|
13662
|
+
adhocAliases: ["core", "pm-core-v2", "foundation"]
|
|
13663
|
+
},
|
|
13664
|
+
{
|
|
13665
|
+
tag: "contracts",
|
|
13666
|
+
label: "Contracts",
|
|
13667
|
+
description: "Type contracts, schemas, and public API surface definitions",
|
|
13668
|
+
axes: ["domain"],
|
|
13669
|
+
adhocAliases: ["contracts", "schema"]
|
|
13670
|
+
},
|
|
13671
|
+
{
|
|
13672
|
+
tag: "caamp",
|
|
13673
|
+
label: "CAAMP",
|
|
13674
|
+
description: "Cross-Agent Adaptive Messaging Protocol \u2014 hooks, adapters, providers",
|
|
13675
|
+
axes: ["domain"],
|
|
13676
|
+
adhocAliases: ["caamp", "cant", "pi", "cant-dsl"]
|
|
13677
|
+
},
|
|
13678
|
+
{
|
|
13679
|
+
tag: "skills",
|
|
13680
|
+
label: "Skills",
|
|
13681
|
+
description: "Agent skill definitions, injection, dispatch, and guard patterns",
|
|
13682
|
+
axes: ["domain"],
|
|
13683
|
+
adhocAliases: ["skills"]
|
|
13684
|
+
},
|
|
13685
|
+
{
|
|
13686
|
+
tag: "brain",
|
|
13687
|
+
label: "BRAIN",
|
|
13688
|
+
description: "Cognitive memory system \u2014 decisions, patterns, observations, learnings",
|
|
13689
|
+
axes: ["domain"],
|
|
13690
|
+
adhocAliases: ["brain"]
|
|
13691
|
+
},
|
|
13692
|
+
{
|
|
13693
|
+
tag: "nexus",
|
|
13694
|
+
label: "Nexus",
|
|
13695
|
+
description: "Code intelligence surface \u2014 project indexing, impact analysis, cross-repo",
|
|
13696
|
+
axes: ["domain"],
|
|
13697
|
+
adhocAliases: ["nexus"]
|
|
13698
|
+
},
|
|
13699
|
+
{
|
|
13700
|
+
tag: "orchestration",
|
|
13701
|
+
label: "Orchestration",
|
|
13702
|
+
description: "Multi-agent orchestration, playbooks, LOOM lifecycle, spawn dispatch",
|
|
13703
|
+
axes: ["domain"],
|
|
13704
|
+
adhocAliases: ["orchestration", "orchestrate"]
|
|
13705
|
+
},
|
|
13706
|
+
{
|
|
13707
|
+
tag: "sessions",
|
|
13708
|
+
label: "Sessions",
|
|
13709
|
+
description: "Session lifecycle \u2014 handoff, debrief, briefing, snapshot, state",
|
|
13710
|
+
axes: ["domain"],
|
|
13711
|
+
adhocAliases: ["sessions"]
|
|
13712
|
+
},
|
|
13713
|
+
{
|
|
13714
|
+
tag: "tasks",
|
|
13715
|
+
label: "Tasks",
|
|
13716
|
+
description: "Task management \u2014 CRUD, gates, evidence, acceptance criteria, lifecycle",
|
|
13717
|
+
axes: ["domain"],
|
|
13718
|
+
adhocAliases: ["tasks"]
|
|
13719
|
+
},
|
|
13720
|
+
{
|
|
13721
|
+
tag: "docs",
|
|
13722
|
+
label: "Documents",
|
|
13723
|
+
description: "Document storage, retrieval, taxonomy, publish, and provenance",
|
|
13724
|
+
axes: ["domain"],
|
|
13725
|
+
adhocAliases: ["docs", "documentation"]
|
|
13726
|
+
},
|
|
13727
|
+
{
|
|
13728
|
+
tag: "cleoos",
|
|
13729
|
+
label: "CleoOS",
|
|
13730
|
+
description: "CleoOS runtime \u2014 gateway, daemon, injection facade, agents",
|
|
13731
|
+
axes: ["domain"],
|
|
13732
|
+
adhocAliases: ["cleoos", "facade", "sentient"]
|
|
13733
|
+
},
|
|
13734
|
+
{
|
|
13735
|
+
tag: "worktrunk",
|
|
13736
|
+
label: "Worktrunk",
|
|
13737
|
+
description: "Git worktree management \u2014 spawn, adopt, prune, lifecycle",
|
|
13738
|
+
axes: ["domain"],
|
|
13739
|
+
adhocAliases: ["worktrunk", "worktrunk-ssot"]
|
|
13740
|
+
},
|
|
13741
|
+
{
|
|
13742
|
+
tag: "agents",
|
|
13743
|
+
label: "Agents",
|
|
13744
|
+
description: "Agent profiles, execution learning, registry, dispatch",
|
|
13745
|
+
axes: ["domain"],
|
|
13746
|
+
adhocAliases: ["agents"]
|
|
13747
|
+
},
|
|
13748
|
+
{
|
|
13749
|
+
tag: "routing",
|
|
13750
|
+
label: "Routing",
|
|
13751
|
+
description: "Operation routing, capability matrix, dispatch path resolution",
|
|
13752
|
+
axes: ["domain"],
|
|
13753
|
+
adhocAliases: ["routing"]
|
|
13754
|
+
},
|
|
13755
|
+
{
|
|
13756
|
+
tag: "studio",
|
|
13757
|
+
label: "Studio",
|
|
13758
|
+
description: "Web UI, dashboard, and visual interfaces",
|
|
13759
|
+
axes: ["domain"],
|
|
13760
|
+
adhocAliases: ["studio"]
|
|
13761
|
+
},
|
|
13762
|
+
// ─── Type tags ─────────────────────────────────────────────────
|
|
13763
|
+
{
|
|
13764
|
+
tag: "architectural",
|
|
13765
|
+
label: "Architectural Decision",
|
|
13766
|
+
description: "Cross-cutting architectural decision with durable rationale",
|
|
13767
|
+
axes: ["type"],
|
|
13768
|
+
adhocAliases: ["architectural"]
|
|
13769
|
+
},
|
|
13770
|
+
{
|
|
13771
|
+
tag: "technical",
|
|
13772
|
+
label: "Technical Decision",
|
|
13773
|
+
description: "Implementation-scoped technical decision (library, pattern, algorithm)",
|
|
13774
|
+
axes: ["type"],
|
|
13775
|
+
adhocAliases: ["technical"]
|
|
13776
|
+
},
|
|
13777
|
+
{
|
|
13778
|
+
tag: "process",
|
|
13779
|
+
label: "Process Decision",
|
|
13780
|
+
description: "Workflow, methodology, or operational process decision",
|
|
13781
|
+
axes: ["type"],
|
|
13782
|
+
adhocAliases: ["process"]
|
|
13783
|
+
},
|
|
13784
|
+
{
|
|
13785
|
+
tag: "strategic",
|
|
13786
|
+
label: "Strategic Decision",
|
|
13787
|
+
description: "Long-horizon direction-setting decision spanning multiple epics",
|
|
13788
|
+
axes: ["type"],
|
|
13789
|
+
adhocAliases: ["strategic"]
|
|
13790
|
+
},
|
|
13791
|
+
{
|
|
13792
|
+
tag: "tactical",
|
|
13793
|
+
label: "Tactical Decision",
|
|
13794
|
+
description: "Short-horizon execution-level decision (AGT-* dispatch, within-sprint)",
|
|
13795
|
+
axes: ["type"],
|
|
13796
|
+
adhocAliases: ["tactical"]
|
|
13797
|
+
},
|
|
13798
|
+
{
|
|
13799
|
+
tag: "operational",
|
|
13800
|
+
label: "Operational Decision",
|
|
13801
|
+
description: "Infrastructure, deployment, or runtime configuration decision",
|
|
13802
|
+
axes: ["type"],
|
|
13803
|
+
adhocAliases: ["operational"]
|
|
13804
|
+
},
|
|
13805
|
+
{
|
|
13806
|
+
tag: "bugfix",
|
|
13807
|
+
label: "Bug Fix",
|
|
13808
|
+
description: "Defect correction or regression fix",
|
|
13809
|
+
axes: ["type"],
|
|
13810
|
+
adhocAliases: ["bugfix", "bug-fix", "hygiene"]
|
|
13811
|
+
},
|
|
13812
|
+
{
|
|
13813
|
+
tag: "refactor",
|
|
13814
|
+
label: "Refactor",
|
|
13815
|
+
description: "Internal restructuring without functional change",
|
|
13816
|
+
axes: ["type"],
|
|
13817
|
+
adhocAliases: ["refactor"]
|
|
13818
|
+
},
|
|
13819
|
+
{
|
|
13820
|
+
tag: "feature",
|
|
13821
|
+
label: "Feature",
|
|
13822
|
+
description: "New capability or user-facing enhancement",
|
|
13823
|
+
axes: ["type"],
|
|
13824
|
+
adhocAliases: ["feature"]
|
|
13825
|
+
},
|
|
13826
|
+
{
|
|
13827
|
+
tag: "discovery",
|
|
13828
|
+
label: "Discovery",
|
|
13829
|
+
description: "Exploratory research, investigation, or spike outcome",
|
|
13830
|
+
axes: ["type"],
|
|
13831
|
+
adhocAliases: ["discovery", "exploration", "research-type"]
|
|
13832
|
+
},
|
|
13833
|
+
{
|
|
13834
|
+
tag: "migration",
|
|
13835
|
+
label: "Migration",
|
|
13836
|
+
description: "Data or schema migration, backfill, or upgrade path",
|
|
13837
|
+
axes: ["type"],
|
|
13838
|
+
adhocAliases: ["migration", "migrations"]
|
|
13839
|
+
},
|
|
13840
|
+
{
|
|
13841
|
+
tag: "unification",
|
|
13842
|
+
label: "Unification",
|
|
13843
|
+
description: "Consolidation of fragmented systems into a single SSoT",
|
|
13844
|
+
axes: ["type"],
|
|
13845
|
+
adhocAliases: ["unification"]
|
|
13846
|
+
},
|
|
13847
|
+
{
|
|
13848
|
+
tag: "bootstrap",
|
|
13849
|
+
label: "Bootstrap",
|
|
13850
|
+
description: "Initial setup, scaffolding, or seed infrastructure",
|
|
13851
|
+
axes: ["type"],
|
|
13852
|
+
adhocAliases: ["bootstrap"]
|
|
13853
|
+
},
|
|
13854
|
+
// ─── Lifecycle tags ────────────────────────────────────────────
|
|
13855
|
+
{
|
|
13856
|
+
tag: "research",
|
|
13857
|
+
label: "Research",
|
|
13858
|
+
description: "LOOM stage 1: information gathering and domain understanding",
|
|
13859
|
+
axes: ["lifecycle"],
|
|
13860
|
+
adhocAliases: ["research", "wave-0"]
|
|
13861
|
+
},
|
|
13862
|
+
{
|
|
13863
|
+
tag: "consensus",
|
|
13864
|
+
label: "Consensus",
|
|
13865
|
+
description: "LOOM stage 2: multi-agent consensus and validation of findings",
|
|
13866
|
+
axes: ["lifecycle"],
|
|
13867
|
+
adhocAliases: ["consensus"]
|
|
13868
|
+
},
|
|
13869
|
+
{
|
|
13870
|
+
tag: "design",
|
|
13871
|
+
label: "Architecture Decision",
|
|
13872
|
+
description: "LOOM stage 3: architecture decision recording and validation",
|
|
13873
|
+
axes: ["lifecycle"],
|
|
13874
|
+
adhocAliases: ["design", "architecture_decision"]
|
|
13875
|
+
},
|
|
13876
|
+
{
|
|
13877
|
+
tag: "specification",
|
|
13878
|
+
label: "Specification",
|
|
13879
|
+
description: "LOOM stage 4: technical specification authoring",
|
|
13880
|
+
axes: ["lifecycle"],
|
|
13881
|
+
adhocAliases: ["specification", "rfc"]
|
|
13882
|
+
},
|
|
13883
|
+
{
|
|
13884
|
+
tag: "decomposition",
|
|
13885
|
+
label: "Decomposition",
|
|
13886
|
+
description: "LOOM stage 5: task decomposition and dependency modeling",
|
|
13887
|
+
axes: ["lifecycle"],
|
|
13888
|
+
adhocAliases: ["decomposition"]
|
|
13889
|
+
},
|
|
13890
|
+
{
|
|
13891
|
+
tag: "implementation",
|
|
13892
|
+
label: "Implementation",
|
|
13893
|
+
description: "LOOM stage 6: code authoring and unit-level verification",
|
|
13894
|
+
axes: ["lifecycle"],
|
|
13895
|
+
adhocAliases: [
|
|
13896
|
+
"implementation",
|
|
13897
|
+
"wave-1",
|
|
13898
|
+
"wave-2",
|
|
13899
|
+
"wave-3",
|
|
13900
|
+
"wave-4",
|
|
13901
|
+
"wave-5",
|
|
13902
|
+
"wave.1",
|
|
13903
|
+
"wave.2",
|
|
13904
|
+
"wave.3"
|
|
13905
|
+
]
|
|
13906
|
+
},
|
|
13907
|
+
{
|
|
13908
|
+
tag: "validation",
|
|
13909
|
+
label: "Validation",
|
|
13910
|
+
description: "LOOM stage 7: integration testing and gate verification",
|
|
13911
|
+
axes: ["lifecycle"],
|
|
13912
|
+
adhocAliases: ["validation", "testing"]
|
|
13913
|
+
},
|
|
13914
|
+
{
|
|
13915
|
+
tag: "release",
|
|
13916
|
+
label: "Release",
|
|
13917
|
+
description: "LOOM stage 9: versioning, changelog, npm publish, tag push",
|
|
13918
|
+
axes: ["lifecycle", "type"],
|
|
13919
|
+
adhocAliases: ["release"]
|
|
13920
|
+
},
|
|
13921
|
+
// ─── Priority tags ─────────────────────────────────────────────
|
|
13922
|
+
{
|
|
13923
|
+
tag: "p0",
|
|
13924
|
+
label: "P0 \u2014 Critical",
|
|
13925
|
+
description: "Drop-everything critical: blocks release, data loss, security incident",
|
|
13926
|
+
axes: ["priority"],
|
|
13927
|
+
adhocAliases: ["p0", "critical", "prime-tier1"]
|
|
13928
|
+
},
|
|
13929
|
+
{
|
|
13930
|
+
tag: "p1",
|
|
13931
|
+
label: "P1 \u2014 High",
|
|
13932
|
+
description: "High priority: blocks dependent work, user-visible degradation",
|
|
13933
|
+
axes: ["priority"],
|
|
13934
|
+
adhocAliases: ["p1"]
|
|
13935
|
+
},
|
|
13936
|
+
{
|
|
13937
|
+
tag: "p2",
|
|
13938
|
+
label: "P2 \u2014 Medium",
|
|
13939
|
+
description: "Medium priority: should fix, not blocking current wave",
|
|
13940
|
+
axes: ["priority"],
|
|
13941
|
+
adhocAliases: ["p2"]
|
|
13942
|
+
},
|
|
13943
|
+
{
|
|
13944
|
+
tag: "p3",
|
|
13945
|
+
label: "P3 \u2014 Low",
|
|
13946
|
+
description: "Low priority: nice-to-have, cleanup, future consideration",
|
|
13947
|
+
axes: ["priority"],
|
|
13948
|
+
adhocAliases: ["p3"]
|
|
13949
|
+
},
|
|
13950
|
+
// ─── Doc-kind tags (absorb docs-taxonomy) ──────────────────────
|
|
13951
|
+
{
|
|
13952
|
+
tag: "adr",
|
|
13953
|
+
label: "Architecture Decision Record",
|
|
13954
|
+
description: "Formal architecture decision record with rationale and alternatives",
|
|
13955
|
+
axes: ["doc_kind"],
|
|
13956
|
+
adhocAliases: ["adr"]
|
|
13957
|
+
},
|
|
13958
|
+
{
|
|
13959
|
+
tag: "spec",
|
|
13960
|
+
label: "Specification",
|
|
13961
|
+
description: "Technical specification for a feature, protocol, or subsystem",
|
|
13962
|
+
axes: ["doc_kind"],
|
|
13963
|
+
adhocAliases: ["spec"]
|
|
13964
|
+
},
|
|
13965
|
+
{
|
|
13966
|
+
tag: "research",
|
|
13967
|
+
label: "Research Note",
|
|
13968
|
+
description: "Investigation findings, surveys, and domain analysis",
|
|
13969
|
+
axes: ["doc_kind"],
|
|
13970
|
+
adhocAliases: ["research"]
|
|
13971
|
+
},
|
|
13972
|
+
{
|
|
13973
|
+
tag: "handoff",
|
|
13974
|
+
label: "Handoff Note",
|
|
13975
|
+
description: "Cross-session handoff with state, blockers, and next actions",
|
|
13976
|
+
axes: ["doc_kind"],
|
|
13977
|
+
adhocAliases: ["handoff"]
|
|
13978
|
+
},
|
|
13979
|
+
{
|
|
13980
|
+
tag: "note",
|
|
13981
|
+
label: "Note",
|
|
13982
|
+
description: "General-purpose note, observation, or free-form documentation",
|
|
13983
|
+
axes: ["doc_kind"],
|
|
13984
|
+
adhocAliases: ["note"]
|
|
13985
|
+
},
|
|
13986
|
+
{
|
|
13987
|
+
tag: "llmreadme",
|
|
13988
|
+
label: "LLM README",
|
|
13989
|
+
description: "Agent-consumable project overview, conventions, and context",
|
|
13990
|
+
axes: ["doc_kind"],
|
|
13991
|
+
adhocAliases: ["llmreadme", "llm-readme"]
|
|
13992
|
+
},
|
|
13993
|
+
{
|
|
13994
|
+
tag: "designmd",
|
|
13995
|
+
label: "Design Doc",
|
|
13996
|
+
description: "Google DESIGN.md token spec for agent interface contracts",
|
|
13997
|
+
axes: ["doc_kind"],
|
|
13998
|
+
adhocAliases: ["designmd", "design-md"]
|
|
13999
|
+
},
|
|
14000
|
+
{
|
|
14001
|
+
tag: "changeset",
|
|
14002
|
+
label: "Changeset",
|
|
14003
|
+
description: "User-facing changelog entry for a single change",
|
|
14004
|
+
axes: ["doc_kind"],
|
|
14005
|
+
adhocAliases: ["changeset"]
|
|
14006
|
+
},
|
|
14007
|
+
{
|
|
14008
|
+
tag: "changelog",
|
|
14009
|
+
label: "Changelog",
|
|
14010
|
+
description: "Aggregated release changelog for a version",
|
|
14011
|
+
axes: ["doc_kind"],
|
|
14012
|
+
adhocAliases: ["changelog"]
|
|
14013
|
+
}
|
|
14014
|
+
];
|
|
14015
|
+
CANONICAL_TAG_VALUES = BUILTIN_TAXONOMY_TAGS.map((t) => t.tag);
|
|
14016
|
+
_TAG_BY_ID = new Map(
|
|
14017
|
+
BUILTIN_TAXONOMY_TAGS.map((t) => [t.tag, t])
|
|
14018
|
+
);
|
|
14019
|
+
ADHOC_TO_CANONICAL = /* @__PURE__ */ new Map();
|
|
14020
|
+
for (const tag of BUILTIN_TAXONOMY_TAGS) {
|
|
14021
|
+
for (const alias2 of tag.adhocAliases) {
|
|
14022
|
+
ADHOC_TO_CANONICAL.set(alias2, tag.tag);
|
|
14023
|
+
}
|
|
14024
|
+
}
|
|
14025
|
+
TAGS_BY_AXIS = /* @__PURE__ */ new Map();
|
|
14026
|
+
for (const axis of ["domain", "type", "lifecycle", "priority", "doc_kind"]) {
|
|
14027
|
+
TAGS_BY_AXIS.set(
|
|
14028
|
+
axis,
|
|
14029
|
+
BUILTIN_TAXONOMY_TAGS.filter((t) => t.axes.includes(axis))
|
|
14030
|
+
);
|
|
14031
|
+
}
|
|
14032
|
+
CANONICAL_TYPE_TAGS = TAGS_BY_AXIS.get("type").map(
|
|
14033
|
+
(t) => t.tag
|
|
14034
|
+
);
|
|
14035
|
+
CANONICAL_DOMAIN_TAGS = TAGS_BY_AXIS.get("domain").map(
|
|
14036
|
+
(t) => t.tag
|
|
14037
|
+
);
|
|
14038
|
+
CANONICAL_DOC_KIND_TAGS = TAGS_BY_AXIS.get("doc_kind").map(
|
|
14039
|
+
(t) => t.tag
|
|
14040
|
+
);
|
|
14041
|
+
TaxonomyError = class extends Error {
|
|
14042
|
+
constructor(message, invalidTags) {
|
|
14043
|
+
super(message);
|
|
14044
|
+
this.invalidTags = invalidTags;
|
|
14045
|
+
this.name = "TaxonomyError";
|
|
14046
|
+
}
|
|
14047
|
+
invalidTags;
|
|
14048
|
+
};
|
|
14049
|
+
TaxonomyRegistry = class _TaxonomyRegistry {
|
|
14050
|
+
byId;
|
|
14051
|
+
adhocMap;
|
|
14052
|
+
constructor(tags) {
|
|
14053
|
+
this.byId = new Map(tags.map((t) => [t.tag, t]));
|
|
14054
|
+
this.adhocMap = /* @__PURE__ */ new Map();
|
|
14055
|
+
for (const tag of tags) {
|
|
14056
|
+
for (const alias2 of tag.adhocAliases) {
|
|
14057
|
+
const existingTarget = this.adhocMap.get(alias2);
|
|
14058
|
+
if (existingTarget !== void 0 && existingTarget !== tag.tag) {
|
|
14059
|
+
throw new TaxonomyError(
|
|
14060
|
+
`Ad-hoc alias '${alias2}' maps to both '${existingTarget}' and '${tag.tag}' \u2014 aliases must be unique across targets`,
|
|
14061
|
+
[alias2]
|
|
14062
|
+
);
|
|
14063
|
+
}
|
|
14064
|
+
this.adhocMap.set(alias2, tag.tag);
|
|
14065
|
+
}
|
|
14066
|
+
}
|
|
14067
|
+
}
|
|
14068
|
+
/** Default built-in registry singleton. */
|
|
14069
|
+
static default = new _TaxonomyRegistry(BUILTIN_TAXONOMY_TAGS);
|
|
14070
|
+
/** True when `tag` is a canonical tag. */
|
|
14071
|
+
isCanonical(tag) {
|
|
14072
|
+
return this.byId.has(tag);
|
|
14073
|
+
}
|
|
14074
|
+
/** Look up metadata for a canonical tag. */
|
|
14075
|
+
get(tag) {
|
|
14076
|
+
return this.byId.get(tag);
|
|
14077
|
+
}
|
|
14078
|
+
/** List all canonical tags. */
|
|
14079
|
+
list() {
|
|
14080
|
+
return [...this.byId.values()];
|
|
14081
|
+
}
|
|
14082
|
+
/** List tags for a specific axis. */
|
|
14083
|
+
listByAxis(axis) {
|
|
14084
|
+
return this.list().filter((t) => t.axes.includes(axis));
|
|
14085
|
+
}
|
|
14086
|
+
/**
|
|
14087
|
+
* Normalize an ad-hoc label to its canonical form.
|
|
14088
|
+
*
|
|
14089
|
+
* Returns the canonical tag id, or `undefined` if the label has no
|
|
14090
|
+
* known canonical mapping.
|
|
14091
|
+
*/
|
|
14092
|
+
normalize(adhoc) {
|
|
14093
|
+
return this.adhocMap.get(adhoc);
|
|
14094
|
+
}
|
|
14095
|
+
/**
|
|
14096
|
+
* Validate that every tag in `tags` is canonical.
|
|
14097
|
+
*
|
|
14098
|
+
* @param tags - Tags to validate.
|
|
14099
|
+
* @returns An array of invalid tags. Empty array = all valid.
|
|
14100
|
+
*/
|
|
14101
|
+
validate(tags) {
|
|
14102
|
+
return tags.filter((t) => !this.byId.has(t));
|
|
14103
|
+
}
|
|
14104
|
+
/**
|
|
14105
|
+
* Validate tags and throw on failure.
|
|
14106
|
+
*
|
|
14107
|
+
* @param tags - Tags to validate.
|
|
14108
|
+
* @param context - Human-readable context for the error message.
|
|
14109
|
+
* @throws TaxonomyError when any tag is not canonical.
|
|
14110
|
+
*/
|
|
14111
|
+
validateOrThrow(tags, context) {
|
|
14112
|
+
const invalid = this.validate(tags);
|
|
14113
|
+
if (invalid.length > 0) {
|
|
14114
|
+
throw new TaxonomyError(
|
|
14115
|
+
`${context}: unknown tags [${invalid.join(", ")}]. Use canonical tags. Run 'cleo taxonomy list' to see all valid tags.`,
|
|
14116
|
+
invalid
|
|
14117
|
+
);
|
|
14118
|
+
}
|
|
14119
|
+
}
|
|
14120
|
+
/**
|
|
14121
|
+
* Normalize a set of ad-hoc labels to canonical form.
|
|
14122
|
+
*
|
|
14123
|
+
* Unknown labels are passed through unchanged (they may be
|
|
14124
|
+
* project-specific extensions or task-id references).
|
|
14125
|
+
*
|
|
14126
|
+
* @param labels - Ad-hoc labels to normalize.
|
|
14127
|
+
* @returns Normalized label set (deduplicated).
|
|
14128
|
+
*/
|
|
14129
|
+
normalizeSet(labels) {
|
|
14130
|
+
const result = /* @__PURE__ */ new Set();
|
|
14131
|
+
for (const label of labels) {
|
|
14132
|
+
const canonical = this.normalize(label);
|
|
14133
|
+
result.add(canonical ?? label);
|
|
14134
|
+
}
|
|
14135
|
+
return [...result];
|
|
14136
|
+
}
|
|
14137
|
+
};
|
|
14138
|
+
}
|
|
14139
|
+
});
|
|
14140
|
+
|
|
13591
14141
|
// packages/contracts/src/templates/manifest.ts
|
|
13592
14142
|
import { z as z15 } from "zod";
|
|
13593
14143
|
var TEMPLATE_KINDS, TEMPLATE_SUBSTITUTIONS, TEMPLATE_UPDATE_STRATEGIES, PLACEHOLDER_SOURCES, PlaceholderSpecSchema, TemplateManifestEntrySchema;
|
|
@@ -13740,6 +14290,7 @@ var init_src2 = __esm({
|
|
|
13740
14290
|
init_task_evidence();
|
|
13741
14291
|
init_archive();
|
|
13742
14292
|
init_tasks2();
|
|
14293
|
+
init_taxonomy();
|
|
13743
14294
|
init_manifest2();
|
|
13744
14295
|
init_validator();
|
|
13745
14296
|
init_workgraph();
|
|
@@ -18700,15 +19251,17 @@ var init_diagnostics = __esm({
|
|
|
18700
19251
|
// packages/cleo/src/dispatch/domains/docs.ts
|
|
18701
19252
|
import { readFile } from "node:fs/promises";
|
|
18702
19253
|
import { resolve as resolve2 } from "node:path";
|
|
19254
|
+
import { LLM_OUTPUT_MODES } from "@cleocode/contracts/operations/docs";
|
|
18703
19255
|
import { pushWarning } from "@cleocode/core";
|
|
18704
19256
|
import {
|
|
18705
19257
|
AUTO_TOKEN,
|
|
18706
19258
|
allocateAdrSlug,
|
|
18707
19259
|
allocateAutoSlugForDispatch,
|
|
18708
19260
|
consumeReservedSlug,
|
|
19261
|
+
createAttachmentBlobStore,
|
|
18709
19262
|
createAttachmentStore,
|
|
18710
19263
|
createAttachmentStoreDocsAccessor,
|
|
18711
|
-
|
|
19264
|
+
createDocsReadModel,
|
|
18712
19265
|
DOCS_UPDATE_LIFECYCLE_STATUS_LIST,
|
|
18713
19266
|
exportDocument,
|
|
18714
19267
|
findSimilarDocs,
|
|
@@ -18735,11 +19288,11 @@ import {
|
|
|
18735
19288
|
SUPERSEDE_SAME_SLUG_CODE,
|
|
18736
19289
|
searchAllProjectDocs,
|
|
18737
19290
|
searchDocs,
|
|
18738
|
-
statusDocs,
|
|
18739
19291
|
supersedeDoc,
|
|
18740
19292
|
syncFromGit,
|
|
18741
19293
|
updateDocBySlug,
|
|
18742
19294
|
validateDocBody,
|
|
19295
|
+
writeAuditEntry,
|
|
18743
19296
|
writeChangesetEntry
|
|
18744
19297
|
} from "@cleocode/core/internal";
|
|
18745
19298
|
function getDocKindRegistry() {
|
|
@@ -18759,6 +19312,12 @@ function getDocKindRegistry() {
|
|
|
18759
19312
|
function registeredKindValues() {
|
|
18760
19313
|
return getDocKindRegistry().list().map((d) => d.kind);
|
|
18761
19314
|
}
|
|
19315
|
+
async function currentAttachmentBackend() {
|
|
19316
|
+
return resolveAttachmentBackend();
|
|
19317
|
+
}
|
|
19318
|
+
function exportTaskDocument(options) {
|
|
19319
|
+
return exportDocument(options);
|
|
19320
|
+
}
|
|
18762
19321
|
function inferOwnerType(ownerId) {
|
|
18763
19322
|
if (/^T\d+$/i.test(ownerId)) return "task";
|
|
18764
19323
|
if (ownerId.startsWith("ses_")) return "session";
|
|
@@ -18860,6 +19419,7 @@ function docsEnvelopeToResponse(envelope, gateway, operation, startTime) {
|
|
|
18860
19419
|
error: {
|
|
18861
19420
|
code: String(envelope.error?.code ?? "E_INTERNAL"),
|
|
18862
19421
|
message: envelope.error?.message ?? "Unknown error",
|
|
19422
|
+
...envelope.error?.fix !== void 0 ? { fix: envelope.error.fix } : {},
|
|
18863
19423
|
// T9636 — preserve structured details (e.g. slug suggestions) so the
|
|
18864
19424
|
// CLI can render alternative slugs without a separate API call.
|
|
18865
19425
|
...envelope.error?.details !== void 0 ? { details: envelope.error.details } : {}
|
|
@@ -18950,8 +19510,10 @@ async function dispatchDocsLegacyQuery(operation, params) {
|
|
|
18950
19510
|
name: typeof params["name"] === "string" ? params["name"] : void 0,
|
|
18951
19511
|
projectRoot
|
|
18952
19512
|
});
|
|
18953
|
-
case "status":
|
|
18954
|
-
|
|
19513
|
+
case "status": {
|
|
19514
|
+
const model = createDocsReadModel();
|
|
19515
|
+
return model.status(projectRoot);
|
|
19516
|
+
}
|
|
18955
19517
|
default:
|
|
18956
19518
|
throw new Error(`Unsupported docs query operation: ${operation}`);
|
|
18957
19519
|
}
|
|
@@ -18976,10 +19538,19 @@ async function dispatchDocsLegacyMutate(operation, params) {
|
|
|
18976
19538
|
});
|
|
18977
19539
|
} catch {
|
|
18978
19540
|
}
|
|
19541
|
+
try {
|
|
19542
|
+
writeAuditEntry(projectRoot, {
|
|
19543
|
+
op: "docs.publish",
|
|
19544
|
+
slug: result.blobName,
|
|
19545
|
+
attachmentId: result.blobSha256,
|
|
19546
|
+
summary: `Published doc '${result.blobName}' to ${result.relativePath}`
|
|
19547
|
+
});
|
|
19548
|
+
} catch {
|
|
19549
|
+
}
|
|
18979
19550
|
return result;
|
|
18980
19551
|
}
|
|
18981
|
-
case "publish-pr":
|
|
18982
|
-
|
|
19552
|
+
case "publish-pr": {
|
|
19553
|
+
const prResult = await publishDocsAsPr({
|
|
18983
19554
|
slugOrId: String(params["slugOrId"]),
|
|
18984
19555
|
...typeof params["slug"] === "string" ? { slug: params["slug"] } : {},
|
|
18985
19556
|
...typeof params["type"] === "string" ? { type: params["type"] } : {},
|
|
@@ -18987,14 +19558,39 @@ async function dispatchDocsLegacyMutate(operation, params) {
|
|
|
18987
19558
|
...typeof params["body"] === "string" ? { body: params["body"] } : {},
|
|
18988
19559
|
...typeof params["base"] === "string" ? { base: params["base"] } : {}
|
|
18989
19560
|
});
|
|
18990
|
-
|
|
18991
|
-
|
|
19561
|
+
if (prResult.success) {
|
|
19562
|
+
try {
|
|
19563
|
+
writeAuditEntry(projectRoot, {
|
|
19564
|
+
op: "docs.publish-pr",
|
|
19565
|
+
slug: prResult.data.slug,
|
|
19566
|
+
type: prResult.data.type,
|
|
19567
|
+
attachmentId: prResult.data.blobSha,
|
|
19568
|
+
summary: `Published PR for doc '${prResult.data.slug}' (${prResult.data.action}) \u2014 ${prResult.data.prUrl}`
|
|
19569
|
+
});
|
|
19570
|
+
} catch {
|
|
19571
|
+
}
|
|
19572
|
+
}
|
|
19573
|
+
return prResult;
|
|
19574
|
+
}
|
|
19575
|
+
case "sync": {
|
|
19576
|
+
const syncResult = await syncFromGit({
|
|
18992
19577
|
ownerId: String(params["ownerId"]),
|
|
18993
19578
|
fromPath: String(params["fromPath"]),
|
|
18994
19579
|
blobName: typeof params["blobName"] === "string" ? params["blobName"] : void 0,
|
|
18995
19580
|
contentType: typeof params["contentType"] === "string" ? params["contentType"] : void 0,
|
|
18996
19581
|
projectRoot
|
|
18997
19582
|
});
|
|
19583
|
+
try {
|
|
19584
|
+
writeAuditEntry(projectRoot, {
|
|
19585
|
+
op: "docs.sync",
|
|
19586
|
+
slug: typeof params["blobName"] === "string" && params["blobName"] || void 0,
|
|
19587
|
+
ownerId: String(params["ownerId"]),
|
|
19588
|
+
summary: `Synced doc from '${String(params["fromPath"])}' for owner ${String(params["ownerId"])}`
|
|
19589
|
+
});
|
|
19590
|
+
} catch {
|
|
19591
|
+
}
|
|
19592
|
+
return syncResult;
|
|
19593
|
+
}
|
|
18998
19594
|
case "import": {
|
|
18999
19595
|
const scanRoot = String(params["scanRoot"]);
|
|
19000
19596
|
const accessor = createAttachmentStoreDocsAccessor(projectRoot);
|
|
@@ -19008,6 +19604,13 @@ async function dispatchDocsLegacyMutate(operation, params) {
|
|
|
19008
19604
|
auditDir: projectRoot,
|
|
19009
19605
|
classify: makeClassifierForScanRoot(scanRoot, projectRoot)
|
|
19010
19606
|
});
|
|
19607
|
+
try {
|
|
19608
|
+
writeAuditEntry(projectRoot, {
|
|
19609
|
+
op: "docs.import",
|
|
19610
|
+
summary: `Imported ${result.counters.importCount} created, ${result.counters.noopCount} skipped, ${result.counters.errorCount} errors from '${scanRoot}'`
|
|
19611
|
+
});
|
|
19612
|
+
} catch {
|
|
19613
|
+
}
|
|
19011
19614
|
return {
|
|
19012
19615
|
dryRun: result.dryRun,
|
|
19013
19616
|
counters: result.counters,
|
|
@@ -19023,7 +19626,7 @@ async function dispatchDocsLegacyMutate(operation, params) {
|
|
|
19023
19626
|
throw new Error(`Unsupported docs mutate operation: ${operation}`);
|
|
19024
19627
|
}
|
|
19025
19628
|
}
|
|
19026
|
-
var DOCS_LIST_DEFAULT_LIMIT, _registryCache, SLUG_PATTERN, SLUG_MAX_LEN, _docsTypedHandler, QUERY_OPS3, MUTATE_OPS3, DocsHandler;
|
|
19629
|
+
var DOCS_LIST_DEFAULT_LIMIT, SLUG_COLLISION_GUIDANCE, _registryCache, SLUG_PATTERN, SLUG_MAX_LEN, _docsTypedHandler, QUERY_OPS3, MUTATE_OPS3, DocsHandler;
|
|
19027
19630
|
var init_docs2 = __esm({
|
|
19028
19631
|
"packages/cleo/src/dispatch/domains/docs.ts"() {
|
|
19029
19632
|
"use strict";
|
|
@@ -19032,6 +19635,13 @@ var init_docs2 = __esm({
|
|
|
19032
19635
|
init_base();
|
|
19033
19636
|
init_meta2();
|
|
19034
19637
|
DOCS_LIST_DEFAULT_LIMIT = 50;
|
|
19638
|
+
SLUG_COLLISION_GUIDANCE = `slug '{slug}' is already reserved in this project. Three ways to proceed:
|
|
19639
|
+
|
|
19640
|
+
1. Update the existing document: cleo docs update {slug} [--file <path> | --content <text>]
|
|
19641
|
+
2. Use a different slug: cleo docs add <owner> <file> --slug <alternative>
|
|
19642
|
+
3. Supersede with a new slug: cleo docs supersede {slug} <new-slug>
|
|
19643
|
+
|
|
19644
|
+
Recovery command: cleo docs update {slug} --file <your-file>`;
|
|
19035
19645
|
_registryCache = /* @__PURE__ */ new Map();
|
|
19036
19646
|
SLUG_PATTERN = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
|
|
19037
19647
|
SLUG_MAX_LEN = 80;
|
|
@@ -19062,30 +19672,29 @@ var init_docs2 = __esm({
|
|
|
19062
19672
|
"no scope set \u2014 defaulted to --project. Pass --task <id>, --session <id>, or --observation <id> for a narrower listing."
|
|
19063
19673
|
);
|
|
19064
19674
|
}
|
|
19065
|
-
const
|
|
19066
|
-
const backend = await
|
|
19675
|
+
const model = createDocsReadModel();
|
|
19676
|
+
const backend = await currentAttachmentBackend();
|
|
19067
19677
|
if (isProjectScope) {
|
|
19068
|
-
const
|
|
19069
|
-
|
|
19070
|
-
|
|
19071
|
-
);
|
|
19072
|
-
const
|
|
19073
|
-
|
|
19074
|
-
|
|
19075
|
-
|
|
19076
|
-
|
|
19077
|
-
|
|
19078
|
-
|
|
19079
|
-
|
|
19080
|
-
|
|
19081
|
-
|
|
19082
|
-
|
|
19083
|
-
|
|
19084
|
-
|
|
19085
|
-
...
|
|
19086
|
-
|
|
19087
|
-
|
|
19088
|
-
ownerType: ot
|
|
19678
|
+
const docs = await model.listProjectDocs({
|
|
19679
|
+
kind: typeFilter,
|
|
19680
|
+
limit: Number.isFinite(effectiveLimit) ? effectiveLimit : void 0
|
|
19681
|
+
});
|
|
19682
|
+
const totalCount = docs.length;
|
|
19683
|
+
const projected = docs.map((doc) => ({
|
|
19684
|
+
id: doc.id,
|
|
19685
|
+
sha256: `${doc.sha256.slice(0, 8)}\u2026`,
|
|
19686
|
+
_sortSha: doc.sha256,
|
|
19687
|
+
kind: "blob",
|
|
19688
|
+
mime: doc.mimeType ?? "\u2014",
|
|
19689
|
+
size: doc.sizeBytes,
|
|
19690
|
+
description: void 0,
|
|
19691
|
+
labels: void 0,
|
|
19692
|
+
createdAt: doc.createdAt,
|
|
19693
|
+
refCount: 0,
|
|
19694
|
+
...doc.slug ? { slug: doc.slug } : {},
|
|
19695
|
+
...doc.kind ? { type: doc.kind } : {},
|
|
19696
|
+
ownerId: doc.ownerId,
|
|
19697
|
+
ownerType: doc.ownerType
|
|
19089
19698
|
}));
|
|
19090
19699
|
projected.sort(
|
|
19091
19700
|
(a, b) => comparator(
|
|
@@ -19093,12 +19702,10 @@ var init_docs2 = __esm({
|
|
|
19093
19702
|
{ sha256: b._sortSha, slug: b.slug, createdAt: b.createdAt }
|
|
19094
19703
|
)
|
|
19095
19704
|
);
|
|
19096
|
-
const
|
|
19097
|
-
const sliced = Number.isFinite(effectiveLimit) ? projected.slice(0, effectiveLimit) : projected;
|
|
19098
|
-
const truncated = totalCount > sliced.length;
|
|
19705
|
+
const truncated = totalCount > projected.length;
|
|
19099
19706
|
if (truncated) {
|
|
19100
19707
|
hintParts.push(
|
|
19101
|
-
`showing ${
|
|
19708
|
+
`showing ${projected.length} of ${totalCount} \u2014 pass --limit <N> to widen or page further.`
|
|
19102
19709
|
);
|
|
19103
19710
|
}
|
|
19104
19711
|
return lafsSuccess(
|
|
@@ -19107,12 +19714,12 @@ var init_docs2 = __esm({
|
|
|
19107
19714
|
ownerType: "task",
|
|
19108
19715
|
project: true,
|
|
19109
19716
|
...typeFilter !== void 0 ? { type: typeFilter } : {},
|
|
19110
|
-
count:
|
|
19717
|
+
count: projected.length,
|
|
19111
19718
|
...truncated ? { totalCount } : {},
|
|
19112
19719
|
limit: Number.isFinite(effectiveLimit) ? effectiveLimit : 0,
|
|
19113
19720
|
orderBy,
|
|
19114
19721
|
...hintParts.length > 0 ? { hint: hintParts.join(" ") } : {},
|
|
19115
|
-
attachments:
|
|
19722
|
+
attachments: projected.map(({ _sortSha: _drop, ...row }) => row),
|
|
19116
19723
|
attachmentBackend: backend
|
|
19117
19724
|
},
|
|
19118
19725
|
"list"
|
|
@@ -19120,28 +19727,20 @@ var init_docs2 = __esm({
|
|
|
19120
19727
|
}
|
|
19121
19728
|
const scopedOwner = ownerId;
|
|
19122
19729
|
const ownerType = inferOwnerType(scopedOwner);
|
|
19123
|
-
const
|
|
19124
|
-
const
|
|
19125
|
-
|
|
19126
|
-
|
|
19127
|
-
|
|
19128
|
-
|
|
19129
|
-
|
|
19130
|
-
|
|
19131
|
-
|
|
19132
|
-
|
|
19133
|
-
|
|
19134
|
-
|
|
19135
|
-
|
|
19136
|
-
kind:
|
|
19137
|
-
mime: m.attachment.kind === "local-file" || m.attachment.kind === "blob" ? m.attachment.mime : m.attachment.mime ?? "\u2014",
|
|
19138
|
-
size: m.attachment.kind === "local-file" || m.attachment.kind === "blob" ? m.attachment.size : void 0,
|
|
19139
|
-
description: m.attachment.description,
|
|
19140
|
-
labels: m.attachment.labels,
|
|
19141
|
-
createdAt: m.createdAt,
|
|
19142
|
-
refCount: m.refCount,
|
|
19143
|
-
...slug ? { slug } : {},
|
|
19144
|
-
...type2 ? { type: type2 } : {}
|
|
19730
|
+
const ownerDocs = await model.resolveByOwner(scopedOwner, { ownerType, kind: typeFilter });
|
|
19731
|
+
const projectedOwner = ownerDocs.map((doc) => ({
|
|
19732
|
+
id: doc.id,
|
|
19733
|
+
sha256: `${doc.sha256.slice(0, 8)}\u2026`,
|
|
19734
|
+
_sortSha: doc.sha256,
|
|
19735
|
+
kind: "blob",
|
|
19736
|
+
mime: doc.mimeType ?? "\u2014",
|
|
19737
|
+
size: doc.sizeBytes,
|
|
19738
|
+
description: void 0,
|
|
19739
|
+
labels: void 0,
|
|
19740
|
+
createdAt: doc.createdAt,
|
|
19741
|
+
refCount: 0,
|
|
19742
|
+
...doc.slug ? { slug: doc.slug } : {},
|
|
19743
|
+
...doc.kind ? { type: doc.kind } : {}
|
|
19145
19744
|
}));
|
|
19146
19745
|
projectedOwner.sort(
|
|
19147
19746
|
(a, b) => comparator(
|
|
@@ -19168,7 +19767,6 @@ var init_docs2 = __esm({
|
|
|
19168
19767
|
orderBy,
|
|
19169
19768
|
...hintParts.length > 0 ? { hint: hintParts.join(" ") } : {},
|
|
19170
19769
|
attachments: slicedOwner.map(({ _sortSha: _drop, ...row }) => row),
|
|
19171
|
-
// Cast: core returns 'llmtxt'|'legacy'; contracts uses 'legacy'|'llmstxt-v2' (drift T1529)
|
|
19172
19770
|
attachmentBackend: backend
|
|
19173
19771
|
},
|
|
19174
19772
|
"list"
|
|
@@ -19221,6 +19819,79 @@ var init_docs2 = __esm({
|
|
|
19221
19819
|
"generate"
|
|
19222
19820
|
);
|
|
19223
19821
|
},
|
|
19822
|
+
// ── docs.llm-output (T11137) ──────────────────────────────────────────────
|
|
19823
|
+
"llm-output": async (params) => {
|
|
19824
|
+
const forId = params.for;
|
|
19825
|
+
if (!forId) {
|
|
19826
|
+
return lafsError("E_INVALID_INPUT", "--for <entityId> is required", "llm-output");
|
|
19827
|
+
}
|
|
19828
|
+
let mode;
|
|
19829
|
+
if (params.mode !== void 0) {
|
|
19830
|
+
const raw = String(params.mode);
|
|
19831
|
+
if (!LLM_OUTPUT_MODES.includes(raw)) {
|
|
19832
|
+
return lafsError(
|
|
19833
|
+
"E_INVALID_INPUT",
|
|
19834
|
+
`--mode must be one of: ${LLM_OUTPUT_MODES.join("|")}`,
|
|
19835
|
+
"llm-output"
|
|
19836
|
+
);
|
|
19837
|
+
}
|
|
19838
|
+
mode = raw;
|
|
19839
|
+
} else {
|
|
19840
|
+
mode = /^T\d+$/i.test(forId) ? "task-export" : "attachment-bundle";
|
|
19841
|
+
}
|
|
19842
|
+
const cwd = getProjectRoot5();
|
|
19843
|
+
if (mode === "task-export") {
|
|
19844
|
+
const result2 = await exportTaskDocument({
|
|
19845
|
+
taskId: forId,
|
|
19846
|
+
includeAttachments: params.includeAttachments !== false,
|
|
19847
|
+
includeMemoryRefs: params.includeMemoryRefs === true,
|
|
19848
|
+
projectRoot: cwd
|
|
19849
|
+
});
|
|
19850
|
+
return lafsSuccess(
|
|
19851
|
+
{
|
|
19852
|
+
forId,
|
|
19853
|
+
mode: "task-export",
|
|
19854
|
+
content: result2.markdown,
|
|
19855
|
+
sectionCount: result2.pages,
|
|
19856
|
+
usedLlmtxtPackage: true
|
|
19857
|
+
},
|
|
19858
|
+
"llm-output"
|
|
19859
|
+
);
|
|
19860
|
+
}
|
|
19861
|
+
const result = await generateDocsLlmsTxt({ ownerId: forId, cwd });
|
|
19862
|
+
let aid, asha;
|
|
19863
|
+
if (params.attach) {
|
|
19864
|
+
const store = createAttachmentStore();
|
|
19865
|
+
const desc = {
|
|
19866
|
+
kind: "llms-txt",
|
|
19867
|
+
source: "generated",
|
|
19868
|
+
content: result.content,
|
|
19869
|
+
description: `llms.txt for ${forId}`,
|
|
19870
|
+
labels: ["llms-txt", "generated"]
|
|
19871
|
+
};
|
|
19872
|
+
const meta = await store.put(
|
|
19873
|
+
Buffer.from(result.content, "utf-8"),
|
|
19874
|
+
desc,
|
|
19875
|
+
inferOwnerType(forId),
|
|
19876
|
+
forId,
|
|
19877
|
+
"cleo-docs-llm-output",
|
|
19878
|
+
cwd
|
|
19879
|
+
);
|
|
19880
|
+
aid = meta.id;
|
|
19881
|
+
asha = meta.sha256;
|
|
19882
|
+
}
|
|
19883
|
+
return lafsSuccess(
|
|
19884
|
+
{
|
|
19885
|
+
forId,
|
|
19886
|
+
mode: "attachment-bundle",
|
|
19887
|
+
content: result.content,
|
|
19888
|
+
sectionCount: result.attachmentCount,
|
|
19889
|
+
usedLlmtxtPackage: result.usedLlmtxtPackage,
|
|
19890
|
+
...aid ? { attached: true, attachmentId: aid, attachmentSha256: asha } : { attached: false }
|
|
19891
|
+
},
|
|
19892
|
+
"llm-output"
|
|
19893
|
+
);
|
|
19894
|
+
},
|
|
19224
19895
|
// ── docs.fetch ─────────────────────────────────────────────────────────────
|
|
19225
19896
|
fetch: async (params) => {
|
|
19226
19897
|
const ref = params.attachmentRef;
|
|
@@ -19231,103 +19902,53 @@ var init_docs2 = __esm({
|
|
|
19231
19902
|
"fetch"
|
|
19232
19903
|
);
|
|
19233
19904
|
}
|
|
19234
|
-
const
|
|
19235
|
-
const
|
|
19236
|
-
|
|
19237
|
-
const looksLikeSlug = SLUG_PATTERN.test(ref) && !/^[0-9a-f]+$/i.test(ref);
|
|
19238
|
-
const isHexPrefix = /^[0-9a-f]{6,63}$/i.test(ref);
|
|
19239
|
-
let fetchResult = null;
|
|
19240
|
-
let metadata = isSha256 ? null : looksLikeAttId ? await store.getMetadata(ref) : null;
|
|
19241
|
-
if (metadata) {
|
|
19242
|
-
fetchResult = await store.get(metadata.sha256);
|
|
19243
|
-
} else if (isSha256) {
|
|
19244
|
-
fetchResult = await store.get(ref);
|
|
19245
|
-
if (fetchResult) {
|
|
19246
|
-
metadata = fetchResult.metadata;
|
|
19247
|
-
}
|
|
19248
|
-
}
|
|
19249
|
-
if (!metadata && looksLikeSlug) {
|
|
19250
|
-
const bySlug = await store.findBySlug(ref);
|
|
19251
|
-
if (bySlug) {
|
|
19252
|
-
metadata = bySlug.metadata;
|
|
19253
|
-
fetchResult = await store.get(metadata.sha256);
|
|
19254
|
-
}
|
|
19255
|
-
}
|
|
19256
|
-
if (!metadata && isHexPrefix) {
|
|
19257
|
-
const projectList = await store.listAllInProject();
|
|
19258
|
-
const seen = /* @__PURE__ */ new Map();
|
|
19259
|
-
for (const row of projectList) {
|
|
19260
|
-
if (row.metadata.sha256.toLowerCase().startsWith(ref.toLowerCase())) {
|
|
19261
|
-
seen.set(row.metadata.id, row);
|
|
19262
|
-
}
|
|
19263
|
-
}
|
|
19264
|
-
if (seen.size > 1) {
|
|
19265
|
-
return lafsError(
|
|
19266
|
-
"E_AMBIGUOUS",
|
|
19267
|
-
`sha256 prefix '${ref}' matches ${seen.size} attachments \u2014 provide more hex digits`,
|
|
19268
|
-
"fetch"
|
|
19269
|
-
);
|
|
19270
|
-
}
|
|
19271
|
-
const hit = seen.values().next().value;
|
|
19272
|
-
if (hit) {
|
|
19273
|
-
metadata = hit.metadata;
|
|
19274
|
-
fetchResult = await store.get(metadata.sha256);
|
|
19275
|
-
}
|
|
19276
|
-
}
|
|
19277
|
-
if (!metadata && !looksLikeAttId) {
|
|
19278
|
-
const direct = await store.getMetadata(ref);
|
|
19279
|
-
if (direct) {
|
|
19280
|
-
metadata = direct;
|
|
19281
|
-
fetchResult = await store.get(direct.sha256);
|
|
19282
|
-
}
|
|
19283
|
-
}
|
|
19284
|
-
if (!fetchResult || !metadata) {
|
|
19905
|
+
const model = createDocsReadModel();
|
|
19906
|
+
const doc = await model.resolveLatest(ref) ?? await model.resolveByAttachmentId(ref);
|
|
19907
|
+
if (!doc) {
|
|
19285
19908
|
return lafsError("E_NOT_FOUND", `Attachment not found: ${ref}`, "fetch");
|
|
19286
19909
|
}
|
|
19910
|
+
const content = await model.fetchContent(doc);
|
|
19911
|
+
if (content === null) {
|
|
19912
|
+
return lafsError("E_NOT_FOUND", `Content not retrievable: ${ref}`, "fetch");
|
|
19913
|
+
}
|
|
19287
19914
|
const cwd = getProjectRoot5();
|
|
19288
19915
|
const cleoDir = resolveCanonicalCleoDir(resolveProjectByCwd(cwd));
|
|
19289
19916
|
let storagePath;
|
|
19290
|
-
if (
|
|
19291
|
-
|
|
19292
|
-
|
|
19293
|
-
const prefix = metadata.sha256.slice(0, 2);
|
|
19294
|
-
const rest = metadata.sha256.slice(2);
|
|
19917
|
+
if (doc.sha256) {
|
|
19918
|
+
const prefix = doc.sha256.slice(0, 2);
|
|
19919
|
+
const rest = doc.sha256.slice(2);
|
|
19295
19920
|
const extMap = {
|
|
19296
19921
|
"text/markdown": ".md",
|
|
19297
19922
|
"text/plain": ".txt",
|
|
19298
19923
|
"application/json": ".json",
|
|
19299
19924
|
"application/pdf": ".pdf"
|
|
19300
19925
|
};
|
|
19301
|
-
const
|
|
19302
|
-
const ext = extMap[mime] ?? ".bin";
|
|
19926
|
+
const ext = extMap[doc.mimeType ?? ""] ?? ".bin";
|
|
19303
19927
|
storagePath = resolve2(cleoDir, "attachments", "sha256", prefix, `${rest}${ext}`);
|
|
19304
19928
|
}
|
|
19305
19929
|
const MAX_INLINE = 1024 * 1024;
|
|
19306
|
-
const
|
|
19307
|
-
const
|
|
19308
|
-
const
|
|
19930
|
+
const contentBytes = Buffer.from(content, "utf-8");
|
|
19931
|
+
const bytesBase64 = contentBytes.length <= MAX_INLINE ? contentBytes.toString("base64") : void 0;
|
|
19932
|
+
const backend = await currentAttachmentBackend();
|
|
19309
19933
|
return lafsSuccess(
|
|
19310
19934
|
{
|
|
19311
|
-
// Project the domain AttachmentMetadata (nested `attachment` object) into the
|
|
19312
|
-
// flat DocsAttachmentRow wire format consumed by CLI + HTTP callers.
|
|
19313
19935
|
metadata: {
|
|
19314
|
-
id:
|
|
19315
|
-
sha256:
|
|
19316
|
-
kind:
|
|
19317
|
-
mime:
|
|
19318
|
-
size:
|
|
19319
|
-
description:
|
|
19320
|
-
labels:
|
|
19321
|
-
createdAt:
|
|
19322
|
-
refCount:
|
|
19323
|
-
...
|
|
19324
|
-
...
|
|
19936
|
+
id: doc.id,
|
|
19937
|
+
sha256: doc.sha256,
|
|
19938
|
+
kind: "blob",
|
|
19939
|
+
mime: doc.mimeType ?? "text/plain",
|
|
19940
|
+
size: doc.sizeBytes,
|
|
19941
|
+
description: doc.summary ?? void 0,
|
|
19942
|
+
labels: void 0,
|
|
19943
|
+
createdAt: doc.createdAt,
|
|
19944
|
+
refCount: 0,
|
|
19945
|
+
...doc.slug ? { slug: doc.slug } : {},
|
|
19946
|
+
...doc.kind ? { type: doc.kind } : {}
|
|
19325
19947
|
},
|
|
19326
19948
|
path: storagePath,
|
|
19327
|
-
sizeBytes:
|
|
19949
|
+
sizeBytes: contentBytes.length,
|
|
19328
19950
|
...bytesBase64 !== void 0 ? { bytesBase64 } : {},
|
|
19329
19951
|
inlined: bytesBase64 !== void 0,
|
|
19330
|
-
// Cast: core returns 'llmtxt'|'legacy'; contracts uses 'legacy'|'llmstxt-v2' (T1529)
|
|
19331
19952
|
attachmentBackend: backend
|
|
19332
19953
|
},
|
|
19333
19954
|
"fetch"
|
|
@@ -19475,6 +20096,17 @@ var init_docs2 = __esm({
|
|
|
19475
20096
|
type: "changeset"
|
|
19476
20097
|
};
|
|
19477
20098
|
emitDocAttachmentObservation(changesetPayload, getProjectRoot5());
|
|
20099
|
+
try {
|
|
20100
|
+
writeAuditEntry(getProjectRoot5(), {
|
|
20101
|
+
op: "docs.add",
|
|
20102
|
+
slug: outcome.result.slug,
|
|
20103
|
+
type: "changeset",
|
|
20104
|
+
attachmentId: outcome.result.attachmentId,
|
|
20105
|
+
sha256: outcome.result.sha256,
|
|
20106
|
+
summary: `Added changeset '${outcome.result.slug}'`
|
|
20107
|
+
});
|
|
20108
|
+
} catch {
|
|
20109
|
+
}
|
|
19478
20110
|
return lafsSuccess(
|
|
19479
20111
|
{
|
|
19480
20112
|
attachmentId: outcome.result.attachmentId,
|
|
@@ -19487,9 +20119,8 @@ var init_docs2 = __esm({
|
|
|
19487
20119
|
kind: "blob",
|
|
19488
20120
|
ownerId: outcome.result.ownerId,
|
|
19489
20121
|
ownerType: "task",
|
|
19490
|
-
//
|
|
19491
|
-
|
|
19492
|
-
attachmentBackend: "legacy",
|
|
20122
|
+
// Cast: core returns 'llmtxt' (Wave C — legacy backend retired for mirror store).
|
|
20123
|
+
attachmentBackend: await currentAttachmentBackend(),
|
|
19493
20124
|
slug: outcome.result.slug,
|
|
19494
20125
|
type: "changeset"
|
|
19495
20126
|
},
|
|
@@ -19530,7 +20161,8 @@ var init_docs2 = __esm({
|
|
|
19530
20161
|
success: false,
|
|
19531
20162
|
error: {
|
|
19532
20163
|
code: "E_SLUG_RESERVED",
|
|
19533
|
-
message:
|
|
20164
|
+
message: SLUG_COLLISION_GUIDANCE.replaceAll("{slug}", slug ?? ""),
|
|
20165
|
+
fix: `cleo docs update ${slug ?? "<slug>"} --file <your-file>`,
|
|
19534
20166
|
details: {
|
|
19535
20167
|
suggestions: reservation.suggestions,
|
|
19536
20168
|
aliases: ["E_SLUG_TAKEN"]
|
|
@@ -19611,7 +20243,8 @@ var init_docs2 = __esm({
|
|
|
19611
20243
|
success: false,
|
|
19612
20244
|
error: {
|
|
19613
20245
|
code: "E_SLUG_RESERVED",
|
|
19614
|
-
message:
|
|
20246
|
+
message: SLUG_COLLISION_GUIDANCE.replaceAll("{slug}", err.slug ?? ""),
|
|
20247
|
+
fix: `cleo docs update ${err.slug ?? "<slug>"} --file <your-file>`,
|
|
19615
20248
|
details: {
|
|
19616
20249
|
suggestions: err.suggestions,
|
|
19617
20250
|
aliases: ["E_SLUG_TAKEN"]
|
|
@@ -19622,17 +20255,17 @@ var init_docs2 = __esm({
|
|
|
19622
20255
|
throw err;
|
|
19623
20256
|
}
|
|
19624
20257
|
if (adrNumber !== void 0 && slug !== void 0) consumeReservedSlug(slug);
|
|
19625
|
-
let backend = "
|
|
20258
|
+
let backend = "llmtxt";
|
|
19626
20259
|
try {
|
|
19627
|
-
const
|
|
19628
|
-
const
|
|
20260
|
+
const blobMirror = createAttachmentBlobStore(getProjectRoot5());
|
|
20261
|
+
const mirrorResult = await blobMirror.put(ownerId, {
|
|
19629
20262
|
name: absPath.split(/[\\/]/).pop() ?? meta.sha256.slice(0, 12),
|
|
19630
20263
|
data: new Uint8Array(bytes),
|
|
19631
20264
|
contentType: mime
|
|
19632
20265
|
});
|
|
19633
|
-
backend =
|
|
20266
|
+
backend = mirrorResult.backend;
|
|
19634
20267
|
} catch {
|
|
19635
|
-
backend = await
|
|
20268
|
+
backend = await currentAttachmentBackend();
|
|
19636
20269
|
}
|
|
19637
20270
|
import("@cleocode/core/internal").then(
|
|
19638
20271
|
({ ensureLlmtxtNode }) => ensureLlmtxtNode(
|
|
@@ -19652,6 +20285,18 @@ var init_docs2 = __esm({
|
|
|
19652
20285
|
...type2 !== void 0 ? { type: type2 } : {}
|
|
19653
20286
|
};
|
|
19654
20287
|
emitDocAttachmentObservation(filePayload, getProjectRoot5());
|
|
20288
|
+
try {
|
|
20289
|
+
writeAuditEntry(getProjectRoot5(), {
|
|
20290
|
+
op: "docs.add",
|
|
20291
|
+
slug,
|
|
20292
|
+
type: type2,
|
|
20293
|
+
attachmentId: meta.id,
|
|
20294
|
+
sha256: meta.sha256,
|
|
20295
|
+
ownerId,
|
|
20296
|
+
summary: `Added doc '${slug ?? meta.sha256.slice(0, 12)}'${type2 ? ` of type '${type2}'` : ""} for owner ${ownerId}`
|
|
20297
|
+
});
|
|
20298
|
+
} catch {
|
|
20299
|
+
}
|
|
19655
20300
|
return lafsSuccess(
|
|
19656
20301
|
{
|
|
19657
20302
|
attachmentId: meta.id,
|
|
@@ -19695,7 +20340,8 @@ var init_docs2 = __esm({
|
|
|
19695
20340
|
success: false,
|
|
19696
20341
|
error: {
|
|
19697
20342
|
code: "E_SLUG_RESERVED",
|
|
19698
|
-
message:
|
|
20343
|
+
message: SLUG_COLLISION_GUIDANCE.replaceAll("{slug}", err.slug ?? ""),
|
|
20344
|
+
fix: `cleo docs update ${err.slug ?? "<slug>"} --file <your-file>`,
|
|
19699
20345
|
details: {
|
|
19700
20346
|
suggestions: err.suggestions,
|
|
19701
20347
|
aliases: ["E_SLUG_TAKEN"]
|
|
@@ -19710,7 +20356,7 @@ var init_docs2 = __esm({
|
|
|
19710
20356
|
({ ensureLlmtxtNode }) => ensureLlmtxtNode(getProjectRoot5(), meta.sha256, `${ownerType}:${ownerId}`, url)
|
|
19711
20357
|
).catch(() => {
|
|
19712
20358
|
});
|
|
19713
|
-
const backend =
|
|
20359
|
+
const backend = await currentAttachmentBackend();
|
|
19714
20360
|
const urlPayload = {
|
|
19715
20361
|
kind: "doc-attachment",
|
|
19716
20362
|
attachmentId: meta.id,
|
|
@@ -19720,6 +20366,18 @@ var init_docs2 = __esm({
|
|
|
19720
20366
|
...type2 !== void 0 ? { type: type2 } : {}
|
|
19721
20367
|
};
|
|
19722
20368
|
emitDocAttachmentObservation(urlPayload, getProjectRoot5());
|
|
20369
|
+
try {
|
|
20370
|
+
writeAuditEntry(getProjectRoot5(), {
|
|
20371
|
+
op: "docs.add",
|
|
20372
|
+
slug,
|
|
20373
|
+
type: type2,
|
|
20374
|
+
attachmentId: meta.id,
|
|
20375
|
+
sha256: meta.sha256,
|
|
20376
|
+
ownerId,
|
|
20377
|
+
summary: `Added URL doc '${slug ?? url}'${type2 ? ` of type '${type2}'` : ""} for owner ${ownerId}`
|
|
20378
|
+
});
|
|
20379
|
+
} catch {
|
|
20380
|
+
}
|
|
19723
20381
|
return lafsSuccess(
|
|
19724
20382
|
{
|
|
19725
20383
|
attachmentId: meta.id,
|
|
@@ -19774,11 +20432,20 @@ var init_docs2 = __esm({
|
|
|
19774
20432
|
const blobPurged = derefResult.status === "removed";
|
|
19775
20433
|
const refCountAfter = derefResult.status === "derefd" ? derefResult.refCountAfter : 0;
|
|
19776
20434
|
try {
|
|
19777
|
-
const
|
|
19778
|
-
await
|
|
20435
|
+
const blobMirror = createAttachmentBlobStore(getProjectRoot5());
|
|
20436
|
+
await blobMirror.remove(attachmentId, fromOwner);
|
|
20437
|
+
} catch {
|
|
20438
|
+
}
|
|
20439
|
+
const backend = await currentAttachmentBackend();
|
|
20440
|
+
try {
|
|
20441
|
+
writeAuditEntry(getProjectRoot5(), {
|
|
20442
|
+
op: "docs.remove",
|
|
20443
|
+
attachmentId,
|
|
20444
|
+
ownerId: fromOwner,
|
|
20445
|
+
summary: `Removed attachment ${attachmentId} from owner ${fromOwner}${blobPurged ? " (blob purged)" : ""}`
|
|
20446
|
+
});
|
|
19779
20447
|
} catch {
|
|
19780
20448
|
}
|
|
19781
|
-
const backend = await resolveAttachmentBackend();
|
|
19782
20449
|
return lafsSuccess(
|
|
19783
20450
|
{
|
|
19784
20451
|
removed: blobPurged,
|
|
@@ -19827,6 +20494,42 @@ var init_docs2 = __esm({
|
|
|
19827
20494
|
"details" in outcome.error ? outcome.error.details : void 0
|
|
19828
20495
|
);
|
|
19829
20496
|
}
|
|
20497
|
+
let backend = "llmtxt";
|
|
20498
|
+
try {
|
|
20499
|
+
const blobMirror = createAttachmentBlobStore(getProjectRoot5());
|
|
20500
|
+
const updatedBytes = hasFile ? new Uint8Array(await readFile(resolve2(filePath))) : new Uint8Array(Buffer.from(inlineContent, "utf-8"));
|
|
20501
|
+
const contentType = hasFile ? mimeFromPath(resolve2(filePath)) : "text/plain";
|
|
20502
|
+
const store = createAttachmentStore();
|
|
20503
|
+
const rows = await store.listAllInProject(projectRoot);
|
|
20504
|
+
const ownerIds = Array.from(
|
|
20505
|
+
new Set(
|
|
20506
|
+
rows.filter((row) => row.metadata.id === outcome.result.attachmentId).map((row) => row.ownerId)
|
|
20507
|
+
)
|
|
20508
|
+
);
|
|
20509
|
+
const mirrorOwnerIds = ownerIds.length > 0 ? ownerIds : [`slug:${outcome.result.slug}`];
|
|
20510
|
+
for (const mirrorOwnerId of mirrorOwnerIds) {
|
|
20511
|
+
const mirrorResult = await blobMirror.put(mirrorOwnerId, {
|
|
20512
|
+
name: outcome.result.slug,
|
|
20513
|
+
data: updatedBytes,
|
|
20514
|
+
contentType
|
|
20515
|
+
});
|
|
20516
|
+
backend = mirrorResult.backend;
|
|
20517
|
+
}
|
|
20518
|
+
} catch {
|
|
20519
|
+
backend = await currentAttachmentBackend();
|
|
20520
|
+
}
|
|
20521
|
+
try {
|
|
20522
|
+
writeAuditEntry(getProjectRoot5(), {
|
|
20523
|
+
op: "docs.update",
|
|
20524
|
+
slug: outcome.result.slug,
|
|
20525
|
+
type: outcome.result.type ?? void 0,
|
|
20526
|
+
attachmentId: outcome.result.attachmentId,
|
|
20527
|
+
sha256: outcome.result.sha256,
|
|
20528
|
+
previousSha256: outcome.result.previousSha256 ?? void 0,
|
|
20529
|
+
summary: `Updated doc '${outcome.result.slug}'${outcome.result.lifecycleStatus ? ` (status: ${outcome.result.lifecycleStatus})` : ""}`
|
|
20530
|
+
});
|
|
20531
|
+
} catch {
|
|
20532
|
+
}
|
|
19830
20533
|
return lafsSuccess(
|
|
19831
20534
|
{
|
|
19832
20535
|
slug: outcome.result.slug,
|
|
@@ -19839,7 +20542,15 @@ var init_docs2 = __esm({
|
|
|
19839
20542
|
lifecycleStatus: outcome.result.lifecycleStatus,
|
|
19840
20543
|
updatedAt: outcome.result.updatedAt,
|
|
19841
20544
|
version: outcome.result.version,
|
|
20545
|
+
/** Version SSoT (T11181) — canonical version identifiers. */
|
|
20546
|
+
ownerVersion: outcome.result.ownerVersion,
|
|
20547
|
+
/** Sequential doc version counter (T11181). */
|
|
20548
|
+
docVersion: outcome.result.docVersion,
|
|
19842
20549
|
squashed: outcome.result.squashed,
|
|
20550
|
+
summary: outcome.result.summary,
|
|
20551
|
+
// T11053 — surface which backend stored the updated blob so
|
|
20552
|
+
// observability consumers can confirm the V2 mirror succeeded.
|
|
20553
|
+
attachmentBackend: backend,
|
|
19843
20554
|
...outcome.result.dryRun === true ? { dryRun: true } : {},
|
|
19844
20555
|
...outcome.result.wouldWrite !== void 0 ? { wouldWrite: outcome.result.wouldWrite } : {},
|
|
19845
20556
|
...outcome.result.wouldChange !== void 0 ? { wouldChange: outcome.result.wouldChange } : {}
|
|
@@ -19871,6 +20582,15 @@ var init_docs2 = __esm({
|
|
|
19871
20582
|
edgeId: result.edgeId,
|
|
19872
20583
|
...result.reason !== void 0 ? { reason: result.reason } : {}
|
|
19873
20584
|
};
|
|
20585
|
+
try {
|
|
20586
|
+
writeAuditEntry(getProjectRoot5(), {
|
|
20587
|
+
op: "docs.supersede",
|
|
20588
|
+
slug: result.newSlug,
|
|
20589
|
+
attachmentId: result.newAttachmentId,
|
|
20590
|
+
summary: `Superseded '${result.oldSlug}' \u2192 '${result.newSlug}'${result.reason ? ` (reason: ${result.reason})` : ""}`
|
|
20591
|
+
});
|
|
20592
|
+
} catch {
|
|
20593
|
+
}
|
|
19874
20594
|
return lafsSuccess(payload, "supersede");
|
|
19875
20595
|
} catch (err) {
|
|
19876
20596
|
const code = err && typeof err === "object" && "code" in err && typeof err.code === "number" ? (
|
|
@@ -46439,6 +47159,53 @@ var init_strict_args = __esm({
|
|
|
46439
47159
|
}
|
|
46440
47160
|
});
|
|
46441
47161
|
|
|
47162
|
+
// packages/cleo/src/cli/commands/docs/audit.ts
|
|
47163
|
+
var auditCommand3;
|
|
47164
|
+
var init_audit3 = __esm({
|
|
47165
|
+
"packages/cleo/src/cli/commands/docs/audit.ts"() {
|
|
47166
|
+
"use strict";
|
|
47167
|
+
init_src2();
|
|
47168
|
+
init_cli();
|
|
47169
|
+
init_define_cli_command();
|
|
47170
|
+
init_renderers();
|
|
47171
|
+
auditCommand3 = defineCommand({
|
|
47172
|
+
meta: {
|
|
47173
|
+
name: "audit",
|
|
47174
|
+
description: "Query the immutable docs audit trail (--slug <slug> or --verify for integrity check)"
|
|
47175
|
+
},
|
|
47176
|
+
args: {
|
|
47177
|
+
slug: {
|
|
47178
|
+
type: "string",
|
|
47179
|
+
description: "Show audit history for a specific document slug"
|
|
47180
|
+
},
|
|
47181
|
+
verify: {
|
|
47182
|
+
type: "boolean",
|
|
47183
|
+
description: "Verify checkpoint chain integrity across the full audit log"
|
|
47184
|
+
}
|
|
47185
|
+
},
|
|
47186
|
+
async run({ args }) {
|
|
47187
|
+
if (!args.slug && !args.verify) {
|
|
47188
|
+
cliError(
|
|
47189
|
+
"Pass --slug <slug> to view history or --verify to check integrity.",
|
|
47190
|
+
1 /* GENERAL_ERROR */
|
|
47191
|
+
);
|
|
47192
|
+
return;
|
|
47193
|
+
}
|
|
47194
|
+
await dispatchFromCli(
|
|
47195
|
+
"query",
|
|
47196
|
+
"docs",
|
|
47197
|
+
"audit",
|
|
47198
|
+
{
|
|
47199
|
+
...typeof args.slug === "string" ? { slug: args.slug } : {},
|
|
47200
|
+
...args.verify === true ? { verify: true } : {}
|
|
47201
|
+
},
|
|
47202
|
+
{ command: "docs audit" }
|
|
47203
|
+
);
|
|
47204
|
+
}
|
|
47205
|
+
});
|
|
47206
|
+
}
|
|
47207
|
+
});
|
|
47208
|
+
|
|
46442
47209
|
// packages/cleo/src/cli/commands/docs/graph.ts
|
|
46443
47210
|
import {
|
|
46444
47211
|
buildDocProvenanceGraph,
|
|
@@ -46931,7 +47698,7 @@ async function spawnDetachedServer(opts) {
|
|
|
46931
47698
|
if (handle) await handle.close();
|
|
46932
47699
|
return child;
|
|
46933
47700
|
}
|
|
46934
|
-
var DETACHED_CHILD_ENV, serveCommand, openCommand, stopCommand4, viewerStatusCommand, docsViewerSubcommands;
|
|
47701
|
+
var DETACHED_CHILD_ENV, serveCommand, openCommand, stopCommand4, viewerStatusCommand, runViewerStatus, viewerCommand, docsViewerSubcommands;
|
|
46935
47702
|
var init_docs_viewer = __esm({
|
|
46936
47703
|
"packages/cleo/src/cli/commands/docs-viewer.ts"() {
|
|
46937
47704
|
"use strict";
|
|
@@ -46944,7 +47711,7 @@ var init_docs_viewer = __esm({
|
|
|
46944
47711
|
serveCommand = defineCommand({
|
|
46945
47712
|
meta: {
|
|
46946
47713
|
name: "serve",
|
|
46947
|
-
description: "Run
|
|
47714
|
+
description: "[legacy] Run docs viewer \u2014 prefer `cleo docs viewer start`"
|
|
46948
47715
|
},
|
|
46949
47716
|
args: {
|
|
46950
47717
|
port: {
|
|
@@ -47115,7 +47882,7 @@ var init_docs_viewer = __esm({
|
|
|
47115
47882
|
openCommand = defineCommand({
|
|
47116
47883
|
meta: {
|
|
47117
47884
|
name: "open",
|
|
47118
|
-
description: "Open
|
|
47885
|
+
description: "[legacy] Open docs viewer in browser \u2014 prefer `cleo docs viewer open`"
|
|
47119
47886
|
},
|
|
47120
47887
|
args: {
|
|
47121
47888
|
slug: {
|
|
@@ -47212,7 +47979,7 @@ var init_docs_viewer = __esm({
|
|
|
47212
47979
|
stopCommand4 = defineCommand({
|
|
47213
47980
|
meta: {
|
|
47214
47981
|
name: "stop",
|
|
47215
|
-
description: "Stop the
|
|
47982
|
+
description: "[legacy] Stop the docs viewer \u2014 prefer `cleo docs viewer stop`"
|
|
47216
47983
|
},
|
|
47217
47984
|
args: {
|
|
47218
47985
|
timeout: {
|
|
@@ -47285,64 +48052,85 @@ var init_docs_viewer = __esm({
|
|
|
47285
48052
|
viewerStatusCommand = defineCommand({
|
|
47286
48053
|
meta: {
|
|
47287
48054
|
name: "viewer-status",
|
|
47288
|
-
description: "Report viewer
|
|
48055
|
+
description: "[legacy] Report viewer state \u2014 prefer `cleo docs viewer status`"
|
|
47289
48056
|
},
|
|
47290
48057
|
async run() {
|
|
47291
|
-
|
|
47292
|
-
|
|
47293
|
-
|
|
47294
|
-
|
|
47295
|
-
|
|
47296
|
-
|
|
47297
|
-
operation: "docs.viewer-status",
|
|
47298
|
-
message: "viewer not running"
|
|
47299
|
-
}
|
|
47300
|
-
);
|
|
47301
|
-
return;
|
|
47302
|
-
}
|
|
47303
|
-
const alive = isProcessAlive(record.pid);
|
|
47304
|
-
if (!alive) {
|
|
47305
|
-
await removeViewerPidFile();
|
|
47306
|
-
cliOutput(
|
|
47307
|
-
{
|
|
47308
|
-
running: false,
|
|
47309
|
-
reason: "stale pidfile",
|
|
47310
|
-
pid: record.pid,
|
|
47311
|
-
pidFile: viewerPidFilePath()
|
|
47312
|
-
},
|
|
47313
|
-
{
|
|
47314
|
-
command: "docs viewer-status",
|
|
47315
|
-
operation: "docs.viewer-status",
|
|
47316
|
-
message: `stale pidfile removed (pid ${record.pid} not alive)`
|
|
47317
|
-
}
|
|
47318
|
-
);
|
|
47319
|
-
return;
|
|
47320
|
-
}
|
|
48058
|
+
await runViewerStatus();
|
|
48059
|
+
}
|
|
48060
|
+
});
|
|
48061
|
+
runViewerStatus = async () => {
|
|
48062
|
+
const record = await readViewerPidFile();
|
|
48063
|
+
if (!record) {
|
|
47321
48064
|
cliOutput(
|
|
48065
|
+
{ running: false, pidFile: viewerPidFilePath() },
|
|
47322
48066
|
{
|
|
47323
|
-
|
|
48067
|
+
command: "docs viewer-status",
|
|
48068
|
+
operation: "docs.viewer-status",
|
|
48069
|
+
message: "viewer not running"
|
|
48070
|
+
}
|
|
48071
|
+
);
|
|
48072
|
+
return;
|
|
48073
|
+
}
|
|
48074
|
+
const alive = isProcessAlive(record.pid);
|
|
48075
|
+
if (!alive) {
|
|
48076
|
+
await removeViewerPidFile();
|
|
48077
|
+
cliOutput(
|
|
48078
|
+
{
|
|
48079
|
+
running: false,
|
|
48080
|
+
reason: "stale pidfile",
|
|
47324
48081
|
pid: record.pid,
|
|
47325
|
-
port: record.port,
|
|
47326
|
-
host: record.host,
|
|
47327
|
-
projectRoot: record.projectRoot,
|
|
47328
|
-
startedAt: record.startedAt,
|
|
47329
|
-
uptimeMs: Date.now() - record.startedAt,
|
|
47330
|
-
url: `http://${record.host}:${record.port}`,
|
|
47331
48082
|
pidFile: viewerPidFilePath()
|
|
47332
48083
|
},
|
|
47333
48084
|
{
|
|
47334
48085
|
command: "docs viewer-status",
|
|
47335
48086
|
operation: "docs.viewer-status",
|
|
47336
|
-
message: `
|
|
48087
|
+
message: `stale pidfile removed (pid ${record.pid} not alive)`
|
|
47337
48088
|
}
|
|
47338
48089
|
);
|
|
48090
|
+
return;
|
|
48091
|
+
}
|
|
48092
|
+
cliOutput(
|
|
48093
|
+
{
|
|
48094
|
+
running: true,
|
|
48095
|
+
pid: record.pid,
|
|
48096
|
+
port: record.port,
|
|
48097
|
+
host: record.host,
|
|
48098
|
+
projectRoot: record.projectRoot,
|
|
48099
|
+
startedAt: record.startedAt,
|
|
48100
|
+
uptimeMs: Date.now() - record.startedAt,
|
|
48101
|
+
url: `http://${record.host}:${record.port}`,
|
|
48102
|
+
pidFile: viewerPidFilePath()
|
|
48103
|
+
},
|
|
48104
|
+
{
|
|
48105
|
+
command: "docs viewer-status",
|
|
48106
|
+
operation: "docs.viewer-status",
|
|
48107
|
+
message: `viewer running (pid ${record.pid})`
|
|
48108
|
+
}
|
|
48109
|
+
);
|
|
48110
|
+
};
|
|
48111
|
+
viewerCommand = defineCommand({
|
|
48112
|
+
meta: {
|
|
48113
|
+
name: "viewer",
|
|
48114
|
+
description: "Manage the docs web viewer lifecycle (start/stop/open/status)"
|
|
48115
|
+
},
|
|
48116
|
+
subCommands: {
|
|
48117
|
+
start: serveCommand,
|
|
48118
|
+
stop: stopCommand4,
|
|
48119
|
+
open: openCommand,
|
|
48120
|
+
status: viewerStatusCommand
|
|
48121
|
+
},
|
|
48122
|
+
async run({ cmd, rawArgs }) {
|
|
48123
|
+
const firstArg = rawArgs?.find((a) => !a.startsWith("-"));
|
|
48124
|
+
if (firstArg && cmd.subCommands && firstArg in cmd.subCommands) return;
|
|
48125
|
+
await runViewerStatus();
|
|
47339
48126
|
}
|
|
47340
48127
|
});
|
|
47341
48128
|
docsViewerSubcommands = {
|
|
47342
48129
|
serve: serveCommand,
|
|
47343
48130
|
open: openCommand,
|
|
47344
48131
|
stop: stopCommand4,
|
|
47345
|
-
"viewer-status": viewerStatusCommand
|
|
48132
|
+
"viewer-status": viewerStatusCommand,
|
|
48133
|
+
viewer: viewerCommand
|
|
47346
48134
|
};
|
|
47347
48135
|
}
|
|
47348
48136
|
});
|
|
@@ -47350,10 +48138,12 @@ var init_docs_viewer = __esm({
|
|
|
47350
48138
|
// packages/cleo/src/cli/commands/docs.ts
|
|
47351
48139
|
var docs_exports = {};
|
|
47352
48140
|
__export(docs_exports, {
|
|
48141
|
+
_llmOutputCommand: () => _llmOutputCommand,
|
|
47353
48142
|
docsCommand: () => docsCommand
|
|
47354
48143
|
});
|
|
47355
48144
|
import { appendFile, mkdir as mkdir2, readdir, readFile as readFile4, writeFile as writeFile2 } from "node:fs/promises";
|
|
47356
48145
|
import { dirname as dirname8, isAbsolute as isAbsolute2, join as join21, resolve as resolve5 } from "node:path";
|
|
48146
|
+
import { pushWarning as pushWarning3 } from "@cleocode/core";
|
|
47357
48147
|
import {
|
|
47358
48148
|
CleoError as CleoError3,
|
|
47359
48149
|
CounterMismatchError,
|
|
@@ -47494,7 +48284,7 @@ function loadCliRegistry(projectRoot) {
|
|
|
47494
48284
|
throw err;
|
|
47495
48285
|
}
|
|
47496
48286
|
}
|
|
47497
|
-
var docsOutputFlagHelp, docsOutputArgs, addCommand5, listCommand8, fetchCommand, removeCommand2, supersedeCommandArgs, supersedeCommand, generateCommand, exportCommand4, searchCommand, findCommand3, mergeCommand, rankCommand, docsUpdateOperation, docsUpdateSchema, docsUpdateArgs, docsUpdateCliArgs, updateCommand, versionsCommand, publishCommand2, publishPrCommand, syncCommand3, statusCommand7, gapCheckCommand, importCommand2, schemaCommand, listTypesCommand, docsCommand;
|
|
48287
|
+
var docsOutputFlagHelp, docsOutputArgs, addCommand5, listCommand8, fetchCommand, removeCommand2, supersedeCommandArgs, supersedeCommand, generateCommand, exportCommand4, _llmOutputCommand, llmOutputCommand, searchCommand, findCommand3, mergeCommand, queryCommand, rankCommand, docsUpdateOperation, docsUpdateSchema, docsUpdateArgs, docsUpdateCliArgs, updateCommand, versionsCommand, publishCommand2, publishPrCommand, checkCommand6, syncCommand3, statusCommand7, gapCheckCommand, importCommand2, schemaCommand, listTypesCommand, docsCommand;
|
|
47498
48288
|
var init_docs3 = __esm({
|
|
47499
48289
|
"packages/cleo/src/cli/commands/docs.ts"() {
|
|
47500
48290
|
"use strict";
|
|
@@ -47506,6 +48296,7 @@ var init_docs3 = __esm({
|
|
|
47506
48296
|
init_registry_args();
|
|
47507
48297
|
init_strict_args();
|
|
47508
48298
|
init_renderers();
|
|
48299
|
+
init_audit3();
|
|
47509
48300
|
init_graph2();
|
|
47510
48301
|
init_docs_viewer();
|
|
47511
48302
|
docsOutputFlagHelp = " --json Emit the canonical LAFS JSON envelope (also accepted as a global flag)\n --output <mode> Re-render the result as envelope|id|table|count|silent (also accepted as a global flag)";
|
|
@@ -47522,7 +48313,7 @@ var init_docs3 = __esm({
|
|
|
47522
48313
|
addCommand5 = defineCommand({
|
|
47523
48314
|
meta: {
|
|
47524
48315
|
name: "add",
|
|
47525
|
-
description: 'Attach a local file or remote URL to a CLEO entity (task, session, observation). Owner type is inferred from the ID prefix: T### \u2192 task, ses_* \u2192 session, O-* \u2192 observation. Use --slug to set a human-friendly alias (unique per project) (T9636).\n\nPositional arguments:\n <owner-id> Owner entity ID (T###, ses_*, O-*) \u2014 required\n [file] Local file path to attach \u2014 optional when --url is set\n\nNamed arguments:\n --url <url> Remote URL to attach (instead of a local file)\n --desc <text> Free-text description of this attachment\n --labels <csv> Comma-separated labels (e.g. rfc,spec)\n --attached-by <name> Agent identity that created the attachment (default: "human")\n --slug <kebab> Human-friendly alias, unique per project (T9636)\n --title <text> Human-readable title \u2014 REQUIRED for --type adr when --slug is omitted (T10360)\n --type <kind> Taxonomy classification \u2014 run `cleo docs
|
|
48316
|
+
description: 'Attach a local file or remote URL to a CLEO entity (task, session, observation). Owner type is inferred from the ID prefix: T### \u2192 task, ses_* \u2192 session, O-* \u2192 observation. Use --slug to set a human-friendly alias (unique per project) (T9636).\n\nPositional arguments:\n <owner-id> Owner entity ID (T###, ses_*, O-*) \u2014 required\n [file] Local file path to attach \u2014 optional when --url is set\n\nNamed arguments:\n --url <url> Remote URL to attach (instead of a local file)\n --desc <text> Free-text description of this attachment\n --labels <csv> Comma-separated labels (e.g. rfc,spec)\n --attached-by <name> Agent identity that created the attachment (default: "human")\n --slug <kebab> Human-friendly alias, unique per project (T9636)\n --title <text> Human-readable title \u2014 REQUIRED for --type adr when --slug is omitted (T10360)\n --type <kind> Taxonomy classification \u2014 run `cleo docs schema` for kinds\n --allow-similar Bypass the slug-similarity warn \u2014 every bypass is audited\n to .cleo/audit/similar-bypass.jsonl (T10361)\n --strict Enforce body-schema (requiredSections) \u2014 fail with\n E_DOC_SCHEMA_MISMATCH instead of warning (T10160)\n' + docsOutputFlagHelp + "\n\nValidation behaviors:\n \u2022 Unknown flags \u2192 E_UNKNOWN_FLAG with did-you-mean suggestions (T10359)\n \u2022 Slug collision \u2192 E_SLUG_RESERVED + 3 alternative slugs (T10386)\n \u2022 Near-duplicate slug \u2192 W_SLUG_SIMILAR warning unless --allow-similar (T10361)\n \u2022 For --type adr without --slug, slug auto-allocates as `adr-NNN-<kebab-title>` via the\n central allocator (T10360 \u2014 closes T10153). --title is required in this case."
|
|
47526
48317
|
},
|
|
47527
48318
|
args: {
|
|
47528
48319
|
"owner-id": {
|
|
@@ -47561,7 +48352,7 @@ var init_docs3 = __esm({
|
|
|
47561
48352
|
},
|
|
47562
48353
|
type: {
|
|
47563
48354
|
type: "string",
|
|
47564
|
-
description: "Taxonomy classification \u2014 run `cleo docs
|
|
48355
|
+
description: "Taxonomy classification \u2014 run `cleo docs schema` to enumerate registered kinds (T9637 / T9788 / T11142)"
|
|
47565
48356
|
},
|
|
47566
48357
|
"allow-similar": {
|
|
47567
48358
|
type: "boolean",
|
|
@@ -47916,6 +48707,12 @@ var init_docs3 = __esm({
|
|
|
47916
48707
|
},
|
|
47917
48708
|
args: supersedeCommandArgs,
|
|
47918
48709
|
async run({ args, rawArgs }) {
|
|
48710
|
+
pushWarning3({
|
|
48711
|
+
code: "W_DEPRECATED_COMMAND",
|
|
48712
|
+
message: "cleo docs supersede is deprecated - use `cleo docs update` for new work (T11179)",
|
|
48713
|
+
deprecated: "docs supersede",
|
|
48714
|
+
replacement: "docs update"
|
|
48715
|
+
});
|
|
47919
48716
|
try {
|
|
47920
48717
|
assertKnownFlags(rawArgs, supersedeCommandArgs, "docs supersede");
|
|
47921
48718
|
} catch (err) {
|
|
@@ -47958,6 +48755,9 @@ var init_docs3 = __esm({
|
|
|
47958
48755
|
}
|
|
47959
48756
|
},
|
|
47960
48757
|
async run({ args }) {
|
|
48758
|
+
humanInfo(
|
|
48759
|
+
`cleo: docs generate is deprecated \u2014 use \`cleo docs llm-output --for ${args.for} --mode attachment-bundle\` (T11137)`
|
|
48760
|
+
);
|
|
47961
48761
|
await dispatchFromCli(
|
|
47962
48762
|
"query",
|
|
47963
48763
|
"docs",
|
|
@@ -48006,7 +48806,8 @@ var init_docs3 = __esm({
|
|
|
48006
48806
|
const includeMemoryRefs = args["include-memory-refs"] === true;
|
|
48007
48807
|
const projectRoot = getProjectRoot38();
|
|
48008
48808
|
try {
|
|
48009
|
-
const result = await dispatchDocsRaw("query", "
|
|
48809
|
+
const result = await dispatchDocsRaw("query", "llm-output", {
|
|
48810
|
+
mode: "task-export",
|
|
48010
48811
|
taskId,
|
|
48011
48812
|
includeAttachments,
|
|
48012
48813
|
includeMemoryRefs
|
|
@@ -48015,20 +48816,20 @@ var init_docs3 = __esm({
|
|
|
48015
48816
|
if (typeof args.out === "string" && args.out.length > 0) {
|
|
48016
48817
|
const outPath = isAbsolute2(args.out) ? args.out : resolve5(projectRoot, args.out);
|
|
48017
48818
|
await mkdir2(dirname8(outPath), { recursive: true });
|
|
48018
|
-
await writeFile2(outPath, result.
|
|
48819
|
+
await writeFile2(outPath, result.content, "utf8");
|
|
48019
48820
|
writtenPath = outPath;
|
|
48020
48821
|
}
|
|
48021
48822
|
if (args.json) {
|
|
48022
48823
|
cliOutput(
|
|
48023
|
-
{ markdown: result.
|
|
48824
|
+
{ markdown: result.content, pages: result.sectionCount, path: writtenPath ?? null },
|
|
48024
48825
|
{ command: "docs export", operation: "docs.export" }
|
|
48025
48826
|
);
|
|
48026
48827
|
} else {
|
|
48027
48828
|
if (writtenPath) {
|
|
48028
|
-
humanInfo(`Wrote ${result.
|
|
48829
|
+
humanInfo(`Wrote ${result.sectionCount} page(s) to ${writtenPath}`);
|
|
48029
48830
|
} else {
|
|
48030
|
-
process.stdout.write(result.
|
|
48031
|
-
if (!result.
|
|
48831
|
+
process.stdout.write(result.content);
|
|
48832
|
+
if (!result.content.endsWith("\n")) process.stdout.write("\n");
|
|
48032
48833
|
}
|
|
48033
48834
|
}
|
|
48034
48835
|
} catch (err) {
|
|
@@ -48040,6 +48841,167 @@ var init_docs3 = __esm({
|
|
|
48040
48841
|
}
|
|
48041
48842
|
}
|
|
48042
48843
|
});
|
|
48844
|
+
_llmOutputCommand = defineCommand({
|
|
48845
|
+
meta: {
|
|
48846
|
+
name: "llm-output",
|
|
48847
|
+
description: "Unified LLM output: task export (rich Markdown with frontmatter + body + attachments + memory refs) or attachment-bundle (llms.txt summarising all attachments). Replaces `docs export` and `docs generate`."
|
|
48848
|
+
},
|
|
48849
|
+
args: {
|
|
48850
|
+
for: {
|
|
48851
|
+
type: "string",
|
|
48852
|
+
description: "Target entity ID (T###, ses_*, O-*, D-*, L-*, P-*)",
|
|
48853
|
+
required: true
|
|
48854
|
+
},
|
|
48855
|
+
mode: {
|
|
48856
|
+
type: "string",
|
|
48857
|
+
description: "Output mode: 'task-export' or 'attachment-bundle' (auto-detected)"
|
|
48858
|
+
},
|
|
48859
|
+
out: { type: "string", description: "Output file path. Omit for stdout." },
|
|
48860
|
+
"include-attachments": {
|
|
48861
|
+
type: "boolean",
|
|
48862
|
+
default: true,
|
|
48863
|
+
description: "Append attachment manifest (task-export, default: true)"
|
|
48864
|
+
},
|
|
48865
|
+
"include-memory-refs": {
|
|
48866
|
+
type: "boolean",
|
|
48867
|
+
default: false,
|
|
48868
|
+
description: "Append BRAIN memory refs (task-export, default: false)"
|
|
48869
|
+
},
|
|
48870
|
+
attach: {
|
|
48871
|
+
type: "boolean",
|
|
48872
|
+
description: "Save as llms-txt attachment on target (attachment-bundle)"
|
|
48873
|
+
},
|
|
48874
|
+
...docsOutputArgs
|
|
48875
|
+
},
|
|
48876
|
+
async run({ args }) {
|
|
48877
|
+
const forId = String(args.for);
|
|
48878
|
+
const projectRoot = getProjectRoot38();
|
|
48879
|
+
try {
|
|
48880
|
+
const result = await dispatchDocsRaw("query", "llm-output", {
|
|
48881
|
+
for: forId,
|
|
48882
|
+
...typeof args.mode === "string" ? { mode: args.mode } : {},
|
|
48883
|
+
includeAttachments: args["include-attachments"] !== false,
|
|
48884
|
+
includeMemoryRefs: args["include-memory-refs"] === true,
|
|
48885
|
+
...args.attach ? { attach: true } : {}
|
|
48886
|
+
});
|
|
48887
|
+
let writtenPath;
|
|
48888
|
+
if (typeof args.out === "string" && args.out.length > 0) {
|
|
48889
|
+
const outPath = isAbsolute2(args.out) ? args.out : resolve5(projectRoot, args.out);
|
|
48890
|
+
await mkdir2(dirname8(outPath), { recursive: true });
|
|
48891
|
+
await writeFile2(outPath, result.content, "utf8");
|
|
48892
|
+
writtenPath = outPath;
|
|
48893
|
+
}
|
|
48894
|
+
if (args.json) {
|
|
48895
|
+
cliOutput(
|
|
48896
|
+
{
|
|
48897
|
+
forId: result.forId,
|
|
48898
|
+
mode: result.mode,
|
|
48899
|
+
content: result.content,
|
|
48900
|
+
sectionCount: result.sectionCount,
|
|
48901
|
+
usedLlmtxtPackage: result.usedLlmtxtPackage,
|
|
48902
|
+
attached: result.attached,
|
|
48903
|
+
attachmentId: result.attachmentId,
|
|
48904
|
+
attachmentSha256: result.attachmentSha256,
|
|
48905
|
+
path: writtenPath ?? null
|
|
48906
|
+
},
|
|
48907
|
+
{ command: "docs llm-output", operation: "docs.llm-output" }
|
|
48908
|
+
);
|
|
48909
|
+
} else {
|
|
48910
|
+
if (writtenPath) {
|
|
48911
|
+
humanInfo(
|
|
48912
|
+
`Wrote ${result.sectionCount} ${result.mode === "task-export" ? "page(s)" : "section(s)"} to ${writtenPath}`
|
|
48913
|
+
);
|
|
48914
|
+
} else {
|
|
48915
|
+
process.stdout.write(result.content);
|
|
48916
|
+
if (!result.content.endsWith("\n")) process.stdout.write("\n");
|
|
48917
|
+
}
|
|
48918
|
+
}
|
|
48919
|
+
} catch (err) {
|
|
48920
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
48921
|
+
cliError(`docs llm-output failed: ${message}`, 1 /* GENERAL_ERROR */, {
|
|
48922
|
+
name: "E_DOCS_LLM_OUTPUT_FAILED"
|
|
48923
|
+
});
|
|
48924
|
+
process.exit(1 /* GENERAL_ERROR */);
|
|
48925
|
+
}
|
|
48926
|
+
}
|
|
48927
|
+
});
|
|
48928
|
+
llmOutputCommand = defineCommand({
|
|
48929
|
+
meta: {
|
|
48930
|
+
name: "llm-output",
|
|
48931
|
+
description: "Unified LLM output: task export (rich Markdown) or attachment-bundle (llms.txt). Replaces `docs export` and `docs generate`."
|
|
48932
|
+
},
|
|
48933
|
+
args: {
|
|
48934
|
+
for: { type: "string", description: "Target entity ID", required: true },
|
|
48935
|
+
mode: {
|
|
48936
|
+
type: "string",
|
|
48937
|
+
description: "Output mode: task-export|attachment-bundle (auto-detected)"
|
|
48938
|
+
},
|
|
48939
|
+
out: { type: "string", description: "Output file path" },
|
|
48940
|
+
"include-attachments": {
|
|
48941
|
+
type: "boolean",
|
|
48942
|
+
default: true,
|
|
48943
|
+
description: "Include attachment manifest (task-export)"
|
|
48944
|
+
},
|
|
48945
|
+
"include-memory-refs": {
|
|
48946
|
+
type: "boolean",
|
|
48947
|
+
default: false,
|
|
48948
|
+
description: "Include memory refs (task-export)"
|
|
48949
|
+
},
|
|
48950
|
+
attach: { type: "boolean", description: "Save as llms-txt attachment (attachment-bundle)" },
|
|
48951
|
+
...docsOutputArgs
|
|
48952
|
+
},
|
|
48953
|
+
async run({ args }) {
|
|
48954
|
+
const forId = String(args.for);
|
|
48955
|
+
const projectRoot = getProjectRoot38();
|
|
48956
|
+
try {
|
|
48957
|
+
const result = await dispatchDocsRaw("query", "llm-output", {
|
|
48958
|
+
for: forId,
|
|
48959
|
+
...typeof args.mode === "string" ? { mode: args.mode } : {},
|
|
48960
|
+
includeAttachments: args["include-attachments"] !== false,
|
|
48961
|
+
includeMemoryRefs: args["include-memory-refs"] === true,
|
|
48962
|
+
...args.attach ? { attach: true } : {}
|
|
48963
|
+
});
|
|
48964
|
+
let writtenPath;
|
|
48965
|
+
if (typeof args.out === "string" && args.out.length > 0) {
|
|
48966
|
+
const outPath = isAbsolute2(args.out) ? args.out : resolve5(projectRoot, args.out);
|
|
48967
|
+
await mkdir2(dirname8(outPath), { recursive: true });
|
|
48968
|
+
await writeFile2(outPath, result.content, "utf8");
|
|
48969
|
+
writtenPath = outPath;
|
|
48970
|
+
}
|
|
48971
|
+
if (args.json) {
|
|
48972
|
+
cliOutput(
|
|
48973
|
+
{
|
|
48974
|
+
forId: result.forId,
|
|
48975
|
+
mode: result.mode,
|
|
48976
|
+
content: result.content,
|
|
48977
|
+
sectionCount: result.sectionCount,
|
|
48978
|
+
usedLlmtxtPackage: result.usedLlmtxtPackage,
|
|
48979
|
+
attached: result.attached,
|
|
48980
|
+
attachmentId: result.attachmentId,
|
|
48981
|
+
attachmentSha256: result.attachmentSha256,
|
|
48982
|
+
path: writtenPath ?? null
|
|
48983
|
+
},
|
|
48984
|
+
{ command: "docs llm-output", operation: "docs.llm-output" }
|
|
48985
|
+
);
|
|
48986
|
+
} else {
|
|
48987
|
+
if (writtenPath) {
|
|
48988
|
+
humanInfo(
|
|
48989
|
+
`Wrote ${result.sectionCount} ${result.mode === "task-export" ? "page(s)" : "section(s)"} to ${writtenPath}`
|
|
48990
|
+
);
|
|
48991
|
+
} else {
|
|
48992
|
+
process.stdout.write(result.content);
|
|
48993
|
+
if (!result.content.endsWith("\n")) process.stdout.write("\n");
|
|
48994
|
+
}
|
|
48995
|
+
}
|
|
48996
|
+
} catch (err) {
|
|
48997
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
48998
|
+
cliError(`docs llm-output failed: ${message}`, 1 /* GENERAL_ERROR */, {
|
|
48999
|
+
name: "E_DOCS_LLM_OUTPUT_FAILED"
|
|
49000
|
+
});
|
|
49001
|
+
process.exit(1 /* GENERAL_ERROR */);
|
|
49002
|
+
}
|
|
49003
|
+
}
|
|
49004
|
+
});
|
|
48043
49005
|
searchCommand = defineCommand({
|
|
48044
49006
|
meta: {
|
|
48045
49007
|
name: "search",
|
|
@@ -48242,6 +49204,157 @@ var init_docs3 = __esm({
|
|
|
48242
49204
|
}
|
|
48243
49205
|
}
|
|
48244
49206
|
});
|
|
49207
|
+
queryCommand = defineCommand({
|
|
49208
|
+
meta: {
|
|
49209
|
+
name: "query",
|
|
49210
|
+
description: 'Unified docs query surface: semantic search, similar-doc discovery, and entity ranking. Subsumes the legacy search, find, and rank subcommands into one consistent surface.\n\nModes (mutually exclusive):\n cleo docs query "<text>" Free-text search\n cleo docs query --similar <slug> Find similar to a slug\n cleo docs query --for <id> Rank for an entity\n\nCommon flags: --limit <n>, --type <kind>, --json\nFree-text search flags: --owner <id>\nSimilar-to-slug flags: --threshold <0..1>, --all-kinds\nEntity-ranking flags: --text "<query>"\n\n' + docsOutputFlagHelp
|
|
49211
|
+
},
|
|
49212
|
+
args: {
|
|
49213
|
+
query: {
|
|
49214
|
+
type: "positional",
|
|
49215
|
+
description: "Free-text query for semantic search",
|
|
49216
|
+
required: false
|
|
49217
|
+
},
|
|
49218
|
+
similar: {
|
|
49219
|
+
type: "string",
|
|
49220
|
+
description: "Slug of seed doc to find similar docs against (find mode)"
|
|
49221
|
+
},
|
|
49222
|
+
for: {
|
|
49223
|
+
type: "string",
|
|
49224
|
+
description: "Owner entity ID to rank attachments for (rank mode)"
|
|
49225
|
+
},
|
|
49226
|
+
text: {
|
|
49227
|
+
type: "string",
|
|
49228
|
+
description: "Custom query string for the rank mode (default: owner ID)"
|
|
49229
|
+
},
|
|
49230
|
+
type: {
|
|
49231
|
+
type: "string",
|
|
49232
|
+
description: "Filter by taxonomy type: spec|adr|research|handoff|note|llm-readme"
|
|
49233
|
+
},
|
|
49234
|
+
owner: {
|
|
49235
|
+
type: "string",
|
|
49236
|
+
description: "Scope free-text search to a specific owner entity ID"
|
|
49237
|
+
},
|
|
49238
|
+
limit: {
|
|
49239
|
+
type: "string",
|
|
49240
|
+
description: "Maximum number of results to return (default: 10)"
|
|
49241
|
+
},
|
|
49242
|
+
threshold: {
|
|
49243
|
+
type: "string",
|
|
49244
|
+
description: "Minimum cosine similarity score in [0, 1] (for --similar mode, default: 0.5)"
|
|
49245
|
+
},
|
|
49246
|
+
"all-kinds": {
|
|
49247
|
+
type: "boolean",
|
|
49248
|
+
description: "Disable the same-kind filter and rank across every DocKind (for --similar mode)"
|
|
49249
|
+
},
|
|
49250
|
+
...docsOutputArgs
|
|
49251
|
+
},
|
|
49252
|
+
async run({ args, rawArgs }) {
|
|
49253
|
+
try {
|
|
49254
|
+
assertKnownFlags(rawArgs, queryCommand.args, "docs query");
|
|
49255
|
+
} catch (err) {
|
|
49256
|
+
if (err instanceof UnknownFlagError) {
|
|
49257
|
+
cliError(err.message, 6 /* VALIDATION_ERROR */, {
|
|
49258
|
+
name: err.code,
|
|
49259
|
+
fix: err.fix,
|
|
49260
|
+
alternatives: err.suggestions.map((s) => ({ action: s, command: s })),
|
|
49261
|
+
details: { flag: err.flag, knownFlags: err.knownFlags }
|
|
49262
|
+
});
|
|
49263
|
+
process.exit(6 /* VALIDATION_ERROR */);
|
|
49264
|
+
}
|
|
49265
|
+
throw err;
|
|
49266
|
+
}
|
|
49267
|
+
const similarSlug = typeof args.similar === "string" ? args.similar.trim() : "";
|
|
49268
|
+
const forId = typeof args.for === "string" ? args.for.trim() : "";
|
|
49269
|
+
const textQuery = typeof args.query === "string" ? String(args.query) : "";
|
|
49270
|
+
const customQuery = typeof args.text === "string" ? String(args.text) : void 0;
|
|
49271
|
+
const typeFilter = typeof args.type === "string" ? String(args.type) : void 0;
|
|
49272
|
+
const ownerScope = typeof args.owner === "string" ? String(args.owner) : void 0;
|
|
49273
|
+
const modes = [];
|
|
49274
|
+
if (similarSlug.length > 0) modes.push("--similar");
|
|
49275
|
+
if (forId.length > 0) modes.push("--for");
|
|
49276
|
+
if (textQuery.length > 0) modes.push("<query>");
|
|
49277
|
+
if (modes.length === 0) {
|
|
49278
|
+
cliError(
|
|
49279
|
+
"docs query requires a query mode: pass a free-text <query>, --similar <slug>, or --for <id>",
|
|
49280
|
+
6 /* VALIDATION_ERROR */,
|
|
49281
|
+
{
|
|
49282
|
+
name: "E_VALIDATION",
|
|
49283
|
+
fix: 'Examples: cleo docs query "authentication flow" | cleo docs query --similar adr-073 | cleo docs query --for T123'
|
|
49284
|
+
}
|
|
49285
|
+
);
|
|
49286
|
+
process.exit(6 /* VALIDATION_ERROR */);
|
|
49287
|
+
}
|
|
49288
|
+
if (modes.length > 1) {
|
|
49289
|
+
cliError(
|
|
49290
|
+
`docs query modes are mutually exclusive \u2014 got ${modes.join(", ")}. Choose one.`,
|
|
49291
|
+
6 /* VALIDATION_ERROR */,
|
|
49292
|
+
{
|
|
49293
|
+
name: "E_VALIDATION",
|
|
49294
|
+
fix: "Pass exactly one of: free-text <query>, --similar <slug>, or --for <id>"
|
|
49295
|
+
}
|
|
49296
|
+
);
|
|
49297
|
+
process.exit(6 /* VALIDATION_ERROR */);
|
|
49298
|
+
}
|
|
49299
|
+
let limit;
|
|
49300
|
+
if (typeof args.limit === "string") {
|
|
49301
|
+
const parsed = Number.parseInt(args.limit, 10);
|
|
49302
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
49303
|
+
cliError(
|
|
49304
|
+
`--limit must be a positive integer (got "${args.limit}")`,
|
|
49305
|
+
6 /* VALIDATION_ERROR */,
|
|
49306
|
+
{ name: "E_VALIDATION" }
|
|
49307
|
+
);
|
|
49308
|
+
process.exit(6 /* VALIDATION_ERROR */);
|
|
49309
|
+
}
|
|
49310
|
+
limit = parsed;
|
|
49311
|
+
}
|
|
49312
|
+
let threshold;
|
|
49313
|
+
if (typeof args.threshold === "string") {
|
|
49314
|
+
const parsed = Number.parseFloat(args.threshold);
|
|
49315
|
+
if (!Number.isFinite(parsed) || parsed < 0 || parsed > 1) {
|
|
49316
|
+
cliError(
|
|
49317
|
+
`--threshold must be a number in [0, 1] (got "${args.threshold}")`,
|
|
49318
|
+
6 /* VALIDATION_ERROR */,
|
|
49319
|
+
{ name: "E_VALIDATION" }
|
|
49320
|
+
);
|
|
49321
|
+
process.exit(6 /* VALIDATION_ERROR */);
|
|
49322
|
+
}
|
|
49323
|
+
threshold = parsed;
|
|
49324
|
+
}
|
|
49325
|
+
const allKinds = args["all-kinds"] === true;
|
|
49326
|
+
try {
|
|
49327
|
+
if (similarSlug.length > 0) {
|
|
49328
|
+
const result = await dispatchDocsRaw("query", "find", {
|
|
49329
|
+
similarSlug,
|
|
49330
|
+
...limit !== void 0 ? { limit } : {},
|
|
49331
|
+
...threshold !== void 0 ? { threshold } : {},
|
|
49332
|
+
allKinds
|
|
49333
|
+
});
|
|
49334
|
+
cliOutput(result, { command: "docs query", operation: "docs.find" });
|
|
49335
|
+
} else if (forId.length > 0) {
|
|
49336
|
+
const result = await dispatchDocsRaw("query", "rank", {
|
|
49337
|
+
ownerId: forId,
|
|
49338
|
+
query: customQuery ?? void 0
|
|
49339
|
+
});
|
|
49340
|
+
cliOutput(result, { command: "docs query", operation: "docs.rank" });
|
|
49341
|
+
} else {
|
|
49342
|
+
const result = await dispatchDocsRaw("query", "search", {
|
|
49343
|
+
query: textQuery,
|
|
49344
|
+
...ownerScope ? { ownerId: ownerScope } : {},
|
|
49345
|
+
...limit !== void 0 ? { limit } : {},
|
|
49346
|
+
...typeFilter ? { type: typeFilter } : {}
|
|
49347
|
+
});
|
|
49348
|
+
cliOutput(result, { command: "docs query", operation: "docs.search" });
|
|
49349
|
+
}
|
|
49350
|
+
} catch (err) {
|
|
49351
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
49352
|
+
const code = err instanceof Error && typeof err.code === "string" ? err.code : "E_DOCS_QUERY_FAILED";
|
|
49353
|
+
cliError(`docs query failed: ${message}`, 1 /* GENERAL_ERROR */, { name: code });
|
|
49354
|
+
process.exit(1 /* GENERAL_ERROR */);
|
|
49355
|
+
}
|
|
49356
|
+
}
|
|
49357
|
+
});
|
|
48245
49358
|
rankCommand = defineCommand({
|
|
48246
49359
|
meta: {
|
|
48247
49360
|
name: "rank",
|
|
@@ -48392,34 +49505,125 @@ var init_docs3 = __esm({
|
|
|
48392
49505
|
publishCommand2 = defineCommand({
|
|
48393
49506
|
meta: {
|
|
48394
49507
|
name: "publish",
|
|
48395
|
-
description: "
|
|
49508
|
+
description: "Publish a doc to a local file (--target file) or a GitHub PR (--target pr). Default target is file. Use --target pr with a slug-or-id to open/update a PR. Use --dry-run to preview without side effects."
|
|
48396
49509
|
},
|
|
48397
49510
|
args: {
|
|
49511
|
+
"slug-or-id": {
|
|
49512
|
+
type: "positional",
|
|
49513
|
+
description: "Slug, attachment id, or full sha256 hex of the doc to publish. Required for --target pr."
|
|
49514
|
+
},
|
|
49515
|
+
target: {
|
|
49516
|
+
type: "string",
|
|
49517
|
+
description: "Publish target: file (local git-tracked path) or pr (GitHub PR). Default: file.",
|
|
49518
|
+
default: "file"
|
|
49519
|
+
},
|
|
48398
49520
|
for: {
|
|
48399
49521
|
type: "string",
|
|
48400
|
-
description: "Owner entity ID whose attachment to publish (T###, ses_*, O-*)"
|
|
48401
|
-
required: true
|
|
49522
|
+
description: "Owner entity ID whose attachment to publish (T###, ses_*, O-*). Required for --target file."
|
|
48402
49523
|
},
|
|
48403
49524
|
to: {
|
|
48404
49525
|
type: "string",
|
|
48405
|
-
description: "Destination file path (absolute or relative to project root)"
|
|
48406
|
-
required: true
|
|
49526
|
+
description: "Destination file path (absolute or relative to project root). Required for --target file."
|
|
48407
49527
|
},
|
|
48408
49528
|
attachment: {
|
|
48409
49529
|
type: "string",
|
|
48410
49530
|
description: "Specific attachment ID or SHA-256 to publish (default: latest)"
|
|
48411
49531
|
},
|
|
48412
|
-
|
|
49532
|
+
slug: {
|
|
49533
|
+
type: "string",
|
|
49534
|
+
description: "Override the slug used for the branch + filename. Required when <slug-or-id> is an attachment id or sha256 with no stored slug."
|
|
49535
|
+
},
|
|
49536
|
+
type: {
|
|
49537
|
+
type: "string",
|
|
49538
|
+
description: "Override the publish dir taxonomy (spec|adr|research|handoff|note|llm-readme)."
|
|
49539
|
+
},
|
|
49540
|
+
title: {
|
|
49541
|
+
type: "string",
|
|
49542
|
+
description: "Override the PR title. Default: `docs(<type>): publish <slug>`."
|
|
49543
|
+
},
|
|
49544
|
+
body: {
|
|
49545
|
+
type: "string",
|
|
49546
|
+
description: "Override the PR body. Default: an auto-generated summary."
|
|
49547
|
+
},
|
|
49548
|
+
base: {
|
|
49549
|
+
type: "string",
|
|
49550
|
+
description: "Base branch for the PR. Default: main."
|
|
49551
|
+
},
|
|
49552
|
+
"dry-run": {
|
|
48413
49553
|
type: "boolean",
|
|
48414
|
-
description: "
|
|
48415
|
-
}
|
|
49554
|
+
description: "Preview what would happen without side effects. Reports resolved target, mode, and parameters. No files are written and no git/gh commands are invoked."
|
|
49555
|
+
},
|
|
49556
|
+
json: { type: "boolean", description: "Emit LAFS JSON envelope" }
|
|
48416
49557
|
},
|
|
48417
49558
|
async run({ args }) {
|
|
49559
|
+
const target = String(args.target ?? "file");
|
|
49560
|
+
const dryRun = args["dry-run"] === true;
|
|
49561
|
+
if (dryRun) {
|
|
49562
|
+
const details = { target, dryRun: true };
|
|
49563
|
+
if (target === "pr") {
|
|
49564
|
+
details.slugOrId = String(args["slug-or-id"] ?? "");
|
|
49565
|
+
if (args.slug) details.slug = String(args.slug);
|
|
49566
|
+
if (args.type) details.type = String(args.type);
|
|
49567
|
+
if (args.title) details.title = String(args.title);
|
|
49568
|
+
} else {
|
|
49569
|
+
details.for = args.for ? String(args.for) : null;
|
|
49570
|
+
details.to = args.to ? String(args.to) : null;
|
|
49571
|
+
if (args.attachment) details.attachment = String(args.attachment);
|
|
49572
|
+
}
|
|
49573
|
+
cliOutput(details, { command: "docs publish", operation: "docs.publish" });
|
|
49574
|
+
return;
|
|
49575
|
+
}
|
|
49576
|
+
if (target === "pr") {
|
|
49577
|
+
const slugOrId = String(args["slug-or-id"] ?? "");
|
|
49578
|
+
if (!slugOrId) {
|
|
49579
|
+
cliError(
|
|
49580
|
+
"docs publish --target pr requires a slug-or-id argument",
|
|
49581
|
+
1 /* GENERAL_ERROR */,
|
|
49582
|
+
{ name: "E_MISSING_ARG" }
|
|
49583
|
+
);
|
|
49584
|
+
process.exit(1 /* GENERAL_ERROR */);
|
|
49585
|
+
}
|
|
49586
|
+
const result = await dispatchDocsRaw("mutate", "publish", {
|
|
49587
|
+
slugOrId,
|
|
49588
|
+
target: "pr",
|
|
49589
|
+
...typeof args.slug === "string" ? { slug: args.slug } : {},
|
|
49590
|
+
...typeof args.type === "string" ? { type: args.type } : {},
|
|
49591
|
+
...typeof args.title === "string" ? { title: args.title } : {},
|
|
49592
|
+
...typeof args.body === "string" ? { body: args.body } : {},
|
|
49593
|
+
...typeof args.base === "string" ? { base: args.base } : {}
|
|
49594
|
+
});
|
|
49595
|
+
if (result.success) {
|
|
49596
|
+
cliOutput(result.data, { command: "docs publish", operation: "docs.publish" });
|
|
49597
|
+
return;
|
|
49598
|
+
}
|
|
49599
|
+
const e = result.error;
|
|
49600
|
+
cliError(
|
|
49601
|
+
e.message,
|
|
49602
|
+
1 /* GENERAL_ERROR */,
|
|
49603
|
+
{
|
|
49604
|
+
name: e.codeName,
|
|
49605
|
+
...e.fix ? { fix: e.fix } : {},
|
|
49606
|
+
...e.alternatives ? { alternatives: e.alternatives.map((alt) => ({ action: alt, command: alt })) } : {},
|
|
49607
|
+
...e.details ? { details: e.details } : {}
|
|
49608
|
+
},
|
|
49609
|
+
{ operation: "docs.publish" }
|
|
49610
|
+
);
|
|
49611
|
+
process.exit(1 /* GENERAL_ERROR */);
|
|
49612
|
+
}
|
|
49613
|
+
if (!args.for || !args.to) {
|
|
49614
|
+
cliError(
|
|
49615
|
+
"docs publish --target file requires --for <ownerId> and --to <path>",
|
|
49616
|
+
1 /* GENERAL_ERROR */,
|
|
49617
|
+
{ name: "E_MISSING_ARG" }
|
|
49618
|
+
);
|
|
49619
|
+
process.exit(1 /* GENERAL_ERROR */);
|
|
49620
|
+
}
|
|
48418
49621
|
try {
|
|
48419
49622
|
const result = await dispatchDocsRaw("mutate", "publish", {
|
|
48420
49623
|
ownerId: String(args.for),
|
|
48421
49624
|
toPath: String(args.to),
|
|
48422
|
-
attachmentId: args.attachment ?? void 0
|
|
49625
|
+
attachmentId: args.attachment ?? void 0,
|
|
49626
|
+
target: "file"
|
|
48423
49627
|
});
|
|
48424
49628
|
cliOutput(result, { command: "docs publish", operation: "docs.publish" });
|
|
48425
49629
|
} catch (err) {
|
|
@@ -48434,7 +49638,7 @@ var init_docs3 = __esm({
|
|
|
48434
49638
|
publishPrCommand = defineCommand({
|
|
48435
49639
|
meta: {
|
|
48436
49640
|
name: "publish-pr",
|
|
48437
|
-
description: "Publish an attachment to a GitHub PR. Opens a new PR on branch `docs/<slug>` with frontmatter, or atomically updates the existing open PR for the same slug."
|
|
49641
|
+
description: "[DEPRECATED] Use `docs publish --target pr` instead. Publish an attachment to a GitHub PR. Opens a new PR on branch `docs/<slug>` with frontmatter, or atomically updates the existing open PR for the same slug. Use --dry-run to preview without side effects."
|
|
48438
49642
|
},
|
|
48439
49643
|
args: {
|
|
48440
49644
|
"slug-or-id": {
|
|
@@ -48442,10 +49646,7 @@ var init_docs3 = __esm({
|
|
|
48442
49646
|
description: "Slug, attachment id, or full sha256 hex of the doc to publish",
|
|
48443
49647
|
required: true
|
|
48444
49648
|
},
|
|
48445
|
-
slug: {
|
|
48446
|
-
type: "string",
|
|
48447
|
-
description: "Override the slug used for the branch + filename. Required when <slug-or-id> is an attachment id or sha256 with no stored slug."
|
|
48448
|
-
},
|
|
49649
|
+
slug: { type: "string", description: "Override the slug used for the branch + filename." },
|
|
48449
49650
|
type: {
|
|
48450
49651
|
type: "string",
|
|
48451
49652
|
description: "Override the publish dir taxonomy (spec|adr|research|handoff|note|llm-readme)."
|
|
@@ -48458,15 +49659,25 @@ var init_docs3 = __esm({
|
|
|
48458
49659
|
type: "string",
|
|
48459
49660
|
description: "Override the PR body. Default: an auto-generated summary."
|
|
48460
49661
|
},
|
|
48461
|
-
base: {
|
|
48462
|
-
|
|
48463
|
-
description: "Base branch for the PR. Default: main."
|
|
48464
|
-
}
|
|
49662
|
+
base: { type: "string", description: "Base branch for the PR. Default: main." },
|
|
49663
|
+
"dry-run": { type: "boolean", description: "Preview what would happen without side effects." }
|
|
48465
49664
|
},
|
|
48466
49665
|
async run({ args }) {
|
|
49666
|
+
humanInfo(
|
|
49667
|
+
"[deprecated] `docs publish-pr` is deprecated. Use `docs publish --target pr <slug-or-id>` instead."
|
|
49668
|
+
);
|
|
48467
49669
|
const slugOrId = String(args["slug-or-id"]);
|
|
48468
|
-
|
|
49670
|
+
if (args["dry-run"] === true) {
|
|
49671
|
+
const details = { slugOrId, target: "pr", dryRun: true };
|
|
49672
|
+
if (args.slug) details.slug = String(args.slug);
|
|
49673
|
+
if (args.type) details.type = String(args.type);
|
|
49674
|
+
if (args.title) details.title = String(args.title);
|
|
49675
|
+
cliOutput(details, { command: "docs publish-pr", operation: "docs.publish" });
|
|
49676
|
+
return;
|
|
49677
|
+
}
|
|
49678
|
+
const result = await dispatchDocsRaw("mutate", "publish", {
|
|
48469
49679
|
slugOrId,
|
|
49680
|
+
target: "pr",
|
|
48470
49681
|
...typeof args.slug === "string" ? { slug: args.slug } : {},
|
|
48471
49682
|
...typeof args.type === "string" ? { type: args.type } : {},
|
|
48472
49683
|
...typeof args.title === "string" ? { title: args.title } : {},
|
|
@@ -48474,7 +49685,7 @@ var init_docs3 = __esm({
|
|
|
48474
49685
|
...typeof args.base === "string" ? { base: args.base } : {}
|
|
48475
49686
|
});
|
|
48476
49687
|
if (result.success) {
|
|
48477
|
-
cliOutput(result.data, { command: "docs publish-pr", operation: "docs.publish
|
|
49688
|
+
cliOutput(result.data, { command: "docs publish-pr", operation: "docs.publish" });
|
|
48478
49689
|
return;
|
|
48479
49690
|
}
|
|
48480
49691
|
const e = result.error;
|
|
@@ -48484,16 +49695,77 @@ var init_docs3 = __esm({
|
|
|
48484
49695
|
{
|
|
48485
49696
|
name: e.codeName,
|
|
48486
49697
|
...e.fix ? { fix: e.fix } : {},
|
|
48487
|
-
...e.alternatives ? {
|
|
48488
|
-
alternatives: e.alternatives.map((alt) => ({ action: alt, command: alt }))
|
|
48489
|
-
} : {},
|
|
49698
|
+
...e.alternatives ? { alternatives: e.alternatives.map((alt) => ({ action: alt, command: alt })) } : {},
|
|
48490
49699
|
...e.details ? { details: e.details } : {}
|
|
48491
49700
|
},
|
|
48492
|
-
{ operation: "docs.publish
|
|
49701
|
+
{ operation: "docs.publish" }
|
|
48493
49702
|
);
|
|
48494
49703
|
process.exit(1 /* GENERAL_ERROR */);
|
|
48495
49704
|
}
|
|
48496
49705
|
});
|
|
49706
|
+
checkCommand6 = defineCommand({
|
|
49707
|
+
meta: {
|
|
49708
|
+
name: "check",
|
|
49709
|
+
description: "Unified drift management: check documentation for drift, status, and gaps. Use --drift, --status, --gaps for specific checks; runs all by default."
|
|
49710
|
+
},
|
|
49711
|
+
args: {
|
|
49712
|
+
drift: {
|
|
49713
|
+
type: "boolean",
|
|
49714
|
+
description: "Run legacy drift check (scripts/ vs COMMANDS-INDEX.json)"
|
|
49715
|
+
},
|
|
49716
|
+
status: {
|
|
49717
|
+
type: "boolean",
|
|
49718
|
+
description: "Run git\u21C4llmtxt drift check (published files vs docs SSoT)"
|
|
49719
|
+
},
|
|
49720
|
+
gaps: { type: "boolean", description: "Run knowledge transfer gap check (review docs)" },
|
|
49721
|
+
all: {
|
|
49722
|
+
type: "boolean",
|
|
49723
|
+
description: "Run all three checks (default when no mode flag is set)"
|
|
49724
|
+
},
|
|
49725
|
+
quick: { type: "boolean", description: "Drift check only: quick mode (commands only)" },
|
|
49726
|
+
strict: { type: "boolean", description: "Exit with non-zero code on any drift detection" },
|
|
49727
|
+
epic: { type: "string", description: "Gap check only: filter by epic ID" },
|
|
49728
|
+
task: { type: "string", description: "Gap check only: filter by task ID" },
|
|
49729
|
+
json: { type: "boolean", description: "Emit LAFS JSON envelope" }
|
|
49730
|
+
},
|
|
49731
|
+
async run({ args }) {
|
|
49732
|
+
const hasExplicit = args.drift === true || args.status === true || args.gaps === true;
|
|
49733
|
+
const runDrift = args.drift === true || args.all === true || !hasExplicit;
|
|
49734
|
+
const runStatus = args.status === true || args.all === true || !hasExplicit;
|
|
49735
|
+
const runGaps = args.gaps === true || args.all === true || !hasExplicit;
|
|
49736
|
+
const projectRoot = process.cwd();
|
|
49737
|
+
const results = {};
|
|
49738
|
+
let anyDrift = false;
|
|
49739
|
+
try {
|
|
49740
|
+
if (runDrift) {
|
|
49741
|
+
const r = await detectDrift(projectRoot);
|
|
49742
|
+
results.drift = r;
|
|
49743
|
+
if (r.status !== "clean") anyDrift = true;
|
|
49744
|
+
}
|
|
49745
|
+
if (runStatus) {
|
|
49746
|
+
const r = await dispatchDocsRaw("query", "status", {});
|
|
49747
|
+
results.status = r;
|
|
49748
|
+
if (!r.allInSync) anyDrift = true;
|
|
49749
|
+
}
|
|
49750
|
+
if (runGaps) {
|
|
49751
|
+
const r = await runGapCheck(projectRoot, args.epic ?? args.task ?? void 0);
|
|
49752
|
+
results.gaps = r;
|
|
49753
|
+
if (r.length > 0) anyDrift = true;
|
|
49754
|
+
}
|
|
49755
|
+
cliOutput(results, {
|
|
49756
|
+
command: "docs check",
|
|
49757
|
+
message: anyDrift ? "Drift detected \u2014 see results for details" : "All checks passed \u2014 no drift detected"
|
|
49758
|
+
});
|
|
49759
|
+
if (args.strict && anyDrift) process.exit(2);
|
|
49760
|
+
} catch (err) {
|
|
49761
|
+
if (err instanceof CleoError3) {
|
|
49762
|
+
cliError(err.message, err.code, { name: "E_DOCS_CHECK_FAILED" });
|
|
49763
|
+
process.exit(err.code);
|
|
49764
|
+
}
|
|
49765
|
+
throw err;
|
|
49766
|
+
}
|
|
49767
|
+
}
|
|
49768
|
+
});
|
|
48497
49769
|
syncCommand3 = defineCommand({
|
|
48498
49770
|
meta: {
|
|
48499
49771
|
name: "sync",
|
|
@@ -48725,12 +49997,16 @@ var init_docs3 = __esm({
|
|
|
48725
49997
|
schemaCommand = defineCommand({
|
|
48726
49998
|
meta: {
|
|
48727
49999
|
name: "schema",
|
|
48728
|
-
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`.
|
|
50000
|
+
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`. (T11142)."
|
|
48729
50001
|
},
|
|
48730
50002
|
args: {
|
|
48731
|
-
|
|
50003
|
+
counts: {
|
|
48732
50004
|
type: "boolean",
|
|
48733
50005
|
description: "Include per-kind attachment counts from the project SSoT"
|
|
50006
|
+
},
|
|
50007
|
+
"include-counts": {
|
|
50008
|
+
type: "boolean",
|
|
50009
|
+
description: "DEPRECATED -- use --counts instead. Accepted for backward compatibility but will be removed in a future release."
|
|
48734
50010
|
}
|
|
48735
50011
|
},
|
|
48736
50012
|
async run({ args }) {
|
|
@@ -48738,8 +50014,9 @@ var init_docs3 = __esm({
|
|
|
48738
50014
|
const { registry, configError } = loadCliRegistry(projectRoot);
|
|
48739
50015
|
const kinds = registry.list().map(toWireKind);
|
|
48740
50016
|
const extensionsCount = kinds.filter((k) => k.isExtension).length;
|
|
50017
|
+
const wantCounts = args.counts === true || args["include-counts"] === true;
|
|
48741
50018
|
let counts2;
|
|
48742
|
-
if (
|
|
50019
|
+
if (wantCounts) {
|
|
48743
50020
|
counts2 = {};
|
|
48744
50021
|
const { createAttachmentStore: createAttachmentStore5 } = await import("@cleocode/core/internal");
|
|
48745
50022
|
const store = createAttachmentStore5();
|
|
@@ -48769,52 +50046,57 @@ var init_docs3 = __esm({
|
|
|
48769
50046
|
listTypesCommand = defineCommand({
|
|
48770
50047
|
meta: {
|
|
48771
50048
|
name: "list-types",
|
|
48772
|
-
description: "
|
|
50049
|
+
description: "DEPRECATED -- use `cleo docs schema` instead. Lists every registered doc kind (T11142)."
|
|
48773
50050
|
},
|
|
48774
50051
|
args: {
|
|
48775
50052
|
counts: {
|
|
48776
50053
|
type: "boolean",
|
|
48777
50054
|
description: "Include per-kind attachment counts from the project SSoT"
|
|
50055
|
+
},
|
|
50056
|
+
"include-counts": {
|
|
50057
|
+
type: "boolean",
|
|
50058
|
+
description: "DEPRECATED -- use --counts instead."
|
|
48778
50059
|
}
|
|
48779
50060
|
},
|
|
48780
50061
|
async run({ args }) {
|
|
50062
|
+
pushWarning3({
|
|
50063
|
+
code: "W_DEPRECATED_COMMAND",
|
|
50064
|
+
message: "cleo docs list-types is deprecated -- use `cleo docs schema` instead (T11142)",
|
|
50065
|
+
deprecated: "docs list-types",
|
|
50066
|
+
replacement: "docs schema"
|
|
50067
|
+
});
|
|
48781
50068
|
const projectRoot = getProjectRoot38();
|
|
48782
50069
|
const { registry, configError } = loadCliRegistry(projectRoot);
|
|
48783
50070
|
const kinds = registry.list().map(toWireKind);
|
|
50071
|
+
const extensionsCount = kinds.filter((k) => k.isExtension).length;
|
|
50072
|
+
const wantCounts = args.counts === true || args["include-counts"] === true;
|
|
48784
50073
|
let counts2;
|
|
48785
|
-
if (
|
|
50074
|
+
if (wantCounts) {
|
|
48786
50075
|
counts2 = {};
|
|
48787
50076
|
const { createAttachmentStore: createAttachmentStore5 } = await import("@cleocode/core/internal");
|
|
48788
50077
|
const store = createAttachmentStore5();
|
|
48789
50078
|
for (const k of kinds) counts2[k.kind] = 0;
|
|
48790
50079
|
try {
|
|
48791
|
-
const
|
|
48792
|
-
for (const row of
|
|
50080
|
+
const rows = await store.listAllInProject(projectRoot);
|
|
50081
|
+
for (const row of rows) {
|
|
48793
50082
|
const key = row.type;
|
|
48794
50083
|
if (key && key in counts2) counts2[key] = (counts2[key] ?? 0) + 1;
|
|
48795
50084
|
}
|
|
48796
50085
|
} catch {
|
|
48797
50086
|
}
|
|
48798
50087
|
}
|
|
48799
|
-
const rows = kinds.map((k) => ({
|
|
48800
|
-
kind: k.kind,
|
|
48801
|
-
label: k.label,
|
|
48802
|
-
...counts2 ? { count: counts2[k.kind] ?? 0 } : {},
|
|
48803
|
-
requiresEntityId: k.requiresEntityId,
|
|
48804
|
-
publishDir: k.publishDir,
|
|
48805
|
-
isExtension: k.isExtension
|
|
48806
|
-
}));
|
|
48807
50088
|
cliOutput(
|
|
48808
50089
|
{
|
|
48809
50090
|
version: 1,
|
|
48810
|
-
|
|
48811
|
-
|
|
50091
|
+
builtinsCount: kinds.length - extensionsCount,
|
|
50092
|
+
extensionsCount,
|
|
50093
|
+
kinds,
|
|
50094
|
+
...counts2 ? { counts: counts2 } : {},
|
|
48812
50095
|
...configError ? { configError } : {}
|
|
48813
50096
|
},
|
|
48814
50097
|
{
|
|
48815
50098
|
command: "docs list-types",
|
|
48816
|
-
operation: "docs.list-types"
|
|
48817
|
-
message: configError ? `loaded built-ins only \u2014 ${configError.message}` : void 0
|
|
50099
|
+
operation: "docs.list-types"
|
|
48818
50100
|
}
|
|
48819
50101
|
);
|
|
48820
50102
|
}
|
|
@@ -48822,30 +50104,42 @@ var init_docs3 = __esm({
|
|
|
48822
50104
|
docsCommand = defineCommand({
|
|
48823
50105
|
meta: {
|
|
48824
50106
|
name: "docs",
|
|
48825
|
-
description: "
|
|
50107
|
+
description: "Canonical six-verb docs path: add, update, fetch, list, remove, publish. Unified query: query (subsumes search/find/rank). LLM output: llm-output (replaces generate + export). Advanced: supersede, merge, graph, versions. Audit: audit (query the immutable docs audit trail). Legacy/migration: search, find, rank, sync, status, gap-check, import (use query for new work). Viewer: viewer (start/stop/open/status). Utilities: schema (list-types \u2192 schema)."
|
|
48826
50108
|
},
|
|
48827
50109
|
subCommands: {
|
|
50110
|
+
// T11136 — Unified drift management (consolidates sync/status/gap-check)
|
|
50111
|
+
check: checkCommand6,
|
|
50112
|
+
// Canonical six-verb path (add, update, fetch, list, remove, publish)
|
|
48828
50113
|
add: addCommand5,
|
|
48829
50114
|
update: updateCommand,
|
|
48830
|
-
list: listCommand8,
|
|
48831
50115
|
fetch: fetchCommand,
|
|
50116
|
+
list: listCommand8,
|
|
48832
50117
|
remove: removeCommand2,
|
|
50118
|
+
publish: publishCommand2,
|
|
50119
|
+
// T11176 — unified search/find/rank surface (preferred entry point)
|
|
50120
|
+
query: queryCommand,
|
|
50121
|
+
// Advanced primitives
|
|
48833
50122
|
supersede: supersedeCommand,
|
|
48834
50123
|
generate: generateCommand,
|
|
48835
50124
|
export: exportCommand4,
|
|
48836
|
-
|
|
48837
|
-
search: searchCommand,
|
|
50125
|
+
"llm-output": llmOutputCommand,
|
|
48838
50126
|
merge: mergeCommand,
|
|
48839
50127
|
// T10164 — DocProvenanceResponse-typed graph (`--root <slug>|<taskId>`).
|
|
48840
50128
|
graph: graphCommand,
|
|
50129
|
+
// Legacy aliases (use `query` for new work — retained for backward compatibility)
|
|
50130
|
+
search: searchCommand,
|
|
50131
|
+
find: findCommand3,
|
|
48841
50132
|
rank: rankCommand,
|
|
48842
50133
|
versions: versionsCommand,
|
|
48843
|
-
publish: publishCommand2,
|
|
48844
50134
|
"publish-pr": publishPrCommand,
|
|
50135
|
+
// T11182 — unified docs audit trail
|
|
50136
|
+
audit: auditCommand3,
|
|
50137
|
+
// Legacy/migration (use canonical verbs for new work)
|
|
48845
50138
|
sync: syncCommand3,
|
|
48846
50139
|
status: statusCommand7,
|
|
48847
50140
|
"gap-check": gapCheckCommand,
|
|
48848
50141
|
import: importCommand2,
|
|
50142
|
+
// Utilities
|
|
48849
50143
|
// T9788 — canonical doc-kind taxonomy discovery surface.
|
|
48850
50144
|
schema: schemaCommand,
|
|
48851
50145
|
"list-types": listTypesCommand,
|
|
@@ -48865,7 +50159,7 @@ var doctor_db_substrate_exports = {};
|
|
|
48865
50159
|
__export(doctor_db_substrate_exports, {
|
|
48866
50160
|
doctorDbSubstrateCommand: () => doctorDbSubstrateCommand
|
|
48867
50161
|
});
|
|
48868
|
-
import { getProjectRoot as getProjectRoot39, pushWarning as
|
|
50162
|
+
import { getProjectRoot as getProjectRoot39, pushWarning as pushWarning4 } from "@cleocode/core";
|
|
48869
50163
|
import { surveyDbSubstrate, surveyFleetDbSubstrate } from "@cleocode/core/doctor/db-substrate.js";
|
|
48870
50164
|
function pushSubstrateWarnings(result) {
|
|
48871
50165
|
for (const warning of result.warnings) {
|
|
@@ -48877,7 +50171,7 @@ function pushSubstrateWarnings(result) {
|
|
|
48877
50171
|
if (warning.kind === "orphan-project-root") {
|
|
48878
50172
|
context["parentWorkspace"] = warning.parentWorkspace ?? null;
|
|
48879
50173
|
}
|
|
48880
|
-
|
|
50174
|
+
pushWarning4({
|
|
48881
50175
|
code: warning.kind === "orphan-project-root" ? "W_DB_SUBSTRATE_ORPHAN_PROJECT_ROOT" : "W_DB_SUBSTRATE_NESTED_NEXUS_DUPLICATE",
|
|
48882
50176
|
message: warning.kind === "orphan-project-root" ? `Orphan project-root .cleo/ at ${warning.path} (T9550 regression class \u2014 review then remove)` + (warning.parentWorkspace ? ` \u2014 attributed to workspace: ${warning.parentWorkspace}` : "") : `Nested-nexus duplicate at ${warning.path} (structural duplicate of the canonical flat layout)`,
|
|
48883
50177
|
severity: "warn",
|
|
@@ -48888,7 +50182,7 @@ function pushSubstrateWarnings(result) {
|
|
|
48888
50182
|
for (const [role, entry] of Object.entries(projectSurvey.dbs)) {
|
|
48889
50183
|
if (entry.pragmaDrift === null || entry.pragmaDrift.length === 0) continue;
|
|
48890
50184
|
for (const drift of entry.pragmaDrift) {
|
|
48891
|
-
|
|
50185
|
+
pushWarning4({
|
|
48892
50186
|
code: "W_DB_SUBSTRATE_PRAGMA_DRIFT",
|
|
48893
50187
|
message: `Pragma drift on ${role} (${entry.filePath}): expected ${drift.pragma}=${drift.expected}, actual=${drift.actual ?? "<unmeasurable>"}`,
|
|
48894
50188
|
severity: "warn",
|
|
@@ -48905,7 +50199,7 @@ function pushSubstrateWarnings(result) {
|
|
|
48905
50199
|
}
|
|
48906
50200
|
for (const report of result.crossDbOrphans) {
|
|
48907
50201
|
if (report.skipped || report.orphanCount === 0) continue;
|
|
48908
|
-
|
|
50202
|
+
pushWarning4({
|
|
48909
50203
|
code: `W_DB_SUBSTRATE_CROSS_DB_${report.invariant}`,
|
|
48910
50204
|
message: `${report.invariant}: ${report.orphanCount} orphan row${report.orphanCount === 1 ? "" : "s"} \u2014 ${report.description}. ${report.suggestedFix}`,
|
|
48911
50205
|
severity: "warn",
|
|
@@ -48922,7 +50216,7 @@ function pushPerDbWarnings(result) {
|
|
|
48922
50216
|
for (const projectSurvey of result.projects) {
|
|
48923
50217
|
for (const [role, dbEntry] of Object.entries(projectSurvey.dbs)) {
|
|
48924
50218
|
if (dbEntry.quarantinedTo !== null) {
|
|
48925
|
-
|
|
50219
|
+
pushWarning4({
|
|
48926
50220
|
code: "W_DB_SUBSTRATE_AUTO_QUARANTINED",
|
|
48927
50221
|
message: `Auto-quarantined corrupt ${role} DB at ${dbEntry.filePath} \u2192 ${dbEntry.quarantinedTo}. Recover via: cleo backup recover ${role}`,
|
|
48928
50222
|
severity: "warn",
|
|
@@ -48935,7 +50229,7 @@ function pushPerDbWarnings(result) {
|
|
|
48935
50229
|
});
|
|
48936
50230
|
}
|
|
48937
50231
|
if (dbEntry.timedOut) {
|
|
48938
|
-
|
|
50232
|
+
pushWarning4({
|
|
48939
50233
|
code: "W_DB_SUBSTRATE_INTEGRITY_TIMEOUT",
|
|
48940
50234
|
message: `integrity_check on ${role} DB at ${dbEntry.filePath} took ${dbEntry.integrityCheckMs}ms \u2014 slow substrate flagged for operator attention`,
|
|
48941
50235
|
severity: "warn",
|
|
@@ -49860,7 +51154,7 @@ __export(doctor_exports, {
|
|
|
49860
51154
|
});
|
|
49861
51155
|
import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "node:fs";
|
|
49862
51156
|
import { join as join24 } from "node:path";
|
|
49863
|
-
import { getProjectRoot as getProjectRoot42, pushWarning as
|
|
51157
|
+
import { getProjectRoot as getProjectRoot42, pushWarning as pushWarning5 } from "@cleocode/core";
|
|
49864
51158
|
import { renderInvariantAuditLines } from "@cleocode/core/doctor/invariant-audit-render.js";
|
|
49865
51159
|
import {
|
|
49866
51160
|
quarantineRogueCleoDir,
|
|
@@ -50394,7 +51688,7 @@ var init_doctor = __esm({
|
|
|
50394
51688
|
const legacyOrphans = legacyScanResult.orphans;
|
|
50395
51689
|
const totalAnomalies = comprehensive.count;
|
|
50396
51690
|
if (legacyScanResult.softWarnMessage) {
|
|
50397
|
-
|
|
51691
|
+
pushWarning5({
|
|
50398
51692
|
code: "W_DOCTOR_SCAN_SOFT_WARN",
|
|
50399
51693
|
message: legacyScanResult.softWarnMessage,
|
|
50400
51694
|
severity: "warn"
|
|
@@ -50402,7 +51696,7 @@ var init_doctor = __esm({
|
|
|
50402
51696
|
}
|
|
50403
51697
|
if (legacyScanResult.isPartial) {
|
|
50404
51698
|
const reason = legacyScanResult.partialReason === "timeout" ? `timed out after ${timeoutSecs}s (use --timeout <seconds> to adjust)` : `per-level entry cap of ${maxEntriesPerLevel} exceeded (use --max-entries-per-level <n> to adjust)`;
|
|
50405
|
-
|
|
51699
|
+
pushWarning5({
|
|
50406
51700
|
code: "W_DOCTOR_SCAN_PARTIAL",
|
|
50407
51701
|
message: `legacy orphan scan is PARTIAL \u2014 ${reason}. Results may be incomplete.`,
|
|
50408
51702
|
severity: "warn",
|
|
@@ -50446,7 +51740,7 @@ var init_doctor = __esm({
|
|
|
50446
51740
|
maxEntriesPerLevel: Number.isFinite(maxEntriesPerLevel) ? maxEntriesPerLevel : 500
|
|
50447
51741
|
});
|
|
50448
51742
|
if (scanResult.softWarnMessage) {
|
|
50449
|
-
|
|
51743
|
+
pushWarning5({
|
|
50450
51744
|
code: "W_DOCTOR_SCAN_SOFT_WARN",
|
|
50451
51745
|
message: scanResult.softWarnMessage,
|
|
50452
51746
|
severity: "warn"
|
|
@@ -50454,7 +51748,7 @@ var init_doctor = __esm({
|
|
|
50454
51748
|
}
|
|
50455
51749
|
if (scanResult.isPartial) {
|
|
50456
51750
|
const reason = scanResult.partialReason === "timeout" ? `timed out after ${timeoutSecs}s (use --timeout <seconds> to adjust)` : `per-level entry cap of ${maxEntriesPerLevel} exceeded (use --max-entries-per-level <n> to adjust)`;
|
|
50457
|
-
|
|
51751
|
+
pushWarning5({
|
|
50458
51752
|
code: "W_DOCTOR_SCAN_PARTIAL",
|
|
50459
51753
|
message: `orphan scan is PARTIAL \u2014 ${reason}. Only orphans found before abort will be pruned.`,
|
|
50460
51754
|
severity: "warn",
|
|
@@ -51788,7 +53082,7 @@ function applyJsonFlag(jsonFlag) {
|
|
|
51788
53082
|
setFormatContext({ format: "json", source: "flag", quiet: false });
|
|
51789
53083
|
}
|
|
51790
53084
|
}
|
|
51791
|
-
var statusCommand9, resolveCommand, depsCommand2, rawCommand, discoverCommand, searchCommand2, augmentCommand, contextCommand2, impactCommand2, impactFullCommand, clustersCommand, flowsCommand, diffCommand, routeMapCommand, shapeCheckCommand, searchCodeCommand, wikiCommand, hotPathsCommand, hotNodesCommand, coldSymbolsCommand, orphansCommand,
|
|
53085
|
+
var statusCommand9, resolveCommand, depsCommand2, rawCommand, discoverCommand, searchCommand2, augmentCommand, contextCommand2, impactCommand2, impactFullCommand, clustersCommand, flowsCommand, diffCommand, routeMapCommand, shapeCheckCommand, searchCodeCommand, wikiCommand, hotPathsCommand, hotNodesCommand, coldSymbolsCommand, orphansCommand, queryCommand2, initCommand, syncCommand4, reconcileCommand, livingFullContextCommand, livingTaskFootprintCommand, livingBrainAnchorsCommand, livingWhyCommand, livingConduitScanCommand, livingCommand, graphCommand2;
|
|
51792
53086
|
var init_graph3 = __esm({
|
|
51793
53087
|
"packages/cleo/src/cli/commands/graph.ts"() {
|
|
51794
53088
|
"use strict";
|
|
@@ -52296,7 +53590,7 @@ var init_graph3 = __esm({
|
|
|
52296
53590
|
await dispatchFromCli("query", "nexus", "orphans.list", {}, { command: "graph" });
|
|
52297
53591
|
}
|
|
52298
53592
|
});
|
|
52299
|
-
|
|
53593
|
+
queryCommand2 = defineCommand({
|
|
52300
53594
|
meta: { name: "query", description: "Execute recursive CTE queries against nexus.db" },
|
|
52301
53595
|
args: {
|
|
52302
53596
|
cte: {
|
|
@@ -52604,7 +53898,7 @@ var init_graph3 = __esm({
|
|
|
52604
53898
|
"hot-nodes": hotNodesCommand,
|
|
52605
53899
|
"cold-symbols": coldSymbolsCommand,
|
|
52606
53900
|
orphans: orphansCommand,
|
|
52607
|
-
query:
|
|
53901
|
+
query: queryCommand2,
|
|
52608
53902
|
init: initCommand,
|
|
52609
53903
|
sync: syncCommand4,
|
|
52610
53904
|
reconcile: reconcileCommand,
|
|
@@ -52899,7 +54193,7 @@ import {
|
|
|
52899
54193
|
CleoError as CleoError4,
|
|
52900
54194
|
getWorkflowTemplatesDir as getCoreWorkflowTemplatesDir,
|
|
52901
54195
|
initProject as initProject2,
|
|
52902
|
-
pushWarning as
|
|
54196
|
+
pushWarning as pushWarning6,
|
|
52903
54197
|
scaffoldWorkflows
|
|
52904
54198
|
} from "@cleocode/core";
|
|
52905
54199
|
import { getTemplatesByKind } from "@cleocode/core/templates/registry";
|
|
@@ -52979,7 +54273,7 @@ var init_init = __esm({
|
|
|
52979
54273
|
async run({ args }) {
|
|
52980
54274
|
try {
|
|
52981
54275
|
if (args.workflows) {
|
|
52982
|
-
|
|
54276
|
+
pushWarning6({
|
|
52983
54277
|
code: "W_INIT_WORKFLOWS_DEPRECATED",
|
|
52984
54278
|
message: "[deprecated] cleo init --workflows: use `cleo templates install --kind workflow` instead. This alias will be removed in v2026.7.0.",
|
|
52985
54279
|
severity: "warn",
|
|
@@ -54597,7 +55891,7 @@ var llm_exports = {};
|
|
|
54597
55891
|
__export(llm_exports, {
|
|
54598
55892
|
llmCommand: () => llmCommand
|
|
54599
55893
|
});
|
|
54600
|
-
import { pushWarning as
|
|
55894
|
+
import { pushWarning as pushWarning7 } from "@cleocode/core";
|
|
54601
55895
|
async function getListProviders() {
|
|
54602
55896
|
const { listProviders } = await import(
|
|
54603
55897
|
/* webpackIgnore: true */
|
|
@@ -54728,7 +56022,7 @@ var init_llm3 = __esm({
|
|
|
54728
56022
|
apiKey = envValue;
|
|
54729
56023
|
source = "env";
|
|
54730
56024
|
} else if (typeof a["api-key"] === "string" && a["api-key"]) {
|
|
54731
|
-
|
|
56025
|
+
pushWarning7({
|
|
54732
56026
|
code: "W_DEPRECATED_FLAG",
|
|
54733
56027
|
message: API_KEY_FLAG_DEPRECATION,
|
|
54734
56028
|
deprecated: "--api-key=<value>",
|
|
@@ -55839,7 +57133,10 @@ var init_memory3 = __esm({
|
|
|
55839
57133
|
}
|
|
55840
57134
|
});
|
|
55841
57135
|
decisionFindCommand = defineCommand({
|
|
55842
|
-
meta: {
|
|
57136
|
+
meta: {
|
|
57137
|
+
name: "decision-find",
|
|
57138
|
+
description: "Search architectural decisions (use BEFORE grep or ledger files)"
|
|
57139
|
+
},
|
|
55843
57140
|
args: {
|
|
55844
57141
|
query: {
|
|
55845
57142
|
type: "positional",
|
|
@@ -55875,7 +57172,10 @@ var init_memory3 = __esm({
|
|
|
55875
57172
|
}
|
|
55876
57173
|
});
|
|
55877
57174
|
decisionStoreCommand = defineCommand({
|
|
55878
|
-
meta: {
|
|
57175
|
+
meta: {
|
|
57176
|
+
name: "decision-store",
|
|
57177
|
+
description: "Store an architectural decision \u2014 supports --linked-task, --confirmation-state, --supersedes, --superseded-by, --decided-by"
|
|
57178
|
+
},
|
|
55879
57179
|
args: {
|
|
55880
57180
|
decision: {
|
|
55881
57181
|
type: "string",
|
|
@@ -55943,7 +57243,10 @@ var init_memory3 = __esm({
|
|
|
55943
57243
|
}
|
|
55944
57244
|
});
|
|
55945
57245
|
linkCommand = defineCommand({
|
|
55946
|
-
meta: {
|
|
57246
|
+
meta: {
|
|
57247
|
+
name: "link",
|
|
57248
|
+
description: "Connect a BRAIN decision/observation to a task (example: cleo memory link T10520 D012)"
|
|
57249
|
+
},
|
|
55947
57250
|
args: {
|
|
55948
57251
|
taskId: {
|
|
55949
57252
|
type: "positional",
|
|
@@ -57234,7 +58537,10 @@ data: ${JSON.stringify({ ts: item.ts })}
|
|
|
57234
58537
|
}
|
|
57235
58538
|
});
|
|
57236
58539
|
memoryCommand = defineCommand({
|
|
57237
|
-
meta: {
|
|
58540
|
+
meta: {
|
|
58541
|
+
name: "memory",
|
|
58542
|
+
description: "BRAIN memory operations (patterns, learnings, decisions \u2014 use decision-store/-find for architectural decisions)"
|
|
58543
|
+
},
|
|
57238
58544
|
subCommands: {
|
|
57239
58545
|
store: storeCommand,
|
|
57240
58546
|
find: findCommand6,
|
|
@@ -57530,7 +58836,7 @@ function applyJsonFlag2(jsonFlag) {
|
|
|
57530
58836
|
setFormatContext({ format: "json", source: "flag", quiet: false });
|
|
57531
58837
|
}
|
|
57532
58838
|
}
|
|
57533
|
-
var initCommand3, registerCommand2, unregisterCommand, listCommand14, statusCommand10, showCommand8, resolveCommand2, discoverCommand2, augmentCommand2, setupCommand, searchCommand3, depsCommand3, criticalPathCommand2, blockingCommand, orphansCommand2, syncCommand5, reconcileCommand2, graphCommand3, shareStatusCommand, transferPreviewCommand, transferCommand, permissionSetCommand, permissionCommand, shareExportCommand, shareImportCommand, shareCommand, clustersCommand2, flowsCommand2, contextCommand4, impactCommand3, analyzeCommand3, projectsListCommand, projectsRegisterCommand, projectsRemoveCommand, projectsScanCommand, projectsCleanCommand, projectsCommand, refreshBridgeCommand, exportCommand6, diffCommand2,
|
|
58839
|
+
var initCommand3, registerCommand2, unregisterCommand, listCommand14, statusCommand10, showCommand8, resolveCommand2, discoverCommand2, augmentCommand2, setupCommand, searchCommand3, depsCommand3, criticalPathCommand2, blockingCommand, orphansCommand2, syncCommand5, reconcileCommand2, graphCommand3, shareStatusCommand, transferPreviewCommand, transferCommand, permissionSetCommand, permissionCommand, shareExportCommand, shareImportCommand, shareCommand, clustersCommand2, flowsCommand2, contextCommand4, impactCommand3, analyzeCommand3, projectsListCommand, projectsRegisterCommand, projectsRemoveCommand, projectsScanCommand, projectsCleanCommand, projectsCommand, refreshBridgeCommand, exportCommand6, diffCommand2, queryCommand3, routeMapCommand2, shapeCheckCommand2, fullContextCommand, taskFootprintCommand, brainAnchorsCommand, whyCommand, impactFullCommand2, conduitScanCommand, taskSymbolsCommand, searchCodeCommand2, contractsSyncCommand, contractsShowCommand, contractsLinkTasksCommand, contractsCommand, groupCommand, wikiCommand2, hotPathsCommand2, hotNodesCommand2, coldSymbolsCommand2, sigilSyncCommand, sigilListCommand, sigilCommand, topEntriesCommand, nexusCommand;
|
|
57534
58840
|
var init_nexus3 = __esm({
|
|
57535
58841
|
"packages/cleo/src/cli/commands/nexus.ts"() {
|
|
57536
58842
|
"use strict";
|
|
@@ -58960,7 +60266,7 @@ var init_nexus3 = __esm({
|
|
|
58960
60266
|
});
|
|
58961
60267
|
}
|
|
58962
60268
|
});
|
|
58963
|
-
|
|
60269
|
+
queryCommand3 = defineCommand({
|
|
58964
60270
|
meta: {
|
|
58965
60271
|
name: "query",
|
|
58966
60272
|
description: "Execute recursive CTE queries against nexus.db"
|
|
@@ -59946,7 +61252,7 @@ var init_nexus3 = __esm({
|
|
|
59946
61252
|
context: contextCommand4,
|
|
59947
61253
|
impact: impactCommand3,
|
|
59948
61254
|
analyze: analyzeCommand3,
|
|
59949
|
-
query:
|
|
61255
|
+
query: queryCommand3,
|
|
59950
61256
|
projects: projectsCommand,
|
|
59951
61257
|
"refresh-bridge": refreshBridgeCommand,
|
|
59952
61258
|
export: exportCommand6,
|
|
@@ -64645,7 +65951,7 @@ var init_saga = __esm({
|
|
|
64645
65951
|
createCommand3 = defineCommand({
|
|
64646
65952
|
meta: {
|
|
64647
65953
|
name: "create",
|
|
64648
|
-
description: "Create a new Saga (
|
|
65954
|
+
description: "Create a new Saga (top-level task with type='saga')"
|
|
64649
65955
|
},
|
|
64650
65956
|
args: {
|
|
64651
65957
|
title: {
|
|
@@ -64689,12 +65995,12 @@ var init_saga = __esm({
|
|
|
64689
65995
|
addCommand11 = defineCommand({
|
|
64690
65996
|
meta: {
|
|
64691
65997
|
name: "add",
|
|
64692
|
-
description: "Link a member Epic to a Saga
|
|
65998
|
+
description: "Link a member Epic to a Saga via parent_id containment"
|
|
64693
65999
|
},
|
|
64694
66000
|
args: {
|
|
64695
66001
|
sagaId: {
|
|
64696
66002
|
type: "positional",
|
|
64697
|
-
description: "Saga task ID (must have
|
|
66003
|
+
description: "Saga task ID (must have type='saga')",
|
|
64698
66004
|
required: true
|
|
64699
66005
|
},
|
|
64700
66006
|
epicId: {
|
|
@@ -64716,7 +66022,7 @@ var init_saga = __esm({
|
|
|
64716
66022
|
detachCommand2 = defineCommand({
|
|
64717
66023
|
meta: {
|
|
64718
66024
|
name: "detach",
|
|
64719
|
-
description: "Remove a Saga member
|
|
66025
|
+
description: "Remove a Saga member via parent_id containment \u2014 idempotent, audit-logged"
|
|
64720
66026
|
},
|
|
64721
66027
|
args: {
|
|
64722
66028
|
sagaId: {
|
|
@@ -64748,7 +66054,7 @@ var init_saga = __esm({
|
|
|
64748
66054
|
listCommand22 = defineCommand({
|
|
64749
66055
|
meta: {
|
|
64750
66056
|
name: "list",
|
|
64751
|
-
description: "List all Sagas
|
|
66057
|
+
description: "List all Sagas"
|
|
64752
66058
|
},
|
|
64753
66059
|
async run() {
|
|
64754
66060
|
await dispatchFromCli("query", "tasks", "saga.list", {}, { command: "saga" });
|
|
@@ -64757,7 +66063,7 @@ var init_saga = __esm({
|
|
|
64757
66063
|
membersCommand = defineCommand({
|
|
64758
66064
|
meta: {
|
|
64759
66065
|
name: "members",
|
|
64760
|
-
description: "List all member Epics linked to a Saga via
|
|
66066
|
+
description: "List all member Epics linked to a Saga via parent_id containment"
|
|
64761
66067
|
},
|
|
64762
66068
|
args: {
|
|
64763
66069
|
sagaId: {
|
|
@@ -64779,12 +66085,12 @@ var init_saga = __esm({
|
|
|
64779
66085
|
repairCommand = defineCommand({
|
|
64780
66086
|
meta: {
|
|
64781
66087
|
name: "repair",
|
|
64782
|
-
description: "Detach an I5-violating parentId from a Saga
|
|
66088
|
+
description: "Detach an I5-violating parentId from a Saga. Idempotent."
|
|
64783
66089
|
},
|
|
64784
66090
|
args: {
|
|
64785
66091
|
sagaId: {
|
|
64786
66092
|
type: "positional",
|
|
64787
|
-
description: "Saga task ID (must have
|
|
66093
|
+
description: "Saga task ID (must have type='saga')",
|
|
64788
66094
|
required: true
|
|
64789
66095
|
}
|
|
64790
66096
|
},
|
|
@@ -66582,7 +67888,7 @@ __export(sequence_exports, {
|
|
|
66582
67888
|
sequenceCommand: () => sequenceCommand
|
|
66583
67889
|
});
|
|
66584
67890
|
import { getProjectRoot as getProjectRoot51 } from "@cleocode/core/internal";
|
|
66585
|
-
var showCommand12,
|
|
67891
|
+
var showCommand12, checkCommand7, repairCommand2, sequenceCommand;
|
|
66586
67892
|
var init_sequence = __esm({
|
|
66587
67893
|
"packages/cleo/src/cli/commands/sequence.ts"() {
|
|
66588
67894
|
"use strict";
|
|
@@ -66601,7 +67907,7 @@ var init_sequence = __esm({
|
|
|
66601
67907
|
);
|
|
66602
67908
|
}
|
|
66603
67909
|
});
|
|
66604
|
-
|
|
67910
|
+
checkCommand7 = defineCommand({
|
|
66605
67911
|
meta: { name: "check", description: "Verify counter >= max(todo + archive)" },
|
|
66606
67912
|
async run() {
|
|
66607
67913
|
await dispatchFromCli(
|
|
@@ -66636,7 +67942,7 @@ var init_sequence = __esm({
|
|
|
66636
67942
|
},
|
|
66637
67943
|
subCommands: {
|
|
66638
67944
|
show: showCommand12,
|
|
66639
|
-
check:
|
|
67945
|
+
check: checkCommand7,
|
|
66640
67946
|
repair: repairCommand2
|
|
66641
67947
|
},
|
|
66642
67948
|
async run({ cmd, rawArgs }) {
|
|
@@ -70433,7 +71739,7 @@ var testing_exports = {};
|
|
|
70433
71739
|
__export(testing_exports, {
|
|
70434
71740
|
testingCommand: () => testingCommand
|
|
70435
71741
|
});
|
|
70436
|
-
var validateCommand9,
|
|
71742
|
+
var validateCommand9, checkCommand8, statusCommand16, coverageCommand, runCommand5, testingCommand;
|
|
70437
71743
|
var init_testing = __esm({
|
|
70438
71744
|
"packages/cleo/src/cli/commands/testing.ts"() {
|
|
70439
71745
|
"use strict";
|
|
@@ -70467,7 +71773,7 @@ var init_testing = __esm({
|
|
|
70467
71773
|
);
|
|
70468
71774
|
}
|
|
70469
71775
|
});
|
|
70470
|
-
|
|
71776
|
+
checkCommand8 = defineCommand({
|
|
70471
71777
|
meta: { name: "check", description: "Validate testing protocol from a manifest file" },
|
|
70472
71778
|
args: {
|
|
70473
71779
|
manifestFile: {
|
|
@@ -70540,7 +71846,7 @@ var init_testing = __esm({
|
|
|
70540
71846
|
meta: { name: "testing", description: "Validate testing protocol compliance" },
|
|
70541
71847
|
subCommands: {
|
|
70542
71848
|
validate: validateCommand9,
|
|
70543
|
-
check:
|
|
71849
|
+
check: checkCommand8,
|
|
70544
71850
|
status: statusCommand16,
|
|
70545
71851
|
coverage: coverageCommand,
|
|
70546
71852
|
run: runCommand5
|
|
@@ -72287,7 +73593,7 @@ var validateCommand10, applyCommand, planCommand4, structureCommand, workgraphCo
|
|
|
72287
73593
|
var init_workgraph2 = __esm({
|
|
72288
73594
|
"packages/cleo/src/cli/commands/workgraph.ts"() {
|
|
72289
73595
|
"use strict";
|
|
72290
|
-
|
|
73596
|
+
init_define_cli_command();
|
|
72291
73597
|
validateCommand10 = defineCommand({
|
|
72292
73598
|
meta: {
|
|
72293
73599
|
name: "validate",
|
|
@@ -73096,7 +74402,7 @@ var COMMAND_MANIFEST = [
|
|
|
73096
74402
|
{
|
|
73097
74403
|
exportName: "docsCommand",
|
|
73098
74404
|
name: "docs",
|
|
73099
|
-
description: "
|
|
74405
|
+
description: "Canonical six-verb docs path: add, update, fetch, list, remove, publish. ",
|
|
73100
74406
|
load: async () => (await Promise.resolve().then(() => (init_docs3(), docs_exports))).docsCommand
|
|
73101
74407
|
},
|
|
73102
74408
|
{
|
|
@@ -73312,7 +74618,7 @@ var COMMAND_MANIFEST = [
|
|
|
73312
74618
|
{
|
|
73313
74619
|
exportName: "memoryCommand",
|
|
73314
74620
|
name: "memory",
|
|
73315
|
-
description: "BRAIN memory operations (patterns, learnings)",
|
|
74621
|
+
description: "BRAIN memory operations (patterns, learnings, decisions \u2014 use decision-store/-find for architectural decisions)",
|
|
73316
74622
|
load: async () => (await Promise.resolve().then(() => (init_memory3(), memory_exports))).memoryCommand
|
|
73317
74623
|
},
|
|
73318
74624
|
{
|