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.
- package/LICENSE +21 -21
- package/README.md +331 -294
- package/bin/create-ai-context.js +1507 -775
- package/lib/adapters/aider.js +131 -131
- package/lib/adapters/antigravity.js +205 -205
- package/lib/adapters/claude.js +397 -397
- package/lib/adapters/cline.js +125 -125
- package/lib/adapters/continue.js +138 -138
- package/lib/adapters/copilot.js +131 -131
- package/lib/adapters/index.js +78 -78
- package/lib/adapters/windsurf.js +138 -138
- package/lib/ai-context-generator.js +234 -234
- package/lib/ai-orchestrator.js +432 -432
- package/lib/call-tracer.js +444 -444
- package/lib/content-preservation.js +243 -243
- package/lib/cross-tool-sync/file-watcher.js +274 -274
- package/lib/cross-tool-sync/index.js +41 -40
- package/lib/cross-tool-sync/sync-manager.js +540 -512
- package/lib/cross-tool-sync/sync-service.js +297 -297
- package/lib/detector.js +726 -726
- package/lib/doc-discovery.js +741 -741
- package/lib/drift-checker.js +920 -920
- package/lib/environment-detector.js +239 -239
- package/lib/index.js +399 -399
- package/lib/install-hooks.js +82 -82
- package/lib/installer.js +419 -419
- package/lib/migrate.js +328 -328
- package/lib/placeholder.js +632 -632
- package/lib/prompts.js +341 -341
- package/lib/smart-merge.js +540 -540
- package/lib/spinner.js +60 -60
- package/lib/static-analyzer.js +729 -729
- package/lib/template-coordination.js +148 -148
- package/lib/template-populator.js +843 -843
- package/lib/template-renderer.js +392 -392
- package/lib/utils/fs-wrapper.js +79 -79
- package/lib/utils/path-utils.js +60 -60
- package/lib/validate.js +155 -155
- package/package.json +1 -1
- package/templates/AI_CONTEXT.md.template +245 -245
- package/templates/base/README.md +260 -257
- package/templates/base/RPI_WORKFLOW_PLAN.md +325 -320
- package/templates/base/agents/api-developer.md +76 -76
- package/templates/base/agents/context-engineer.md +525 -525
- package/templates/base/agents/core-architect.md +76 -76
- package/templates/base/agents/database-ops.md +76 -76
- package/templates/base/agents/deployment-ops.md +76 -76
- package/templates/base/agents/integration-hub.md +76 -76
- package/templates/base/analytics/README.md +114 -114
- package/templates/base/automation/config.json +58 -58
- package/templates/base/automation/generators/code-mapper.js +308 -308
- package/templates/base/automation/generators/index-builder.js +321 -321
- package/templates/base/automation/hooks/post-commit.sh +83 -83
- package/templates/base/automation/hooks/pre-commit.sh +103 -103
- package/templates/base/ci-templates/README.md +108 -108
- package/templates/base/ci-templates/github-actions/context-check.yml +144 -144
- package/templates/base/ci-templates/github-actions/validate-docs.yml +105 -105
- package/templates/base/commands/analytics.md +238 -238
- package/templates/base/commands/auto-sync.md +172 -172
- package/templates/base/commands/collab.md +194 -194
- package/templates/base/commands/context-optimize.md +226 -0
- package/templates/base/commands/help.md +485 -450
- package/templates/base/commands/rpi-implement.md +164 -115
- package/templates/base/commands/rpi-plan.md +147 -93
- package/templates/base/commands/rpi-research.md +145 -88
- package/templates/base/commands/session-resume.md +144 -144
- package/templates/base/commands/session-save.md +112 -112
- package/templates/base/commands/validate-all.md +77 -77
- package/templates/base/commands/verify-docs-current.md +86 -86
- package/templates/base/config/base.json +57 -57
- package/templates/base/config/environments/development.json +13 -13
- package/templates/base/config/environments/production.json +17 -17
- package/templates/base/config/environments/staging.json +13 -13
- package/templates/base/config/local.json.example +21 -21
- package/templates/base/context/.meta/generated-at.json +18 -18
- package/templates/base/context/ARCHITECTURE_SNAPSHOT.md +156 -156
- package/templates/base/context/CODE_TO_WORKFLOW_MAP.md +94 -94
- package/templates/base/context/FILE_OWNERSHIP.md +57 -57
- package/templates/base/context/INTEGRATION_POINTS.md +92 -92
- package/templates/base/context/KNOWN_GOTCHAS.md +195 -195
- package/templates/base/context/TESTING_MAP.md +95 -95
- package/templates/base/context/WORKFLOW_INDEX.md +129 -129
- package/templates/base/context/workflows/WORKFLOW_TEMPLATE.md +294 -294
- package/templates/base/indexes/agents/CAPABILITY_MATRIX.md +255 -255
- package/templates/base/indexes/agents/CATEGORY_INDEX.md +44 -44
- package/templates/base/indexes/code/CATEGORY_INDEX.md +38 -38
- package/templates/base/indexes/routing/CATEGORY_INDEX.md +39 -39
- package/templates/base/indexes/search/CATEGORY_INDEX.md +39 -39
- package/templates/base/indexes/workflows/CATEGORY_INDEX.md +38 -38
- package/templates/base/knowledge/README.md +98 -98
- package/templates/base/knowledge/sessions/README.md +88 -88
- package/templates/base/knowledge/sessions/TEMPLATE.md +150 -150
- package/templates/base/knowledge/shared/decisions/0001-adopt-context-engineering.md +144 -144
- package/templates/base/knowledge/shared/decisions/README.md +49 -49
- package/templates/base/knowledge/shared/decisions/TEMPLATE.md +123 -123
- package/templates/base/knowledge/shared/patterns/README.md +62 -62
- package/templates/base/knowledge/shared/patterns/TEMPLATE.md +120 -120
- package/templates/base/plans/PLAN_TEMPLATE.md +316 -250
- package/templates/base/research/RESEARCH_TEMPLATE.md +245 -153
- package/templates/base/schemas/agent.schema.json +141 -141
- package/templates/base/schemas/anchors.schema.json +54 -54
- package/templates/base/schemas/automation.schema.json +93 -93
- package/templates/base/schemas/command.schema.json +134 -134
- package/templates/base/schemas/hashes.schema.json +40 -40
- package/templates/base/schemas/manifest.schema.json +117 -117
- package/templates/base/schemas/plan.schema.json +136 -136
- package/templates/base/schemas/research.schema.json +115 -115
- package/templates/base/schemas/roles.schema.json +34 -34
- package/templates/base/schemas/session.schema.json +77 -77
- package/templates/base/schemas/settings.schema.json +244 -244
- package/templates/base/schemas/staleness.schema.json +53 -53
- package/templates/base/schemas/team-config.schema.json +42 -42
- package/templates/base/schemas/workflow.schema.json +126 -126
- package/templates/base/session/checkpoints/.gitkeep +2 -2
- package/templates/base/session/current/state.json +20 -20
- package/templates/base/session/history/.gitkeep +2 -2
- package/templates/base/settings.json +3 -3
- package/templates/base/standards/COMPATIBILITY.md +219 -219
- package/templates/base/standards/EXTENSION_GUIDELINES.md +280 -280
- package/templates/base/standards/QUALITY_CHECKLIST.md +211 -211
- package/templates/base/standards/README.md +66 -66
- package/templates/base/sync/anchors.json +6 -6
- package/templates/base/sync/hashes.json +6 -6
- package/templates/base/sync/staleness.json +10 -10
- package/templates/base/team/README.md +168 -168
- package/templates/base/team/config.json +79 -79
- package/templates/base/team/roles.json +145 -145
- package/templates/base/tools/bin/claude-context.js +151 -151
- package/templates/base/tools/lib/anchor-resolver.js +276 -276
- package/templates/base/tools/lib/config-loader.js +363 -363
- package/templates/base/tools/lib/detector.js +350 -350
- package/templates/base/tools/lib/diagnose.js +206 -206
- package/templates/base/tools/lib/drift-detector.js +373 -373
- package/templates/base/tools/lib/errors.js +199 -199
- package/templates/base/tools/lib/index.js +36 -36
- package/templates/base/tools/lib/init.js +192 -192
- package/templates/base/tools/lib/logger.js +230 -230
- package/templates/base/tools/lib/placeholder.js +201 -201
- package/templates/base/tools/lib/session-manager.js +354 -354
- package/templates/base/tools/lib/validate.js +521 -521
- package/templates/base/tools/package.json +49 -49
- package/templates/handlebars/aider-config.hbs +146 -80
- package/templates/handlebars/antigravity.hbs +377 -377
- package/templates/handlebars/claude.hbs +183 -183
- package/templates/handlebars/cline.hbs +62 -62
- package/templates/handlebars/continue-config.hbs +116 -116
- package/templates/handlebars/copilot.hbs +130 -130
- package/templates/handlebars/partials/gotcha-list.hbs +11 -11
- package/templates/handlebars/partials/header.hbs +3 -3
- package/templates/handlebars/partials/workflow-summary.hbs +16 -16
- package/templates/handlebars/windsurf-rules.hbs +69 -69
- package/templates/hooks/post-commit.hbs +28 -29
- 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 };
|