chati-dev 4.3.0 → 4.4.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 (156) hide show
  1. package/README.md +18 -13
  2. package/bin/chati.js +32 -4
  3. package/framework/agents/build/dev.md +9 -5
  4. package/framework/agents/discover/brief.md +2 -0
  5. package/framework/agents/discover/brownfield-wu.md +2 -0
  6. package/framework/agents/discover/greenfield-wu.md +18 -1
  7. package/framework/agents/plan/detail.md +2 -0
  8. package/framework/agents/plan/tasks.md +31 -0
  9. package/framework/agents/plan/ux-brand-architect.md +21 -2
  10. package/framework/agents/plan/ux-component-engineer.md +10 -0
  11. package/framework/agents/quality/qa-implementation.md +1 -1
  12. package/framework/agents/quality/qa-planning.md +1 -1
  13. package/framework/agents/quality/qa-visual.md +33 -21
  14. package/framework/config.yaml +5 -4
  15. package/framework/constitution.md +58 -11
  16. package/framework/context/governance.md +12 -10
  17. package/framework/context/root.md +2 -2
  18. package/framework/data/entity-registry.yaml +12 -4
  19. package/framework/data/qa-rubrics.yaml +335 -0
  20. package/framework/domains/constitution.yaml +3 -3
  21. package/framework/executors/json-validate.js +80 -0
  22. package/framework/executors/npm-script.js +72 -0
  23. package/framework/executors/path-check.js +67 -0
  24. package/framework/executors/registry.yaml +36 -0
  25. package/framework/hooks/advance-trigger.js +47 -3
  26. package/framework/hooks/constitution-guard.js +9 -4
  27. package/framework/hooks/git-push-authority.js +113 -0
  28. package/framework/hooks/license-guard.js +59 -9
  29. package/framework/hooks/model-governance.js +40 -17
  30. package/framework/hooks/prism-engine.js +78 -11
  31. package/framework/hooks/session-digest.js +12 -3
  32. package/framework/hooks/settings.json +7 -3
  33. package/framework/hooks/style-guard.js +52 -3
  34. package/framework/hooks/team-quality-gate.js +43 -5
  35. package/framework/i18n/en.yaml +3 -3
  36. package/framework/i18n/es.yaml +3 -3
  37. package/framework/i18n/fr.yaml +3 -3
  38. package/framework/i18n/pt.yaml +3 -3
  39. package/framework/intelligence/confidence.yaml +85 -6
  40. package/framework/intelligence/context-engine.md +9 -5
  41. package/framework/intelligence/decision-engine.md +1 -1
  42. package/framework/orchestrator/chati-router.js +59 -5
  43. package/framework/orchestrator/chati-update.md +19 -3
  44. package/framework/orchestrator/chati.md +20 -1
  45. package/framework/quality-gates/planning-gate.md +2 -0
  46. package/framework/rules/human-writing-style.md +47 -0
  47. package/framework/scaffold/motion-premium/README.md +12 -2
  48. package/framework/scaffold/motion-premium/lib/animations/tokens.ts.template +1 -1
  49. package/framework/scaffold/motion-premium/scaffold.yaml +6 -1
  50. package/framework/scaffold/motion-premium-3d/README.md +10 -0
  51. package/framework/scaffold/motion-premium-3d/components/webgl/WebGLContext.tsx.template +1 -1
  52. package/framework/scaffold/motion-premium-3d/scaffold.yaml +3 -0
  53. package/framework/scaffold/saas-dashboard/README.md +58 -0
  54. package/framework/scaffold/saas-dashboard/app/dashboard/page.tsx.template +546 -0
  55. package/framework/scaffold/saas-dashboard/app/globals.css.template +746 -0
  56. package/framework/scaffold/saas-dashboard/app/layout.tsx.template +192 -0
  57. package/framework/scaffold/saas-dashboard/app/shell.css.template +1070 -0
  58. package/framework/scaffold/saas-dashboard/components/data/Chart.tsx.template +725 -0
  59. package/framework/scaffold/saas-dashboard/components/data/DataTable.tsx.template +623 -0
  60. package/framework/scaffold/saas-dashboard/components/data/DataTable.types.ts.template +104 -0
  61. package/framework/scaffold/saas-dashboard/components/data/DataTablePagination.tsx.template +234 -0
  62. package/framework/scaffold/saas-dashboard/components/data/SkeletonBlock.tsx.template +111 -0
  63. package/framework/scaffold/saas-dashboard/components/data/StatCard.tsx.template +393 -0
  64. package/framework/scaffold/saas-dashboard/components/data/StatCardGrid.tsx.template +121 -0
  65. package/framework/scaffold/saas-dashboard/components/feedback/EmptyState.tsx.template +281 -0
  66. package/framework/scaffold/saas-dashboard/components/interaction/CommandPalette.tsx.template +767 -0
  67. package/framework/scaffold/saas-dashboard/components/interaction/Field.tsx.template +351 -0
  68. package/framework/scaffold/saas-dashboard/components/interaction/Form.tsx.template +424 -0
  69. package/framework/scaffold/saas-dashboard/components/primitives/Badge.tsx.template +193 -0
  70. package/framework/scaffold/saas-dashboard/components/primitives/Button.tsx.template +261 -0
  71. package/framework/scaffold/saas-dashboard/components/primitives/Card.tsx.template +287 -0
  72. package/framework/scaffold/saas-dashboard/components/primitives/Input.tsx.template +310 -0
  73. package/framework/scaffold/saas-dashboard/components/primitives/Spinner.tsx.template +135 -0
  74. package/framework/scaffold/saas-dashboard/components/primitives/index.ts.template +60 -0
  75. package/framework/scaffold/saas-dashboard/components/shell/AppShell.tsx.template +174 -0
  76. package/framework/scaffold/saas-dashboard/components/shell/Breadcrumb.tsx.template +186 -0
  77. package/framework/scaffold/saas-dashboard/components/shell/Container.tsx.template +86 -0
  78. package/framework/scaffold/saas-dashboard/components/shell/NavItem.tsx.template +147 -0
  79. package/framework/scaffold/saas-dashboard/components/shell/Sidebar.tsx.template +378 -0
  80. package/framework/scaffold/saas-dashboard/components/shell/SidebarContext.tsx.template +169 -0
  81. package/framework/scaffold/saas-dashboard/components/shell/ThemeToggle.tsx.template +128 -0
  82. package/framework/scaffold/saas-dashboard/components/shell/Topbar.tsx.template +301 -0
  83. package/framework/scaffold/saas-dashboard/lib/brand.ts.template +324 -0
  84. package/framework/scaffold/saas-dashboard/scaffold.yaml +225 -0
  85. package/framework/schemas/session.schema.json +5 -0
  86. package/framework/schemas/task.schema.json +9 -0
  87. package/framework/scripts/visual-qa.js +101 -3
  88. package/framework/tasks/orchestrator-health.md +4 -4
  89. package/framework/tasks/qa-impl-verdict.md +11 -5
  90. package/framework/templates/brandbook-html-tmpl.md +1 -1
  91. package/framework/templates/qa-gate-tmpl.yaml +24 -11
  92. package/package.json +4 -3
  93. package/src/config/context-file-generator.js +0 -6
  94. package/src/dashboard/renderer.js +0 -36
  95. package/src/executors/runner.js +204 -0
  96. package/src/installer/core.js +13 -3
  97. package/src/installer/templates.js +5 -6
  98. package/src/intelligence/registry-manager.js +1 -1
  99. package/src/license/client.js +9 -3
  100. package/src/license/commands.js +12 -2
  101. package/src/license/machine-id.js +42 -1
  102. package/src/memory/gotchas.js +58 -40
  103. package/src/memory/magic-docs.js +1 -1
  104. package/src/memory/session-digest.js +9 -4
  105. package/src/orchestrator/cli.js +186 -15
  106. package/src/orchestrator/doctor.js +98 -16
  107. package/src/orchestrator/pipeline-manager.js +44 -22
  108. package/src/orchestrator/session-manager.js +64 -8
  109. package/src/telemetry/sender.js +7 -19
  110. package/src/terminal/run-team.js +3 -3
  111. package/src/upgrade/tracked-files-detector.js +34 -16
  112. package/src/utils/feature-flags.js +1 -1
  113. package/src/utils/flatten-entities.js +4 -40
  114. package/src/utils/schema-validator.js +0 -14
  115. package/src/wizard/i18n.js +3 -3
  116. package/src/api/index.js +0 -120
  117. package/src/autonomy/autonomous-gate.js +0 -294
  118. package/src/autonomy/build-loop.js +0 -281
  119. package/src/autonomy/build-state.js +0 -286
  120. package/src/autonomy/cause-analyzer.js +0 -177
  121. package/src/autonomy/escalation.js +0 -214
  122. package/src/autonomy/index.js +0 -51
  123. package/src/autonomy/mode-manager.js +0 -225
  124. package/src/autonomy/mode-suggester.js +0 -283
  125. package/src/autonomy/progress-reporter.js +0 -275
  126. package/src/autonomy/safety-net.js +0 -370
  127. package/src/config/agent-customizer.js +0 -231
  128. package/src/decision/analyzer.js +0 -291
  129. package/src/decision/engine.js +0 -250
  130. package/src/decision/index.js +0 -38
  131. package/src/decision/registry-healer.js +0 -468
  132. package/src/decision/registry-updater.js +0 -339
  133. package/src/extensions/loader.js +0 -145
  134. package/src/extensions/registry.js +0 -134
  135. package/src/gates/circuit-breaker.js +0 -151
  136. package/src/gates/g1-planning-complete.js +0 -154
  137. package/src/gates/g2-qa-planning.js +0 -156
  138. package/src/gates/g3-implementation.js +0 -215
  139. package/src/gates/g4-qa-implementation.js +0 -240
  140. package/src/gates/g5-deploy-ready.js +0 -181
  141. package/src/gates/gate-base.js +0 -185
  142. package/src/gates/index.js +0 -46
  143. package/src/health/auto-fix.js +0 -216
  144. package/src/health/engine.js +0 -246
  145. package/src/merger/semantic-merger.js +0 -292
  146. package/src/preview/detector.js +0 -238
  147. package/src/preview/index.js +0 -20
  148. package/src/preview/launcher.js +0 -235
  149. package/src/preview/log-buffer.js +0 -103
  150. package/src/quality/metrics-collector.js +0 -281
  151. package/src/quality/test-runner.js +0 -366
  152. package/src/tasks/executor.js +0 -195
  153. package/src/tasks/index.js +0 -4
  154. package/src/tasks/loader.js +0 -210
  155. package/src/tasks/router.js +0 -182
  156. package/src/utils/event-bus.js +0 -126
