chati-dev 4.3.1 → 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 (147) hide show
  1. package/README.md +18 -13
  2. package/bin/chati.js +12 -4
  3. package/framework/agents/build/dev.md +5 -1
  4. package/framework/agents/discover/greenfield-wu.md +16 -1
  5. package/framework/agents/plan/tasks.md +31 -0
  6. package/framework/agents/plan/ux-brand-architect.md +21 -2
  7. package/framework/agents/plan/ux-component-engineer.md +10 -0
  8. package/framework/agents/quality/qa-implementation.md +1 -1
  9. package/framework/agents/quality/qa-planning.md +1 -1
  10. package/framework/agents/quality/qa-visual.md +24 -21
  11. package/framework/config.yaml +5 -4
  12. package/framework/constitution.md +58 -11
  13. package/framework/context/governance.md +12 -10
  14. package/framework/context/root.md +2 -2
  15. package/framework/data/entity-registry.yaml +12 -4
  16. package/framework/data/qa-rubrics.yaml +335 -0
  17. package/framework/domains/constitution.yaml +3 -3
  18. package/framework/executors/json-validate.js +80 -0
  19. package/framework/executors/npm-script.js +72 -0
  20. package/framework/executors/path-check.js +67 -0
  21. package/framework/executors/registry.yaml +36 -0
  22. package/framework/hooks/advance-trigger.js +47 -3
  23. package/framework/hooks/constitution-guard.js +9 -4
  24. package/framework/hooks/git-push-authority.js +113 -0
  25. package/framework/hooks/license-guard.js +59 -9
  26. package/framework/hooks/model-governance.js +40 -17
  27. package/framework/hooks/prism-engine.js +78 -11
  28. package/framework/hooks/session-digest.js +12 -3
  29. package/framework/hooks/settings.json +7 -3
  30. package/framework/hooks/style-guard.js +52 -3
  31. package/framework/hooks/team-quality-gate.js +43 -5
  32. package/framework/i18n/en.yaml +3 -3
  33. package/framework/i18n/es.yaml +3 -3
  34. package/framework/i18n/fr.yaml +3 -3
  35. package/framework/i18n/pt.yaml +3 -3
  36. package/framework/intelligence/confidence.yaml +85 -6
  37. package/framework/intelligence/context-engine.md +9 -5
  38. package/framework/intelligence/decision-engine.md +1 -1
  39. package/framework/orchestrator/chati-router.js +1 -1
  40. package/framework/orchestrator/chati-update.md +19 -3
  41. package/framework/orchestrator/chati.md +19 -1
  42. package/framework/quality-gates/planning-gate.md +2 -0
  43. package/framework/scaffold/motion-premium/scaffold.yaml +2 -1
  44. package/framework/scaffold/motion-premium-3d/components/webgl/WebGLContext.tsx.template +1 -1
  45. package/framework/scaffold/saas-dashboard/README.md +58 -0
  46. package/framework/scaffold/saas-dashboard/app/dashboard/page.tsx.template +546 -0
  47. package/framework/scaffold/saas-dashboard/app/globals.css.template +746 -0
  48. package/framework/scaffold/saas-dashboard/app/layout.tsx.template +192 -0
  49. package/framework/scaffold/saas-dashboard/app/shell.css.template +1070 -0
  50. package/framework/scaffold/saas-dashboard/components/data/Chart.tsx.template +725 -0
  51. package/framework/scaffold/saas-dashboard/components/data/DataTable.tsx.template +623 -0
  52. package/framework/scaffold/saas-dashboard/components/data/DataTable.types.ts.template +104 -0
  53. package/framework/scaffold/saas-dashboard/components/data/DataTablePagination.tsx.template +234 -0
  54. package/framework/scaffold/saas-dashboard/components/data/SkeletonBlock.tsx.template +111 -0
  55. package/framework/scaffold/saas-dashboard/components/data/StatCard.tsx.template +393 -0
  56. package/framework/scaffold/saas-dashboard/components/data/StatCardGrid.tsx.template +121 -0
  57. package/framework/scaffold/saas-dashboard/components/feedback/EmptyState.tsx.template +281 -0
  58. package/framework/scaffold/saas-dashboard/components/interaction/CommandPalette.tsx.template +767 -0
  59. package/framework/scaffold/saas-dashboard/components/interaction/Field.tsx.template +351 -0
  60. package/framework/scaffold/saas-dashboard/components/interaction/Form.tsx.template +424 -0
  61. package/framework/scaffold/saas-dashboard/components/primitives/Badge.tsx.template +193 -0
  62. package/framework/scaffold/saas-dashboard/components/primitives/Button.tsx.template +261 -0
  63. package/framework/scaffold/saas-dashboard/components/primitives/Card.tsx.template +287 -0
  64. package/framework/scaffold/saas-dashboard/components/primitives/Input.tsx.template +310 -0
  65. package/framework/scaffold/saas-dashboard/components/primitives/Spinner.tsx.template +135 -0
  66. package/framework/scaffold/saas-dashboard/components/primitives/index.ts.template +60 -0
  67. package/framework/scaffold/saas-dashboard/components/shell/AppShell.tsx.template +174 -0
  68. package/framework/scaffold/saas-dashboard/components/shell/Breadcrumb.tsx.template +186 -0
  69. package/framework/scaffold/saas-dashboard/components/shell/Container.tsx.template +86 -0
  70. package/framework/scaffold/saas-dashboard/components/shell/NavItem.tsx.template +147 -0
  71. package/framework/scaffold/saas-dashboard/components/shell/Sidebar.tsx.template +378 -0
  72. package/framework/scaffold/saas-dashboard/components/shell/SidebarContext.tsx.template +169 -0
  73. package/framework/scaffold/saas-dashboard/components/shell/ThemeToggle.tsx.template +128 -0
  74. package/framework/scaffold/saas-dashboard/components/shell/Topbar.tsx.template +301 -0
  75. package/framework/scaffold/saas-dashboard/lib/brand.ts.template +324 -0
  76. package/framework/scaffold/saas-dashboard/scaffold.yaml +225 -0
  77. package/framework/schemas/session.schema.json +5 -0
  78. package/framework/schemas/task.schema.json +9 -0
  79. package/framework/scripts/visual-qa.js +87 -1
  80. package/framework/tasks/orchestrator-health.md +4 -4
  81. package/framework/tasks/qa-impl-verdict.md +11 -5
  82. package/framework/templates/qa-gate-tmpl.yaml +24 -11
  83. package/package.json +3 -3
  84. package/src/config/context-file-generator.js +0 -6
  85. package/src/dashboard/renderer.js +0 -36
  86. package/src/executors/runner.js +204 -0
  87. package/src/installer/core.js +2 -1
  88. package/src/installer/templates.js +5 -6
  89. package/src/intelligence/registry-manager.js +1 -1
  90. package/src/license/client.js +9 -3
  91. package/src/license/commands.js +12 -2
  92. package/src/license/machine-id.js +42 -1
  93. package/src/memory/gotchas.js +58 -40
  94. package/src/memory/magic-docs.js +1 -1
  95. package/src/memory/session-digest.js +9 -4
  96. package/src/orchestrator/cli.js +174 -14
  97. package/src/orchestrator/doctor.js +98 -16
  98. package/src/orchestrator/pipeline-manager.js +44 -22
  99. package/src/orchestrator/session-manager.js +56 -8
  100. package/src/telemetry/sender.js +7 -19
  101. package/src/terminal/run-team.js +3 -3
  102. package/src/upgrade/tracked-files-detector.js +34 -16
  103. package/src/utils/feature-flags.js +1 -1
  104. package/src/utils/flatten-entities.js +4 -40
  105. package/src/utils/schema-validator.js +0 -14
  106. package/src/wizard/i18n.js +3 -3
  107. package/src/api/index.js +0 -120
  108. package/src/autonomy/autonomous-gate.js +0 -294
  109. package/src/autonomy/build-loop.js +0 -281
  110. package/src/autonomy/build-state.js +0 -286
  111. package/src/autonomy/cause-analyzer.js +0 -177
  112. package/src/autonomy/escalation.js +0 -214
  113. package/src/autonomy/index.js +0 -51
  114. package/src/autonomy/mode-manager.js +0 -225
  115. package/src/autonomy/mode-suggester.js +0 -283
  116. package/src/autonomy/progress-reporter.js +0 -275
  117. package/src/autonomy/safety-net.js +0 -370
  118. package/src/config/agent-customizer.js +0 -231
  119. package/src/decision/analyzer.js +0 -291
  120. package/src/decision/engine.js +0 -250
  121. package/src/decision/index.js +0 -38
  122. package/src/decision/registry-healer.js +0 -468
  123. package/src/decision/registry-updater.js +0 -339
  124. package/src/extensions/loader.js +0 -145
  125. package/src/extensions/registry.js +0 -134
  126. package/src/gates/circuit-breaker.js +0 -151
  127. package/src/gates/g1-planning-complete.js +0 -154
  128. package/src/gates/g2-qa-planning.js +0 -156
  129. package/src/gates/g3-implementation.js +0 -215
  130. package/src/gates/g4-qa-implementation.js +0 -240
  131. package/src/gates/g5-deploy-ready.js +0 -181
  132. package/src/gates/gate-base.js +0 -185
  133. package/src/gates/index.js +0 -46
  134. package/src/health/auto-fix.js +0 -216
  135. package/src/health/engine.js +0 -246
  136. package/src/merger/semantic-merger.js +0 -292
  137. package/src/preview/detector.js +0 -238
  138. package/src/preview/index.js +0 -20
  139. package/src/preview/launcher.js +0 -235
  140. package/src/preview/log-buffer.js +0 -103
  141. package/src/quality/metrics-collector.js +0 -281
  142. package/src/quality/test-runner.js +0 -366
  143. package/src/tasks/executor.js +0 -195
  144. package/src/tasks/index.js +0 -4
  145. package/src/tasks/loader.js +0 -210
  146. package/src/tasks/router.js +0 -182
  147. 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';