create-claude-context 1.2.0 → 1.2.2

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # create-claude-context
2
2
 
3
- Set up Claude Context Engineering for any project with a single command.
3
+ Set up Claude Context Engineering for any project with a single command. **Automatically analyzes your codebase** and generates real documentation.
4
4
 
5
5
  ## Quick Start
6
6
 
@@ -16,12 +16,22 @@ npm init claude-context
16
16
 
17
17
  ## What It Does
18
18
 
19
- This CLI tool sets up a complete context engineering system for your codebase:
19
+ This CLI tool performs **real codebase analysis** and creates a complete context engineering system:
20
20
 
21
- 1. **Creates `.claude/` directory** - Context engineering documentation
22
- 2. **Creates `CLAUDE.md`** - Entry point for Claude Code
23
- 3. **Detects tech stack** - Auto-configures for your project
24
- 4. **Installs plugin** - Adds ongoing commands (optional)
21
+ 1. **Analyzes codebase** - Discovers entry points, workflows, architecture
22
+ 2. **Creates `.claude/` directory** - Populated with real project data
23
+ 3. **Creates `CLAUDE.md`** - Entry point with actual file references
24
+ 4. **Detects tech stack** - Auto-configures for your project
25
+ 5. **AI handoff** - Creates instructions for `@context-engineer` (when in Claude Code)
26
+
27
+ ### Automatic Analysis
28
+
29
+ | What's Detected | Description |
30
+ |-----------------|-------------|
31
+ | Entry Points | API routes, CLI handlers, event listeners |
32
+ | Workflows | Authentication, payments, data processing patterns |
33
+ | Architecture | Directory structure, layers, dependencies |
34
+ | Tech Stack | Languages, frameworks, package managers |
25
35
 
26
36
  ## Options
27
37
 
@@ -34,11 +44,24 @@ Options:
34
44
  -t, --template Use a tech stack preset
35
45
  --no-git Skip git initialization
36
46
  --dry-run Show what would be done
47
+ --ai Force AI mode (requires Claude Code)
48
+ --static Force static-only analysis
49
+ --analyze-only Run analysis without installation
37
50
  -v, --verbose Show detailed output
38
51
  -V, --version Output version number
39
52
  -h, --help Display help
40
53
  ```
41
54
 
55
+ ## Execution Modes
56
+
57
+ | Mode | Condition | Capabilities |
58
+ |------|-----------|--------------|
59
+ | **full-ai** | Claude Code + API key | Complete AI-enhanced analysis |
60
+ | **hybrid** | Claude Code (no API) | Static analysis + AI handoff |
61
+ | **standalone** | No Claude Code | Static analysis only |
62
+
63
+ In hybrid mode, `INIT_REQUEST.md` is created for `@context-engineer` to complete setup.
64
+
42
65
  ## Tech Stack Presets
43
66
 
44
67
  ```bash
@@ -36,9 +36,19 @@ program
36
36
  .option('--no-git', 'Skip git initialization')
37
37
  .option('--dry-run', 'Show what would be done without making changes')
38
38
  .option('-v, --verbose', 'Show detailed output')
