chati-dev 4.2.1 → 4.3.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 (222) hide show
  1. package/README.md +80 -53
  2. package/bin/chati.js +150 -5
  3. package/framework/agents/build/dev.md +509 -76
  4. package/framework/agents/deploy/devops.md +40 -25
  5. package/framework/agents/discover/brief.md +156 -22
  6. package/framework/agents/discover/brownfield-wu.md +24 -14
  7. package/framework/agents/discover/greenfield-wu.md +100 -14
  8. package/framework/agents/plan/architect-data-engineer.md +6 -6
  9. package/framework/agents/plan/architect-system.md +46 -12
  10. package/framework/agents/plan/architect.md +40 -20
  11. package/framework/agents/plan/detail.md +36 -24
  12. package/framework/agents/plan/phases.md +36 -26
  13. package/framework/agents/plan/tasks.md +114 -33
  14. package/framework/agents/plan/ux-brand-architect.md +240 -8
  15. package/framework/agents/plan/ux-component-engineer.md +28 -13
  16. package/framework/agents/plan/ux-researcher.md +7 -6
  17. package/framework/agents/plan/ux.md +55 -22
  18. package/framework/agents/quality/qa-implementation.md +143 -74
  19. package/framework/agents/quality/qa-planning.md +115 -42
  20. package/framework/agents/quality/qa-visual.md +439 -0
  21. package/framework/agents/shared/visualizer.md +128 -0
  22. package/framework/config.yaml +8 -7
  23. package/framework/constitution.md +127 -43
  24. package/framework/context/governance.md +12 -7
  25. package/framework/context/quality.md +6 -5
  26. package/framework/context/root.md +6 -6
  27. package/framework/data/entity-registry.yaml +377 -4
  28. package/framework/data/model-limits.json +19 -0
  29. package/framework/domains/agents/qa-visual.yaml +74 -0
  30. package/framework/domains/constitution.yaml +46 -2
  31. package/framework/domains/workflows/greenfield-fullstack.yaml +2 -2
  32. package/framework/hooks/advance-trigger.js +131 -0
  33. package/framework/hooks/brief-validator.js +83 -0
  34. package/framework/hooks/constitution-guard.js +91 -36
  35. package/framework/hooks/license-guard.js +129 -190
  36. package/framework/hooks/mode-governance.js +68 -16
  37. package/framework/hooks/model-governance.js +19 -8
  38. package/framework/hooks/package.json +3 -0
  39. package/framework/hooks/post-dev.js +207 -0
  40. package/framework/hooks/prism-engine.js +288 -105
  41. package/framework/hooks/read-protection.js +37 -9
  42. package/framework/hooks/reasoning-escalator.js +371 -0
  43. package/framework/hooks/reference-trigger.js +117 -0
  44. package/framework/hooks/session-digest.js +94 -20
  45. package/framework/hooks/settings.json +32 -1
  46. package/framework/hooks/style-guard.js +52 -13
  47. package/framework/hooks/team-quality-gate.js +58 -25
  48. package/framework/hooks/undercover-guard.js +34 -13
  49. package/framework/i18n/en.yaml +3 -3
  50. package/framework/i18n/es.yaml +3 -3
  51. package/framework/i18n/fr.yaml +3 -3
  52. package/framework/i18n/pt.yaml +3 -3
  53. package/framework/intelligence/context-engine.md +4 -5
  54. package/framework/intelligence/decision-engine.md +1 -1
  55. package/framework/intelligence/hooks-performance.md +3 -3
  56. package/framework/migrations/v1.0-to-v1.1.yaml +1 -1
  57. package/framework/migrations/v1.4-to-v2.0.yaml +11 -11
  58. package/framework/migrations/v4.0-to-v4.1.yaml +2 -2
  59. package/framework/migrations/v4.2-to-v4.3.yaml +29 -0
  60. package/framework/orchestrator/chati-router.js +387 -0
  61. package/framework/orchestrator/chati-update.md +40 -40
  62. package/framework/orchestrator/chati.md +318 -115
  63. package/framework/scaffold/motion-premium/README.md +89 -0
  64. package/framework/scaffold/motion-premium/app/globals.css.template +400 -0
  65. package/framework/scaffold/motion-premium/app/layout.tsx.template +110 -0
  66. package/framework/scaffold/motion-premium/components/animation/BackgroundCrossfadeProvider.tsx.template +170 -0
  67. package/framework/scaffold/motion-premium/components/animation/LenisProvider.tsx.template +49 -0
  68. package/framework/scaffold/motion-premium/components/animation/PageTransitionWrapper.tsx.template +83 -0
  69. package/framework/scaffold/motion-premium/components/animation/Preloader.tsx.template +171 -0
  70. package/framework/scaffold/motion-premium/components/ui/Container.tsx.template +69 -0
  71. package/framework/scaffold/motion-premium/components/ui/PageSection.tsx.template +74 -0
  72. package/framework/scaffold/motion-premium/lib/animations/gsap.ts.template +112 -0
  73. package/framework/scaffold/motion-premium/lib/animations/refreshCoordinator.ts.template +75 -0
  74. package/framework/scaffold/motion-premium/lib/animations/tokens.ts.template +119 -0
  75. package/framework/scaffold/motion-premium/lib/animations/useGsapContext.ts.template +92 -0
  76. package/framework/scaffold/motion-premium/lib/animations/useScrollSnapStepper.ts.template +265 -0
  77. package/framework/scaffold/motion-premium/lib/animations/useSmoothScroll.ts.template +67 -0
  78. package/framework/scaffold/motion-premium/lib/brand.ts.template +43 -0
  79. package/framework/scaffold/motion-premium/scaffold.yaml +174 -0
  80. package/framework/scaffold/motion-premium-3d/README.md +80 -0
  81. package/framework/scaffold/motion-premium-3d/app/(3d)/scroll-demo/ScrollDemoCanvas.tsx.template +81 -0
  82. package/framework/scaffold/motion-premium-3d/app/(3d)/scroll-demo/ScrollDemoClient.tsx.template +75 -0
  83. package/framework/scaffold/motion-premium-3d/app/(3d)/scroll-demo/page.tsx.template +26 -0
  84. package/framework/scaffold/motion-premium-3d/components/3d/CameraRig.tsx.template +100 -0
  85. package/framework/scaffold/motion-premium-3d/components/3d/CanvasProvider.tsx.template +85 -0
  86. package/framework/scaffold/motion-premium-3d/components/3d/InvalidateOnScroll.tsx.template +51 -0
  87. package/framework/scaffold/motion-premium-3d/components/3d/MeshCrossfade.tsx.template +79 -0
  88. package/framework/scaffold/motion-premium-3d/components/3d/ScrollCrossfade.tsx.template +88 -0
  89. package/framework/scaffold/motion-premium-3d/components/3d/ScrollScene.tsx.template +121 -0
  90. package/framework/scaffold/motion-premium-3d/components/webgl/SceneFallback.tsx.template +65 -0
  91. package/framework/scaffold/motion-premium-3d/components/webgl/WebGLContext.tsx.template +68 -0
  92. package/framework/scaffold/motion-premium-3d/lib/webgl/detect.ts.template +69 -0
  93. package/framework/scaffold/motion-premium-3d/scaffold.yaml +133 -0
  94. package/framework/schemas/session.schema.json +109 -21
  95. package/framework/scripts/reference-capture.js +430 -0
  96. package/framework/scripts/visual-qa.js +674 -0
  97. package/framework/tasks/orchestrator-handoff.md +1 -1
  98. package/framework/tasks/orchestrator-resume.md +1 -1
  99. package/framework/tasks/orchestrator-route.md +1 -1
  100. package/framework/tasks/orchestrator-status.md +3 -3
  101. package/framework/tasks/qa-planning-gate-define.md +1 -1
  102. package/framework/templates/brandbook-html-tmpl.md +1 -1
  103. package/framework/templates/brandbook-tmpl.yaml +1 -1
  104. package/framework/templates/component-spec-tmpl.yaml +1 -1
  105. package/framework/templates/design-token-tmpl.yaml +1 -1
  106. package/framework/templates/icon-system-tmpl.yaml +1 -1
  107. package/framework/templates/team-planning-tasks.yaml +6 -5
  108. package/framework/workflows/brownfield-discovery.yaml +2 -2
  109. package/framework/workflows/brownfield-fullstack.yaml +15 -11
  110. package/framework/workflows/brownfield-service.yaml +14 -10
  111. package/framework/workflows/brownfield-ui.yaml +15 -11
  112. package/framework/workflows/greenfield-fullstack.yaml +16 -13
  113. package/framework/workflows/quick-flow.yaml +3 -3
  114. package/framework/workflows/standard-flow.yaml +12 -9
  115. package/package.json +10 -5
  116. package/src/autonomy/autonomous-gate.js +1 -0
  117. package/src/autonomy/build-state.js +1 -2
  118. package/src/autonomy/progress-reporter.js +1 -1
  119. package/src/config/agent-customizer.js +11 -3
  120. package/src/config/claude-settings-generator.js +226 -0
  121. package/src/config/context-file-generator.js +41 -21
  122. package/src/config/framework-adapter.js +1 -0
  123. package/src/config/gemini-hooks-generator.js +76 -6
  124. package/src/config/mcp-configs.js +1 -0
  125. package/src/context/layers/l1-global.js +2 -1
  126. package/src/dashboard/data-reader.js +4 -3
  127. package/src/dashboard/layout.js +2 -1
  128. package/src/decision/analyzer.js +6 -30
  129. package/src/decision/engine.js +4 -28
  130. package/src/decision/registry-healer.js +3 -2
  131. package/src/decision/registry-updater.js +23 -14
  132. package/src/extensions/loader.js +2 -8
  133. package/src/gates/g1-planning-complete.js +2 -1
  134. package/src/gates/g2-qa-planning.js +2 -1
  135. package/src/gates/g3-implementation.js +2 -1
  136. package/src/gates/g4-qa-implementation.js +3 -2
  137. package/src/gates/g5-deploy-ready.js +2 -1
  138. package/src/health/engine.js +4 -3
  139. package/src/installer/core.js +557 -81
  140. package/src/installer/preflight.js +131 -0
  141. package/src/installer/provider-overlay.js +3 -3
  142. package/src/installer/scaffold-applier.js +358 -0
  143. package/src/installer/templates.js +52 -31
  144. package/src/installer/validator.js +17 -12
  145. package/src/intelligence/registry-manager.js +22 -29
  146. package/src/intelligence/timeline.js +11 -6
  147. package/src/license/commands.js +1 -1
  148. package/src/license/wait.js +102 -0
  149. package/src/memory/agent-memory.js +81 -0
  150. package/src/memory/dream.js +32 -1
  151. package/src/merger/replace-merger.js +28 -15
  152. package/src/orchestrator/agent-selector.js +2 -1
  153. package/src/orchestrator/cli.js +1908 -80
  154. package/src/orchestrator/doctor.js +270 -0
  155. package/src/orchestrator/handoff-engine.js +4 -3
  156. package/src/orchestrator/index.js +2 -0
  157. package/src/orchestrator/pipeline-manager.js +306 -15
  158. package/src/orchestrator/session-manager.js +331 -6
  159. package/src/tasks/handoff.js +3 -2
  160. package/src/telemetry/config.js +4 -3
  161. package/src/telemetry/schema.js +1 -0
  162. package/src/terminal/collector.js +3 -2
  163. package/src/terminal/index.js +1 -2
  164. package/src/terminal/isolation.js +52 -18
  165. package/src/terminal/prompt-builder.js +42 -25
  166. package/src/terminal/run-parallel.js +1 -1
  167. package/src/terminal/run-team.js +3 -3
  168. package/src/terminal/team-task-list.js +43 -4
  169. package/src/upgrade/backup.js +3 -2
  170. package/src/upgrade/checker.js +3 -2
  171. package/src/upgrade/migrator.js +65 -7
  172. package/src/upgrade/tracked-files-detector.js +86 -0
  173. package/src/upgrade/user-messages.js +94 -0
  174. package/src/utils/config-parser.js +2 -1
  175. package/src/utils/feature-flags.js +2 -1
  176. package/src/utils/flatten-entities.js +69 -0
  177. package/src/utils/framework-dir.js +16 -0
  178. package/src/utils/model-id.js +85 -0
  179. package/src/utils/provider-limits.js +84 -23
  180. package/src/utils/schema-validator.js +1 -1
  181. package/src/wizard/i18n.js +5 -4
  182. package/src/wizard/index.js +14 -0
  183. package/assets/logo - c/303/263pia.png +0 -0
  184. package/assets/logo.svg +0 -42
  185. package/assets/logo2.png +0 -0
  186. package/assets/social-preview.png +0 -0
  187. package/scripts/bundle-framework.js +0 -69
  188. package/scripts/changelog-generator.js +0 -222
  189. package/scripts/codebase-mapper.js +0 -728
  190. package/scripts/commit-message-generator.js +0 -167
  191. package/scripts/coverage-analyzer.js +0 -260
  192. package/scripts/dependency-analyzer.js +0 -280
  193. package/scripts/doctor/checks/agents.js +0 -77
  194. package/scripts/doctor/checks/constitution.js +0 -41
  195. package/scripts/doctor/checks/domain-alignment.js +0 -58
  196. package/scripts/doctor/checks/prism-layers.js +0 -84
  197. package/scripts/doctor/checks/registry.js +0 -55
  198. package/scripts/doctor/checks/schemas.js +0 -61
  199. package/scripts/doctor/fixes/reference-fix.js +0 -100
  200. package/scripts/doctor/fixes/registry-fix.js +0 -56
  201. package/scripts/doctor/index.js +0 -212
  202. package/scripts/framework-analyzer.js +0 -308
  203. package/scripts/generate-constitution-domain.js +0 -253
  204. package/scripts/generate-signing-key.js +0 -33
  205. package/scripts/health-check.js +0 -481
  206. package/scripts/ide-sync.js +0 -326
  207. package/scripts/performance-analyzer.js +0 -325
  208. package/scripts/plan-tracker.js +0 -278
  209. package/scripts/populate-entity-registry.js +0 -481
  210. package/scripts/pr-review.js +0 -317
  211. package/scripts/rollback-manager.js +0 -310
  212. package/scripts/semantic-lint.js +0 -328
  213. package/scripts/sign-manifest.js +0 -53
  214. package/scripts/stuck-detector.js +0 -343
  215. package/scripts/test-quality-assessment.js +0 -257
  216. package/scripts/validate-agents.js +0 -368
  217. package/scripts/validate-package.js +0 -367
  218. package/scripts/validate-tasks.js +0 -465
  219. package/src/autonomy/worktree-manager.js +0 -250
  220. package/src/intelligence/decision-engine.js +0 -256
  221. package/src/intelligence/document-sharder.js +0 -221
  222. package/src/intelligence/elicitation.js +0 -265
