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.
- package/README.md +80 -53
- package/bin/chati.js +150 -5
- package/framework/agents/build/dev.md +509 -76
- package/framework/agents/deploy/devops.md +40 -25
- package/framework/agents/discover/brief.md +156 -22
- package/framework/agents/discover/brownfield-wu.md +24 -14
- package/framework/agents/discover/greenfield-wu.md +100 -14
- package/framework/agents/plan/architect-data-engineer.md +6 -6
- package/framework/agents/plan/architect-system.md +46 -12
- package/framework/agents/plan/architect.md +40 -20
- package/framework/agents/plan/detail.md +36 -24
- package/framework/agents/plan/phases.md +36 -26
- package/framework/agents/plan/tasks.md +114 -33
- package/framework/agents/plan/ux-brand-architect.md +240 -8
- package/framework/agents/plan/ux-component-engineer.md +28 -13
- package/framework/agents/plan/ux-researcher.md +7 -6
- package/framework/agents/plan/ux.md +55 -22
- package/framework/agents/quality/qa-implementation.md +143 -74
- package/framework/agents/quality/qa-planning.md +115 -42
- package/framework/agents/quality/qa-visual.md +439 -0
- package/framework/agents/shared/visualizer.md +128 -0
- package/framework/config.yaml +8 -7
- package/framework/constitution.md +127 -43
- package/framework/context/governance.md +12 -7
- package/framework/context/quality.md +6 -5
- package/framework/context/root.md +6 -6
- package/framework/data/entity-registry.yaml +377 -4
- package/framework/data/model-limits.json +19 -0
- package/framework/domains/agents/qa-visual.yaml +74 -0
- package/framework/domains/constitution.yaml +46 -2
- package/framework/domains/workflows/greenfield-fullstack.yaml +2 -2
- package/framework/hooks/advance-trigger.js +131 -0
- package/framework/hooks/brief-validator.js +83 -0
- package/framework/hooks/constitution-guard.js +91 -36
- package/framework/hooks/license-guard.js +129 -190
- package/framework/hooks/mode-governance.js +68 -16
- package/framework/hooks/model-governance.js +19 -8
- package/framework/hooks/package.json +3 -0
- package/framework/hooks/post-dev.js +207 -0
- package/framework/hooks/prism-engine.js +288 -105
- package/framework/hooks/read-protection.js +37 -9
- package/framework/hooks/reasoning-escalator.js +371 -0
- package/framework/hooks/reference-trigger.js +117 -0
- package/framework/hooks/session-digest.js +94 -20
- package/framework/hooks/settings.json +32 -1
- package/framework/hooks/style-guard.js +52 -13
- package/framework/hooks/team-quality-gate.js +58 -25
- package/framework/hooks/undercover-guard.js +34 -13
- package/framework/i18n/en.yaml +3 -3
- package/framework/i18n/es.yaml +3 -3
- package/framework/i18n/fr.yaml +3 -3
- package/framework/i18n/pt.yaml +3 -3
- package/framework/intelligence/context-engine.md +4 -5
- package/framework/intelligence/decision-engine.md +1 -1
- package/framework/intelligence/hooks-performance.md +3 -3
- package/framework/migrations/v1.0-to-v1.1.yaml +1 -1
- package/framework/migrations/v1.4-to-v2.0.yaml +11 -11
- package/framework/migrations/v4.0-to-v4.1.yaml +2 -2
- package/framework/migrations/v4.2-to-v4.3.yaml +29 -0
- package/framework/orchestrator/chati-router.js +387 -0
- package/framework/orchestrator/chati-update.md +40 -40
- package/framework/orchestrator/chati.md +318 -115
- package/framework/scaffold/motion-premium/README.md +89 -0
- package/framework/scaffold/motion-premium/app/globals.css.template +400 -0
- package/framework/scaffold/motion-premium/app/layout.tsx.template +110 -0
- package/framework/scaffold/motion-premium/components/animation/BackgroundCrossfadeProvider.tsx.template +170 -0
- package/framework/scaffold/motion-premium/components/animation/LenisProvider.tsx.template +49 -0
- package/framework/scaffold/motion-premium/components/animation/PageTransitionWrapper.tsx.template +83 -0
- package/framework/scaffold/motion-premium/components/animation/Preloader.tsx.template +171 -0
- package/framework/scaffold/motion-premium/components/ui/Container.tsx.template +69 -0
- package/framework/scaffold/motion-premium/components/ui/PageSection.tsx.template +74 -0
- package/framework/scaffold/motion-premium/lib/animations/gsap.ts.template +112 -0
- package/framework/scaffold/motion-premium/lib/animations/refreshCoordinator.ts.template +75 -0
- package/framework/scaffold/motion-premium/lib/animations/tokens.ts.template +119 -0
- package/framework/scaffold/motion-premium/lib/animations/useGsapContext.ts.template +92 -0
- package/framework/scaffold/motion-premium/lib/animations/useScrollSnapStepper.ts.template +265 -0
- package/framework/scaffold/motion-premium/lib/animations/useSmoothScroll.ts.template +67 -0
- package/framework/scaffold/motion-premium/lib/brand.ts.template +43 -0
- package/framework/scaffold/motion-premium/scaffold.yaml +174 -0
- package/framework/scaffold/motion-premium-3d/README.md +80 -0
- package/framework/scaffold/motion-premium-3d/app/(3d)/scroll-demo/ScrollDemoCanvas.tsx.template +81 -0
- package/framework/scaffold/motion-premium-3d/app/(3d)/scroll-demo/ScrollDemoClient.tsx.template +75 -0
- package/framework/scaffold/motion-premium-3d/app/(3d)/scroll-demo/page.tsx.template +26 -0
- package/framework/scaffold/motion-premium-3d/components/3d/CameraRig.tsx.template +100 -0
- package/framework/scaffold/motion-premium-3d/components/3d/CanvasProvider.tsx.template +85 -0
- package/framework/scaffold/motion-premium-3d/components/3d/InvalidateOnScroll.tsx.template +51 -0
- package/framework/scaffold/motion-premium-3d/components/3d/MeshCrossfade.tsx.template +79 -0
- package/framework/scaffold/motion-premium-3d/components/3d/ScrollCrossfade.tsx.template +88 -0
- package/framework/scaffold/motion-premium-3d/components/3d/ScrollScene.tsx.template +121 -0
- package/framework/scaffold/motion-premium-3d/components/webgl/SceneFallback.tsx.template +65 -0
- package/framework/scaffold/motion-premium-3d/components/webgl/WebGLContext.tsx.template +68 -0
- package/framework/scaffold/motion-premium-3d/lib/webgl/detect.ts.template +69 -0
- package/framework/scaffold/motion-premium-3d/scaffold.yaml +133 -0
- package/framework/schemas/session.schema.json +109 -21
- package/framework/scripts/reference-capture.js +430 -0
- package/framework/scripts/visual-qa.js +674 -0
- package/framework/tasks/orchestrator-handoff.md +1 -1
- package/framework/tasks/orchestrator-resume.md +1 -1
- package/framework/tasks/orchestrator-route.md +1 -1
- package/framework/tasks/orchestrator-status.md +3 -3
- package/framework/tasks/qa-planning-gate-define.md +1 -1
- package/framework/templates/brandbook-html-tmpl.md +1 -1
- package/framework/templates/brandbook-tmpl.yaml +1 -1
- package/framework/templates/component-spec-tmpl.yaml +1 -1
- package/framework/templates/design-token-tmpl.yaml +1 -1
- package/framework/templates/icon-system-tmpl.yaml +1 -1
- package/framework/templates/team-planning-tasks.yaml +6 -5
- package/framework/workflows/brownfield-discovery.yaml +2 -2
- package/framework/workflows/brownfield-fullstack.yaml +15 -11
- package/framework/workflows/brownfield-service.yaml +14 -10
- package/framework/workflows/brownfield-ui.yaml +15 -11
- package/framework/workflows/greenfield-fullstack.yaml +16 -13
- package/framework/workflows/quick-flow.yaml +3 -3
- package/framework/workflows/standard-flow.yaml +12 -9
- package/package.json +10 -5
- package/src/autonomy/autonomous-gate.js +1 -0
- package/src/autonomy/build-state.js +1 -2
- package/src/autonomy/progress-reporter.js +1 -1
- package/src/config/agent-customizer.js +11 -3
- package/src/config/claude-settings-generator.js +226 -0
- package/src/config/context-file-generator.js +41 -21
- package/src/config/framework-adapter.js +1 -0
- package/src/config/gemini-hooks-generator.js +76 -6
- package/src/config/mcp-configs.js +1 -0
- package/src/context/layers/l1-global.js +2 -1
- package/src/dashboard/data-reader.js +4 -3
- package/src/dashboard/layout.js +2 -1
- package/src/decision/analyzer.js +6 -30
- package/src/decision/engine.js +4 -28
- package/src/decision/registry-healer.js +3 -2
- package/src/decision/registry-updater.js +23 -14
- package/src/extensions/loader.js +2 -8
- package/src/gates/g1-planning-complete.js +2 -1
- package/src/gates/g2-qa-planning.js +2 -1
- package/src/gates/g3-implementation.js +2 -1
- package/src/gates/g4-qa-implementation.js +3 -2
- package/src/gates/g5-deploy-ready.js +2 -1
- package/src/health/engine.js +4 -3
- package/src/installer/core.js +557 -81
- package/src/installer/preflight.js +131 -0
- package/src/installer/provider-overlay.js +3 -3
- package/src/installer/scaffold-applier.js +358 -0
- package/src/installer/templates.js +52 -31
- package/src/installer/validator.js +17 -12
- package/src/intelligence/registry-manager.js +22 -29
- package/src/intelligence/timeline.js +11 -6
- package/src/license/commands.js +1 -1
- package/src/license/wait.js +102 -0
- package/src/memory/agent-memory.js +81 -0
- package/src/memory/dream.js +32 -1
- package/src/merger/replace-merger.js +28 -15
- package/src/orchestrator/agent-selector.js +2 -1
- package/src/orchestrator/cli.js +1908 -80
- package/src/orchestrator/doctor.js +270 -0
- package/src/orchestrator/handoff-engine.js +4 -3
- package/src/orchestrator/index.js +2 -0
- package/src/orchestrator/pipeline-manager.js +306 -15
- package/src/orchestrator/session-manager.js +331 -6
- package/src/tasks/handoff.js +3 -2
- package/src/telemetry/config.js +4 -3
- package/src/telemetry/schema.js +1 -0
- package/src/terminal/collector.js +3 -2
- package/src/terminal/index.js +1 -2
- package/src/terminal/isolation.js +52 -18
- package/src/terminal/prompt-builder.js +42 -25
- package/src/terminal/run-parallel.js +1 -1
- package/src/terminal/run-team.js +3 -3
- package/src/terminal/team-task-list.js +43 -4
- package/src/upgrade/backup.js +3 -2
- package/src/upgrade/checker.js +3 -2
- package/src/upgrade/migrator.js +65 -7
- package/src/upgrade/tracked-files-detector.js +86 -0
- package/src/upgrade/user-messages.js +94 -0
- package/src/utils/config-parser.js +2 -1
- package/src/utils/feature-flags.js +2 -1
- package/src/utils/flatten-entities.js +69 -0
- package/src/utils/framework-dir.js +16 -0
- package/src/utils/model-id.js +85 -0
- package/src/utils/provider-limits.js +84 -23
- package/src/utils/schema-validator.js +1 -1
- package/src/wizard/i18n.js +5 -4
- package/src/wizard/index.js +14 -0
- package/assets/logo - c/303/263pia.png +0 -0
- package/assets/logo.svg +0 -42
- package/assets/logo2.png +0 -0
- package/assets/social-preview.png +0 -0
- package/scripts/bundle-framework.js +0 -69
- package/scripts/changelog-generator.js +0 -222
- package/scripts/codebase-mapper.js +0 -728
- package/scripts/commit-message-generator.js +0 -167
- package/scripts/coverage-analyzer.js +0 -260
- package/scripts/dependency-analyzer.js +0 -280
- package/scripts/doctor/checks/agents.js +0 -77
- package/scripts/doctor/checks/constitution.js +0 -41
- package/scripts/doctor/checks/domain-alignment.js +0 -58
- package/scripts/doctor/checks/prism-layers.js +0 -84
- package/scripts/doctor/checks/registry.js +0 -55
- package/scripts/doctor/checks/schemas.js +0 -61
- package/scripts/doctor/fixes/reference-fix.js +0 -100
- package/scripts/doctor/fixes/registry-fix.js +0 -56
- package/scripts/doctor/index.js +0 -212
- package/scripts/framework-analyzer.js +0 -308
- package/scripts/generate-constitution-domain.js +0 -253
- package/scripts/generate-signing-key.js +0 -33
- package/scripts/health-check.js +0 -481
- package/scripts/ide-sync.js +0 -326
- package/scripts/performance-analyzer.js +0 -325
- package/scripts/plan-tracker.js +0 -278
- package/scripts/populate-entity-registry.js +0 -481
- package/scripts/pr-review.js +0 -317
- package/scripts/rollback-manager.js +0 -310
- package/scripts/semantic-lint.js +0 -328
- package/scripts/sign-manifest.js +0 -53
- package/scripts/stuck-detector.js +0 -343
- package/scripts/test-quality-assessment.js +0 -257
- package/scripts/validate-agents.js +0 -368
- package/scripts/validate-package.js +0 -367
- package/scripts/validate-tasks.js +0 -465
- package/src/autonomy/worktree-manager.js +0 -250
- package/src/intelligence/decision-engine.js +0 -256
- package/src/intelligence/document-sharder.js +0 -221
- 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
|
-
}
|