create-universal-ai-context 2.5.0 → 2.6.0-final

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.
Files changed (153) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +331 -294
  3. package/bin/create-ai-context.js +1507 -775
  4. package/lib/adapters/aider.js +131 -131
  5. package/lib/adapters/antigravity.js +205 -205
  6. package/lib/adapters/claude.js +397 -397
  7. package/lib/adapters/cline.js +125 -125
  8. package/lib/adapters/continue.js +138 -138
  9. package/lib/adapters/copilot.js +131 -131
  10. package/lib/adapters/index.js +78 -78
  11. package/lib/adapters/windsurf.js +138 -138
  12. package/lib/ai-context-generator.js +234 -234
  13. package/lib/ai-orchestrator.js +432 -432
  14. package/lib/call-tracer.js +444 -444
  15. package/lib/content-preservation.js +243 -243
  16. package/lib/cross-tool-sync/file-watcher.js +274 -274
  17. package/lib/cross-tool-sync/index.js +41 -40
  18. package/lib/cross-tool-sync/sync-manager.js +540 -512
  19. package/lib/cross-tool-sync/sync-service.js +297 -297
  20. package/lib/detector.js +726 -726
  21. package/lib/doc-discovery.js +741 -741
  22. package/lib/drift-checker.js +920 -920
  23. package/lib/environment-detector.js +239 -239
  24. package/lib/index.js +399 -399
  25. package/lib/install-hooks.js +82 -82
  26. package/lib/installer.js +419 -419
  27. package/lib/migrate.js +328 -328
  28. package/lib/placeholder.js +632 -632
  29. package/lib/prompts.js +341 -341
  30. package/lib/smart-merge.js +540 -540
  31. package/lib/spinner.js +60 -60
  32. package/lib/static-analyzer.js +729 -729
  33. package/lib/template-coordination.js +148 -148
  34. package/lib/template-populator.js +843 -843
  35. package/lib/template-renderer.js +392 -392
  36. package/lib/utils/fs-wrapper.js +79 -79
  37. package/lib/utils/path-utils.js +60 -60
  38. package/lib/validate.js +155 -155
  39. package/package.json +1 -1
  40. package/templates/AI_CONTEXT.md.template +245 -245
  41. package/templates/base/README.md +260 -257
  42. package/templates/base/RPI_WORKFLOW_PLAN.md +325 -320
  43. package/templates/base/agents/api-developer.md +76 -76
  44. package/templates/base/agents/context-engineer.md +525 -525
  45. package/templates/base/agents/core-architect.md +76 -76
  46. package/templates/base/agents/database-ops.md +76 -76
  47. package/templates/base/agents/deployment-ops.md +76 -76
  48. package/templates/base/agents/integration-hub.md +76 -76
  49. package/templates/base/analytics/README.md +114 -114
  50. package/templates/base/automation/config.json +58 -58
  51. package/templates/base/automation/generators/code-mapper.js +308 -308
  52. package/templates/base/automation/generators/index-builder.js +321 -321
  53. package/templates/base/automation/hooks/post-commit.sh +83 -83
  54. package/templates/base/automation/hooks/pre-commit.sh +103 -103
  55. package/templates/base/ci-templates/README.md +108 -108
  56. package/templates/base/ci-templates/github-actions/context-check.yml +144 -144
  57. package/templates/base/ci-templates/github-actions/validate-docs.yml +105 -105
  58. package/templates/base/commands/analytics.md +238 -238
  59. package/templates/base/commands/auto-sync.md +172 -172
  60. package/templates/base/commands/collab.md +194 -194
  61. package/templates/base/commands/context-optimize.md +226 -0
  62. package/templates/base/commands/help.md +485 -450
  63. package/templates/base/commands/rpi-implement.md +164 -115
  64. package/templates/base/commands/rpi-plan.md +147 -93
  65. package/templates/base/commands/rpi-research.md +145 -88
  66. package/templates/base/commands/session-resume.md +144 -144
  67. package/templates/base/commands/session-save.md +112 -112
  68. package/templates/base/commands/validate-all.md +77 -77
  69. package/templates/base/commands/verify-docs-current.md +86 -86
  70. package/templates/base/config/base.json +57 -57
  71. package/templates/base/config/environments/development.json +13 -13
  72. package/templates/base/config/environments/production.json +17 -17
  73. package/templates/base/config/environments/staging.json +13 -13
  74. package/templates/base/config/local.json.example +21 -21
  75. package/templates/base/context/.meta/generated-at.json +18 -18
  76. package/templates/base/context/ARCHITECTURE_SNAPSHOT.md +156 -156
  77. package/templates/base/context/CODE_TO_WORKFLOW_MAP.md +94 -94
  78. package/templates/base/context/FILE_OWNERSHIP.md +57 -57
  79. package/templates/base/context/INTEGRATION_POINTS.md +92 -92
  80. package/templates/base/context/KNOWN_GOTCHAS.md +195 -195
  81. package/templates/base/context/TESTING_MAP.md +95 -95
  82. package/templates/base/context/WORKFLOW_INDEX.md +129 -129
  83. package/templates/base/context/workflows/WORKFLOW_TEMPLATE.md +294 -294
  84. package/templates/base/indexes/agents/CAPABILITY_MATRIX.md +255 -255
  85. package/templates/base/indexes/agents/CATEGORY_INDEX.md +44 -44
  86. package/templates/base/indexes/code/CATEGORY_INDEX.md +38 -38
  87. package/templates/base/indexes/routing/CATEGORY_INDEX.md +39 -39
  88. package/templates/base/indexes/search/CATEGORY_INDEX.md +39 -39
  89. package/templates/base/indexes/workflows/CATEGORY_INDEX.md +38 -38
  90. package/templates/base/knowledge/README.md +98 -98
  91. package/templates/base/knowledge/sessions/README.md +88 -88
  92. package/templates/base/knowledge/sessions/TEMPLATE.md +150 -150
  93. package/templates/base/knowledge/shared/decisions/0001-adopt-context-engineering.md +144 -144
  94. package/templates/base/knowledge/shared/decisions/README.md +49 -49
  95. package/templates/base/knowledge/shared/decisions/TEMPLATE.md +123 -123
  96. package/templates/base/knowledge/shared/patterns/README.md +62 -62
  97. package/templates/base/knowledge/shared/patterns/TEMPLATE.md +120 -120
  98. package/templates/base/plans/PLAN_TEMPLATE.md +316 -250
  99. package/templates/base/research/RESEARCH_TEMPLATE.md +245 -153
  100. package/templates/base/schemas/agent.schema.json +141 -141
  101. package/templates/base/schemas/anchors.schema.json +54 -54
  102. package/templates/base/schemas/automation.schema.json +93 -93
  103. package/templates/base/schemas/command.schema.json +134 -134
  104. package/templates/base/schemas/hashes.schema.json +40 -40
  105. package/templates/base/schemas/manifest.schema.json +117 -117
  106. package/templates/base/schemas/plan.schema.json +136 -136
  107. package/templates/base/schemas/research.schema.json +115 -115
  108. package/templates/base/schemas/roles.schema.json +34 -34
  109. package/templates/base/schemas/session.schema.json +77 -77
  110. package/templates/base/schemas/settings.schema.json +244 -244
  111. package/templates/base/schemas/staleness.schema.json +53 -53
  112. package/templates/base/schemas/team-config.schema.json +42 -42
  113. package/templates/base/schemas/workflow.schema.json +126 -126
  114. package/templates/base/session/checkpoints/.gitkeep +2 -2
  115. package/templates/base/session/current/state.json +20 -20
  116. package/templates/base/session/history/.gitkeep +2 -2
  117. package/templates/base/settings.json +3 -3
  118. package/templates/base/standards/COMPATIBILITY.md +219 -219
  119. package/templates/base/standards/EXTENSION_GUIDELINES.md +280 -280
  120. package/templates/base/standards/QUALITY_CHECKLIST.md +211 -211
  121. package/templates/base/standards/README.md +66 -66
  122. package/templates/base/sync/anchors.json +6 -6
  123. package/templates/base/sync/hashes.json +6 -6
  124. package/templates/base/sync/staleness.json +10 -10
  125. package/templates/base/team/README.md +168 -168
  126. package/templates/base/team/config.json +79 -79
  127. package/templates/base/team/roles.json +145 -145
  128. package/templates/base/tools/bin/claude-context.js +151 -151
  129. package/templates/base/tools/lib/anchor-resolver.js +276 -276
  130. package/templates/base/tools/lib/config-loader.js +363 -363
  131. package/templates/base/tools/lib/detector.js +350 -350
  132. package/templates/base/tools/lib/diagnose.js +206 -206
  133. package/templates/base/tools/lib/drift-detector.js +373 -373
  134. package/templates/base/tools/lib/errors.js +199 -199
  135. package/templates/base/tools/lib/index.js +36 -36
  136. package/templates/base/tools/lib/init.js +192 -192
  137. package/templates/base/tools/lib/logger.js +230 -230
  138. package/templates/base/tools/lib/placeholder.js +201 -201
  139. package/templates/base/tools/lib/session-manager.js +354 -354
  140. package/templates/base/tools/lib/validate.js +521 -521
  141. package/templates/base/tools/package.json +49 -49
  142. package/templates/handlebars/aider-config.hbs +146 -80
  143. package/templates/handlebars/antigravity.hbs +377 -377
  144. package/templates/handlebars/claude.hbs +183 -183
  145. package/templates/handlebars/cline.hbs +62 -62
  146. package/templates/handlebars/continue-config.hbs +116 -116
  147. package/templates/handlebars/copilot.hbs +130 -130
  148. package/templates/handlebars/partials/gotcha-list.hbs +11 -11
  149. package/templates/handlebars/partials/header.hbs +3 -3
  150. package/templates/handlebars/partials/workflow-summary.hbs +16 -16
  151. package/templates/handlebars/windsurf-rules.hbs +69 -69
  152. package/templates/hooks/post-commit.hbs +28 -29
  153. package/templates/hooks/pre-commit.hbs +46 -46
