domain-knowledge-kit 0.2.8 → 0.2.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +34 -139
  2. package/dist/cli.js +10 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/features/audit/commands/stats.d.ts +3 -0
  5. package/dist/features/audit/commands/stats.d.ts.map +1 -0
  6. package/dist/features/audit/commands/stats.js +90 -0
  7. package/dist/features/audit/commands/stats.js.map +1 -0
  8. package/dist/features/pipeline/commands/validate.d.ts.map +1 -1
  9. package/dist/features/pipeline/commands/validate.js +32 -13
  10. package/dist/features/pipeline/commands/validate.js.map +1 -1
  11. package/dist/features/query/commands/graph.d.ts +3 -0
  12. package/dist/features/query/commands/graph.d.ts.map +1 -0
  13. package/dist/features/query/commands/graph.js +86 -0
  14. package/dist/features/query/commands/graph.js.map +1 -0
  15. package/dist/features/query/commands/summary.d.ts +7 -0
  16. package/dist/features/query/commands/summary.d.ts.map +1 -0
  17. package/dist/features/query/commands/summary.js +43 -0
  18. package/dist/features/query/commands/summary.js.map +1 -0
  19. package/dist/features/refactor/commands/rename.d.ts +3 -0
  20. package/dist/features/refactor/commands/rename.d.ts.map +1 -0
  21. package/dist/features/refactor/commands/rename.js +152 -0
  22. package/dist/features/refactor/commands/rename.js.map +1 -0
  23. package/dist/features/refactor/commands/rm.d.ts +3 -0
  24. package/dist/features/refactor/commands/rm.d.ts.map +1 -0
  25. package/dist/features/refactor/commands/rm.js +93 -0
  26. package/dist/features/refactor/commands/rm.js.map +1 -0
  27. package/dist/features/scaffold/commands/add-item.d.ts +11 -0
  28. package/dist/features/scaffold/commands/add-item.d.ts.map +1 -1
  29. package/dist/features/scaffold/commands/add-item.js +119 -23
  30. package/dist/features/scaffold/commands/add-item.js.map +1 -1
  31. package/dist/features/scaffold/commands/new-adr.d.ts.map +1 -1
  32. package/dist/features/scaffold/commands/new-adr.js +19 -2
  33. package/dist/features/scaffold/commands/new-adr.js.map +1 -1
  34. package/dist/features/scaffold/commands/new-context.d.ts.map +1 -1
  35. package/dist/features/scaffold/commands/new-context.js +10 -0
  36. package/dist/features/scaffold/commands/new-context.js.map +1 -1
  37. package/dist/features/scaffold/commands/new-domain.d.ts.map +1 -1
  38. package/dist/features/scaffold/commands/new-domain.js +9 -0
  39. package/dist/features/scaffold/commands/new-domain.js.map +1 -1
  40. package/package.json +1 -1
package/README.md CHANGED
@@ -1,147 +1,42 @@
1
1
  # Domain Knowledge Kit
2
2
 
