mcp-adr-analysis-server 2.0.21 → 2.1.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 (263) hide show
  1. package/README.md +94 -839
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/src/config/ai-config.d.ts.map +1 -1
  4. package/dist/src/config/ai-config.js +9 -9
  5. package/dist/src/config/ai-config.js.map +1 -1
  6. package/dist/src/index.d.ts +15 -0
  7. package/dist/src/index.d.ts.map +1 -1
  8. package/dist/src/index.js +1594 -837
  9. package/dist/src/index.js.map +1 -1
  10. package/dist/src/prompts/analysis-prompts.d.ts +4 -1
  11. package/dist/src/prompts/analysis-prompts.d.ts.map +1 -1
  12. package/dist/src/prompts/analysis-prompts.js +61 -30
  13. package/dist/src/prompts/analysis-prompts.js.map +1 -1
  14. package/dist/src/prompts/index.d.ts +17 -1
  15. package/dist/src/prompts/index.d.ts.map +1 -1
  16. package/dist/src/prompts/index.js +325 -1
  17. package/dist/src/prompts/index.js.map +1 -1
  18. package/dist/src/prompts/rule-generation-prompts.d.ts +5 -1
  19. package/dist/src/prompts/rule-generation-prompts.d.ts.map +1 -1
  20. package/dist/src/prompts/rule-generation-prompts.js +5 -1
  21. package/dist/src/prompts/rule-generation-prompts.js.map +1 -1
  22. package/dist/src/prompts/security-prompts.d.ts +6 -1
  23. package/dist/src/prompts/security-prompts.d.ts.map +1 -1
  24. package/dist/src/prompts/security-prompts.js +6 -1
  25. package/dist/src/prompts/security-prompts.js.map +1 -1
  26. package/dist/src/prompts/todo-prompts.d.ts +49 -0
  27. package/dist/src/prompts/todo-prompts.d.ts.map +1 -0
  28. package/dist/src/prompts/todo-prompts.js +824 -0
  29. package/dist/src/prompts/todo-prompts.js.map +1 -0
  30. package/dist/src/resources/index.d.ts.map +1 -1
  31. package/dist/src/resources/index.js +9 -7
  32. package/dist/src/resources/index.js.map +1 -1
  33. package/dist/src/tools/adr-bootstrap-validation-tool.d.ts +47 -0
  34. package/dist/src/tools/adr-bootstrap-validation-tool.d.ts.map +1 -0
  35. package/dist/src/tools/adr-bootstrap-validation-tool.js +979 -0
  36. package/dist/src/tools/adr-bootstrap-validation-tool.js.map +1 -0
  37. package/dist/src/tools/adr-suggestion-tool.d.ts +1 -0
  38. package/dist/src/tools/adr-suggestion-tool.d.ts.map +1 -1
  39. package/dist/src/tools/adr-suggestion-tool.js +330 -32
  40. package/dist/src/tools/adr-suggestion-tool.js.map +1 -1
  41. package/dist/src/tools/content-masking-tool.d.ts +5 -0
  42. package/dist/src/tools/content-masking-tool.d.ts.map +1 -1
  43. package/dist/src/tools/content-masking-tool.js +631 -28
  44. package/dist/src/tools/content-masking-tool.js.map +1 -1
  45. package/dist/src/tools/deployment-readiness-tool.d.ts +8 -5
  46. package/dist/src/tools/deployment-readiness-tool.d.ts.map +1 -1
  47. package/dist/src/tools/deployment-readiness-tool.js +1017 -93
  48. package/dist/src/tools/deployment-readiness-tool.js.map +1 -1
  49. package/dist/src/tools/environment-analysis-tool.d.ts +4 -0
  50. package/dist/src/tools/environment-analysis-tool.d.ts.map +1 -1
  51. package/dist/src/tools/environment-analysis-tool.js +568 -24
  52. package/dist/src/tools/environment-analysis-tool.js.map +1 -1
  53. package/dist/src/tools/interactive-adr-planning-tool.d.ts.map +1 -1
  54. package/dist/src/tools/interactive-adr-planning-tool.js +270 -108
  55. package/dist/src/tools/interactive-adr-planning-tool.js.map +1 -1
  56. package/dist/src/tools/mcp-planning-tool.d.ts.map +1 -1
  57. package/dist/src/tools/mcp-planning-tool.js +316 -183
  58. package/dist/src/tools/mcp-planning-tool.js.map +1 -1
  59. package/dist/src/tools/memory-loading-tool.d.ts +60 -0
  60. package/dist/src/tools/memory-loading-tool.d.ts.map +1 -0
  61. package/dist/src/tools/memory-loading-tool.js +457 -0
  62. package/dist/src/tools/memory-loading-tool.js.map +1 -0
  63. package/dist/src/tools/research-integration-tool.d.ts +4 -1
  64. package/dist/src/tools/research-integration-tool.d.ts.map +1 -1
  65. package/dist/src/tools/research-integration-tool.js +5 -1
  66. package/dist/src/tools/research-integration-tool.js.map +1 -1
  67. package/dist/src/tools/review-existing-adrs-tool.d.ts +19 -0
  68. package/dist/src/tools/review-existing-adrs-tool.d.ts.map +1 -0
  69. package/dist/src/tools/review-existing-adrs-tool.js +1204 -0
  70. package/dist/src/tools/review-existing-adrs-tool.js.map +1 -0
  71. package/dist/src/tools/rule-generation-tool.d.ts +2 -0
  72. package/dist/src/tools/rule-generation-tool.d.ts.map +1 -1
  73. package/dist/src/tools/rule-generation-tool.js +274 -33
  74. package/dist/src/tools/rule-generation-tool.js.map +1 -1
  75. package/dist/src/tools/smart-git-push-tool-v2.d.ts +4 -0
  76. package/dist/src/tools/smart-git-push-tool-v2.d.ts.map +1 -1
  77. package/dist/src/tools/smart-git-push-tool-v2.js +423 -229
  78. package/dist/src/tools/smart-git-push-tool-v2.js.map +1 -1
  79. package/dist/src/tools/smart-git-push-tool.d.ts +3 -0
  80. package/dist/src/tools/smart-git-push-tool.d.ts.map +1 -1
  81. package/dist/src/tools/smart-git-push-tool.js +241 -235
  82. package/dist/src/tools/smart-git-push-tool.js.map +1 -1
  83. package/dist/src/tools/tool-chain-orchestrator.d.ts +2 -2
  84. package/dist/src/tools/tool-chain-orchestrator.d.ts.map +1 -1
  85. package/dist/src/tools/tool-chain-orchestrator.js +152 -93
  86. package/dist/src/tools/tool-chain-orchestrator.js.map +1 -1
  87. package/dist/src/tools/troubleshoot-guided-workflow-tool.d.ts +22 -13
  88. package/dist/src/tools/troubleshoot-guided-workflow-tool.d.ts.map +1 -1
  89. package/dist/src/tools/troubleshoot-guided-workflow-tool.js +660 -28
  90. package/dist/src/tools/troubleshoot-guided-workflow-tool.js.map +1 -1
  91. package/dist/src/types/ape-framework.d.ts +93 -0
  92. package/dist/src/types/ape-framework.d.ts.map +1 -1
  93. package/dist/src/types/ape-framework.js +10 -10
  94. package/dist/src/types/ape-framework.js.map +1 -1
  95. package/dist/src/types/enhanced-errors.d.ts +173 -0
  96. package/dist/src/types/enhanced-errors.d.ts.map +1 -0
  97. package/dist/src/types/enhanced-errors.js +668 -0
  98. package/dist/src/types/enhanced-errors.js.map +1 -0
  99. package/dist/src/types/index.d.ts +129 -3
  100. package/dist/src/types/index.d.ts.map +1 -1
  101. package/dist/src/types/index.js +15 -0
  102. package/dist/src/types/index.js.map +1 -1
  103. package/dist/src/types/knowledge-generation.d.ts +78 -0
  104. package/dist/src/types/knowledge-generation.d.ts.map +1 -1
  105. package/dist/src/types/knowledge-generation.js +10 -6
  106. package/dist/src/types/knowledge-generation.js.map +1 -1
  107. package/dist/src/types/knowledge-graph-schemas.d.ts +92 -0
  108. package/dist/src/types/knowledge-graph-schemas.d.ts.map +1 -1
  109. package/dist/src/types/knowledge-graph-schemas.js +45 -17
  110. package/dist/src/types/knowledge-graph-schemas.js.map +1 -1
  111. package/dist/src/types/memory-entities.d.ts +7209 -0
  112. package/dist/src/types/memory-entities.d.ts.map +1 -0
  113. package/dist/src/types/memory-entities.js +395 -0
  114. package/dist/src/types/memory-entities.js.map +1 -0
  115. package/dist/src/types/reflexion-framework.d.ts +44 -0
  116. package/dist/src/types/reflexion-framework.d.ts.map +1 -1
  117. package/dist/src/types/reflexion-framework.js +7 -7
  118. package/dist/src/types/reflexion-framework.js.map +1 -1
  119. package/dist/src/types/todo-json-schemas.d.ts +7 -653
  120. package/dist/src/types/todo-json-schemas.d.ts.map +1 -1
  121. package/dist/src/types/todo-json-schemas.js +6 -110
  122. package/dist/src/types/todo-json-schemas.js.map +1 -1
  123. package/dist/src/types/tool-arguments.d.ts +224 -0
  124. package/dist/src/types/tool-arguments.d.ts.map +1 -0
  125. package/dist/src/types/tool-arguments.js +6 -0
  126. package/dist/src/types/tool-arguments.js.map +1 -0
  127. package/dist/src/utils/actual-file-operations.d.ts.map +1 -1
  128. package/dist/src/utils/actual-file-operations.js +25 -9
  129. package/dist/src/utils/actual-file-operations.js.map +1 -1
  130. package/dist/src/utils/adr-discovery.d.ts +33 -1
  131. package/dist/src/utils/adr-discovery.d.ts.map +1 -1
  132. package/dist/src/utils/adr-discovery.js +14 -9
  133. package/dist/src/utils/adr-discovery.js.map +1 -1
  134. package/dist/src/utils/adr-suggestions.d.ts +72 -0
  135. package/dist/src/utils/adr-suggestions.d.ts.map +1 -1
  136. package/dist/src/utils/adr-suggestions.js +6 -0
  137. package/dist/src/utils/adr-suggestions.js.map +1 -1
  138. package/dist/src/utils/cache.d.ts.map +1 -1
  139. package/dist/src/utils/cache.js +22 -19
  140. package/dist/src/utils/cache.js.map +1 -1
  141. package/dist/src/utils/chain-of-thought-template.d.ts +13 -1
  142. package/dist/src/utils/chain-of-thought-template.d.ts.map +1 -1
  143. package/dist/src/utils/chain-of-thought-template.js +31 -22
  144. package/dist/src/utils/chain-of-thought-template.js.map +1 -1
  145. package/dist/src/utils/config.d.ts.map +1 -1
  146. package/dist/src/utils/config.js +1 -0
  147. package/dist/src/utils/config.js.map +1 -1
  148. package/dist/src/utils/directory-compat.js +1 -1
  149. package/dist/src/utils/directory-compat.js.map +1 -1
  150. package/dist/src/utils/enhanced-logging.d.ts +195 -0
  151. package/dist/src/utils/enhanced-logging.d.ts.map +1 -0
  152. package/dist/src/utils/enhanced-logging.js +449 -0
  153. package/dist/src/utils/enhanced-logging.js.map +1 -0
  154. package/dist/src/utils/file-system.d.ts +182 -34
  155. package/dist/src/utils/file-system.d.ts.map +1 -1
  156. package/dist/src/utils/file-system.js +648 -774
  157. package/dist/src/utils/file-system.js.map +1 -1
  158. package/dist/src/utils/gitleaks-detector.d.ts +50 -0
  159. package/dist/src/utils/gitleaks-detector.d.ts.map +1 -0
  160. package/dist/src/utils/gitleaks-detector.js +334 -0
  161. package/dist/src/utils/gitleaks-detector.js.map +1 -0
  162. package/dist/src/utils/interactive-approval.d.ts +1 -1
  163. package/dist/src/utils/interactive-approval.d.ts.map +1 -1
  164. package/dist/src/utils/interactive-approval.js +22 -17
  165. package/dist/src/utils/interactive-approval.js.map +1 -1
  166. package/dist/src/utils/json-safe.d.ts.map +1 -1
  167. package/dist/src/utils/json-safe.js +9 -6
  168. package/dist/src/utils/json-safe.js.map +1 -1
  169. package/dist/src/utils/knowledge-graph-manager.d.ts +37 -1
  170. package/dist/src/utils/knowledge-graph-manager.d.ts.map +1 -1
  171. package/dist/src/utils/knowledge-graph-manager.js +315 -70
  172. package/dist/src/utils/knowledge-graph-manager.js.map +1 -1
  173. package/dist/src/utils/location-filter.d.ts +35 -10
  174. package/dist/src/utils/location-filter.d.ts.map +1 -1
  175. package/dist/src/utils/location-filter.js +360 -94
  176. package/dist/src/utils/location-filter.js.map +1 -1
  177. package/dist/src/utils/mcp-response-validator.d.ts.map +1 -1
  178. package/dist/src/utils/mcp-response-validator.js +34 -19
  179. package/dist/src/utils/mcp-response-validator.js.map +1 -1
  180. package/dist/src/utils/memory-entity-manager.d.ts +134 -0
  181. package/dist/src/utils/memory-entity-manager.d.ts.map +1 -0
  182. package/dist/src/utils/memory-entity-manager.js +851 -0
  183. package/dist/src/utils/memory-entity-manager.js.map +1 -0
  184. package/dist/src/utils/memory-health-scoring.d.ts +125 -0
  185. package/dist/src/utils/memory-health-scoring.d.ts.map +1 -0
  186. package/dist/src/utils/memory-health-scoring.js +277 -0
  187. package/dist/src/utils/memory-health-scoring.js.map +1 -0
  188. package/dist/src/utils/memory-migration-manager.d.ts +93 -0
  189. package/dist/src/utils/memory-migration-manager.d.ts.map +1 -0
  190. package/dist/src/utils/memory-migration-manager.js +842 -0
  191. package/dist/src/utils/memory-migration-manager.js.map +1 -0
  192. package/dist/src/utils/memory-relationship-mapper.d.ts +87 -0
  193. package/dist/src/utils/memory-relationship-mapper.d.ts.map +1 -0
  194. package/dist/src/utils/memory-relationship-mapper.js +482 -0
  195. package/dist/src/utils/memory-relationship-mapper.js.map +1 -0
  196. package/dist/src/utils/memory-rollback-manager.d.ts +105 -0
  197. package/dist/src/utils/memory-rollback-manager.d.ts.map +1 -0
  198. package/dist/src/utils/memory-rollback-manager.js +575 -0
  199. package/dist/src/utils/memory-rollback-manager.js.map +1 -0
  200. package/dist/src/utils/memory-transformation.d.ts +59 -0
  201. package/dist/src/utils/memory-transformation.d.ts.map +1 -0
  202. package/dist/src/utils/memory-transformation.js +742 -0
  203. package/dist/src/utils/memory-transformation.js.map +1 -0
  204. package/dist/src/utils/output-masking.d.ts +12 -0
  205. package/dist/src/utils/output-masking.d.ts.map +1 -1
  206. package/dist/src/utils/output-masking.js +5 -0
  207. package/dist/src/utils/output-masking.js.map +1 -1
  208. package/dist/src/utils/prompt-execution.d.ts.map +1 -1
  209. package/dist/src/utils/prompt-execution.js +72 -51
  210. package/dist/src/utils/prompt-execution.js.map +1 -1
  211. package/dist/src/utils/release-readiness-detector.d.ts.map +1 -1
  212. package/dist/src/utils/release-readiness-detector.js +43 -42
  213. package/dist/src/utils/release-readiness-detector.js.map +1 -1
  214. package/dist/src/utils/research-integration.d.ts.map +1 -1
  215. package/dist/src/utils/research-integration.js +73 -44
  216. package/dist/src/utils/research-integration.js.map +1 -1
  217. package/dist/src/utils/research-questions.d.ts.map +1 -1
  218. package/dist/src/utils/research-questions.js +40 -14
  219. package/dist/src/utils/research-questions.js.map +1 -1
  220. package/dist/src/utils/ripgrep-wrapper.d.ts +84 -0
  221. package/dist/src/utils/ripgrep-wrapper.d.ts.map +1 -0
  222. package/dist/src/utils/ripgrep-wrapper.js +255 -0
  223. package/dist/src/utils/ripgrep-wrapper.js.map +1 -0
  224. package/dist/src/utils/rule-generation.d.ts.map +1 -1
  225. package/dist/src/utils/rule-generation.js +26 -15
  226. package/dist/src/utils/rule-generation.js.map +1 -1
  227. package/dist/src/utils/todo-file-watcher.d.ts +11 -23
  228. package/dist/src/utils/todo-file-watcher.d.ts.map +1 -1
  229. package/dist/src/utils/todo-file-watcher.js +18 -156
  230. package/dist/src/utils/todo-file-watcher.js.map +1 -1
  231. package/dist/src/utils/tree-sitter-analyzer.d.ts +185 -0
  232. package/dist/src/utils/tree-sitter-analyzer.d.ts.map +1 -0
  233. package/dist/src/utils/tree-sitter-analyzer.js +885 -0
  234. package/dist/src/utils/tree-sitter-analyzer.js.map +1 -0
  235. package/package.json +51 -10
  236. package/dist/src/tools/smart-score-tool.d.ts +0 -173
  237. package/dist/src/tools/smart-score-tool.d.ts.map +0 -1
  238. package/dist/src/tools/smart-score-tool.js +0 -681
  239. package/dist/src/tools/smart-score-tool.js.map +0 -1
  240. package/dist/src/tools/todo-management-tool-v2.d.ts +0 -368
  241. package/dist/src/tools/todo-management-tool-v2.d.ts.map +0 -1
  242. package/dist/src/tools/todo-management-tool-v2.js +0 -922
  243. package/dist/src/tools/todo-management-tool-v2.js.map +0 -1
  244. package/dist/src/utils/enhanced-sensitive-detector.d.ts +0 -61
  245. package/dist/src/utils/enhanced-sensitive-detector.d.ts.map +0 -1
  246. package/dist/src/utils/enhanced-sensitive-detector.js +0 -437
  247. package/dist/src/utils/enhanced-sensitive-detector.js.map +0 -1
  248. package/dist/src/utils/project-health-scoring.d.ts +0 -177
  249. package/dist/src/utils/project-health-scoring.d.ts.map +0 -1
  250. package/dist/src/utils/project-health-scoring.js +0 -370
  251. package/dist/src/utils/project-health-scoring.js.map +0 -1
  252. package/dist/src/utils/todo-json-manager.d.ts +0 -71
  253. package/dist/src/utils/todo-json-manager.d.ts.map +0 -1
  254. package/dist/src/utils/todo-json-manager.js +0 -396
  255. package/dist/src/utils/todo-json-manager.js.map +0 -1
  256. package/dist/src/utils/todo-markdown-converter.d.ts +0 -16
  257. package/dist/src/utils/todo-markdown-converter.d.ts.map +0 -1
  258. package/dist/src/utils/todo-markdown-converter.js +0 -362
  259. package/dist/src/utils/todo-markdown-converter.js.map +0 -1
  260. package/dist/src/utils/todo-migration.d.ts +0 -47
  261. package/dist/src/utils/todo-migration.d.ts.map +0 -1
  262. package/dist/src/utils/todo-migration.js +0 -261
  263. package/dist/src/utils/todo-migration.js.map +0 -1
