create-universal-ai-context 2.0.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 +171 -0
- package/bin/create-ai-context.js +337 -0
- package/lib/adapters/antigravity.js +160 -0
- package/lib/adapters/claude.js +122 -0
- package/lib/adapters/cline.js +111 -0
- package/lib/adapters/copilot.js +117 -0
- package/lib/adapters/index.js +69 -0
- package/lib/ai-context-generator.js +234 -0
- package/lib/ai-orchestrator.js +431 -0
- package/lib/call-tracer.js +444 -0
- package/lib/detector.js +726 -0
- package/lib/environment-detector.js +239 -0
- package/lib/index.js +310 -0
- package/lib/installer.js +418 -0
- package/lib/migrate.js +319 -0
- package/lib/placeholder.js +541 -0
- package/lib/prompts.js +287 -0
- package/lib/spinner.js +60 -0
- package/lib/static-analyzer.js +729 -0
- package/lib/template-populator.js +843 -0
- package/lib/template-renderer.js +382 -0
- package/lib/validate.js +155 -0
- package/package.json +70 -0
- package/templates/AI_CONTEXT.md.template +245 -0
- package/templates/base/README.md +257 -0
- package/templates/base/RPI_WORKFLOW_PLAN.md +320 -0
- package/templates/base/agents/api-developer.md +76 -0
- package/templates/base/agents/context-engineer.md +525 -0
- package/templates/base/agents/core-architect.md +76 -0
- package/templates/base/agents/database-ops.md +76 -0
- package/templates/base/agents/deployment-ops.md +76 -0
- package/templates/base/agents/integration-hub.md +76 -0
- package/templates/base/analytics/README.md +114 -0
- package/templates/base/automation/config.json +58 -0
- package/templates/base/automation/generators/code-mapper.js +308 -0
- package/templates/base/automation/generators/index-builder.js +321 -0
- package/templates/base/automation/hooks/post-commit.sh +83 -0
- package/templates/base/automation/hooks/pre-commit.sh +103 -0
- package/templates/base/ci-templates/README.md +108 -0
- package/templates/base/ci-templates/github-actions/context-check.yml +144 -0
- package/templates/base/ci-templates/github-actions/validate-docs.yml +105 -0
- package/templates/base/commands/analytics.md +238 -0
- package/templates/base/commands/auto-sync.md +172 -0
- package/templates/base/commands/collab.md +194 -0
- package/templates/base/commands/help.md +450 -0
- package/templates/base/commands/rpi-implement.md +115 -0
- package/templates/base/commands/rpi-plan.md +93 -0
- package/templates/base/commands/rpi-research.md +88 -0
- package/templates/base/commands/session-resume.md +144 -0
- package/templates/base/commands/session-save.md +112 -0
- package/templates/base/commands/validate-all.md +77 -0
- package/templates/base/commands/verify-docs-current.md +86 -0
- package/templates/base/config/base.json +57 -0
- package/templates/base/config/environments/development.json +13 -0
- package/templates/base/config/environments/production.json +17 -0
- package/templates/base/config/environments/staging.json +13 -0
- package/templates/base/config/local.json.example +21 -0
- package/templates/base/context/.meta/generated-at.json +18 -0
- package/templates/base/context/ARCHITECTURE_SNAPSHOT.md +156 -0
- package/templates/base/context/CODE_TO_WORKFLOW_MAP.md +94 -0
- package/templates/base/context/FILE_OWNERSHIP.md +57 -0
- package/templates/base/context/INTEGRATION_POINTS.md +92 -0
- package/templates/base/context/KNOWN_GOTCHAS.md +195 -0
- package/templates/base/context/TESTING_MAP.md +95 -0
- package/templates/base/context/WORKFLOW_INDEX.md +129 -0
- package/templates/base/context/workflows/WORKFLOW_TEMPLATE.md +294 -0
- package/templates/base/indexes/agents/CAPABILITY_MATRIX.md +255 -0
- package/templates/base/indexes/agents/CATEGORY_INDEX.md +44 -0
- package/templates/base/indexes/code/CATEGORY_INDEX.md +38 -0
- package/templates/base/indexes/routing/CATEGORY_INDEX.md +39 -0
- package/templates/base/indexes/search/CATEGORY_INDEX.md +39 -0
- package/templates/base/indexes/workflows/CATEGORY_INDEX.md +38 -0
- package/templates/base/knowledge/README.md +98 -0
- package/templates/base/knowledge/sessions/README.md +88 -0
- package/templates/base/knowledge/sessions/TEMPLATE.md +150 -0
- package/templates/base/knowledge/shared/decisions/0001-adopt-context-engineering.md +144 -0
- package/templates/base/knowledge/shared/decisions/README.md +49 -0
- package/templates/base/knowledge/shared/decisions/TEMPLATE.md +123 -0
- package/templates/base/knowledge/shared/patterns/README.md +62 -0
- package/templates/base/knowledge/shared/patterns/TEMPLATE.md +120 -0
- package/templates/base/plans/PLAN_TEMPLATE.md +250 -0
- package/templates/base/plans/active/.gitkeep +0 -0
- package/templates/base/plans/completed/.gitkeep +0 -0
- package/templates/base/research/RESEARCH_TEMPLATE.md +153 -0
- package/templates/base/research/active/.gitkeep +0 -0
- package/templates/base/research/completed/.gitkeep +0 -0
- package/templates/base/schemas/agent.schema.json +141 -0
- package/templates/base/schemas/anchors.schema.json +54 -0
- package/templates/base/schemas/automation.schema.json +93 -0
- package/templates/base/schemas/command.schema.json +134 -0
- package/templates/base/schemas/hashes.schema.json +40 -0
- package/templates/base/schemas/manifest.schema.json +117 -0
- package/templates/base/schemas/plan.schema.json +136 -0
- package/templates/base/schemas/research.schema.json +115 -0
- package/templates/base/schemas/roles.schema.json +34 -0
- package/templates/base/schemas/session.schema.json +77 -0
- package/templates/base/schemas/settings.schema.json +244 -0
- package/templates/base/schemas/staleness.schema.json +53 -0
- package/templates/base/schemas/team-config.schema.json +42 -0
- package/templates/base/schemas/workflow.schema.json +126 -0
- package/templates/base/session/checkpoints/.gitkeep +2 -0
- package/templates/base/session/current/state.json +20 -0
- package/templates/base/session/history/.gitkeep +2 -0
- package/templates/base/settings.json +3 -0
- package/templates/base/standards/COMPATIBILITY.md +219 -0
- package/templates/base/standards/EXTENSION_GUIDELINES.md +280 -0
- package/templates/base/standards/QUALITY_CHECKLIST.md +211 -0
- package/templates/base/standards/README.md +66 -0
- package/templates/base/sync/anchors.json +6 -0
- package/templates/base/sync/hashes.json +6 -0
- package/templates/base/sync/staleness.json +10 -0
- package/templates/base/team/README.md +168 -0
- package/templates/base/team/config.json +79 -0
- package/templates/base/team/roles.json +145 -0
- package/templates/base/tools/bin/claude-context.js +151 -0
- package/templates/base/tools/lib/anchor-resolver.js +276 -0
- package/templates/base/tools/lib/config-loader.js +363 -0
- package/templates/base/tools/lib/detector.js +350 -0
- package/templates/base/tools/lib/diagnose.js +206 -0
- package/templates/base/tools/lib/drift-detector.js +373 -0
- package/templates/base/tools/lib/errors.js +199 -0
- package/templates/base/tools/lib/index.js +36 -0
- package/templates/base/tools/lib/init.js +192 -0
- package/templates/base/tools/lib/logger.js +230 -0
- package/templates/base/tools/lib/placeholder.js +201 -0
- package/templates/base/tools/lib/session-manager.js +354 -0
- package/templates/base/tools/lib/validate.js +521 -0
- package/templates/base/tools/package.json +49 -0
- package/templates/handlebars/antigravity.hbs +337 -0
- package/templates/handlebars/claude.hbs +184 -0
- package/templates/handlebars/cline.hbs +63 -0
- package/templates/handlebars/copilot.hbs +131 -0
- package/templates/handlebars/partials/gotcha-list.hbs +11 -0
- package/templates/handlebars/partials/header.hbs +3 -0
- package/templates/handlebars/partials/workflow-summary.hbs +16 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Adapter
|
|
3
|
+
*
|
|
4
|
+
* Generates AI_CONTEXT.md and .ai-context/ directory structure.
|
|
5
|
+
* This is the primary/universal format.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const { renderTemplateByName, buildContext } = require('../template-renderer');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Adapter metadata
|
|
14
|
+
*/
|
|
15
|
+
const adapter = {
|
|
16
|
+
name: 'claude',
|
|
17
|
+
displayName: 'Claude Code',
|
|
18
|
+
description: 'Universal AI context format for Claude Code and other AI assistants',
|
|
19
|
+
outputType: 'single-file',
|
|
20
|
+
outputPath: 'AI_CONTEXT.md'
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Get output path for Claude context file
|
|
25
|
+
* @param {string} projectRoot - Project root directory
|
|
26
|
+
* @returns {string} Output file path
|
|
27
|
+
*/
|
|
28
|
+
function getOutputPath(projectRoot) {
|
|
29
|
+
return path.join(projectRoot, 'AI_CONTEXT.md');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Check if Claude output already exists
|
|
34
|
+
* @param {string} projectRoot - Project root directory
|
|
35
|
+
* @returns {boolean}
|
|
36
|
+
*/
|
|
37
|
+
function exists(projectRoot) {
|
|
38
|
+
return fs.existsSync(getOutputPath(projectRoot));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Generate Claude context file
|
|
43
|
+
* @param {object} analysis - Analysis results from static analyzer
|
|
44
|
+
* @param {object} config - Configuration from CLI
|
|
45
|
+
* @param {string} projectRoot - Project root directory
|
|
46
|
+
* @returns {object} Generation result
|
|
47
|
+
*/
|
|
48
|
+
async function generate(analysis, config, projectRoot) {
|
|
49
|
+
const result = {
|
|
50
|
+
success: false,
|
|
51
|
+
adapter: adapter.name,
|
|
52
|
+
files: [],
|
|
53
|
+
errors: []
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
// Build context from analysis
|
|
58
|
+
const context = buildContext(analysis, config);
|
|
59
|
+
|
|
60
|
+
// Render template
|
|
61
|
+
const content = renderTemplateByName('claude', context);
|
|
62
|
+
|
|
63
|
+
// Write output file
|
|
64
|
+
const outputPath = getOutputPath(projectRoot);
|
|
65
|
+
fs.writeFileSync(outputPath, content, 'utf-8');
|
|
66
|
+
|
|
67
|
+
result.success = true;
|
|
68
|
+
result.files.push({
|
|
69
|
+
path: outputPath,
|
|
70
|
+
relativePath: 'AI_CONTEXT.md',
|
|
71
|
+
size: content.length
|
|
72
|
+
});
|
|
73
|
+
} catch (error) {
|
|
74
|
+
result.errors.push({
|
|
75
|
+
message: error.message,
|
|
76
|
+
stack: error.stack
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Validate Claude output
|
|
85
|
+
* @param {string} projectRoot - Project root directory
|
|
86
|
+
* @returns {object} Validation result
|
|
87
|
+
*/
|
|
88
|
+
function validate(projectRoot) {
|
|
89
|
+
const outputPath = getOutputPath(projectRoot);
|
|
90
|
+
|
|
91
|
+
if (!fs.existsSync(outputPath)) {
|
|
92
|
+
return {
|
|
93
|
+
valid: false,
|
|
94
|
+
error: 'AI_CONTEXT.md not found'
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const content = fs.readFileSync(outputPath, 'utf-8');
|
|
99
|
+
|
|
100
|
+
// Check for unreplaced placeholders
|
|
101
|
+
const placeholderMatch = content.match(/\{\{[A-Z_]+\}\}/g);
|
|
102
|
+
if (placeholderMatch && placeholderMatch.length > 0) {
|
|
103
|
+
return {
|
|
104
|
+
valid: false,
|
|
105
|
+
error: `Found ${placeholderMatch.length} unreplaced placeholders`,
|
|
106
|
+
placeholders: placeholderMatch
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
valid: true,
|
|
112
|
+
size: content.length
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
module.exports = {
|
|
117
|
+
...adapter,
|
|
118
|
+
getOutputPath,
|
|
119
|
+
exists,
|
|
120
|
+
generate,
|
|
121
|
+
validate
|
|
122
|
+
};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cline Adapter
|
|
3
|
+
*
|
|
4
|
+
* Generates .clinerules file for Cline VS Code extension.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const { renderTemplateByName, buildContext } = require('../template-renderer');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Adapter metadata
|
|
13
|
+
*/
|
|
14
|
+
const adapter = {
|
|
15
|
+
name: 'cline',
|
|
16
|
+
displayName: 'Cline',
|
|
17
|
+
description: 'Rules file for Cline VS Code extension',
|
|
18
|
+
outputType: 'single-file',
|
|
19
|
+
outputPath: '.clinerules'
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Get output path for Cline rules file
|
|
24
|
+
* @param {string} projectRoot - Project root directory
|
|
25
|
+
* @returns {string} Output file path
|
|
26
|
+
*/
|
|
27
|
+
function getOutputPath(projectRoot) {
|
|
28
|
+
return path.join(projectRoot, '.clinerules');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Check if Cline output already exists
|
|
33
|
+
* @param {string} projectRoot - Project root directory
|
|
34
|
+
* @returns {boolean}
|
|
35
|
+
*/
|
|
36
|
+
function exists(projectRoot) {
|
|
37
|
+
return fs.existsSync(getOutputPath(projectRoot));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Generate Cline rules file
|
|
42
|
+
* @param {object} analysis - Analysis results from static analyzer
|
|
43
|
+
* @param {object} config - Configuration from CLI
|
|
44
|
+
* @param {string} projectRoot - Project root directory
|
|
45
|
+
* @returns {object} Generation result
|
|
46
|
+
*/
|
|
47
|
+
async function generate(analysis, config, projectRoot) {
|
|
48
|
+
const result = {
|
|
49
|
+
success: false,
|
|
50
|
+
adapter: adapter.name,
|
|
51
|
+
files: [],
|
|
52
|
+
errors: []
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
// Build context from analysis
|
|
57
|
+
const context = buildContext(analysis, config);
|
|
58
|
+
|
|
59
|
+
// Render template
|
|
60
|
+
const content = renderTemplateByName('cline', context);
|
|
61
|
+
|
|
62
|
+
// Write output file
|
|
63
|
+
const outputPath = getOutputPath(projectRoot);
|
|
64
|
+
fs.writeFileSync(outputPath, content, 'utf-8');
|
|
65
|
+
|
|
66
|
+
result.success = true;
|
|
67
|
+
result.files.push({
|
|
68
|
+
path: outputPath,
|
|
69
|
+
relativePath: '.clinerules',
|
|
70
|
+
size: content.length
|
|
71
|
+
});
|
|
72
|
+
} catch (error) {
|
|
73
|
+
result.errors.push({
|
|
74
|
+
message: error.message,
|
|
75
|
+
stack: error.stack
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Validate Cline output
|
|
84
|
+
* @param {string} projectRoot - Project root directory
|
|
85
|
+
* @returns {object} Validation result
|
|
86
|
+
*/
|
|
87
|
+
function validate(projectRoot) {
|
|
88
|
+
const outputPath = getOutputPath(projectRoot);
|
|
89
|
+
|
|
90
|
+
if (!fs.existsSync(outputPath)) {
|
|
91
|
+
return {
|
|
92
|
+
valid: false,
|
|
93
|
+
error: '.clinerules not found'
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const content = fs.readFileSync(outputPath, 'utf-8');
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
valid: true,
|
|
101
|
+
size: content.length
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
module.exports = {
|
|
106
|
+
...adapter,
|
|
107
|
+
getOutputPath,
|
|
108
|
+
exists,
|
|
109
|
+
generate,
|
|
110
|
+
validate
|
|
111
|
+
};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub Copilot Adapter
|
|
3
|
+
*
|
|
4
|
+
* Generates .github/copilot-instructions.md file.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const { renderTemplateByName, buildContext } = require('../template-renderer');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Adapter metadata
|
|
13
|
+
*/
|
|
14
|
+
const adapter = {
|
|
15
|
+
name: 'copilot',
|
|
16
|
+
displayName: 'GitHub Copilot',
|
|
17
|
+
description: 'Context file for GitHub Copilot VS Code extension',
|
|
18
|
+
outputType: 'single-file',
|
|
19
|
+
outputPath: '.github/copilot-instructions.md'
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Get output path for Copilot instructions file
|
|
24
|
+
* @param {string} projectRoot - Project root directory
|
|
25
|
+
* @returns {string} Output file path
|
|
26
|
+
*/
|
|
27
|
+
function getOutputPath(projectRoot) {
|
|
28
|
+
return path.join(projectRoot, '.github', 'copilot-instructions.md');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Check if Copilot output already exists
|
|
33
|
+
* @param {string} projectRoot - Project root directory
|
|
34
|
+
* @returns {boolean}
|
|
35
|
+
*/
|
|
36
|
+
function exists(projectRoot) {
|
|
37
|
+
return fs.existsSync(getOutputPath(projectRoot));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Generate Copilot instructions file
|
|
42
|
+
* @param {object} analysis - Analysis results from static analyzer
|
|
43
|
+
* @param {object} config - Configuration from CLI
|
|
44
|
+
* @param {string} projectRoot - Project root directory
|
|
45
|
+
* @returns {object} Generation result
|
|
46
|
+
*/
|
|
47
|
+
async function generate(analysis, config, projectRoot) {
|
|
48
|
+
const result = {
|
|
49
|
+
success: false,
|
|
50
|
+
adapter: adapter.name,
|
|
51
|
+
files: [],
|
|
52
|
+
errors: []
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
// Build context from analysis
|
|
57
|
+
const context = buildContext(analysis, config);
|
|
58
|
+
|
|
59
|
+
// Render template
|
|
60
|
+
const content = renderTemplateByName('copilot', context);
|
|
61
|
+
|
|
62
|
+
// Ensure .github directory exists
|
|
63
|
+
const outputPath = getOutputPath(projectRoot);
|
|
64
|
+
const outputDir = path.dirname(outputPath);
|
|
65
|
+
if (!fs.existsSync(outputDir)) {
|
|
66
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Write output file
|
|
70
|
+
fs.writeFileSync(outputPath, content, 'utf-8');
|
|
71
|
+
|
|
72
|
+
result.success = true;
|
|
73
|
+
result.files.push({
|
|
74
|
+
path: outputPath,
|
|
75
|
+
relativePath: '.github/copilot-instructions.md',
|
|
76
|
+
size: content.length
|
|
77
|
+
});
|
|
78
|
+
} catch (error) {
|
|
79
|
+
result.errors.push({
|
|
80
|
+
message: error.message,
|
|
81
|
+
stack: error.stack
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return result;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Validate Copilot output
|
|
90
|
+
* @param {string} projectRoot - Project root directory
|
|
91
|
+
* @returns {object} Validation result
|
|
92
|
+
*/
|
|
93
|
+
function validate(projectRoot) {
|
|
94
|
+
const outputPath = getOutputPath(projectRoot);
|
|
95
|
+
|
|
96
|
+
if (!fs.existsSync(outputPath)) {
|
|
97
|
+
return {
|
|
98
|
+
valid: false,
|
|
99
|
+
error: 'copilot-instructions.md not found'
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const content = fs.readFileSync(outputPath, 'utf-8');
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
valid: true,
|
|
107
|
+
size: content.length
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
module.exports = {
|
|
112
|
+
...adapter,
|
|
113
|
+
getOutputPath,
|
|
114
|
+
exists,
|
|
115
|
+
generate,
|
|
116
|
+
validate
|
|
117
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Context Adapters
|
|
3
|
+
*
|
|
4
|
+
* Exports all available AI tool adapters.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const claude = require('./claude');
|
|
8
|
+
const copilot = require('./copilot');
|
|
9
|
+
const cline = require('./cline');
|
|
10
|
+
const antigravity = require('./antigravity');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* All available adapters
|
|
14
|
+
*/
|
|
15
|
+
const adapters = {
|
|
16
|
+
claude,
|
|
17
|
+
copilot,
|
|
18
|
+
cline,
|
|
19
|
+
antigravity
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Get adapter by name
|
|
24
|
+
* @param {string} name - Adapter name
|
|
25
|
+
* @returns {object|null} Adapter or null if not found
|
|
26
|
+
*/
|
|
27
|
+
function getAdapter(name) {
|
|
28
|
+
return adapters[name] || null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Get all adapter names
|
|
33
|
+
* @returns {string[]} Array of adapter names
|
|
34
|
+
*/
|
|
35
|
+
function getAdapterNames() {
|
|
36
|
+
return Object.keys(adapters);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Get adapters by names
|
|
41
|
+
* @param {string[]} names - Array of adapter names
|
|
42
|
+
* @returns {object[]} Array of adapters
|
|
43
|
+
*/
|
|
44
|
+
function getAdapters(names) {
|
|
45
|
+
return names
|
|
46
|
+
.map(name => adapters[name])
|
|
47
|
+
.filter(Boolean);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Get all adapters
|
|
52
|
+
* @returns {object[]} Array of all adapters
|
|
53
|
+
*/
|
|
54
|
+
function getAllAdapters() {
|
|
55
|
+
return Object.values(adapters);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
module.exports = {
|
|
59
|
+
adapters,
|
|
60
|
+
getAdapter,
|
|
61
|
+
getAdapterNames,
|
|
62
|
+
getAdapters,
|
|
63
|
+
getAllAdapters,
|
|
64
|
+
// Export individual adapters
|
|
65
|
+
claude,
|
|
66
|
+
copilot,
|
|
67
|
+
cline,
|
|
68
|
+
antigravity
|
|
69
|
+
};
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Context Generator
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates context generation for multiple AI tools.
|
|
5
|
+
* Uses adapters to generate tool-specific output files.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const { getAdapters, getAllAdapters, getAdapterNames } = require('./adapters');
|
|
10
|
+
const { initialize: initTemplateRenderer, buildContext } = require('./template-renderer');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Default AI tools to generate for
|
|
14
|
+
*/
|
|
15
|
+
const DEFAULT_AI_TOOLS = ['claude', 'copilot', 'cline', 'antigravity'];
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Initialize the generator
|
|
19
|
+
*/
|
|
20
|
+
function initialize() {
|
|
21
|
+
initTemplateRenderer();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Generate context files for selected AI tools
|
|
26
|
+
* @param {object} analysis - Analysis results from static analyzer
|
|
27
|
+
* @param {object} config - Configuration from CLI
|
|
28
|
+
* @param {string} projectRoot - Project root directory
|
|
29
|
+
* @param {object} options - Generation options
|
|
30
|
+
* @returns {object} Generation results
|
|
31
|
+
*/
|
|
32
|
+
async function generateAll(analysis, config, projectRoot, options = {}) {
|
|
33
|
+
const {
|
|
34
|
+
aiTools = config.aiTools || DEFAULT_AI_TOOLS,
|
|
35
|
+
verbose = false,
|
|
36
|
+
dryRun = false
|
|
37
|
+
} = options;
|
|
38
|
+
|
|
39
|
+
const results = {
|
|
40
|
+
success: true,
|
|
41
|
+
generated: [],
|
|
42
|
+
skipped: [],
|
|
43
|
+
errors: [],
|
|
44
|
+
summary: {
|
|
45
|
+
total: 0,
|
|
46
|
+
successful: 0,
|
|
47
|
+
failed: 0,
|
|
48
|
+
files: 0
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// Initialize template renderer
|
|
53
|
+
initialize();
|
|
54
|
+
|
|
55
|
+
// Get adapters for selected tools
|
|
56
|
+
const adapters = getAdapters(aiTools);
|
|
57
|
+
|
|
58
|
+
if (adapters.length === 0) {
|
|
59
|
+
results.success = false;
|
|
60
|
+
results.errors.push({
|
|
61
|
+
message: `No valid adapters found for: ${aiTools.join(', ')}`,
|
|
62
|
+
validAdapters: getAdapterNames()
|
|
63
|
+
});
|
|
64
|
+
return results;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Generate for each adapter
|
|
68
|
+
for (const adapter of adapters) {
|
|
69
|
+
results.summary.total++;
|
|
70
|
+
|
|
71
|
+
if (verbose) {
|
|
72
|
+
console.log(`Generating ${adapter.displayName} context...`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (dryRun) {
|
|
76
|
+
results.skipped.push({
|
|
77
|
+
adapter: adapter.name,
|
|
78
|
+
reason: 'dry-run mode',
|
|
79
|
+
outputPath: adapter.outputPath
|
|
80
|
+
});
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
const result = await adapter.generate(analysis, config, projectRoot);
|
|
86
|
+
|
|
87
|
+
if (result.success) {
|
|
88
|
+
results.summary.successful++;
|
|
89
|
+
results.summary.files += result.files.length;
|
|
90
|
+
results.generated.push({
|
|
91
|
+
adapter: adapter.name,
|
|
92
|
+
displayName: adapter.displayName,
|
|
93
|
+
files: result.files,
|
|
94
|
+
outputType: adapter.outputType
|
|
95
|
+
});
|
|
96
|
+
} else {
|
|
97
|
+
results.summary.failed++;
|
|
98
|
+
results.errors.push({
|
|
99
|
+
adapter: adapter.name,
|
|
100
|
+
errors: result.errors
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
} catch (error) {
|
|
104
|
+
results.summary.failed++;
|
|
105
|
+
results.errors.push({
|
|
106
|
+
adapter: adapter.name,
|
|
107
|
+
message: error.message,
|
|
108
|
+
stack: error.stack
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Update overall success
|
|
114
|
+
results.success = results.summary.failed === 0;
|
|
115
|
+
|
|
116
|
+
return results;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Generate context for a single AI tool
|
|
121
|
+
* @param {string} toolName - AI tool name (claude, copilot, cline, antigravity)
|
|
122
|
+
* @param {object} analysis - Analysis results from static analyzer
|
|
123
|
+
* @param {object} config - Configuration from CLI
|
|
124
|
+
* @param {string} projectRoot - Project root directory
|
|
125
|
+
* @returns {object} Generation result
|
|
126
|
+
*/
|
|
127
|
+
async function generateSingle(toolName, analysis, config, projectRoot) {
|
|
128
|
+
initialize();
|
|
129
|
+
|
|
130
|
+
const adapters = getAdapters([toolName]);
|
|
131
|
+
|
|
132
|
+
if (adapters.length === 0) {
|
|
133
|
+
return {
|
|
134
|
+
success: false,
|
|
135
|
+
error: `Unknown AI tool: ${toolName}`,
|
|
136
|
+
validTools: getAdapterNames()
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const adapter = adapters[0];
|
|
141
|
+
return adapter.generate(analysis, config, projectRoot);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Validate generated context files
|
|
146
|
+
* @param {string} projectRoot - Project root directory
|
|
147
|
+
* @param {string[]} aiTools - AI tools to validate
|
|
148
|
+
* @returns {object} Validation results
|
|
149
|
+
*/
|
|
150
|
+
function validateAll(projectRoot, aiTools = DEFAULT_AI_TOOLS) {
|
|
151
|
+
const adapters = getAdapters(aiTools);
|
|
152
|
+
const results = {
|
|
153
|
+
valid: true,
|
|
154
|
+
validations: []
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
for (const adapter of adapters) {
|
|
158
|
+
const validation = adapter.validate(projectRoot);
|
|
159
|
+
results.validations.push({
|
|
160
|
+
adapter: adapter.name,
|
|
161
|
+
displayName: adapter.displayName,
|
|
162
|
+
...validation
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
if (!validation.valid) {
|
|
166
|
+
results.valid = false;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return results;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Check which AI tool outputs exist
|
|
175
|
+
* @param {string} projectRoot - Project root directory
|
|
176
|
+
* @returns {object} Existence check results
|
|
177
|
+
*/
|
|
178
|
+
function checkExisting(projectRoot) {
|
|
179
|
+
const adapters = getAllAdapters();
|
|
180
|
+
const existing = {};
|
|
181
|
+
|
|
182
|
+
for (const adapter of adapters) {
|
|
183
|
+
existing[adapter.name] = {
|
|
184
|
+
exists: adapter.exists(projectRoot),
|
|
185
|
+
path: adapter.outputPath
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return existing;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Get context information for display
|
|
194
|
+
* @param {object} analysis - Analysis results
|
|
195
|
+
* @param {object} config - Configuration
|
|
196
|
+
* @returns {object} Context info for display
|
|
197
|
+
*/
|
|
198
|
+
function getContextInfo(analysis, config) {
|
|
199
|
+
const context = buildContext(analysis, config);
|
|
200
|
+
|
|
201
|
+
return {
|
|
202
|
+
projectName: context.project.name,
|
|
203
|
+
techStack: context.project.tech_stack,
|
|
204
|
+
workflowCount: context.workflows.length,
|
|
205
|
+
entryPointCount: context.key_files.entry_points.length,
|
|
206
|
+
gotchaCount: context.gotchas.length,
|
|
207
|
+
constraintCount: context.critical_constraints.length
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Get supported AI tools
|
|
213
|
+
* @returns {object[]} Array of tool info objects
|
|
214
|
+
*/
|
|
215
|
+
function getSupportedTools() {
|
|
216
|
+
return getAllAdapters().map(adapter => ({
|
|
217
|
+
name: adapter.name,
|
|
218
|
+
displayName: adapter.displayName,
|
|
219
|
+
description: adapter.description,
|
|
220
|
+
outputType: adapter.outputType,
|
|
221
|
+
outputPath: adapter.outputPath
|
|
222
|
+
}));
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
module.exports = {
|
|
226
|
+
generateAll,
|
|
227
|
+
generateSingle,
|
|
228
|
+
validateAll,
|
|
229
|
+
checkExisting,
|
|
230
|
+
getContextInfo,
|
|
231
|
+
getSupportedTools,
|
|
232
|
+
initialize,
|
|
233
|
+
DEFAULT_AI_TOOLS
|
|
234
|
+
};
|