3
- Define, validate, search, and document your domain model all from YAML.
4
-
5
- ## What Is This?
6
-
7
- Domain Knowledge Kit (DKK) is a CLI tool for teams practicing Domain-Driven Design. Instead of scattering domain knowledge across wikis, diagrams, and tribal memory, you define your **bounded contexts**, **events**, **commands**, **policies**, **aggregates**, **read models**, and **glossary** in structured YAML files. DKK then:
8
-
9
- - **Validates** schema conformance and referential integrity across your entire model
10
- - **Generates** browsable Markdown documentation from your YAML definitions
11
- - **Builds** a full-text search index (SQLite FTS5) for instant domain queries
12
- - **Links** Architecture Decision Records (ADRs) bidirectionally to domain items
13
- - **Integrates** with AI coding agents so they understand your domain, not just your code
14
-
15
- ## Quick Start
16
-
17
- ```bash
18
- # Install
19
- npm install -g domain-knowledge-kit
20
-
21
- # Create a bounded context (per-item directory format)
22
- mkdir -p .dkk/domain/contexts/ordering/{events,commands,aggregates}
23
-
24
- # Context metadata
25
- cat > .dkk/domain/contexts/ordering/context.yml << 'EOF'
26
- name: ordering
27
- description: Handles customer order lifecycle.
28
- EOF
29
-
30
- # One file per domain item
31
- cat > .dkk/domain/contexts/ordering/events/OrderPlaced.yml << 'EOF'
32
- name: OrderPlaced
33
- description: Raised when a customer order is confirmed.
34
- raised_by: Order
35
- EOF
36
-
37
- cat > .dkk/domain/contexts/ordering/commands/PlaceOrder.yml << 'EOF'
38
- name: PlaceOrder
39
- description: Submit a new customer order.
40
- handled_by: Order
41
- EOF
42
-
43
- cat > .dkk/domain/contexts/ordering/aggregates/Order.yml << 'EOF'
44
- name: Order
45
- description: Manages order state and invariants.
46
- handles:
47
- commands:
48
- - PlaceOrder
49
- emits:
50
- events:
51
- - OrderPlaced
52
- EOF
53
-
54
- # Register it in .dkk/domain/index.yml
55
- # Add "- name: ordering" to the contexts array
56
-
57
- # Validate and render
58
- dkk validate
59
- dkk render
60
-
61
- # Explore
62
- dkk search "order"
63
- dkk show ordering.OrderPlaced
64
- dkk related ordering.Order
65
- ```
66
-
67
- → **[Full Getting Started Guide](docs/getting-started.md)** — step-by-step walkthrough with examples.
3
+ > *Humans design the domain. AI agents align the codebase.*
4
+
5
+ ## Philosophy
6
+
7
+ ### AI agents love structure
8
+
9
+ Large language models thrive with well-structured, unambiguous context. A flat codebase gives them syntax; a structured domain model gives them **meaning**. DKK makes your domain a first-class, machine-readable citizen of your repository.
10
+
11
+ ### Humans can define domain events easily
12
+
13
+ You don't need a diagram tool or a modeling session. Writing `OrderPlaced` in a YAML file — with a one-line description and a reference to the aggregate that emits it — is how humans naturally think in DDD. Defining events, commands, and policies in plain YAML reveals the bigger picture without drowning in implementation details.
14
+
15
+ ### Reading domain models beats reading code
16
+
17
+ Business logic spread across services, handlers, and database schemas is hard to reason about holistically. A domain model is a curated, intentional view of *what your system does and why* — not *how* it does it. DKK keeps that view always up-to-date and always searchable.
18
+
19
+ ### Keeping ADRs, even deprecated ones, preserves project memory
20
+
21
+ Architectural decisions aren't born in a vacuum. Understanding *why* a choice was made matters as much as knowing *what* the choice was. Deprecated ADRs aren't noise — they are the institutional memory that prevents teams (and AI agents) from relitigating past decisions.
22
+
23
+ ### Easy-to-reach, detailed, colocated knowledge for AI agents
24
+
25
+ Knowledge that lives next to the code is knowledge that gets used. DKK colocates your domain model, ADRs, and generated docs inside the repository itself. AI agents can discover, query, and traverse this knowledge without leaving the codebase — making every interaction domain-aware.
26
+
27
+ ---
68
28
 
69
29
  ## Documentation
70
30
 
