create-universal-ai-context 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +171 -0
  3. package/bin/create-ai-context.js +337 -0
  4. package/lib/adapters/antigravity.js +160 -0
  5. package/lib/adapters/claude.js +122 -0
  6. package/lib/adapters/cline.js +111 -0
  7. package/lib/adapters/copilot.js +117 -0
  8. package/lib/adapters/index.js +69 -0
  9. package/lib/ai-context-generator.js +234 -0
  10. package/lib/ai-orchestrator.js +431 -0
  11. package/lib/call-tracer.js +444 -0
  12. package/lib/detector.js +726 -0
  13. package/lib/environment-detector.js +239 -0
  14. package/lib/index.js +310 -0
  15. package/lib/installer.js +418 -0
  16. package/lib/migrate.js +319 -0
  17. package/lib/placeholder.js +541 -0
  18. package/lib/prompts.js +287 -0
  19. package/lib/spinner.js +60 -0
  20. package/lib/static-analyzer.js +729 -0
  21. package/lib/template-populator.js +843 -0
  22. package/lib/template-renderer.js +382 -0
  23. package/lib/validate.js +155 -0
  24. package/package.json +70 -0
  25. package/templates/AI_CONTEXT.md.template +245 -0
  26. package/templates/base/README.md +257 -0
  27. package/templates/base/RPI_WORKFLOW_PLAN.md +320 -0
  28. package/templates/base/agents/api-developer.md +76 -0
  29. package/templates/base/agents/context-engineer.md +525 -0
  30. package/templates/base/agents/core-architect.md +76 -0
  31. package/templates/base/agents/database-ops.md +76 -0
  32. package/templates/base/agents/deployment-ops.md +76 -0
  33. package/templates/base/agents/integration-hub.md +76 -0
  34. package/templates/base/analytics/README.md +114 -0
  35. package/templates/base/automation/config.json +58 -0
  36. package/templates/base/automation/generators/code-mapper.js +308 -0
  37. package/templates/base/automation/generators/index-builder.js +321 -0
  38. package/templates/base/automation/hooks/post-commit.sh +83 -0
  39. package/templates/base/automation/hooks/pre-commit.sh +103 -0
  40. package/templates/base/ci-templates/README.md +108 -0
  41. package/templates/base/ci-templates/github-actions/context-check.yml +144 -0
  42. package/templates/base/ci-templates/github-actions/validate-docs.yml +105 -0
  43. package/templates/base/commands/analytics.md +238 -0
  44. package/templates/base/commands/auto-sync.md +172 -0
  45. package/templates/base/commands/collab.md +194 -0
  46. package/templates/base/commands/help.md +450 -0
  47. package/templates/base/commands/rpi-implement.md +115 -0
  48. package/templates/base/commands/rpi-plan.md +93 -0
  49. package/templates/base/commands/rpi-research.md +88 -0
  50. package/templates/base/commands/session-resume.md +144 -0
  51. package/templates/base/commands/session-save.md +112 -0
  52. package/templates/base/commands/validate-all.md +77 -0
  53. package/templates/base/commands/verify-docs-current.md +86 -0
  54. package/templates/base/config/base.json +57 -0
  55. package/templates/base/config/environments/development.json +13 -0
  56. package/templates/base/config/environments/production.json +17 -0
  57. package/templates/base/config/environments/staging.json +13 -0
  58. package/templates/base/config/local.json.example +21 -0
  59. package/templates/base/context/.meta/generated-at.json +18 -0
  60. package/templates/base/context/ARCHITECTURE_SNAPSHOT.md +156 -0
  61. package/templates/base/context/CODE_TO_WORKFLOW_MAP.md +94 -0
  62. package/templates/base/context/FILE_OWNERSHIP.md +57 -0
  63. package/templates/base/context/INTEGRATION_POINTS.md +92 -0
  64. package/templates/base/context/KNOWN_GOTCHAS.md +195 -0
  65. package/templates/base/context/TESTING_MAP.md +95 -0
  66. package/templates/base/context/WORKFLOW_INDEX.md +129 -0
  67. package/templates/base/context/workflows/WORKFLOW_TEMPLATE.md +294 -0
  68. package/templates/base/indexes/agents/CAPABILITY_MATRIX.md +255 -0
  69. package/templates/base/indexes/agents/CATEGORY_INDEX.md +44 -0
  70. package/templates/base/indexes/code/CATEGORY_INDEX.md +38 -0
  71. package/templates/base/indexes/routing/CATEGORY_INDEX.md +39 -0
  72. package/templates/base/indexes/search/CATEGORY_INDEX.md +39 -0
  73. package/templates/base/indexes/workflows/CATEGORY_INDEX.md +38 -0
  74. package/templates/base/knowledge/README.md +98 -0
  75. package/templates/base/knowledge/sessions/README.md +88 -0
  76. package/templates/base/knowledge/sessions/TEMPLATE.md +150 -0
  77. package/templates/base/knowledge/shared/decisions/0001-adopt-context-engineering.md +144 -0
  78. package/templates/base/knowledge/shared/decisions/README.md +49 -0
  79. package/templates/base/knowledge/shared/decisions/TEMPLATE.md +123 -0
  80. package/templates/base/knowledge/shared/patterns/README.md +62 -0
  81. package/templates/base/knowledge/shared/patterns/TEMPLATE.md +120 -0
  82. package/templates/base/plans/PLAN_TEMPLATE.md +250 -0
  83. package/templates/base/plans/active/.gitkeep +0 -0
  84. package/templates/base/plans/completed/.gitkeep +0 -0
  85. package/templates/base/research/RESEARCH_TEMPLATE.md +153 -0
  86. package/templates/base/research/active/.gitkeep +0 -0
  87. package/templates/base/research/completed/.gitkeep +0 -0
  88. package/templates/base/schemas/agent.schema.json +141 -0
  89. package/templates/base/schemas/anchors.schema.json +54 -0
  90. package/templates/base/schemas/automation.schema.json +93 -0
  91. package/templates/base/schemas/command.schema.json +134 -0
  92. package/templates/base/schemas/hashes.schema.json +40 -0
  93. package/templates/base/schemas/manifest.schema.json +117 -0
  94. package/templates/base/schemas/plan.schema.json +136 -0
  95. package/templates/base/schemas/research.schema.json +115 -0
  96. package/templates/base/schemas/roles.schema.json +34 -0
  97. package/templates/base/schemas/session.schema.json +77 -0
  98. package/templates/base/schemas/settings.schema.json +244 -0
  99. package/templates/base/schemas/staleness.schema.json +53 -0
  100. package/templates/base/schemas/team-config.schema.json +42 -0
  101. package/templates/base/schemas/workflow.schema.json +126 -0
  102. package/templates/base/session/checkpoints/.gitkeep +2 -0
  103. package/templates/base/session/current/state.json +20 -0
  104. package/templates/base/session/history/.gitkeep +2 -0
  105. package/templates/base/settings.json +3 -0
  106. package/templates/base/standards/COMPATIBILITY.md +219 -0
  107. package/templates/base/standards/EXTENSION_GUIDELINES.md +280 -0
  108. package/templates/base/standards/QUALITY_CHECKLIST.md +211 -0
  109. package/templates/base/standards/README.md +66 -0
  110. package/templates/base/sync/anchors.json +6 -0
  111. package/templates/base/sync/hashes.json +6 -0
  112. package/templates/base/sync/staleness.json +10 -0
  113. package/templates/base/team/README.md +168 -0
  114. package/templates/base/team/config.json +79 -0
  115. package/templates/base/team/roles.json +145 -0
  116. package/templates/base/tools/bin/claude-context.js +151 -0
  117. package/templates/base/tools/lib/anchor-resolver.js +276 -0
  118. package/templates/base/tools/lib/config-loader.js +363 -0
  119. package/templates/base/tools/lib/detector.js +350 -0
  120. package/templates/base/tools/lib/diagnose.js +206 -0
  121. package/templates/base/tools/lib/drift-detector.js +373 -0
  122. package/templates/base/tools/lib/errors.js +199 -0
  123. package/templates/base/tools/lib/index.js +36 -0
  124. package/templates/base/tools/lib/init.js +192 -0
  125. package/templates/base/tools/lib/logger.js +230 -0
  126. package/templates/base/tools/lib/placeholder.js +201 -0
  127. package/templates/base/tools/lib/session-manager.js +354 -0
  128. package/templates/base/tools/lib/validate.js +521 -0
  129. package/templates/base/tools/package.json +49 -0
  130. package/templates/handlebars/antigravity.hbs +337 -0
  131. package/templates/handlebars/claude.hbs +184 -0
  132. package/templates/handlebars/cline.hbs +63 -0
  133. package/templates/handlebars/copilot.hbs +131 -0
  134. package/templates/handlebars/partials/gotcha-list.hbs +11 -0
  135. package/templates/handlebars/partials/header.hbs +3 -0
  136. package/templates/handlebars/partials/workflow-summary.hbs +16 -0
