create-universal-ai-context 2.4.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 -764
  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
@@ -1,308 +1,308 @@
1
- /**
2
- * Code Mapper - Auto-generates CODE_TO_WORKFLOW_MAP.md
3
- *
4
- * Scans workflow files for file:line references and builds
5
- * a reverse index mapping code files to their documentation.
6
- */
7
-
8
- const fs = require('fs');
9
- const path = require('path');
10
- const glob = require('glob');
11
-
12
- const CLAUDE_DIR = path.join(__dirname, '..', '..');
13
- const CONFIG_PATH = path.join(__dirname, '..', 'config.json');
14
-
15
- /**
16
- * Load automation config
17
- */
18
- function loadConfig() {
19
- try {
20
- const content = fs.readFileSync(CONFIG_PATH, 'utf-8');
21
- return JSON.parse(content);
22
- } catch (error) {
23
- console.error('Failed to load config:', error.message);
24
- return null;
25
- }
26
- }
27
-
28
- /**
29
- * Extract file references from markdown content
30
- */
31
- function extractReferences(content, filePath) {
32
- const references = [];
33
- const patterns = [
34
- // file.ext:123 format
35
- /([a-zA-Z0-9_\-./]+\.[a-zA-Z]+):(\d+)/g,
36
- // [Line 123] format with preceding file path
37
- /`([^`]+)`[^[]*\[Line (\d+)\]/g,
38
- // [Lines 123-456] format
39
- /`([^`]+)`[^[]*\[Lines (\d+)-(\d+)\]/g,
40
- // file.ext::function() semantic anchor format
41
- /([a-zA-Z0-9_\-./]+\.[a-zA-Z]+)::(\w+)\(\)/g
42
- ];
43
-
44
- // Simple line number extraction
45
- const linePattern = /([a-zA-Z0-9_\-./]+\.[a-zA-Z0-9]+):(\d+)/g;
46
- let match;
47
- while ((match = linePattern.exec(content)) !== null) {
48
- references.push({
49
- file: match[1],
50
- line: parseInt(match[2]),
51
- type: 'line',
52
- source: filePath
53
- });
54
- }
55
-
56
- // Semantic anchor extraction
57
- const anchorPattern = /([a-zA-Z0-9_\-./]+\.[a-zA-Z0-9]+)::(\w+)\(\)/g;
58
- while ((match = anchorPattern.exec(content)) !== null) {
59
- references.push({
60
- file: match[1],
61
- anchor: match[2],
62
- type: 'anchor',
63
- source: filePath
64
- });
65
- }
66
-
67
- return references;
68
- }
69
-
70
- /**
71
- * Scan workflow files and extract all references
72
- */
73
- function scanWorkflows() {
74
- const config = loadConfig();
75
- if (!config) return {};
76
-
77
- const allReferences = {};
78
- const scanPatterns = config.generators.code_mapper.scan_patterns || [
79
- 'context/workflows/*.md',
80
- 'agents/*.md'
81
- ];
82
-
83
- for (const pattern of scanPatterns) {
84
- const fullPattern = path.join(CLAUDE_DIR, pattern);
85
- const files = glob.sync(fullPattern);
86
-
87
- for (const file of files) {
88
- try {
89
- const content = fs.readFileSync(file, 'utf-8');
90
- const relativePath = path.relative(CLAUDE_DIR, file);
91
- const refs = extractReferences(content, relativePath);
92
-
93
- for (const ref of refs) {
94
- const normalizedPath = ref.file.replace(/\\/g, '/');
95
- if (!allReferences[normalizedPath]) {
96
- allReferences[normalizedPath] = {
97
- documentedIn: [],
98
- references: []
99
- };
100
- }
101
-
102
- // Add source document
103
- if (!allReferences[normalizedPath].documentedIn.includes(relativePath)) {
104
- allReferences[normalizedPath].documentedIn.push(relativePath);
105
- }
106
-
107
- // Add reference details
108
- allReferences[normalizedPath].references.push({
109
- source: relativePath,
110
- line: ref.line,
111
- anchor: ref.anchor,
112
- type: ref.type
113
- });
114
- }
115
- } catch (error) {
116
- console.error(`Error scanning ${file}:`, error.message);
117
- }
118
- }
119
- }
120
-
121
- return allReferences;
122
- }
123
-
124
- /**
125
- * Generate CODE_TO_WORKFLOW_MAP.md content
126
- */
127
- function generateMapContent(references) {
128
- const now = new Date().toISOString();
129
- let content = `# Code to Workflow Map
130
-
131
- > **Auto-generated:** ${now}
132
- > **Generator:** code-mapper.js
133
- >
134
- > This file maps source code files to the workflow documentation that references them.
135
- > Use this to find which docs need updating after code changes.
136
-
137
- ---
138
-
139
- ## How to Use
140
-
141
- 1. **Modified a file?** Search for it below
142
- 2. **Find "Documented In"** section for affected workflows
143
- 3. **Check references** to see what needs updating
144
- 4. **Run \`/verify-docs-current [file]\`** to validate
145
-
146
- ---
147
-
148
- ## File Mappings
149
-
150
- `;
151
-
152
- // Sort files alphabetically
153
- const sortedFiles = Object.keys(references).sort();
154
-
155
- // Group by directory
156
- const byDirectory = {};
157
- for (const file of sortedFiles) {
158
- const dir = path.dirname(file) || '.';
159
- if (!byDirectory[dir]) {
160
- byDirectory[dir] = [];
161
- }
162
- byDirectory[dir].push(file);
163
- }
164
-
165
- for (const dir of Object.keys(byDirectory).sort()) {
166
- content += `### ${dir}/\n\n`;
167
-
168
- for (const file of byDirectory[dir]) {
169
- const data = references[file];
170
- const fileName = path.basename(file);
171
- const refCount = data.references.length;
172
-
173
- content += `#### \`${fileName}\`\n\n`;
174
- content += `**Documented In:**\n`;
175
- for (const doc of data.documentedIn) {
176
- content += `- [${doc}](./${doc})\n`;
177
- }
178
-
179
- content += `\n**References:** ${refCount}\n`;
180
-
181
- // Group references by type
182
- const lineRefs = data.references.filter(r => r.type === 'line');
183
- const anchorRefs = data.references.filter(r => r.type === 'anchor');
184
-
185
- if (lineRefs.length > 0) {
186
- content += `\n*Line References:*\n`;
187
- for (const ref of lineRefs.slice(0, 5)) {
188
- content += `- Line ${ref.line} in ${ref.source}\n`;
189
- }
190
- if (lineRefs.length > 5) {
191
- content += `- ... and ${lineRefs.length - 5} more\n`;
192
- }
193
- }
194
-
195
- if (anchorRefs.length > 0) {
196
- content += `\n*Semantic Anchors:*\n`;
197
- for (const ref of anchorRefs) {
198
- content += `- \`${ref.anchor}()\` in ${ref.source}\n`;
199
- }
200
- }
201
-
202
- content += `\n**Update After Changing:**\n`;
203
- for (const doc of data.documentedIn) {
204
- content += `- [ ] ${doc}\n`;
205
- }
206
-
207
- content += '\n---\n\n';
208
- }
209
- }
210
-
211
- // Summary section
212
- content += `## Summary
213
-
214
- | Metric | Value |
215
- |--------|-------|
216
- | Files Documented | ${sortedFiles.length} |
217
- | Total References | ${Object.values(references).reduce((sum, r) => sum + r.references.length, 0)} |
218
- | Workflow Files | ${new Set(Object.values(references).flatMap(r => r.documentedIn)).size} |
219
- | Generated | ${now} |
220
-
221
- ---
222
-
223
- ## Files NOT Currently Documented
224
-
225
- *Run \`npx claude-context generate --scan-orphans\` to find undocumented code files.*
226
-
227
- ---
228
-
229
- *This file is auto-generated. Do not edit manually.*
230
- *Regenerate with: \`npx claude-context generate --code-map\`*
231
- `;
232
-
233
- return content;
234
- }
235
-
236
- /**
237
- * Generate and write CODE_TO_WORKFLOW_MAP.md
238
- */
239
- function generate(options = {}) {
240
- const { dryRun = false, verbose = false } = options;
241
-
242
- console.log('Scanning workflow files...');
243
- const references = scanWorkflows();
244
-
245
- const fileCount = Object.keys(references).length;
246
- const refCount = Object.values(references).reduce(
247
- (sum, r) => sum + r.references.length, 0
248
- );
249
-
250
- console.log(`Found ${fileCount} files with ${refCount} references`);
251
-
252
- if (verbose) {
253
- for (const [file, data] of Object.entries(references)) {
254
- console.log(` ${file}: ${data.references.length} refs in ${data.documentedIn.length} docs`);
255
- }
256
- }
257
-
258
- const content = generateMapContent(references);
259
-
260
- if (dryRun) {
261
- console.log('\n--- DRY RUN OUTPUT ---\n');
262
- console.log(content.substring(0, 2000) + '\n...(truncated)');
263
- return { success: true, fileCount, refCount };
264
- }
265
-
266
- const outputPath = path.join(CLAUDE_DIR, 'context', 'CODE_TO_WORKFLOW_MAP.md');
267
- try {
268
- fs.writeFileSync(outputPath, content);
269
- console.log(`Generated: ${outputPath}`);
270
-
271
- // Update metadata
272
- const metaPath = path.join(CLAUDE_DIR, 'context', '.meta', 'generated-at.json');
273
- const metaDir = path.dirname(metaPath);
274
- if (!fs.existsSync(metaDir)) {
275
- fs.mkdirSync(metaDir, { recursive: true });
276
- }
277
- const metadata = {
278
- 'CODE_TO_WORKFLOW_MAP.md': {
279
- generatedAt: new Date().toISOString(),
280
- filesScanned: fileCount,
281
- referencesFound: refCount
282
- }
283
- };
284
- fs.writeFileSync(metaPath, JSON.stringify(metadata, null, 2));
285
-
286
- return { success: true, fileCount, refCount, outputPath };
287
- } catch (error) {
288
- console.error('Failed to write output:', error.message);
289
- return { success: false, error: error.message };
290
- }
291
- }
292
-
293
- // CLI execution
294
- if (require.main === module) {
295
- const args = process.argv.slice(2);
296
- const dryRun = args.includes('--dry-run');
297
- const verbose = args.includes('--verbose') || args.includes('-v');
298
-
299
- const result = generate({ dryRun, verbose });
300
- process.exit(result.success ? 0 : 1);
301
- }
302
-
303
- module.exports = {
304
- generate,
305
- scanWorkflows,
306
- extractReferences,
307
- generateMapContent
308
- };
1
+ /**
2
+ * Code Mapper - Auto-generates CODE_TO_WORKFLOW_MAP.md
3
+ *
4
+ * Scans workflow files for file:line references and builds
5
+ * a reverse index mapping code files to their documentation.
6
+ */
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+ const glob = require('glob');
11
+
12
+ const CLAUDE_DIR = path.join(__dirname, '..', '..');
13
+ const CONFIG_PATH = path.join(__dirname, '..', 'config.json');
14
+
15
+ /**
16
+ * Load automation config
17
+ */
18
+ function loadConfig() {
19
+ try {
20
+ const content = fs.readFileSync(CONFIG_PATH, 'utf-8');
21
+ return JSON.parse(content);
22
+ } catch (error) {
23
+ console.error('Failed to load config:', error.message);
24
+ return null;
25
+ }
26
+ }
27
+
28
+ /**
29
+ * Extract file references from markdown content
30
+ */
31
+ function extractReferences(content, filePath) {
32
+ const references = [];
33
+ const patterns = [
34
+ // file.ext:123 format
35
+ /([a-zA-Z0-9_\-./]+\.[a-zA-Z]+):(\d+)/g,
36
+ // [Line 123] format with preceding file path
37
+ /`([^`]+)`[^[]*\[Line (\d+)\]/g,
38
+ // [Lines 123-456] format
39
+ /`([^`]+)`[^[]*\[Lines (\d+)-(\d+)\]/g,
40
+ // file.ext::function() semantic anchor format
41
+ /([a-zA-Z0-9_\-./]+\.[a-zA-Z]+)::(\w+)\(\)/g
42
+ ];
43
+
44
+ // Simple line number extraction
45
+ const linePattern = /([a-zA-Z0-9_\-./]+\.[a-zA-Z0-9]+):(\d+)/g;
46
+ let match;
47
+ while ((match = linePattern.exec(content)) !== null) {
48
+ references.push({
49
+ file: match[1],
50
+ line: parseInt(match[2]),
51
+ type: 'line',
52
+ source: filePath
53
+ });
54
+ }
55
+
56
+ // Semantic anchor extraction
57
+ const anchorPattern = /([a-zA-Z0-9_\-./]+\.[a-zA-Z0-9]+)::(\w+)\(\)/g;
58
+ while ((match = anchorPattern.exec(content)) !== null) {
59
+ references.push({
60
+ file: match[1],
61
+ anchor: match[2],
62
+ type: 'anchor',
63
+ source: filePath
64
+ });
65
+ }
66
+
67
+ return references;
68
+ }
69
+
70
+ /**
71
+ * Scan workflow files and extract all references
72
+ */
73
+ function scanWorkflows() {
74
+ const config = loadConfig();
75
+ if (!config) return {};
76
+
77
+ const allReferences = {};
78
+ const scanPatterns = config.generators.code_mapper.scan_patterns || [
79
+ 'context/workflows/*.md',
80
+ 'agents/*.md'
81
+ ];
82
+
83
+ for (const pattern of scanPatterns) {
84
+ const fullPattern = path.join(CLAUDE_DIR, pattern);
85
+ const files = glob.sync(fullPattern);
86
+
87
+ for (const file of files) {
88
+ try {
89
+ const content = fs.readFileSync(file, 'utf-8');
90
+ const relativePath = path.relative(CLAUDE_DIR, file);
91
+ const refs = extractReferences(content, relativePath);
92
+
93
+ for (const ref of refs) {
94
+ const normalizedPath = ref.file.replace(/\\/g, '/');
95
+ if (!allReferences[normalizedPath]) {
96
+ allReferences[normalizedPath] = {
97
+ documentedIn: [],
98
+ references: []
99
+ };
100
+ }
101
+
102
+ // Add source document
103
+ if (!allReferences[normalizedPath].documentedIn.includes(relativePath)) {
104
+ allReferences[normalizedPath].documentedIn.push(relativePath);
105
+ }
106
+
107
+ // Add reference details
108
+ allReferences[normalizedPath].references.push({
109
+ source: relativePath,
110
+ line: ref.line,
111
+ anchor: ref.anchor,
112
+ type: ref.type
113
+ });
114
+ }
115
+ } catch (error) {
116
+ console.error(`Error scanning ${file}:`, error.message);
117
+ }
118
+ }
119
+ }
120
+
121
+ return allReferences;
122
+ }
123
+
124
+ /**
125
+ * Generate CODE_TO_WORKFLOW_MAP.md content
126
+ */
127
+ function generateMapContent(references) {
128
+ const now = new Date().toISOString();
129
+ let content = `# Code to Workflow Map
130
+
131
+ > **Auto-generated:** ${now}
132
+ > **Generator:** code-mapper.js
133
+ >
134
+ > This file maps source code files to the workflow documentation that references them.
135
+ > Use this to find which docs need updating after code changes.
136
+
137
+ ---
138
+
139
+ ## How to Use
140
+
141
+ 1. **Modified a file?** Search for it below
142
+ 2. **Find "Documented In"** section for affected workflows
143
+ 3. **Check references** to see what needs updating
144
+ 4. **Run \`/verify-docs-current [file]\`** to validate
145
+
146
+ ---
147
+
148
+ ## File Mappings
149
+
150
+ `;
151
+
152
+ // Sort files alphabetically
153
+ const sortedFiles = Object.keys(references).sort();
154
+
155
+ // Group by directory
156
+ const byDirectory = {};
157
+ for (const file of sortedFiles) {
158
+ const dir = path.dirname(file) || '.';
159
+ if (!byDirectory[dir]) {
160
+ byDirectory[dir] = [];
161
+ }
162
+ byDirectory[dir].push(file);
163
+ }
164
+
165
+ for (const dir of Object.keys(byDirectory).sort()) {
166
+ content += `### ${dir}/\n\n`;
167
+
168
+ for (const file of byDirectory[dir]) {
169
+ const data = references[file];
170
+ const fileName = path.basename(file);
171
+ const refCount = data.references.length;
172
+
173
+ content += `#### \`${fileName}\`\n\n`;
174
+ content += `**Documented In:**\n`;
175
+ for (const doc of data.documentedIn) {
176
+ content += `- [${doc}](./${doc})\n`;
177
+ }
178
+
179
+ content += `\n**References:** ${refCount}\n`;
180
+
181
+ // Group references by type
182
+ const lineRefs = data.references.filter(r => r.type === 'line');
183
+ const anchorRefs = data.references.filter(r => r.type === 'anchor');
184
+
185
+ if (lineRefs.length > 0) {
186
+ content += `\n*Line References:*\n`;
187
+ for (const ref of lineRefs.slice(0, 5)) {
188
+ content += `- Line ${ref.line} in ${ref.source}\n`;
189
+ }
190
+ if (lineRefs.length > 5) {
191
+ content += `- ... and ${lineRefs.length - 5} more\n`;
192
+ }
193
+ }
194
+
195
+ if (anchorRefs.length > 0) {
196
+ content += `\n*Semantic Anchors:*\n`;
197
+ for (const ref of anchorRefs) {
198
+ content += `- \`${ref.anchor}()\` in ${ref.source}\n`;
199
+ }
200
+ }
201
+
202
+ content += `\n**Update After Changing:**\n`;
203
+ for (const doc of data.documentedIn) {
204
+ content += `- [ ] ${doc}\n`;
205
+ }
206
+
207
+ content += '\n---\n\n';
208
+ }
209
+ }
210
+
211
+ // Summary section
212
+ content += `## Summary
213
+
214
+ | Metric | Value |
215
+ |--------|-------|
216
+ | Files Documented | ${sortedFiles.length} |
217
+ | Total References | ${Object.values(references).reduce((sum, r) => sum + r.references.length, 0)} |
218
+ | Workflow Files | ${new Set(Object.values(references).flatMap(r => r.documentedIn)).size} |
219
+ | Generated | ${now} |
220
+
221
+ ---
222
+
223
+ ## Files NOT Currently Documented
224
+
225
+ *Run \`npx claude-context generate --scan-orphans\` to find undocumented code files.*
226
+
227
+ ---
228
+
229
+ *This file is auto-generated. Do not edit manually.*
230
+ *Regenerate with: \`npx claude-context generate --code-map\`*
231
+ `;
232
+
233
+ return content;
234
+ }
235
+
236
+ /**
237
+ * Generate and write CODE_TO_WORKFLOW_MAP.md
238
+ */
239
+ function generate(options = {}) {
240
+ const { dryRun = false, verbose = false } = options;
241
+
242
+ console.log('Scanning workflow files...');
243
+ const references = scanWorkflows();
244
+
245
+ const fileCount = Object.keys(references).length;
246
+ const refCount = Object.values(references).reduce(
247
+ (sum, r) => sum + r.references.length, 0
248
+ );
249
+
250
+ console.log(`Found ${fileCount} files with ${refCount} references`);
251
+
252
+ if (verbose) {
253
+ for (const [file, data] of Object.entries(references)) {
254
+ console.log(` ${file}: ${data.references.length} refs in ${data.documentedIn.length} docs`);
255
+ }
256
+ }
257
+
258
+ const content = generateMapContent(references);
259
+
260
+ if (dryRun) {
261
+ console.log('\n--- DRY RUN OUTPUT ---\n');
262
+ console.log(content.substring(0, 2000) + '\n...(truncated)');
263
+ return { success: true, fileCount, refCount };
264
+ }
265
+
266
+ const outputPath = path.join(CLAUDE_DIR, 'context', 'CODE_TO_WORKFLOW_MAP.md');
267
+ try {
268
+ fs.writeFileSync(outputPath, content);
269
+ console.log(`Generated: ${outputPath}`);
270
+
271
+ // Update metadata
272
+ const metaPath = path.join(CLAUDE_DIR, 'context', '.meta', 'generated-at.json');
273
+ const metaDir = path.dirname(metaPath);
274
+ if (!fs.existsSync(metaDir)) {
275
+ fs.mkdirSync(metaDir, { recursive: true });
276
+ }
277
+ const metadata = {
278
+ 'CODE_TO_WORKFLOW_MAP.md': {
279
+ generatedAt: new Date().toISOString(),
280
+ filesScanned: fileCount,
281
+ referencesFound: refCount
282
+ }
283
+ };
284
+ fs.writeFileSync(metaPath, JSON.stringify(metadata, null, 2));
285
+
286
+ return { success: true, fileCount, refCount, outputPath };
287
+ } catch (error) {
288
+ console.error('Failed to write output:', error.message);
289
+ return { success: false, error: error.message };
290
+ }
291
+ }
292
+
293
+ // CLI execution
294
+ if (require.main === module) {
295
+ const args = process.argv.slice(2);
296
+ const dryRun = args.includes('--dry-run');
297
+ const verbose = args.includes('--verbose') || args.includes('-v');
298
+
299
+ const result = generate({ dryRun, verbose });
300
+ process.exit(result.success ? 0 : 1);
301
+ }
302
+
303
+ module.exports = {
304
+ generate,
305
+ scanWorkflows,
306
+ extractReferences,
307
+ generateMapContent
308
+ };