71
- | Guide | What You'll Learn |
72
- |-------|-------------------|
73
- | **[Getting Started](docs/getting-started.md)** | Install, create your first context, run quality gates, search and explore |
74
- | **[Domain Modeling](docs/domain-modeling.md)** | All item types, YAML structure, cross-references, naming conventions, ID formats |
75
- | **[CLI Reference](docs/cli-reference.md)** | Every command and flag: `list`, `show`, `search`, `related`, `validate`, `render`, `init`, `prime`, `adr show`, `adr related` |
76
- | **[ADR Guide](docs/adr-guide.md)** | Architecture Decision Records: format, bidirectional linking, querying, best practices |
77
- | **[AI Agent Integration](docs/ai-agent-integration.md)** | `dkk init`, `dkk prime`, Copilot integration, reusable prompts, portable skills |
78
-
79
- ## Key Commands
80
-
81
- ```bash
82
- dkk validate # Schema + cross-reference validation
83
- dkk render # Validate → render docs → rebuild search index
84
- dkk search "payment" # Full-text search with ranking
85
- dkk show ordering.Order # Display full item definition
86
- dkk related ordering.Order # Graph traversal of connected items
87
- dkk list --type event # List all events across contexts
88
- dkk init # Set up AI agent onboarding
89
- dkk prime # Output agent context to stdout
90
- ```
91
-
92
- → **[Full CLI Reference](docs/cli-reference.md)**
93
-
94
- ## AI Agent Integration
95
-
96
- DKK has first-class support for AI coding agents. Two commands get you set up:
97
-
98
- ```bash
99
- dkk init # Add a DKK section to AGENTS.md (idempotent)
100
- dkk prime # Output full domain context for AI consumption
101
- ```
102
-
103
- Agents can then search, show, and traverse your domain model — making domain-aware decisions when writing, reviewing, or refactoring code. DKK also ships with GitHub Copilot instructions, reusable agent prompts, and a portable agent skill.
104
-
105
- → **[AI Agent Integration Guide](docs/ai-agent-integration.md)**
106
-
107
- ## Directory Layout
108
-
109
- ```
110
- .dkk/ # Domain model + generated + managed
111
- domain/ # Domain model (YAML)
112
- index.yml # Contexts + flows
113
- actors.yml # Global actors
114
- contexts/ # Bounded contexts (one dir each)
115
- <name>/ # Context directory
116
- context.yml # Context metadata + glossary
117
- events/ # One .yml file per event
118
- commands/ # One .yml file per command
119
- aggregates/ # One .yml file per aggregate
120
- policies/ # One .yml file per policy
121
- read-models/ # One .yml file per read model
122
- adr/ # Architecture Decision Records
123
- docs/ # Generated docs (do not edit)
124
- src/ # Source code (vertical slices)
125
- tools/dkk/ # Schemas + templates
126
- schema/ # JSON Schemas for validation
127
- templates/ # Handlebars templates for rendering
128
- ```
129
-
130
- ## Contributing / Local Development
131
-
132
- ```bash
133
- npm install
134
-
135
- # Run directly via tsx (no build step needed)
136
- npm run dev -- validate
137
- npm run dev -- render
138
-
139
- # Or build first
140
- npm run build
141
- npx dkk validate
142
- ```
143
-
144
- The source code uses **vertical feature slices** — each feature (`query`, `adr`, `pipeline`, `agent`) owns its commands, logic, and tests. Cross-cutting infrastructure lives in `shared/`.
31
+ All technical details, CLI references, and integration guides live in the [`docs/`](docs/) folder.
32
+
33
+ | Guide | What It Covers |
34
+ |-------|----------------|
35
+ | **[Getting Started](docs/getting-started.md)** | Installation, first context, quality gates |
36
+ | **[Domain Modeling](docs/domain-modeling.md)** | YAML structure, item types, naming conventions |
37
+ | **[CLI Reference](docs/cli-reference.md)** | Every command and flag |
38
+ | **[ADR Guide](docs/adr-guide.md)** | Writing, linking, and querying ADRs |
39
+ | **[AI Agent Integration](docs/ai-agent-integration.md)** | Onboarding agents, context-efficient retrieval |
145
40
 
146
41
  ## License
147
42
 
package/dist/cli.js CHANGED
@@ -2,8 +2,10 @@
2
2
  import { Command } from "commander";
3
3
  import { registerList } from "./features/query/commands/list.js";
4
4
  import { registerShow } from "./features/query/commands/show.js";
5
+ import { registerSummary } from "./features/query/commands/summary.js";
5
6
  import { registerSearch } from "./features/query/commands/search.js";
6
7
  import { registerRelated } from "./features/query/commands/related.js";
