@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
@@ -0,0 +1,187 @@
1
+ /**
2
+ * LearningHistory — Track feedback and learn from interactions
3
+ *
4
+ * Records suggestions that were accepted, rejected, or modified,
5
+ * and computes statistics about the agent's accuracy and user preferences.
6
+ */
7
+ import { readFileSync, writeFileSync } from 'fs';
8
+ export class LearningHistory {
9
+ entries = [];
10
+ /**
11
+ * Record a learning entry
12
+ */
13
+ record(entry) {
14
+ this.entries.push(entry);
15
+ }
16
+ /**
17
+ * Get all entries
18
+ */
19
+ getAll() {
20
+ return [...this.entries];
21
+ }
22
+ /**
23
+ * Get entries for a specific target (component, token, file, etc.)
24
+ */
25
+ getForTarget(target) {
26
+ return this.entries.filter((e) => e.suggestion.target === target);
27
+ }
28
+ /**
29
+ * Get entries by type
30
+ */
31
+ getByType(type) {
32
+ return this.entries.filter((e) => e.suggestion.type === type);
33
+ }
34
+ /**
35
+ * Get entries by decision
36
+ */
37
+ getByDecision(decision) {
38
+ return this.entries.filter((e) => e.decision === decision);
39
+ }
40
+ /**
41
+ * Get entries by tag
42
+ */
43
+ getByTag(tag) {
44
+ return this.entries.filter((e) => e.tags.includes(tag));
45
+ }
46
+ /**
47
+ * Get entries within a time range
48
+ */
49
+ getByDateRange(startTime, endTime) {
50
+ const start = new Date(startTime).getTime();
51
+ const end = new Date(endTime).getTime();
52
+ return this.entries.filter((e) => {
53
+ const eTime = new Date(e.timestamp).getTime();
54
+ return eTime >= start && eTime <= end;
55
+ });
56
+ }
57
+ /**
58
+ * Compute statistics about learning
59
+ */
60
+ getStats() {
61
+ const total = this.entries.length;
62
+ if (total === 0) {
63
+ return {
64
+ totalSuggestions: 0,
65
+ acceptanceRate: 0,
66
+ rejectionRate: 0,
67
+ modificationRate: 0,
68
+ acceptedCount: 0,
69
+ rejectedCount: 0,
70
+ modifiedCount: 0,
71
+ accuracyTrend: [],
72
+ mostRejectedType: '',
73
+ mostAcceptedType: '',
74
+ };
75
+ }
76
+ const accepted = this.entries.filter((e) => e.decision === 'accepted').length;
77
+ const rejected = this.entries.filter((e) => e.decision === 'rejected').length;
78
+ const modified = this.entries.filter((e) => e.decision === 'modified').length;
79
+ const acceptanceRate = accepted / total;
80
+ const rejectionRate = rejected / total;
81
+ const modificationRate = modified / total;
82
+ // Compute trend by week
83
+ const byWeek = new Map();
84
+ for (const entry of this.entries) {
85
+ const date = new Date(entry.timestamp);
86
+ const weekStart = new Date(date);
87
+ weekStart.setDate(date.getDate() - date.getDay());
88
+ const weekKey = weekStart.toISOString().split('T')[0];
89
+ if (!byWeek.has(weekKey)) {
90
+ byWeek.set(weekKey, { accepted: 0, total: 0 });
91
+ }
92
+ const week = byWeek.get(weekKey);
93
+ week.total++;
94
+ if (entry.decision === 'accepted') {
95
+ week.accepted++;
96
+ }
97
+ }
98
+ const accuracyTrend = Array.from(byWeek.entries())
99
+ .sort(([a], [b]) => a.localeCompare(b))
100
+ .map(([week, stats]) => ({
101
+ week,
102
+ accuracy: stats.accepted / stats.total,
103
+ }));
104
+ // Find most rejected and accepted types
105
+ const typeStats = new Map();
106
+ for (const entry of this.entries) {
107
+ if (!typeStats.has(entry.suggestion.type)) {
108
+ typeStats.set(entry.suggestion.type, { accepted: 0, rejected: 0 });
109
+ }
110
+ const stats = typeStats.get(entry.suggestion.type);
111
+ if (entry.decision === 'accepted') {
112
+ stats.accepted++;
113
+ }
114
+ else if (entry.decision === 'rejected') {
115
+ stats.rejected++;
116
+ }
117
+ }
118
+ let mostRejectedType = '';
119
+ let maxRejections = 0;
120
+ for (const [type, stats] of typeStats) {
121
+ if (stats.rejected > maxRejections) {
122
+ maxRejections = stats.rejected;
123
+ mostRejectedType = type;
124
+ }
125
+ }
126
+ let mostAcceptedType = '';
127
+ let maxAcceptances = 0;
128
+ for (const [type, stats] of typeStats) {
129
+ if (stats.accepted > maxAcceptances) {
130
+ maxAcceptances = stats.accepted;
131
+ mostAcceptedType = type;
132
+ }
133
+ }
134
+ return {
135
+ totalSuggestions: total,
136
+ acceptanceRate,
137
+ rejectionRate,
138
+ modificationRate,
139
+ acceptedCount: accepted,
140
+ rejectedCount: rejected,
141
+ modifiedCount: modified,
142
+ accuracyTrend,
143
+ mostRejectedType,
144
+ mostAcceptedType,
145
+ };
146
+ }
147
+ /**
148
+ * Clear all entries
149
+ */
150
+ clear() {
151
+ this.entries = [];
152
+ }
153
+ /**
154
+ * Save to a JSON file
155
+ */
156
+ save(filePath) {
157
+ writeFileSync(filePath, JSON.stringify(this.toJSON(), null, 2), 'utf-8');
158
+ }
159
+ /**
160
+ * Load from a JSON file
161
+ */
162
+ static load(filePath) {
163
+ try {
164
+ const content = readFileSync(filePath, 'utf-8');
165
+ const data = JSON.parse(content);
166
+ return LearningHistory.fromJSON(data);
167
+ }
168
+ catch {
169
+ return new LearningHistory();
170
+ }
171
+ }
172
+ /**
173
+ * Serialize to JSON
174
+ */
175
+ toJSON() {
176
+ return [...this.entries];
177
+ }
178
+ /**
179
+ * Deserialize from JSON
180
+ */
181
+ static fromJSON(arr) {
182
+ const history = new LearningHistory();
183
+ history.entries = [...arr];
184
+ return history;
185
+ }
186
+ }
187
+ //# sourceMappingURL=learning-history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"learning-history.js","sourceRoot":"","sources":["../../src/knowledge-graph/learning-history.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * RelationshipMap — Track component composition recipes
3
+ *
4
+ * Stores canonical composition recipes and analyzes component relationships
5
+ * to understand how components work together.
6
+ */
7
+ import type { CompositionRecipe } from '../types.js';
8
+ import type { ComponentIndex } from './component-index.js';
9
+ export declare class RelationshipMap {
10
+ private recipes;
11
+ /**
12
+ * Add a composition recipe
13
+ */
14
+ addRecipe(recipe: CompositionRecipe): void;
15
+ /**
16
+ * Get a recipe by name
17
+ */
18
+ getRecipe(name: string): CompositionRecipe | undefined;
19
+ /**
20
+ * Find all recipes that involve a component
21
+ */
22
+ findRecipesFor(tagName: string): CompositionRecipe[];
23
+ /**
24
+ * Get all recipes
25
+ */
26
+ getAll(): CompositionRecipe[];
27
+ /**
28
+ * Get recipes by status
29
+ */
30
+ getByStatus(status: 'canonical' | 'candidate' | 'deprecated'): CompositionRecipe[];
31
+ /**
32
+ * Build relationships from component analysis
33
+ *
34
+ * Scans component properties and slots to infer composition recipes.
35
+ * This is a starting point for recipe discovery.
36
+ */
37
+ buildFromComponents(componentIndex: ComponentIndex): Promise<void>;
38
+ /**
39
+ * Infer composition recipes from component metadata
40
+ */
41
+ private inferRecipes;
42
+ /**
43
+ * Infer the role of a card child component
44
+ */
45
+ private inferCardChildRole;
46
+ /**
47
+ * Serialize to JSON
48
+ */
49
+ toJSON(): Record<string, CompositionRecipe>;
50
+ /**
51
+ * Deserialize from JSON
52
+ */
53
+ static fromJSON(obj: Record<string, CompositionRecipe>): RelationshipMap;
54
+ }
55
+ //# sourceMappingURL=relationship-map.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relationship-map.d.ts","sourceRoot":"","sources":["../../src/knowledge-graph/relationship-map.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAmC,MAAM,aAAa,CAAC;AACtF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,qBAAa,eAAe;IAC1B,OAAO,CAAC,OAAO,CAA6C;IAE5D;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI;IAI1C;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAItD;;OAEG;IACH,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,EAAE;IAMpD;;OAEG;IACH,MAAM,IAAI,iBAAiB,EAAE;IAI7B;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,GAAG,iBAAiB,EAAE;IAIlF;;;;;OAKG;IACG,mBAAmB,CAAC,cAAc,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAWxE;;OAEG;IACH,OAAO,CAAC,YAAY;IAoKpB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAM1B;;OAEG;IACH,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC;IAQ3C;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAAG,eAAe;CAOzE"}
@@ -0,0 +1,238 @@
1
+ /**
2
+ * RelationshipMap — Track component composition recipes
3
+ *
4
+ * Stores canonical composition recipes and analyzes component relationships
5
+ * to understand how components work together.
6
+ */
7
+ export class RelationshipMap {
8
+ recipes = new Map();
9
+ /**
10
+ * Add a composition recipe
11
+ */
12
+ addRecipe(recipe) {
13
+ this.recipes.set(recipe.name, recipe);
14
+ }
15
+ /**
16
+ * Get a recipe by name
17
+ */
18
+ getRecipe(name) {
19
+ return this.recipes.get(name);
20
+ }
21
+ /**
22
+ * Find all recipes that involve a component
23
+ */
24
+ findRecipesFor(tagName) {
25
+ return this.getAll().filter((recipe) => recipe.components.some((comp) => comp.tagName === tagName));
26
+ }
27
+ /**
28
+ * Get all recipes
29
+ */
30
+ getAll() {
31
+ return Array.from(this.recipes.values());
32
+ }
33
+ /**
34
+ * Get recipes by status
35
+ */
36
+ getByStatus(status) {
37
+ return this.getAll().filter((r) => r.status === status);
38
+ }
39
+ /**
40
+ * Build relationships from component analysis
41
+ *
42
+ * Scans component properties and slots to infer composition recipes.
43
+ * This is a starting point for recipe discovery.
44
+ */
45
+ async buildFromComponents(componentIndex) {
46
+ const components = componentIndex.getAll();
47
+ // Detect common recipes
48
+ const recipes = this.inferRecipes(components);
49
+ for (const recipe of recipes) {
50
+ this.addRecipe(recipe);
51
+ }
52
+ }
53
+ /**
54
+ * Infer composition recipes from component metadata
55
+ */
56
+ inferRecipes(components) {
57
+ const recipes = [];
58
+ // Recipe: Button with Icon
59
+ const button = components.find((c) => c.tagName === 'ed-button');
60
+ const icon = components.find((c) => c.tagName === 'ed-icon');
61
+ if (button && icon) {
62
+ recipes.push({
63
+ name: 'button-with-icon',
64
+ intent: 'A button that displays an icon alongside or above the text',
65
+ components: [
66
+ {
67
+ tagName: 'ed-button',
68
+ role: 'container',
69
+ required: true,
70
+ },
71
+ {
72
+ tagName: 'ed-icon',
73
+ role: 'icon',
74
+ required: false,
75
+ },
76
+ ],
77
+ tokens: {},
78
+ rules: [
79
+ 'Icon should have aria-hidden="true" to avoid announcing to screen readers',
80
+ 'Button must have text content for accessibility',
81
+ ],
82
+ confidence: 0.9,
83
+ status: 'canonical',
84
+ });
85
+ }
86
+ // Recipe: Card with Content
87
+ const card = components.find((c) => c.tagName === 'ed-card');
88
+ if (card && card.childComponents) {
89
+ recipes.push({
90
+ name: 'card-section-structure',
91
+ intent: 'A card layout with header, body, and footer sections',
92
+ components: [
93
+ {
94
+ tagName: 'ed-card',
95
+ role: 'container',
96
+ required: true,
97
+ },
98
+ ...card.childComponents.map((tagName) => ({
99
+ tagName,
100
+ role: this.inferCardChildRole(tagName),
101
+ required: false,
102
+ })),
103
+ ],
104
+ tokens: {},
105
+ rules: ['Sections should follow logical reading order'],
106
+ confidence: 0.85,
107
+ status: 'canonical',
108
+ });
109
+ }
110
+ // Recipe: Accordion with Items
111
+ const accordion = components.find((c) => c.tagName === 'ed-accordion');
112
+ if (accordion && accordion.childComponents) {
113
+ recipes.push({
114
+ name: 'accordion-structure',
115
+ intent: 'An accordion with collapsible items',
116
+ components: [
117
+ {
118
+ tagName: 'ed-accordion',
119
+ role: 'container',
120
+ required: true,
121
+ },
122
+ {
123
+ tagName: 'ed-accordion-panel',
124
+ role: 'item',
125
+ required: true,
126
+ },
127
+ ],
128
+ tokens: {},
129
+ rules: ['Each panel must have a unique ID', 'Only one panel can be open at a time'],
130
+ confidence: 0.9,
131
+ status: 'canonical',
132
+ });
133
+ }
134
+ // Recipe: Navigation structure
135
+ const nav = components.find((c) => c.tagName === 'ed-primary-nav');
136
+ if (nav) {
137
+ recipes.push({
138
+ name: 'navigation-structure',
139
+ intent: 'A hierarchical navigation menu',
140
+ components: [
141
+ {
142
+ tagName: 'ed-primary-nav',
143
+ role: 'navigation',
144
+ required: true,
145
+ },
146
+ ],
147
+ tokens: {},
148
+ rules: ['Must use semantic nav element', 'Links should be keyboard navigable'],
149
+ confidence: 0.85,
150
+ status: 'candidate',
151
+ });
152
+ }
153
+ // Recipe: Form with fields
154
+ const textField = components.find((c) => c.tagName === 'ed-text-input');
155
+ const checkboxField = components.find((c) => c.tagName === 'ed-checkbox-field');
156
+ if (textField || checkboxField) {
157
+ const formFieldComponents = [];
158
+ if (textField) {
159
+ formFieldComponents.push({
160
+ tagName: 'ed-text-input',
161
+ role: 'input',
162
+ required: false,
163
+ });
164
+ }
165
+ if (checkboxField) {
166
+ formFieldComponents.push({
167
+ tagName: 'ed-checkbox-field',
168
+ role: 'input',
169
+ required: false,
170
+ });
171
+ }
172
+ recipes.push({
173
+ name: 'form-fields',
174
+ intent: 'Form inputs with labels and validation',
175
+ components: formFieldComponents,
176
+ tokens: {},
177
+ rules: ['All inputs must have associated labels', 'Validation messages should be announced to screen readers'],
178
+ confidence: 0.8,
179
+ status: 'candidate',
180
+ });
181
+ }
182
+ // Recipe: Modal/Dialog
183
+ const modal = components.find((c) => c.tagName === 'ed-modal');
184
+ if (modal) {
185
+ recipes.push({
186
+ name: 'modal-dialog',
187
+ intent: 'A modal dialog with header, body, and footer',
188
+ components: [
189
+ {
190
+ tagName: 'ed-modal',
191
+ role: 'container',
192
+ required: true,
193
+ },
194
+ ],
195
+ tokens: {},
196
+ rules: [
197
+ 'Focus must be managed and returned when modal closes',
198
+ 'Must support Escape key to close',
199
+ 'Should use role="dialog"',
200
+ ],
201
+ confidence: 0.85,
202
+ status: 'candidate',
203
+ });
204
+ }
205
+ return recipes;
206
+ }
207
+ /**
208
+ * Infer the role of a card child component
209
+ */
210
+ inferCardChildRole(tagName) {
211
+ if (tagName.includes('header'))
212
+ return 'header';
213
+ if (tagName.includes('footer'))
214
+ return 'footer';
215
+ return 'content';
216
+ }
217
+ /**
218
+ * Serialize to JSON
219
+ */
220
+ toJSON() {
221
+ const obj = {};
222
+ for (const [name, recipe] of this.recipes) {
223
+ obj[name] = recipe;
224
+ }
225
+ return obj;
226
+ }
227
+ /**
228
+ * Deserialize from JSON
229
+ */
230
+ static fromJSON(obj) {
231
+ const map = new RelationshipMap();
232
+ for (const [name, recipe] of Object.entries(obj)) {
233
+ map.recipes.set(name, recipe);
234
+ }
235
+ return map;
236
+ }
237
+ }
238
+ //# sourceMappingURL=relationship-map.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relationship-map.js","sourceRoot":"","sources":["../../src/knowledge-graph/relationship-map.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * TokenTaxonomy — Organize and classify design tokens
3
+ *
4
+ * Parses token files and classifies tokens by tier (definition/usage/component),
5
+ * category (color/spacing/typography), and theme.
6
+ */
7
+ import type { TokenCategory, TokenEntry, TokenTier } from '../types.js';
8
+ export declare class TokenTaxonomy {
9
+ private tokens;
10
+ /**
11
+ * Build the token taxonomy by scanning token files.
12
+ *
13
+ * Two-pass build:
14
+ * 1. Walk the source JSON files in `tier-{1-definitions,2-usage,3-components}/`
15
+ * directories to build an authoritative `tokenName → tier` map. The file
16
+ * path is the source of truth for tier; relying on CSS-variable name
17
+ * heuristics mis-classifies tier-2 blocks like `animation` and `viz`
18
+ * because their first segment after `--ed-theme-` isn't a stock CSS
19
+ * category name (#680).
20
+ * 2. Parse the compiled tokens.css per theme for the actual values,
21
+ * looking up the tier in the map produced by pass 1.
22
+ *
23
+ * Tokens that exist in the compiled CSS but not in any source JSON
24
+ * (deprecated/leftover) fall through to the legacy name-heuristic
25
+ * classifier so we never emit an empty tier — but in practice every
26
+ * compiled token traces back to a JSON definition.
27
+ */
28
+ build(rootDir: string): Promise<void>;
29
+ /**
30
+ * Build the authoritative `tokenName → tier` map by walking source JSON.
31
+ *
32
+ * Looks under any theme directory (`bfw`, `bfw-dark`, `altitude`, etc.)
33
+ * for these conventional subdirectories:
34
+ * - `tier-1-definitions/*.json` → tier "definition"
35
+ * - `tier-2-usage/*.json` → tier "usage"
36
+ * - `tier-3-components/*.json` → tier "component"
37
+ *
38
+ * Each leaf node (object with a non-object `value`) becomes a CSS variable
39
+ * name derived from the path: `--ed-<dot.path.dashed>` for tier 1, and
40
+ * `--ed-theme-<dot.path.dashed>` for tiers 2 and 3. The tier-1 vs theme
41
+ * prefix split mirrors how Style Dictionary emits the compiled CSS.
42
+ *
43
+ * Earliest tier wins on collision (in practice tokens don't appear in
44
+ * multiple tiers; this just keeps the result deterministic).
45
+ */
46
+ private buildTierMap;
47
+ /**
48
+ * Walk a Style-Dictionary-style JSON tree and yield the CSS variable name
49
+ * for each leaf (object with a non-object `value` property). Non-leaf
50
+ * objects recurse; primitive/array values are ignored.
51
+ */
52
+ private collectCssVarNames;
53
+ /**
54
+ * Parse a tokens.css file and extract all tokens
55
+ */
56
+ private parseTokenFile;
57
+ /**
58
+ * Derive the color subcategory ("background" | "content" | "border") from
59
+ * a token name. The convention is that the segment immediately after
60
+ * `color-` in the name is the subcategory:
61
+ * --ed-theme-color-background-default → "background"
62
+ * --ed-theme-color-content-default → "content"
63
+ * --ed-theme-color-border-subtle → "border"
64
+ * Returns undefined for non-color tokens, definition-tier color tokens
65
+ * (no subcategory in name), and any color-token shape we don't recognize.
66
+ */
67
+ private deriveSubcategory;
68
+ /**
69
+ * Derive the CSS properties this token is valid to apply to.
70
+ * Only meaningful for color tokens with a known subcategory; other tokens
71
+ * return undefined (no `validProperties` field on output).
72
+ */
73
+ private deriveValidProperties;
74
+ /**
75
+ * Classify a token as tier 1 (definition), tier 2 (usage), or tier 3 (component)
76
+ *
77
+ * Tier 1: --ed-{category}-{name} (e.g., --ed-color-brand-blue)
78
+ * Tier 2: --ed-theme-{category}-{semantic} (e.g., --ed-theme-color-background-default)
79
+ * Tier 3: --ed-theme-{component}-{property} (e.g., --ed-theme-button-background)
80
+ */
81
+ private classifyTier;
82
+ /**
83
+ * Classify a token by category
84
+ */
85
+ private classifyCategory;
86
+ /**
87
+ * Extract intent from token name
88
+ */
89
+ private extractIntent;
90
+ /**
91
+ * Extract what token this one references (if any)
92
+ */
93
+ private extractReferences;
94
+ /**
95
+ * Get a token by name
96
+ */
97
+ getToken(name: string): TokenEntry | undefined;
98
+ /**
99
+ * Get all tokens
100
+ */
101
+ getAll(): TokenEntry[];
102
+ /**
103
+ * Get tokens by tier
104
+ */
105
+ getByTier(tier: TokenTier): TokenEntry[];
106
+ /**
107
+ * Get tokens by category
108
+ */
109
+ getByCategory(category: TokenCategory): TokenEntry[];
110
+ /**
111
+ * Get tokens by theme
112
+ */
113
+ getByTheme(theme: string): TokenEntry[];
114
+ /**
115
+ * Get available themes
116
+ */
117
+ getThemes(): string[];
118
+ /**
119
+ * Serialize to JSON
120
+ */
121
+ toJSON(): Record<string, TokenEntry>;
122
+ /**
123
+ * Deserialize from JSON
124
+ */
125
+ static fromJSON(obj: Record<string, TokenEntry>): TokenTaxonomy;
126
+ }
127
+ //# sourceMappingURL=token-taxonomy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-taxonomy.d.ts","sourceRoot":"","sources":["../../src/knowledge-graph/token-taxonomy.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExE,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAsC;IAEpD;;;;;;;;;;;;;;;;;OAiBG;IACG,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsB3C;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,YAAY;IA0BpB;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAgB1B;;OAEG;YACW,cAAc;IA0C5B;;;;;;;;;OASG;IACH,OAAO,CAAC,iBAAiB;IAUzB;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IAe7B;;;;;;OAMG;IACH,OAAO,CAAC,YAAY;IAqBpB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAwBxB;;OAEG;IACH,OAAO,CAAC,aAAa;IAiBrB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAUzB;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAU9C;;OAEG;IACH,MAAM,IAAI,UAAU,EAAE;IActB;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,SAAS,GAAG,UAAU,EAAE;IAcxC;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,aAAa,GAAG,UAAU,EAAE;IAcpD;;OAEG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,EAAE;IAIvC;;OAEG;IACH,SAAS,IAAI,MAAM,EAAE;IAQrB;;OAEG;IACH,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC;IAepC;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,aAAa;CAOhE"}