39
+ // New options for context engineering initialization
40
+ .option('--ai', 'Force AI mode (creates INIT_REQUEST.md for @context-engineer)')
41
+ .option('--static', 'Force standalone mode (static analysis only, no AI setup)')
42
+ .option('--analyze-only', 'Run codebase analysis without installation')
39
43
  .action(async (projectName, options) => {
40
44
  console.log(banner);
41
45
 
46
+ // Validate mutually exclusive options
47
+ if (options.ai && options.static) {
48
+ console.error(chalk.red('\n✖ Error: --ai and --static are mutually exclusive'));
49
+ process.exit(1);
50
+ }
51
+
42
52
  try {
43
53
  await run({
44
54
  projectName,
@@ -47,7 +57,11 @@ program
47
57
  template: options.template,
48
58
  initGit: options.git !== false,
49
59
  dryRun: options.dryRun,
50
- verbose: options.verbose
60
+ verbose: options.verbose,
61
+ // New options
62
+ forceAi: options.ai,
63
+ forceStatic: options.static,
64
+ analyzeOnly: options.analyzeOnly
51
65
  });
52
66
  } catch (error) {
53
67
  console.error(chalk.red('\n✖ Error:'), error.message);
@@ -0,0 +1,423 @@
1
+ /**
2
+ * AI Orchestrator
3
+ *
4
+ * Coordinates with @context-engineer agent for full AI-powered analysis.
5
+ * Creates initialization requests and generates agent instructions.
6
+ */
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+
11
+ /**
12
+ * Marker file for pending initialization
13
+ */
14
+ const INIT_MARKER = '.init-pending';
15
+
16
+ /**
17
+ * Instruction file for agent
18
+ */
19
+ const INIT_REQUEST_FILE = 'INIT_REQUEST.md';
20
+
21
+ /**
22
+ * Progress tracking file
23
+ */
24
+ const PROGRESS_FILE = 'INIT_PROGRESS.json';
25
+
26
+ /**
27
+ * Create an initialization request marker
28
+ * @param {string} claudeDir - .claude directory path
29
+ * @param {object} config - Configuration from CLI
30
+ * @returns {object} Request object
31
+ */
32
+ function createInitializationRequest(claudeDir, config) {
33
+ const request = {
34
+ version: '1.0.0',
35
+ createdAt: new Date().toISOString(),
36
+ projectName: config.projectName || path.basename(path.dirname(claudeDir)),
37
+ config: {
38
+ techStack: config.techStack,
39
+ features: config.features,
40
+ installPlugin: config.installPlugin
41
+ },
42
+ phases: [
43
+ { id: 'repository-analysis', name: 'Repository Analysis', status: 'pending', progress: 0 },
44
+ { id: 'workflow-discovery', name: 'Workflow Discovery', status: 'pending', progress: 0 },
45
+ { id: 'template-population', name: 'Template Population', status: 'pending', progress: 0 },
46
+ { id: 'index-generation', name: 'Index Generation', status: 'pending', progress: 0 },
47
+ { id: 'validation', name: 'Validation', status: 'pending', progress: 0 },
48
+ { id: 'finalization', name: 'Finalization', status: 'pending', progress: 0 }
49
+ ],
50
+ status: 'pending',
51
+ completedAt: null
52
+ };
53
+
54
+ const markerPath = path.join(claudeDir, INIT_MARKER);
55
+ fs.writeFileSync(markerPath, JSON.stringify(request, null, 2));
56
+
57
+ return request;
58
+ }
59
+
60
+ /**
61
+ * Generate agent instruction file with pre-analysis results
62
+ * @param {string} claudeDir - .claude directory path
63
+ * @param {object} analysis - Pre-analysis results from static analyzer
64
+ * @param {object} config - Configuration from CLI
65
+ */
66
+ function generateAgentInstructions(claudeDir, analysis, config) {
67
+ const projectName = config.projectName || path.basename(path.dirname(claudeDir));
68
+ const pkgVersion = getPackageVersion();
69
+
70
+ const instructions = `# Context Engineering Initialization Request
71
+
72
+ > **Auto-generated by \`create-claude-context\` v${pkgVersion}**
73
+ > Generated: ${new Date().toISOString()}
74
+
75
+ ## Status: Awaiting AI Completion
76
+
77
+ The CLI has performed static pre-analysis and prepared the template structure.
78
+ Full AI-powered context engineering is requested to complete initialization.
79
+
80
+ ---
81
+
82
+ ## Project Overview
83
+
84
+ | Property | Value |
85
+ |----------|-------|
86
+ | **Project Name** | ${projectName} |
87
+ | **Tech Stack** | ${analysis.techStack?.summary || 'Detected during analysis'} |
88
+ | **Source Files** | ${analysis.sourceFiles || 'TBD'} |
89
+ | **Lines of Code** | ${analysis.linesOfCode?.total || 'TBD'} |
90
+
91
+ ---
92
+
93
+ ## Pre-Analysis Results
94
+
95
+ ### Entry Points Discovered (${analysis.entryPoints?.length || 0})
96
+
97
+ ${formatEntryPoints(analysis.entryPoints)}
98
+
99
+ ### Workflow Candidates (${analysis.workflows?.length || 0})
100
+
101
+ ${formatWorkflows(analysis.workflows)}
102
+
103
+ ### Architecture Layers
104
+
105
+ ${formatLayers(analysis.architecture?.layers)}
106
+
107
+ ### Dependencies (${analysis.dependencies?.length || 0})
108
+
109
+ ${formatDependencies(analysis.dependencies)}
110
+
111
+ ---
112
+
113
+ ## Requested Actions
114
+
115
+ Please complete the context engineering initialization by:
116
+
117
+ ### Phase 1: Verify Pre-Analysis
118
+ - [ ] Review discovered entry points for accuracy
119
+ - [ ] Confirm workflow candidates are valid
120
+ - [ ] Identify any missed entry points or workflows
121
+
122
+ ### Phase 2: Deep Workflow Discovery
123
+ - [ ] Trace call chains for each workflow (3 levels deep)
124
+ - [ ] Identify database operations per workflow
125
+ - [ ] Map external API calls per workflow
126
+ - [ ] Document error handling patterns
127
+
128
+ ### Phase 3: Template Population
129
+ - [ ] Fill ARCHITECTURE_SNAPSHOT.md with real architecture
130
+ - [ ] Create individual workflow files (8-15 total)
131
+ - [ ] Populate CODE_TO_WORKFLOW_MAP.md with file references
132
+ - [ ] Update WORKFLOW_INDEX.md with all workflows
133
+
134
+ ### Phase 4: Index Generation
135
+ - [ ] Generate proper category indexes
136
+ - [ ] Create semantic anchors for key functions
137
+ - [ ] Build reverse lookup indexes
138
+
139
+ ### Phase 5: Validation
140
+ - [ ] Verify line number accuracy (target: 60%+)
141
+ - [ ] Check all internal links
142
+ - [ ] Confirm no placeholder values remain
143
+
144
+ ### Phase 6: Finalization
145
+ - [ ] Generate summary report
146
+ - [ ] Update CLAUDE.md with project-specific info
147
+ - [ ] Create maintenance schedule
148
+
149
+ ---
150
+
151
+ ## Quick Start Command
152
+
153
+ \`\`\`bash
154
+ @context-engineer "Complete initialization for ${projectName} using the pre-analysis in INIT_REQUEST.md"
155
+ \`\`\`
156
+
157
+ Or use the dedicated command:
158
+
159
+ \`\`\`bash
160
+ /rpi-research "Complete context engineering initialization"
161
+ \`\`\`
162
+
163
+ ---
164
+
165
+ ## Files to Update
166
+
167
+ | File | Action |
168
+ |------|--------|
169
+ | \`context/ARCHITECTURE_SNAPSHOT.md\` | Populate with real architecture |
170
+ | \`context/WORKFLOW_INDEX.md\` | Add all discovered workflows |
171
+ | \`context/CODE_TO_WORKFLOW_MAP.md\` | Map files to workflows |
172
+ | \`context/workflows/*.md\` | Create individual workflow docs |
173
+ | \`indexes/workflows/CATEGORY_INDEX.md\` | Generate category index |
174
+ | \`../CLAUDE.md\` | Finalize with project info |
175
+
176
+ ---
177
+
178
+ ## Pre-Analysis Data
179
+
180
+ The following JSON contains the full pre-analysis for programmatic use:
181
+
182
+ \`\`\`json
183
+ ${JSON.stringify(analysis.summary || {}, null, 2)}
184
+ \`\`\`
185
+
186
+ ---
187
+
188
+ *This file will be deleted automatically after successful initialization.*
189
+ *Generated by create-claude-context v${pkgVersion}*
190
+ `;
191
+
192
+ const instructionPath = path.join(claudeDir, INIT_REQUEST_FILE);
193
+ fs.writeFileSync(instructionPath, instructions);
194
+
195
+ return instructionPath;
196
+ }
197
+
198
+ /**
199
+ * Format entry points for markdown
200
+ * @param {object[]} entryPoints - Entry points array
201
+ * @returns {string}
202
+ */
203
+ function formatEntryPoints(entryPoints) {
204
+ if (!entryPoints || entryPoints.length === 0) {
205
+ return '*No entry points discovered during pre-analysis. AI analysis will discover them.*\n';
206
+ }
207
+
208
+ const limited = entryPoints.slice(0, 15);
209
+ let output = '| File | Line | Route | Method |\n|------|------|-------|--------|\n';
210
+
211
+ for (const ep of limited) {
212
+ output += `| \`${ep.file}\` | ${ep.line} | ${ep.route || '-'} | ${ep.method || '-'} |\n`;
213
+ }
214
+
215
+ if (entryPoints.length > 15) {
216
+ output += `\n*...and ${entryPoints.length - 15} more entry points*\n`;
217
+ }
218
+
219
+ return output;
220
+ }
221
+
222
+ /**
223
+ * Format workflows for markdown
224
+ * @param {object[]} workflows - Workflows array
225
+ * @returns {string}
226
+ */
227
+ function formatWorkflows(workflows) {
228
+ if (!workflows || workflows.length === 0) {
229
+ return '*No workflows discovered during pre-analysis. AI analysis will discover them.*\n';
230
+ }
231
+
232
+ let output = '| Workflow | Category | Complexity | Files | Confidence |\n|----------|----------|------------|-------|------------|\n';
233
+
234
+ for (const wf of workflows) {
235
+ output += `| **${wf.name}** | ${wf.category} | ${wf.complexity} | ${wf.fileCount || wf.files?.length || 0} | ${wf.confidence || '-'}% |\n`;
236
+ }
237
+
238
+ return output;
239
+ }
240
+
241
+ /**
242
+ * Format architecture layers for markdown
243
+ * @param {object[]} layers - Layers array
244
+ * @returns {string}
245
+ */
246
+ function formatLayers(layers) {
247
+ if (!layers || layers.length === 0) {
248
+ return '*Architecture layers will be determined during AI analysis.*\n';
249
+ }
250
+
251
+ let output = '| Layer | Directories | Purpose |\n|-------|-------------|----------|\n';
252
+
253
+ for (const layer of layers) {
254
+ output += `| **${layer.name}** | ${layer.directories?.join(', ') || '-'} | ${layer.purpose || '-'} |\n`;
255
+ }
256
+
257
+ return output;
258
+ }
259
+
260
+ /**
261
+ * Format dependencies for markdown
262
+ * @param {object[]} dependencies - Dependencies array
263
+ * @returns {string}
264
+ */
265
+ function formatDependencies(dependencies) {
266
+ if (!dependencies || dependencies.length === 0) {
267
+ return '*No dependencies detected.*\n';
268
+ }
269
+
270
+ // Group by ecosystem
271
+ const byEcosystem = {};
272
+ for (const dep of dependencies) {
273
+ const eco = dep.ecosystem || 'unknown';
274
+ if (!byEcosystem[eco]) byEcosystem[eco] = [];
275
+ byEcosystem[eco].push(dep);
276
+ }
277
+
278
+ let output = '';
279
+ for (const [ecosystem, deps] of Object.entries(byEcosystem)) {
280
+ output += `\n**${ecosystem.toUpperCase()}** (${deps.length}):\n`;
281
+ const topDeps = deps.slice(0, 10);
282
+ output += topDeps.map(d => `- ${d.name}@${d.version}`).join('\n') + '\n';
283
+ if (deps.length > 10) {
284
+ output += `- *...and ${deps.length - 10} more*\n`;
285
+ }
286
+ }
287
+
288
+ return output;
289
+ }
290
+
291
+ /**
292
+ * Get package version
293
+ * @returns {string}
294
+ */
295
+ function getPackageVersion() {
296
+ try {
297
+ const pkgPath = path.join(__dirname, '..', 'package.json');
298
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
299
+ return pkg.version || '1.0.0';
300
+ } catch {
301
+ return '1.0.0';
302
+ }
303
+ }
304
+
305
+ /**
306
+ * Check initialization status
307
+ * @param {string} claudeDir - .claude directory path
308
+ * @returns {object}
309
+ */
310
+ function checkInitializationStatus(claudeDir) {
311
+ const markerPath = path.join(claudeDir, INIT_MARKER);
312
+
313
+ if (!fs.existsSync(markerPath)) {
314
+ return { status: 'not-started', request: null };
315
+ }
316
+
317
+ try {
318
+ const request = JSON.parse(fs.readFileSync(markerPath, 'utf-8'));
319
+ const completedPhases = request.phases.filter(p => p.status === 'completed').length;
320
+ const totalPhases = request.phases.length;
321
+
322
+ return {
323
+ status: completedPhases === totalPhases ? 'completed' : 'in-progress',
324
+ progress: Math.round((completedPhases / totalPhases) * 100),
325
+ completedPhases,
326
+ totalPhases,
327
+ request
328
+ };
329
+ } catch {
330
+ return { status: 'error', request: null };
331
+ }
332
+ }
333
+
334
+ /**
335
+ * Update initialization progress
336
+ * @param {string} claudeDir - .claude directory path
337
+ * @param {string} phaseId - Phase ID to update
338
+ * @param {string} status - New status ('in-progress', 'completed', 'failed')
339
+ * @param {number} progress - Progress percentage (0-100)
340
+ */
341
+ function updateInitializationProgress(claudeDir, phaseId, status, progress = 0) {
342
+ const markerPath = path.join(claudeDir, INIT_MARKER);
343
+
344
+ if (!fs.existsSync(markerPath)) {
345
+ return false;
346
+ }
347
+
348
+ try {
349
+ const request = JSON.parse(fs.readFileSync(markerPath, 'utf-8'));
350
+ const phase = request.phases.find(p => p.id === phaseId);
351
+
352
+ if (phase) {
353
+ phase.status = status;
354
+ phase.progress = progress;
355
+ phase.updatedAt = new Date().toISOString();
356
+ }
357
+
358
+ // Check if all phases are completed
359
+ const allCompleted = request.phases.every(p => p.status === 'completed');
360
+ if (allCompleted) {
361
+ request.status = 'completed';
362
+ request.completedAt = new Date().toISOString();
363
+ } else {
364
+ request.status = 'in-progress';
365
+ }
366
+
367
+ fs.writeFileSync(markerPath, JSON.stringify(request, null, 2));
368
+ return true;
369
+ } catch {
370
+ return false;
371
+ }
372
+ }
373
+
374
+ /**
375
+ * Mark initialization as complete and clean up
376
+ * @param {string} claudeDir - .claude directory path
377
+ * @param {boolean} removeMarker - Whether to remove the marker file
378
+ */
379
+ function completeInitialization(claudeDir, removeMarker = true) {
380
+ const markerPath = path.join(claudeDir, INIT_MARKER);
381
+ const instructionPath = path.join(claudeDir, INIT_REQUEST_FILE);
382
+
383
+ if (fs.existsSync(markerPath)) {
384
+ const request = JSON.parse(fs.readFileSync(markerPath, 'utf-8'));
385
+ request.status = 'completed';
386
+ request.completedAt = new Date().toISOString();
387
+
388
+ // Archive to progress file
389
+ const progressPath = path.join(claudeDir, PROGRESS_FILE);
390
+ fs.writeFileSync(progressPath, JSON.stringify(request, null, 2));
391
+
392
+ if (removeMarker) {
393
+ fs.unlinkSync(markerPath);
394
+ }
395
+ }
396
+
397
+ // Remove instruction file
398
+ if (removeMarker && fs.existsSync(instructionPath)) {
399
+ fs.unlinkSync(instructionPath);
400
+ }
401
+ }
402
+
403
+ /**
404
+ * Check if initialization is pending
405
+ * @param {string} claudeDir - .claude directory path
406
+ * @returns {boolean}
407
+ */
408
+ function isInitializationPending(claudeDir) {
409
+ const markerPath = path.join(claudeDir, INIT_MARKER);
410
+ return fs.existsSync(markerPath);
411
+ }
412
+
413
+ module.exports = {
414
+ createInitializationRequest,
415
+ generateAgentInstructions,
416
+ checkInitializationStatus,
417
+ updateInitializationProgress,
418
+ completeInitialization,
419
+ isInitializationPending,
420
+ INIT_MARKER,
421
+ INIT_REQUEST_FILE,
422
+ PROGRESS_FILE
423
+ };