8
+ import { registerGraph } from "./features/query/commands/graph.js";
7
9
  import { registerValidate } from "./features/pipeline/commands/validate.js";
8
10
  import { registerRender } from "./features/pipeline/commands/render.js";
9
11
  import { registerAdrShow } from "./features/adr/commands/adr-show.js";
@@ -14,6 +16,9 @@ import { registerNewDomain } from "./features/scaffold/commands/new-domain.js";
14
16
  import { registerNewContext } from "./features/scaffold/commands/new-context.js";
15
17
  import { registerNewAdr } from "./features/scaffold/commands/new-adr.js";
16
18
  import { registerAddItem } from "./features/scaffold/commands/add-item.js";
19
+ import { registerRename } from "./features/refactor/commands/rename.js";
20
+ import { registerRm } from "./features/refactor/commands/rm.js";
21
+ import { registerStats } from "./features/audit/commands/stats.js";
17
22
  import { formatCliError } from "./shared/errors.js";
18
23
  /** Whether to show full stack traces (set DEBUG=1 in env). */
19
24
  const DEBUG = Boolean(process.env.DEBUG);
@@ -26,12 +31,17 @@ program
26
31
  // Top-level commands
27
32
  registerList(program);
28
33
  registerShow(program);
34
+ registerSummary(program);
29
35
  registerSearch(program);
30
36
  registerRelated(program);
37
+ registerGraph(program);
31
38
  registerValidate(program);
32
39
  registerRender(program);
33
40
  registerInit(program);
34
41
  registerPrime(program);
42
+ registerRename(program);
43
+ registerRm(program);
44
+ registerStats(program);
35
45
  // ADR sub-command group
36
46
  const adrCmd = program
