chati-dev 4.2.2 → 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 +7 -6
- package/framework/constitution.md +127 -44
- 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 +24 -5
- package/framework/hooks/license-guard.js +62 -27
- package/framework/hooks/mode-governance.js +13 -2
- package/framework/hooks/model-governance.js +1 -0
- package/framework/hooks/post-dev.js +207 -0
- package/framework/hooks/prism-engine.js +274 -105
- package/framework/hooks/reasoning-escalator.js +371 -0
- package/framework/hooks/reference-trigger.js +117 -0
- package/framework/hooks/session-digest.js +50 -1
- package/framework/hooks/settings.json +32 -1
- package/framework/hooks/style-guard.js +25 -6
- package/framework/hooks/team-quality-gate.js +19 -12
- package/framework/hooks/undercover-guard.js +4 -2
- 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 +294 -94
- 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 +27 -7
- package/src/config/context-file-generator.js +41 -21
- package/src/config/framework-adapter.js +1 -0
- package/src/config/gemini-hooks-generator.js +19 -7
- 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 +422 -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 +46 -29
- 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 +1869 -71
- 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 -505
- 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,77 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Doctor check: Agent definition files.
|
|
3
|
-
*
|
|
4
|
-
* Validates that all primary agent definition files exist with valid structure.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { readFileSync, existsSync } from 'fs';
|
|
8
|
-
import { join } from 'path';
|
|
9
|
-
|
|
10
|
-
const EXPECTED_AGENTS = {
|
|
11
|
-
'discover/greenfield-wu.md': 'greenfield-wu',
|
|
12
|
-
'discover/brownfield-wu.md': 'brownfield-wu',
|
|
13
|
-
'discover/brief.md': 'brief',
|
|
14
|
-
'plan/detail.md': 'detail',
|
|
15
|
-
'plan/architect.md': 'architect',
|
|
16
|
-
'plan/ux.md': 'ux',
|
|
17
|
-
'plan/phases.md': 'phases',
|
|
18
|
-
'plan/tasks.md': 'tasks',
|
|
19
|
-
'quality/qa-planning.md': 'qa-planning',
|
|
20
|
-
'quality/qa-implementation.md': 'qa-implementation',
|
|
21
|
-
'build/dev.md': 'dev',
|
|
22
|
-
'deploy/devops.md': 'devops',
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Run agents check.
|
|
27
|
-
*
|
|
28
|
-
* @param {string} frameworkDir - Path to framework directory
|
|
29
|
-
* @returns {{ pass: boolean, details: string, severity: string, fixable: boolean, fixId: string|null }}
|
|
30
|
-
*/
|
|
31
|
-
export function checkAgents(frameworkDir) {
|
|
32
|
-
const agentsDir = join(frameworkDir, 'agents');
|
|
33
|
-
const orchestratorDir = join(frameworkDir, 'orchestrator');
|
|
34
|
-
|
|
35
|
-
const missing = [];
|
|
36
|
-
const invalid = [];
|
|
37
|
-
|
|
38
|
-
for (const [relPath, name] of Object.entries(EXPECTED_AGENTS)) {
|
|
39
|
-
const fullPath = join(agentsDir, relPath);
|
|
40
|
-
if (!existsSync(fullPath)) {
|
|
41
|
-
missing.push(name);
|
|
42
|
-
continue;
|
|
43
|
-
}
|
|
44
|
-
try {
|
|
45
|
-
const content = readFileSync(fullPath, 'utf8');
|
|
46
|
-
if (!content.includes('## Identity') && !content.includes('## Mission')) {
|
|
47
|
-
invalid.push(name);
|
|
48
|
-
}
|
|
49
|
-
} catch {
|
|
50
|
-
invalid.push(name);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Check orchestrator
|
|
55
|
-
const orchPath = join(orchestratorDir, 'chati.md');
|
|
56
|
-
if (!existsSync(orchPath)) {
|
|
57
|
-
missing.push('orchestrator');
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const total = Object.keys(EXPECTED_AGENTS).length + 1;
|
|
61
|
-
const found = total - missing.length;
|
|
62
|
-
|
|
63
|
-
if (missing.length > 0 || invalid.length > 0) {
|
|
64
|
-
const issues = [];
|
|
65
|
-
if (missing.length) issues.push(`missing: ${missing.join(', ')}`);
|
|
66
|
-
if (invalid.length) issues.push(`invalid: ${invalid.join(', ')}`);
|
|
67
|
-
return {
|
|
68
|
-
pass: false,
|
|
69
|
-
details: `${found}/${total} agents found; ${issues.join('; ')}`,
|
|
70
|
-
severity: missing.length > 0 ? 'critical' : 'warning',
|
|
71
|
-
fixable: false,
|
|
72
|
-
fixId: null,
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return { pass: true, details: `${found}/${total} agents present`, severity: 'info', fixable: false, fixId: null };
|
|
77
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Doctor check: Constitution integrity.
|
|
3
|
-
*
|
|
4
|
-
* Validates constitution.md exists and contains the expected number of articles.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { readFileSync, existsSync } from 'fs';
|
|
8
|
-
import { join } from 'path';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Run constitution integrity check.
|
|
12
|
-
*
|
|
13
|
-
* @param {string} frameworkDir - Path to framework directory
|
|
14
|
-
* @returns {{ pass: boolean, details: string, severity: string, fixable: boolean, fixId: string|null }}
|
|
15
|
-
*/
|
|
16
|
-
export function checkConstitution(frameworkDir) {
|
|
17
|
-
const constPath = join(frameworkDir, 'constitution.md');
|
|
18
|
-
if (!existsSync(constPath)) {
|
|
19
|
-
return { pass: false, details: 'constitution.md not found', severity: 'critical', fixable: false, fixId: null };
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
try {
|
|
23
|
-
const content = readFileSync(constPath, 'utf8');
|
|
24
|
-
const articleMatches = content.match(/^## Article [IVXLCDM]+/gm) || [];
|
|
25
|
-
const articleCount = articleMatches.length;
|
|
26
|
-
|
|
27
|
-
if (articleCount < 10) {
|
|
28
|
-
return {
|
|
29
|
-
pass: false,
|
|
30
|
-
details: `Only ${articleCount} articles found (expected 10+)`,
|
|
31
|
-
severity: 'warning',
|
|
32
|
-
fixable: false,
|
|
33
|
-
fixId: null,
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return { pass: true, details: `${articleCount} articles found`, severity: 'info', fixable: false, fixId: null };
|
|
38
|
-
} catch (err) {
|
|
39
|
-
return { pass: false, details: `Failed to read: ${err.message}`, severity: 'critical', fixable: false, fixId: null };
|
|
40
|
-
}
|
|
41
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Doctor check: Domain-Agent alignment.
|
|
3
|
-
*
|
|
4
|
-
* Validates that each agent domain YAML has a corresponding agent .md file.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { existsSync, readdirSync } from 'fs';
|
|
8
|
-
import { join, basename } from 'path';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Run domain-agent alignment check.
|
|
12
|
-
*
|
|
13
|
-
* @param {string} frameworkDir - Path to framework directory
|
|
14
|
-
* @returns {{ pass: boolean, details: string, severity: string, fixable: boolean, fixId: string|null }}
|
|
15
|
-
*/
|
|
16
|
-
export function checkDomainAlignment(frameworkDir) {
|
|
17
|
-
const domainsDir = join(frameworkDir, 'domains', 'agents');
|
|
18
|
-
if (!existsSync(domainsDir)) {
|
|
19
|
-
return { pass: false, details: 'domains/agents/ directory not found', severity: 'warning', fixable: false, fixId: null };
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const domainFiles = readdirSync(domainsDir).filter(f => f.endsWith('.yaml'));
|
|
23
|
-
const mismatches = [];
|
|
24
|
-
|
|
25
|
-
for (const file of domainFiles) {
|
|
26
|
-
const agentName = basename(file, '.yaml');
|
|
27
|
-
|
|
28
|
-
// Orchestrator has a different path
|
|
29
|
-
if (agentName === 'orchestrator') {
|
|
30
|
-
if (!existsSync(join(frameworkDir, 'orchestrator', 'chati.md'))) {
|
|
31
|
-
mismatches.push('orchestrator');
|
|
32
|
-
}
|
|
33
|
-
continue;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Other agents: check all category dirs
|
|
37
|
-
const agentDirs = ['agents/discover', 'agents/plan', 'agents/quality', 'agents/build', 'agents/deploy'];
|
|
38
|
-
const found = agentDirs.some(dir =>
|
|
39
|
-
existsSync(join(frameworkDir, dir, `${agentName}.md`))
|
|
40
|
-
);
|
|
41
|
-
|
|
42
|
-
if (!found) {
|
|
43
|
-
mismatches.push(agentName);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (mismatches.length > 0) {
|
|
48
|
-
return {
|
|
49
|
-
pass: false,
|
|
50
|
-
details: `Mismatched agents: ${mismatches.join(', ')}`,
|
|
51
|
-
severity: 'warning',
|
|
52
|
-
fixable: false,
|
|
53
|
-
fixId: null,
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return { pass: true, details: `${domainFiles.length} domain-agent pairs aligned`, severity: 'info', fixable: false, fixId: null };
|
|
58
|
-
}
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Doctor check: PRISM Layer integrity.
|
|
3
|
-
*
|
|
4
|
-
* Validates that all 6 PRISM layers (L0-L5) have the required
|
|
5
|
-
* domain files and configuration in place.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { existsSync, readdirSync, readFileSync } from 'fs';
|
|
9
|
-
import { join } from 'path';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Run PRISM layers integrity check.
|
|
13
|
-
*
|
|
14
|
-
* @param {string} frameworkDir - Path to framework directory
|
|
15
|
-
* @returns {{ pass: boolean, details: string, severity: string, fixable: boolean, fixId: string|null }}
|
|
16
|
-
*/
|
|
17
|
-
export function checkPrismLayers(frameworkDir) {
|
|
18
|
-
const domainsDir = join(frameworkDir, 'domains');
|
|
19
|
-
if (!existsSync(domainsDir)) {
|
|
20
|
-
return { pass: false, details: 'domains/ directory not found', severity: 'critical', fixable: false, fixId: null };
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const issues = [];
|
|
24
|
-
|
|
25
|
-
// L0: Constitution domain
|
|
26
|
-
const constitutionDomain = join(domainsDir, 'constitution.yaml');
|
|
27
|
-
if (!existsSync(constitutionDomain)) {
|
|
28
|
-
issues.push('L0: constitution.yaml missing');
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// L1: Global domain
|
|
32
|
-
const globalDomain = join(domainsDir, 'global.yaml');
|
|
33
|
-
if (!existsSync(globalDomain)) {
|
|
34
|
-
issues.push('L1: global.yaml missing');
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// L2: Agent domains
|
|
38
|
-
const agentsDir = join(domainsDir, 'agents');
|
|
39
|
-
if (!existsSync(agentsDir)) {
|
|
40
|
-
issues.push('L2: agents/ directory missing');
|
|
41
|
-
} else {
|
|
42
|
-
const agentDomains = readdirSync(agentsDir).filter(f => f.endsWith('.yaml'));
|
|
43
|
-
if (agentDomains.length < 12) {
|
|
44
|
-
issues.push(`L2: only ${agentDomains.length}/12 agent domains found`);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// L3: Workflow domains
|
|
49
|
-
const workflowsDir = join(domainsDir, 'workflows');
|
|
50
|
-
if (!existsSync(workflowsDir)) {
|
|
51
|
-
issues.push('L3: workflows/ directory missing');
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// L4: Task context (checked via task domain files or inline)
|
|
55
|
-
// L4 is dynamic (loaded from handoff data), so we check that the task
|
|
56
|
-
// processing layer module exists
|
|
57
|
-
const l4Module = join(frameworkDir, '..', 'src', 'context', 'layers', 'l4-task.js');
|
|
58
|
-
if (!existsSync(l4Module)) {
|
|
59
|
-
issues.push('L4: l4-task.js module missing');
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// L5: Keywords domains
|
|
63
|
-
const keywordsDir = join(domainsDir, 'keywords');
|
|
64
|
-
if (!existsSync(keywordsDir)) {
|
|
65
|
-
issues.push('L5: keywords/ directory missing');
|
|
66
|
-
} else {
|
|
67
|
-
const keywordFiles = readdirSync(keywordsDir).filter(f => f.endsWith('.yaml'));
|
|
68
|
-
if (keywordFiles.length === 0) {
|
|
69
|
-
issues.push('L5: no keyword domain files found');
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if (issues.length > 0) {
|
|
74
|
-
return {
|
|
75
|
-
pass: false,
|
|
76
|
-
details: issues.join('; '),
|
|
77
|
-
severity: issues.some(i => i.includes('L0') || i.includes('L1')) ? 'critical' : 'warning',
|
|
78
|
-
fixable: false,
|
|
79
|
-
fixId: null,
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return { pass: true, details: 'All 6 PRISM layers (L0-L5) validated', severity: 'info', fixable: false, fixId: null };
|
|
84
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Doctor check: Entity Registry integrity.
|
|
3
|
-
*
|
|
4
|
-
* Validates entity-registry.yaml exists, parses correctly,
|
|
5
|
-
* entity count matches metadata, and all entity paths exist.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { readFileSync, existsSync } from 'fs';
|
|
9
|
-
import { join } from 'path';
|
|
10
|
-
import yaml from 'js-yaml';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Run entity registry integrity check.
|
|
14
|
-
*
|
|
15
|
-
* @param {string} frameworkDir - Path to framework directory
|
|
16
|
-
* @returns {{ pass: boolean, details: string, severity: string, fixable: boolean, fixId: string|null }}
|
|
17
|
-
*/
|
|
18
|
-
export function checkRegistry(frameworkDir) {
|
|
19
|
-
const regPath = join(frameworkDir, 'data', 'entity-registry.yaml');
|
|
20
|
-
if (!existsSync(regPath)) {
|
|
21
|
-
return { pass: false, details: 'entity-registry.yaml not found', severity: 'critical', fixable: false, fixId: null };
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
try {
|
|
25
|
-
const content = readFileSync(regPath, 'utf8');
|
|
26
|
-
const registry = yaml.load(content);
|
|
27
|
-
|
|
28
|
-
if (!registry || !registry.entities) {
|
|
29
|
-
return { pass: false, details: 'entity-registry.yaml has no entities section', severity: 'critical', fixable: false, fixId: null };
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// Count all entities across all categories
|
|
33
|
-
let entityCount = 0;
|
|
34
|
-
for (const category of Object.values(registry.entities)) {
|
|
35
|
-
if (typeof category === 'object' && category !== null) {
|
|
36
|
-
entityCount += Object.keys(category).length;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const declaredCount = registry.metadata?.entity_count || 0;
|
|
41
|
-
if (declaredCount > 0 && entityCount !== declaredCount) {
|
|
42
|
-
return {
|
|
43
|
-
pass: false,
|
|
44
|
-
details: `Entity count mismatch: declared ${declaredCount}, actual ${entityCount}`,
|
|
45
|
-
severity: 'warning',
|
|
46
|
-
fixable: true,
|
|
47
|
-
fixId: 'registry-count',
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return { pass: true, details: `${entityCount} entities registered`, severity: 'info', fixable: false, fixId: null };
|
|
52
|
-
} catch (err) {
|
|
53
|
-
return { pass: false, details: `Failed to parse: ${err.message}`, severity: 'critical', fixable: false, fixId: null };
|
|
54
|
-
}
|
|
55
|
-
}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Doctor check: JSON Schema validation.
|
|
3
|
-
*
|
|
4
|
-
* Validates that all expected schema files exist and contain valid JSON.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { readFileSync, existsSync, readdirSync } from 'fs';
|
|
8
|
-
import { join } from 'path';
|
|
9
|
-
|
|
10
|
-
const EXPECTED_SCHEMAS = [
|
|
11
|
-
'session.schema.json',
|
|
12
|
-
'config.schema.json',
|
|
13
|
-
'context.schema.json',
|
|
14
|
-
'memory.schema.json',
|
|
15
|
-
'task.schema.json',
|
|
16
|
-
];
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Run schema validation check.
|
|
20
|
-
*
|
|
21
|
-
* @param {string} frameworkDir - Path to framework directory
|
|
22
|
-
* @returns {{ pass: boolean, details: string, severity: string, fixable: boolean, fixId: string|null }}
|
|
23
|
-
*/
|
|
24
|
-
export function checkSchemas(frameworkDir) {
|
|
25
|
-
const schemasDir = join(frameworkDir, 'schemas');
|
|
26
|
-
if (!existsSync(schemasDir)) {
|
|
27
|
-
return { pass: false, details: 'schemas/ directory not found', severity: 'critical', fixable: false, fixId: null };
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const missing = [];
|
|
31
|
-
const invalid = [];
|
|
32
|
-
|
|
33
|
-
for (const schema of EXPECTED_SCHEMAS) {
|
|
34
|
-
const schemaPath = join(schemasDir, schema);
|
|
35
|
-
if (!existsSync(schemaPath)) {
|
|
36
|
-
missing.push(schema);
|
|
37
|
-
continue;
|
|
38
|
-
}
|
|
39
|
-
try {
|
|
40
|
-
JSON.parse(readFileSync(schemaPath, 'utf8'));
|
|
41
|
-
} catch {
|
|
42
|
-
invalid.push(schema);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (missing.length > 0 || invalid.length > 0) {
|
|
47
|
-
const issues = [];
|
|
48
|
-
if (missing.length) issues.push(`missing: ${missing.join(', ')}`);
|
|
49
|
-
if (invalid.length) issues.push(`invalid JSON: ${invalid.join(', ')}`);
|
|
50
|
-
return {
|
|
51
|
-
pass: false,
|
|
52
|
-
details: issues.join('; '),
|
|
53
|
-
severity: missing.length > 0 ? 'critical' : 'warning',
|
|
54
|
-
fixable: false,
|
|
55
|
-
fixId: null,
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const actualSchemas = readdirSync(schemasDir).filter(f => f.endsWith('.json'));
|
|
60
|
-
return { pass: true, details: `${actualSchemas.length} schemas valid`, severity: 'info', fixable: false, fixId: null };
|
|
61
|
-
}
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Doctor fix: Broken path references.
|
|
3
|
-
*
|
|
4
|
-
* Scans entity-registry.yaml for broken path references and
|
|
5
|
-
* attempts to locate the correct paths.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { readFileSync, writeFileSync, existsSync, readdirSync } from 'fs';
|
|
9
|
-
import { join, basename } from 'path';
|
|
10
|
-
import yaml from 'js-yaml';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Fix broken path references in entity-registry.yaml.
|
|
14
|
-
*
|
|
15
|
-
* @param {string} frameworkDir - Path to framework directory
|
|
16
|
-
* @returns {{ fixed: boolean, details: string, fixedPaths: string[] }}
|
|
17
|
-
*/
|
|
18
|
-
export function fixBrokenReferences(frameworkDir) {
|
|
19
|
-
const regPath = join(frameworkDir, 'data', 'entity-registry.yaml');
|
|
20
|
-
if (!existsSync(regPath)) {
|
|
21
|
-
return { fixed: false, details: 'entity-registry.yaml not found', fixedPaths: [] };
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
try {
|
|
25
|
-
const content = readFileSync(regPath, 'utf8');
|
|
26
|
-
const registry = yaml.load(content);
|
|
27
|
-
|
|
28
|
-
if (!registry || !registry.entities) {
|
|
29
|
-
return { fixed: false, details: 'No entities section found', fixedPaths: [] };
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const fixedPaths = [];
|
|
33
|
-
let updatedContent = content;
|
|
34
|
-
|
|
35
|
-
for (const category of Object.values(registry.entities)) {
|
|
36
|
-
for (const [name, entity] of Object.entries(category)) {
|
|
37
|
-
if (!entity.path) continue;
|
|
38
|
-
|
|
39
|
-
// Path in registry is relative to project root (e.g., "chati.dev/agents/...")
|
|
40
|
-
const relPath = entity.path.replace(/^chati\.dev\//, '');
|
|
41
|
-
const fullPath = join(frameworkDir, relPath);
|
|
42
|
-
|
|
43
|
-
if (existsSync(fullPath)) continue;
|
|
44
|
-
|
|
45
|
-
// Try to find the file by name
|
|
46
|
-
const fileName = basename(relPath);
|
|
47
|
-
const found = findFile(frameworkDir, fileName);
|
|
48
|
-
|
|
49
|
-
if (found) {
|
|
50
|
-
const newPath = 'chati.dev/' + found;
|
|
51
|
-
updatedContent = updatedContent.replace(
|
|
52
|
-
`path: ${entity.path}`,
|
|
53
|
-
`path: ${newPath}`
|
|
54
|
-
);
|
|
55
|
-
fixedPaths.push(`${name}: ${entity.path} -> ${newPath}`);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (fixedPaths.length === 0) {
|
|
61
|
-
return { fixed: false, details: 'No broken references found', fixedPaths: [] };
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
writeFileSync(regPath, updatedContent, 'utf8');
|
|
65
|
-
return { fixed: true, details: `Fixed ${fixedPaths.length} path reference(s)`, fixedPaths };
|
|
66
|
-
} catch (err) {
|
|
67
|
-
return { fixed: false, details: `Fix failed: ${err.message}`, fixedPaths: [] };
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Search for a file by name within the framework directory.
|
|
73
|
-
*
|
|
74
|
-
* @param {string} dir - Directory to search
|
|
75
|
-
* @param {string} fileName - File name to find
|
|
76
|
-
* @param {string} [prefix=''] - Path prefix for recursion
|
|
77
|
-
* @param {number} [depth=0] - Current depth
|
|
78
|
-
* @returns {string|null} Relative path from frameworkDir or null
|
|
79
|
-
*/
|
|
80
|
-
function findFile(dir, fileName, prefix = '', depth = 0) {
|
|
81
|
-
if (depth > 4) return null;
|
|
82
|
-
|
|
83
|
-
try {
|
|
84
|
-
const entries = readdirSync(dir, { withFileTypes: true });
|
|
85
|
-
for (const entry of entries) {
|
|
86
|
-
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
87
|
-
if (entry.isFile() && entry.name === fileName) {
|
|
88
|
-
return rel;
|
|
89
|
-
}
|
|
90
|
-
if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'node_modules') {
|
|
91
|
-
const found = findFile(join(dir, entry.name), fileName, rel, depth + 1);
|
|
92
|
-
if (found) return found;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
} catch {
|
|
96
|
-
// Permission error or inaccessible directory
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
return null;
|
|
100
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Doctor fix: Registry count correction.
|
|
3
|
-
*
|
|
4
|
-
* Auto-fixes entity_count mismatch in entity-registry.yaml
|
|
5
|
-
* by counting actual entities and updating metadata.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
|
9
|
-
import { join } from 'path';
|
|
10
|
-
import yaml from 'js-yaml';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Fix entity count mismatch in entity-registry.yaml.
|
|
14
|
-
*
|
|
15
|
-
* @param {string} frameworkDir - Path to framework directory
|
|
16
|
-
* @returns {{ fixed: boolean, details: string }}
|
|
17
|
-
*/
|
|
18
|
-
export function fixRegistryCount(frameworkDir) {
|
|
19
|
-
const regPath = join(frameworkDir, 'data', 'entity-registry.yaml');
|
|
20
|
-
if (!existsSync(regPath)) {
|
|
21
|
-
return { fixed: false, details: 'entity-registry.yaml not found' };
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
try {
|
|
25
|
-
const content = readFileSync(regPath, 'utf8');
|
|
26
|
-
const registry = yaml.load(content);
|
|
27
|
-
|
|
28
|
-
if (!registry || !registry.entities) {
|
|
29
|
-
return { fixed: false, details: 'No entities section found' };
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// Count actual entities
|
|
33
|
-
let entityCount = 0;
|
|
34
|
-
for (const category of Object.values(registry.entities)) {
|
|
35
|
-
if (typeof category === 'object' && category !== null) {
|
|
36
|
-
entityCount += Object.keys(category).length;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const declaredCount = registry.metadata?.entity_count || 0;
|
|
41
|
-
if (entityCount === declaredCount) {
|
|
42
|
-
return { fixed: false, details: 'Entity count already correct' };
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// Update the count using regex to preserve YAML formatting
|
|
46
|
-
const updatedContent = content.replace(
|
|
47
|
-
/entity_count:\s*\d+/,
|
|
48
|
-
`entity_count: ${entityCount}`
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
writeFileSync(regPath, updatedContent, 'utf8');
|
|
52
|
-
return { fixed: true, details: `Updated entity_count from ${declaredCount} to ${entityCount}` };
|
|
53
|
-
} catch (err) {
|
|
54
|
-
return { fixed: false, details: `Fix failed: ${err.message}` };
|
|
55
|
-
}
|
|
56
|
-
}
|