@@ -1,368 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Validate Agents — Validates agent definition files (.md with frontmatter-like structure).
5
- *
6
- * Exports:
7
- * validateAllAgents(frameworkDir) → AgentValidationReport
8
- * validateAgent(frameworkDir, agentPath) → single agent validation result
9
- * getAgentCompleteness(agentContent) → { score: 0-100, missing: [] }
10
- *
11
- * EXPECTED_AGENTS: 12 agents + 1 orchestrator = 13 total
12
- */
13
-
14
- import { readFileSync, existsSync } from 'fs';
15
- import { join, basename } from 'path';
16
- import yaml from 'js-yaml';
17
-
18
- /**
19
- * Expected agents organized by category.
20
- */
21
- export const EXPECTED_AGENTS = {
22
- discover: ['greenfield-wu', 'brownfield-wu', 'brief'],
23
- plan: ['detail', 'architect', 'ux', 'phases', 'tasks'],
24
- quality: ['qa-planning', 'qa-implementation'],
25
- build: ['dev'],
26
- deploy: ['devops'],
27
- };
28
-
29
- /**
30
- * All expected agent names as a flat list (excluding orchestrator).
31
- */
32
- export const ALL_AGENT_NAMES = Object.values(EXPECTED_AGENTS).flat();
33
-
34
- /**
35
- * Sections expected in a complete agent definition.
36
- */
37
- const COMPLETENESS_SECTIONS = [
38
- { name: 'Identity', patterns: ['## Identity', '## identity'] },
39
- { name: 'Mission', patterns: ['## Mission', '## mission'] },
40
- { name: 'On Activation', patterns: ['## On Activation', '## on activation'] },
41
- { name: 'Execution', patterns: ['## Execution', '## execution', '## Steps', '## steps'] },
42
- { name: 'Self-Validation', patterns: ['## Self-Validation', '## self-validation', '## Validation', 'Self-Validation Criteria'] },
43
- { name: 'Handoff', patterns: ['## Handoff', '## handoff', 'Handoff Protocol', 'handoff_to'] },
44
- { name: 'Protocols', patterns: ['## Protocols', '## protocols', 'Universal Protocols'] },
45
- { name: 'Behavioral', patterns: ['## Behavioral', '## behavioral', '## Personality', '## personality', '## Style', '## Communication'] },
46
- ];
47
-
48
- // ---------------------------------------------------------------------------
49
- // Internal Helpers
50
- // ---------------------------------------------------------------------------
51
-
52
- /**
53
- * Parse identity fields from agent markdown content.
54
- * Agent files use markdown sections rather than YAML frontmatter.
55
- * We extract identity from the "## Identity" section.
56
- * @param {string} content - Full agent .md content.
57
- * @returns {object} Parsed identity fields.
58
- */
59
- function parseAgentIdentity(content) {
60
- const identity = {};
61
-
62
- // Extract Role
63
- const roleMatch = content.match(/\*\*Role\*\*:\s*(.+)/);
64
- if (roleMatch) identity.role = roleMatch[1].trim();
65
-
66
- // Extract Pipeline Position
67
- const posMatch = content.match(/\*\*Pipeline Position\*\*:\s*(.+)/);
68
- if (posMatch) identity.pipelinePosition = posMatch[1].trim();
69
-
70
- // Extract Category
71
- const catMatch = content.match(/\*\*Category\*\*:\s*(.+)/);
72
- if (catMatch) identity.category = catMatch[1].trim();
73
-
74
- // Extract name from title
75
- const titleMatch = content.match(/^#\s+(.+?)(?:\s*—|\s*-|\n)/m);
76
- if (titleMatch) identity.title = titleMatch[1].trim();
77
-
78
- // Extract Question Answered
79
- const questionMatch = content.match(/\*\*Question Answered\*\*:\s*(.+)/);
80
- if (questionMatch) identity.questionAnswered = questionMatch[1].trim();
81
-
82
- return identity;
83
- }
84
-
85
- /**
86
- * Extract the agent name from the filename.
87
- * @param {string} filePath - Path to the agent .md file.
88
- * @returns {string} Agent name without extension.
89
- */
90
- function agentNameFromPath(filePath) {
91
- return basename(filePath, '.md');
92
- }
93
-
94
- /**
95
- * Get the completeness score for an agent definition.
96
- * @param {string} agentContent - Full markdown content of the agent.
97
- * @returns {{ score: number, missing: string[], found: string[] }}
98
- */
99
- export function getAgentCompleteness(agentContent) {
100
- const found = [];
101
- const missing = [];
102
-
103
- for (const section of COMPLETENESS_SECTIONS) {
104
- const hasSection = section.patterns.some(p =>
105
- agentContent.toLowerCase().includes(p.toLowerCase()),
106
- );
107
- if (hasSection) {
108
- found.push(section.name);
109
- } else {
110
- missing.push(section.name);
111
- }
112
- }
113
-
114
- const score = Math.round((found.length / COMPLETENESS_SECTIONS.length) * 100);
115
-
116
- return { score, missing, found };
117
- }
118
-
119
- /**
120
- * Validate a single agent definition file.
121
- * @param {string} frameworkDir - Path to the framework directory.
122
- * @param {string} agentRelPath - Relative path to the agent file within agents/ or orchestrator/.
123
- * @returns {object} Validation result.
124
- */
125
- export function validateAgent(frameworkDir, agentRelPath) {
126
- const fullPath = join(frameworkDir, agentRelPath);
127
- const agentName = agentNameFromPath(fullPath);
128
-
129
- const result = {
130
- name: agentName,
131
- path: agentRelPath,
132
- valid: true,
133
- errors: [],
134
- warnings: [],
135
- completeness: null,
136
- identity: null,
137
- };
138
-
139
- // Check file exists
140
- if (!existsSync(fullPath)) {
141
- result.valid = false;
142
- result.errors.push(`File not found: ${agentRelPath}`);
143
- return result;
144
- }
145
-
146
- let content;
147
- try {
148
- content = readFileSync(fullPath, 'utf8');
149
- } catch (err) {
150
- result.valid = false;
151
- result.errors.push(`Cannot read file: ${err.message}`);
152
- return result;
153
- }
154
-
155
- // Check non-empty
156
- if (content.trim().length === 0) {
157
- result.valid = false;
158
- result.errors.push('File is empty');
159
- return result;
160
- }
161
-
162
- // Check has a title heading
163
- if (!content.match(/^#\s+.+/m)) {
164
- result.warnings.push('No title heading found');
165
- }
166
-
167
- // Parse identity
168
- const identity = parseAgentIdentity(content);
169
- result.identity = identity;
170
-
171
- // Check Identity section exists
172
- if (!identity.role && agentName !== 'chati') {
173
- result.warnings.push('No Role found in Identity section');
174
- }
175
-
176
- // Check Category for non-orchestrator agents
177
- if (agentName !== 'chati' && !identity.category) {
178
- result.warnings.push('No Category found in Identity section');
179
- }
180
-
181
- // Check Mission section
182
- if (!content.toLowerCase().includes('## mission') && !content.toLowerCase().includes('## on activation')) {
183
- result.warnings.push('No Mission or On Activation section found');
184
- }
185
-
186
- // Completeness check
187
- result.completeness = getAgentCompleteness(content);
188
-
189
- // Low completeness is a warning
190
- if (result.completeness.score < 50) {
191
- result.warnings.push(`Low completeness score: ${result.completeness.score}%`);
192
- }
193
-
194
- // Validation result
195
- if (result.errors.length > 0) {
196
- result.valid = false;
197
- }
198
-
199
- return result;
200
- }
201
-
202
- /**
203
- * Validate all expected agent files.
204
- * @param {string} frameworkDir - Path to the framework directory.
205
- * @returns {object} Full validation report.
206
- */
207
- export function validateAllAgents(frameworkDir) {
208
- const report = {
209
- valid: true,
210
- agents: [],
211
- missing: [],
212
- totalExpected: ALL_AGENT_NAMES.length + 1, // +1 for orchestrator
213
- totalFound: 0,
214
- totalValid: 0,
215
- errors: [],
216
- warnings: [],
217
- };
218
-
219
- if (!existsSync(frameworkDir)) {
220
- report.valid = false;
221
- report.errors.push(`Framework directory not found: ${frameworkDir}`);
222
- return report;
223
- }
224
-
225
- // Validate each expected agent
226
- for (const [category, agents] of Object.entries(EXPECTED_AGENTS)) {
227
- for (const agent of agents) {
228
- const relPath = join('agents', category, `${agent}.md`);
229
- const fullPath = join(frameworkDir, relPath);
230
-
231
- if (!existsSync(fullPath)) {
232
- report.missing.push(agent);
233
- report.agents.push({
234
- name: agent,
235
- path: relPath,
236
- valid: false,
237
- errors: ['File not found'],
238
- warnings: [],
239
- completeness: null,
240
- identity: null,
241
- });
242
- continue;
243
- }
244
-
245
- report.totalFound++;
246
- const result = validateAgent(frameworkDir, relPath);
247
- report.agents.push(result);
248
- if (result.valid) report.totalValid++;
249
- }
250
- }
251
-
252
- // Validate orchestrator
253
- const orchRelPath = join('orchestrator', 'chati.md');
254
- const orchFullPath = join(frameworkDir, orchRelPath);
255
-
256
- if (!existsSync(orchFullPath)) {
257
- report.missing.push('orchestrator');
258
- report.agents.push({
259
- name: 'orchestrator',
260
- path: orchRelPath,
261
- valid: false,
262
- errors: ['File not found'],
263
- warnings: [],
264
- completeness: null,
265
- identity: null,
266
- });
267
- } else {
268
- report.totalFound++;
269
- const orchResult = validateAgent(frameworkDir, orchRelPath);
270
- orchResult.name = 'orchestrator';
271
- report.agents.push(orchResult);
272
- if (orchResult.valid) report.totalValid++;
273
- }
274
-
275
- // Cross-reference with entity-registry
276
- const regPath = join(frameworkDir, 'data', 'entity-registry.yaml');
277
- if (existsSync(regPath)) {
278
- try {
279
- const registry = yaml.load(readFileSync(regPath, 'utf8'));
280
- const registeredAgents = registry?.entities?.agents ? Object.keys(registry.entities.agents) : [];
281
-
282
- for (const agent of ALL_AGENT_NAMES) {
283
- if (!registeredAgents.includes(agent)) {
284
- report.warnings.push(`Agent '${agent}' not found in entity-registry.yaml`);
285
- }
286
- }
287
-
288
- if (!registeredAgents.includes('orchestrator')) {
289
- report.warnings.push("Orchestrator not found in entity-registry.yaml");
290
- }
291
- } catch {
292
- report.warnings.push('Could not cross-reference with entity-registry.yaml');
293
- }
294
- }
295
-
296
- // Overall validity
297
- if (report.missing.length > 0) {
298
- report.valid = false;
299
- report.errors.push(`Missing ${report.missing.length} agent(s): ${report.missing.join(', ')}`);
300
- }
301
-
302
- return report;
303
- }
304
-
305
- /**
306
- * Format agent validation report as a human-readable string.
307
- * @param {object} report - Report from validateAllAgents.
308
- * @returns {string}
309
- */
310
- export function formatAgentReport(report) {
311
- const lines = [
312
- '=== Agent Validation Report ===',
313
- `Status: ${report.valid ? '[PASS]' : '[FAIL]'}`,
314
- `Agents: ${report.totalFound}/${report.totalExpected} found, ${report.totalValid} valid`,
315
- '',
316
- ];
317
-
318
- if (report.missing.length > 0) {
319
- lines.push(`Missing: ${report.missing.join(', ')}`);
320
- lines.push('');
321
- }
322
-
323
- for (const agent of report.agents) {
324
- const symbol = agent.valid ? '[PASS]' : '[FAIL]';
325
- const completeness = agent.completeness ? ` (${agent.completeness.score}%)` : '';
326
- lines.push(` ${symbol} ${agent.name}${completeness}`);
327
-
328
- for (const err of agent.errors) {
329
- lines.push(` ERROR: ${err}`);
330
- }
331
- for (const warn of agent.warnings) {
332
- lines.push(` WARN: ${warn}`);
333
- }
334
- }
335
-
336
- if (report.warnings.length > 0) {
337
- lines.push('');
338
- lines.push('Warnings:');
339
- for (const warn of report.warnings) {
340
- lines.push(` - ${warn}`);
341
- }
342
- }
343
-
344
- lines.push('');
345
- lines.push('=== End Report ===');
346
- return lines.join('\n');
347
- }
348
-
349
- // ---------------------------------------------------------------------------
350
- // CLI entrypoint
351
- // ---------------------------------------------------------------------------
352
-
353
- const isMainModule = process.argv[1] && (
354
- process.argv[1].endsWith('validate-agents.js') ||
355
- process.argv[1].endsWith('validate-agents')
356
- );
357
-
358
- if (isMainModule) {
359
- const frameworkDir = process.argv[2] || join(process.cwd(), 'chati.dev');
360
-
361
- console.log(`Validating agents in: ${frameworkDir}`);
362
- const report = validateAllAgents(frameworkDir);
363
- console.log(formatAgentReport(report));
364
-
365
- if (!report.valid) {
366
- process.exit(1);
367
- }
368
- }