telos-framework 0.1.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/LICENSE +21 -0
- package/README.md +245 -0
- package/USAGE.md +337 -0
- package/bin/telos-cli.js +41 -0
- package/lib/commands/init.js +112 -0
- package/lib/commands/rediscover.js +48 -0
- package/lib/commands/status.js +77 -0
- package/lib/commands/validate.js +148 -0
- package/lib/discovery/code-scanner.js +129 -0
- package/lib/discovery/hierarchy-builder.js +147 -0
- package/lib/discovery/mcp-discovery.js +90 -0
- package/lib/discovery/telos-discovery.js +69 -0
- package/lib/discovery/tool-mapper.js +151 -0
- package/lib/generators/agent-generator.js +374 -0
- package/lib/generators/agents-md-generator.js +73 -0
- package/lib/generators/all-agents-generator.js +196 -0
- package/lib/generators/logos-md-generator.js +192 -0
- package/lib/generators/telos-md-generator.js +121 -0
- package/lib/generators/tools-md-generator.js +204 -0
- package/lib/integration/capability-abstraction.js +162 -0
- package/lib/integration/graceful-degradation.js +152 -0
- package/lib/integration/mcp-client.js +109 -0
- package/lib/integration/tool-config-writers.js +142 -0
- package/lib/integration/tool-invoker.js +166 -0
- package/lib/platform/platform-detector.js +74 -0
- package/lib/platform/symlink-creator.js +103 -0
- package/lib/spec/spec-formatter.js +79 -0
- package/lib/spec/spec-translator.js +150 -0
- package/lib/spec/validation-cascade.js +156 -0
- package/logos/orchestrator.js +139 -0
- package/logos/state-manager.js +137 -0
- package/package.json +59 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
const fs = require('fs').promises;
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const os = require('os');
|
|
4
|
+
|
|
5
|
+
async function discoverMcpServers() {
|
|
6
|
+
const servers = [];
|
|
7
|
+
|
|
8
|
+
const configPaths = [
|
|
9
|
+
path.join(os.homedir(), '.config', 'claude', 'claude_desktop_config.json'),
|
|
10
|
+
path.join(os.homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json'),
|
|
11
|
+
path.join(os.homedir(), 'AppData', 'Roaming', 'Claude', 'config.json')
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
for (const configPath of configPaths) {
|
|
15
|
+
try {
|
|
16
|
+
const content = await fs.readFile(configPath, 'utf8');
|
|
17
|
+
const config = JSON.parse(content);
|
|
18
|
+
|
|
19
|
+
if (config.mcpServers) {
|
|
20
|
+
for (const [name, serverConfig] of Object.entries(config.mcpServers)) {
|
|
21
|
+
servers.push({
|
|
22
|
+
name,
|
|
23
|
+
command: serverConfig.command,
|
|
24
|
+
args: serverConfig.args || [],
|
|
25
|
+
env: serverConfig.env || {}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
} catch (error) {
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return servers;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function mapMcpToCapabilities(servers) {
|
|
38
|
+
const capabilities = {
|
|
39
|
+
L1: [],
|
|
40
|
+
L2: [],
|
|
41
|
+
L3: [],
|
|
42
|
+
L4: [],
|
|
43
|
+
L5: [],
|
|
44
|
+
L6: [],
|
|
45
|
+
L7: [],
|
|
46
|
+
L8: [],
|
|
47
|
+
L9: []
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
for (const server of servers) {
|
|
51
|
+
const name = server.name.toLowerCase();
|
|
52
|
+
|
|
53
|
+
if (name.includes('filesystem') || name.includes('file')) {
|
|
54
|
+
capabilities.L1.push({ server: server.name, capability: 'file-operations' });
|
|
55
|
+
capabilities.L2.push({ server: server.name, capability: 'file-read-write' });
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (name.includes('github') || name.includes('git')) {
|
|
59
|
+
capabilities.L3.push({ server: server.name, capability: 'version-control' });
|
|
60
|
+
capabilities.L4.push({ server: server.name, capability: 'ci-cd-integration' });
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (name.includes('brave') || name.includes('browser') || name.includes('chrome')) {
|
|
64
|
+
capabilities.L5.push({ server: server.name, capability: 'browser-automation' });
|
|
65
|
+
capabilities.L6.push({ server: server.name, capability: 'ux-testing' });
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (name.includes('postgres') || name.includes('database') || name.includes('mysql')) {
|
|
69
|
+
capabilities.L4.push({ server: server.name, capability: 'database-access' });
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (name.includes('fetch') || name.includes('web') || name.includes('http')) {
|
|
73
|
+
capabilities.L4.push({ server: server.name, capability: 'api-testing' });
|
|
74
|
+
capabilities.L7.push({ server: server.name, capability: 'web-research' });
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (name.includes('slack') || name.includes('email')) {
|
|
78
|
+
capabilities.L7.push({ server: server.name, capability: 'user-feedback' });
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (name.includes('analytics') || name.includes('metrics')) {
|
|
82
|
+
capabilities.L7.push({ server: server.name, capability: 'analytics' });
|
|
83
|
+
capabilities.L8.push({ server: server.name, capability: 'business-metrics' });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return capabilities;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
module.exports = { discoverMcpServers, mapMcpToCapabilities };
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
const inquirer = require('inquirer');
|
|
2
|
+
const chalk = require('chalk');
|
|
3
|
+
|
|
4
|
+
async function discoverTelos(options = {}) {
|
|
5
|
+
console.log(chalk.cyan('\n=== Telos Discovery ===\n'));
|
|
6
|
+
console.log('Let\'s discover the ultimate purpose of your software.\n');
|
|
7
|
+
|
|
8
|
+
const answers = {};
|
|
9
|
+
|
|
10
|
+
answers.purpose = await inquirer.prompt([
|
|
11
|
+
{
|
|
12
|
+
type: 'input',
|
|
13
|
+
name: 'value',
|
|
14
|
+
message: 'What is the ultimate purpose of your software?\n (Why does this project exist?)',
|
|
15
|
+
validate: (input) => input.trim().length > 0 || 'Purpose cannot be empty'
|
|
16
|
+
}
|
|
17
|
+
]).then(a => a.value);
|
|
18
|
+
|
|
19
|
+
answers.beneficiaries = await inquirer.prompt([
|
|
20
|
+
{
|
|
21
|
+
type: 'input',
|
|
22
|
+
name: 'value',
|
|
23
|
+
message: 'Who ultimately benefits from achieving this purpose?',
|
|
24
|
+
validate: (input) => input.trim().length > 0 || 'Beneficiaries cannot be empty'
|
|
25
|
+
}
|
|
26
|
+
]).then(a => a.value);
|
|
27
|
+
|
|
28
|
+
answers.impact = await inquirer.prompt([
|
|
29
|
+
{
|
|
30
|
+
type: 'input',
|
|
31
|
+
name: 'value',
|
|
32
|
+
message: 'What measurable impact defines success?',
|
|
33
|
+
validate: (input) => input.trim().length > 0 || 'Impact cannot be empty'
|
|
34
|
+
}
|
|
35
|
+
]).then(a => a.value);
|
|
36
|
+
|
|
37
|
+
answers.constraints = await inquirer.prompt([
|
|
38
|
+
{
|
|
39
|
+
type: 'input',
|
|
40
|
+
name: 'value',
|
|
41
|
+
message: 'What ethical or practical constraints guide this purpose?',
|
|
42
|
+
default: 'None specified'
|
|
43
|
+
}
|
|
44
|
+
]).then(a => a.value);
|
|
45
|
+
|
|
46
|
+
const { confirm } = await inquirer.prompt([
|
|
47
|
+
{
|
|
48
|
+
type: 'confirm',
|
|
49
|
+
name: 'confirm',
|
|
50
|
+
message: `\nYour Telos:\n ${chalk.bold(answers.purpose)}\n\nIs this correct?`,
|
|
51
|
+
default: true
|
|
52
|
+
}
|
|
53
|
+
]);
|
|
54
|
+
|
|
55
|
+
if (!confirm) {
|
|
56
|
+
console.log(chalk.yellow('Let\'s try again...\n'));
|
|
57
|
+
return discoverTelos(options);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
telos: answers.purpose,
|
|
62
|
+
beneficiaries: answers.beneficiaries,
|
|
63
|
+
impact: answers.impact,
|
|
64
|
+
constraints: answers.constraints,
|
|
65
|
+
timestamp: new Date().toISOString()
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
module.exports = { discoverTelos };
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
function mapToolsToLevels(projectScan, mcpCapabilities) {
|
|
2
|
+
const levelTools = {
|
|
3
|
+
L1: {
|
|
4
|
+
level: 'L1',
|
|
5
|
+
name: 'Syntax-Linter',
|
|
6
|
+
tools: []
|
|
7
|
+
},
|
|
8
|
+
L2: {
|
|
9
|
+
level: 'L2',
|
|
10
|
+
name: 'Function-Author',
|
|
11
|
+
tools: []
|
|
12
|
+
},
|
|
13
|
+
L3: {
|
|
14
|
+
level: 'L3',
|
|
15
|
+
name: 'Component-Architect',
|
|
16
|
+
tools: []
|
|
17
|
+
},
|
|
18
|
+
L4: {
|
|
19
|
+
level: 'L4',
|
|
20
|
+
name: 'Integration-Contractor',
|
|
21
|
+
tools: []
|
|
22
|
+
},
|
|
23
|
+
L5: {
|
|
24
|
+
level: 'L5',
|
|
25
|
+
name: 'Journey-Validator',
|
|
26
|
+
tools: []
|
|
27
|
+
},
|
|
28
|
+
L6: {
|
|
29
|
+
level: 'L6',
|
|
30
|
+
name: 'UX-Simulator',
|
|
31
|
+
tools: []
|
|
32
|
+
},
|
|
33
|
+
L7: {
|
|
34
|
+
level: 'L7',
|
|
35
|
+
name: 'Insight-Synthesizer',
|
|
36
|
+
tools: []
|
|
37
|
+
},
|
|
38
|
+
L8: {
|
|
39
|
+
level: 'L8',
|
|
40
|
+
name: 'Market-Analyst',
|
|
41
|
+
tools: []
|
|
42
|
+
},
|
|
43
|
+
L9: {
|
|
44
|
+
level: 'L9',
|
|
45
|
+
name: 'Telos-Guardian',
|
|
46
|
+
tools: []
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
for (const linter of projectScan.linters || []) {
|
|
51
|
+
levelTools.L1.tools.push({
|
|
52
|
+
name: linter,
|
|
53
|
+
category: 'linter',
|
|
54
|
+
capability: 'static-analysis'
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
for (const testFw of projectScan.testFrameworks || []) {
|
|
59
|
+
if (testFw === 'Playwright' || testFw === 'Cypress') {
|
|
60
|
+
levelTools.L5.tools.push({
|
|
61
|
+
name: testFw,
|
|
62
|
+
category: 'e2e-testing',
|
|
63
|
+
capability: 'journey-validation'
|
|
64
|
+
});
|
|
65
|
+
} else {
|
|
66
|
+
levelTools.L2.tools.push({
|
|
67
|
+
name: testFw,
|
|
68
|
+
category: 'unit-testing',
|
|
69
|
+
capability: 'function-testing'
|
|
70
|
+
});
|
|
71
|
+
levelTools.L3.tools.push({
|
|
72
|
+
name: testFw,
|
|
73
|
+
category: 'component-testing',
|
|
74
|
+
capability: 'component-validation'
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
for (const framework of projectScan.frameworks || []) {
|
|
80
|
+
if (framework.includes('React') || framework.includes('Vue') || framework.includes('Svelte') || framework.includes('Angular')) {
|
|
81
|
+
levelTools.L3.tools.push({
|
|
82
|
+
name: framework,
|
|
83
|
+
category: 'ui-framework',
|
|
84
|
+
capability: 'component-building'
|
|
85
|
+
});
|
|
86
|
+
levelTools.L6.tools.push({
|
|
87
|
+
name: framework,
|
|
88
|
+
category: 'ux-framework',
|
|
89
|
+
capability: 'user-interface'
|
|
90
|
+
});
|
|
91
|
+
} else {
|
|
92
|
+
levelTools.L4.tools.push({
|
|
93
|
+
name: framework,
|
|
94
|
+
category: 'backend-framework',
|
|
95
|
+
capability: 'api-implementation'
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
for (const [level, caps] of Object.entries(mcpCapabilities)) {
|
|
101
|
+
for (const cap of caps) {
|
|
102
|
+
levelTools[level].tools.push({
|
|
103
|
+
name: cap.server,
|
|
104
|
+
category: 'mcp-server',
|
|
105
|
+
capability: cap.capability
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return levelTools;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function getToolRecommendations(levelTools) {
|
|
114
|
+
const recommendations = [];
|
|
115
|
+
|
|
116
|
+
if (levelTools.L1.tools.length === 0) {
|
|
117
|
+
recommendations.push({
|
|
118
|
+
level: 'L1',
|
|
119
|
+
message: 'No linters detected. Consider adding ESLint or Prettier.',
|
|
120
|
+
priority: 'medium'
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (levelTools.L2.tools.length === 0) {
|
|
125
|
+
recommendations.push({
|
|
126
|
+
level: 'L2',
|
|
127
|
+
message: 'No test framework detected. Consider adding Vitest or Jest.',
|
|
128
|
+
priority: 'high'
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (levelTools.L5.tools.length === 0) {
|
|
133
|
+
recommendations.push({
|
|
134
|
+
level: 'L5',
|
|
135
|
+
message: 'No E2E testing framework detected. Consider adding Playwright.',
|
|
136
|
+
priority: 'medium'
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (levelTools.L7.tools.length === 0) {
|
|
141
|
+
recommendations.push({
|
|
142
|
+
level: 'L7',
|
|
143
|
+
message: 'No analytics tools detected. Consider user feedback mechanisms.',
|
|
144
|
+
priority: 'low'
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return recommendations;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
module.exports = { mapToolsToLevels, getToolRecommendations };
|
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
const fs = require('fs').promises;
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
async function generateL9Agent(hierarchy, outputPath) {
|
|
5
|
+
const l9 = hierarchy.L9;
|
|
6
|
+
|
|
7
|
+
const content = `# L9: Telos-Guardian
|
|
8
|
+
|
|
9
|
+
**Role**: Strategic Alignment Validator
|
|
10
|
+
|
|
11
|
+
## Your Mandate
|
|
12
|
+
|
|
13
|
+
You are the Telos-Guardian, the highest-level agent in this multi-agent collective. Your purpose is to ensure that all development activities serve the ultimate Telos:
|
|
14
|
+
|
|
15
|
+
> **${l9.purpose}**
|
|
16
|
+
|
|
17
|
+
## Ultimate Purpose Details
|
|
18
|
+
|
|
19
|
+
- **Beneficiaries**: ${l9.beneficiaries}
|
|
20
|
+
- **Success Impact**: ${l9.impact}
|
|
21
|
+
- **Constraints**: ${l9.constraints}
|
|
22
|
+
|
|
23
|
+
## Your Responsibilities
|
|
24
|
+
|
|
25
|
+
1. **Strategic Validation**: Review all major changes for alignment with the Telos
|
|
26
|
+
2. **Purpose Clarification**: Resolve ambiguities by referring back to ultimate purpose
|
|
27
|
+
3. **Conflict Resolution**: When lower levels conflict, appeal to Telos for guidance
|
|
28
|
+
4. **Vision Protection**: Prevent scope creep and mission drift
|
|
29
|
+
|
|
30
|
+
## When You Are Invoked
|
|
31
|
+
|
|
32
|
+
- New feature proposals (validate strategic fit)
|
|
33
|
+
- Architectural decisions with long-term implications
|
|
34
|
+
- Conflicts between lower-level agents
|
|
35
|
+
- Product direction questions
|
|
36
|
+
- Quarterly/milestone reviews
|
|
37
|
+
|
|
38
|
+
## Your Tools
|
|
39
|
+
|
|
40
|
+
- Strategic documents (PRD, vision docs, roadmaps)
|
|
41
|
+
- Business metrics and KPIs
|
|
42
|
+
- User research and market analysis
|
|
43
|
+
- Historical decision logs
|
|
44
|
+
|
|
45
|
+
## Communication Protocol
|
|
46
|
+
|
|
47
|
+
### Input Format
|
|
48
|
+
You receive structured requests from Logos orchestrator:
|
|
49
|
+
|
|
50
|
+
\`\`\`
|
|
51
|
+
TELOS VALIDATION REQUEST
|
|
52
|
+
Change: [description]
|
|
53
|
+
Proposed by: [agent level]
|
|
54
|
+
Rationale: [why this serves lower-level purpose]
|
|
55
|
+
REQUEST: Does this serve our ultimate Telos?
|
|
56
|
+
\`\`\`
|
|
57
|
+
|
|
58
|
+
### Output Format
|
|
59
|
+
Respond with structured validation:
|
|
60
|
+
|
|
61
|
+
\`\`\`
|
|
62
|
+
TELOS VALIDATION RESPONSE
|
|
63
|
+
Change: [description]
|
|
64
|
+
Alignment: [ALIGNED | MISALIGNED | CONDITIONAL]
|
|
65
|
+
Reasoning: [explanation tied to Telos]
|
|
66
|
+
Recommendation: [APPROVE | REJECT | MODIFY]
|
|
67
|
+
Modification needed: [if CONDITIONAL/MODIFY]
|
|
68
|
+
\`\`\`
|
|
69
|
+
|
|
70
|
+
## Validation Criteria
|
|
71
|
+
|
|
72
|
+
Ask these questions:
|
|
73
|
+
1. Does this advance our stated purpose: "${l9.purpose}"?
|
|
74
|
+
2. Does this benefit ${l9.beneficiaries}?
|
|
75
|
+
3. Does this contribute to ${l9.impact}?
|
|
76
|
+
4. Does this respect ${l9.constraints}?
|
|
77
|
+
5. Is there a better alternative more aligned with our Telos?
|
|
78
|
+
|
|
79
|
+
If any answer is "no," investigate why and recommend alternatives.
|
|
80
|
+
|
|
81
|
+
## Examples
|
|
82
|
+
|
|
83
|
+
### Aligned Change
|
|
84
|
+
\`\`\`
|
|
85
|
+
Change: Add accessibility features to core interface
|
|
86
|
+
Alignment: ALIGNED
|
|
87
|
+
Reasoning: Directly serves beneficiaries (${l9.beneficiaries}) by removing barriers to access, advancing our purpose of ${l9.purpose}
|
|
88
|
+
Recommendation: APPROVE
|
|
89
|
+
\`\`\`
|
|
90
|
+
|
|
91
|
+
### Misaligned Change
|
|
92
|
+
\`\`\`
|
|
93
|
+
Change: Add social media sharing to increase virality
|
|
94
|
+
Alignment: MISALIGNED
|
|
95
|
+
Reasoning: While potentially increasing reach, this doesn't directly serve our Telos. Our purpose is ${l9.purpose}, not viral growth. Could distract from core mission.
|
|
96
|
+
Recommendation: REJECT
|
|
97
|
+
Alternative: Focus on core value delivery that organically attracts users
|
|
98
|
+
\`\`\`
|
|
99
|
+
|
|
100
|
+
### Conditional Change
|
|
101
|
+
\`\`\`
|
|
102
|
+
Change: Implement premium tier pricing
|
|
103
|
+
Alignment: CONDITIONAL
|
|
104
|
+
Reasoning: Could serve Telos if revenue funds mission-critical features, but risks excluding beneficiaries (${l9.beneficiaries})
|
|
105
|
+
Recommendation: MODIFY
|
|
106
|
+
Modification needed: Ensure free tier preserves core value; premium only for advanced features
|
|
107
|
+
\`\`\`
|
|
108
|
+
|
|
109
|
+
## Remember
|
|
110
|
+
|
|
111
|
+
You are the guardian of meaning. Every line of code should ultimately serve our Telos. When in doubt, ask: "Why are we building this software?" The answer is always:
|
|
112
|
+
|
|
113
|
+
**${l9.purpose}**
|
|
114
|
+
|
|
115
|
+
Hold this truth immutable.
|
|
116
|
+
`;
|
|
117
|
+
|
|
118
|
+
await fs.mkdir(path.dirname(outputPath), { recursive: true });
|
|
119
|
+
await fs.writeFile(outputPath, content, 'utf8');
|
|
120
|
+
|
|
121
|
+
return outputPath;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async function generateL1Agent(hierarchy, tools, outputPath) {
|
|
125
|
+
const l1 = hierarchy.L1;
|
|
126
|
+
const linters = tools.filter(t => t.category === 'linter');
|
|
127
|
+
|
|
128
|
+
const toolsList = linters.length > 0
|
|
129
|
+
? linters.map(t => `- **${t.name}**: ${t.capability}`).join('\n')
|
|
130
|
+
: '- *No automated linters detected - manual code review required*';
|
|
131
|
+
|
|
132
|
+
const content = `# L1: Syntax-Linter
|
|
133
|
+
|
|
134
|
+
**Role**: Code Structure & Quality Validator
|
|
135
|
+
|
|
136
|
+
## Your Mandate
|
|
137
|
+
|
|
138
|
+
You are the Syntax-Linter, the foundational agent ensuring code structural integrity. Your purpose:
|
|
139
|
+
|
|
140
|
+
> **${l1.purpose}**
|
|
141
|
+
|
|
142
|
+
This serves the ultimate Telos by maintaining a clean, maintainable codebase foundation.
|
|
143
|
+
|
|
144
|
+
## Your Responsibilities
|
|
145
|
+
|
|
146
|
+
1. **Syntax Validation**: Ensure code follows language syntax rules
|
|
147
|
+
2. **Style Enforcement**: Apply consistent formatting and naming conventions
|
|
148
|
+
3. **Static Analysis**: Detect code smells and anti-patterns
|
|
149
|
+
4. **Import/Dependency Check**: Validate module imports and dependencies
|
|
150
|
+
|
|
151
|
+
## Available Tools
|
|
152
|
+
|
|
153
|
+
${toolsList}
|
|
154
|
+
|
|
155
|
+
## When You Are Invoked
|
|
156
|
+
|
|
157
|
+
- Before any code is committed
|
|
158
|
+
- During PR reviews
|
|
159
|
+
- As part of CI/CD pipeline
|
|
160
|
+
- When code quality degrades
|
|
161
|
+
|
|
162
|
+
## Communication Protocol
|
|
163
|
+
|
|
164
|
+
### Input Format
|
|
165
|
+
\`\`\`
|
|
166
|
+
LINT REQUEST
|
|
167
|
+
Files: [list of file paths]
|
|
168
|
+
Context: [what changed]
|
|
169
|
+
REQUEST: Validate code structure
|
|
170
|
+
\`\`\`
|
|
171
|
+
|
|
172
|
+
### Output Format
|
|
173
|
+
\`\`\`
|
|
174
|
+
LINT RESPONSE
|
|
175
|
+
Files checked: [count]
|
|
176
|
+
Issues found: [count]
|
|
177
|
+
Critical: [list]
|
|
178
|
+
Warnings: [list]
|
|
179
|
+
Status: [PASS | FAIL | WARNINGS]
|
|
180
|
+
\`\`\`
|
|
181
|
+
|
|
182
|
+
## Validation Process
|
|
183
|
+
|
|
184
|
+
1. Run available linters on changed files
|
|
185
|
+
2. Check for:
|
|
186
|
+
- Syntax errors
|
|
187
|
+
- Formatting inconsistencies
|
|
188
|
+
- Unused imports/variables
|
|
189
|
+
- Code complexity violations
|
|
190
|
+
- Security vulnerabilities (basic)
|
|
191
|
+
3. Categorize issues by severity
|
|
192
|
+
4. Report with actionable fixes
|
|
193
|
+
|
|
194
|
+
## Integration with Higher Levels
|
|
195
|
+
|
|
196
|
+
- Reports to **L2 Function-Author**: "Code structure is sound, ready for logic implementation"
|
|
197
|
+
- Escalates to **L2** when structural issues require refactoring
|
|
198
|
+
|
|
199
|
+
## Example Scenarios
|
|
200
|
+
|
|
201
|
+
### Pass
|
|
202
|
+
\`\`\`
|
|
203
|
+
Files checked: 3
|
|
204
|
+
Issues found: 0
|
|
205
|
+
Status: PASS
|
|
206
|
+
All files meet code quality standards.
|
|
207
|
+
\`\`\`
|
|
208
|
+
|
|
209
|
+
### Warnings
|
|
210
|
+
\`\`\`
|
|
211
|
+
Files checked: 5
|
|
212
|
+
Issues found: 7
|
|
213
|
+
Warnings:
|
|
214
|
+
- src/utils.js:23 - Unused variable 'temp'
|
|
215
|
+
- src/api.js:45 - Line exceeds 100 characters
|
|
216
|
+
Status: WARNINGS
|
|
217
|
+
Recommend fixing before commit.
|
|
218
|
+
\`\`\`
|
|
219
|
+
|
|
220
|
+
### Fail
|
|
221
|
+
\`\`\`
|
|
222
|
+
Files checked: 2
|
|
223
|
+
Issues found: 3
|
|
224
|
+
Critical:
|
|
225
|
+
- src/auth.js:12 - Syntax error: unexpected token
|
|
226
|
+
- src/db.js:56 - Import not found: './config'
|
|
227
|
+
Status: FAIL
|
|
228
|
+
Cannot proceed until critical issues resolved.
|
|
229
|
+
\`\`\`
|
|
230
|
+
|
|
231
|
+
## Remember
|
|
232
|
+
|
|
233
|
+
Clean code structure is the foundation. Without L1 integrity, higher-level abstractions crumble. Hold the line on quality.
|
|
234
|
+
`;
|
|
235
|
+
|
|
236
|
+
await fs.mkdir(path.dirname(outputPath), { recursive: true });
|
|
237
|
+
await fs.writeFile(outputPath, content, 'utf8');
|
|
238
|
+
|
|
239
|
+
return outputPath;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
async function generateL2Agent(hierarchy, tools, outputPath) {
|
|
243
|
+
const l2 = hierarchy.L2;
|
|
244
|
+
const testTools = tools.filter(t => t.category === 'unit-testing');
|
|
245
|
+
|
|
246
|
+
const toolsList = testTools.length > 0
|
|
247
|
+
? testTools.map(t => `- **${t.name}**: ${t.capability}`).join('\n')
|
|
248
|
+
: '- *No unit test framework detected - manual testing required*';
|
|
249
|
+
|
|
250
|
+
const content = `# L2: Function-Author
|
|
251
|
+
|
|
252
|
+
**Role**: Unit Logic & TDD Implementer
|
|
253
|
+
|
|
254
|
+
## Your Mandate
|
|
255
|
+
|
|
256
|
+
You are the Function-Author, responsible for implementing discrete units of behavior. Your purpose:
|
|
257
|
+
|
|
258
|
+
> **${l2.purpose}**
|
|
259
|
+
|
|
260
|
+
This serves the ultimate Telos through reliable, tested building blocks.
|
|
261
|
+
|
|
262
|
+
## Your Responsibilities
|
|
263
|
+
|
|
264
|
+
1. **TDD Implementation**: Write tests first, then code
|
|
265
|
+
2. **Pure Functions**: Prefer stateless, predictable behavior
|
|
266
|
+
3. **Error Handling**: Graceful failure modes
|
|
267
|
+
4. **Unit Testing**: Comprehensive test coverage
|
|
268
|
+
|
|
269
|
+
## Available Tools
|
|
270
|
+
|
|
271
|
+
${toolsList}
|
|
272
|
+
|
|
273
|
+
## When You Are Invoked
|
|
274
|
+
|
|
275
|
+
- Implementing new functions/methods
|
|
276
|
+
- Fixing unit-level bugs
|
|
277
|
+
- Refactoring existing logic
|
|
278
|
+
- Adding test coverage
|
|
279
|
+
|
|
280
|
+
## Development Protocol
|
|
281
|
+
|
|
282
|
+
### RED → GREEN → REFACTOR
|
|
283
|
+
|
|
284
|
+
1. **RED**: Write failing test
|
|
285
|
+
2. **GREEN**: Write minimal code to pass
|
|
286
|
+
3. **REFACTOR**: Improve while keeping tests green
|
|
287
|
+
|
|
288
|
+
### Input Format
|
|
289
|
+
\`\`\`
|
|
290
|
+
FUNCTION REQUEST
|
|
291
|
+
Spec: [function specification]
|
|
292
|
+
Inputs: [parameters]
|
|
293
|
+
Outputs: [return value]
|
|
294
|
+
Context: [serves component X in service of L3 purpose]
|
|
295
|
+
REQUEST: Implement with TDD
|
|
296
|
+
\`\`\`
|
|
297
|
+
|
|
298
|
+
### Output Format
|
|
299
|
+
\`\`\`
|
|
300
|
+
FUNCTION RESPONSE
|
|
301
|
+
Implementation: [code location]
|
|
302
|
+
Tests: [test file location]
|
|
303
|
+
Coverage: [percentage]
|
|
304
|
+
Status: [PASS | FAIL]
|
|
305
|
+
Serves: [L3 component]
|
|
306
|
+
\`\`\`
|
|
307
|
+
|
|
308
|
+
## TDD Workflow
|
|
309
|
+
|
|
310
|
+
\`\`\`javascript
|
|
311
|
+
// 1. RED: Write test first
|
|
312
|
+
describe('calculateDiscount', () => {
|
|
313
|
+
it('should apply 10% discount for premium users', () => {
|
|
314
|
+
expect(calculateDiscount(100, 'premium')).toBe(90);
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
// 2. GREEN: Implement minimal code
|
|
319
|
+
function calculateDiscount(price, tier) {
|
|
320
|
+
if (tier === 'premium') return price * 0.9;
|
|
321
|
+
return price;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// 3. REFACTOR: Improve design
|
|
325
|
+
function calculateDiscount(price, tier) {
|
|
326
|
+
const discounts = { premium: 0.1, vip: 0.2 };
|
|
327
|
+
const discount = discounts[tier] || 0;
|
|
328
|
+
return price * (1 - discount);
|
|
329
|
+
}
|
|
330
|
+
\`\`\`
|
|
331
|
+
|
|
332
|
+
## Integration with Other Levels
|
|
333
|
+
|
|
334
|
+
- Receives specs from **L3 Component-Architect**
|
|
335
|
+
- Validated by **L1 Syntax-Linter**
|
|
336
|
+
- Composed into components by **L3**
|
|
337
|
+
|
|
338
|
+
## Quality Standards
|
|
339
|
+
|
|
340
|
+
- **Test Coverage**: Aim for >80%
|
|
341
|
+
- **Function Size**: Keep functions small (<50 lines)
|
|
342
|
+
- **Complexity**: Cyclomatic complexity <10
|
|
343
|
+
- **Side Effects**: Minimize or isolate
|
|
344
|
+
|
|
345
|
+
## Example Report
|
|
346
|
+
|
|
347
|
+
\`\`\`
|
|
348
|
+
FUNCTION RESPONSE
|
|
349
|
+
Implementation: src/pricing/discount.js
|
|
350
|
+
Tests: src/pricing/discount.test.js
|
|
351
|
+
Coverage: 95%
|
|
352
|
+
Tests: 12 passed, 0 failed
|
|
353
|
+
Status: PASS
|
|
354
|
+
Serves: L3 PricingComponent - enables dynamic pricing logic
|
|
355
|
+
\`\`\`
|
|
356
|
+
|
|
357
|
+
## Remember
|
|
358
|
+
|
|
359
|
+
Functions are atoms of behavior. Each must be:
|
|
360
|
+
- **Tested**: No untested code
|
|
361
|
+
- **Pure** (when possible): Same input → same output
|
|
362
|
+
- **Focused**: One responsibility
|
|
363
|
+
- **Composable**: Works with other functions
|
|
364
|
+
|
|
365
|
+
Your work enables higher abstractions. Be rigorous.
|
|
366
|
+
`;
|
|
367
|
+
|
|
368
|
+
await fs.mkdir(path.dirname(outputPath), { recursive: true });
|
|
369
|
+
await fs.writeFile(outputPath, content, 'utf8');
|
|
370
|
+
|
|
371
|
+
return outputPath;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
module.exports = { generateL9Agent, generateL1Agent, generateL2Agent };
|