37
47
  .command("adr")
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAC;AAC/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,8DAA8D;AAC9D,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAEzC,yEAAyE;AAEzE,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,KAAK,CAAC;KACX,WAAW,CAAC,2BAA2B,CAAC;KACxC,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,qBAAqB;AACrB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,eAAe,CAAC,OAAO,CAAC,CAAC;AACzB,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAC1B,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,aAAa,CAAC,OAAO,CAAC,CAAC;AAEvB,wBAAwB;AACxB,MAAM,MAAM,GAAG,OAAO;KACnB,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,sBAAsB,CAAC,CAAC;AAEvC,eAAe,CAAC,MAAM,CAAC,CAAC;AACxB,kBAAkB,CAAC,MAAM,CAAC,CAAC;AAE3B,0BAA0B;AAC1B,MAAM,MAAM,GAAG,OAAO;KACnB,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,gCAAgC,CAAC,CAAC;AAEjD,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAC1B,kBAAkB,CAAC,MAAM,CAAC,CAAC;AAC3B,cAAc,CAAC,MAAM,CAAC,CAAC;AAEvB,sDAAsD;AACtD,eAAe,CAAC,OAAO,CAAC,CAAC;AAEzB,OAAO,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAC1C,OAAO,CAAC,KAAK,CAAC,UAAU,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC/C,IAAI,KAAK,IAAI,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;QAC/C,OAAO,CAAC,KAAK,CAAC,mBAAmB,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAC;AAC/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,8DAA8D;AAC9D,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAEzC,yEAAyE;AAEzE,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,KAAK,CAAC;KACX,WAAW,CAAC,2BAA2B,CAAC;KACxC,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,qBAAqB;AACrB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,eAAe,CAAC,OAAO,CAAC,CAAC;AACzB,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,eAAe,CAAC,OAAO,CAAC,CAAC;AACzB,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAC1B,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,UAAU,CAAC,OAAO,CAAC,CAAC;AACpB,aAAa,CAAC,OAAO,CAAC,CAAC;AAEvB,wBAAwB;AACxB,MAAM,MAAM,GAAG,OAAO;KACnB,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,sBAAsB,CAAC,CAAC;AAEvC,eAAe,CAAC,MAAM,CAAC,CAAC;AACxB,kBAAkB,CAAC,MAAM,CAAC,CAAC;AAE3B,0BAA0B;AAC1B,MAAM,MAAM,GAAG,OAAO;KACnB,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,gCAAgC,CAAC,CAAC;AAEjD,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAC1B,kBAAkB,CAAC,MAAM,CAAC,CAAC;AAC3B,cAAc,CAAC,MAAM,CAAC,CAAC;AAEvB,sDAAsD;AACtD,eAAe,CAAC,OAAO,CAAC,CAAC;AAEzB,OAAO,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAC1C,OAAO,CAAC,KAAK,CAAC,UAAU,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC/C,IAAI,KAAK,IAAI,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;QAC/C,OAAO,CAAC,KAAK,CAAC,mBAAmB,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Command as Cmd } from "commander";
2
+ export declare function registerStats(program: Cmd): void;
3
+ //# sourceMappingURL=stats.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../../../src/features/audit/commands/stats.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,WAAW,CAAC;AAIhD,wBAAgB,aAAa,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI,CA4EhD"}
@@ -0,0 +1,90 @@
1
+ import { loadDomainModel } from "../../../shared/loader.js";
2
+ import { DomainGraph } from "../../../shared/graph.js";
3
+ export function registerStats(program) {
4
+ program
5
+ .command("stats")
6
+ .description("Print domain model statistics and potential orphaned items")
7
+ .option("-r, --root <path>", "Override repository root")
8
+ .action((opts) => {
9
+ const model = loadDomainModel({ root: opts.root });
10
+ const graph = DomainGraph.from(model);
11
+ const stats = {
12
+ contexts: 0,
13
+ events: 0,
14
+ commands: 0,
15
+ aggregates: 0,
16
+ policies: 0,
17
+ readModels: 0,
18
+ actors: 0,
19
+ adrs: 0,
20
+ flows: 0,
21
+ orphaned: []
22
+ };
23
+ for (const [id, node] of graph.nodes) {
24
+ switch (node.kind) {
25
+ case "context":
26
+ stats.contexts++;
27
+ break;
28
+ case "event":
29
+ stats.events++;
30
+ break;
31
+ case "command":
32
+ stats.commands++;
33
+ break;
34
+ case "aggregate":
35
+ stats.aggregates++;
36
+ break;
37
+ case "policy":
38
+ stats.policies++;
39
+ break;
40
+ case "read_model":
41
+ stats.readModels++;
42
+ break;
43
+ case "actor":
44
+ stats.actors++;
45
+ break;
46
+ case "adr":
47
+ stats.adrs++;
48
+ break;
49
+ case "flow":
50
+ stats.flows++;
51
+ break;
52
+ }
53
+ // Check for orphaned items (items with only 1 edge = "contains" from context,
54
+ // meaning they don't participate in handles/emits/triggers/etc with other items)
55
+ if (node.kind !== "context" && node.kind !== "actor" && node.kind !== "adr" && node.kind !== "flow" && node.kind !== "glossary") {
56
+ let connectionCount = 0;
57
+ for (const edge of graph.edges) {
58
+ if ((edge.from === id || edge.to === id) && edge.label !== "contains") {
59
+ connectionCount++;
60
+ }
61
+ }
62
+ if (connectionCount === 0) {
63
+ stats.orphaned.push(id);
64
+ }
65
+ }
66
+ }
67
+ console.log(`\n📊 Domain Model Statistics\n`);
68
+ console.log(` Contexts: ${stats.contexts}`);
69
+ console.log(` Events: ${stats.events}`);
70
+ console.log(` Commands: ${stats.commands}`);
71
+ console.log(` Aggregates: ${stats.aggregates}`);
72
+ console.log(` Policies: ${stats.policies}`);
73
+ console.log(` Read Models: ${stats.readModels}`);
74
+ console.log(` Actors: ${stats.actors}`);
75
+ console.log(` Flows: ${stats.flows}`);
76
+ console.log(` ADRs: ${stats.adrs}`);
77
+ console.log(`\n🔍 Health Check`);
78
+ if (stats.orphaned.length > 0) {
79
+ console.log(` Found ${stats.orphaned.length} potentially orphaned items (no relationships):`);
80
+ for (const orphan of stats.orphaned) {
81
+ console.log(` - ${orphan}`);
82
+ }
83
+ }
84
+ else {
85
+ console.log(` No orphaned items found! All clear.`);
86
+ }
87
+ console.log("");
88
+ });
89
+ }
90
+ //# sourceMappingURL=stats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.js","sourceRoot":"","sources":["../../../../src/features/audit/commands/stats.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../../src/features/pipeline/commands/validate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,WAAW,CAAC;AAIhD,0CAA0C;AAC1C,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI,CA8CnD"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../../src/features/pipeline/commands/validate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,WAAW,CAAC;AAIhD,0CAA0C;AAC1C,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI,CAiEnD"}
@@ -3,40 +3,59 @@ import { validateDomainModel } from "../validator.js";
3
3
  /** Register the `validate` subcommand. */
