create-claude-context 1.2.0 → 1.2.1
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 +29 -6
- package/bin/create-claude-context.js +15 -1
- package/lib/ai-orchestrator.js +423 -0
- package/lib/call-tracer.js +444 -0
- package/lib/detector.js +83 -0
- package/lib/environment-detector.js +239 -0
- package/lib/index.js +128 -27
- package/lib/placeholder.js +80 -19
- package/lib/static-analyzer.js +729 -0
- package/lib/template-populator.js +835 -0
- package/package.json +1 -1
- package/templates/base/settings.json +1 -77
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment Detector
|
|
3
|
+
*
|
|
4
|
+
* Detects execution context to determine analysis mode:
|
|
5
|
+
* - full-ai: Running inside Claude Code with API access
|
|
6
|
+
* - hybrid: Running inside Claude Code without direct API access
|
|
7
|
+
* - standalone: Running via npx without Claude Code
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const path = require('path');
|
|
12
|
+
const os = require('os');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Environment indicators for Claude Code detection
|
|
16
|
+
*/
|
|
17
|
+
const CLAUDE_INDICATORS = {
|
|
18
|
+
// Environment variables set by Claude Code
|
|
19
|
+
envVars: [
|
|
20
|
+
'CLAUDE_CODE_SESSION',
|
|
21
|
+
'CLAUDE_SESSION_ID',
|
|
22
|
+
'CLAUDE_AGENT_ID',
|
|
23
|
+
'ANTHROPIC_API_KEY',
|
|
24
|
+
'CLAUDE_API_KEY'
|
|
25
|
+
],
|
|
26
|
+
|
|
27
|
+
// Directories that indicate Claude Code presence
|
|
28
|
+
directories: [
|
|
29
|
+
path.join(os.homedir(), '.claude'),
|
|
30
|
+
path.join(os.homedir(), '.claude-code'),
|
|
31
|
+
path.join(os.homedir(), '.config', 'claude-code')
|
|
32
|
+
],
|
|
33
|
+
|
|
34
|
+
// Files that indicate active Claude Code session
|
|
35
|
+
sessionFiles: [
|
|
36
|
+
'.claude-session',
|
|
37
|
+
'.claude-code-session'
|
|
38
|
+
]
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Capability definitions by mode
|
|
43
|
+
*/
|
|
44
|
+
const CAPABILITIES = {
|
|
45
|
+
'full-ai': [
|
|
46
|
+
'workflow-discovery',
|
|
47
|
+
'call-tracing',
|
|
48
|
+
'semantic-analysis',
|
|
49
|
+
'architecture-understanding',
|
|
50
|
+
'smart-documentation'
|
|
51
|
+
],
|
|
52
|
+
'hybrid': [
|
|
53
|
+
'workflow-discovery',
|
|
54
|
+
'basic-analysis',
|
|
55
|
+
'pattern-matching'
|
|
56
|
+
],
|
|
57
|
+
'standalone': [
|
|
58
|
+
'static-analysis',
|
|
59
|
+
'pattern-matching',
|
|
60
|
+
'structure-mapping'
|
|
61
|
+
]
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Detect if running inside a Claude Code session
|
|
66
|
+
* @returns {boolean}
|
|
67
|
+
*/
|
|
68
|
+
function isClaudeCodeSession() {
|
|
69
|
+
// Check environment variables
|
|
70
|
+
for (const envVar of CLAUDE_INDICATORS.envVars) {
|
|
71
|
+
if (process.env[envVar]) {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Check for Claude directories
|
|
77
|
+
for (const dir of CLAUDE_INDICATORS.directories) {
|
|
78
|
+
if (fs.existsSync(dir)) {
|
|
79
|
+
// Directory exists, check for recent session markers
|
|
80
|
+
const sessionMarker = path.join(dir, 'session', 'current', 'state.json');
|
|
81
|
+
if (fs.existsSync(sessionMarker)) {
|
|
82
|
+
try {
|
|
83
|
+
const state = JSON.parse(fs.readFileSync(sessionMarker, 'utf-8'));
|
|
84
|
+
// Check if session is recent (within last 24 hours)
|
|
85
|
+
if (state.startedAt) {
|
|
86
|
+
const sessionStart = new Date(state.startedAt);
|
|
87
|
+
const hoursSinceStart = (Date.now() - sessionStart.getTime()) / (1000 * 60 * 60);
|
|
88
|
+
if (hoursSinceStart < 24) {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
} catch {
|
|
93
|
+
// Ignore parse errors
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Even without active session, presence of .claude indicates CLI usage
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Check for session files in current directory
|
|
102
|
+
for (const sessionFile of CLAUDE_INDICATORS.sessionFiles) {
|
|
103
|
+
if (fs.existsSync(path.join(process.cwd(), sessionFile))) {
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Check if we're in a TTY with Claude Code characteristics
|
|
109
|
+
if (process.stdout.isTTY) {
|
|
110
|
+
// Check for VS Code terminal (common Claude Code environment)
|
|
111
|
+
if (process.env.TERM_PROGRAM === 'vscode') {
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Check for Claude Code specific terminal markers
|
|
116
|
+
if (process.env.CLAUDE_CODE_TERMINAL === 'true') {
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Check if API access is available
|
|
126
|
+
* @returns {boolean}
|
|
127
|
+
*/
|
|
128
|
+
function hasApiAccess() {
|
|
129
|
+
return !!(
|
|
130
|
+
process.env.ANTHROPIC_API_KEY ||
|
|
131
|
+
process.env.CLAUDE_API_KEY ||
|
|
132
|
+
process.env.CLAUDE_CODE_API_ACCESS === 'true'
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Detect the current execution environment
|
|
138
|
+
* @returns {{mode: string, isClaudeCode: boolean, hasApiAccess: boolean, capabilities: string[], indicators: string[]}}
|
|
139
|
+
*/
|
|
140
|
+
function detectEnvironment() {
|
|
141
|
+
const result = {
|
|
142
|
+
isClaudeCode: false,
|
|
143
|
+
hasApiAccess: false,
|
|
144
|
+
mode: 'standalone',
|
|
145
|
+
capabilities: [],
|
|
146
|
+
indicators: []
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
// Check for Claude Code session
|
|
150
|
+
result.isClaudeCode = isClaudeCodeSession();
|
|
151
|
+
|
|
152
|
+
// Check for API access
|
|
153
|
+
result.hasApiAccess = hasApiAccess();
|
|
154
|
+
|
|
155
|
+
// Collect detected indicators for debugging
|
|
156
|
+
for (const envVar of CLAUDE_INDICATORS.envVars) {
|
|
157
|
+
if (process.env[envVar]) {
|
|
158
|
+
result.indicators.push(`env:${envVar}`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
for (const dir of CLAUDE_INDICATORS.directories) {
|
|
162
|
+
if (fs.existsSync(dir)) {
|
|
163
|
+
result.indicators.push(`dir:${path.basename(dir)}`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Determine mode based on detection
|
|
168
|
+
if (result.isClaudeCode && result.hasApiAccess) {
|
|
169
|
+
result.mode = 'full-ai';
|
|
170
|
+
} else if (result.isClaudeCode) {
|
|
171
|
+
result.mode = 'hybrid';
|
|
172
|
+
} else {
|
|
173
|
+
result.mode = 'standalone';
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Assign capabilities based on mode
|
|
177
|
+
result.capabilities = CAPABILITIES[result.mode] || CAPABILITIES.standalone;
|
|
178
|
+
|
|
179
|
+
return result;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Get a human-readable description of the environment
|
|
184
|
+
* @param {object} env - Environment detection result
|
|
185
|
+
* @returns {string}
|
|
186
|
+
*/
|
|
187
|
+
function getEnvironmentDescription(env) {
|
|
188
|
+
switch (env.mode) {
|
|
189
|
+
case 'full-ai':
|
|
190
|
+
return 'Claude Code session with AI analysis enabled';
|
|
191
|
+
case 'hybrid':
|
|
192
|
+
return 'Claude Code session (AI analysis available on next run)';
|
|
193
|
+
case 'standalone':
|
|
194
|
+
return 'Standalone mode (static analysis only)';
|
|
195
|
+
default:
|
|
196
|
+
return 'Unknown environment';
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Check if a specific capability is available
|
|
202
|
+
* @param {object} env - Environment detection result
|
|
203
|
+
* @param {string} capability - Capability to check
|
|
204
|
+
* @returns {boolean}
|
|
205
|
+
*/
|
|
206
|
+
function hasCapability(env, capability) {
|
|
207
|
+
return env.capabilities.includes(capability);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Force a specific mode (for testing or CLI override)
|
|
212
|
+
* @param {string} mode - Mode to force ('full-ai', 'hybrid', 'standalone')
|
|
213
|
+
* @returns {object} Environment result with forced mode
|
|
214
|
+
*/
|
|
215
|
+
function forceMode(mode) {
|
|
216
|
+
if (!CAPABILITIES[mode]) {
|
|
217
|
+
throw new Error(`Invalid mode: ${mode}. Valid modes: ${Object.keys(CAPABILITIES).join(', ')}`);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return {
|
|
221
|
+
isClaudeCode: mode !== 'standalone',
|
|
222
|
+
hasApiAccess: mode === 'full-ai',
|
|
223
|
+
mode,
|
|
224
|
+
capabilities: CAPABILITIES[mode],
|
|
225
|
+
indicators: [`forced:${mode}`],
|
|
226
|
+
forced: true
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
module.exports = {
|
|
231
|
+
detectEnvironment,
|
|
232
|
+
isClaudeCodeSession,
|
|
233
|
+
hasApiAccess,
|
|
234
|
+
getEnvironmentDescription,
|
|
235
|
+
hasCapability,
|
|
236
|
+
forceMode,
|
|
237
|
+
CLAUDE_INDICATORS,
|
|
238
|
+
CAPABILITIES
|
|
239
|
+
};
|
package/lib/index.js
CHANGED
|
@@ -5,10 +5,15 @@
|
|
|
5
5
|
* 1. Interactive prompts (or defaults)
|
|
6
6
|
* 2. Directory structure creation
|
|
7
7
|
* 3. Template copying
|
|
8
|
-
* 4.
|
|
9
|
-
* 5.
|
|
10
|
-
* 6.
|
|
11
|
-
* 7.
|
|
8
|
+
* 4. Environment detection (Claude Code or standalone)
|
|
9
|
+
* 5. Tech stack detection
|
|
10
|
+
* 6. Deep codebase analysis
|
|
11
|
+
* 7. Template population with real data
|
|
12
|
+
* 8. Placeholder replacement
|
|
13
|
+
* 9. AI orchestration (if in Claude Code)
|
|
14
|
+
* 10. Validation
|
|
15
|
+
* 11. Plugin installation (optional)
|
|
16
|
+
* 12. Git initialization (optional)
|
|
12
17
|
*/
|
|
13
18
|
|
|
14
19
|
const path = require('path');
|
|
@@ -25,6 +30,16 @@ const { detectTechStack } = require('./detector');
|
|
|
25
30
|
const { replacePlaceholders } = require('./placeholder');
|
|
26
31
|
const { validateInstallation } = require('./validate');
|
|
27
32
|
|
|
33
|
+
// New modules for context engineering initialization
|
|
34
|
+
const { detectEnvironment, forceMode, getEnvironmentDescription } = require('./environment-detector');
|
|
35
|
+
const { analyzeCodebase } = require('./static-analyzer');
|
|
36
|
+
const {
|
|
37
|
+
createInitializationRequest,
|
|
38
|
+
generateAgentInstructions,
|
|
39
|
+
isInitializationPending
|
|
40
|
+
} = require('./ai-orchestrator');
|
|
41
|
+
const { populateAllTemplates } = require('./template-populator');
|
|
42
|
+
|
|
28
43
|
/**
|
|
29
44
|
* Main entry point
|
|
30
45
|
*/
|
|
@@ -36,7 +51,11 @@ async function run(options = {}) {
|
|
|
36
51
|
template,
|
|
37
52
|
initGit = true,
|
|
38
53
|
dryRun = false,
|
|
39
|
-
verbose = false
|
|
54
|
+
verbose = false,
|
|
55
|
+
// New options for context engineering
|
|
56
|
+
forceAi = false,
|
|
57
|
+
forceStatic = false,
|
|
58
|
+
analyzeOnly = false
|
|
40
59
|
} = options;
|
|
41
60
|
|
|
42
61
|
// Determine target directory
|
|
@@ -45,6 +64,7 @@ async function run(options = {}) {
|
|
|
45
64
|
: process.cwd();
|
|
46
65
|
|
|
47
66
|
const projectNameResolved = projectName || path.basename(targetDir);
|
|
67
|
+
const claudeDir = path.join(targetDir, '.claude');
|
|
48
68
|
|
|
49
69
|
// Get configuration (prompts or defaults)
|
|
50
70
|
let config;
|
|
@@ -76,35 +96,100 @@ async function run(options = {}) {
|
|
|
76
96
|
spinner.succeed(`Created project directory: ${projectNameResolved}`);
|
|
77
97
|
}
|
|
78
98
|
|
|
79
|
-
// Phase 2:
|
|
99
|
+
// Phase 2: Detect execution environment
|
|
100
|
+
spinner.start('Detecting execution environment...');
|
|
101
|
+
let env;
|
|
102
|
+
if (forceAi) {
|
|
103
|
+
env = forceMode('full-ai');
|
|
104
|
+
} else if (forceStatic) {
|
|
105
|
+
env = forceMode('standalone');
|
|
106
|
+
} else {
|
|
107
|
+
env = detectEnvironment();
|
|
108
|
+
}
|
|
109
|
+
spinner.succeed(`Environment: ${getEnvironmentDescription(env)}`);
|
|
110
|
+
|
|
111
|
+
// Phase 3: Create .claude directory structure
|
|
80
112
|
spinner.start('Creating .claude directory structure...');
|
|
81
113
|
const dirsCreated = await createDirectoryStructure(targetDir, config);
|
|
82
114
|
spinner.succeed(`Created .claude directory structure (${dirsCreated} directories)`);
|
|
83
115
|
|
|
84
|
-
// Phase
|
|
116
|
+
// Phase 4: Copy template files
|
|
85
117
|
spinner.start('Copying template files...');
|
|
86
118
|
const filesCopied = await copyTemplates(targetDir, config);
|
|
87
119
|
spinner.succeed(`Copied ${filesCopied} template files`);
|
|
88
120
|
|
|
89
|
-
// Phase
|
|
121
|
+
// Phase 5: Detect technology stack
|
|
90
122
|
spinner.start('Detecting technology stack...');
|
|
91
123
|
const techStack = await detectTechStack(targetDir);
|
|
124
|
+
config.techStack = techStack;
|
|
92
125
|
spinner.succeed(`Detected: ${techStack.summary || 'Generic project'}`);
|
|
93
126
|
|
|
94
|
-
// Phase
|
|
95
|
-
spinner.start('
|
|
127
|
+
// Phase 6: Deep codebase analysis
|
|
128
|
+
spinner.start('Analyzing codebase...');
|
|
129
|
+
let analysis;
|
|
130
|
+
try {
|
|
131
|
+
analysis = await analyzeCodebase(targetDir, { techStack });
|
|
132
|
+
const summary = analysis.summary || {};
|
|
133
|
+
spinner.succeed(
|
|
134
|
+
`Analyzed: ${summary.totalFiles || 0} files, ` +
|
|
135
|
+
`${summary.entryPointCount || 0} entry points, ` +
|
|
136
|
+
`${summary.workflowCount || 0} workflows`
|
|
137
|
+
);
|
|
138
|
+
} catch (error) {
|
|
139
|
+
spinner.warn(`Analysis partial: ${error.message}`);
|
|
140
|
+
analysis = { workflows: [], entryPoints: [], architecture: {}, techStack };
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Add tech stack to analysis
|
|
144
|
+
analysis.techStack = techStack;
|
|
145
|
+
|
|
146
|
+
// Phase 7: Create CLAUDE.md at root (before population)
|
|
147
|
+
spinner.start('Creating CLAUDE.md...');
|
|
148
|
+
await createClaudeMd(targetDir, config, techStack);
|
|
149
|
+
spinner.succeed('Created CLAUDE.md at project root');
|
|
150
|
+
|
|
151
|
+
// Phase 8: Populate templates with real data
|
|
152
|
+
spinner.start('Populating templates with analysis results...');
|
|
153
|
+
let populationResults;
|
|
154
|
+
try {
|
|
155
|
+
populationResults = await populateAllTemplates(claudeDir, analysis, config);
|
|
156
|
+
const counts = {
|
|
157
|
+
populated: populationResults.populated?.length || 0,
|
|
158
|
+
created: populationResults.created?.length || 0,
|
|
159
|
+
errors: populationResults.errors?.length || 0
|
|
160
|
+
};
|
|
161
|
+
if (counts.errors > 0) {
|
|
162
|
+
spinner.warn(`Populated ${counts.populated} files, created ${counts.created} workflows (${counts.errors} errors)`);
|
|
163
|
+
} else {
|
|
164
|
+
spinner.succeed(`Populated ${counts.populated} files, created ${counts.created} workflow docs`);
|
|
165
|
+
}
|
|
166
|
+
} catch (error) {
|
|
167
|
+
spinner.warn(`Population partial: ${error.message}`);
|
|
168
|
+
populationResults = { populated: [], created: [], errors: [error.message] };
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Phase 9: Replace remaining placeholders
|
|
172
|
+
spinner.start('Replacing remaining placeholders...');
|
|
96
173
|
const placeholdersReplaced = await replacePlaceholders(targetDir, {
|
|
97
174
|
...config,
|
|
98
|
-
techStack
|
|
175
|
+
techStack,
|
|
176
|
+
analysis
|
|
99
177
|
});
|
|
100
178
|
spinner.succeed(`Replaced ${placeholdersReplaced} placeholders`);
|
|
101
179
|
|
|
102
|
-
// Phase
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
180
|
+
// Phase 10: AI Orchestration (if in Claude Code environment)
|
|
181
|
+
if (env.mode === 'full-ai' || env.mode === 'hybrid') {
|
|
182
|
+
spinner.start('Preparing AI initialization request...');
|
|
183
|
+
try {
|
|
184
|
+
createInitializationRequest(claudeDir, config);
|
|
185
|
+
generateAgentInstructions(claudeDir, analysis, config);
|
|
186
|
+
spinner.succeed('Created INIT_REQUEST.md for @context-engineer');
|
|
187
|
+
} catch (error) {
|
|
188
|
+
spinner.warn(`AI setup skipped: ${error.message}`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
106
191
|
|
|
107
|
-
// Phase
|
|
192
|
+
// Phase 11: Validate installation
|
|
108
193
|
spinner.start('Validating installation...');
|
|
109
194
|
const validation = await validateInstallation(targetDir);
|
|
110
195
|
if (validation.passed) {
|
|
@@ -113,15 +198,13 @@ async function run(options = {}) {
|
|
|
113
198
|
spinner.warn(`Validation completed with ${validation.warnings} warnings`);
|
|
114
199
|
}
|
|
115
200
|
|
|
116
|
-
// Phase
|
|
201
|
+
// Phase 12: Install Claude Code plugin (optional)
|
|
117
202
|
if (config.installPlugin) {
|
|
118
203
|
spinner.start('Installing Claude Code plugin...');
|
|
119
|
-
// Plugin installation would use: npx claude-plugins install claude-context-engineering
|
|
120
|
-
// For now, we'll note it as a next step
|
|
121
204
|
spinner.succeed('Plugin ready (install with: /plugin install claude-context-engineering)');
|
|
122
205
|
}
|
|
123
206
|
|
|
124
|
-
// Phase
|
|
207
|
+
// Phase 13: Initialize git (optional)
|
|
125
208
|
if (config.initGit && !fs.existsSync(path.join(targetDir, '.git'))) {
|
|
126
209
|
spinner.start('Initializing git repository...');
|
|
127
210
|
try {
|
|
@@ -133,37 +216,55 @@ async function run(options = {}) {
|
|
|
133
216
|
}
|
|
134
217
|
}
|
|
135
218
|
|
|
136
|
-
// Success message
|
|
137
|
-
showSuccess(config, techStack);
|
|
219
|
+
// Success message (mode-aware)
|
|
220
|
+
showSuccess(config, techStack, env, analysis, populationResults);
|
|
138
221
|
}
|
|
139
222
|
|
|
140
223
|
/**
|
|
141
224
|
* Display success message with next steps
|
|
142
225
|
*/
|
|
143
|
-
function showSuccess(config, techStack) {
|
|
226
|
+
function showSuccess(config, techStack, env, analysis, populationResults) {
|
|
144
227
|
const boxWidth = 59;
|
|
228
|
+
const isAiMode = env.mode === 'full-ai' || env.mode === 'hybrid';
|
|
229
|
+
const workflowCount = analysis?.workflows?.length || 0;
|
|
230
|
+
const entryPointCount = analysis?.entryPoints?.length || 0;
|
|
145
231
|
|
|
146
232
|
console.log(`
|
|
147
233
|
${chalk.green('╔' + '═'.repeat(boxWidth) + '╗')}
|
|
148
234
|
${chalk.green('║')} ${chalk.bold.white('✓ Context Engineering Initialized Successfully!')} ${chalk.green('║')}
|
|
149
235
|
${chalk.green('╚' + '═'.repeat(boxWidth) + '╝')}
|
|
150
236
|
|
|
237
|
+
${chalk.bold('Analysis Results:')}
|
|
238
|
+
${chalk.cyan('•')} Entry Points: ${chalk.white(entryPointCount)} discovered
|
|
239
|
+
${chalk.cyan('•')} Workflows: ${chalk.white(workflowCount)} documented
|
|
240
|
+
${chalk.cyan('•')} Mode: ${chalk.white(env.mode)}
|
|
241
|
+
|
|
151
242
|
${chalk.bold('Created:')}
|
|
152
243
|
${chalk.cyan('•')} .claude/ ${chalk.gray('(context engineering system)')}
|
|
153
244
|
${chalk.cyan('•')} CLAUDE.md ${chalk.gray('(AI navigation guide)')}
|
|
245
|
+
${workflowCount > 0 ? ` ${chalk.cyan('•')} ${workflowCount} workflow docs ${chalk.gray('(auto-generated)')}` : ''}
|
|
154
246
|
|
|
155
247
|
${chalk.bold('Available Commands:')}
|
|
156
248
|
${chalk.cyan('•')} /rpi-research ${chalk.gray('Research a feature')}
|
|
157
249
|
${chalk.cyan('•')} /rpi-plan ${chalk.gray('Create implementation plan')}
|
|
158
250
|
${chalk.cyan('•')} /rpi-implement ${chalk.gray('Execute with documentation')}
|
|
159
251
|
${chalk.cyan('•')} /validate-all ${chalk.gray('Run validation suite')}
|
|
252
|
+
`);
|
|
160
253
|
|
|
161
|
-
|
|
254
|
+
if (isAiMode) {
|
|
255
|
+
console.log(`${chalk.bold.yellow('AI Initialization Pending:')}
|
|
256
|
+
${chalk.white('Run this command in Claude Code to complete:')}
|
|
257
|
+
${chalk.cyan('@context-engineer "Complete initialization using INIT_REQUEST.md"')}
|
|
258
|
+
`);
|
|
259
|
+
} else {
|
|
260
|
+
console.log(`${chalk.bold('Next Steps:')}
|
|
162
261
|
${chalk.white('1.')} Review ${chalk.cyan('CLAUDE.md')} and customize for your project
|
|
163
|
-
${chalk.white('2.')}
|
|
164
|
-
${chalk.white('3.')}
|
|
262
|
+
${chalk.white('2.')} Review generated workflow docs in ${chalk.cyan('.claude/context/workflows/')}
|
|
263
|
+
${chalk.white('3.')} Run ${chalk.cyan('@context-engineer "Enhance documentation"')} for AI analysis
|
|
264
|
+
`);
|
|
265
|
+
}
|
|
165
266
|
|
|
166
|
-
|
|
267
|
+
console.log(`${chalk.gray('Documentation: https://github.com/SireJeff/claude-context-engineering-template')}
|
|
167
268
|
`);
|
|
168
269
|
}
|
|
169
270
|
|
package/lib/placeholder.js
CHANGED
|
@@ -50,9 +50,9 @@ const KNOWN_PLACEHOLDERS = {
|
|
|
50
50
|
};
|
|
51
51
|
|
|
52
52
|
/**
|
|
53
|
-
* Get default placeholder values based on config
|
|
53
|
+
* Get default placeholder values based on config, tech stack, and analysis
|
|
54
54
|
*/
|
|
55
|
-
function getDefaultValues(config = {}, techStack = {}) {
|
|
55
|
+
function getDefaultValues(config = {}, techStack = {}, analysis = {}) {
|
|
56
56
|
const today = new Date().toISOString().split('T')[0];
|
|
57
57
|
const projectName = config.projectName || 'my-project';
|
|
58
58
|
|
|
@@ -61,34 +61,60 @@ function getDefaultValues(config = {}, techStack = {}) {
|
|
|
61
61
|
install: 'npm install',
|
|
62
62
|
dev: 'npm run dev',
|
|
63
63
|
test: 'npm test',
|
|
64
|
-
|
|
64
|
+
testE2e: 'npm run test:e2e',
|
|
65
|
+
testCoverage: 'npm run test:coverage',
|
|
66
|
+
migrateCreate: 'npm run migration:create',
|
|
67
|
+
migrateRun: 'npm run migration:run',
|
|
68
|
+
deploy: 'npm run deploy'
|
|
65
69
|
};
|
|
66
70
|
|
|
67
71
|
if (techStack.commands) {
|
|
68
|
-
commands = techStack.commands;
|
|
72
|
+
commands = { ...commands, ...techStack.commands };
|
|
69
73
|
} else if (techStack.languages?.includes('python')) {
|
|
70
74
|
commands = {
|
|
71
75
|
install: 'pip install -r requirements.txt',
|
|
72
76
|
dev: 'python main.py',
|
|
73
77
|
test: 'pytest',
|
|
74
|
-
|
|
78
|
+
testE2e: 'pytest tests/e2e/',
|
|
79
|
+
testCoverage: 'pytest --cov',
|
|
80
|
+
migrateCreate: 'alembic revision --autogenerate',
|
|
81
|
+
migrateRun: 'alembic upgrade head',
|
|
82
|
+
deploy: 'docker-compose up -d'
|
|
75
83
|
};
|
|
76
84
|
} else if (techStack.languages?.includes('go')) {
|
|
77
85
|
commands = {
|
|
78
86
|
install: 'go mod download',
|
|
79
87
|
dev: 'go run .',
|
|
80
88
|
test: 'go test ./...',
|
|
81
|
-
|
|
89
|
+
testE2e: 'go test ./e2e/...',
|
|
90
|
+
testCoverage: 'go test -cover ./...',
|
|
91
|
+
migrateCreate: 'migrate create -ext sql',
|
|
92
|
+
migrateRun: 'migrate -path migrations up',
|
|
93
|
+
deploy: 'docker-compose up -d'
|
|
82
94
|
};
|
|
83
95
|
} else if (techStack.languages?.includes('rust')) {
|
|
84
96
|
commands = {
|
|
85
97
|
install: 'cargo build',
|
|
86
98
|
dev: 'cargo run',
|
|
87
99
|
test: 'cargo test',
|
|
88
|
-
|
|
100
|
+
testE2e: 'cargo test --test e2e',
|
|
101
|
+
testCoverage: 'cargo tarpaulin',
|
|
102
|
+
migrateCreate: 'sqlx migrate add',
|
|
103
|
+
migrateRun: 'sqlx migrate run',
|
|
104
|
+
deploy: 'cargo build --release'
|
|
89
105
|
};
|
|
90
106
|
}
|
|
91
107
|
|
|
108
|
+
// Build core files list from analysis
|
|
109
|
+
let coreFilesList = '- src/\n- config/';
|
|
110
|
+
if (analysis.entryPoints && analysis.entryPoints.length > 0) {
|
|
111
|
+
const uniqueFiles = [...new Set(analysis.entryPoints.map(e => e.file))];
|
|
112
|
+
coreFilesList = uniqueFiles.slice(0, 10).map(f => `- \`${f}\``).join('\n');
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Get workflow count from analysis
|
|
116
|
+
const workflowCount = analysis.workflows?.length || 0;
|
|
117
|
+
|
|
92
118
|
return {
|
|
93
119
|
PROJECT_NAME: projectName,
|
|
94
120
|
PROJECT_DESCRIPTION: `${projectName} application`,
|
|
@@ -97,23 +123,58 @@ function getDefaultValues(config = {}, techStack = {}) {
|
|
|
97
123
|
PROJECT_STATUS: 'Development',
|
|
98
124
|
API_URL: `https://api.${projectName}.example.com`,
|
|
99
125
|
REPO_URL: `https://github.com/user/${projectName}`,
|
|
100
|
-
DEPLOYMENT_PLATFORM: '
|
|
126
|
+
DEPLOYMENT_PLATFORM: 'TBD',
|
|
101
127
|
INSTALL_COMMAND: commands.install,
|
|
102
128
|
DEV_START_COMMAND: commands.dev,
|
|
103
129
|
TEST_COMMAND: commands.test,
|
|
104
|
-
TEST_E2E_COMMAND:
|
|
105
|
-
TEST_COVERAGE_COMMAND:
|
|
106
|
-
MIGRATION_CREATE_COMMAND:
|
|
107
|
-
MIGRATION_RUN_COMMAND: commands.
|
|
108
|
-
DEPLOY_COMMAND:
|
|
109
|
-
MODELS_PATH: '
|
|
110
|
-
MIGRATIONS_PATH: '
|
|
111
|
-
CORE_FILES_LIST:
|
|
112
|
-
WORKFLOWS_COUNT:
|
|
130
|
+
TEST_E2E_COMMAND: commands.testE2e,
|
|
131
|
+
TEST_COVERAGE_COMMAND: commands.testCoverage,
|
|
132
|
+
MIGRATION_CREATE_COMMAND: commands.migrateCreate,
|
|
133
|
+
MIGRATION_RUN_COMMAND: commands.migrateRun,
|
|
134
|
+
DEPLOY_COMMAND: commands.deploy,
|
|
135
|
+
MODELS_PATH: 'models/',
|
|
136
|
+
MIGRATIONS_PATH: 'migrations/',
|
|
137
|
+
CORE_FILES_LIST: coreFilesList,
|
|
138
|
+
WORKFLOWS_COUNT: String(workflowCount),
|
|
139
|
+
WORKFLOW_DOMAINS_COUNT: String(workflowCount > 0 ? Math.min(workflowCount, 5) : 0),
|
|
140
|
+
CODE_DOMAINS_COUNT: '0',
|
|
113
141
|
AGENTS_COUNT: '6',
|
|
114
|
-
COMMANDS_COUNT: '
|
|
142
|
+
COMMANDS_COUNT: '11',
|
|
143
|
+
INDEX_FILES_COUNT: '15',
|
|
115
144
|
DATE: today,
|
|
116
145
|
AGENT_TABLE_ROWS: '',
|
|
146
|
+
AGENT_ROUTING_TABLE: '@context-engineer for setup, @core-architect for design',
|
|
147
|
+
DEBUGGING_QUICK_REFS: 'KNOWN_GOTCHAS.md, logs/',
|
|
148
|
+
EXAMPLE_REFACTOR_TASK: 'Refactor the authentication flow',
|
|
149
|
+
EXAMPLE_LOWLEVEL_TASK: 'Fix hardcoded API URL in config',
|
|
150
|
+
EXAMPLE_FEATURE_TASK: 'Add user notifications feature',
|
|
151
|
+
CONFIG_SEARCH_PATTERN: 'grep -r "process.env" --include="*.js" --include="*.ts"',
|
|
152
|
+
URL_SEARCH_PATTERN: 'grep -rE "https?://" --include="*.js" --include="*.ts" --include="*.json"',
|
|
153
|
+
EXTERNAL_INTEGRATIONS_LIST: '*No external integrations detected. Document manually if present.*',
|
|
154
|
+
ARCHITECTURE_DIAGRAM: `┌─────────────────────────────────────┐
|
|
155
|
+
│ [Application] │
|
|
156
|
+
│ │
|
|
157
|
+
│ ┌───────────┐ ┌───────────┐ │
|
|
158
|
+
│ │ API │ │ Services │ │
|
|
159
|
+
│ └───────────┘ └───────────┘ │
|
|
160
|
+
│ │
|
|
161
|
+
│ ┌───────────┐ ┌───────────┐ │
|
|
162
|
+
│ │ Models │ │ Database │ │
|
|
163
|
+
│ └───────────┘ └───────────┘ │
|
|
164
|
+
└─────────────────────────────────────┘`,
|
|
165
|
+
CRITICAL_URLS: `- Production: https://${projectName}.example.com`,
|
|
166
|
+
BUSINESS_CONSTANTS: '- TBD (document key business constants)',
|
|
167
|
+
GOTCHA_CATEGORY_1: 'Database',
|
|
168
|
+
GOTCHA_1_ITEMS: '- TBD (document database gotchas)',
|
|
169
|
+
GOTCHA_CATEGORY_2: 'API',
|
|
170
|
+
GOTCHA_2_ITEMS: '- TBD (document API gotchas)',
|
|
171
|
+
PRODUCTION_PLATFORM: 'TBD',
|
|
172
|
+
PRODUCTION_SERVICES: 'Web, API, Database',
|
|
173
|
+
MONITORING_COMMANDS: 'Check logs, health endpoints',
|
|
174
|
+
MIGRATION_CONSTRAINTS: 'Always backup before migrations',
|
|
175
|
+
TESTING_CONSTRAINTS: 'Run tests before merging',
|
|
176
|
+
SECURITY_CONSTRAINTS: 'Never commit secrets',
|
|
177
|
+
CONTACT_INFO: 'TBD (add contact info)',
|
|
117
178
|
};
|
|
118
179
|
}
|
|
119
180
|
|
|
@@ -122,7 +183,7 @@ function getDefaultValues(config = {}, techStack = {}) {
|
|
|
122
183
|
*/
|
|
123
184
|
async function replacePlaceholders(targetDir, config = {}) {
|
|
124
185
|
const claudeDir = path.join(targetDir, '.claude');
|
|
125
|
-
const values = getDefaultValues(config, config.techStack || {});
|
|
186
|
+
const values = getDefaultValues(config, config.techStack || {}, config.analysis || {});
|
|
126
187
|
|
|
127
188
|
// Find all markdown and JSON files
|
|
128
189
|
const files = await glob('**/*.{md,json}', {
|