@@ -0,0 +1,843 @@
1
+ /**
2
+ * AI Context Engineering - Template Populator
3
+ *
4
+ * Takes analysis results and populates all template files
5
+ * with real, project-specific content.
6
+ */
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+ const { glob } = require('glob');
11
+
12
+ /**
13
+ * Context directory and file names
14
+ */
15
+ const AI_CONTEXT_DIR = '.ai-context';
16
+ const AI_CONTEXT_FILE = 'AI_CONTEXT.md';
17
+
18
+ /**
19
+ * Slugify a string for use in filenames
20
+ * @param {string} str - String to slugify
21
+ * @returns {string}
22
+ */
23
+ function slugify(str) {
24
+ return str
25
+ .toLowerCase()
26
+ .replace(/[^a-z0-9]+/g, '-')
27
+ .replace(/^-|-$/g, '');
28
+ }
29
+
30
+ /**
31
+ * Populate all templates with analysis results
32
+ * @param {string} contextDir - .ai-context directory path
33
+ * @param {object} analysis - Analysis results from static analyzer
34
+ * @param {object} config - Configuration from CLI
35
+ * @returns {Promise<object>} Results of population
36
+ */
37
+ async function populateAllTemplates(contextDir, analysis, config) {
38
+ const results = {
39
+ populated: [],
40
+ skipped: [],
41
+ errors: [],
42
+ created: []
43
+ };
44
+
45
+ const projectRoot = path.dirname(contextDir);
46
+ const projectName = config.projectName || path.basename(projectRoot);
47
+
48
+ // 1. Populate AI_CONTEXT.md at project root
49
+ try {
50
+ await populateAiContextMd(projectRoot, analysis, config);
51
+ results.populated.push(AI_CONTEXT_FILE);
52
+ } catch (error) {
53
+ results.errors.push({ file: AI_CONTEXT_FILE, error: error.message });
54
+ }
55
+
56
+ // 2. Generate ARCHITECTURE_SNAPSHOT.md
57
+ try {
58
+ const content = generateArchitectureSnapshot(analysis, config);
59
+ const filePath = path.join(contextDir, 'context', 'ARCHITECTURE_SNAPSHOT.md');
60
+ ensureDir(path.dirname(filePath));
61
+ fs.writeFileSync(filePath, content);
62
+ results.populated.push('context/ARCHITECTURE_SNAPSHOT.md');
63
+ } catch (error) {
64
+ results.errors.push({ file: 'ARCHITECTURE_SNAPSHOT.md', error: error.message });
65
+ }
66
+
67
+ // 3. Generate WORKFLOW_INDEX.md
68
+ try {
69
+ const content = generateWorkflowIndex(analysis, config);
70
+ const filePath = path.join(contextDir, 'context', 'WORKFLOW_INDEX.md');
71
+ ensureDir(path.dirname(filePath));
72
+ fs.writeFileSync(filePath, content);
73
+ results.populated.push('context/WORKFLOW_INDEX.md');
74
+ } catch (error) {
75
+ results.errors.push({ file: 'WORKFLOW_INDEX.md', error: error.message });
76
+ }
77
+
78
+ // 4. Generate CODE_TO_WORKFLOW_MAP.md
79
+ try {
80
+ const content = generateCodeToWorkflowMap(analysis, config);
81
+ const filePath = path.join(contextDir, 'context', 'CODE_TO_WORKFLOW_MAP.md');
82
+ ensureDir(path.dirname(filePath));
83
+ fs.writeFileSync(filePath, content);
84
+ results.populated.push('context/CODE_TO_WORKFLOW_MAP.md');
85
+ } catch (error) {
86
+ results.errors.push({ file: 'CODE_TO_WORKFLOW_MAP.md', error: error.message });
87
+ }
88
+
89
+ // 5. Generate individual workflow files
90
+ const workflowsDir = path.join(contextDir, 'context', 'workflows');
91
+ ensureDir(workflowsDir);
92
+
93
+ for (const workflow of (analysis.workflows || [])) {
94
+ try {
95
+ const content = generateWorkflowFile(workflow, analysis, config);
96
+ const filename = `${slugify(workflow.name)}.md`;
97
+ const filePath = path.join(workflowsDir, filename);
98
+ fs.writeFileSync(filePath, content);
99
+ results.created.push(`context/workflows/${filename}`);
100
+ } catch (error) {
101
+ results.errors.push({ file: `workflow:${workflow.name}`, error: error.message });
102
+ }
103
+ }
104
+
105
+ // 6. Update category indexes
106
+ try {
107
+ await updateCategoryIndexes(contextDir, analysis, config);
108
+ results.populated.push('indexes/workflows/CATEGORY_INDEX.md');
109
+ } catch (error) {
110
+ results.errors.push({ file: 'CATEGORY_INDEX.md', error: error.message });
111
+ }
112
+
113
+ return results;
114
+ }
115
+
116
+ /**
117
+ * Ensure directory exists
118
+ * @param {string} dirPath - Directory path
119
+ */
120
+ function ensureDir(dirPath) {
121
+ if (!fs.existsSync(dirPath)) {
122
+ fs.mkdirSync(dirPath, { recursive: true });
123
+ }
124
+ }
125
+
126
+ /**
127
+ * Populate AI_CONTEXT.md with real project info
128
+ * @param {string} projectRoot - Project root directory
129
+ * @param {object} analysis - Analysis results
130
+ * @param {object} config - Configuration
131
+ */
132
+ async function populateAiContextMd(projectRoot, analysis, config) {
133
+ const aiContextPath = path.join(projectRoot, AI_CONTEXT_FILE);
134
+
135
+ if (!fs.existsSync(aiContextPath)) {
136
+ return;
137
+ }
138
+
139
+ let content = fs.readFileSync(aiContextPath, 'utf-8');
140
+ const projectName = config.projectName || path.basename(projectRoot);
141
+
142
+ // Build replacement map from analysis
143
+ const replacements = {
144
+ '{{PROJECT_NAME}}': projectName,
145
+ '{{PROJECT_DESCRIPTION}}': `${projectName} application`,
146
+ '{{TECH_STACK}}': analysis.techStack?.summary || config.techStack?.summary || 'Unknown',
147
+ '{{PROJECT_STATUS}}': 'Development',
148
+ '{{PRODUCTION_URL}}': `https://${slugify(projectName)}.example.com`,
149
+ '{{API_URL}}': `https://api.${slugify(projectName)}.example.com`,
150
+ '{{REPO_URL}}': `https://github.com/user/${slugify(projectName)}`,
151
+ '{{DEPLOYMENT_PLATFORM}}': detectDeploymentPlatform(projectRoot),
152
+ '{{DATE}}': new Date().toISOString().split('T')[0],
153
+
154
+ // Commands
155
+ '{{INSTALL_COMMAND}}': getInstallCommand(analysis.techStack || config.techStack),
156
+ '{{DEV_START_COMMAND}}': getDevCommand(analysis.techStack || config.techStack),
157
+ '{{TEST_COMMAND}}': getTestCommand(analysis.techStack || config.techStack),
158
+ '{{TEST_E2E_COMMAND}}': 'npm run test:e2e',
159
+ '{{TEST_COVERAGE_COMMAND}}': 'npm run test:coverage',
160
+ '{{MIGRATION_CREATE_COMMAND}}': getMigrationCreateCommand(analysis.techStack || config.techStack),
161
+ '{{MIGRATION_RUN_COMMAND}}': getMigrationRunCommand(analysis.techStack || config.techStack),
162
+ '{{DEPLOY_COMMAND}}': 'npm run deploy',
163
+
164
+ // Paths
165
+ '{{MODELS_PATH}}': findModelsPath(analysis),
166
+ '{{MIGRATIONS_PATH}}': findMigrationsPath(analysis),
167
+ '{{CORE_FILES_LIST}}': formatCoreFiles(analysis),
168
+
169
+ // Counts
170
+ '{{WORKFLOWS_COUNT}}': String(analysis.workflows?.length || 0),
171
+ '{{AGENTS_COUNT}}': '6',
172
+ '{{COMMANDS_COUNT}}': '11',
173
+ '{{INDEX_FILES_COUNT}}': '15',
174
+ '{{WORKFLOW_DOMAINS_COUNT}}': String(analysis.workflows?.length || 0),
175
+ '{{CODE_DOMAINS_COUNT}}': String(analysis.architecture?.layers?.length || 0),
176
+
177
+ // Architecture
178
+ '{{ARCHITECTURE_DIAGRAM}}': generateAsciiArchitecture(analysis),
179
+
180
+ // Misc
181
+ '{{EXTERNAL_INTEGRATIONS_LIST}}': formatExternalIntegrations(analysis),
182
+ '{{CONFIG_SEARCH_PATTERN}}': 'grep -r "process.env" --include="*.js" --include="*.ts"',
183
+ '{{URL_SEARCH_PATTERN}}': 'grep -rE "https?://" --include="*.js" --include="*.ts" --include="*.json"',
184
+
185
+ // Placeholders for manual filling
186
+ '{{EXAMPLE_REFACTOR_TASK}}': 'Refactor the authentication flow',
187
+ '{{EXAMPLE_LOWLEVEL_TASK}}': 'Fix hardcoded API URL in config',
188
+ '{{EXAMPLE_FEATURE_TASK}}': 'Add user notifications feature',
189
+ '{{CRITICAL_URLS}}': `- Production: https://${slugify(projectName)}.example.com`,
190
+ '{{BUSINESS_CONSTANTS}}': '- TBD (document key business constants)',
191
+ '{{DEBUGGING_QUICK_REFS}}': 'KNOWN_GOTCHAS.md, logs/',
192
+ '{{AGENT_ROUTING_TABLE}}': '@context-engineer for setup, @core-architect for design',
193
+ '{{GOTCHA_CATEGORY_1}}': 'Database',
194
+ '{{GOTCHA_1_ITEMS}}': '- TBD (document database gotchas)',
195
+ '{{GOTCHA_CATEGORY_2}}': 'API',
196
+ '{{GOTCHA_2_ITEMS}}': '- TBD (document API gotchas)',
197
+ '{{PRODUCTION_PLATFORM}}': detectDeploymentPlatform(projectRoot),
198
+ '{{PRODUCTION_SERVICES}}': 'Web, API, Database',
199
+ '{{MONITORING_COMMANDS}}': 'Check logs, health endpoints',
200
+ '{{MIGRATION_CONSTRAINTS}}': 'Always backup before migrations',
201
+ '{{TESTING_CONSTRAINTS}}': 'Run tests before merging',
202
+ '{{SECURITY_CONSTRAINTS}}': 'Never commit secrets',
203
+ '{{CONTACT_INFO}}': 'TBD (add contact info)'
204
+ };
205
+
206
+ // Apply replacements
207
+ for (const [placeholder, value] of Object.entries(replacements)) {
208
+ content = content.replace(new RegExp(escapeRegex(placeholder), 'g'), value);
209
+ }
210
+
211
+ fs.writeFileSync(aiContextPath, content);
212
+ }
213
+
214
+ /**
215
+ * Escape regex special characters
216
+ * @param {string} str - String to escape
217
+ * @returns {string}
218
+ */
219
+ function escapeRegex(str) {
220
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
221
+ }
222
+
223
+ /**
224
+ * Generate ARCHITECTURE_SNAPSHOT.md content
225
+ * @param {object} analysis - Analysis results
226
+ * @param {object} config - Configuration
227
+ * @returns {string}
228
+ */
229
+ function generateArchitectureSnapshot(analysis, config) {
230
+ const projectName = config.projectName || 'Project';
231
+ const date = new Date().toISOString().split('T')[0];
232
+
233
+ return `# Architecture Snapshot - ${projectName}
234
+
235
+ **Purpose:** High-level system map for rapid orientation
236
+ **Load:** When starting a new session or onboarding
237
+ **Size:** ~10k tokens (5% of 200k budget)
238
+ **Last Updated:** ${date}
239
+
240
+ ---
241
+
242
+ ## System Overview
243
+
244
+ \`\`\`
245
+ ${generateAsciiArchitecture(analysis)}
246
+ \`\`\`
247
+
248
+ ---
249
+
250
+ ## Technology Stack
251
+
252
+ | Layer | Technology | Purpose |
253
+ |-------|------------|---------|
254
+ ${formatTechStackTable(analysis)}
255
+
256
+ ---
257
+
258
+ ## Core Components
259
+
260
+ ${formatComponents(analysis)}
261
+
262
+ ---
263
+
264
+ ## Directory Structure
265
+
266
+ \`\`\`
267
+ ${analysis.architecture?.directoryTree || 'TBD - Run AI analysis for complete structure'}
268
+ \`\`\`
269
+
270
+ ---
271
+
272
+ ## Entry Points
273
+
274
+ | Type | Count | Key Files |
275
+ |------|-------|-----------|
276
+ | API Routes | ${analysis.entryPoints?.length || 0} | ${getTopEntryPointFiles(analysis)} |
277
+ | Workflows | ${analysis.workflows?.length || 0} | See WORKFLOW_INDEX.md |
278
+
279
+ ---
280
+
281
+ ## External Integrations
282
+
283
+ ${formatExternalIntegrations(analysis)}
284
+
285
+ ---
286
+
287
+ ## Data Flow
288
+
289
+ \`\`\`
290
+ Request → Router → Controller → Service → Repository → Database
291
+
292
+ External APIs
293
+ \`\`\`
294
+
295
+ ---
296
+
297
+ ## Key Metrics
298
+
299
+ | Metric | Value |
300
+ |--------|-------|
301
+ | Total Source Files | ${analysis.sourceFiles || 'TBD'} |
302
+ | Lines of Code | ${analysis.linesOfCode?.total || 'TBD'} |
303
+ | Dependencies | ${analysis.dependencies?.length || 0} |
304
+ | Entry Points | ${analysis.entryPoints?.length || 0} |
305
+ | Workflows | ${analysis.workflows?.length || 0} |
306
+
307
+ ---
308
+
309
+ *Auto-generated by create-ai-context. Enhance with AI analysis for complete details.*
310
+ `;
311
+ }
312
+
313
+ /**
314
+ * Generate WORKFLOW_INDEX.md content
315
+ * @param {object} analysis - Analysis results
316
+ * @param {object} config - Configuration
317
+ * @returns {string}
318
+ */
319
+ function generateWorkflowIndex(analysis, config) {
320
+ const projectName = config.projectName || 'Project';
321
+ const date = new Date().toISOString().split('T')[0];
322
+ const workflows = analysis.workflows || [];
323
+
324
+ return `# Workflow Index - ${projectName}
325
+
326
+ **Purpose:** Master catalog of all documented workflows
327
+ **Load:** At session start for navigation
328
+ **Size:** ~15k tokens (7.5% of 200k budget)
329
+ **Last Updated:** ${date}
330
+
331
+ ---
332
+
333
+ ## Quick Navigation
334
+
335
+ | Workflow | Category | Complexity | Files | Link |
336
+ |----------|----------|------------|-------|------|
337
+ ${workflows.map(wf =>
338
+ `| ${wf.name} | ${wf.category} | ${wf.complexity} | ${wf.fileCount || wf.files?.length || 0} | [Details](./workflows/${slugify(wf.name)}.md) |`
339
+ ).join('\n') || '| *No workflows discovered* | - | - | - | - |'}
340
+
341
+ ---
342
+
343
+ ## Workflows by Category
344
+
345
+ ${formatWorkflowsByCategory(workflows)}
346
+
347
+ ---
348
+
349
+ ## Entry Points Summary
350
+
351
+ | Entry Point | Workflow | Method |
352
+ |-------------|----------|--------|
353
+ ${formatEntryPointsTable(analysis.entryPoints)}
354
+
355
+ ---
356
+
357
+ ## Cross-Reference: Files → Workflows
358
+
359
+ See [CODE_TO_WORKFLOW_MAP.md](./CODE_TO_WORKFLOW_MAP.md) for reverse lookup.
360
+
361
+ ---
362
+
363
+ ## Maintenance
364
+
365
+ - **Verification Frequency:** Weekly spot-checks, quarterly full review
366
+ - **Last Verified:** ${date}
367
+ - **Next Review:** TBD
368
+
369
+ ---
370
+
371
+ *Auto-generated by create-ai-context. Run AI analysis for complete workflow documentation.*
372
+ `;
373
+ }
374
+
375
+ /**
376
+ * Generate CODE_TO_WORKFLOW_MAP.md content
377
+ * @param {object} analysis - Analysis results
378
+ * @param {object} config - Configuration
379
+ * @returns {string}
380
+ */
381
+ function generateCodeToWorkflowMap(analysis, config) {
382
+ const projectName = config.projectName || 'Project';
383
+ const date = new Date().toISOString().split('T')[0];
384
+
385
+ // Build file to workflow mapping
386
+ const fileMap = buildFileToWorkflowMap(analysis);
387
+
388
+ return `# Code to Workflow Map - ${projectName}
389
+
390
+ **Purpose:** Reverse lookup - find documentation for any file
391
+ **Load:** When investigating a specific file
392
+ **Size:** ~20k tokens (10% of 200k budget)
393
+ **Last Updated:** ${date}
394
+
395
+ ---
396
+
397
+ ## How to Use
398
+
399
+ When you modify a file:
400
+ 1. Find it in this index
401
+ 2. Check which workflows reference it
402
+ 3. Update those workflow docs accordingly
403
+
404
+ ---
405
+
406
+ ## File Index
407
+
408
+ ${formatFileIndex(fileMap)}
409
+
410
+ ---
411
+
412
+ ## Undocumented Files
413
+
414
+ The following files are not yet mapped to workflows:
415
+
416
+ ${formatUndocumentedFiles(analysis, fileMap)}
417
+
418
+ ---
419
+
420
+ ## Update Checklist
421
+
422
+ After modifying code:
423
+
424
+ - [ ] Find affected file(s) in this index
425
+ - [ ] Update line numbers in referenced workflows
426
+ - [ ] Verify function signatures still match
427
+ - [ ] Run \`/verify-docs-current\` to validate
428
+
429
+ ---
430
+
431
+ *Auto-generated by create-ai-context. Run \`/auto-sync --rebuild-map\` to refresh.*
432
+ `;
433
+ }
434
+
435
+ /**
436
+ * Generate individual workflow file
437
+ * @param {object} workflow - Workflow data
438
+ * @param {object} analysis - Full analysis
439
+ * @param {object} config - Configuration
440
+ * @returns {string}
441
+ */
442
+ function generateWorkflowFile(workflow, analysis, config) {
443
+ const date = new Date().toISOString().split('T')[0];
444
+
445
+ // Find entry points for this workflow
446
+ const workflowEntryPoints = (analysis.entryPoints || []).filter(ep =>
447
+ workflow.files?.some(f => ep.file.includes(f) || f.includes(ep.file))
448
+ );
449
+
450
+ return `---
451
+ name: ${slugify(workflow.name)}
452
+ category: ${workflow.category || 'general'}
453
+ complexity: ${workflow.complexity || 'MEDIUM'}
454
+ last_updated: ${date}
455
+ status: discovered
456
+ ---
457
+
458
+ # ${workflow.name}
459
+
460
+ ## Overview
461
+
462
+ **Purpose:** ${getWorkflowPurpose(workflow)}
463
+ **Complexity:** ${workflow.complexity || 'MEDIUM'}
464
+ **Confidence:** ${workflow.confidence || 0}%
465
+ **Files Involved:** ${workflow.fileCount || workflow.files?.length || 0}
466
+
467
+ ---
468
+
469
+ ## Entry Points
470
+
471
+ ${workflowEntryPoints.length > 0 ? formatWorkflowEntryPoints(workflowEntryPoints) : '*Entry points to be documented during AI analysis*'}
472
+
473
+ ---
474
+
475
+ ## Key Files
476
+
477
+ | File | Purpose |
478
+ |------|---------|
479
+ ${(workflow.files || []).slice(0, 20).map(f => `| \`${f}\` | TBD |`).join('\n') || '| *No files mapped* | - |'}
480
+
481
+ ---
482
+
483
+ ## Call Chain
484
+
485
+ \`\`\`
486
+ ${workflow.name.toLowerCase().replace(/\s+/g, '_')}()
487
+ ├─ [To be traced during AI analysis]
488
+ └─ [To be traced during AI analysis]
489
+ \`\`\`
490
+
491
+ ---
492
+
493
+ ## Database Operations
494
+
495
+ *Database operations to be documented during AI analysis*
496
+
497
+ ---
498
+
499
+ ## External Dependencies
500
+
501
+ *External dependencies to be documented during AI analysis*
502
+
503
+ ---
504
+
505
+ ## Test Coverage
506
+
507
+ | Test File | Type | Coverage |
508
+ |-----------|------|----------|
509
+ | *TBD* | - | - |
510
+
511
+ ---
512
+
513
+ ## Known Gotchas
514
+
515
+ *No gotchas documented yet. Add as discovered.*
516
+
517
+ ---
518
+
519
+ ## Maintenance
520
+
521
+ - **Last Verified:** ${date}
522
+ - **Verification Method:** Auto-discovered
523
+ - **Next Review:** TBD
524
+
525
+ ---
526
+
527
+ *Auto-generated by create-ai-context. Enhance with AI analysis for complete documentation.*
528
+ `;
529
+ }
530
+
531
+ /**
532
+ * Update category indexes
533
+ * @param {string} contextDir - .ai-context directory path
534
+ * @param {object} analysis - Analysis results
535
+ * @param {object} config - Configuration
536
+ */
537
+ async function updateCategoryIndexes(contextDir, analysis, config) {
538
+ const indexPath = path.join(contextDir, 'indexes', 'workflows', 'CATEGORY_INDEX.md');
539
+ ensureDir(path.dirname(indexPath));
540
+
541
+ const workflows = analysis.workflows || [];
542
+ const categories = [...new Set(workflows.map(w => w.category))];
543
+ const date = new Date().toISOString().split('T')[0];
544
+
545
+ const content = `# Workflow Category Index
546
+
547
+ **Purpose:** Quick navigation to workflow categories
548
+ **Load:** At session start
549
+ **Last Updated:** ${date}
550
+
551
+ ---
552
+
553
+ ## Categories
554
+
555
+ ${categories.map(cat => {
556
+ const catWorkflows = workflows.filter(w => w.category === cat);
557
+ return `### ${cat.charAt(0).toUpperCase() + cat.slice(1)}
558
+
559
+ | Workflow | Complexity | Link |
560
+ |----------|------------|------|
561
+ ${catWorkflows.map(w => `| ${w.name} | ${w.complexity} | [Details](../../context/workflows/${slugify(w.name)}.md) |`).join('\n')}
562
+ `;
563
+ }).join('\n') || '*No workflows discovered yet*'}
564
+
565
+ ---
566
+
567
+ ## Summary
568
+
569
+ | Category | Count |
570
+ |----------|-------|
571
+ ${categories.map(cat => `| ${cat} | ${workflows.filter(w => w.category === cat).length} |`).join('\n') || '| - | 0 |'}
572
+
573
+ ---
574
+
575
+ *Auto-generated by create-ai-context*
576
+ `;
577
+
578
+ fs.writeFileSync(indexPath, content);
579
+ }
580
+
581
+ // Helper functions
582
+
583
+ function getInstallCommand(techStack) {
584
+ const languages = techStack?.languages || [];
585
+ if (languages.includes('python')) return 'pip install -r requirements.txt';
586
+ if (languages.includes('go')) return 'go mod download';
587
+ if (languages.includes('rust')) return 'cargo build';
588
+ if (languages.includes('ruby')) return 'bundle install';
589
+ return 'npm install';
590
+ }
591
+
592
+ function getDevCommand(techStack) {
593
+ const languages = techStack?.languages || [];
594
+ if (languages.includes('python')) return 'python main.py';
595
+ if (languages.includes('go')) return 'go run .';
596
+ if (languages.includes('rust')) return 'cargo run';
597
+ if (languages.includes('ruby')) return 'rails server';
598
+ return 'npm run dev';
599
+ }
600
+
601
+ function getTestCommand(techStack) {
602
+ const languages = techStack?.languages || [];
603
+ if (languages.includes('python')) return 'pytest';
604
+ if (languages.includes('go')) return 'go test ./...';
605
+ if (languages.includes('rust')) return 'cargo test';
606
+ if (languages.includes('ruby')) return 'rspec';
607
+ return 'npm test';
608
+ }
609
+
610
+ function getMigrationCreateCommand(techStack) {
611
+ const languages = techStack?.languages || [];
612
+ if (languages.includes('python')) return 'alembic revision --autogenerate -m "description"';
613
+ if (languages.includes('ruby')) return 'rails generate migration MigrationName';
614
+ return 'npm run migration:create';
615
+ }
616
+
617
+ function getMigrationRunCommand(techStack) {
618
+ const languages = techStack?.languages || [];
619
+ if (languages.includes('python')) return 'alembic upgrade head';
620
+ if (languages.includes('ruby')) return 'rails db:migrate';
621
+ return 'npm run migration:run';
622
+ }
623
+
624
+ function detectDeploymentPlatform(projectRoot) {
625
+ if (fs.existsSync(path.join(projectRoot, 'vercel.json'))) return 'Vercel';
626
+ if (fs.existsSync(path.join(projectRoot, 'netlify.toml'))) return 'Netlify';
627
+ if (fs.existsSync(path.join(projectRoot, 'Dockerfile'))) return 'Docker';
628
+ if (fs.existsSync(path.join(projectRoot, 'fly.toml'))) return 'Fly.io';
629
+ if (fs.existsSync(path.join(projectRoot, 'render.yaml'))) return 'Render';
630
+ if (fs.existsSync(path.join(projectRoot, 'railway.json'))) return 'Railway';
631
+ return 'TBD';
632
+ }
633
+
634
+ function findModelsPath(analysis) {
635
+ const layers = analysis.architecture?.layers || [];
636
+ const domainLayer = layers.find(l => l.name === 'domain');
637
+ if (domainLayer?.directories?.length > 0) {
638
+ return domainLayer.directories[0] + '/';
639
+ }
640
+ return 'models/';
641
+ }
642
+
643
+ function findMigrationsPath(analysis) {
644
+ return 'migrations/';
645
+ }
646
+
647
+ function formatCoreFiles(analysis) {
648
+ const entryPoints = analysis.entryPoints || [];
649
+ const uniqueFiles = [...new Set(entryPoints.map(ep => ep.file))].slice(0, 5);
650
+ return uniqueFiles.map(f => `- \`${f}\``).join('\n') || '- TBD';
651
+ }
652
+
653
+ function generateAsciiArchitecture(analysis) {
654
+ const layers = analysis.architecture?.layers || [];
655
+
656
+ if (layers.length === 0) {
657
+ return `┌─────────────────────────────────────┐
658
+ │ [Application] │
659
+ │ │
660
+ │ ┌───────────┐ ┌───────────┐ │
661
+ │ │ API │ │ Services │ │
662
+ │ └───────────┘ └───────────┘ │
663
+ │ │
664
+ │ ┌───────────┐ ┌───────────┐ │
665
+ │ │ Models │ │ Database │ │
666
+ │ └───────────┘ └───────────┘ │
667
+ └─────────────────────────────────────┘`;
668
+ }
669
+
670
+ let diagram = '┌─────────────────────────────────────┐\n';
671
+ for (const layer of layers.slice(0, 4)) {
672
+ diagram += `│ [${layer.name.padEnd(30)}] │\n`;
673
+ diagram += `│ ${layer.directories?.slice(0, 2).join(', ').padEnd(32)}│\n`;
674
+ }
675
+ diagram += '└─────────────────────────────────────┘';
676
+
677
+ return diagram;
678
+ }
679
+
680
+ function formatTechStackTable(analysis) {
681
+ const techStack = analysis.techStack || {};
682
+ const rows = [];
683
+
684
+ if (techStack.languages?.length > 0) {
685
+ rows.push(`| **Languages** | ${techStack.languages.join(', ')} | Core development |`);
686
+ }
687
+ if (techStack.frameworks?.length > 0) {
688
+ rows.push(`| **Frameworks** | ${techStack.frameworks.join(', ')} | Application framework |`);
689
+ }
690
+ if (techStack.databases?.length > 0) {
691
+ rows.push(`| **Databases** | ${techStack.databases.join(', ')} | Data persistence |`);
692
+ }
693
+
694
+ return rows.join('\n') || '| *TBD* | - | - |';
695
+ }
696
+
697
+ function formatComponents(analysis) {
698
+ const layers = analysis.architecture?.layers || [];
699
+ return layers.map(layer => `
700
+ ### ${layer.name.charAt(0).toUpperCase() + layer.name.slice(1)}
701
+
702
+ **Purpose:** ${layer.purpose || 'TBD'}
703
+ **Directories:** ${layer.directories?.join(', ') || 'TBD'}
704
+ `).join('\n') || '*Components will be documented during AI analysis*';
705
+ }
706
+
707
+ function getTopEntryPointFiles(analysis) {
708
+ const entryPoints = analysis.entryPoints || [];
709
+ const files = [...new Set(entryPoints.map(ep => ep.file))].slice(0, 3);
710
+ return files.join(', ') || 'TBD';
711
+ }
712
+
713
+ function formatExternalIntegrations(analysis) {
714
+ const deps = analysis.dependencies || [];
715
+ const integrations = deps.filter(d =>
716
+ ['stripe', 'aws', 'firebase', 'twilio', 'sendgrid', 'redis', 'elasticsearch'].some(
717
+ int => d.name.toLowerCase().includes(int)
718
+ )
719
+ );
720
+
721
+ if (integrations.length === 0) {
722
+ return '*No external integrations detected. Document manually if present.*';
723
+ }
724
+
725
+ return integrations.map(i => `- **${i.name}** (${i.version})`).join('\n');
726
+ }
727
+
728
+ function formatWorkflowsByCategory(workflows) {
729
+ const categories = [...new Set(workflows.map(w => w.category))];
730
+
731
+ return categories.map(cat => {
732
+ const catWorkflows = workflows.filter(w => w.category === cat);
733
+ return `### ${cat.charAt(0).toUpperCase() + cat.slice(1)}
734
+
735
+ ${catWorkflows.map(w => `- [${w.name}](./workflows/${slugify(w.name)}.md) - ${w.complexity}`).join('\n')}
736
+ `;
737
+ }).join('\n') || '*No workflows by category*';
738
+ }
739
+
740
+ function formatEntryPointsTable(entryPoints) {
741
+ if (!entryPoints || entryPoints.length === 0) {
742
+ return '| *TBD* | - | - |';
743
+ }
744
+
745
+ return entryPoints.slice(0, 20).map(ep =>
746
+ `| \`${ep.file}:${ep.line}\` | ${ep.route || 'TBD'} | ${ep.method || '-'} |`
747
+ ).join('\n');
748
+ }
749
+
750
+ function buildFileToWorkflowMap(analysis) {
751
+ const map = {};
752
+ const workflows = analysis.workflows || [];
753
+
754
+ for (const workflow of workflows) {
755
+ for (const file of (workflow.files || [])) {
756
+ if (!map[file]) map[file] = [];
757
+ map[file].push(workflow.name);
758
+ }
759
+ }
760
+
761
+ return map;
762
+ }
763
+
764
+ function formatFileIndex(fileMap) {
765
+ const entries = Object.entries(fileMap);
766
+
767
+ if (entries.length === 0) {
768
+ return '*No files mapped to workflows yet. Run AI analysis to populate.*';
769
+ }
770
+
771
+ // Group by directory
772
+ const byDir = {};
773
+ for (const [file, workflows] of entries) {
774
+ const dir = path.dirname(file) || '.';
775
+ if (!byDir[dir]) byDir[dir] = [];
776
+ byDir[dir].push({ file, workflows });
777
+ }
778
+
779
+ return Object.entries(byDir).map(([dir, files]) => `
780
+ ### ${dir}/
781
+
782
+ | File | Workflows |
783
+ |------|-----------|
784
+ ${files.map(f => `| \`${path.basename(f.file)}\` | ${f.workflows.join(', ')} |`).join('\n')}
785
+ `).join('\n');
786
+ }
787
+
788
+ function formatUndocumentedFiles(analysis, fileMap) {
789
+ const mappedFiles = new Set(Object.keys(fileMap));
790
+ const allEntryFiles = (analysis.entryPoints || []).map(ep => ep.file);
791
+ const unmapped = allEntryFiles.filter(f => !mappedFiles.has(f));
792
+
793
+ if (unmapped.length === 0) {
794
+ return '*All entry point files are mapped to workflows.*';
795
+ }
796
+
797
+ return unmapped.slice(0, 20).map(f => `- \`${f}\``).join('\n');
798
+ }
799
+
800
+ function getWorkflowPurpose(workflow) {
801
+ const purposes = {
802
+ authentication: 'Handles user authentication and session management',
803
+ userManagement: 'Manages user accounts, profiles, and preferences',
804
+ payments: 'Processes payments, billing, and subscriptions',
805
+ dataProcessing: 'Handles background jobs and data pipelines',
806
+ apiEndpoints: 'Exposes API endpoints for external consumption',
807
+ database: 'Manages database operations and queries',
808
+ notifications: 'Sends notifications via email, SMS, or push',
809
+ fileHandling: 'Handles file uploads, storage, and downloads',
810
+ search: 'Provides search functionality across the application',
811
+ analytics: 'Tracks metrics and generates analytics',
812
+ testing: 'Contains test suites and fixtures',
813
+ configuration: 'Manages application configuration'
814
+ };
815
+
816
+ return purposes[workflow.type] || `Handles ${workflow.name.toLowerCase()} functionality`;
817
+ }
818
+
819
+ function formatWorkflowEntryPoints(entryPoints) {
820
+ return entryPoints.slice(0, 10).map(ep => `
821
+ ### \`${ep.file}:${ep.line}\`
822
+
823
+ **Route:** ${ep.route || 'N/A'}
824
+ **Method:** ${ep.method || 'N/A'}
825
+
826
+ \`\`\`
827
+ ${ep.context || 'No context available'}
828
+ \`\`\`
829
+ `).join('\n');
830
+ }
831
+
832
+ module.exports = {
833
+ populateAllTemplates,
834
+ populateAiContextMd,
835
+ generateArchitectureSnapshot,
836
+ generateWorkflowIndex,
837
+ generateCodeToWorkflowMap,
838
+ generateWorkflowFile,
839
+ updateCategoryIndexes,
840
+ slugify,
841
+ AI_CONTEXT_DIR,
842
+ AI_CONTEXT_FILE
843
+ };