@@ -1,838 +1,712 @@
1
1
  /**
2
2
  * File system utilities for MCP ADR Analysis Server
3
- * Generates prompts for AI-driven file discovery, reading, and analysis operations
4
- * Enhanced with Chain-of-Thought prompting to reduce LLM confusion
3
+ * Uses fast-glob for efficient file discovery with .gitignore support
4
+ * Enhanced with Smart Code Linking capabilities
5
5
  */
6
- import { dirname } from 'path';
6
+ import fg from 'fast-glob';
7
+ import * as fs from 'fs/promises';
8
+ import * as path from 'path';
7
9
  import { FileSystemError } from '../types/index.js';
8
- import { enhancePromptWithCoT, COT_PATTERNS } from './chain-of-thought-template.js';
9
10
  /**
10
- * Generate prompt for AI-driven project structure analysis
11
+ * Find files using fast-glob with .gitignore support
12
+ *
13
+ * @param projectPath - Path to the project to search
14
+ * @param patterns - Glob patterns to match files
15
+ * @param options - Options for file discovery
16
+ * @returns Promise resolving to file discovery results
11
17
  */
12
- export async function analyzeProjectStructure(projectPath) {
18
+ export async function findFiles(projectPath, patterns, options = {}) {
13
19
  try {
14
- console.error(`[DEBUG] Starting prompt generation for project path: ${projectPath}`);
15
- // Pure prompt-driven approach - delegate all path resolution and validation to AI
16
20
  const safeProjectPath = projectPath || '.';
17
- console.error(`[DEBUG] Using prompt-driven analysis for path: ${safeProjectPath}`);
18
- // Note: Path validation is delegated to the AI agent that will perform the actual scanning
19
- // Define file patterns for analysis
20
- const filePatterns = [
21
- '**/*',
22
- '!node_modules/**',
23
- '!.git/**',
24
- '!dist/**',
25
- '!build/**',
26
- '!coverage/**',
27
- '!.mcp-adr-cache/**',
28
- '!*.log',
29
- ];
30
- console.error(`[DEBUG] Generated prompt for file patterns:`, filePatterns);
31
- console.error(`[DEBUG] Target directory: ${safeProjectPath}`);
32
- // Generate Chain-of-Thought enhanced analysis prompt
33
- const basePrompt = `
34
- # Project Structure Analysis Request
35
-
36
- Analyze the project structure at: **${safeProjectPath}**
37
-
38
- ## Analysis Requirements
39
-
40
- **File Discovery**: Scan the directory using the following patterns:
41
- ${filePatterns.map(pattern => ` - ${pattern}`).join('\n')}
42
-
43
- **Technology Stack Detection**: Identify:
44
- - Programming languages (based on file extensions)
45
- - Frameworks and libraries (from package.json, requirements.txt, etc.)
46
- - Build tools and configuration files
47
- - Testing frameworks and tools
48
-
49
- **Architectural Patterns**: Analyze:
50
- - Directory structure and organization
51
- - Code organization patterns (MVC, microservices, etc.)
52
- - Configuration management approaches
53
- - Documentation patterns
54
-
55
- **Project Ecosystem**: Examine:
56
- - Dependencies and package management
57
- - Development tools and workflows
58
- - CI/CD configurations
59
- - Documentation and README files
60
-
61
- ## Expected Output Format
62
-
63
- \`\`\`json
64
- {
65
- "rootPath": "<resolved-absolute-path>",
66
- "totalFiles": <number>,
67
- "totalDirectories": <number>,
68
- "technologies": [
69
- {
70
- "name": "technology_name",
71
- "type": "language|framework|tool",
72
- "confidence": 0.95,
73
- "evidence": ["file1.ext", "config.json"]
74
- }
75
- ],
76
- "patterns": [
77
- {
78
- "name": "pattern_name",
79
- "type": "architectural|organizational",
80
- "description": "pattern description",
81
- "evidence": ["directory_structure", "file_patterns"]
21
+ // Ensure patterns are properly formatted
22
+ const normalizedPatterns = patterns.map(pattern => {
23
+ // If pattern doesn't start with !, make it relative to the project path
24
+ if (!pattern.startsWith('!') && !path.isAbsolute(pattern)) {
25
+ return pattern;
26
+ }
27
+ return pattern;
28
+ });
29
+ // Use fast-glob to find files
30
+ const entries = await fg(normalizedPatterns, {
31
+ cwd: safeProjectPath,
32
+ dot: true,
33
+ absolute: false,
34
+ stats: true,
35
+ followSymbolicLinks: false,
36
+ onlyFiles: true,
37
+ // Exclude common non-source directories by default
38
+ // fast-glob automatically respects .gitignore when these patterns are used
39
+ ignore: [
40
+ '**/node_modules/**',
41
+ '**/.git/**',
42
+ '**/dist/**',
43
+ '**/build/**',
44
+ '**/coverage/**',
45
+ '**/.mcp-adr-cache/**',
46
+ '**/*.log',
47
+ '**/.DS_Store',
48
+ '**/Thumbs.db',
49
+ ],
50
+ });
51
+ // Apply limit if specified
52
+ const limitedEntries = options.limit ? entries.slice(0, options.limit) : entries;
53
+ // Convert glob results to FileInfo format
54
+ const files = await Promise.all(limitedEntries.map(async (entry) => {
55
+ const filePath = typeof entry === 'string' ? entry : entry.path;
56
+ const fullPath = path.join(safeProjectPath, filePath);
57
+ let stats;
58
+ if (typeof entry === 'object' && entry.stats) {
59
+ stats = entry.stats;
60
+ }
61
+ else {
62
+ stats = await fs.stat(fullPath);
63
+ }
64
+ const fileInfo = {
65
+ path: filePath,
66
+ name: path.basename(filePath),
67
+ extension: path.extname(filePath),
68
+ size: stats.size,
69
+ directory: path.dirname(filePath),
70
+ };
71
+ // Include content if requested
72
+ if (options.includeContent) {
73
+ try {
74
+ fileInfo.content = await fs.readFile(fullPath, 'utf-8');
75
+ }
76
+ catch (error) {
77
+ console.warn(`Could not read content of ${fullPath}:`, error);
78
+ }
79
+ }
80
+ return fileInfo;
81
+ }));
82
+ return {
83
+ files,
84
+ totalFiles: files.length,
85
+ searchPatterns: patterns,
86
+ searchPath: safeProjectPath,
87
+ };
82
88
  }
83
- ],
84
- "files": [
85
- {
86
- "path": "relative/path/to/file",
87
- "name": "filename.ext",
88
- "extension": ".ext",
89
- "directory": "relative/path/to",
90
- "category": "source|config|documentation|test"
89
+ catch (error) {
90
+ throw new FileSystemError(`Failed to find files: ${error instanceof Error ? error.message : String(error)}`, { projectPath, patterns });
91
91
  }
92
- ],
93
- "directories": ["dir1", "dir2/subdir"],
94
- "summary": "Brief project description and key findings"
95
92
  }
96
- \`\`\`
97
- `;
98
- // Enhance the base prompt with Chain-of-Thought reasoning
99
- const prompt = enhancePromptWithCoT(basePrompt, COT_PATTERNS.PROJECT_ANALYSIS);
100
- const instructions = `
101
- ## Implementation Steps
102
-
103
- 1. **Directory Scanning**: Use appropriate file system tools to scan the resolved project path
104
- 2. **Pattern Filtering**: Apply exclusion patterns: ${filePatterns.filter(p => p.startsWith('!')).join(', ')}
105
- 3. **File Analysis**: Examine file extensions, names, and content (for config files)
106
- 4. **Technology Detection**: Look for package.json, requirements.txt, Cargo.toml, etc.
107
- 5. **Pattern Recognition**: Analyze directory structure and file organization
108
- 6. **Result Compilation**: Format findings according to the specified JSON structure
109
-
110
- ## Safety Checks
111
-
112
- - ✅ Path resolution delegated to AI agent with security validation
113
- - ✅ System directory protection enabled
114
- - ✅ File patterns defined for efficient scanning
115
- - ✅ Exclusion patterns prevent scanning large/unnecessary directories
116
-
117
- ## Context Information
118
-
119
- - **Project Path**: ${safeProjectPath}
120
- - **Analysis Type**: Comprehensive project ecosystem analysis
121
- - **Output Format**: Structured JSON with technology stack and architectural patterns
122
- `;
93
+ /**
94
+ * Analyze project structure to detect technologies and patterns
95
+ * Uses direct file analysis instead of AI prompts
96
+ *
97
+ * @param projectPath - Path to the project to analyze
98
+ * @returns Promise resolving to project analysis results
99
+ */
100
+ export async function analyzeProjectStructure(projectPath) {
101
+ try {
102
+ const safeProjectPath = path.resolve(projectPath || '.');
103
+ // Define patterns for different file types
104
+ const filePatterns = [
105
+ '**/*.{js,jsx,ts,tsx,py,java,cs,go,rs,rb,php,swift,kt,scala,c,cpp,h,hpp}',
106
+ '**/package.json',
107
+ '**/requirements.txt',
108
+ '**/Gemfile',
109
+ '**/Cargo.toml',
110
+ '**/go.mod',
111
+ '**/pom.xml',
112
+ '**/*.{yml,yaml}',
113
+ '**/Dockerfile',
114
+ '**/*.tf',
115
+ '**/.env*',
116
+ '**/README*',
117
+ ];
118
+ // Find all relevant files
119
+ const { files } = await findFiles(safeProjectPath, filePatterns, {
120
+ includeContent: false,
121
+ limit: 1000, // Limit for performance
122
+ });
123
+ // Analyze technologies based on files found
124
+ const technologies = await detectTechnologies(safeProjectPath, files);
125
+ // Detect architectural patterns
126
+ const patterns = detectArchitecturalPatterns(files);
127
+ // Count directories
128
+ const directories = [...new Set(files.map(f => f.directory))];
129
+ // Generate summary
130
+ const summary = generateProjectSummary(files, technologies, patterns);
123
131
  return {
124
- prompt,
125
- instructions,
126
- context: {
127
- projectPath: safeProjectPath,
128
- absoluteProjectPath: 'resolved-by-ai-agent',
129
- filePatterns
130
- }
132
+ rootPath: safeProjectPath,
133
+ files,
134
+ technologies,
135
+ patterns,
136
+ summary,
137
+ totalFiles: files.length,
138
+ totalDirectories: directories.length,
131
139
  };
132
140
  }
133
141
  catch (error) {
134
- // If it's already a FileSystemError, re-throw it to preserve the specific error message
135
- if (error instanceof FileSystemError) {
136
- throw error;
137
- }
138
- throw new FileSystemError(`Failed to generate project analysis prompt: ${error instanceof Error ? error.message : String(error)}`, { projectPath, absoluteProjectPath: 'resolved-by-ai-agent' });
142
+ throw new FileSystemError(`Failed to analyze project structure: ${error instanceof Error ? error.message : String(error)}`, { projectPath });
139
143
  }
140
144
  }
141
145
  /**
142
- * Generate prompt for AI-driven file content reading
146
+ * Read file content safely
147
+ *
148
+ * @param filePath - Path to the file to read
149
+ * @returns Promise resolving to file content and metadata
143
150
  */
144
151
  export async function readFileContent(filePath) {
145
152
  try {
146
- console.error(`[DEBUG] Generating file read prompt for: ${filePath}`);
147
- // Pure prompt-driven approach - delegate file reading to AI agent
148
- const safeFilePath = filePath || '';
149
- const prompt = `
150
- # File Content Reading Request
151
-
152
- Please read the content of the file: **${safeFilePath}**
153
-
154
- ## Path Security Validation
155
-
156
- The AI agent must:
157
- 1. **Validate file path security**: Ensure the path is not a system directory (/, /usr, /bin, /etc, /var, /tmp, etc.)
158
- 2. **Resolve relative paths safely**: Handle relative paths from the current working directory
159
- 3. **Prevent unauthorized access**: Reject attempts to read sensitive system files or directories outside the project scope
160
- 4. **Validate file existence**: Check if the file exists before attempting to read
161
-
162
- ## File Reading Requirements
163
-
164
- 1. **Safe File Access**: Read the file content using appropriate file system tools
165
- 2. **Encoding Handling**: Read the file as UTF-8 text content
166
- 3. **Error Handling**: Provide clear error messages for:
167
- - File not found
168
- - Permission denied
169
- - Invalid file path
170
- - Binary files or unsupported formats
171
-
172
- ## Expected Output Format
173
-
174
- \`\`\`json
175
- {
176
- "success": true,
177
- "filePath": "${safeFilePath}",
178
- "content": "file content as string",
179
- "metadata": {
180
- "size": <file_size_in_bytes>,
181
- "encoding": "utf-8",
182
- "lastModified": "ISO_timestamp"
183
- },
184
- "security": {
185
- "pathValidated": true,
186
- "accessAuthorized": true,
187
- "systemDirectoryCheck": "passed"
188
- }
189
- }
190
- \`\`\`
191
-
192
- ## Error Response Format (if file cannot be read)
193
-
194
- \`\`\`json
195
- {
196
- "success": false,
197
- "filePath": "${safeFilePath}",
198
- "error": "detailed error message",
199
- "errorType": "FILE_NOT_FOUND|PERMISSION_DENIED|INVALID_PATH|SECURITY_VIOLATION",
200
- "security": {
201
- "pathValidated": boolean,
202
- "accessAuthorized": boolean,
203
- "systemDirectoryCheck": "passed|failed",
204
- "rejectionReason": "specific reason if access denied"
205
- }
206
- }
207
- \`\`\`
208
- `;
209
- const instructions = `
210
- ## Implementation Steps
211
-
212
- 1. **Security Validation**:
213
- - Validate the file path: ${safeFilePath}
214
- - Ensure it's not a system directory or sensitive location
215
- - Check for path traversal attempts (../, .\\, etc.)
216
-
217
- 2. **File Access**:
218
- - Check if the file exists and is readable
219
- - Verify file permissions allow reading
220
- - Handle symbolic links safely
221
-
222
- 3. **Content Reading**:
223
- - Read file content as UTF-8 text
224
- - Handle large files appropriately
225
- - Detect and handle binary files
226
-
227
- 4. **Response Generation**:
228
- - Format response according to the specified JSON structure
229
- - Include comprehensive metadata and security validation results
230
- - Provide detailed error information if reading fails
231
-
232
- ## Safety Checks
233
-
234
- - ✅ Path security validation delegated to AI agent
235
- - ✅ System directory protection enabled
236
- - ✅ File access permission validation required
237
- - ✅ Comprehensive error handling specified
238
-
239
- ## Context Information
240
-
241
- - **File Path**: ${safeFilePath}
242
- - **Operation**: Safe file content reading
243
- - **Security Level**: High (with path validation and access control)
244
- `;
153
+ const resolvedPath = path.resolve(filePath);
154
+ // Check if file exists
155
+ try {
156
+ await fs.access(resolvedPath);
157
+ }
158
+ catch {
159
+ return {
160
+ success: false,
161
+ filePath,
162
+ error: 'File not found',
163
+ };
164
+ }
165
+ // Read file content
166
+ const content = await fs.readFile(resolvedPath, 'utf-8');
167
+ const stats = await fs.stat(resolvedPath);
245
168
  return {
246
- prompt,
247
- instructions,
248
- context: {
249
- filePath: safeFilePath,
250
- operation: 'file_read',
251
- securityLevel: 'high',
252
- expectedFormat: 'json'
253
- }
169
+ success: true,
170
+ filePath,
171
+ content,
172
+ metadata: {
173
+ size: stats.size,
174
+ encoding: 'utf-8',
175
+ lastModified: stats.mtime.toISOString(),
176
+ },
254
177
  };
255
178
  }
256
179
  catch (error) {
257
- throw new FileSystemError(`Failed to generate file read prompt: ${error instanceof Error ? error.message : String(error)}`, { filePath });
180
+ return {
181
+ success: false,
182
+ filePath,
183
+ error: error instanceof Error ? error.message : String(error),
184
+ };
258
185
  }
259
186
  }
260
187
  /**
261
- * Generate prompt for AI-driven file discovery
188
+ * Check if a file exists
189
+ *
190
+ * @param filePath - Path to check
191
+ * @returns Promise resolving to existence check result
262
192
  */
263
- export async function findFiles(projectPath, patterns, options = {}) {
193
+ export async function fileExists(filePath) {
264
194
  try {
265
- // Pure prompt-driven approach - delegate all path resolution and validation to AI
266
- const safeProjectPath = projectPath || '.';
267
- const prompt = `
268
- # File Discovery Request
269
-
270
- Please find files matching the specified patterns in: **${safeProjectPath}**
271
-
272
- ## Path Resolution Instructions
273
- 1. **Safely resolve the project path**: If path is "." or "./", use the current working directory
274
- 2. **Validate path security**: Ensure the path is not a system directory (/, /usr, /bin, etc.)
275
- 3. **Handle relative paths**: Resolve relative paths from the current working directory
276
-
277
- ## Search Patterns
278
- ${patterns.map(pattern => `- ${pattern}`).join('\n')}
279
-
280
- ## Requirements
281
- - Search in the resolved directory (safely resolve ${safeProjectPath})
282
- - Apply patterns to filter files
283
- - ${options.includeContent ? 'Include file content in results' : 'Return file metadata only'}
284
-
285
- ## Expected Output Format
286
-
287
- \`\`\`json
288
- {
289
- "files": [
290
- {
291
- "path": "relative/path/to/file",
292
- "name": "filename.ext",
293
- "extension": ".ext",
294
- "size": 1234,
295
- "directory": "relative/path/to"${options.includeContent ? ',\n "content": "file content here"' : ''}
195
+ const resolvedPath = path.resolve(filePath);
196
+ try {
197
+ const stats = await fs.stat(resolvedPath);
198
+ let type = 'file';
199
+ if (stats.isDirectory())
200
+ type = 'directory';
201
+ else if (stats.isSymbolicLink())
202
+ type = 'symlink';
203
+ return {
204
+ success: true,
205
+ filePath,
206
+ exists: true,
207
+ metadata: {
208
+ type,
209
+ accessible: true,
210
+ lastChecked: new Date().toISOString(),
211
+ },
212
+ };
213
+ }
214
+ catch {
215
+ return {
216
+ success: true,
217
+ filePath,
218
+ exists: false,
219
+ metadata: {
220
+ type: null,
221
+ accessible: false,
222
+ lastChecked: new Date().toISOString(),
223
+ },
224
+ };
225
+ }
226
+ }
227
+ catch (error) {
228
+ throw new FileSystemError(`Failed to check file existence: ${error instanceof Error ? error.message : String(error)}`, { filePath });
296
229
  }
297
- ],
298
- "totalFiles": <number>,
299
- "searchPatterns": ${JSON.stringify(patterns)},
300
- "searchPath": "<resolved-absolute-path>"
301
230
  }
302
- \`\`\`
303
- `;
304
- const instructions = `
305
- ## Implementation Steps
306
- 1. Scan the resolved directory (safely resolve ${safeProjectPath})
307
- 2. Apply patterns: ${patterns.join(', ')}
308
- 3. Collect file metadata (name, size, extension, path)
309
- ${options.includeContent ? '4. Read and include file content' : '4. Skip file content reading'}
310
- 5. Format results as JSON
311
-
312
- ## Context
313
- - Base directory: ${safeProjectPath}
314
- - Include content: ${options.includeContent || false}
315
- - Pattern count: ${patterns.length}
316
- `;
317
- return {
318
- prompt,
319
- instructions,
320
- context: {
321
- projectPath: safeProjectPath,
322
- absoluteProjectPath: 'resolved-by-ai-agent',
323
- patterns,
324
- includeContent: options.includeContent || false
325
- }
326
- };
231
+ /**
232
+ * Ensure a directory exists, creating it if necessary
233
+ *
234
+ * @param dirPath - Path to the directory
235
+ * @returns Promise resolving when directory is ensured
236
+ */
237
+ export async function ensureDirectory(dirPath) {
238
+ try {
239
+ const resolvedPath = path.resolve(dirPath);
240
+ try {
241
+ await fs.access(resolvedPath);
242
+ return {
243
+ success: true,
244
+ dirPath,
245
+ created: false,
246
+ };
247
+ }
248
+ catch {
249
+ // Directory doesn't exist, create it
250
+ await fs.mkdir(resolvedPath, { recursive: true });
251
+ return {
252
+ success: true,
253
+ dirPath,
254
+ created: true,
255
+ };
256
+ }
327
257
  }
328
258
  catch (error) {
329
- throw new FileSystemError(`Failed to generate file discovery prompt: ${error instanceof Error ? error.message : String(error)}`, { projectPath, patterns });
259
+ return {
260
+ success: false,
261
+ dirPath,
262
+ created: false,
263
+ error: error instanceof Error ? error.message : String(error),
264
+ };
330
265
  }
331
266
  }
332
267
  /**
333
- * Generate prompt for AI-driven file existence check
268
+ * Write content to a file, creating directories as needed
269
+ *
270
+ * @param filePath - Path to the file
271
+ * @param content - Content to write
272
+ * @returns Promise resolving when file is written
334
273
  */
335
- export async function fileExists(filePath) {
274
+ export async function writeFile(filePath, content) {
336
275
  try {
337
- console.error(`[DEBUG] Generating file existence check prompt for: ${filePath}`);
338
- // Pure prompt-driven approach - delegate file existence check to AI agent
339
- const safeFilePath = filePath || '';
340
- const prompt = `
341
- # File Existence Check Request
342
-
343
- Please check if the file exists: **${safeFilePath}**
344
-
345
- ## Path Security Validation
346
-
347
- The AI agent must:
348
- 1. **Validate file path security**: Ensure the path is not a system directory (/, /usr, /bin, /etc, /var, /tmp, etc.)
349
- 2. **Resolve relative paths safely**: Handle relative paths from the current working directory
350
- 3. **Prevent unauthorized access**: Reject attempts to check sensitive system files or directories outside the project scope
351
- 4. **Validate path format**: Check for valid file path format and reject malicious patterns
352
-
353
- ## File Existence Check Requirements
354
-
355
- 1. **Safe Path Resolution**: Resolve the file path using appropriate file system tools
356
- 2. **Access Validation**: Check if the file exists and is accessible
357
- 3. **Security Compliance**: Ensure the check doesn't expose sensitive information
358
- 4. **Error Handling**: Handle various scenarios:
359
- - File exists and is accessible
360
- - File does not exist
361
- - Path is invalid or malformed
362
- - Permission denied
363
- - Path points to a directory instead of a file
364
-
365
- ## Expected Output Format
366
-
367
- \`\`\`json
368
- {
369
- "success": true,
370
- "filePath": "${safeFilePath}",
371
- "exists": true,
372
- "metadata": {
373
- "type": "file|directory|symlink",
374
- "accessible": true,
375
- "lastChecked": "ISO_timestamp"
376
- },
377
- "security": {
378
- "pathValidated": true,
379
- "accessAuthorized": true,
380
- "systemDirectoryCheck": "passed"
381
- }
382
- }
383
- \`\`\`
384
-
385
- ## Response Format for Non-Existent File
386
-
387
- \`\`\`json
388
- {
389
- "success": true,
390
- "filePath": "${safeFilePath}",
391
- "exists": false,
392
- "metadata": {
393
- "type": null,
394
- "accessible": false,
395
- "lastChecked": "ISO_timestamp"
396
- },
397
- "security": {
398
- "pathValidated": true,
399
- "accessAuthorized": true,
400
- "systemDirectoryCheck": "passed"
401
- }
402
- }
403
- \`\`\`
404
-
405
- ## Error Response Format (for security violations or invalid paths)
406
-
407
- \`\`\`json
408
- {
409
- "success": false,
410
- "filePath": "${safeFilePath}",
411
- "exists": false,
412
- "error": "detailed error message",
413
- "errorType": "INVALID_PATH|SECURITY_VIOLATION|PERMISSION_DENIED|MALFORMED_PATH",
414
- "security": {
415
- "pathValidated": boolean,
416
- "accessAuthorized": boolean,
417
- "systemDirectoryCheck": "passed|failed",
418
- "rejectionReason": "specific reason if access denied"
419
- }
420
- }
421
- \`\`\`
422
- `;
423
- const instructions = `
424
- ## Implementation Steps
425
-
426
- 1. **Security Validation**:
427
- - Validate the file path: ${safeFilePath}
428
- - Ensure it's not a system directory or sensitive location
429
- - Check for path traversal attempts (../, .\\, etc.)
430
- - Validate path format and reject malicious patterns
431
-
432
- 2. **Path Resolution**:
433
- - Resolve relative paths from the current working directory
434
- - Handle symbolic links appropriately
435
- - Normalize path separators for the operating system
436
-
437
- 3. **Existence Check**:
438
- - Check if the file exists at the resolved path
439
- - Determine if it's a file, directory, or symbolic link
440
- - Verify accessibility without reading content
441
-
442
- 4. **Response Generation**:
443
- - Format response according to the specified JSON structure
444
- - Include comprehensive metadata and security validation results
445
- - Provide clear boolean result in the "exists" field
446
- - Include detailed error information if check fails
447
-
448
- ## Safety Checks
449
-
450
- - ✅ Path security validation delegated to AI agent
451
- - ✅ System directory protection enabled
452
- - ✅ File access permission validation required
453
- - ✅ Comprehensive error handling specified
454
- - ✅ Boolean result format clearly defined
455
-
456
- ## Context Information
457
-
458
- - **File Path**: ${safeFilePath}
459
- - **Operation**: Safe file existence check
460
- - **Security Level**: High (with path validation and access control)
461
- - **Expected Result**: Boolean existence status with metadata
462
- `;
276
+ const resolvedPath = path.resolve(filePath);
277
+ const dir = path.dirname(resolvedPath);
278
+ // Ensure directory exists
279
+ const dirResult = await ensureDirectory(dir);
280
+ // Write file
281
+ await fs.writeFile(resolvedPath, content, 'utf-8');
463
282
  return {
464
- prompt,
465
- instructions,
466
- context: {
467
- filePath: safeFilePath,
468
- operation: 'file_exists_check',
469
- securityLevel: 'high',
470
- expectedFormat: 'json',
471
- resultType: 'boolean'
472
- }
283
+ success: true,
284
+ filePath,
285
+ written: true,
286
+ metadata: {
287
+ size: Buffer.byteLength(content, 'utf-8'),
288
+ directoryCreated: dirResult.created,
289
+ },
473
290
  };
474
291
  }
475
292
  catch (error) {
476
- throw new FileSystemError(`Failed to generate file existence check prompt: ${error instanceof Error ? error.message : String(error)}`, { filePath });
293
+ return {
294
+ success: false,
295
+ filePath,
296
+ written: false,
297
+ error: error instanceof Error ? error.message : String(error),
298
+ };
477
299
  }
478
300
  }
479
301
  /**
480
- * Generate prompt for AI-driven directory creation
302
+ * Find related code files for an ADR using Smart Code Linking
303
+ * Uses AI for keyword extraction and ripgrep for efficient searching
304
+ *
305
+ * @param adrPath - Path to the ADR file
306
+ * @param adrContent - Content of the ADR
307
+ * @param projectPath - Root path of the project
308
+ * @param options - Additional options for search customization
309
+ * @returns Promise resolving to related code files
481
310
  */
482
- export async function ensureDirectory(dirPath) {
311
+ export async function findRelatedCode(adrPath, adrContent, projectPath, options = {}) {
312
+ const { useAI = true, useRipgrep = true, maxFiles = 50, includeContent = false } = options;
483
313
  try {
484
- console.error(`[DEBUG] Generating directory creation prompt for: ${dirPath}`);
485
- // Pure prompt-driven approach - delegate directory creation to AI agent
486
- const safeDirPath = dirPath || '';
487
- const prompt = `
488
- # Directory Creation Request
489
-
490
- Please ensure the directory exists: **${safeDirPath}**
491
-
492
- ## Path Security Validation
493
-
494
- The AI agent must:
495
- 1. **Validate directory path security**: Ensure the path is not a system directory (/, /usr, /bin, /etc, /var, /tmp, etc.)
496
- 2. **Resolve relative paths safely**: Handle relative paths from the current working directory
497
- 3. **Prevent unauthorized access**: Reject attempts to create directories in sensitive system locations
498
- 4. **Validate path format**: Check for valid directory path format and reject malicious patterns
499
-
500
- ## Directory Creation Requirements
501
-
502
- 1. **Safe Path Resolution**: Resolve the directory path using appropriate file system tools
503
- 2. **Recursive Creation**: Create parent directories if they don't exist (recursive: true)
504
- 3. **Permission Handling**: Ensure appropriate permissions for directory creation
505
- 4. **Error Handling**: Handle various scenarios:
506
- - Directory already exists (success)
507
- - Parent directories don't exist (create them)
508
- - Permission denied
509
- - Invalid path or malformed directory name
510
- - Disk space issues
511
-
512
- ## Action Confirmation Required
513
-
514
- Before creating any directories, confirm the action with the user:
515
-
516
- **Action**: Create directory structure
517
- **Target**: ${safeDirPath}
518
- **Type**: Directory creation (recursive)
519
- **Impact**: Creates directory and any missing parent directories
520
-
521
- ## Expected Output Format
522
-
523
- \`\`\`json
524
- {
525
- "success": true,
526
- "dirPath": "${safeDirPath}",
527
- "created": true,
528
- "metadata": {
529
- "type": "directory",
530
- "recursive": true,
531
- "permissions": "755",
532
- "createdAt": "ISO_timestamp"
533
- },
534
- "security": {
535
- "pathValidated": true,
536
- "accessAuthorized": true,
537
- "systemDirectoryCheck": "passed"
538
- },
539
- "confirmation": {
540
- "actionConfirmed": true,
541
- "userApproved": true
542
- }
543
- }
544
- \`\`\`
545
-
546
- ## Response Format for Existing Directory
547
-
548
- \`\`\`json
549
- {
550
- "success": true,
551
- "dirPath": "${safeDirPath}",
552
- "created": false,
553
- "metadata": {
554
- "type": "directory",
555
- "alreadyExists": true,
556
- "permissions": "existing_permissions",
557
- "lastModified": "ISO_timestamp"
558
- },
559
- "security": {
560
- "pathValidated": true,
561
- "accessAuthorized": true,
562
- "systemDirectoryCheck": "passed"
563
- }
564
- }
565
- \`\`\`
566
-
567
- ## Error Response Format
568
-
569
- \`\`\`json
570
- {
571
- "success": false,
572
- "dirPath": "${safeDirPath}",
573
- "created": false,
574
- "error": "detailed error message",
575
- "errorType": "PERMISSION_DENIED|INVALID_PATH|SECURITY_VIOLATION|DISK_FULL",
576
- "security": {
577
- "pathValidated": boolean,
578
- "accessAuthorized": boolean,
579
- "systemDirectoryCheck": "passed|failed",
580
- "rejectionReason": "specific reason if access denied"
581
- }
582
- }
583
- \`\`\`
584
- `;
585
- const instructions = `
586
- ## Implementation Steps
587
-
588
- 1. **Security Validation**:
589
- - Validate the directory path: ${safeDirPath}
590
- - Ensure it's not a system directory or sensitive location
591
- - Check for path traversal attempts (../, .\\, etc.)
592
- - Validate path format and reject malicious patterns
593
-
594
- 2. **Action Confirmation**:
595
- - Present the directory creation action to the user for confirmation
596
- - Include details about what directories will be created
597
- - Wait for user approval before proceeding
598
-
599
- 3. **Directory Creation**:
600
- - Check if the directory already exists
601
- - Create parent directories recursively if needed
602
- - Set appropriate permissions (755 or system default)
603
- - Handle symbolic links appropriately
604
-
605
- 4. **Response Generation**:
606
- - Format response according to the specified JSON structure
607
- - Include comprehensive metadata and security validation results
608
- - Provide detailed error information if creation fails
609
- - Include confirmation status
610
-
611
- ## Safety Checks
612
-
613
- - ✅ Path security validation delegated to AI agent
614
- - ✅ System directory protection enabled
615
- - ✅ Action confirmation required before directory creation
616
- - ✅ Recursive directory creation with permission handling
617
- - ✅ Comprehensive error handling specified
618
-
619
- ## Context Information
620
-
621
- - **Directory Path**: ${safeDirPath}
622
- - **Operation**: Safe directory creation (recursive)
623
- - **Security Level**: High (with path validation and access control)
624
- - **Confirmation Required**: Yes (action confirmation pattern)
625
- `;
626
- return {
627
- prompt,
628
- instructions,
629
- context: {
630
- dirPath: safeDirPath,
631
- operation: 'directory_creation',
632
- securityLevel: 'high',
633
- expectedFormat: 'json',
634
- confirmationRequired: true,
635
- recursive: true
314
+ let keywords = [];
315
+ let confidence = 0.5;
316
+ // Step 1: Extract keywords using AI if available
317
+ if (useAI) {
318
+ try {
319
+ keywords = await extractKeywordsWithAI(adrContent);
320
+ confidence = 0.9; // Higher confidence with AI
321
+ }
322
+ catch (error) {
323
+ console.warn('AI keyword extraction failed, falling back to regex:', error);
324
+ keywords = extractKeywordsFromContent(adrContent);
325
+ confidence = 0.6;
636
326
  }
327
+ }
328
+ else {
329
+ keywords = extractKeywordsFromContent(adrContent);
330
+ confidence = 0.6;
331
+ }
332
+ // Step 2: Search for files using ripgrep or fast-glob
333
+ let relatedFiles = [];
334
+ if (useRipgrep) {
335
+ try {
336
+ const ripgrepModule = await import('./ripgrep-wrapper.js');
337
+ const { searchMultiplePatterns, isRipgrepAvailable } = ripgrepModule;
338
+ if (await isRipgrepAvailable()) {
339
+ // Use ripgrep for efficient searching
340
+ const searchResults = await searchMultiplePatterns(keywords.slice(0, 10), // Limit keywords for performance
341
+ projectPath, {
342
+ fileType: 'ts,js,py,java,go,rs,cs',
343
+ maxMatches: 5,
344
+ caseInsensitive: true,
345
+ });
346
+ // Collect unique files from all pattern matches
347
+ const uniqueFiles = new Set();
348
+ searchResults.forEach(files => {
349
+ files.forEach(file => uniqueFiles.add(file));
350
+ });
351
+ // Convert file paths to FileInfo objects
352
+ const filePromises = Array.from(uniqueFiles)
353
+ .slice(0, maxFiles)
354
+ .map(async (filePath) => {
355
+ const fullPath = path.resolve(projectPath, filePath);
356
+ const stats = await fs.stat(fullPath);
357
+ const fileInfo = {
358
+ path: filePath,
359
+ name: path.basename(filePath),
360
+ extension: path.extname(filePath),
361
+ size: stats.size,
362
+ directory: path.dirname(filePath),
363
+ };
364
+ if (includeContent) {
365
+ try {
366
+ fileInfo.content = await fs.readFile(fullPath, 'utf-8');
367
+ }
368
+ catch {
369
+ // Ignore read errors
370
+ }
371
+ }
372
+ return fileInfo;
373
+ });
374
+ relatedFiles = await Promise.all(filePromises);
375
+ confidence = Math.min(0.95, confidence + 0.1); // Boost confidence with ripgrep
376
+ }
377
+ else {
378
+ throw new Error('Ripgrep not available');
379
+ }
380
+ }
381
+ catch (error) {
382
+ console.warn('Ripgrep search failed, falling back to fast-glob:', error);
383
+ // Fall through to fast-glob search
384
+ }
385
+ }
386
+ // Fallback to fast-glob if ripgrep didn't work or wasn't used
387
+ if (relatedFiles.length === 0) {
388
+ // Build search patterns based on keywords
389
+ const searchPatterns = keywords.slice(0, 10).map(keyword => `**/*${keyword}*`);
390
+ // Find files matching the patterns
391
+ const { files } = await findFiles(projectPath, searchPatterns, {
392
+ includeContent,
393
+ limit: maxFiles,
394
+ });
395
+ // Filter to source code files only
396
+ const sourceExtensions = ['.ts', '.js', '.tsx', '.jsx', '.py', '.java', '.cs', '.go', '.rs'];
397
+ relatedFiles = files.filter(file => sourceExtensions.includes(file.extension));
398
+ }
399
+ // Step 3: Score and rank files by relevance
400
+ const scoredFiles = relatedFiles.map(file => {
401
+ let score = 0;
402
+ const fileName = file.name.toLowerCase();
403
+ const filePath = file.path.toLowerCase();
404
+ // Score based on keyword matches in file name/path
405
+ keywords.forEach(keyword => {
406
+ const lowerKeyword = keyword.toLowerCase();
407
+ if (fileName.includes(lowerKeyword))
408
+ score += 3;
409
+ if (filePath.includes(lowerKeyword))
410
+ score += 1;
411
+ });
412
+ return { file, score };
413
+ });
414
+ // Sort by score and take top results
415
+ scoredFiles.sort((a, b) => b.score - a.score);
416
+ const topFiles = scoredFiles.slice(0, maxFiles).map(item => item.file);
417
+ // Adjust confidence based on results
418
+ if (topFiles.length === 0) {
419
+ confidence = 0.2;
420
+ }
421
+ else if (topFiles.length < 5) {
422
+ confidence = Math.min(confidence, 0.5);
423
+ }
424
+ return {
425
+ adrPath,
426
+ relatedFiles: topFiles,
427
+ keywords,
428
+ searchPatterns: keywords.map(k => `**/*${k}*`),
429
+ confidence,
637
430
  };
638
431
  }
639
432
  catch (error) {
640
- throw new FileSystemError(`Failed to generate directory creation prompt: ${error instanceof Error ? error.message : String(error)}`, { dirPath });
433
+ throw new FileSystemError(`Failed to find related code: ${error instanceof Error ? error.message : String(error)}`, { adrPath });
641
434
  }
642
435
  }
643
436
  /**
644
- * Generate prompt for AI-driven file writing with directory creation
437
+ * Extract keywords from ADR content using AI
645
438
  */
646
- export async function writeFile(filePath, content) {
439
+ async function extractKeywordsWithAI(content) {
647
440
  try {
648
- console.error(`[DEBUG] Generating file write prompt for: ${filePath}`);
649
- // Pure prompt-driven approach - delegate file writing to AI agent
650
- const safeFilePath = filePath || '';
651
- const safeContent = content || '';
652
- const contentPreview = safeContent.length > 200 ? safeContent.substring(0, 200) + '...' : safeContent;
653
- const prompt = `
654
- # File Writing Request
655
-
656
- Please write content to the file: **${safeFilePath}**
657
-
658
- ## Path Security Validation
659
-
660
- The AI agent must:
661
- 1. **Validate file path security**: Ensure the path is not a system directory (/, /usr, /bin, /etc, /var, /tmp, etc.)
662
- 2. **Resolve relative paths safely**: Handle relative paths from the current working directory
663
- 3. **Prevent unauthorized access**: Reject attempts to write to sensitive system files or directories
664
- 4. **Validate path format**: Check for valid file path format and reject malicious patterns
665
-
666
- ## Content Security Validation
667
-
668
- The AI agent must:
669
- 1. **Content sanitization**: Validate content for security issues (no malicious scripts, etc.)
670
- 2. **Encoding validation**: Ensure content is properly encoded as UTF-8
671
- 3. **Size validation**: Check content size is reasonable
672
- 4. **Format validation**: Verify content format matches file extension expectations
673
-
674
- ## File Writing Requirements
675
-
676
- 1. **Directory Creation**: Ensure parent directory exists (create if needed)
677
- 2. **Safe File Writing**: Write content using appropriate file system tools
678
- 3. **Encoding Handling**: Write the file as UTF-8 text content
679
- 4. **Atomic Operations**: Use atomic write operations when possible
680
- 5. **Permission Handling**: Set appropriate file permissions
681
- 6. **Backup Consideration**: Consider backing up existing files if they exist
682
-
683
- ## Action Confirmation Required
684
-
685
- Before writing any files, confirm the action with the user:
686
-
687
- **Action**: Write file content
688
- **Target**: ${safeFilePath}
689
- **Content Size**: ${safeContent.length} characters
690
- **Content Preview**: ${contentPreview}
691
- **Type**: File creation/modification
692
- **Impact**: Creates file and any missing parent directories
693
-
694
- ## Expected Output Format
695
-
696
- \`\`\`json
697
- {
698
- "success": true,
699
- "filePath": "${safeFilePath}",
700
- "written": true,
701
- "metadata": {
702
- "type": "file",
703
- "size": ${safeContent.length},
704
- "encoding": "utf-8",
705
- "permissions": "644",
706
- "createdAt": "ISO_timestamp",
707
- "directoryCreated": boolean
708
- },
709
- "security": {
710
- "pathValidated": true,
711
- "contentValidated": true,
712
- "accessAuthorized": true,
713
- "systemDirectoryCheck": "passed"
714
- },
715
- "confirmation": {
716
- "actionConfirmed": true,
717
- "userApproved": true
718
- }
719
- }
720
- \`\`\`
721
-
722
- ## Response Format for File Update
723
-
724
- \`\`\`json
725
- {
726
- "success": true,
727
- "filePath": "${safeFilePath}",
728
- "written": true,
729
- "metadata": {
730
- "type": "file",
731
- "size": ${safeContent.length},
732
- "encoding": "utf-8",
733
- "permissions": "644",
734
- "updatedAt": "ISO_timestamp",
735
- "previousSize": <previous_file_size>,
736
- "directoryCreated": false
737
- },
738
- "security": {
739
- "pathValidated": true,
740
- "contentValidated": true,
741
- "accessAuthorized": true,
742
- "systemDirectoryCheck": "passed"
743
- },
744
- "confirmation": {
745
- "actionConfirmed": true,
746
- "userApproved": true
747
- }
748
- }
749
- \`\`\`
750
-
751
- ## Error Response Format
752
-
753
- \`\`\`json
754
- {
755
- "success": false,
756
- "filePath": "${safeFilePath}",
757
- "written": false,
758
- "error": "detailed error message",
759
- "errorType": "PERMISSION_DENIED|INVALID_PATH|SECURITY_VIOLATION|CONTENT_INVALID|DISK_FULL",
760
- "security": {
761
- "pathValidated": boolean,
762
- "contentValidated": boolean,
763
- "accessAuthorized": boolean,
764
- "systemDirectoryCheck": "passed|failed",
765
- "rejectionReason": "specific reason if access denied"
766
- }
767
- }
768
- \`\`\`
769
- `;
770
- const instructions = `
771
- ## Implementation Steps
772
-
773
- 1. **Security Validation**:
774
- - Validate the file path: ${safeFilePath}
775
- - Ensure it's not a system directory or sensitive location
776
- - Check for path traversal attempts (../, .\\, etc.)
777
- - Validate content for security issues
778
-
779
- 2. **Action Confirmation**:
780
- - Present the file writing action to the user for confirmation
781
- - Include details about the file path and content preview
782
- - Show content size and any directories that will be created
783
- - Wait for user approval before proceeding
784
-
785
- 3. **Directory Preparation**:
786
- - Extract directory path from file path: ${dirname(safeFilePath)}
787
- - Ensure parent directory exists (create recursively if needed)
788
- - Validate directory permissions
789
-
790
- 4. **File Writing**:
791
- - Check if file already exists (for backup consideration)
792
- - Write content to file using UTF-8 encoding
793
- - Set appropriate file permissions (644 or system default)
794
- - Use atomic write operations when possible
795
-
796
- 5. **Response Generation**:
797
- - Format response according to the specified JSON structure
798
- - Include comprehensive metadata and security validation results
799
- - Provide detailed error information if writing fails
800
- - Include confirmation status and directory creation details
801
-
802
- ## Safety Checks
803
-
804
- - ✅ Path security validation delegated to AI agent
805
- - ✅ Content security validation required
806
- - ✅ System directory protection enabled
807
- - ✅ Action confirmation required before file writing
808
- - ✅ Directory creation with permission handling
809
- - ✅ Comprehensive error handling specified
810
-
811
- ## Context Information
812
-
813
- - **File Path**: ${safeFilePath}
814
- - **Content Size**: ${safeContent.length} characters
815
- - **Operation**: Safe file writing with directory creation
816
- - **Security Level**: High (with path and content validation)
817
- - **Confirmation Required**: Yes (action confirmation pattern)
818
- `;
819
- return {
820
- prompt,
821
- instructions,
822
- context: {
823
- filePath: safeFilePath,
824
- contentSize: safeContent.length,
825
- operation: 'file_write',
826
- securityLevel: 'high',
827
- expectedFormat: 'json',
828
- confirmationRequired: true,
829
- directoryCreation: true
441
+ // Dynamic import to avoid circular dependencies
442
+ const aiModule = await import('./ai-executor.js');
443
+ const { AIExecutor } = aiModule;
444
+ const executor = new AIExecutor();
445
+ if (!executor.isAvailable()) {
446
+ throw new Error('AI executor not available');
447
+ }
448
+ const prompt = `Extract the most important technical keywords, class names, function names, and architectural terms from this ADR content. Return only a JSON array of strings with the top 20 most relevant keywords for code searching.
449
+
450
+ ADR Content:
451
+ ${content.substring(0, 3000)} // Limit content length
452
+
453
+ Example output format:
454
+ ["UserService", "authentication", "JWT", "PostgreSQL", "REST_API", "validate_token", "user_repository"]
455
+
456
+ Return ONLY the JSON array, no other text.`;
457
+ const result = await executor.executePrompt(prompt, {
458
+ temperature: 0.3,
459
+ maxTokens: 500,
460
+ });
461
+ // Parse the AI response
462
+ const cleanedResponse = result.content.trim();
463
+ const jsonMatch = cleanedResponse.match(/\[.*\]/s);
464
+ if (jsonMatch) {
465
+ const keywords = JSON.parse(jsonMatch[0]);
466
+ if (Array.isArray(keywords)) {
467
+ return keywords.filter(k => typeof k === 'string').slice(0, 20);
830
468
  }
831
- };
469
+ }
470
+ throw new Error('Invalid AI response format');
832
471
  }
833
472
  catch (error) {
834
- throw new FileSystemError(`Failed to generate file write prompt: ${error instanceof Error ? error.message : String(error)}`, { filePath });
473
+ console.error('AI keyword extraction failed:', error);
474
+ throw error;
475
+ }
476
+ }
477
+ // Helper functions
478
+ /**
479
+ * Detect technologies from project files
480
+ */
481
+ async function detectTechnologies(projectPath, files) {
482
+ const technologies = new Set();
483
+ // Check for package.json
484
+ const packageJsonFile = files.find(f => f.name === 'package.json');
485
+ if (packageJsonFile) {
486
+ technologies.add('Node.js');
487
+ try {
488
+ const content = await fs.readFile(path.join(projectPath, packageJsonFile.path), 'utf-8');
489
+ const packageJson = JSON.parse(content);
490
+ const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
491
+ if (deps.react)
492
+ technologies.add('React');
493
+ if (deps.vue)
494
+ technologies.add('Vue');
495
+ if (deps.angular)
496
+ technologies.add('Angular');
497
+ if (deps.express)
498
+ technologies.add('Express');
499
+ if (deps.fastify)
500
+ technologies.add('Fastify');
501
+ if (deps['@aws-sdk'] || deps['aws-sdk'])
502
+ technologies.add('AWS SDK');
503
+ if (deps['@google-cloud'])
504
+ technologies.add('GCP SDK');
505
+ if (deps['@azure'])
506
+ technologies.add('Azure SDK');
507
+ }
508
+ catch {
509
+ // Ignore parsing errors
510
+ }
511
+ }
512
+ // Check for other technology indicators
513
+ if (files.some(f => f.name === 'requirements.txt'))
514
+ technologies.add('Python');
515
+ if (files.some(f => f.name === 'Gemfile'))
516
+ technologies.add('Ruby');
517
+ if (files.some(f => f.name === 'pom.xml'))
518
+ technologies.add('Maven/Java');
519
+ if (files.some(f => f.name === 'Cargo.toml'))
520
+ technologies.add('Rust');
521
+ if (files.some(f => f.name === 'go.mod'))
522
+ technologies.add('Go');
523
+ if (files.some(f => f.name === 'Dockerfile'))
524
+ technologies.add('Docker');
525
+ if (files.some(f => f.name === 'docker-compose.yml'))
526
+ technologies.add('Docker Compose');
527
+ if (files.some(f => f.extension === '.tf'))
528
+ technologies.add('Terraform');
529
+ // Check for Kubernetes files
530
+ const k8sFiles = files.filter(f => f.extension === '.yaml' || f.extension === '.yml');
531
+ if (k8sFiles.length > 0) {
532
+ for (const file of k8sFiles.slice(0, 5)) {
533
+ // Check first 5 YAML files
534
+ try {
535
+ const content = await fs.readFile(path.join(projectPath, file.path), 'utf-8');
536
+ if (content.includes('apiVersion:') && content.includes('kind:')) {
537
+ technologies.add('Kubernetes');
538
+ break;
539
+ }
540
+ }
541
+ catch {
542
+ // Ignore read errors
543
+ }
544
+ }
835
545
  }
546
+ return Array.from(technologies);
547
+ }
548
+ /**
549
+ * Detect architectural patterns from file structure
550
+ */
551
+ function detectArchitecturalPatterns(files) {
552
+ const patterns = new Set();
553
+ const fileNames = files.map(f => f.name.toLowerCase());
554
+ const filePaths = files.map(f => f.path.toLowerCase());
555
+ // Common architectural patterns
556
+ if (fileNames.some(name => name.includes('controller')))
557
+ patterns.add('MVC');
558
+ if (fileNames.some(name => name.includes('service')))
559
+ patterns.add('Service Layer');
560
+ if (fileNames.some(name => name.includes('repository')))
561
+ patterns.add('Repository Pattern');
562
+ if (fileNames.some(name => name.includes('factory')))
563
+ patterns.add('Factory Pattern');
564
+ // Microservices patterns
565
+ if (filePaths.some(path => path.includes('microservice')))
566
+ patterns.add('Microservices');
567
+ // Container patterns
568
+ if (fileNames.some(name => name === 'dockerfile'))
569
+ patterns.add('Containerization');
570
+ // Infrastructure as Code
571
+ if (files.some(f => f.extension === '.tf'))
572
+ patterns.add('Infrastructure as Code');
573
+ // CI/CD patterns
574
+ if (filePaths.some(path => path.includes('.github/workflows')))
575
+ patterns.add('CI/CD Pipeline');
576
+ return Array.from(patterns);
577
+ }
578
+ /**
579
+ * Generate a summary of the project analysis
580
+ */
581
+ function generateProjectSummary(files, technologies, patterns) {
582
+ const extensions = [...new Set(files.map(f => f.extension))].filter(ext => ext);
583
+ const summary = `Project with ${files.length} files. ` +
584
+ `Technologies: ${technologies.join(', ') || 'Not detected'}. ` +
585
+ `Patterns: ${patterns.join(', ') || 'Not detected'}. ` +
586
+ `Main file types: ${extensions.slice(0, 5).join(', ')}.`;
587
+ return summary;
588
+ }
589
+ /**
590
+ * Simple keyword extraction from content
591
+ * This will be enhanced with LLM integration later
592
+ */
593
+ function extractKeywordsFromContent(content) {
594
+ const keywords = [];
595
+ // Extract technology names
596
+ const techPatterns = [
597
+ /\b(React|Vue|Angular|Node\.js|Express|FastAPI|Django|Spring|Rails)\b/gi,
598
+ /\b(PostgreSQL|MySQL|MongoDB|Redis|Elasticsearch)\b/gi,
599
+ /\b(Docker|Kubernetes|AWS|Azure|GCP)\b/gi,
600
+ ];
601
+ techPatterns.forEach(pattern => {
602
+ const matches = content.match(pattern);
603
+ if (matches) {
604
+ keywords.push(...matches.map(m => m.toLowerCase()));
605
+ }
606
+ });
607
+ // Extract potential class/function names (CamelCase or snake_case)
608
+ const codePatterns = /\b[A-Z][a-zA-Z]+(?:[A-Z][a-z]+)*\b|\b[a-z]+_[a-z_]+\b/g;
609
+ const codeMatches = content.match(codePatterns);
610
+ if (codeMatches) {
611
+ keywords.push(...codeMatches.slice(0, 10)); // Limit to 10 code patterns
612
+ }
613
+ return [...new Set(keywords)]; // Remove duplicates
614
+ }
615
+ /**
616
+ * Generate backward-compatible prompt response for project analysis
617
+ * This wraps the new analyzeProjectStructure to provide the old interface
618
+ * @deprecated Use analyzeProjectStructure directly
619
+ */
620
+ export async function analyzeProjectStructureCompat(projectPath) {
621
+ const analysis = await analyzeProjectStructure(projectPath);
622
+ // Generate a descriptive prompt from the actual analysis
623
+ const prompt = `Project Analysis Results:
624
+ Root Path: ${analysis.rootPath}
625
+ Total Files: ${analysis.totalFiles}
626
+ Total Directories: ${analysis.totalDirectories}
627
+ Technologies: ${analysis.technologies.join(', ')}
628
+ Patterns: ${analysis.patterns.join(', ')}
629
+ Summary: ${analysis.summary}`;
630
+ const instructions = `This analysis was performed using fast-glob file discovery.
631
+ Technologies were detected by examining configuration files and dependencies.
632
+ Architectural patterns were identified from file structure and naming conventions.`;
633
+ return {
634
+ prompt,
635
+ instructions,
636
+ context: {
637
+ projectPath: analysis.rootPath,
638
+ absoluteProjectPath: analysis.rootPath,
639
+ filePatterns: ['**/*'],
640
+ },
641
+ };
642
+ }
643
+ /**
644
+ * Backward-compatible file exists wrapper
645
+ * @deprecated Use fileExists directly
646
+ */
647
+ export async function fileExistsCompat(filePath) {
648
+ const result = await fileExists(filePath);
649
+ const prompt = `File existence check: ${filePath}
650
+ Result: ${result.exists ? 'File exists' : 'File does not exist'}
651
+ Type: ${result.metadata?.type || 'unknown'}`;
652
+ const instructions = 'File existence was checked using Node.js fs.stat';
653
+ return {
654
+ ...result,
655
+ prompt,
656
+ instructions,
657
+ context: { filePath },
658
+ };
659
+ }
660
+ /**
661
+ * Backward-compatible ensure directory wrapper
662
+ * @deprecated Use ensureDirectory directly
663
+ */
664
+ export async function ensureDirectoryCompat(dirPath) {
665
+ const result = await ensureDirectory(dirPath);
666
+ const prompt = `Directory operation: ${dirPath}
667
+ Result: ${result.created ? 'Directory created' : 'Directory already exists'}
668
+ Success: ${result.success}`;
669
+ const instructions = 'Directory was ensured using Node.js fs.mkdir with recursive option';
670
+ return {
671
+ ...result,
672
+ prompt,
673
+ instructions,
674
+ context: { dirPath },
675
+ };
676
+ }
677
+ /**
678
+ * Backward-compatible write file wrapper
679
+ * @deprecated Use writeFile directly
680
+ */
681
+ export async function writeFileCompat(filePath, content) {
682
+ const result = await writeFile(filePath, content);
683
+ const prompt = `File write operation: ${filePath}
684
+ Result: ${result.written ? 'File written successfully' : 'File write failed'}
685
+ Size: ${result.metadata?.size || 0} bytes`;
686
+ const instructions = 'File was written using Node.js fs.writeFile';
687
+ return {
688
+ ...result,
689
+ prompt,
690
+ instructions,
691
+ context: { filePath, contentSize: content.length },
692
+ };
693
+ }
694
+ /**
695
+ * Backward-compatible read file wrapper
696
+ * @deprecated Use readFileContent directly
697
+ */
698
+ export async function readFileContentCompat(filePath) {
699
+ const result = await readFileContent(filePath);
700
+ const prompt = `File read operation: ${filePath}
701
+ Result: ${result.success ? 'File read successfully' : 'File read failed'}
702
+ Size: ${result.metadata?.size || 0} bytes`;
703
+ const instructions = 'File was read using Node.js fs.readFile';
704
+ return {
705
+ ...result,
706
+ prompt,
707
+ instructions,
708
+ context: { filePath },
709
+ };
836
710
  }
837
711
  /**
838
712
  * Get file extension patterns for different file types