@@ -1,250 +0,0 @@
1
- /**
2
- * Decision Engine - Core COMPASS module for chati.dev
3
- * Analyzes intent and recommends: REUSE (>=90%), ADAPT (60-89%), CREATE (<60%)
4
- *
5
- * NOTE: This module handles entity-level routing (registry lookup).
6
- * For intent-level similarity scoring (weighted keyword + purpose),
7
- * see `intelligence/decision-engine.js` (calculateIntentSimilarity).
8
- *
9
- * @module decision/engine
10
- */
11
-
12
- import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
13
- import { join } from 'path';
14
- import yaml from 'js-yaml';
15
- import { resolveFrameworkDir } from '../utils/framework-dir.js';
16
- import { flattenEntitiesFromRegistry } from '../utils/flatten-entities.js';
17
-
18
- /**
19
- * Analyze a request against existing entities and recommend action.
20
- * Uses keyword matching to find similar existing artifacts.
21
- *
22
- * @param {string} projectDir
23
- * @param {object} request - { description, type, keywords, agent }
24
- * @returns {{ recommendation: 'REUSE'|'ADAPT'|'CREATE', score: number, matches: object[], reasoning: string }}
25
- */
26
- export function analyzeRequest(projectDir, request) {
27
- const registryPath = join(projectDir, resolveFrameworkDir(projectDir), 'entity-registry.yaml');
28
-
29
- if (!existsSync(registryPath)) {
30
- return {
31
- recommendation: 'CREATE',
32
- score: 0,
33
- matches: [],
34
- reasoning: 'No entity registry found - first artifact in project'
35
- };
36
- }
37
-
38
- const registry = yaml.load(readFileSync(registryPath, 'utf8'));
39
- const entities = flattenEntitiesFromRegistry(registry);
40
-
41
- // Calculate similarity scores for all entities
42
- const scoredMatches = entities
43
- .map(entity => ({
44
- entity,
45
- score: calculateSimilarity(request, entity)
46
- }))
47
- .filter(match => match.score > 0)
48
- .sort((a, b) => b.score - a.score);
49
-
50
- const topScore = scoredMatches.length > 0 ? scoredMatches[0].score : 0;
51
- const topMatches = scoredMatches.slice(0, 5).map(m => ({
52
- path: m.entity.path,
53
- type: m.entity.type,
54
- score: m.score,
55
- purpose: m.entity.purpose || 'No purpose defined'
56
- }));
57
-
58
- let recommendation;
59
- let reasoning;
60
-
61
- if (topScore >= 90) {
62
- recommendation = 'REUSE';
63
- reasoning = `High similarity (${topScore}%) - existing artifact meets requirements`;
64
- } else if (topScore >= 60) {
65
- recommendation = 'ADAPT';
66
- reasoning = `Moderate similarity (${topScore}%) - adapt existing artifact`;
67
- } else {
68
- recommendation = 'CREATE';
69
- reasoning = topScore > 0
70
- ? `Low similarity (${topScore}%) - create new artifact`
71
- : 'No similar artifacts found - create new';
72
- }
73
-
74
- const decision = {
75
- timestamp: new Date().toISOString(),
76
- request: {
77
- description: request.description,
78
- type: request.type,
79
- keywords: request.keywords,
80
- agent: request.agent
81
- },
82
- recommendation,
83
- score: topScore,
84
- reasoning,
85
- topMatches: topMatches.slice(0, 3)
86
- };
87
-
88
- recordDecision(projectDir, decision);
89
-
90
- return {
91
- recommendation,
92
- score: topScore,
93
- matches: topMatches,
94
- reasoning
95
- };
96
- }
97
-
98
- /**
99
- * Calculate similarity between a request and an entity.
100
- * Uses keyword overlap (Jaccard similarity) + type matching.
101
- *
102
- * @param {object} request - { keywords, type }
103
- * @param {object} entity - { keywords, type, purpose }
104
- * @returns {number} Score 0-100
105
- */
106
- export function calculateSimilarity(request, entity) {
107
- // Normalize and collect keywords
108
- const requestKeywords = new Set(
109
- (request.keywords || []).map(k => k.toLowerCase())
110
- );
111
-
112
- const entityKeywords = new Set();
113
-
114
- // Extract from entity keywords (primary source)
115
- if (entity.keywords) {
116
- entity.keywords.forEach(k => entityKeywords.add(k.toLowerCase()));
117
- }
118
-
119
- // Extract from entity name (secondary source - only key terms)
120
- if (entity.name) {
121
- const nameWords = entity.name
122
- .toLowerCase()
123
- .replace(/[._-]/g, ' ')
124
- .split(/\W+/)
125
- .filter(w => w.length > 3);
126
- nameWords.forEach(w => entityKeywords.add(w));
127
- }
128
-
129
- if (requestKeywords.size === 0 || entityKeywords.size === 0) {
130
- return 0;
131
- }
132
-
133
- // Calculate Jaccard similarity
134
- const intersection = new Set(
135
- [...requestKeywords].filter(k => entityKeywords.has(k))
136
- );
137
- const union = new Set([...requestKeywords, ...entityKeywords]);
138
-
139
- let score = (intersection.size / union.size) * 100;
140
-
141
- // Add bonus points for type match (additive, not multiplicative)
142
- if (request.type && entity.type && request.type === entity.type) {
143
- score = Math.min(100, score + 25);
144
- }
145
-
146
- // Add bonus for high intersection ratio (more matches = better)
147
- const intersectionRatio = intersection.size / requestKeywords.size;
148
- if (intersectionRatio >= 0.8) {
149
- score = Math.min(100, score + 15);
150
- } else if (intersectionRatio >= 0.5) {
151
- score = Math.min(100, score + 10);
152
- }
153
-
154
- return Math.round(score);
155
- }
156
-
157
- /**
158
- * Get decision history for auditing.
159
- * @param {string} projectDir
160
- * @returns {object[]} Recent decisions
161
- */
162
- export function getDecisionHistory(projectDir) {
163
- const historyPath = join(projectDir, '.chati', 'decisions', 'history.json');
164
-
165
- if (!existsSync(historyPath)) {
166
- return [];
167
- }
168
-
169
- try {
170
- const content = readFileSync(historyPath, 'utf8');
171
- const data = JSON.parse(content);
172
- return data.decisions || [];
173
- } catch { /* expected: file may not exist */
174
- return [];
175
- }
176
- }
177
-
178
- /**
179
- * Record a decision for audit trail.
180
- * @param {string} projectDir
181
- * @param {object} decision
182
- */
183
- export function recordDecision(projectDir, decision) {
184
- const decisionsDir = join(projectDir, '.chati', 'decisions');
185
- const historyPath = join(decisionsDir, 'history.json');
186
-
187
- // Ensure directory exists
188
- if (!existsSync(decisionsDir)) {
189
- mkdirSync(decisionsDir, { recursive: true });
190
- }
191
-
192
- let history = { decisions: [] };
193
-
194
- if (existsSync(historyPath)) {
195
- try {
196
- const content = readFileSync(historyPath, 'utf8');
197
- history = JSON.parse(content);
198
- } catch { /* expected: file may not exist */
199
- // Keep empty history if parse fails
200
- }
201
- }
202
-
203
- history.decisions = history.decisions || [];
204
- history.decisions.push(decision);
205
-
206
- // Keep last 100 decisions
207
- if (history.decisions.length > 100) {
208
- history.decisions = history.decisions.slice(-100);
209
- }
210
-
211
- writeFileSync(historyPath, JSON.stringify(history, null, 2), 'utf8');
212
- }
213
-
214
- /**
215
- * Get engine statistics.
216
- * @param {string} projectDir
217
- * @returns {object} { totalDecisions, byRecommendation: { REUSE, ADAPT, CREATE }, avgScore }
218
- */
219
- export function getEngineStats(projectDir) {
220
- const history = getDecisionHistory(projectDir);
221
-
222
- const stats = {
223
- totalDecisions: history.length,
224
- byRecommendation: {
225
- REUSE: 0,
226
- ADAPT: 0,
227
- CREATE: 0
228
- },
229
- avgScore: 0
230
- };
231
-
232
- if (history.length === 0) {
233
- return stats;
234
- }
235
-
236
- let totalScore = 0;
237
-
238
- history.forEach(decision => {
239
- if (decision.recommendation) {
240
- stats.byRecommendation[decision.recommendation] =
241
- (stats.byRecommendation[decision.recommendation] || 0) + 1;
242
- }
243
- totalScore += decision.score || 0;
244
- });
245
-
246
- stats.avgScore = Math.round(totalScore / history.length);
247
-
248
- return stats;
249
- }
250
-
@@ -1,38 +0,0 @@
1
- /**
2
- * Decision Engine - COMPASS for chati.dev
3
- * Barrel exports for decision engine modules
4
- *
5
- * @module decision
6
- */
7
-
8
- export {
9
- analyzeRequest,
10
- calculateSimilarity,
11
- getDecisionHistory,
12
- recordDecision,
13
- getEngineStats
14
- } from './engine.js';
15
-
16
- export {
17
- analyzeImpact,
18
- buildDependencyGraph,
19
- getTransitiveDependents
20
- } from './analyzer.js';
21
-
22
- export {
23
- updateRegistry,
24
- detectNewEntities,
25
- detectRemovedEntities,
26
- generateEntityMeta
27
- } from './registry-updater.js';
28
-
29
- export {
30
- healRegistry,
31
- detectMissingEntities,
32
- detectOrphanedEntries,
33
- detectStaleMetadata,
34
- detectDuplicates,
35
- detectInvalidPaths,
36
- detectCountMismatch,
37
- applyFixes
38
- } from './registry-healer.js';