clckernel 1.2.6
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/AGENTS.md +124 -0
- package/README.es.md +166 -0
- package/README.md +167 -0
- package/bin/cli.js +12 -0
- package/docs/Journal/001-adr-clckernel-governance.md +18 -0
- package/package.json +44 -0
- package/src/adapters/astro.js +67 -0
- package/src/adapters/base.js +109 -0
- package/src/adapters/django.js +70 -0
- package/src/adapters/fastapi.js +69 -0
- package/src/adapters/go.js +50 -0
- package/src/adapters/laravel.js +52 -0
- package/src/adapters/nextjs.js +72 -0
- package/src/adapters/rails.js +54 -0
- package/src/adapters/rust.js +51 -0
- package/src/catalog.js +217 -0
- package/src/config.js +250 -0
- package/src/detector.js +85 -0
- package/src/doctor.js +125 -0
- package/src/generator.js +473 -0
- package/src/index.js +52 -0
- package/src/technologies/detector.js +243 -0
- package/src/technologies/guards/_shared.js +66 -0
- package/src/ui.js +101 -0
- package/src/yaml.js +173 -0
- package/test/adapters/astro.test.js +102 -0
- package/test/adapters/base.test.js +86 -0
- package/test/adapters/django.test.js +95 -0
- package/test/adapters/fastapi.test.js +88 -0
- package/test/adapters/go.test.js +81 -0
- package/test/adapters/laravel.test.js +106 -0
- package/test/adapters/nextjs.test.js +113 -0
- package/test/adapters/rails.test.js +108 -0
- package/test/adapters/rust.test.js +83 -0
- package/test/catalog.test.js +170 -0
- package/test/config.test.js +512 -0
- package/test/detector.test.js +345 -0
- package/test/doctor.test.js +302 -0
- package/test/generator.test.js +419 -0
- package/test/guards_new.test.js +95 -0
- package/test/helpers.js +36 -0
- package/test/integration/cli-flow.test.js +270 -0
- package/test/technologies/celery_guard.test.js +185 -0
- package/test/technologies/detector.test.js +342 -0
- package/test/technologies/docker_guard.test.js +187 -0
- package/test/technologies/integration.test.js +123 -0
- package/test/technologies/postgres_guard.test.js +87 -0
- package/test/technologies/redis_guard.test.js +128 -0
- package/tools/audit.js +219 -0
- package/tools/audit.py +273 -0
- package/tools/celery_guard.py +209 -0
- package/tools/check_a11y.js +109 -0
- package/tools/check_api_contracts.js +139 -0
- package/tools/check_architecture.js +139 -0
- package/tools/check_architecture.py +264 -0
- package/tools/check_custom.js +163 -0
- package/tools/check_custom.py +395 -0
- package/tools/check_db_efficiency.py +190 -0
- package/tools/check_migrations.py +223 -0
- package/tools/check_performance.js +142 -0
- package/tools/check_responsive.js +131 -0
- package/tools/check_scope.py +180 -0
- package/tools/check_seo.js +139 -0
- package/tools/check_storybook.js +108 -0
- package/tools/check_ui_reuse.js +135 -0
- package/tools/docker_guard.py +210 -0
- package/tools/postgres_guard.py +192 -0
- package/tools/redis_guard.py +197 -0
- package/tools/scan_secrets.js +109 -0
- package/tools/scan_secrets.py +153 -0
- package/tools/verify_tdd.py +212 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLC Kernel — Base Stack Adapter Interface
|
|
3
|
+
* All framework-specific adapters (Rails, Astro, Next.js, FastAPI, Go, Rust, Laravel)
|
|
4
|
+
* inherit from this interface to ensure universal polyglot harness behavior.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const { execSync } = require('child_process');
|
|
10
|
+
const { TechnologyDetector } = require('../technologies/detector');
|
|
11
|
+
|
|
12
|
+
class BaseAdapter {
|
|
13
|
+
constructor(name, projectType, testRunner) {
|
|
14
|
+
this.name = name;
|
|
15
|
+
this.projectType = projectType;
|
|
16
|
+
this.testRunner = testRunner;
|
|
17
|
+
this.techDetector = new TechnologyDetector();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
detect(targetDir) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
getSafeguards() {
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Returns the tool manifest for this adapter.
|
|
30
|
+
* Each entry describes one pre-commit tool (script or external CLI).
|
|
31
|
+
* Override in subclasses to declare stack-specific tools.
|
|
32
|
+
* @returns {Array<{name: string, language: string, path: string, command: string, description: string, extCLI?: string}>}
|
|
33
|
+
*/
|
|
34
|
+
getTools() {
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Merges technology-specific tools into the adapter tool manifest.
|
|
40
|
+
* Tech tools are inserted before check_custom to preserve user override escape hatch.
|
|
41
|
+
* @param {Array} baseTools - The adapter's base tool manifest
|
|
42
|
+
* @returns {Array} Merged tool manifest with technology tools inserted
|
|
43
|
+
*/
|
|
44
|
+
_mergeTechTools(baseTools) {
|
|
45
|
+
const techTools = this.techDetector.getToolsForTech(this.detectedTech || []);
|
|
46
|
+
if (techTools.length === 0) return baseTools;
|
|
47
|
+
|
|
48
|
+
const result = [];
|
|
49
|
+
for (const tool of baseTools) {
|
|
50
|
+
if (tool.name === 'check_custom') {
|
|
51
|
+
// Insert tech tools before check_custom
|
|
52
|
+
result.push(...techTools);
|
|
53
|
+
}
|
|
54
|
+
result.push(tool);
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
provision(targetDir, config) {
|
|
60
|
+
// 1. Create docs/ and sdds/
|
|
61
|
+
fs.mkdirSync(path.join(targetDir, 'docs', 'Journal'), { recursive: true });
|
|
62
|
+
fs.mkdirSync(path.join(targetDir, 'docs', 'Architecture'), { recursive: true });
|
|
63
|
+
fs.mkdirSync(path.join(targetDir, 'docs', 'Development'), { recursive: true });
|
|
64
|
+
fs.mkdirSync(path.join(targetDir, 'sdds'), { recursive: true });
|
|
65
|
+
fs.mkdirSync(path.join(targetDir, 'tools'), { recursive: true });
|
|
66
|
+
|
|
67
|
+
// 2. Gitignore sdds/*
|
|
68
|
+
const gitignorePath = path.join(targetDir, '.gitignore');
|
|
69
|
+
let gitignore = fs.existsSync(gitignorePath) ? fs.readFileSync(gitignorePath, 'utf-8') : '';
|
|
70
|
+
if (!gitignore.includes('sdds/*')) {
|
|
71
|
+
gitignore += '\n\n# Local Spec-Driven Development (SDD) files\nsdds/*\n!sdds/.gitkeep\nopenspec/*\n!openspec/.gitkeep\n.ruff_cache/\n';
|
|
72
|
+
fs.writeFileSync(gitignorePath, gitignore, 'utf-8');
|
|
73
|
+
}
|
|
74
|
+
fs.writeFileSync(path.join(targetDir, 'sdds', '.gitkeep'), '', 'utf-8');
|
|
75
|
+
|
|
76
|
+
// 3. Write AGENTS.md
|
|
77
|
+
const isFront = this.projectType === 'frontend';
|
|
78
|
+
const agentsContent = `# 🔨 CLC Kernel ${this.name} (${this.projectType.toUpperCase()}) — AGENTS
|
|
79
|
+
|
|
80
|
+
This document is the **authoritative law** for AI agents working in this repository.
|
|
81
|
+
Forged by **CLC Kernel: The AI Agent Governance Engine**.
|
|
82
|
+
|
|
83
|
+
> 🚨 **RULE #0: MANDATORY EXECUTION OVERRIDE RULE (UNBYPASSABLE)**
|
|
84
|
+
> Even when the user issues a direct or urgent fix request ("fix this bug", "fix this error", "quick fix"):
|
|
85
|
+
> YOU ARE STRICTLY FORBIDDEN from modifying source code directly without completing the full quality harness:
|
|
86
|
+
> 1. **Research & Root Cause Analysis:** Investigate tracebacks and inspect affected files before editing.
|
|
87
|
+
> 2. **TDD Verification (Red Phase):** Write a failing regression test first (${this.testRunner}).
|
|
88
|
+
> 3. **Clean Architecture Implementation (Green Phase):** Make the test pass maintaining layer isolation.
|
|
89
|
+
> 4. **Mandatory Educational Audit Gate:** Execute \`node tools/audit.js\` or \`python tools/audit.py\` and output the Educational Code Summary to stdout.
|
|
90
|
+
> NEVER declare success or skip verification commands for quick fixes.
|
|
91
|
+
|
|
92
|
+
## 1. The Loop (Every Task)
|
|
93
|
+
1. **Research** — Inspect codebase / docs before writing code.
|
|
94
|
+
2. **Plan** — Write an SDD under \`sdds/{change-name}/\`. SDDs live 100% locally and are gitignored.
|
|
95
|
+
3. **Test** (TDD) — Write failing test first (${this.testRunner}).
|
|
96
|
+
4. **Implement** — Make test pass.
|
|
97
|
+
5. **Verify & Audit** — Run \`node tools/audit.js\` or \`python tools/audit.py\`.
|
|
98
|
+
6. **DoD** — Lint, typecheck, tests, coverage, docs, memory.
|
|
99
|
+
7. **Commit** — Pre-commit hook runs automated guards.
|
|
100
|
+
8. **PR** — Generate PR body.
|
|
101
|
+
|
|
102
|
+
## 2. Core AI Safeguards (${this.name})
|
|
103
|
+
${this.getSafeguards().map(s => `- ${s}`).join('\n')}
|
|
104
|
+
`;
|
|
105
|
+
fs.writeFileSync(path.join(targetDir, 'AGENTS.md'), agentsContent, 'utf-8');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
module.exports = BaseAdapter;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLC Kernel — Django Stack Adapter
|
|
3
|
+
* Supports Django apps, pytest-django, Ruff AST, ORM idempotency, and Scope Guard.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const BaseAdapter = require('./base');
|
|
9
|
+
|
|
10
|
+
class DjangoAdapter extends BaseAdapter {
|
|
11
|
+
constructor() {
|
|
12
|
+
super('Django Framework', 'backend', 'pytest-django / manage.py test');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
detect(targetDir) {
|
|
16
|
+
const hasManagePy = fs.existsSync(path.join(targetDir, 'manage.py'));
|
|
17
|
+
const hasPyproject = fs.existsSync(path.join(targetDir, 'pyproject.toml'));
|
|
18
|
+
const hasRequirements = fs.existsSync(path.join(targetDir, 'requirements.txt'));
|
|
19
|
+
|
|
20
|
+
if (hasManagePy) return true;
|
|
21
|
+
|
|
22
|
+
if (hasPyproject || hasRequirements) {
|
|
23
|
+
try {
|
|
24
|
+
const pyproject = hasPyproject ? fs.readFileSync(path.join(targetDir, 'pyproject.toml'), 'utf-8') : '';
|
|
25
|
+
const reqs = hasRequirements ? fs.readFileSync(path.join(targetDir, 'requirements.txt'), 'utf-8') : '';
|
|
26
|
+
return pyproject.toLowerCase().includes('django') || reqs.toLowerCase().includes('django');
|
|
27
|
+
} catch (e) {}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
getSafeguards() {
|
|
34
|
+
return [
|
|
35
|
+
'Flake8 / Ruff AST Python Code Quality Linter',
|
|
36
|
+
'Clean Architecture AST Guard (Domain -> Application -> Views)',
|
|
37
|
+
'Database Efficiency & N+1 Performance Guard (select_related / prefetch_related)',
|
|
38
|
+
'Django ORM Migration Idempotency & Schema Drift Guard',
|
|
39
|
+
'pytest-django Red-to-Green TDD Validator',
|
|
40
|
+
'Secret & Private Key Leak Scanner',
|
|
41
|
+
'Scope Guardrail (git diff vs SDD affected files)',
|
|
42
|
+
'Educational Audit Gate (05-audit-report.md)',
|
|
43
|
+
'Memory Guard (Engram / Graphify ADR Sync)'
|
|
44
|
+
];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Returns the tool manifest for Django projects.
|
|
49
|
+
* Includes Python guard scripts and external CLI tools (ruff, manage.py test).
|
|
50
|
+
* @returns {Array<{name: string, language: string, path: string, command: string, description: string, extCLI?: string}>}
|
|
51
|
+
*/
|
|
52
|
+
getTools() {
|
|
53
|
+
const baseTools = [
|
|
54
|
+
{ name: 'scan_secrets', language: 'py', path: 'scan_secrets.py', command: 'python3 tools/scan_secrets.py', description: 'Scans for leaked secrets and API keys' },
|
|
55
|
+
{ name: 'check_architecture', language: 'py', path: 'check_architecture.py', command: 'python3 tools/check_architecture.py', description: 'Validates Django layer boundaries' },
|
|
56
|
+
{ name: 'check_db_efficiency', language: 'py', path: 'check_db_efficiency.py', command: 'python3 tools/check_db_efficiency.py', description: 'Audits database query efficiency and N+1 loop calls' },
|
|
57
|
+
{ name: 'check_custom', language: 'python', path: 'check_custom.py', command: 'python3 tools/check_custom.py', description: 'Runs user-defined custom rules from .clc-forge.yml' },
|
|
58
|
+
{ name: 'ruff', language: 'external', path: '', command: 'python3 -m ruff check .', description: 'Python AST linter', extCLI: 'ruff' },
|
|
59
|
+
{ name: 'manage', language: 'external', path: '', command: 'python3 manage.py test', description: 'Django test runner', extCLI: 'manage.py' },
|
|
60
|
+
];
|
|
61
|
+
return this._mergeTechTools(baseTools);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
provision(targetDir, config) {
|
|
65
|
+
super.provision(targetDir, config);
|
|
66
|
+
// Pre-commit hook generation moved to generator.js via getTools() manifest
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
module.exports = DjangoAdapter;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLC Kernel — FastAPI Stack Adapter
|
|
3
|
+
* Supports FastAPI apps, pytest, Pydantic V2, Alembic idempotency, and AST Clean Architecture.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const BaseAdapter = require('./base');
|
|
9
|
+
|
|
10
|
+
class FastApiAdapter extends BaseAdapter {
|
|
11
|
+
constructor() {
|
|
12
|
+
super('FastAPI Framework', 'backend', 'Pytest');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
detect(targetDir) {
|
|
16
|
+
const hasPyproject = fs.existsSync(path.join(targetDir, 'pyproject.toml'));
|
|
17
|
+
const hasRequirements = fs.existsSync(path.join(targetDir, 'requirements.txt'));
|
|
18
|
+
|
|
19
|
+
if (hasPyproject || hasRequirements) {
|
|
20
|
+
try {
|
|
21
|
+
const pyproject = hasPyproject ? fs.readFileSync(path.join(targetDir, 'pyproject.toml'), 'utf-8') : '';
|
|
22
|
+
const reqs = hasRequirements ? fs.readFileSync(path.join(targetDir, 'requirements.txt'), 'utf-8') : '';
|
|
23
|
+
return pyproject.toLowerCase().includes('fastapi') || reqs.toLowerCase().includes('fastapi');
|
|
24
|
+
} catch (e) {}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
getSafeguards() {
|
|
31
|
+
return [
|
|
32
|
+
'Ruff / Flake8 Python AST Code Quality Linter',
|
|
33
|
+
'Clean Architecture AST Guard (Domain -> Application -> Routes)',
|
|
34
|
+
'Database Efficiency & N+1 Performance Guard (bulk queries & eager loading)',
|
|
35
|
+
'Alembic Migration Idempotency & Schema Drift Guard',
|
|
36
|
+
'Pytest Red-to-Green TDD Validator',
|
|
37
|
+
'Pydantic V2 Response Schema Validation Guard',
|
|
38
|
+
'Secret & Private Key Leak Scanner',
|
|
39
|
+
'Scope Guardrail (git diff vs SDD affected files)',
|
|
40
|
+
'Educational Audit Gate (05-audit-report.md)',
|
|
41
|
+
'Memory Guard (Engram / Graphify ADR Sync)'
|
|
42
|
+
];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Returns the tool manifest for FastAPI projects.
|
|
47
|
+
* Includes Python guard scripts and external CLI tools (ruff, pytest).
|
|
48
|
+
* @returns {Array<{name: string, language: string, path: string, command: string, description: string, extCLI?: string}>}
|
|
49
|
+
*/
|
|
50
|
+
getTools() {
|
|
51
|
+
const baseTools = [
|
|
52
|
+
{ name: 'scan_secrets', language: 'py', path: 'scan_secrets.py', command: 'python3 tools/scan_secrets.py', description: 'Scans for leaked secrets and API keys' },
|
|
53
|
+
{ name: 'check_architecture', language: 'py', path: 'check_architecture.py', command: 'python3 tools/check_architecture.py', description: 'Validates Clean Architecture layer boundaries' },
|
|
54
|
+
{ name: 'check_db_efficiency', language: 'py', path: 'check_db_efficiency.py', command: 'python3 tools/check_db_efficiency.py', description: 'Audits database query efficiency and N+1 loop calls' },
|
|
55
|
+
{ name: 'check_migrations', language: 'py', path: 'check_migrations.py', command: 'python3 tools/check_migrations.py', description: 'Checks Alembic migration idempotency' },
|
|
56
|
+
{ name: 'check_custom', language: 'python', path: 'check_custom.py', command: 'python3 tools/check_custom.py', description: 'Runs user-defined custom rules from .clc-forge.yml' },
|
|
57
|
+
{ name: 'ruff', language: 'external', path: '', command: 'python3 -m ruff check .', description: 'Python AST linter', extCLI: 'ruff' },
|
|
58
|
+
{ name: 'pytest', language: 'external', path: '', command: 'pytest', description: 'Test runner', extCLI: 'pytest' },
|
|
59
|
+
];
|
|
60
|
+
return this._mergeTechTools(baseTools);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
provision(targetDir, config) {
|
|
64
|
+
super.provision(targetDir, config);
|
|
65
|
+
// Pre-commit hook generation moved to generator.js via getTools() manifest
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
module.exports = FastApiAdapter;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLC Kernel — Go Stack Adapter
|
|
3
|
+
* Supports Golang apps, `go test`, golangci-lint AST, and Domain/UseCase Clean Architecture.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const BaseAdapter = require('./base');
|
|
9
|
+
|
|
10
|
+
class GoAdapter extends BaseAdapter {
|
|
11
|
+
constructor() {
|
|
12
|
+
super('Go (Golang)', 'backend', 'go test');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
detect(targetDir) {
|
|
16
|
+
return fs.existsSync(path.join(targetDir, 'go.mod'));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
getSafeguards() {
|
|
20
|
+
return [
|
|
21
|
+
'golangci-lint Code Quality & AST Linter',
|
|
22
|
+
'Go Clean Architecture Guard (Domain -> UseCase -> Handler)',
|
|
23
|
+
'go test Red-to-Green TDD Validator',
|
|
24
|
+
'Secret & Private Key Leak Scanner',
|
|
25
|
+
'Educational Audit Gate (05-audit-report.md)',
|
|
26
|
+
'Memory Guard (Engram / Graphify ADR Sync)'
|
|
27
|
+
];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Returns the tool manifest for Go projects.
|
|
32
|
+
* External CLIs only — no custom guard scripts bundled.
|
|
33
|
+
* @returns {Array<{name: string, language: string, path: string, command: string, description: string, extCLI?: string}>}
|
|
34
|
+
*/
|
|
35
|
+
getTools() {
|
|
36
|
+
const baseTools = [
|
|
37
|
+
{ name: 'check_custom', language: 'js', path: 'check_custom.js', command: 'node tools/check_custom.js', description: 'Runs user-defined custom rules from .clc-forge.yml' },
|
|
38
|
+
{ name: 'golangci-lint', language: 'external', path: '', command: 'golangci-lint run', description: 'Go linter and static analysis', extCLI: 'golangci-lint' },
|
|
39
|
+
{ name: 'go_test', language: 'external', path: '', command: 'go test ./...', description: 'Go test runner', extCLI: 'go' },
|
|
40
|
+
];
|
|
41
|
+
return this._mergeTechTools(baseTools);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
provision(targetDir, config) {
|
|
45
|
+
super.provision(targetDir, config);
|
|
46
|
+
// Pre-commit hook generation moved to generator.js via getTools() manifest
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
module.exports = GoAdapter;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLC Kernel — PHP / Laravel Stack Adapter
|
|
3
|
+
* Supports Laravel, Pest / PHPUnit, PHPStan AST, and Eloquent migration idempotency.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const BaseAdapter = require('./base');
|
|
9
|
+
|
|
10
|
+
class LaravelAdapter extends BaseAdapter {
|
|
11
|
+
constructor() {
|
|
12
|
+
super('PHP / Laravel', 'backend', 'Pest / PHPUnit');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
detect(targetDir) {
|
|
16
|
+
const hasComposer = fs.existsSync(path.join(targetDir, 'composer.json'));
|
|
17
|
+
const hasArtisan = fs.existsSync(path.join(targetDir, 'artisan'));
|
|
18
|
+
return hasComposer && hasArtisan;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
getSafeguards() {
|
|
22
|
+
return [
|
|
23
|
+
'PHPStan / PHP_CodeSniffer AST Code Quality Linter',
|
|
24
|
+
'Laravel Migration Idempotency & Schema Guard',
|
|
25
|
+
'Pest / PHPUnit Red-to-Green TDD Validator',
|
|
26
|
+
'Secret & Private Key Leak Scanner',
|
|
27
|
+
'Educational Audit Gate (05-audit-report.md)',
|
|
28
|
+
'Memory Guard (Engram / Graphify ADR Sync)'
|
|
29
|
+
];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Returns the tool manifest for Laravel projects.
|
|
34
|
+
* External CLIs only — no custom guard scripts bundled.
|
|
35
|
+
* @returns {Array<{name: string, language: string, path: string, command: string, description: string, extCLI?: string}>}
|
|
36
|
+
*/
|
|
37
|
+
getTools() {
|
|
38
|
+
const baseTools = [
|
|
39
|
+
{ name: 'check_custom', language: 'python', path: 'check_custom.py', command: 'python3 tools/check_custom.py', description: 'Runs user-defined custom rules from .clc-forge.yml' },
|
|
40
|
+
{ name: 'phpstan', language: 'external', path: '', command: './vendor/bin/phpstan analyse', description: 'PHP static analysis', extCLI: 'phpstan' },
|
|
41
|
+
{ name: 'artisan', language: 'external', path: '', command: 'php artisan test', description: 'Laravel test runner', extCLI: 'artisan' },
|
|
42
|
+
];
|
|
43
|
+
return this._mergeTechTools(baseTools);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
provision(targetDir, config) {
|
|
47
|
+
super.provision(targetDir, config);
|
|
48
|
+
// Pre-commit hook generation moved to generator.js via getTools() manifest
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
module.exports = LaravelAdapter;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLC Kernel — Next.js Stack Adapter
|
|
3
|
+
* Supports Next.js (App Router / Pages), React Server Components, Tailwind CSS, Vitest / Jest, and A11y.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const BaseAdapter = require('./base');
|
|
9
|
+
|
|
10
|
+
class NextjsAdapter extends BaseAdapter {
|
|
11
|
+
constructor() {
|
|
12
|
+
super('Next.js (App Router)', 'frontend', 'Vitest / Jest');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
detect(targetDir) {
|
|
16
|
+
const hasPkg = fs.existsSync(path.join(targetDir, 'package.json'));
|
|
17
|
+
if (!hasPkg) return false;
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(targetDir, 'package.json'), 'utf-8'));
|
|
21
|
+
const deps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };
|
|
22
|
+
return Boolean(deps['next']);
|
|
23
|
+
} catch (e) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
getSafeguards() {
|
|
29
|
+
return [
|
|
30
|
+
'UI Component Reuse First Guard (components/ui/ & atomic primitives)',
|
|
31
|
+
'Tailwind v4 Semantic Design Token Guard (bg-primary, text-muted-foreground)',
|
|
32
|
+
'Next.js Clean Architecture & Server Components Guard (layout.tsx protection)',
|
|
33
|
+
'Secret & Client Token Exposure Guard',
|
|
34
|
+
'Accessibility & ARIA Guard (A11y & alt tags)',
|
|
35
|
+
'Responsive Design & Mobile-First Adaptability Guard (breakpoint & touch target audit)',
|
|
36
|
+
'SEO, GEO & Web Performance Guard (metadata, OpenGraph, Core Web Vitals)',
|
|
37
|
+
'Zod API Contract Guard (services response schema parsing)',
|
|
38
|
+
'Performance & Next/Image Guard (next/image & tree-shaking)',
|
|
39
|
+
'Storybook Story Coverage Guard (.stories.tsx)',
|
|
40
|
+
'Educational Audit Gate (05-audit-report.md)',
|
|
41
|
+
'Memory Guard & PR Generator (.github/pull_request_body.md)'
|
|
42
|
+
];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Returns the tool manifest for Next.js projects.
|
|
47
|
+
* Includes JS guard scripts and external CLI tools (tsc, lint-staged).
|
|
48
|
+
* @returns {Array<{name: string, language: string, path: string, command: string, description: string, extCLI?: string}>}
|
|
49
|
+
*/
|
|
50
|
+
getTools() {
|
|
51
|
+
const baseTools = [
|
|
52
|
+
{ name: 'scan_secrets', language: 'js', path: 'scan_secrets.js', command: 'node tools/scan_secrets.js', description: 'Scans for leaked secrets and API keys' },
|
|
53
|
+
{ name: 'check_a11y', language: 'js', path: 'check_a11y.js', command: 'node tools/check_a11y.js', description: 'Validates ARIA and accessibility rules' },
|
|
54
|
+
{ name: 'check_responsive', language: 'js', path: 'check_responsive.js', command: 'node tools/check_responsive.js', description: 'Audits mobile-first responsiveness and fixed-width overflows' },
|
|
55
|
+
{ name: 'check_seo', language: 'js', path: 'check_seo.js', command: 'node tools/check_seo.js', description: 'Validates SEO metadata, OpenGraph, GEO tags, and LCP priority' },
|
|
56
|
+
{ name: 'check_ui_reuse', language: 'js', path: 'check_ui_reuse.js', command: 'node tools/check_ui_reuse.js', description: 'Enforces UI primitive reuse from components/ui/' },
|
|
57
|
+
{ name: 'check_architecture', language: 'js', path: 'check_architecture.js', command: 'node tools/check_architecture.js', description: 'Validates Next.js Server Component boundaries' },
|
|
58
|
+
{ name: 'check_performance', language: 'js', path: 'check_performance.js', command: 'node tools/check_performance.js', description: 'Checks next/image and bundle optimization' },
|
|
59
|
+
{ name: 'check_custom', language: 'js', path: 'check_custom.js', command: 'node tools/check_custom.js', description: 'Runs user-defined custom rules from .clc-forge.yml' },
|
|
60
|
+
{ name: 'tsc', language: 'external', path: '', command: 'npx tsc --noEmit', description: 'TypeScript type checking', extCLI: 'tsc' },
|
|
61
|
+
{ name: 'lint', language: 'external', path: '', command: 'npx lint-staged', description: 'Lint staged files', extCLI: 'lint-staged' },
|
|
62
|
+
];
|
|
63
|
+
return this._mergeTechTools(baseTools);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
provision(targetDir, config) {
|
|
67
|
+
super.provision(targetDir, config);
|
|
68
|
+
// Pre-commit hook generation moved to generator.js via getTools() manifest
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
module.exports = NextjsAdapter;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLC Kernel — Ruby on Rails Stack Adapter
|
|
3
|
+
* Supports Rails, RSpec, RuboCop AST, Brakeman Security, and migration idempotency.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const BaseAdapter = require('./base');
|
|
9
|
+
|
|
10
|
+
class RailsAdapter extends BaseAdapter {
|
|
11
|
+
constructor() {
|
|
12
|
+
super('Ruby on Rails', 'backend', 'RSpec / Minitest');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
detect(targetDir) {
|
|
16
|
+
const hasGemfile = fs.existsSync(path.join(targetDir, 'Gemfile'));
|
|
17
|
+
const hasRailsRoute = fs.existsSync(path.join(targetDir, 'config', 'routes.rb'));
|
|
18
|
+
return hasGemfile && hasRailsRoute;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
getSafeguards() {
|
|
22
|
+
return [
|
|
23
|
+
'RuboCop Code Style & AST Security Guard',
|
|
24
|
+
'Brakeman Rails Vulnerability Scanner',
|
|
25
|
+
'Rails Migration Idempotency Guard (schema drift protection)',
|
|
26
|
+
'RSpec / Minitest Red-to-Green TDD Validator',
|
|
27
|
+
'Secret & Private Credential Leak Scanner',
|
|
28
|
+
'Educational Audit Gate (05-audit-report.md)',
|
|
29
|
+
'Memory Guard (Engram / Graphify ADR Sync)'
|
|
30
|
+
];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Returns the tool manifest for Rails projects.
|
|
35
|
+
* External CLIs only — no custom guard scripts bundled.
|
|
36
|
+
* @returns {Array<{name: string, language: string, path: string, command: string, description: string, extCLI?: string}>}
|
|
37
|
+
*/
|
|
38
|
+
getTools() {
|
|
39
|
+
const baseTools = [
|
|
40
|
+
{ name: 'check_custom', language: 'js', path: 'check_custom.js', command: 'node tools/check_custom.js', description: 'Runs user-defined custom rules from .clc-forge.yml' },
|
|
41
|
+
{ name: 'rubocop', language: 'external', path: '', command: 'bundle exec rubocop --parallel', description: 'Ruby linter', extCLI: 'rubocop' },
|
|
42
|
+
{ name: 'brakeman', language: 'external', path: '', command: 'bundle exec brakeman -q', description: 'Rails vulnerability scanner', extCLI: 'brakeman' },
|
|
43
|
+
{ name: 'rspec', language: 'external', path: '', command: 'bundle exec rspec', description: 'Test runner', extCLI: 'rspec' },
|
|
44
|
+
];
|
|
45
|
+
return this._mergeTechTools(baseTools);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
provision(targetDir, config) {
|
|
49
|
+
super.provision(targetDir, config);
|
|
50
|
+
// Pre-commit hook generation moved to generator.js via getTools() manifest
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
module.exports = RailsAdapter;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLC Kernel — Rust Stack Adapter
|
|
3
|
+
* Supports Rust, `cargo test`, `cargo clippy`, `cargo audit`, and memory safety.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const BaseAdapter = require('./base');
|
|
9
|
+
|
|
10
|
+
class RustAdapter extends BaseAdapter {
|
|
11
|
+
constructor() {
|
|
12
|
+
super('Rust Engine', 'backend', 'cargo test');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
detect(targetDir) {
|
|
16
|
+
return fs.existsSync(path.join(targetDir, 'Cargo.toml'));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
getSafeguards() {
|
|
20
|
+
return [
|
|
21
|
+
'cargo clippy AST Code Quality Linter',
|
|
22
|
+
'cargo audit Security Vulnerability Scanner',
|
|
23
|
+
'cargo test Red-to-Green TDD Validator',
|
|
24
|
+
'Secret & Private Key Leak Scanner',
|
|
25
|
+
'Educational Audit Gate (05-audit-report.md)',
|
|
26
|
+
'Memory Guard (Engram / Graphify ADR Sync)'
|
|
27
|
+
];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Returns the tool manifest for Rust projects.
|
|
32
|
+
* External CLIs only — no custom guard scripts bundled.
|
|
33
|
+
* @returns {Array<{name: string, language: string, path: string, command: string, description: string, extCLI?: string}>}
|
|
34
|
+
*/
|
|
35
|
+
getTools() {
|
|
36
|
+
const baseTools = [
|
|
37
|
+
{ name: 'check_custom', language: 'js', path: 'check_custom.js', command: 'node tools/check_custom.js', description: 'Runs user-defined custom rules from .clc-forge.yml' },
|
|
38
|
+
{ name: 'cargo_clippy', language: 'external', path: '', command: 'cargo clippy -- -D warnings', description: 'Rust linter and static analysis', extCLI: 'clippy' },
|
|
39
|
+
{ name: 'cargo_audit', language: 'external', path: '', command: 'cargo audit', description: 'Security vulnerability scanner', extCLI: 'cargo-audit' },
|
|
40
|
+
{ name: 'cargo_test', language: 'external', path: '', command: 'cargo test', description: 'Rust test runner', extCLI: 'cargo' },
|
|
41
|
+
];
|
|
42
|
+
return this._mergeTechTools(baseTools);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
provision(targetDir, config) {
|
|
46
|
+
super.provision(targetDir, config);
|
|
47
|
+
// Pre-commit hook generation moved to generator.js via getTools() manifest
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
module.exports = RustAdapter;
|