@brad-frost-web/eddie-brain 0.32.0

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 (239) hide show
  1. package/README.md +109 -0
  2. package/dist/analyze/drift-detector.d.ts +30 -0
  3. package/dist/analyze/drift-detector.d.ts.map +1 -0
  4. package/dist/analyze/drift-detector.js +310 -0
  5. package/dist/analyze/drift-detector.js.map +1 -0
  6. package/dist/analyze/health-scorer.d.ts +71 -0
  7. package/dist/analyze/health-scorer.d.ts.map +1 -0
  8. package/dist/analyze/health-scorer.js +420 -0
  9. package/dist/analyze/health-scorer.js.map +1 -0
  10. package/dist/analyze/index.d.ts +11 -0
  11. package/dist/analyze/index.d.ts.map +1 -0
  12. package/dist/analyze/index.js +11 -0
  13. package/dist/analyze/index.js.map +1 -0
  14. package/dist/analyze/naming-validator.d.ts +99 -0
  15. package/dist/analyze/naming-validator.d.ts.map +1 -0
  16. package/dist/analyze/naming-validator.js +430 -0
  17. package/dist/analyze/naming-validator.js.map +1 -0
  18. package/dist/analyze/slot-contract-validator.d.ts +68 -0
  19. package/dist/analyze/slot-contract-validator.d.ts.map +1 -0
  20. package/dist/analyze/slot-contract-validator.js +232 -0
  21. package/dist/analyze/slot-contract-validator.js.map +1 -0
  22. package/dist/analyze/token-validator.d.ts +62 -0
  23. package/dist/analyze/token-validator.d.ts.map +1 -0
  24. package/dist/analyze/token-validator.js +348 -0
  25. package/dist/analyze/token-validator.js.map +1 -0
  26. package/dist/cli/brain.d.ts +12 -0
  27. package/dist/cli/brain.d.ts.map +1 -0
  28. package/dist/cli/brain.js +641 -0
  29. package/dist/cli/brain.js.map +1 -0
  30. package/dist/cli/formatters/json.d.ts +15 -0
  31. package/dist/cli/formatters/json.d.ts.map +1 -0
  32. package/dist/cli/formatters/json.js +18 -0
  33. package/dist/cli/formatters/json.js.map +1 -0
  34. package/dist/cli/formatters/terminal.d.ts +19 -0
  35. package/dist/cli/formatters/terminal.d.ts.map +1 -0
  36. package/dist/cli/formatters/terminal.js +125 -0
  37. package/dist/cli/formatters/terminal.js.map +1 -0
  38. package/dist/cli/index.d.ts +7 -0
  39. package/dist/cli/index.d.ts.map +1 -0
  40. package/dist/cli/index.js +7 -0
  41. package/dist/cli/index.js.map +1 -0
  42. package/dist/data/governance-rules.json +94 -0
  43. package/dist/governance/audit-log.d.ts +17 -0
  44. package/dist/governance/audit-log.d.ts.map +1 -0
  45. package/dist/governance/audit-log.js +44 -0
  46. package/dist/governance/audit-log.js.map +1 -0
  47. package/dist/governance/index.d.ts +8 -0
  48. package/dist/governance/index.d.ts.map +1 -0
  49. package/dist/governance/index.js +8 -0
  50. package/dist/governance/index.js.map +1 -0
  51. package/dist/governance/permissions.d.ts +26 -0
  52. package/dist/governance/permissions.d.ts.map +1 -0
  53. package/dist/governance/permissions.js +75 -0
  54. package/dist/governance/permissions.js.map +1 -0
  55. package/dist/governance/rules-engine.d.ts +24 -0
  56. package/dist/governance/rules-engine.d.ts.map +1 -0
  57. package/dist/governance/rules-engine.js +111 -0
  58. package/dist/governance/rules-engine.js.map +1 -0
  59. package/dist/governance/trust-manager.d.ts +34 -0
  60. package/dist/governance/trust-manager.d.ts.map +1 -0
  61. package/dist/governance/trust-manager.js +148 -0
  62. package/dist/governance/trust-manager.js.map +1 -0
  63. package/dist/index.d.ts +23 -0
  64. package/dist/index.d.ts.map +1 -0
  65. package/dist/index.js +28 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/knowledge-graph/component-index.d.ts +320 -0
  68. package/dist/knowledge-graph/component-index.d.ts.map +1 -0
  69. package/dist/knowledge-graph/component-index.js +1033 -0
  70. package/dist/knowledge-graph/component-index.js.map +1 -0
  71. package/dist/knowledge-graph/index.d.ts +134 -0
  72. package/dist/knowledge-graph/index.d.ts.map +1 -0
  73. package/dist/knowledge-graph/index.js +249 -0
  74. package/dist/knowledge-graph/index.js.map +1 -0
  75. package/dist/knowledge-graph/learning-history.d.ts +77 -0
  76. package/dist/knowledge-graph/learning-history.d.ts.map +1 -0
  77. package/dist/knowledge-graph/learning-history.js +187 -0
  78. package/dist/knowledge-graph/learning-history.js.map +1 -0
  79. package/dist/knowledge-graph/relationship-map.d.ts +55 -0
  80. package/dist/knowledge-graph/relationship-map.d.ts.map +1 -0
  81. package/dist/knowledge-graph/relationship-map.js +238 -0
  82. package/dist/knowledge-graph/relationship-map.js.map +1 -0
  83. package/dist/knowledge-graph/token-taxonomy.d.ts +127 -0
  84. package/dist/knowledge-graph/token-taxonomy.d.ts.map +1 -0
  85. package/dist/knowledge-graph/token-taxonomy.js +357 -0
  86. package/dist/knowledge-graph/token-taxonomy.js.map +1 -0
  87. package/dist/loop/fix-agent.d.ts +55 -0
  88. package/dist/loop/fix-agent.d.ts.map +1 -0
  89. package/dist/loop/fix-agent.js +344 -0
  90. package/dist/loop/fix-agent.js.map +1 -0
  91. package/dist/loop/index.d.ts +8 -0
  92. package/dist/loop/index.d.ts.map +1 -0
  93. package/dist/loop/index.js +8 -0
  94. package/dist/loop/index.js.map +1 -0
  95. package/dist/loop/issue-fetcher.d.ts +51 -0
  96. package/dist/loop/issue-fetcher.d.ts.map +1 -0
  97. package/dist/loop/issue-fetcher.js +188 -0
  98. package/dist/loop/issue-fetcher.js.map +1 -0
  99. package/dist/loop/observer.d.ts +42 -0
  100. package/dist/loop/observer.d.ts.map +1 -0
  101. package/dist/loop/observer.js +220 -0
  102. package/dist/loop/observer.js.map +1 -0
  103. package/dist/loop/pacer.d.ts +44 -0
  104. package/dist/loop/pacer.d.ts.map +1 -0
  105. package/dist/loop/pacer.js +90 -0
  106. package/dist/loop/pacer.js.map +1 -0
  107. package/dist/loop/reporter.d.ts +9 -0
  108. package/dist/loop/reporter.d.ts.map +1 -0
  109. package/dist/loop/reporter.js +119 -0
  110. package/dist/loop/reporter.js.map +1 -0
  111. package/dist/loop/runner.d.ts +57 -0
  112. package/dist/loop/runner.d.ts.map +1 -0
  113. package/dist/loop/runner.js +390 -0
  114. package/dist/loop/runner.js.map +1 -0
  115. package/dist/loop/types.d.ts +151 -0
  116. package/dist/loop/types.d.ts.map +1 -0
  117. package/dist/loop/types.js +22 -0
  118. package/dist/loop/types.js.map +1 -0
  119. package/dist/mcp/index.d.ts +7 -0
  120. package/dist/mcp/index.d.ts.map +1 -0
  121. package/dist/mcp/index.js +7 -0
  122. package/dist/mcp/index.js.map +1 -0
  123. package/dist/mcp/server.d.ts +12 -0
  124. package/dist/mcp/server.d.ts.map +1 -0
  125. package/dist/mcp/server.js +618 -0
  126. package/dist/mcp/server.js.map +1 -0
  127. package/dist/pipeline/agent-runner.d.ts +34 -0
  128. package/dist/pipeline/agent-runner.d.ts.map +1 -0
  129. package/dist/pipeline/agent-runner.js +323 -0
  130. package/dist/pipeline/agent-runner.js.map +1 -0
  131. package/dist/pipeline/agents/accessibility-auditor.d.ts +10 -0
  132. package/dist/pipeline/agents/accessibility-auditor.d.ts.map +1 -0
  133. package/dist/pipeline/agents/accessibility-auditor.js +69 -0
  134. package/dist/pipeline/agents/accessibility-auditor.js.map +1 -0
  135. package/dist/pipeline/agents/code-reviewer.d.ts +10 -0
  136. package/dist/pipeline/agents/code-reviewer.d.ts.map +1 -0
  137. package/dist/pipeline/agents/code-reviewer.js +75 -0
  138. package/dist/pipeline/agents/code-reviewer.js.map +1 -0
  139. package/dist/pipeline/agents/code-writer.d.ts +10 -0
  140. package/dist/pipeline/agents/code-writer.d.ts.map +1 -0
  141. package/dist/pipeline/agents/code-writer.js +103 -0
  142. package/dist/pipeline/agents/code-writer.js.map +1 -0
  143. package/dist/pipeline/agents/component-architect.d.ts +13 -0
  144. package/dist/pipeline/agents/component-architect.d.ts.map +1 -0
  145. package/dist/pipeline/agents/component-architect.js +81 -0
  146. package/dist/pipeline/agents/component-architect.js.map +1 -0
  147. package/dist/pipeline/agents/index.d.ts +16 -0
  148. package/dist/pipeline/agents/index.d.ts.map +1 -0
  149. package/dist/pipeline/agents/index.js +24 -0
  150. package/dist/pipeline/agents/index.js.map +1 -0
  151. package/dist/pipeline/agents/library-researcher.d.ts +12 -0
  152. package/dist/pipeline/agents/library-researcher.d.ts.map +1 -0
  153. package/dist/pipeline/agents/library-researcher.js +85 -0
  154. package/dist/pipeline/agents/library-researcher.js.map +1 -0
  155. package/dist/pipeline/agents/quality-gate.d.ts +9 -0
  156. package/dist/pipeline/agents/quality-gate.d.ts.map +1 -0
  157. package/dist/pipeline/agents/quality-gate.js +71 -0
  158. package/dist/pipeline/agents/quality-gate.js.map +1 -0
  159. package/dist/pipeline/agents/spec-analyst.d.ts +10 -0
  160. package/dist/pipeline/agents/spec-analyst.d.ts.map +1 -0
  161. package/dist/pipeline/agents/spec-analyst.js +72 -0
  162. package/dist/pipeline/agents/spec-analyst.js.map +1 -0
  163. package/dist/pipeline/agents/story-author.d.ts +9 -0
  164. package/dist/pipeline/agents/story-author.d.ts.map +1 -0
  165. package/dist/pipeline/agents/story-author.js +65 -0
  166. package/dist/pipeline/agents/story-author.js.map +1 -0
  167. package/dist/pipeline/artifact-store.d.ts +27 -0
  168. package/dist/pipeline/artifact-store.d.ts.map +1 -0
  169. package/dist/pipeline/artifact-store.js +77 -0
  170. package/dist/pipeline/artifact-store.js.map +1 -0
  171. package/dist/pipeline/conversational-gate.d.ts +26 -0
  172. package/dist/pipeline/conversational-gate.d.ts.map +1 -0
  173. package/dist/pipeline/conversational-gate.js +122 -0
  174. package/dist/pipeline/conversational-gate.js.map +1 -0
  175. package/dist/pipeline/index.d.ts +14 -0
  176. package/dist/pipeline/index.d.ts.map +1 -0
  177. package/dist/pipeline/index.js +17 -0
  178. package/dist/pipeline/index.js.map +1 -0
  179. package/dist/pipeline/iteration-tracker.d.ts +29 -0
  180. package/dist/pipeline/iteration-tracker.d.ts.map +1 -0
  181. package/dist/pipeline/iteration-tracker.js +102 -0
  182. package/dist/pipeline/iteration-tracker.js.map +1 -0
  183. package/dist/pipeline/learning-bridge.d.ts +37 -0
  184. package/dist/pipeline/learning-bridge.d.ts.map +1 -0
  185. package/dist/pipeline/learning-bridge.js +118 -0
  186. package/dist/pipeline/learning-bridge.js.map +1 -0
  187. package/dist/pipeline/orchestrator.d.ts +45 -0
  188. package/dist/pipeline/orchestrator.d.ts.map +1 -0
  189. package/dist/pipeline/orchestrator.js +473 -0
  190. package/dist/pipeline/orchestrator.js.map +1 -0
  191. package/dist/pipeline/templates/architecture.d.ts +27 -0
  192. package/dist/pipeline/templates/architecture.d.ts.map +1 -0
  193. package/dist/pipeline/templates/architecture.js +111 -0
  194. package/dist/pipeline/templates/architecture.js.map +1 -0
  195. package/dist/pipeline/templates/brief.d.ts +22 -0
  196. package/dist/pipeline/templates/brief.d.ts.map +1 -0
  197. package/dist/pipeline/templates/brief.js +121 -0
  198. package/dist/pipeline/templates/brief.js.map +1 -0
  199. package/dist/pipeline/templates/component-rules.d.ts +25 -0
  200. package/dist/pipeline/templates/component-rules.d.ts.map +1 -0
  201. package/dist/pipeline/templates/component-rules.js +93 -0
  202. package/dist/pipeline/templates/component-rules.js.map +1 -0
  203. package/dist/pipeline/templates/index.d.ts +9 -0
  204. package/dist/pipeline/templates/index.d.ts.map +1 -0
  205. package/dist/pipeline/templates/index.js +7 -0
  206. package/dist/pipeline/templates/index.js.map +1 -0
  207. package/dist/pipeline/tool-handler.d.ts +25 -0
  208. package/dist/pipeline/tool-handler.d.ts.map +1 -0
  209. package/dist/pipeline/tool-handler.js +392 -0
  210. package/dist/pipeline/tool-handler.js.map +1 -0
  211. package/dist/pipeline/types.d.ts +146 -0
  212. package/dist/pipeline/types.d.ts.map +1 -0
  213. package/dist/pipeline/types.js +27 -0
  214. package/dist/pipeline/types.js.map +1 -0
  215. package/dist/plan/action-types.d.ts +31 -0
  216. package/dist/plan/action-types.d.ts.map +1 -0
  217. package/dist/plan/action-types.js +83 -0
  218. package/dist/plan/action-types.js.map +1 -0
  219. package/dist/plan/decision-engine.d.ts +57 -0
  220. package/dist/plan/decision-engine.d.ts.map +1 -0
  221. package/dist/plan/decision-engine.js +162 -0
  222. package/dist/plan/decision-engine.js.map +1 -0
  223. package/dist/plan/index.d.ts +6 -0
  224. package/dist/plan/index.d.ts.map +1 -0
  225. package/dist/plan/index.js +6 -0
  226. package/dist/plan/index.js.map +1 -0
  227. package/dist/types.d.ts +351 -0
  228. package/dist/types.d.ts.map +1 -0
  229. package/dist/types.js +26 -0
  230. package/dist/types.js.map +1 -0
  231. package/dist/utils/anthropic.d.ts +15 -0
  232. package/dist/utils/anthropic.d.ts.map +1 -0
  233. package/dist/utils/anthropic.js +40 -0
  234. package/dist/utils/anthropic.js.map +1 -0
  235. package/dist/utils/id.d.ts +8 -0
  236. package/dist/utils/id.d.ts.map +1 -0
  237. package/dist/utils/id.js +14 -0
  238. package/dist/utils/id.js.map +1 -0
  239. package/package.json +80 -0