4
4
  export function registerValidate(program) {
5
5
  program
6
- .command("validate")
6
+ .command("validate [id]")
7
7
  .description("Validate domain YAML against schemas and cross-references")
8
8
  .option("--warn-missing-fields", "Warn about events/commands with no fields")
9
9
  .option("--json", "Output as JSON")
10
+ .option("--minify", "Minify JSON output (useful for AI agents)")
10
11
  .option("-r, --root <path>", "Override repository root")
11
- .action((opts) => {
12
+ .action((id, opts) => {
12
13
  const model = loadDomainModel({ root: opts.root });
13
14
  const result = validateDomainModel(model, {
14
15
  warnMissingFields: opts.warnMissingFields,
15
16
  });
17
+ let { valid, errors, warnings } = result;
18
+ if (id) {
19
+ const isMatch = (p) => {
20
+ if (!p)
21
+ return false;
22
+ if (p === `actor:${id}` || p === `adr:${id}` || p === `context:${id}`)
23
+ return true;
24
+ const [ctx, name] = id.split(".");
25
+ if (ctx && name) {
26
+ return p.startsWith(`context:${ctx}.`) && p.endsWith(`:${name}`);
27
+ }
28
+ return false;
29
+ };
30
+ errors = errors.filter((e) => isMatch(e.path));
31
+ warnings = warnings.filter((w) => isMatch(w.path));
32
+ valid = errors.length === 0;
33
+ }
16
34
  if (opts.json) {
17
- console.log(JSON.stringify({
18
- valid: result.valid,
19
- errors: result.errors.map((e) => ({ message: e.message, path: e.path ?? null })),
20
- warnings: result.warnings.map((w) => ({ message: w.message, path: w.path ?? null })),
21
- }, null, 2));
22
- if (!result.valid)
35
+ const payload = {
36
+ valid,
37
+ errors: errors.map((e) => ({ message: e.message, path: e.path ?? null })),
38
+ warnings: warnings.map((w) => ({ message: w.message, path: w.path ?? null })),
39
+ };
40
+ console.log(JSON.stringify(payload, null, opts.minify ? 0 : 2));
41
+ if (!valid)
23
42
  process.exit(1);
24
43
  return;
25
44
  }
26
45
  // Print warnings
27
- for (const w of result.warnings) {
46
+ for (const w of warnings) {
28
47
  const loc = w.path ? ` (${w.path})` : "";
29
48
  console.warn(`\u26a0 ${w.message}${loc}`);
30
49
  }
31
50
  // Print errors
32
- for (const e of result.errors) {
51
+ for (const e of errors) {
33
52
  const loc = e.path ? ` (${e.path})` : "";
34
53
  console.error(`\u2717 ${e.message}${loc}`);
35
54
  }
36
55
  // Summary
37
- const warnCount = result.warnings.length;
38
- const errCount = result.errors.length;
39
- if (result.valid) {
56
+ const warnCount = warnings.length;
57
+ const errCount = errors.length;
58
+ if (valid) {
40
59
  console.log(`\n\u2713 Validation passed.${warnCount > 0 ? ` (${warnCount} warning(s))` : ""}\n`);
41
60
  }
42
61
  else {
@@ -1 +1 @@
1
- {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../../src/features/pipeline/commands/validate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../../src/features/pipeline/commands/validate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Command as Cmd } from "commander";
2
+ export declare function registerGraph(program: Cmd): void;
3
+ //# sourceMappingURL=graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../../../src/features/query/commands/graph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,WAAW,CAAC;AAUhD,wBAAgB,aAAa,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI,CA6EhD"}
@@ -0,0 +1,86 @@
1
+ import { writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { loadDomainModel } from "../../../shared/loader.js";
4
+ import { DomainGraph } from "../../../shared/graph.js";
5
+ function escapeMermaidId(id) {
6
+ return id.replace(/[\.\-]/g, "_");
7
+ }
8
+ export function registerGraph(program) {
9
+ program
10
+ .command("graph")
11
+ .description("Generate a Mermaid.js flowchart of the domain model")
12
+ .option("-o, --output <file>", "Output file path (default: .dkk/docs/graph.md)")
13
+ .option("-d, --depth <n>", "Maximum traversal depth for large graphs", parseInt, 3)
14
+ .option("-r, --root <path>", "Override repository root")
15
+ .action((opts) => {
16
+ const model = loadDomainModel({ root: opts.root });
17
+ const graph = DomainGraph.from(model);
18
+ const outPath = opts.output || (opts.root ? join(opts.root, ".dkk", "docs", "graph.md") : join(process.cwd(), ".dkk", "docs", "graph.md"));
19
+ const lines = ["```mermaid", "flowchart TD"];
20
+ // Write nodes
21
+ const writtenNodes = new Set();
22
+ for (const [id, node] of graph.nodes) {
23
+ const mId = escapeMermaidId(id);
24
+ writtenNodes.add(mId);
25
+ const label = node.name;
26
+ let shape = `[${label}]`;
27
+ switch (node.kind) {
28
+ case "event":
29
+ shape = `> ${label} ]`;
30
+ break;
31
+ case "command":
32
+ shape = `([${label}])`;
33
+ break;
34
+ case "aggregate":
35
+ shape = `[[${label}]]`;
36
+ break;
37
+ case "policy":
38
+ shape = `{{${label}}}`;
39
+ break;
40
+ case "read_model":
41
+ shape = `[(${label})]`;
42
+ break;
43
+ case "actor":
44
+ shape = `(( ${label} ))`;
45
+ break;
46
+ case "flow":
47
+ shape = `[[${label}]]`;
48
+ break;
49
+ case "adr":
50
+ shape = `[\\${label}\\]`;
51
+ break;
52
+ }
53
+ lines.push(` ${mId}${shape}`);
54
+ }
55
+ lines.push("\n %% Relationships");
56
+ // Write edges
57
+ for (const edge of graph.edges) {
58
+ // Filter out internal structural edges
59
+ if (edge.label === "contains" || edge.label === "flow_next" || edge.label === "adr_ref") {
60
+ continue;
61
+ }
62
+ const from = escapeMermaidId(edge.from);
63
+ const to = escapeMermaidId(edge.to);
64
+ let link = `-->`;
65
+ if (edge.label === "subscribes_to" || edge.label === "used_by") {
66
+ link = `-.->`;
67
+ }
68
+ else if (edge.label === "handles") {
69
+ link = `==>`;
70
+ }
71
+ lines.push(` ${from} ${link}|${edge.label}| ${to}`);
72
+ }
73
+ lines.push("```\n");
74
+ const content = lines.join("\n");
75
+ try {
76
+ writeFileSync(outPath, content, "utf-8");
77
+ console.log(`Generated Mermaid graph at ${outPath}`);
78
+ }
79
+ catch (err) {
80
+ const msg = err instanceof Error ? err.message : String(err);
81
+ console.error(`Failed to write graph to ${outPath}:`, msg);
82
+ process.exit(1);
83
+ }
84
+ });
85
+ }
86
+ //# sourceMappingURL=graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.js","sourceRoot":"","sources":["../../../../src/features/query/commands/graph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * `domain summary <id>` command — concise overview of an item.
3
+ */
4
+ import type { Command as Cmd } from "commander";
5
+ /** Register the `summary` subcommand. */
6
+ export declare function registerSummary(program: Cmd): void;
7
+ //# sourceMappingURL=summary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary.d.ts","sourceRoot":"","sources":["../../../../src/features/query/commands/summary.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,WAAW,CAAC;AAIhD,yCAAyC;AACzC,wBAAgB,eAAe,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI,CAwClD"}
@@ -0,0 +1,43 @@
1
+ import { loadDomainModel } from "../../../shared/loader.js";
2
+ import { DomainGraph } from "../../../shared/graph.js";
3
+ /** Register the `summary` subcommand. */
4
+ export function registerSummary(program) {
5
+ program
6
+ .command("summary <id>")
7
+ .description("Show a concise summary of a domain item (useful for AI context)")
8
+ .option("--json", "Output as JSON")
9
+ .option("--minify", "Minify JSON output")
10
+ .option("-r, --root <path>", "Override repository root")
11
+ .action((id, opts) => {
12
+ const model = loadDomainModel({ root: opts.root });
13
+ const graph = DomainGraph.from(model);
14
+ const node = graph.nodes.get(id);
15
+ if (!node) {
16
+ if (opts.json) {
17
+ console.log(JSON.stringify({ error: `Item "${id}" not found` }, null, opts.minify ? 0 : 2));
18
+ }
19
+ else {
20
+ console.error(`Error: Item "${id}" not found.`);
21
+ }
22
+ process.exit(1);
23
+ }
24
+ const related = Array.from(graph.getRelated(id, 1));
25
+ if (opts.json) {
26
+ const payload = {
27
+ id: node.id,
28
+ name: node.name,
29
+ kind: node.kind,
30
+ context: node.context,
31
+ related,
32
+ };
33
+ console.log(JSON.stringify(payload, null, opts.minify ? 0 : 2));
34
+ return;
35
+ }
36
+ console.log(`\n# [${node.kind}] ${node.name}${node.context ? ` (Context: ${node.context})` : ""}\n`);
37
+ console.log(`Related (${related.length}):`);
38
+ for (const r of related)
39
+ console.log(` - ${r}`);
40
+ console.log();
41
+ });
42
+ }
43
+ //# sourceMappingURL=summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary.js","sourceRoot":"","sources":["../../../../src/features/query/commands/summary.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,yCAAyC;AACzC,MAAM,UAAU,eAAe,CAAC,OAAY;IAC1C,OAAO;SACJ,OAAO,CAAC,cAAc,CAAC;SACvB,WAAW,CAAC,iEAAiE,CAAC;SAC9E,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC;SAClC,MAAM,CAAC,UAAU,EAAE,oBAAoB,CAAC;SACxC,MAAM,CAAC,mBAAmB,EAAE,0BAA0B,CAAC;SACvD,MAAM,CAAC,CAAC,EAAU,EAAE,IAAyD,EAAE,EAAE;QAChF,MAAM,KAAK,GAAG,eAAe,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACnD,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAEtC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9F,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,cAAc,CAAC,CAAC;YAClD,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QAEpD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,MAAM,OAAO,GAAG;gBACd,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,OAAO;aACR,CAAC;YACF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAChE,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QACrG,OAAO,CAAC,GAAG,CAAC,YAAY,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;QAC5C,KAAK,MAAM,CAAC,IAAI,OAAO;YAAE,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACjD,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Command as Cmd } from "commander";
2
+ export declare function registerRename(program: Cmd): void;
3
+ //# sourceMappingURL=rename.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rename.d.ts","sourceRoot":"","sources":["../../../../src/features/refactor/commands/rename.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,WAAW,CAAC;AAkChD,wBAAgB,cAAc,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI,CAyIjD"}