package/lib/index.js CHANGED
@@ -1,399 +1,399 @@
1
- /**
2
- * Main orchestrator for create-ai-context
3
- *
4
- * Universal AI Context Engineering - supports Claude, Copilot, Cline, Antigravity.
5
- *
6
- * Handles the full installation flow:
7
- * 1. Interactive prompts (or defaults)
8
- * 2. Directory structure creation
9
- * 3. Template copying
10
- * 4. Environment detection (Claude Code or standalone)
11
- * 5. Tech stack detection
12
- * 6. Deep codebase analysis
13
- * 7. Template population with real data
14
- * 8. Placeholder replacement
15
- * 9. AI orchestration (if in Claude Code)
16
- * 10. Validation
17
- * 11. Plugin installation (optional)
18
- * 12. Git initialization (optional)
19
- */
20
-
21
- const path = require('path');
22
- const fs = require('fs');
23
- const chalk = require('chalk');
24
- const { runPrompts, getDefaults, runDiscoveryPrompts } = require('./prompts');
25
- const { createSpinner } = require('./spinner');
26
- const {
27
- createDirectoryStructure,
28
- copyTemplates,
29
- createAiContextMd,
30
- AI_CONTEXT_DIR,
31
- AI_CONTEXT_FILE
32
- } = require('./installer');
33
- const { detectTechStack } = require('./detector');
34
- const { replacePlaceholders } = require('./placeholder');
35
- const { validateInstallation } = require('./validate');
36
-
37
- // New modules for context engineering initialization
38
- const { detectEnvironment, forceMode, getEnvironmentDescription } = require('./environment-detector');
39
- const { analyzeCodebase } = require('./static-analyzer');
40
- const {
41
- createInitializationRequest,
42
- generateAgentInstructions,
43
- isInitializationPending
44
- } = require('./ai-orchestrator');
45
- const { populateAllTemplates } = require('./template-populator');
46
- const { generateAll: generateAllContexts, getSupportedTools } = require('./ai-context-generator');
47
-
48
- // Documentation discovery for existing docs detection
49
- const {
50
- discoverExistingDocs,
51
- formatDiscoverySummary,
52
- buildMergedValues
53
- } = require('./doc-discovery');
54
-
55
- /**
56
- * Main entry point
57
- */
58
- async function run(options = {}) {
59
- const {
60
- projectName,
61
- skipPrompts = false,
62
- installPlugin = true,
63
- template,
64
- initGit = true,
65
- dryRun = false,
66
- verbose = false,
67
- // AI tool selection
68
- aiTools = ['claude', 'copilot', 'cline', 'antigravity'],
69
- // Mode options
70
- forceAi = false,
71
- forceStatic = false,
72
- analyzeOnly = false,
73
- // Monorepo options
74
- monorepo = false,
75
- federate = false,
76
- // Merge options (new)
77
- mode = 'merge', // 'merge' | 'overwrite' | 'interactive'
78
- preserveCustom = true,
79
- updateRefs = false,
80
- backup = false,
81
- // Force flag
82
- force = false,
83
- // Placeholder validation
84
- failOnUnreplaced = false
85
- } = options;
86
-
87
- // Determine target directory
88
- const targetDir = projectName
89
- ? path.resolve(process.cwd(), projectName)
90
- : process.cwd();
91
-
92
- const projectNameResolved = projectName || path.basename(targetDir);
93
- const contextDir = path.join(targetDir, AI_CONTEXT_DIR);
94
-
95
- const spinner = createSpinner();
96
-
97
- // ========================================
98
- // Phase 0: Documentation Discovery
99
- // ========================================
100
- spinner.start('Scanning for existing documentation...');
101
- let discovery = null;
102
- let mergeStrategy = mode;
103
- let discoveredValues = {};
104
-
105
- try {
106
- discovery = await discoverExistingDocs(targetDir);
107
-
108
- if (discovery.hasExistingDocs) {
109
- spinner.succeed('Found existing documentation');
110
-
111
- if (verbose) {
112
- console.log(chalk.gray(formatDiscoverySummary(discovery)));
113
- }
114
-
115
- // Handle discovery based on mode and prompts
116
- if (!skipPrompts && mode !== 'overwrite') {
117
- // Run discovery prompts
118
- const discoveryAnswers = await runDiscoveryPrompts(discovery);
119
-
120
- if (discoveryAnswers.existingDocsStrategy === 'skip') {
121
- console.log(chalk.yellow('\nInitialization cancelled by user.\n'));
122
- return;
123
- }
124
-
125
- mergeStrategy = discoveryAnswers.existingDocsStrategy;
126
- discoveredValues = buildMergedValues(
127
- discovery,
128
- mergeStrategy,
129
- discoveryAnswers.conflictResolutions || {}
130
- );
131
- } else if (mode === 'merge') {
132
- // Auto-merge without prompts
133
- discoveredValues = buildMergedValues(discovery, 'merge', {});
134
- }
135
-
136
- // Show what we're doing
137
- if (mergeStrategy === 'merge') {
138
- const valueCount = Object.keys(discoveredValues).length;
139
- console.log(chalk.cyan(` Preserving ${valueCount} values from existing docs`));
140
- } else if (mergeStrategy === 'overwrite') {
141
- console.log(chalk.yellow(' Overwrite mode: existing docs will be replaced'));
142
- }
143
- } else {
144
- spinner.succeed('No existing documentation found - starting fresh');
145
- }
146
- } catch (error) {
147
- spinner.warn(`Discovery partial: ${error.message}`);
148
- discovery = { hasExistingDocs: false };
149
- }
150
-
151
- // ========================================
152
- // Phase 1: Configuration (prompts or defaults)
153
- // ========================================
154
- let config;
155
- if (skipPrompts) {
156
- config = await getDefaults(targetDir, template);
157
- } else {
158
- config = await runPrompts(targetDir, template, discovery);
159
- }
160
-
161
- config.projectName = projectNameResolved;
162
- config.targetDir = targetDir;
163
- config.installPlugin = installPlugin && config.installPlugin;
164
- config.initGit = initGit;
165
- config.dryRun = dryRun;
166
- config.verbose = verbose;
167
- config.aiTools = aiTools;
168
- config.monorepo = monorepo;
169
- // Add merge config
170
- config.mergeStrategy = mergeStrategy;
171
- config.preserveCustom = preserveCustom;
172
- config.updateRefs = updateRefs;
173
- config.backup = backup;
174
- config.discoveredValues = discoveredValues;
175
- config.discovery = discovery;
176
-
177
- if (dryRun) {
178
- console.log(chalk.yellow('\n--dry-run mode: No changes will be made\n'));
179
- console.log('Configuration:', JSON.stringify(config, null, 2));
180
- if (discovery?.hasExistingDocs) {
181
- console.log('\nDiscovery:', JSON.stringify({
182
- tools: discovery.tools,
183
- extractedValues: discovery.extractedValues,
184
- conflicts: discovery.conflicts
185
- }, null, 2));
186
- }
187
- return;
188
- }
189
-
190
- // Phase 2: Create target directory if needed
191
- if (projectName && !fs.existsSync(targetDir)) {
192
- spinner.start('Creating project directory...');
193
- fs.mkdirSync(targetDir, { recursive: true });
194
- spinner.succeed(`Created project directory: ${projectNameResolved}`);
195
- }
196
-
197
- // Phase 2: Detect execution environment
198
- spinner.start('Detecting execution environment...');
199
- let env;
200
- if (forceAi) {
201
- env = forceMode('full-ai');
202
- } else if (forceStatic) {
203
- env = forceMode('standalone');
204
- } else {
205
- env = detectEnvironment();
206
- }
207
- spinner.succeed(`Environment: ${getEnvironmentDescription(env)}`);
208
-
209
- // Phase 3: Create .ai-context directory structure
210
- spinner.start(`Creating ${AI_CONTEXT_DIR} directory structure...`);
211
- const dirsCreated = await createDirectoryStructure(targetDir, config);
212
- spinner.succeed(`Created ${AI_CONTEXT_DIR} directory structure (${dirsCreated} directories)`);
213
-
214
- // Phase 4: Copy template files
215
- spinner.start('Copying template files...');
216
- const filesCopied = await copyTemplates(targetDir, config);
217
- spinner.succeed(`Copied ${filesCopied} template files`);
218
-
219
- // Phase 5: Detect technology stack
220
- spinner.start('Detecting technology stack...');
221
- const techStack = await detectTechStack(targetDir);
222
- config.techStack = techStack;
223
- spinner.succeed(`Detected: ${techStack.summary || 'Generic project'}`);
224
-
225
- // Phase 6: Deep codebase analysis
226
- spinner.start('Analyzing codebase...');
227
- let analysis;
228
- try {
229
- analysis = await analyzeCodebase(targetDir, { techStack });
230
- const summary = analysis.summary || {};
231
- spinner.succeed(
232
- `Analyzed: ${summary.totalFiles || 0} files, ` +
233
- `${summary.entryPointCount || 0} entry points, ` +
234
- `${summary.workflowCount || 0} workflows`
235
- );
236
- } catch (error) {
237
- spinner.warn(`Analysis partial: ${error.message}`);
238
- analysis = { workflows: [], entryPoints: [], architecture: {}, techStack };
239
- }
240
-
241
- // Add tech stack to analysis
242
- analysis.techStack = techStack;
243
-
244
- // Phase 7: Create AI_CONTEXT.md at root (before population)
245
- spinner.start(`Creating ${AI_CONTEXT_FILE}...`);
246
- await createAiContextMd(targetDir, config, techStack);
247
- spinner.succeed(`Created ${AI_CONTEXT_FILE} at project root`);
248
-
249
- // Phase 8: Populate templates with real data
250
- spinner.start('Populating templates with analysis results...');
251
- let populationResults;
252
- try {
253
- populationResults = await populateAllTemplates(contextDir, analysis, config);
254
- const counts = {
255
- populated: populationResults.populated?.length || 0,
256
- created: populationResults.created?.length || 0,
257
- errors: populationResults.errors?.length || 0
258
- };
259
- if (counts.errors > 0) {
260
- spinner.warn(`Populated ${counts.populated} files, created ${counts.created} workflows (${counts.errors} errors)`);
261
- } else {
262
- spinner.succeed(`Populated ${counts.populated} files, created ${counts.created} workflow docs`);
263
- }
264
- } catch (error) {
265
- spinner.warn(`Population partial: ${error.message}`);
266
- populationResults = { populated: [], created: [], errors: [error.message] };
267
- }
268
-
269
- // Phase 9: Replace remaining placeholders
270
- spinner.start('Replacing remaining placeholders...');
271
- const placeholdersReplaced = await replacePlaceholders(targetDir, {
272
- ...config,
273
- techStack,
274
- analysis,
275
- failOnUnreplaced: config.failOnUnreplaced,
276
- verbose: config.verbose
277
- });
278
- spinner.succeed(`Replaced ${placeholdersReplaced.totalReplaced} placeholders`);
279
-
280
- // Phase 10: AI Orchestration (if in Claude Code environment)
281
- if (env.mode === 'full-ai' || env.mode === 'hybrid') {
282
- spinner.start('Preparing AI initialization request...');
283
- try {
284
- createInitializationRequest(contextDir, config);
285
- generateAgentInstructions(contextDir, analysis, config);
286
- spinner.succeed('Created INIT_REQUEST.md for @context-engineer');
287
- } catch (error) {
288
- spinner.warn(`AI setup skipped: ${error.message}`);
289
- }
290
- }
291
-
292
- // Phase 11: Generate AI tool-specific context files
293
- spinner.start('Generating AI tool context files...');
294
- let generationResults;
295
- try {
296
- generationResults = await generateAllContexts(analysis, config, targetDir, {
297
- aiTools: config.aiTools,
298
- verbose: config.verbose,
299
- force: config.force || false
300
- });
301
- const toolsGenerated = generationResults.generated.map(g => g.adapter).join(', ');
302
- if (generationResults.success) {
303
- spinner.succeed(`Generated context for: ${toolsGenerated} (${generationResults.summary.files} files)`);
304
- } else {
305
- spinner.warn(`Generated ${generationResults.summary.successful}/${generationResults.summary.total} tools`);
306
- }
307
- } catch (error) {
308
- spinner.warn(`Context generation partial: ${error.message}`);
309
- generationResults = { generated: [], errors: [error.message] };
310
- }
311
-
312
- // Phase 12: Validate installation
313
- spinner.start('Validating installation...');
314
- const validation = await validateInstallation(targetDir);
315
- if (validation.passed) {
316
- spinner.succeed('All validations passed');
317
- } else {
318
- spinner.warn(`Validation completed with ${validation.warnings} warnings`);
319
- }
320
-
321
- // Phase 13: Install plugin (optional)
322
- if (config.installPlugin) {
323
- spinner.start('Plugin ready...');
324
- spinner.succeed('Plugin ready (install with: /plugin install ai-context-engineering)');
325
- }
326
-
327
- // Phase 14: Initialize git (optional)
328
- if (config.initGit && !fs.existsSync(path.join(targetDir, '.git'))) {
329
- spinner.start('Initializing git repository...');
330
- try {
331
- const { execSync } = require('child_process');
332
- execSync('git init', { cwd: targetDir, stdio: 'pipe' });
333
- spinner.succeed('Initialized git repository');
334
- } catch (e) {
335
- spinner.warn('Could not initialize git (git may not be installed)');
336
- }
337
- }
338
-
339
- // Success message (mode-aware)
340
- showSuccess(config, techStack, env, analysis, populationResults, generationResults);
341
- }
342
-
343
- /**
344
- * Display success message with next steps
345
- */
346
- function showSuccess(config, techStack, env, analysis, populationResults, generationResults) {
347
- const boxWidth = 59;
348
- const isAiMode = env.mode === 'full-ai' || env.mode === 'hybrid';
349
- const workflowCount = analysis?.workflows?.length || 0;
350
- const entryPointCount = analysis?.entryPoints?.length || 0;
351
- const aiTools = config.aiTools || [];
352
- const generatedTools = generationResults?.generated || [];
353
-
354
- console.log(`
355
- ${chalk.green('╔' + '═'.repeat(boxWidth) + '╗')}
356
- ${chalk.green('║')} ${chalk.bold.white('✓ AI Context Engineering Initialized Successfully!')} ${chalk.green('║')}
357
- ${chalk.green('╚' + '═'.repeat(boxWidth) + '╝')}
358
-
359
- ${chalk.bold('Analysis Results:')}
360
- ${chalk.cyan('•')} Entry Points: ${chalk.white(entryPointCount)} discovered
361
- ${chalk.cyan('•')} Workflows: ${chalk.white(workflowCount)} documented
362
- ${chalk.cyan('•')} Mode: ${chalk.white(env.mode)}
363
-
364
- ${chalk.bold('Created:')}
365
- ${chalk.cyan('•')} ${AI_CONTEXT_DIR}/ ${chalk.gray('(context engineering system)')}
366
- ${chalk.cyan('•')} ${AI_CONTEXT_FILE} ${chalk.gray('(AI navigation guide)')}
367
- ${workflowCount > 0 ? ` ${chalk.cyan('•')} ${workflowCount} workflow docs ${chalk.gray('(auto-generated)')}` : ''}
368
-
369
- ${chalk.bold('AI Tools Generated:')}
370
- ${generatedTools.find(g => g.adapter === 'claude') ? ` ${chalk.green('✓')} Claude Code ${chalk.gray('(' + AI_CONTEXT_FILE + ')')}` : (aiTools.includes('claude') ? ` ${chalk.yellow('○')} Claude Code ${chalk.gray('(pending)')}` : '')}
371
- ${generatedTools.find(g => g.adapter === 'copilot') ? ` ${chalk.green('✓')} GitHub Copilot ${chalk.gray('(.github/copilot-instructions.md)')}` : (aiTools.includes('copilot') ? ` ${chalk.yellow('○')} GitHub Copilot ${chalk.gray('(pending)')}` : '')}
372
- ${generatedTools.find(g => g.adapter === 'cline') ? ` ${chalk.green('✓')} Cline ${chalk.gray('(.clinerules)')}` : (aiTools.includes('cline') ? ` ${chalk.yellow('○')} Cline ${chalk.gray('(pending)')}` : '')}
373
- ${generatedTools.find(g => g.adapter === 'antigravity') ? ` ${chalk.green('✓')} Antigravity ${chalk.gray('(.agent/ ' + (generatedTools.find(g => g.adapter === 'antigravity')?.files?.length || 0) + ' files)')}` : (aiTools.includes('antigravity') ? ` ${chalk.yellow('○')} Antigravity ${chalk.gray('(pending)')}` : '')}
374
-
375
- ${chalk.bold('Available Commands:')}
376
- ${chalk.cyan('•')} /rpi-research ${chalk.gray('Research a feature')}
377
- ${chalk.cyan('•')} /rpi-plan ${chalk.gray('Create implementation plan')}
378
- ${chalk.cyan('•')} /rpi-implement ${chalk.gray('Execute with documentation')}
379
- ${chalk.cyan('•')} /validate-all ${chalk.gray('Run validation suite')}
380
- `);
381
-
382
- if (isAiMode) {
383
- console.log(`${chalk.bold.yellow('AI Initialization Pending:')}
384
- ${chalk.white('Run this command in Claude Code to complete:')}
385
- ${chalk.cyan('@context-engineer "Complete initialization using INIT_REQUEST.md"')}
386
- `);
387
- } else {
388
- console.log(`${chalk.bold('Next Steps:')}
389
- ${chalk.white('1.')} Review ${chalk.cyan(AI_CONTEXT_FILE)} and customize for your project
390
- ${chalk.white('2.')} Review generated workflow docs in ${chalk.cyan(AI_CONTEXT_DIR + '/context/workflows/')}
391
- ${chalk.white('3.')} Run ${chalk.cyan('@context-engineer "Enhance documentation"')} for AI analysis
392
- `);
393
- }
394
-
395
- console.log(`${chalk.gray('Documentation: https://github.com/SireJeff/claude-context-engineering-template')}
396
- `);
397
- }
398
-
399
- module.exports = { run };
1
+ /**
2
+ * Main orchestrator for create-ai-context
3
+ *
4
+ * Universal AI Context Engineering - supports Claude, Copilot, Cline, Antigravity.
5
+ *
6
+ * Handles the full installation flow:
7
+ * 1. Interactive prompts (or defaults)
8
+ * 2. Directory structure creation
9
+ * 3. Template copying
10
+ * 4. Environment detection (Claude Code or standalone)
11
+ * 5. Tech stack detection
12
+ * 6. Deep codebase analysis
13
+ * 7. Template population with real data
14
+ * 8. Placeholder replacement
15
+ * 9. AI orchestration (if in Claude Code)
16
+ * 10. Validation
17
+ * 11. Plugin installation (optional)
18
+ * 12. Git initialization (optional)
19
+ */
20
+
21
+ const path = require('path');
22
+ const fs = require('fs');
23
+ const chalk = require('chalk');
24
+ const { runPrompts, getDefaults, runDiscoveryPrompts } = require('./prompts');
25
+ const { createSpinner } = require('./spinner');
26
+ const {
27
+ createDirectoryStructure,
28
+ copyTemplates,
29
+ createAiContextMd,
30
+ AI_CONTEXT_DIR,
31
+ AI_CONTEXT_FILE
32
+ } = require('./installer');
33
+ const { detectTechStack } = require('./detector');
34
+ const { replacePlaceholders } = require('./placeholder');
35
+ const { validateInstallation } = require('./validate');
36
+
37
+ // New modules for context engineering initialization
38
+ const { detectEnvironment, forceMode, getEnvironmentDescription } = require('./environment-detector');
39
+ const { analyzeCodebase } = require('./static-analyzer');
40
+ const {
41
+ createInitializationRequest,
42
+ generateAgentInstructions,
43
+ isInitializationPending
44
+ } = require('./ai-orchestrator');
45
+ const { populateAllTemplates } = require('./template-populator');
46
+ const { generateAll: generateAllContexts, getSupportedTools } = require('./ai-context-generator');
47
+
48
+ // Documentation discovery for existing docs detection
49
+ const {
50
+ discoverExistingDocs,
51
+ formatDiscoverySummary,
52
+ buildMergedValues
53
+ } = require('./doc-discovery');
54
+
55
+ /**
56
+ * Main entry point
57
+ */
58
+ async function run(options = {}) {
59
+ const {
60
+ projectName,
61
+ skipPrompts = false,
62
+ installPlugin = true,
63
+ template,
64
+ initGit = true,
65
+ dryRun = false,
66
+ verbose = false,
67
+ // AI tool selection
68
+ aiTools = ['claude', 'copilot', 'cline', 'antigravity'],
69
+ // Mode options
70
+ forceAi = false,
71
+ forceStatic = false,
72
+ analyzeOnly = false,
73
+ // Monorepo options
74
+ monorepo = false,
75
+ federate = false,
76
+ // Merge options (new)
77
+ mode = 'merge', // 'merge' | 'overwrite' | 'interactive'
78
+ preserveCustom = true,
79
+ updateRefs = false,
80
+ backup = false,
81
+ // Force flag
82
+ force = false,
83
+ // Placeholder validation
84
+ failOnUnreplaced = false
85
+ } = options;
86
+
87
+ // Determine target directory
88
+ const targetDir = projectName
89
+ ? path.resolve(process.cwd(), projectName)
90
+ : process.cwd();
91
+
92
+ const projectNameResolved = projectName || path.basename(targetDir);
93
+ const contextDir = path.join(targetDir, AI_CONTEXT_DIR);
94
+
95
+ const spinner = createSpinner();
96
+
97
+ // ========================================
98
+ // Phase 0: Documentation Discovery
99
+ // ========================================
100
+ spinner.start('Scanning for existing documentation...');
101
+ let discovery = null;
102
+ let mergeStrategy = mode;
103
+ let discoveredValues = {};
104
+
105
+ try {
106
+ discovery = await discoverExistingDocs(targetDir);
107
+
108
+ if (discovery.hasExistingDocs) {
109
+ spinner.succeed('Found existing documentation');
110
+
111
+ if (verbose) {
112
+ console.log(chalk.gray(formatDiscoverySummary(discovery)));
113
+ }
114
+
115
+ // Handle discovery based on mode and prompts
116
+ if (!skipPrompts && mode !== 'overwrite') {
117
+ // Run discovery prompts
118
+ const discoveryAnswers = await runDiscoveryPrompts(discovery);
119
+
120
+ if (discoveryAnswers.existingDocsStrategy === 'skip') {
121
+ console.log(chalk.yellow('\nInitialization cancelled by user.\n'));
122
+ return;
123
+ }
124
+
125
+ mergeStrategy = discoveryAnswers.existingDocsStrategy;
126
+ discoveredValues = buildMergedValues(
127
+ discovery,
128
+ mergeStrategy,
129
+ discoveryAnswers.conflictResolutions || {}
130
+ );
131
+ } else if (mode === 'merge') {
132
+ // Auto-merge without prompts
133
+ discoveredValues = buildMergedValues(discovery, 'merge', {});
134
+ }
135
+
136
+ // Show what we're doing
137
+ if (mergeStrategy === 'merge') {
138
+ const valueCount = Object.keys(discoveredValues).length;
139
+ console.log(chalk.cyan(` Preserving ${valueCount} values from existing docs`));
140
+ } else if (mergeStrategy === 'overwrite') {
141
+ console.log(chalk.yellow(' Overwrite mode: existing docs will be replaced'));
142
+ }
143
+ } else {
144
+ spinner.succeed('No existing documentation found - starting fresh');
145
+ }
146
+ } catch (error) {
147
+ spinner.warn(`Discovery partial: ${error.message}`);
148
+ discovery = { hasExistingDocs: false };
149
+ }
150
+
151
+ // ========================================
152
+ // Phase 1: Configuration (prompts or defaults)
153
+ // ========================================
154
+ let config;
155
+ if (skipPrompts) {
156
+ config = await getDefaults(targetDir, template);
157
+ } else {
158
+ config = await runPrompts(targetDir, template, discovery);
159
+ }
160
+
161
+ config.projectName = projectNameResolved;
162
+ config.targetDir = targetDir;
163
+ config.installPlugin = installPlugin && config.installPlugin;
164
+ config.initGit = initGit;
165
+ config.dryRun = dryRun;
166
+ config.verbose = verbose;
167
+ config.aiTools = aiTools;
168
+ config.monorepo = monorepo;
169
+ // Add merge config
170
+ config.mergeStrategy = mergeStrategy;
171
+ config.preserveCustom = preserveCustom;
172
+ config.updateRefs = updateRefs;
173
+ config.backup = backup;
174
+ config.discoveredValues = discoveredValues;
175
+ config.discovery = discovery;
176
+
177
+ if (dryRun) {
178
+ console.log(chalk.yellow('\n--dry-run mode: No changes will be made\n'));
179
+ console.log('Configuration:', JSON.stringify(config, null, 2));
180
+ if (discovery?.hasExistingDocs) {
181
+ console.log('\nDiscovery:', JSON.stringify({
182
+ tools: discovery.tools,
183
+ extractedValues: discovery.extractedValues,
184
+ conflicts: discovery.conflicts
185
+ }, null, 2));
186
+ }
187
+ return;
188
+ }
189
+
190
+ // Phase 2: Create target directory if needed
191
+ if (projectName && !fs.existsSync(targetDir)) {
192
+ spinner.start('Creating project directory...');
193
+ fs.mkdirSync(targetDir, { recursive: true });
194
+ spinner.succeed(`Created project directory: ${projectNameResolved}`);
195
+ }
196
+
197
+ // Phase 2: Detect execution environment
198
+ spinner.start('Detecting execution environment...');
199
+ let env;
200
+ if (forceAi) {
201
+ env = forceMode('full-ai');
202
+ } else if (forceStatic) {
203
+ env = forceMode('standalone');
204
+ } else {
205
+ env = detectEnvironment();
206
+ }
207
+ spinner.succeed(`Environment: ${getEnvironmentDescription(env)}`);
208
+
209
+ // Phase 3: Create .ai-context directory structure
210
+ spinner.start(`Creating ${AI_CONTEXT_DIR} directory structure...`);
211
+ const dirsCreated = await createDirectoryStructure(targetDir, config);
212
+ spinner.succeed(`Created ${AI_CONTEXT_DIR} directory structure (${dirsCreated} directories)`);
213
+
214
+ // Phase 4: Copy template files
215
+ spinner.start('Copying template files...');
216
+ const filesCopied = await copyTemplates(targetDir, config);
217
+ spinner.succeed(`Copied ${filesCopied} template files`);
218
+
219
+ // Phase 5: Detect technology stack
220
+ spinner.start('Detecting technology stack...');
221
+ const techStack = await detectTechStack(targetDir);
222
+ config.techStack = techStack;
223
+ spinner.succeed(`Detected: ${techStack.summary || 'Generic project'}`);
224
+
225
+ // Phase 6: Deep codebase analysis
226
+ spinner.start('Analyzing codebase...');
227
+ let analysis;
228
+ try {
229
+ analysis = await analyzeCodebase(targetDir, { techStack });
230
+ const summary = analysis.summary || {};
231
+ spinner.succeed(
232
+ `Analyzed: ${summary.totalFiles || 0} files, ` +
233
+ `${summary.entryPointCount || 0} entry points, ` +
234
+ `${summary.workflowCount || 0} workflows`
235
+ );
236
+ } catch (error) {
237
+ spinner.warn(`Analysis partial: ${error.message}`);
238
+ analysis = { workflows: [], entryPoints: [], architecture: {}, techStack };
239
+ }
240
+
241
+ // Add tech stack to analysis
242
+ analysis.techStack = techStack;
243
+
244
+ // Phase 7: Create AI_CONTEXT.md at root (before population)
245
+ spinner.start(`Creating ${AI_CONTEXT_FILE}...`);
246
+ await createAiContextMd(targetDir, config, techStack);
247
+ spinner.succeed(`Created ${AI_CONTEXT_FILE} at project root`);
248
+
249
+ // Phase 8: Populate templates with real data
250
+ spinner.start('Populating templates with analysis results...');
251
+ let populationResults;
252
+ try {
253
+ populationResults = await populateAllTemplates(contextDir, analysis, config);
254
+ const counts = {
255
+ populated: populationResults.populated?.length || 0,
256
+ created: populationResults.created?.length || 0,
257
+ errors: populationResults.errors?.length || 0
258
+ };
259
+ if (counts.errors > 0) {
260
+ spinner.warn(`Populated ${counts.populated} files, created ${counts.created} workflows (${counts.errors} errors)`);
261
+ } else {
262
+ spinner.succeed(`Populated ${counts.populated} files, created ${counts.created} workflow docs`);
263
+ }
264
+ } catch (error) {
265
+ spinner.warn(`Population partial: ${error.message}`);
266
+ populationResults = { populated: [], created: [], errors: [error.message] };
267
+ }
268
+
269
+ // Phase 9: Replace remaining placeholders
270
+ spinner.start('Replacing remaining placeholders...');
271
+ const placeholdersReplaced = await replacePlaceholders(targetDir, {
272
+ ...config,
273
+ techStack,
274
+ analysis,
275
+ failOnUnreplaced: config.failOnUnreplaced,
276
+ verbose: config.verbose
277
+ });
278
+ spinner.succeed(`Replaced ${placeholdersReplaced.totalReplaced} placeholders`);
279
+
280
+ // Phase 10: AI Orchestration (if in Claude Code environment)
281
+ if (env.mode === 'full-ai' || env.mode === 'hybrid') {
282
+ spinner.start('Preparing AI initialization request...');
283
+ try {
284
+ createInitializationRequest(contextDir, config);
285
+ generateAgentInstructions(contextDir, analysis, config);
286
+ spinner.succeed('Created INIT_REQUEST.md for @context-engineer');
287
+ } catch (error) {
288
+ spinner.warn(`AI setup skipped: ${error.message}`);
289
+ }
290
+ }
291
+
292
+ // Phase 11: Generate AI tool-specific context files
293
+ spinner.start('Generating AI tool context files...');
294
+ let generationResults;
295
+ try {
296
+ generationResults = await generateAllContexts(analysis, config, targetDir, {
297
+ aiTools: config.aiTools,
298
+ verbose: config.verbose,
299
+ force: config.force || false
300
+ });
301
+ const toolsGenerated = generationResults.generated.map(g => g.adapter).join(', ');
302
+ if (generationResults.success) {
303
+ spinner.succeed(`Generated context for: ${toolsGenerated} (${generationResults.summary.files} files)`);
304
+ } else {
305
+ spinner.warn(`Generated ${generationResults.summary.successful}/${generationResults.summary.total} tools`);
306
+ }
307
+ } catch (error) {
308
+ spinner.warn(`Context generation partial: ${error.message}`);
309
+ generationResults = { generated: [], errors: [error.message] };
310
+ }
311
+
312
+ // Phase 12: Validate installation
313
+ spinner.start('Validating installation...');
314
+ const validation = await validateInstallation(targetDir);
315
+ if (validation.passed) {
316
+ spinner.succeed('All validations passed');
317
+ } else {
318
+ spinner.warn(`Validation completed with ${validation.warnings} warnings`);
319
+ }
320
+
321
+ // Phase 13: Install plugin (optional)
322
+ if (config.installPlugin) {
323
+ spinner.start('Plugin ready...');
324
+ spinner.succeed('Plugin ready (install with: /plugin install ai-context-engineering)');
325
+ }
326
+
327
+ // Phase 14: Initialize git (optional)
328
+ if (config.initGit && !fs.existsSync(path.join(targetDir, '.git'))) {
329
+ spinner.start('Initializing git repository...');
330
+ try {
331
+ const { execSync } = require('child_process');
332
+ execSync('git init', { cwd: targetDir, stdio: 'pipe' });
333
+ spinner.succeed('Initialized git repository');
334
+ } catch (e) {
335
+ spinner.warn('Could not initialize git (git may not be installed)');
336
+ }
337
+ }
338
+
339
+ // Success message (mode-aware)
340
+ showSuccess(config, techStack, env, analysis, populationResults, generationResults);
341
+ }
342
+
343
+ /**
344
+ * Display success message with next steps
345
+ */
346
+ function showSuccess(config, techStack, env, analysis, populationResults, generationResults) {
347
+ const boxWidth = 59;
348
+ const isAiMode = env.mode === 'full-ai' || env.mode === 'hybrid';
349
+ const workflowCount = analysis?.workflows?.length || 0;
350
+ const entryPointCount = analysis?.entryPoints?.length || 0;
351
+ const aiTools = config.aiTools || [];
352
+ const generatedTools = generationResults?.generated || [];
353
+
354
+ console.log(`
355
+ ${chalk.green('╔' + '═'.repeat(boxWidth) + '╗')}
356
+ ${chalk.green('║')} ${chalk.bold.white('✓ AI Context Engineering Initialized Successfully!')} ${chalk.green('║')}
357
+ ${chalk.green('╚' + '═'.repeat(boxWidth) + '╝')}
358
+
359
+ ${chalk.bold('Analysis Results:')}
360
+ ${chalk.cyan('•')} Entry Points: ${chalk.white(entryPointCount)} discovered
361
+ ${chalk.cyan('•')} Workflows: ${chalk.white(workflowCount)} documented
362
+ ${chalk.cyan('•')} Mode: ${chalk.white(env.mode)}
363
+
364
+ ${chalk.bold('Created:')}
365
+ ${chalk.cyan('•')} ${AI_CONTEXT_DIR}/ ${chalk.gray('(context engineering system)')}
366
+ ${chalk.cyan('•')} ${AI_CONTEXT_FILE} ${chalk.gray('(AI navigation guide)')}
367
+ ${workflowCount > 0 ? ` ${chalk.cyan('•')} ${workflowCount} workflow docs ${chalk.gray('(auto-generated)')}` : ''}
368
+
369
+ ${chalk.bold('AI Tools Generated:')}
370
+ ${generatedTools.find(g => g.adapter === 'claude') ? ` ${chalk.green('✓')} Claude Code ${chalk.gray('(' + AI_CONTEXT_FILE + ')')}` : (aiTools.includes('claude') ? ` ${chalk.yellow('○')} Claude Code ${chalk.gray('(pending)')}` : '')}
371
+ ${generatedTools.find(g => g.adapter === 'copilot') ? ` ${chalk.green('✓')} GitHub Copilot ${chalk.gray('(.github/copilot-instructions.md)')}` : (aiTools.includes('copilot') ? ` ${chalk.yellow('○')} GitHub Copilot ${chalk.gray('(pending)')}` : '')}
372
+ ${generatedTools.find(g => g.adapter === 'cline') ? ` ${chalk.green('✓')} Cline ${chalk.gray('(.clinerules)')}` : (aiTools.includes('cline') ? ` ${chalk.yellow('○')} Cline ${chalk.gray('(pending)')}` : '')}
373
+ ${generatedTools.find(g => g.adapter === 'antigravity') ? ` ${chalk.green('✓')} Antigravity ${chalk.gray('(.agent/ ' + (generatedTools.find(g => g.adapter === 'antigravity')?.files?.length || 0) + ' files)')}` : (aiTools.includes('antigravity') ? ` ${chalk.yellow('○')} Antigravity ${chalk.gray('(pending)')}` : '')}
374
+
375
+ ${chalk.bold('Available Commands:')}
376
+ ${chalk.cyan('•')} /rpi-research ${chalk.gray('Research a feature')}
377
+ ${chalk.cyan('•')} /rpi-plan ${chalk.gray('Create implementation plan')}
378
+ ${chalk.cyan('•')} /rpi-implement ${chalk.gray('Execute with documentation')}
379
+ ${chalk.cyan('•')} /validate-all ${chalk.gray('Run validation suite')}
380
+ `);
381
+
382
+ if (isAiMode) {
383
+ console.log(`${chalk.bold.yellow('AI Initialization Pending:')}
384
+ ${chalk.white('Run this command in Claude Code to complete:')}
385
+ ${chalk.cyan('@context-engineer "Complete initialization using INIT_REQUEST.md"')}
386
+ `);
387
+ } else {
388
+ console.log(`${chalk.bold('Next Steps:')}
389
+ ${chalk.white('1.')} Review ${chalk.cyan(AI_CONTEXT_FILE)} and customize for your project
390
+ ${chalk.white('2.')} Review generated workflow docs in ${chalk.cyan(AI_CONTEXT_DIR + '/context/workflows/')}
391
+ ${chalk.white('3.')} Run ${chalk.cyan('@context-engineer "Enhance documentation"')} for AI analysis
392
+ `);
393
+ }
394
+
395
+ console.log(`${chalk.gray('Documentation: https://github.com/SireJeff/claude-context-engineering-template')}
396
+ `);
397
+ }
398
+
399
+ module.exports = { run };