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
package/src/decision/analyzer.js
CHANGED
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
import { readFileSync, existsSync } from 'fs';
|
|
9
9
|
import { join } from 'path';
|
|
10
10
|
import yaml from 'js-yaml';
|
|
11
|
+
import { resolveFrameworkDir } from '../utils/framework-dir.js';
|
|
12
|
+
import { flattenEntitiesFromRegistry } from '../utils/flatten-entities.js';
|
|
11
13
|
|
|
12
14
|
/**
|
|
13
15
|
* Analyze impact of changing an entity.
|
|
@@ -38,12 +40,12 @@ export function analyzeImpact(projectDir, entityPath) {
|
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
// Load entity details
|
|
41
|
-
const registryPath = join(projectDir,
|
|
43
|
+
const registryPath = join(projectDir, resolveFrameworkDir(projectDir), 'entity-registry.yaml');
|
|
42
44
|
const registry = existsSync(registryPath)
|
|
43
45
|
? yaml.load(readFileSync(registryPath, 'utf8'))
|
|
44
46
|
: { entities: {} };
|
|
45
47
|
|
|
46
|
-
const allEntities =
|
|
48
|
+
const allEntities = flattenEntitiesFromRegistry(registry);
|
|
47
49
|
const entityMap = new Map(allEntities.map(e => [e.path, e]));
|
|
48
50
|
|
|
49
51
|
const affectedEntities = affectedPaths.map(path => {
|
|
@@ -68,7 +70,7 @@ export function analyzeImpact(projectDir, entityPath) {
|
|
|
68
70
|
* @returns {Map<string, string[]>} Map of entityPath -> [dependentPaths]
|
|
69
71
|
*/
|
|
70
72
|
export function buildDependencyGraph(projectDir) {
|
|
71
|
-
const registryPath = join(projectDir,
|
|
73
|
+
const registryPath = join(projectDir, resolveFrameworkDir(projectDir), 'entity-registry.yaml');
|
|
72
74
|
const graph = new Map();
|
|
73
75
|
|
|
74
76
|
if (!existsSync(registryPath)) {
|
|
@@ -76,7 +78,7 @@ export function buildDependencyGraph(projectDir) {
|
|
|
76
78
|
}
|
|
77
79
|
|
|
78
80
|
const registry = yaml.load(readFileSync(registryPath, 'utf8'));
|
|
79
|
-
const entities =
|
|
81
|
+
const entities = flattenEntitiesFromRegistry(registry);
|
|
80
82
|
|
|
81
83
|
// Initialize graph with all entities
|
|
82
84
|
entities.forEach(entity => {
|
|
@@ -287,29 +289,3 @@ function tokenize(text) {
|
|
|
287
289
|
.filter(w => w.length > 2 && !stopwords.has(w));
|
|
288
290
|
}
|
|
289
291
|
|
|
290
|
-
/**
|
|
291
|
-
* Flatten entity registry into array of entities.
|
|
292
|
-
* @private
|
|
293
|
-
* @param {object} registry
|
|
294
|
-
* @returns {object[]}
|
|
295
|
-
*/
|
|
296
|
-
function flattenEntities(registry) {
|
|
297
|
-
const entities = [];
|
|
298
|
-
|
|
299
|
-
if (!registry.entities) {
|
|
300
|
-
return entities;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
Object.entries(registry.entities).forEach(([type, typeEntities]) => {
|
|
304
|
-
if (Array.isArray(typeEntities)) {
|
|
305
|
-
typeEntities.forEach(entity => {
|
|
306
|
-
entities.push({
|
|
307
|
-
...entity,
|
|
308
|
-
type
|
|
309
|
-
});
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
});
|
|
313
|
-
|
|
314
|
-
return entities;
|
|
315
|
-
}
|
package/src/decision/engine.js
CHANGED
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
|
|
13
13
|
import { join } from 'path';
|
|
14
14
|
import yaml from 'js-yaml';
|
|
15
|
+
import { resolveFrameworkDir } from '../utils/framework-dir.js';
|
|
16
|
+
import { flattenEntitiesFromRegistry } from '../utils/flatten-entities.js';
|
|
15
17
|
|
|
16
18
|
/**
|
|
17
19
|
* Analyze a request against existing entities and recommend action.
|
|
@@ -22,7 +24,7 @@ import yaml from 'js-yaml';
|
|
|
22
24
|
* @returns {{ recommendation: 'REUSE'|'ADAPT'|'CREATE', score: number, matches: object[], reasoning: string }}
|
|
23
25
|
*/
|
|
24
26
|
export function analyzeRequest(projectDir, request) {
|
|
25
|
-
const registryPath = join(projectDir,
|
|
27
|
+
const registryPath = join(projectDir, resolveFrameworkDir(projectDir), 'entity-registry.yaml');
|
|
26
28
|
|
|
27
29
|
if (!existsSync(registryPath)) {
|
|
28
30
|
return {
|
|
@@ -34,7 +36,7 @@ export function analyzeRequest(projectDir, request) {
|
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
const registry = yaml.load(readFileSync(registryPath, 'utf8'));
|
|
37
|
-
const entities =
|
|
39
|
+
const entities = flattenEntitiesFromRegistry(registry);
|
|
38
40
|
|
|
39
41
|
// Calculate similarity scores for all entities
|
|
40
42
|
const scoredMatches = entities
|
|
@@ -246,29 +248,3 @@ export function getEngineStats(projectDir) {
|
|
|
246
248
|
return stats;
|
|
247
249
|
}
|
|
248
250
|
|
|
249
|
-
/**
|
|
250
|
-
* Flatten entity registry into array of entities.
|
|
251
|
-
* @private
|
|
252
|
-
* @param {object} registry
|
|
253
|
-
* @returns {object[]}
|
|
254
|
-
*/
|
|
255
|
-
function flattenEntities(registry) {
|
|
256
|
-
const entities = [];
|
|
257
|
-
|
|
258
|
-
if (!registry.entities) {
|
|
259
|
-
return entities;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
Object.entries(registry.entities).forEach(([type, typeEntities]) => {
|
|
263
|
-
if (Array.isArray(typeEntities)) {
|
|
264
|
-
typeEntities.forEach(entity => {
|
|
265
|
-
entities.push({
|
|
266
|
-
...entity,
|
|
267
|
-
type
|
|
268
|
-
});
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
return entities;
|
|
274
|
-
}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { readFileSync, writeFileSync, existsSync, statSync, copyFileSync, mkdirSync } from 'fs';
|
|
9
9
|
import { join, isAbsolute } from 'path';
|
|
10
10
|
import yaml from 'js-yaml';
|
|
11
|
+
import { resolveFrameworkDir } from '../utils/framework-dir.js';
|
|
11
12
|
import { detectNewEntities, detectRemovedEntities, generateEntityMeta } from './registry-updater.js';
|
|
12
13
|
|
|
13
14
|
/**
|
|
@@ -16,7 +17,7 @@ import { detectNewEntities, detectRemovedEntities, generateEntityMeta } from './
|
|
|
16
17
|
* @returns {{ registry: object|null, registryPath: string }}
|
|
17
18
|
*/
|
|
18
19
|
function loadRegistry(projectDir) {
|
|
19
|
-
const registryPath = join(projectDir,
|
|
20
|
+
const registryPath = join(projectDir, resolveFrameworkDir(projectDir), 'entity-registry.yaml');
|
|
20
21
|
if (!existsSync(registryPath)) {
|
|
21
22
|
return { registry: null, registryPath };
|
|
22
23
|
}
|
|
@@ -347,7 +348,7 @@ export function detectCountMismatch(projectDir, preloaded) {
|
|
|
347
348
|
* @returns {{ applied: number, backup: string }}
|
|
348
349
|
*/
|
|
349
350
|
export function applyFixes(projectDir, fixes) {
|
|
350
|
-
const registryPath = join(projectDir,
|
|
351
|
+
const registryPath = join(projectDir, resolveFrameworkDir(projectDir), 'entity-registry.yaml');
|
|
351
352
|
|
|
352
353
|
if (!existsSync(registryPath)) {
|
|
353
354
|
return { applied: 0, backup: null };
|
|
@@ -8,17 +8,26 @@
|
|
|
8
8
|
import { readFileSync, writeFileSync, existsSync, readdirSync, statSync } from 'fs';
|
|
9
9
|
import { join, basename, relative } from 'path';
|
|
10
10
|
import yaml from 'js-yaml';
|
|
11
|
+
import { resolveFrameworkDir } from '../utils/framework-dir.js';
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Build KNOWN_DIRS using resolveFrameworkDir so paths are correct
|
|
15
|
+
* for both chati.dev/ and .chati.dev/ installations.
|
|
16
|
+
* @param {string} projectDir
|
|
17
|
+
* @returns {{ path: string, type: string }[]}
|
|
18
|
+
*/
|
|
19
|
+
function buildKnownDirs(projectDir) {
|
|
20
|
+
const fw = resolveFrameworkDir(projectDir);
|
|
21
|
+
return [
|
|
22
|
+
{ path: `${fw}/agents`, type: 'agent' },
|
|
23
|
+
{ path: `${fw}/tasks`, type: 'task' },
|
|
24
|
+
{ path: `${fw}/schemas`, type: 'schema' },
|
|
25
|
+
{ path: `${fw}/domains`, type: 'domain' },
|
|
26
|
+
{ path: `${fw}/hooks`, type: 'hook' },
|
|
27
|
+
{ path: `${fw}/workflows`, type: 'workflow' },
|
|
28
|
+
{ path: `${fw}/templates`, type: 'template' },
|
|
29
|
+
];
|
|
30
|
+
}
|
|
22
31
|
|
|
23
32
|
/**
|
|
24
33
|
* Scan project for new/changed files and update registry.
|
|
@@ -28,7 +37,7 @@ const KNOWN_DIRS = [
|
|
|
28
37
|
*/
|
|
29
38
|
export function updateRegistry(projectDir, options = {}) {
|
|
30
39
|
const { dryRun = false } = options;
|
|
31
|
-
const registryPath = join(projectDir,
|
|
40
|
+
const registryPath = join(projectDir, resolveFrameworkDir(projectDir), 'entity-registry.yaml');
|
|
32
41
|
|
|
33
42
|
let registry = {
|
|
34
43
|
metadata: {
|
|
@@ -157,7 +166,7 @@ export function updateRegistry(projectDir, options = {}) {
|
|
|
157
166
|
* @returns {object[]} New entity candidates
|
|
158
167
|
*/
|
|
159
168
|
export function detectNewEntities(projectDir) {
|
|
160
|
-
const registryPath = join(projectDir,
|
|
169
|
+
const registryPath = join(projectDir, resolveFrameworkDir(projectDir), 'entity-registry.yaml');
|
|
161
170
|
const existingPaths = new Set();
|
|
162
171
|
|
|
163
172
|
if (existsSync(registryPath)) {
|
|
@@ -175,7 +184,7 @@ export function detectNewEntities(projectDir) {
|
|
|
175
184
|
|
|
176
185
|
const newEntities = [];
|
|
177
186
|
|
|
178
|
-
|
|
187
|
+
buildKnownDirs(projectDir).forEach(({ path: dirPath, type }) => {
|
|
179
188
|
const fullPath = join(projectDir, dirPath);
|
|
180
189
|
if (!existsSync(fullPath)) {
|
|
181
190
|
return;
|
|
@@ -204,7 +213,7 @@ export function detectNewEntities(projectDir) {
|
|
|
204
213
|
* @returns {object[]} Removed entity candidates
|
|
205
214
|
*/
|
|
206
215
|
export function detectRemovedEntities(projectDir) {
|
|
207
|
-
const registryPath = join(projectDir,
|
|
216
|
+
const registryPath = join(projectDir, resolveFrameworkDir(projectDir), 'entity-registry.yaml');
|
|
208
217
|
if (!existsSync(registryPath)) {
|
|
209
218
|
return [];
|
|
210
219
|
}
|
package/src/extensions/loader.js
CHANGED
|
@@ -11,13 +11,7 @@
|
|
|
11
11
|
import { existsSync, readdirSync } from 'fs';
|
|
12
12
|
import { join, extname, basename } from 'path';
|
|
13
13
|
import { registerExtension, EXTENSION_POINTS } from './registry.js';
|
|
14
|
-
|
|
15
|
-
// ---------------------------------------------------------------------------
|
|
16
|
-
// Constants
|
|
17
|
-
// ---------------------------------------------------------------------------
|
|
18
|
-
|
|
19
|
-
/** Directory relative to project root where extensions are stored. */
|
|
20
|
-
const EXTENSIONS_DIR = 'chati.dev/extensions';
|
|
14
|
+
import { resolveFrameworkDir } from '../utils/framework-dir.js';
|
|
21
15
|
|
|
22
16
|
/** Required fields in an extension module's default export. */
|
|
23
17
|
const REQUIRED_FIELDS = ['name', 'point', 'handler'];
|
|
@@ -79,7 +73,7 @@ export function discoverExtensions(projectDir) {
|
|
|
79
73
|
return { files: [], dir: '' };
|
|
80
74
|
}
|
|
81
75
|
|
|
82
|
-
const extDir = join(projectDir,
|
|
76
|
+
const extDir = join(projectDir, resolveFrameworkDir(projectDir), 'extensions');
|
|
83
77
|
|
|
84
78
|
if (!existsSync(extDir)) {
|
|
85
79
|
return { files: [], dir: extDir };
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { existsSync, readdirSync } from 'node:fs';
|
|
9
9
|
import { join } from 'node:path';
|
|
10
|
+
import { resolveFrameworkDir } from '../utils/framework-dir.js';
|
|
10
11
|
import { GateBase } from './gate-base.js';
|
|
11
12
|
import { loadSession } from '../orchestrator/session-manager.js';
|
|
12
13
|
import { loadHandoff } from '../tasks/handoff.js';
|
|
@@ -37,7 +38,7 @@ export class PlanningCompleteGate extends GateBase {
|
|
|
37
38
|
* @returns {object} Evidence about artifact presence, session state, and handoff
|
|
38
39
|
*/
|
|
39
40
|
_collectEvidence(projectDir) {
|
|
40
|
-
const artifactsBase = join(projectDir,
|
|
41
|
+
const artifactsBase = join(projectDir, resolveFrameworkDir(projectDir), 'artifacts');
|
|
41
42
|
const evidence = {
|
|
42
43
|
artifacts: {},
|
|
43
44
|
sessionState: null,
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { existsSync, readdirSync } from 'node:fs';
|
|
9
9
|
import { join } from 'node:path';
|
|
10
|
+
import { resolveFrameworkDir } from '../utils/framework-dir.js';
|
|
10
11
|
import { GateBase, determineVerdict } from './gate-base.js';
|
|
11
12
|
import { loadSession } from '../orchestrator/session-manager.js';
|
|
12
13
|
import { loadHandoff } from '../tasks/handoff.js';
|
|
@@ -28,7 +29,7 @@ export class QAPlanningGate extends GateBase {
|
|
|
28
29
|
* @returns {object} Evidence about test strategy, coverage plan, risk assessment
|
|
29
30
|
*/
|
|
30
31
|
_collectEvidence(projectDir) {
|
|
31
|
-
const artifactsBase = join(projectDir,
|
|
32
|
+
const artifactsBase = join(projectDir, resolveFrameworkDir(projectDir), 'artifacts');
|
|
32
33
|
const evidence = {
|
|
33
34
|
testStrategy: false,
|
|
34
35
|
coveragePlan: false,
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
10
10
|
import { join } from 'node:path';
|
|
11
|
+
import { resolveFrameworkDir } from '../utils/framework-dir.js';
|
|
11
12
|
import { GateBase } from './gate-base.js';
|
|
12
13
|
import { loadSession } from '../orchestrator/session-manager.js';
|
|
13
14
|
import { loadHandoff } from '../tasks/handoff.js';
|
|
@@ -97,7 +98,7 @@ export class ImplementationGate extends GateBase {
|
|
|
97
98
|
// Check for security scan results
|
|
98
99
|
const securityPaths = [
|
|
99
100
|
join(projectDir, '.security-scan'),
|
|
100
|
-
join(projectDir,
|
|
101
|
+
join(projectDir, resolveFrameworkDir(projectDir), 'artifacts', 'security-report.md'),
|
|
101
102
|
];
|
|
102
103
|
for (const secPath of securityPaths) {
|
|
103
104
|
if (existsSync(secPath)) {
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
import { existsSync, readFileSync } from 'node:fs';
|
|
16
16
|
import { join } from 'node:path';
|
|
17
|
+
import { resolveFrameworkDir } from '../utils/framework-dir.js';
|
|
17
18
|
import { GateBase, determineVerdict } from './gate-base.js';
|
|
18
19
|
import { loadSession } from '../orchestrator/session-manager.js';
|
|
19
20
|
import { loadHandoff } from '../tasks/handoff.js';
|
|
@@ -71,7 +72,7 @@ export class QAImplementationGate extends GateBase {
|
|
|
71
72
|
|
|
72
73
|
// Check for performance benchmark results — parse content for real findings
|
|
73
74
|
const perfPaths = [
|
|
74
|
-
join(projectDir,
|
|
75
|
+
join(projectDir, resolveFrameworkDir(projectDir), 'artifacts', 'performance-report.md'),
|
|
75
76
|
join(projectDir, '.performance-benchmark'),
|
|
76
77
|
];
|
|
77
78
|
for (const perfPath of perfPaths) {
|
|
@@ -96,7 +97,7 @@ export class QAImplementationGate extends GateBase {
|
|
|
96
97
|
|
|
97
98
|
// Check for security scan — parse content for real findings
|
|
98
99
|
const secPaths = [
|
|
99
|
-
join(projectDir,
|
|
100
|
+
join(projectDir, resolveFrameworkDir(projectDir), 'artifacts', 'security-report.md'),
|
|
100
101
|
join(projectDir, '.security-scan'),
|
|
101
102
|
];
|
|
102
103
|
for (const secPath of secPaths) {
|
|
@@ -11,6 +11,7 @@ import { join } from 'node:path';
|
|
|
11
11
|
import { GateBase } from './gate-base.js';
|
|
12
12
|
import { loadSession } from '../orchestrator/session-manager.js';
|
|
13
13
|
import { loadHandoff } from '../tasks/handoff.js';
|
|
14
|
+
import { resolveFrameworkDir } from '../utils/framework-dir.js';
|
|
14
15
|
|
|
15
16
|
export class DeployReadyGate extends GateBase {
|
|
16
17
|
constructor() {
|
|
@@ -75,7 +76,7 @@ export class DeployReadyGate extends GateBase {
|
|
|
75
76
|
// Check release notes
|
|
76
77
|
const releaseNotePaths = [
|
|
77
78
|
join(projectDir, 'RELEASE.md'),
|
|
78
|
-
join(projectDir,
|
|
79
|
+
join(projectDir, resolveFrameworkDir(projectDir), 'artifacts', 'release-notes.md'),
|
|
79
80
|
];
|
|
80
81
|
for (const rnPath of releaseNotePaths) {
|
|
81
82
|
if (existsSync(rnPath)) {
|
package/src/health/engine.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import { existsSync, readFileSync } from 'fs';
|
|
10
10
|
import { join } from 'path';
|
|
11
11
|
import { isCommandAvailable, parseProviderConfig } from '../utils/config-parser.js';
|
|
12
|
+
import { resolveFrameworkDir } from '../utils/framework-dir.js';
|
|
12
13
|
|
|
13
14
|
// ---------------------------------------------------------------------------
|
|
14
15
|
// Check Result Types
|
|
@@ -45,7 +46,7 @@ import { isCommandAvailable, parseProviderConfig } from '../utils/config-parser.
|
|
|
45
46
|
*/
|
|
46
47
|
export async function checkCliAvailability(projectDir) {
|
|
47
48
|
const start = Date.now();
|
|
48
|
-
const configPath = join(projectDir,
|
|
49
|
+
const configPath = join(projectDir, resolveFrameworkDir(projectDir), 'config.yaml');
|
|
49
50
|
|
|
50
51
|
if (!existsSync(configPath)) {
|
|
51
52
|
return { name: 'cli-availability', status: 'warn', message: 'No config.yaml found', duration: Date.now() - start };
|
|
@@ -76,7 +77,7 @@ export async function checkCliAvailability(projectDir) {
|
|
|
76
77
|
*/
|
|
77
78
|
export async function checkFrameworkIntegrity(projectDir) {
|
|
78
79
|
const start = Date.now();
|
|
79
|
-
const registryPath = join(projectDir,
|
|
80
|
+
const registryPath = join(projectDir, resolveFrameworkDir(projectDir), 'data', 'entity-registry.yaml');
|
|
80
81
|
|
|
81
82
|
if (!existsSync(registryPath)) {
|
|
82
83
|
return { name: 'framework-integrity', status: 'warn', message: 'No entity registry found', duration: Date.now() - start };
|
|
@@ -133,7 +134,7 @@ export async function checkSessionState(projectDir) {
|
|
|
133
134
|
*/
|
|
134
135
|
export async function checkHooksHealth(projectDir) {
|
|
135
136
|
const start = Date.now();
|
|
136
|
-
const hooksDir = join(projectDir,
|
|
137
|
+
const hooksDir = join(projectDir, resolveFrameworkDir(projectDir), 'hooks');
|
|
137
138
|
|
|
138
139
|
if (!existsSync(hooksDir)) {
|
|
139
140
|
return { name: 'hooks-health', status: 'fail', message: 'Hooks directory not found', duration: Date.now() - start };
|