package/README.md ADDED
@@ -0,0 +1,109 @@
1
+ # Eddie Brain
2
+
3
+ The agentic intelligence layer for the Eddie Design System. Exposes an MCP server so AI coding tools (Claude Code, Cursor, etc.) can query component metadata, validate token usage, check design system health, and compose canonical UI patterns.
4
+
5
+ ## What It Does
6
+
7
+ - **`eddie_get_component`** — Full component docs: props, slots, events, guidelines
8
+ - **`eddie_search`** — Search across components, tokens, and recipes
9
+ - **`eddie_get_token`** — Token value, tier, intent, and which components use it
10
+ - **`eddie_compose_recipe`** — Canonical composition patterns for a given UI intent (e.g. "login form", "destructive confirmation dialog")
11
+ - **`eddie_check_health`** — Health scores across tokens, naming, docs, coverage, accessibility, and consistency
12
+ - **`eddie_validate_file`** — Validate a file against Eddie conventions
13
+ - **`eddie_suggest_fix`** — Suggest fixes for detected violations
14
+ - **`eddie_get_relationships`** — Component composition relationships
15
+
16
+ ## Setup
17
+
18
+ ### Prerequisites
19
+
20
+ - Node.js (same version as the monorepo)
21
+ - The `eddie-design-system` repo cloned locally
22
+
23
+ ### 1. Install dependencies
24
+
25
+ From the repo root:
26
+
27
+ ```bash
28
+ npm install
29
+ ```
30
+
31
+ ### 2. Build the package
32
+
33
+ ```bash
34
+ cd packages/eddie-brain
35
+ npm run build
36
+ ```
37
+
38
+ This runs `tsc` and copies the static knowledge base files (`components.json`, `tokens.json`, etc.) into `dist/`.
39
+
40
+ Verify the output:
41
+
42
+ ```bash
43
+ ls dist/mcp/server.js
44
+ ```
45
+
46
+ ### 3. MCP registration is automatic
47
+
48
+ The repo's `.mcp.json` at the root handles registration for Claude Code:
49
+
50
+ ```json
51
+ {
52
+ "mcpServers": {
53
+ "eddie-brain": {
54
+ "command": "node",
55
+ "args": ["packages/eddie-brain/dist/mcp/server.js"],
56
+ "env": {
57
+ "EDDIE_ROOT": "."
58
+ }
59
+ }
60
+ }
61
+ }
62
+ ```
63
+
64
+ Claude Code reads `.mcp.json` on startup when your working directory is inside `eddie-design-system`. The `EDDIE_ROOT: "."` env var tells the server where to find the design system files. No additional configuration needed.
65
+
66
+ ### Rebuilding After Changes
67
+
68
+ Whenever `src/` or `data/` files change, rebuild and restart your editor session:
69
+
70
+ ```bash
71
+ cd packages/eddie-brain
72
+ npm run build
73
+ ```
74
+
75
+ ## CLI
76
+
77
+ The package also ships a standalone CLI:
78
+
79
+ ```bash
80
+ # Health report for the whole system
81
+ node packages/eddie-brain/dist/cli/brain.js health
82
+
83
+ # Full scan (monitor + analyze)
84
+ node packages/eddie-brain/dist/cli/brain.js scan
85
+ node packages/eddie-brain/dist/cli/brain.js scan --component ed-button
86
+
87
+ # Validate tokens and naming in source files
88
+ node packages/eddie-brain/dist/cli/brain.js validate src/
89
+ node packages/eddie-brain/dist/cli/brain.js validate --fix
90
+
91
+ # Compose a pattern from components
92
+ node packages/eddie-brain/dist/cli/brain.js compose "destructive confirmation dialog"
93
+
94
+ # View audit log
95
+ node packages/eddie-brain/dist/cli/brain.js audit
96
+ node packages/eddie-brain/dist/cli/brain.js audit --since 2026-03-01
97
+ ```
98
+
99
+ ## Development
100
+
101
+ ```bash
102
+ npm run dev # TypeScript watch mode
103
+ npm test # Run tests
104
+ npm run health # Quick health check
105
+ ```
106
+
107
+ ## Architecture
108
+
109
+ See [SPEC.md](./SPEC.md) for the full technical specification, including the knowledge graph schema, trust level model, health scoring categories, and implementation phases.
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Drift Detector
3
+ *
4
+ * Detects deviations from the knowledge graph:
5
+ * - Token drift: new/changed/removed tokens
6
+ * - Recipe drift: composition recipe inconsistencies
7
+ * - Naming drift: naming convention violations
8
+ */
9
+ import { Signal, CompositionRecipe } from '../types.js';
10
+ import type { TokenTaxonomy } from '../knowledge-graph/token-taxonomy.js';
11
+ import type { ComponentIndex } from '../knowledge-graph/component-index.js';
12
+ export declare class DriftDetector {
13
+ /**
14
+ * Detect new, changed, or removed tokens in the codebase
15
+ */
16
+ detectTokenDrift(rootDir: string, taxonomy: TokenTaxonomy): Promise<Signal[]>;
17
+ /**
18
+ * Detect deviations from canonical composition recipes
19
+ */
20
+ detectRecipeDrift(rootDir: string, recipes: CompositionRecipe[]): Promise<Signal[]>;
21
+ /**
22
+ * Detect naming convention violations
23
+ */
24
+ detectNamingDrift(rootDir: string, componentIndex: ComponentIndex): Promise<Signal[]>;
25
+ /**
26
+ * Detect if a component deviates from an expected recipe
27
+ */
28
+ private detectRecipeInComponent;
29
+ }
30
+ //# sourceMappingURL=drift-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drift-detector.d.ts","sourceRoot":"","sources":["../../src/analyze/drift-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,EAAE,MAAM,EAAgC,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACtF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAC1E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAwC5E,qBAAa,aAAa;IACxB;;OAEG;IACG,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAqHnF;;OAEG;IACG,iBAAiB,CACrB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,iBAAiB,EAAE,GAC3B,OAAO,CAAC,MAAM,EAAE,CAAC;IA+BpB;;OAEG;IACG,iBAAiB,CACrB,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,cAAc,GAC7B,OAAO,CAAC,MAAM,EAAE,CAAC;IAmIpB;;OAEG;IACH,OAAO,CAAC,uBAAuB;CAoDhC"}
@@ -0,0 +1,310 @@
1
+ /**
2
+ * Drift Detector
3
+ *
4
+ * Detects deviations from the knowledge graph:
5
+ * - Token drift: new/changed/removed tokens
6
+ * - Recipe drift: composition recipe inconsistencies
7
+ * - Naming drift: naming convention violations
8
+ */
9
+ import { readFile } from 'fs/promises';
10
+ import glob from 'fast-glob';
11
+ export class DriftDetector {
12
+ /**
13
+ * Detect new, changed, or removed tokens in the codebase
14
+ */
15
+ async detectTokenDrift(rootDir, taxonomy) {
16
+ const signals = [];
17
+ // Find all SCSS files
18
+ const scssFiles = await glob('**/*.scss', {
19
+ cwd: rootDir,
20
+ absolute: true,
21
+ ignore: ['**/node_modules/**'],
22
+ });
23
+ const usedTokens = new Set();
24
+ const tokenUsageMap = new Map();
25
+ // Scan files for token usage
26
+ for (const file of scssFiles) {
27
+ try {
28
+ const content = await readFile(file, 'utf-8');
29
+ const tokenMatches = content.match(/var\((--ed-[^)]+)\)/g) || [];
30
+ for (const match of tokenMatches) {
31
+ const tokenName = match.replace(/var\(|\)/g, '');
32
+ usedTokens.add(tokenName);
33
+ if (!tokenUsageMap.has(tokenName)) {
34
+ tokenUsageMap.set(tokenName, []);
35
+ }
36
+ tokenUsageMap.get(tokenName).push(file);
37
+ }
38
+ }
39
+ catch (error) {
40
+ // Skip files that can't be read
41
+ }
42
+ }
43
+ // Get tokens from taxonomy
44
+ const allTokensArray = taxonomy.getAll?.() || [];
45
+ const knownTokens = new Set(allTokensArray.map((t) => t.name) || []);
46
+ // Detect orphaned tokens (used but not in taxonomy)
47
+ for (const token of usedTokens) {
48
+ if (!knownTokens.has(token)) {
49
+ signals.push({
50
+ id: `drift-token-orphaned-${token}`,
51
+ timestamp: new Date().toISOString(),
52
+ source: 'usage',
53
+ severity: 'warning',
54
+ type: 'token-inconsistent',
55
+ message: `Token "${token}" is used in code but not found in token taxonomy`,
56
+ target: token,
57
+ payload: {
58
+ tokenName: token,
59
+ missingThemes: taxonomy.getThemes?.() || [],
60
+ },
61
+ });
62
+ }
63
+ }
64
+ // Detect unused tokens (in taxonomy but not used)
65
+ const allThemes = taxonomy.getThemes?.() || [];
66
+ for (const theme of allThemes) {
67
+ const themeTokens = taxonomy.getByTheme?.(theme) || [];
68
+ for (const token of themeTokens) {
69
+ // Skip internal/private tokens
70
+ if (!token.name || token.name.includes('private')) {
71
+ continue;
72
+ }
73
+ if (!usedTokens.has(token.name)) {
74
+ signals.push({
75
+ id: `drift-token-unused-${token.name}-${theme}`,
76
+ timestamp: new Date().toISOString(),
77
+ source: 'usage',
78
+ severity: 'info',
79
+ type: 'token-removed',
80
+ message: `Token "${token.name}" is defined in theme "${theme}" but not used anywhere`,
81
+ target: token.name,
82
+ payload: {
83
+ tokenName: token.name,
84
+ theme,
85
+ },
86
+ });
87
+ }
88
+ }
89
+ }
90
+ // Check for theme coverage gaps
91
+ for (const token of usedTokens) {
92
+ const missingThemes = [];
93
+ for (const theme of allThemes) {
94
+ const themeTokens = taxonomy.getByTheme?.(theme) || [];
95
+ const hasToken = themeTokens.some((t) => t.name === token);
96
+ if (!hasToken) {
97
+ missingThemes.push(theme);
98
+ }
99
+ }
100
+ if (missingThemes.length > 0) {
101
+ signals.push({
102
+ id: `drift-token-coverage-${token}`,
103
+ timestamp: new Date().toISOString(),
104
+ source: 'usage',
105
+ severity: 'error',
106
+ type: 'token-inconsistent',
107
+ message: `Token "${token}" missing from themes: ${missingThemes.join(', ')}`,
108
+ target: token,
109
+ payload: {
110
+ tokenName: token,
111
+ missingThemes,
112
+ },
113
+ });
114
+ }
115
+ }
116
+ return signals;
117
+ }
118
+ /**
119
+ * Detect deviations from canonical composition recipes
120
+ */
121
+ async detectRecipeDrift(rootDir, recipes) {
122
+ const signals = [];
123
+ // Find all component files that might use these recipes
124
+ const componentFiles = await glob('**/components/**/*.ts', {
125
+ cwd: rootDir,
126
+ absolute: true,
127
+ ignore: ['**/node_modules/**', '**/*.test.ts'],
128
+ });
129
+ for (const file of componentFiles) {
130
+ try {
131
+ const content = await readFile(file, 'utf-8');
132
+ for (const recipe of recipes) {
133
+ // Check if this component file uses this recipe
134
+ const recipeSignals = this.detectRecipeInComponent(file, content, recipe);
135
+ signals.push(...recipeSignals);
136
+ }
137
+ }
138
+ catch (error) {
139
+ // Skip files that can't be read
140
+ }
141
+ }
142
+ return signals;
143
+ }
144
+ /**
145
+ * Detect naming convention violations
146
+ */
147
+ async detectNamingDrift(rootDir, componentIndex) {
148
+ const signals = [];
149
+ // Find all SCSS files with class definitions
150
+ const scssFiles = await glob('**/components/**/*.scss', {
151
+ cwd: rootDir,
152
+ absolute: true,
153
+ ignore: ['**/node_modules/**'],
154
+ });
155
+ const validPrefixes = [
156
+ /^ed-c-/, // Component
157
+ /^ed-l-/, // Layout
158
+ /^ed-u-/, // Utility
159
+ /^ed-r-/, // Recipe component
160
+ /^is-/, // State
161
+ /^has-/, // State
162
+ ];
163
+ for (const file of scssFiles) {
164
+ try {
165
+ const content = await readFile(file, 'utf-8');
166
+ const lines = content.split('\n');
167
+ lines.forEach((line, lineIndex) => {
168
+ // Skip comments
169
+ if (line.trim().startsWith('//'))
170
+ return;
171
+ // Find class definitions (.className {)
172
+ const classMatches = line.matchAll(/\.([a-zA-Z0-9_-]+)\s*[{&]/g);
173
+ for (const match of classMatches) {
174
+ const className = match[1];
175
+ // Check for valid prefix
176
+ const hasValidPrefix = validPrefixes.some((p) => p.test(className));
177
+ if (!hasValidPrefix && !className.startsWith('_') && className.length > 3) {
178
+ signals.push({
179
+ id: `drift-naming-prefix-${className}-${lineIndex}`,
180
+ timestamp: new Date().toISOString(),
181
+ source: 'git',
182
+ severity: 'warning',
183
+ type: 'prefix-mismatch',
184
+ message: `Class ".${className}" in ${file} uses invalid prefix. Expected: ed-c-, ed-l-, ed-u-, ed-r-, is-, or has-`,
185
+ target: className,
186
+ payload: {
187
+ className,
188
+ expectedPrefix: 'ed-c- or ed-l- or ed-u- or ed-r- or is- or has-',
189
+ actualPrefix: className.match(/^[a-z]+-/)?.[0] || 'none',
190
+ },
191
+ });
192
+ }
193
+ // Check for uppercase in class names
194
+ if (/[A-Z]/.test(className)) {
195
+ signals.push({
196
+ id: `drift-naming-case-${className}-${lineIndex}`,
197
+ timestamp: new Date().toISOString(),
198
+ source: 'git',
199
+ severity: 'warning',
200
+ type: 'naming-violation',
201
+ message: `Class ".${className}" contains uppercase letters. BEM classes must be lowercase`,
202
+ target: className,
203
+ payload: {
204
+ className,
205
+ expectedPattern: className.toLowerCase(),
206
+ },
207
+ });
208
+ }
209
+ }
210
+ });
211
+ }
212
+ catch (error) {
213
+ // Skip files that can't be read
214
+ }
215
+ }
216
+ // Check for unclassed HTML elements in component templates
217
+ const componentFiles = await glob('**/components/**/*.ts', {
218
+ cwd: rootDir,
219
+ absolute: true,
220
+ ignore: ['**/node_modules/**', '**/*.test.ts'],
221
+ });
222
+ const allowedUnclassed = [
223
+ 'svg', 'path', 'g', 'circle', 'rect', 'ellipse', 'line',
224
+ 'style', 'script', 'template', 'slot', 'use', 'defs',
225
+ ];
226
+ for (const file of componentFiles) {
227
+ try {
228
+ const content = await readFile(file, 'utf-8');
229
+ // Skip TextPassage components
230
+ if (file.includes('TextPassage'))
231
+ continue;
232
+ const lines = content.split('\n');
233
+ lines.forEach((line, lineIndex) => {
234
+ // Look for HTML elements without class attributes
235
+ const elementMatches = line.matchAll(/<([a-z][a-z0-9]*)\s+(?!.*class=)[^>]*>/gi);
236
+ for (const match of elementMatches) {
237
+ const tag = match[1].toLowerCase();
238
+ if (!allowedUnclassed.includes(tag) && !tag.includes('-')) {
239
+ signals.push({
240
+ id: `drift-unclassed-element-${tag}-${lineIndex}`,
241
+ timestamp: new Date().toISOString(),
242
+ source: 'git',
243
+ severity: 'warning',
244
+ type: 'naming-violation',
245
+ message: `Unclassed <${tag}> element found in ${file}. Every element should have a BEM class`,
246
+ target: tag,
247
+ payload: {
248
+ className: `<${tag}>`,
249
+ expectedPattern: `<${tag} class="ed-c-...">`,
250
+ },
251
+ });
252
+ }
253
+ }
254
+ });
255
+ }
256
+ catch (error) {
257
+ // Skip files that can't be read
258
+ }
259
+ }
260
+ return signals;
261
+ }
262
+ /**
263
+ * Detect if a component deviates from an expected recipe
264
+ */
265
+ detectRecipeInComponent(file, content, recipe) {
266
+ const signals = [];
267
+ // Check if component file mentions recipe components
268
+ for (const recipeComp of recipe.components) {
269
+ const isComponentMentioned = content.includes(recipeComp.tagName);
270
+ if (recipeComp.required && !isComponentMentioned) {
271
+ signals.push({
272
+ id: `drift-recipe-missing-${recipe.name}-${recipeComp.tagName}`,
273
+ timestamp: new Date().toISOString(),
274
+ source: 'usage',
275
+ severity: 'warning',
276
+ type: 'recipe-incomplete',
277
+ message: `Recipe "${recipe.name}" requires component "${recipeComp.tagName}", but it's not found in ${file}`,
278
+ target: recipeComp.tagName,
279
+ payload: {
280
+ recipeName: recipe.name,
281
+ missingComponent: recipeComp.tagName,
282
+ expectedRole: recipeComp.role,
283
+ },
284
+ });
285
+ }
286
+ }
287
+ // Check for required tokens in this component if it uses the recipe
288
+ if (recipe.components.some((c) => content.includes(c.tagName))) {
289
+ for (const [tokenKey, tokenValue] of Object.entries(recipe.tokens)) {
290
+ if (!content.includes(tokenValue)) {
291
+ signals.push({
292
+ id: `drift-recipe-missing-token-${recipe.name}-${tokenKey}`,
293
+ timestamp: new Date().toISOString(),
294
+ source: 'usage',
295
+ severity: 'info',
296
+ type: 'recipe-missing-token',
297
+ message: `Recipe "${recipe.name}" expects token "${tokenValue}" to be used, but not found in ${file}`,
298
+ target: tokenValue,
299
+ payload: {
300
+ recipeName: recipe.name,
301
+ tokenName: tokenValue,
302
+ },
303
+ });
304
+ }
305
+ }
306
+ }
307
+ return signals;
308
+ }
309
+ }
310
+ //# sourceMappingURL=drift-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drift-detector.js","sourceRoot":"","sources":["../../src/analyze/drift-detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Health Scorer
3
+ *
4
+ * Scores system health across 6 categories:
5
+ * - Tokens: proper usage of design tokens
6
+ * - Naming: BEM/BEMIT compliance
7
+ * - Coverage: completeness of component metadata
8
+ * - Documentation: presence and quality of documentation
9
+ * - Accessibility: ARIA and keyboard handling
10
+ * - Consistency: API and pattern consistency
11
+ */
12
+ import { HealthScore, HealthReport, BrainConfig } from '../types.js';
13
+ interface KnowledgeGraph {
14
+ getComponentEntries?: () => any[];
15
+ getTokenTaxonomy?: () => any;
16
+ getTokens?: () => any[];
17
+ getAllThemes?: () => string[];
18
+ }
19
+ export declare class HealthScorer {
20
+ private knowledgeGraph;
21
+ private config;
22
+ private tokenValidator;
23
+ private namingValidator;
24
+ constructor(knowledgeGraph: KnowledgeGraph, config: BrainConfig);
25
+ /**
26
+ * Score a single component across all health categories
27
+ */
28
+ scoreComponent(tagName: string): Promise<HealthScore[]>;
29
+ /**
30
+ * Generate full system health report
31
+ */
32
+ scoreAll(): Promise<HealthReport>;
33
+ /**
34
+ * Score token usage health
35
+ */
36
+ private scoreTokenHealth;
37
+ /**
38
+ * Score naming convention compliance
39
+ */
40
+ private scoreNamingHealth;
41
+ /**
42
+ * Score documentation completeness
43
+ */
44
+ private scoreDocumentationHealth;
45
+ /**
46
+ * Score metadata coverage
47
+ */
48
+ private scoreCoverageHealth;
49
+ /**
50
+ * Score accessibility features
51
+ */
52
+ private scoreAccessibilityHealth;
53
+ /**
54
+ * Score API consistency with similar components
55
+ */
56
+ private scoreConsistencyHealth;
57
+ /**
58
+ * Aggregate scores by category
59
+ */
60
+ private aggregateScores;
61
+ /**
62
+ * Calculate weighted overall score
63
+ */
64
+ private calculateWeightedScore;
65
+ /**
66
+ * Count issues by severity
67
+ */
68
+ private countIssuesBySeverity;
69
+ }
70
+ export {};
71
+ //# sourceMappingURL=health-scorer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-scorer.d.ts","sourceRoot":"","sources":["../../src/analyze/health-scorer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EACL,WAAW,EACX,YAAY,EAGZ,WAAW,EACZ,MAAM,aAAa,CAAC;AAIrB,UAAU,cAAc;IACtB,mBAAmB,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC;IAClC,gBAAgB,CAAC,EAAE,MAAM,GAAG,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,MAAM,EAAE,CAAC;CAC/B;AAOD,qBAAa,YAAY;IAKrB,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,MAAM;IALhB,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,eAAe,CAAkB;gBAG/B,cAAc,EAAE,cAAc,EAC9B,MAAM,EAAE,WAAW;IAM7B;;OAEG;IACG,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAgD7D;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,YAAY,CAAC;IA4BvC;;OAEG;YACW,gBAAgB;IA2B9B;;OAEG;YACW,iBAAiB;IA8B/B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAwEhC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAqD3B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAwDhC;;OAEG;YACW,sBAAsB;IA8DpC;;OAEG;IACH,OAAO,CAAC,eAAe;IAyBvB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAgB9B;;OAEG;IACH,OAAO,CAAC,qBAAqB;CAkB9B"}