@j0hanz/filesystem-context-mcp 1.0.6 → 1.0.8

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 (97) hide show
  1. package/dist/config/types.d.ts +18 -1
  2. package/dist/config/types.d.ts.map +1 -1
  3. package/dist/instructions.md +145 -181
  4. package/dist/lib/directory-helpers.d.ts +5 -0
  5. package/dist/lib/directory-helpers.d.ts.map +1 -0
  6. package/dist/lib/directory-helpers.js +39 -0
  7. package/dist/lib/directory-helpers.js.map +1 -0
  8. package/dist/lib/file-operations.d.ts.map +1 -1
  9. package/dist/lib/file-operations.js +32 -265
  10. package/dist/lib/file-operations.js.map +1 -1
  11. package/dist/lib/formatters.d.ts +12 -0
  12. package/dist/lib/formatters.d.ts.map +1 -1
  13. package/dist/lib/formatters.js +27 -0
  14. package/dist/lib/formatters.js.map +1 -1
  15. package/dist/lib/fs-helpers.d.ts +2 -1
  16. package/dist/lib/fs-helpers.d.ts.map +1 -1
  17. package/dist/lib/fs-helpers.js +24 -6
  18. package/dist/lib/fs-helpers.js.map +1 -1
  19. package/dist/lib/mcp-logger.d.ts +11 -0
  20. package/dist/lib/mcp-logger.d.ts.map +1 -0
  21. package/dist/lib/mcp-logger.js +45 -0
  22. package/dist/lib/mcp-logger.js.map +1 -0
  23. package/dist/lib/path-validation.d.ts +1 -6
  24. package/dist/lib/path-validation.d.ts.map +1 -1
  25. package/dist/lib/path-validation.js.map +1 -1
  26. package/dist/lib/search-helpers.d.ts +13 -0
  27. package/dist/lib/search-helpers.d.ts.map +1 -0
  28. package/dist/lib/search-helpers.js +181 -0
  29. package/dist/lib/search-helpers.js.map +1 -0
  30. package/dist/lib/sorting.d.ts +12 -0
  31. package/dist/lib/sorting.d.ts.map +1 -0
  32. package/dist/lib/sorting.js +41 -0
  33. package/dist/lib/sorting.js.map +1 -0
  34. package/dist/prompts/analyze-codebase.d.ts.map +1 -1
  35. package/dist/prompts/analyze-codebase.js +124 -38
  36. package/dist/prompts/analyze-codebase.js.map +1 -1
  37. package/dist/prompts/filesystem-query.d.ts.map +1 -1
  38. package/dist/prompts/filesystem-query.js +123 -68
  39. package/dist/prompts/filesystem-query.js.map +1 -1
  40. package/dist/prompts/find-duplicates.d.ts.map +1 -1
  41. package/dist/prompts/find-duplicates.js +56 -47
  42. package/dist/prompts/find-duplicates.js.map +1 -1
  43. package/dist/prompts/project-overview.d.ts.map +1 -1
  44. package/dist/prompts/project-overview.js +106 -35
  45. package/dist/prompts/project-overview.js.map +1 -1
  46. package/dist/prompts/search-and-replace.d.ts.map +1 -1
  47. package/dist/prompts/search-and-replace.js +104 -57
  48. package/dist/prompts/search-and-replace.js.map +1 -1
  49. package/dist/prompts/shared.d.ts +11 -0
  50. package/dist/prompts/shared.d.ts.map +1 -0
  51. package/dist/prompts/shared.js +32 -0
  52. package/dist/prompts/shared.js.map +1 -0
  53. package/dist/resources/index.d.ts +3 -0
  54. package/dist/resources/index.d.ts.map +1 -0
  55. package/dist/resources/index.js +54 -0
  56. package/dist/resources/index.js.map +1 -0
  57. package/dist/schemas/inputs.d.ts.map +1 -1
  58. package/dist/schemas/inputs.js +11 -7
  59. package/dist/schemas/inputs.js.map +1 -1
  60. package/dist/schemas/outputs.d.ts +10 -8
  61. package/dist/schemas/outputs.d.ts.map +1 -1
  62. package/dist/schemas/outputs.js +2 -0
  63. package/dist/schemas/outputs.js.map +1 -1
  64. package/dist/server.d.ts.map +1 -1
  65. package/dist/server.js +22 -15
  66. package/dist/server.js.map +1 -1
  67. package/dist/tools/analyze-directory.d.ts.map +1 -1
  68. package/dist/tools/analyze-directory.js +12 -5
  69. package/dist/tools/analyze-directory.js.map +1 -1
  70. package/dist/tools/directory-tree.d.ts.map +1 -1
  71. package/dist/tools/directory-tree.js +15 -3
  72. package/dist/tools/directory-tree.js.map +1 -1
  73. package/dist/tools/get-file-info.d.ts.map +1 -1
  74. package/dist/tools/get-file-info.js +4 -1
  75. package/dist/tools/get-file-info.js.map +1 -1
  76. package/dist/tools/list-allowed-dirs.d.ts.map +1 -1
  77. package/dist/tools/list-allowed-dirs.js +15 -2
  78. package/dist/tools/list-allowed-dirs.js.map +1 -1
  79. package/dist/tools/list-directory.d.ts.map +1 -1
  80. package/dist/tools/list-directory.js +15 -8
  81. package/dist/tools/list-directory.js.map +1 -1
  82. package/dist/tools/read-file.d.ts.map +1 -1
  83. package/dist/tools/read-file.js +6 -2
  84. package/dist/tools/read-file.js.map +1 -1
  85. package/dist/tools/read-media-file.d.ts.map +1 -1
  86. package/dist/tools/read-media-file.js +4 -1
  87. package/dist/tools/read-media-file.js.map +1 -1
  88. package/dist/tools/read-multiple-files.d.ts.map +1 -1
  89. package/dist/tools/read-multiple-files.js +6 -2
  90. package/dist/tools/read-multiple-files.js.map +1 -1
  91. package/dist/tools/search-content.d.ts.map +1 -1
  92. package/dist/tools/search-content.js +42 -5
  93. package/dist/tools/search-content.js.map +1 -1
  94. package/dist/tools/search-files.d.ts.map +1 -1
  95. package/dist/tools/search-files.js +14 -5
  96. package/dist/tools/search-files.js.map +1 -1
  97. package/package.json +1 -1
@@ -1,58 +1,144 @@
1
1
  import { completable } from '@modelcontextprotocol/sdk/server/completable.js';
2
2
  import { z } from 'zod';
3
- import { getAllowedDirectories } from '../lib/path-validation.js';
3
+ import { buildExcludes, pathCompleter } from './shared.js';
4
+ // Extended excludes for codebase analysis (adds minified files)
5
+ const ANALYZE_EXCLUDES = buildExcludes('minified');
6
+ const FOCUS_CONFIG = {
7
+ architecture: {
8
+ patterns: [
9
+ 'export (class|interface|type|function) \\w+',
10
+ '^import .+ from',
11
+ '@module|@package|@namespace',
12
+ ],
13
+ deliverables: [
14
+ 'Module organization & boundaries',
15
+ 'Dependency graph (imports/exports)',
16
+ 'Layer violations & circular deps',
17
+ 'Entry points & public API surface',
18
+ ],
19
+ maxResults: 100,
20
+ },
21
+ patterns: {
22
+ patterns: [
23
+ 'class \\w+Factory|create\\w+\\(',
24
+ 'getInstance\\(|private constructor',
25
+ 'subscribe\\(|addEventListener\\(|on[A-Z]\\w+\\(',
26
+ 'implements \\w+(Strategy|Handler|Provider)',
27
+ ],
28
+ deliverables: [
29
+ 'Design patterns identified (Factory, Singleton, Observer, Strategy)',
30
+ 'Pattern usage frequency & locations',
31
+ 'Anti-patterns & code smells',
32
+ 'Refactoring opportunities',
33
+ ],
34
+ maxResults: 50,
35
+ },
36
+ quality: {
37
+ patterns: [
38
+ 'TODO|FIXME|HACK|XXX|BUG',
39
+ '@deprecated|@obsolete|@legacy',
40
+ 'console\\.(log|warn|error|debug)',
41
+ 'eslint-disable|@ts-ignore|@ts-expect-error',
42
+ ],
43
+ deliverables: [
44
+ 'Technical debt inventory with severity',
45
+ 'Debug/console statements left behind',
46
+ 'Suppressed linting rules',
47
+ 'Documentation coverage gaps',
48
+ ],
49
+ maxResults: 100,
50
+ },
51
+ security: {
52
+ patterns: [
53
+ 'eval\\(|new Function\\(|exec\\(',
54
+ 'password|secret|api_?key|token|credential',
55
+ 'innerHTML|dangerouslySetInnerHTML|outerHTML',
56
+ 'process\\.env\\.|\\$\\{.*SECRET|\\$\\{.*KEY',
57
+ ],
58
+ deliverables: [
59
+ 'Potential code injection vulnerabilities',
60
+ 'Hardcoded secrets & credentials',
61
+ 'Unsafe DOM manipulation',
62
+ 'Environment variable exposure',
63
+ ],
64
+ maxResults: 50,
65
+ },
66
+ };
4
67
  export function registerAnalyzeCodebasePrompt(server) {
5
68
  server.registerPrompt('analyze-codebase', {
6
- description: 'Deep analysis of code patterns, architecture, and implementation details in a codebase',
69
+ description: 'Deep code analysis: architecture, patterns, quality, or security',
7
70
  argsSchema: {
8
- path: completable(z.string().min(1).describe('Root path of the codebase to analyze'), (value) => {
9
- const dirs = getAllowedDirectories();
10
- return dirs.filter((d) => d.toLowerCase().includes(value.toLowerCase()) ||
11
- value.toLowerCase().includes(d.toLowerCase().slice(0, 10)));
12
- }),
71
+ path: completable(z.string().min(1).describe('Codebase root path'), pathCompleter),
13
72
  focus: z
14
73
  .enum(['architecture', 'patterns', 'quality', 'security', 'all'])
15
74
  .optional()
16
75
  .default('all')
17
- .describe('Analysis focus area (default: all)'),
76
+ .describe('Focus: architecture, patterns, quality, security, or all'),
18
77
  filePattern: z
19
78
  .string()
20
79
  .optional()
21
- .default('**/*.{ts,js,py,java,go,rs}')
22
- .describe('Glob pattern for files to analyze (default: common source files)'),
80
+ .default('**/*.{ts,js,tsx,jsx,py,java,go,rs}')
81
+ .describe('Source file glob pattern'),
82
+ maxDepth: z
83
+ .number()
84
+ .int()
85
+ .min(1)
86
+ .max(20)
87
+ .optional()
88
+ .default(10)
89
+ .describe('Maximum directory depth (default: 10)'),
23
90
  },
24
- }, ({ path, focus, filePattern }) => ({
25
- messages: [
26
- {
27
- role: 'user',
28
- content: {
29
- type: 'text',
30
- text: `Perform a deep analysis of the codebase at "${path}" with focus on: ${focus}.
91
+ }, ({ path, focus, filePattern, maxDepth }) => {
92
+ const focusAreas = focus === 'all' ? Object.keys(FOCUS_CONFIG) : [focus];
93
+ const allPatterns = focusAreas.flatMap((f) => FOCUS_CONFIG[f]?.patterns ?? []);
94
+ const allDeliverables = focusAreas.flatMap((f) => FOCUS_CONFIG[f]?.deliverables ?? []);
95
+ const maxResults = Math.min(...focusAreas.map((f) => FOCUS_CONFIG[f]?.maxResults ?? 100));
96
+ const excludesJson = JSON.stringify(ANALYZE_EXCLUDES);
97
+ // Build search instructions for each focus area
98
+ const searchInstructions = focusAreas
99
+ .map((f) => {
100
+ const config = FOCUS_CONFIG[f];
101
+ if (!config)
102
+ return '';
103
+ return ` - **${f}**: \`${config.patterns.slice(0, 2).join('` or `')}\``;
104
+ })
105
+ .filter(Boolean)
106
+ .join('\n');
107
+ return {
108
+ messages: [
109
+ {
110
+ role: 'user',
111
+ content: {
112
+ type: 'text',
113
+ text: `Analyze codebase at "${path}" (focus: **${focus}**).
31
114
 
32
- Use the available filesystem tools systematically:
115
+ ⚠️ First run \`list_allowed_directories\` to verify path is accessible.
33
116
 
34
- 1. **Discovery Phase**
35
- - Use \`directory_tree\` to understand the overall structure
36
- - Use \`search_files\` with pattern "${filePattern}" to find source files
37
- - Use \`analyze_directory\` to get file statistics and identify largest/most recent files
117
+ **Default excludes:** ${ANALYZE_EXCLUDES.slice(0, 4).join(', ')}
38
118
 
39
- 2. **Code Inspection Phase**
40
- - Use \`search_content\` to find key patterns:
41
- ${focus === 'architecture' || focus === 'all' ? '- Search for class/interface definitions, exports, imports' : ''}
42
- ${focus === 'patterns' || focus === 'all' ? '- Search for common design patterns (Factory, Singleton, Observer, etc.)' : ''}
43
- ${focus === 'quality' || focus === 'all' ? '- Search for TODO, FIXME, HACK comments' : ''}
44
- ${focus === 'security' || focus === 'all' ? '- Search for potential security concerns (eval, exec, password, secret, token)' : ''}
45
- - Use \`read_multiple_files\` to examine key files identified in discovery
119
+ **Workflow:**
120
+ 1. \`directory_tree\` maxDepth=${maxDepth} excludePatterns=${excludesJson} structure overview
121
+ 2. \`search_files\` pattern="${filePattern}" excludePatterns=${excludesJson} find source files
122
+ 3. \`analyze_directory\` maxDepth=${maxDepth} excludePatterns=${excludesJson} stats & hotspots
123
+ 4. \`search_content\` contextLines=2 maxResults=${maxResults} excludePatterns=${excludesJson} search for:
124
+ ${searchInstructions}
125
+ 5. \`read_multiple_files\` batch examine key files (most efficient)
46
126
 
47
- 3. **Analysis Deliverables**
48
- ${focus === 'architecture' || focus === 'all' ? '- **Architecture**: Module organization, dependency flow, layering patterns' : ''}
49
- ${focus === 'patterns' || focus === 'all' ? '- **Design Patterns**: Identified patterns, their usage, and effectiveness' : ''}
50
- ${focus === 'quality' || focus === 'all' ? '- **Code Quality**: Technical debt indicators, documentation coverage, consistency' : ''}
51
- ${focus === 'security' || focus === 'all' ? '- **Security**: Potential vulnerabilities, hardcoded secrets, input validation' : ''}
52
- - **Recommendations**: Prioritized list of improvements with rationale`,
127
+ **Regex patterns to search:**
128
+ ${allPatterns.map((p) => `- \`${p}\``).join('\n')}
129
+
130
+ **Deliverables:**
131
+ ${allDeliverables.map((d) => `- ${d}`).join('\n')}
132
+
133
+ **Final Report:**
134
+ - Executive summary (1-2 paragraphs)
135
+ - Findings by category with file:line references
136
+ - Prioritized recommendations (High/Medium/Low)
137
+ - Quick wins vs long-term improvements`,
138
+ },
53
139
  },
54
- },
55
- ],
56
- }));
140
+ ],
141
+ };
142
+ });
57
143
  }
58
144
  //# sourceMappingURL=analyze-codebase.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"analyze-codebase.js","sourceRoot":"","sources":["../../src/prompts/analyze-codebase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iDAAiD,CAAC;AAG9E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAElE,MAAM,UAAU,6BAA6B,CAAC,MAAiB;IAC7D,MAAM,CAAC,cAAc,CACnB,kBAAkB,EAClB;QACE,WAAW,EACT,wFAAwF;QAC1F,UAAU,EAAE;YACV,IAAI,EAAE,WAAW,CACf,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,sCAAsC,CAAC,EAClE,CAAC,KAAK,EAAE,EAAE;gBACR,MAAM,IAAI,GAAG,qBAAqB,EAAE,CAAC;gBACrC,OAAO,IAAI,CAAC,MAAM,CAChB,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;oBAC7C,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAC7D,CAAC;YACJ,CAAC,CACF;YACD,KAAK,EAAE,CAAC;iBACL,IAAI,CAAC,CAAC,cAAc,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;iBAChE,QAAQ,EAAE;iBACV,OAAO,CAAC,KAAK,CAAC;iBACd,QAAQ,CAAC,oCAAoC,CAAC;YACjD,WAAW,EAAE,CAAC;iBACX,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,OAAO,CAAC,4BAA4B,CAAC;iBACrC,QAAQ,CACP,kEAAkE,CACnE;SACJ;KACF,EACD,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC;QACjC,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE;oBACP,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,+CAA+C,IAAI,oBAAoB,KAAK;;;;;;0CAMpD,WAAW;;;;;OAK9C,KAAK,KAAK,cAAc,IAAI,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,4DAA4D,CAAC,CAAC,CAAC,EAAE;OAC/G,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,0EAA0E,CAAC,CAAC,CAAC,EAAE;OACzH,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,yCAAyC,CAAC,CAAC,CAAC,EAAE;OACvF,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,gFAAgF,CAAC,CAAC,CAAC,EAAE;;;;KAIjI,KAAK,KAAK,cAAc,IAAI,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,6EAA6E,CAAC,CAAC,CAAC,EAAE;KAChI,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,4EAA4E,CAAC,CAAC,CAAC,EAAE;KAC3H,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,oFAAoF,CAAC,CAAC,CAAC,EAAE;KAClI,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,gFAAgF,CAAC,CAAC,CAAC,EAAE;0EAC1D;iBAC/D;aACF;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"analyze-codebase.js","sourceRoot":"","sources":["../../src/prompts/analyze-codebase.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"filesystem-query.d.ts","sourceRoot":"","sources":["../../src/prompts/filesystem-query.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMzE,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAkIrE"}
1
+ {"version":3,"file":"filesystem-query.d.ts","sourceRoot":"","sources":["../../src/prompts/filesystem-query.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAyEzE,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA6HrE"}
@@ -1,15 +1,68 @@
1
1
  import { completable } from '@modelcontextprotocol/sdk/server/completable.js';
2
2
  import { z } from 'zod';
3
- import { getAllowedDirectories } from '../lib/path-validation.js';
3
+ import { DEFAULT_EXCLUDES, pathCompleter } from './shared.js';
4
+ const OPERATIONS = {
5
+ explore: {
6
+ tools: `1. \`directory_tree\` maxDepth={depth} excludePatterns={excludes} → hierarchy
7
+ 2. \`analyze_directory\` excludePatterns={excludes} → stats
8
+ 3. \`list_directory\` sortBy="modified" → recent activity`,
9
+ deliverables: `- Structure overview & folder purposes
10
+ - File distribution by type
11
+ - Key config/entry files
12
+ - Notable findings`,
13
+ requiresPattern: false,
14
+ usesDepth: true,
15
+ },
16
+ 'find-files': {
17
+ tools: `1. \`search_files\` pattern="{pattern}" excludePatterns={excludes} maxResults=100 → find matches
18
+ 2. \`read_multiple_files\` → batch examine contents
19
+ 3. \`get_file_info\` → metadata if needed`,
20
+ deliverables: `- Matched files with sizes (up to 100 results)
21
+ - Content summary of key files
22
+ - Related pattern suggestions`,
23
+ requiresPattern: true,
24
+ usesDepth: true,
25
+ maxResults: 100,
26
+ },
27
+ 'search-code': {
28
+ tools: `1. \`search_content\` pattern="{pattern}" contextLines=2 maxResults=50 excludePatterns={excludes} → find matches
29
+ 2. \`read_multiple_files\` → batch read for full context`,
30
+ deliverables: `- Match count & files affected (up to 50 matches)
31
+ - Key matches with surrounding context
32
+ - Pattern usage analysis
33
+ - Suggested refactoring if duplicates found`,
34
+ requiresPattern: true,
35
+ usesDepth: false,
36
+ maxResults: 50,
37
+ },
38
+ 'analyze-size': {
39
+ tools: `1. \`analyze_directory\` maxDepth={depth} excludePatterns={excludes} → size stats
40
+ 2. \`directory_tree\` includeSize=true maxDepth={depth} excludePatterns={excludes} → visualize
41
+ 3. \`search_files\` sortBy="size" maxResults=20 → largest files`,
42
+ deliverables: `- Total size & file counts
43
+ - Top 10 largest files with paths
44
+ - Size breakdown by extension
45
+ - Cleanup suggestions (large/unused files)`,
46
+ requiresPattern: false,
47
+ usesDepth: true,
48
+ },
49
+ 'recent-changes': {
50
+ tools: `1. \`analyze_directory\` maxDepth={depth} excludePatterns={excludes} → recentlyModified
51
+ 2. \`list_directory\` sortBy="modified" recursive=true maxDepth={depth}
52
+ 3. \`read_multiple_files\` → batch examine recent files`,
53
+ deliverables: `- Recent activity timeline (last 24h, 7d, 30d)
54
+ - Most active directories
55
+ - Change patterns & hot spots
56
+ - Files to review`,
57
+ requiresPattern: false,
58
+ usesDepth: true,
59
+ },
60
+ };
4
61
  export function registerFilesystemQueryPrompt(server) {
5
62
  server.registerPrompt('filesystem-query', {
6
- description: 'A guided prompt for performing common filesystem exploration and analysis tasks. Provides structured guidance based on the selected operation type.',
63
+ description: 'Guided filesystem operations: explore, find, search, size, changes',
7
64
  argsSchema: {
8
- path: completable(z.string().min(1).describe('Target path for the operation'), (value) => {
9
- const dirs = getAllowedDirectories();
10
- return dirs.filter((d) => d.toLowerCase().includes(value.toLowerCase()) ||
11
- value.toLowerCase().includes(d.toLowerCase().slice(0, 10)));
12
- }),
65
+ path: completable(z.string().min(1).describe('Target path'), pathCompleter),
13
66
  operation: z
14
67
  .enum([
15
68
  'explore',
@@ -18,7 +71,7 @@ export function registerFilesystemQueryPrompt(server) {
18
71
  'analyze-size',
19
72
  'recent-changes',
20
73
  ])
21
- .describe('Operation type: explore (structure), find-files (by pattern), search-code (content search), analyze-size (disk usage), recent-changes (modified files)'),
74
+ .describe('Operation type'),
22
75
  pattern: z
23
76
  .string()
24
77
  .optional()
@@ -30,73 +83,75 @@ export function registerFilesystemQueryPrompt(server) {
30
83
  .max(20)
31
84
  .optional()
32
85
  .default(5)
33
- .describe('Maximum depth for exploration (default: 5)'),
86
+ .describe('Max depth (1-20, default: 5)'),
87
+ caseSensitive: z
88
+ .boolean()
89
+ .optional()
90
+ .default(false)
91
+ .describe('Case-sensitive search (search-code only)'),
34
92
  },
35
- }, ({ path, operation, pattern, depth }) => {
36
- const operationPrompts = {
37
- explore: `Explore the filesystem structure at "${path}".
38
-
39
- Use these tools in sequence:
40
- 1. \`directory_tree\` with maxDepth=${String(depth)} to visualize the hierarchy
41
- 2. \`analyze_directory\` to get file statistics (types, sizes, counts)
42
- 3. \`list_directory\` with sortBy="modified" for recent activity
43
-
44
- Provide:
45
- - **Structure Overview**: Main directories and their purposes
46
- - **File Distribution**: Breakdown by type and location
47
- - **Key Files**: Important configuration or entry point files
48
- - **Notable Findings**: Unusual patterns or large files`,
49
- 'find-files': `Find files matching pattern "${pattern ?? '**/*'}" in "${path}".
50
-
51
- Use these tools:
52
- 1. \`search_files\` with pattern="${pattern ?? '**/*'}" to find matching files
53
- 2. \`read_multiple_files\` to examine the most relevant matches
54
- 3. Optionally \`get_file_info\` for detailed metadata on specific files
55
-
56
- Provide:
57
- - **Matched Files**: List with paths and sizes
58
- - **Pattern Analysis**: What the pattern captured
59
- - **Content Preview**: Summary of matched file contents
60
- - **Suggestions**: Related patterns that might be useful`,
61
- 'search-code': `Search for code pattern "${pattern ?? ''}" in "${path}".
93
+ }, ({ path, operation, pattern, depth, caseSensitive }) => {
94
+ const config = OPERATIONS[operation];
95
+ // Type guard - should never happen with enum validation, but TypeScript needs this
96
+ if (!config) {
97
+ return {
98
+ messages: [
99
+ {
100
+ role: 'user',
101
+ content: {
102
+ type: 'text',
103
+ text: `Unknown operation: "${operation}". Valid operations: ${Object.keys(OPERATIONS).join(', ')}`,
104
+ },
105
+ },
106
+ ],
107
+ };
108
+ }
109
+ const excludesJson = JSON.stringify(DEFAULT_EXCLUDES);
110
+ // Validate pattern requirement
111
+ if (config.requiresPattern && !pattern) {
112
+ return {
113
+ messages: [
114
+ {
115
+ role: 'user',
116
+ content: {
117
+ type: 'text',
118
+ text: `⚠️ The "${operation}" operation requires a pattern.
62
119
 
63
- Use these tools:
64
- 1. \`search_content\` with pattern="${pattern ?? ''}" and contextLines=2
65
- 2. \`read_multiple_files\` to get full context for important matches
66
- 3. Group results by file and analyze patterns
120
+ Please provide:
121
+ - For **find-files**: a glob pattern (e.g., "**/*.ts", "src/**/*.json")
122
+ - For **search-code**: a regex pattern (e.g., "TODO|FIXME", "function\\s+\\w+")`,
123
+ },
124
+ },
125
+ ],
126
+ };
127
+ }
128
+ // Build tools section with substitutions
129
+ const tools = config.tools
130
+ .replace(/{depth}/g, String(depth))
131
+ .replace(/{excludes}/g, excludesJson)
132
+ .replace(/{pattern}/g, pattern ?? '*');
133
+ // Build search options for search-code
134
+ const searchOptions = operation === 'search-code'
135
+ ? ` caseSensitive=${String(caseSensitive)}`
136
+ : '';
137
+ const patternInfo = pattern ? ` pattern="${pattern}"` : '';
138
+ const depthInfo = config.usesDepth ? ` maxDepth=${String(depth)}` : '';
139
+ const promptText = `**${operation.charAt(0).toUpperCase() + operation.slice(1)}** "${path}"${patternInfo}${depthInfo}${searchOptions}
67
140
 
68
- Provide:
69
- - **Match Summary**: Total matches, files affected
70
- - **Code Context**: Key matches with surrounding code
71
- - **Pattern Usage**: How and where the pattern appears
72
- - **Related Code**: Suggest related patterns to explore`,
73
- 'analyze-size': `Analyze disk usage and file sizes in "${path}".
141
+ ⚠️ First run \`list_allowed_directories\` to verify path is accessible.
74
142
 
75
- Use these tools:
76
- 1. \`analyze_directory\` to get size statistics and largest files
77
- 2. \`directory_tree\` with includeSize=true for size visualization
78
- 3. \`search_files\` to find specific file types if needed
143
+ **Default excludes:** ${DEFAULT_EXCLUDES.join(', ')}
79
144
 
80
- Provide:
81
- - **Size Summary**: Total size, file count, directory count
82
- - **Largest Files**: Top 10 with sizes and paths
83
- - **Type Breakdown**: Size by file extension
84
- - **Cleanup Suggestions**: Files that could be removed or compressed`,
85
- 'recent-changes': `Find recently modified files in "${path}".
145
+ **Tools:**
146
+ ${tools}
86
147
 
87
- Use these tools:
88
- 1. \`analyze_directory\` to see recentlyModified list
89
- 2. \`list_directory\` with sortBy="modified" for detailed listing
90
- 3. \`read_multiple_files\` to examine recent changes
148
+ **Deliverables:**
149
+ ${config.deliverables}
91
150
 
92
- Provide:
93
- - **Recent Activity**: Files modified in last 24h, week, month
94
- - **Change Patterns**: Which areas are most active
95
- - **File Diffs**: Summary of what changed in key files
96
- - **Activity Insights**: Development patterns or areas of focus`,
97
- };
98
- const promptText = operationPrompts[operation] ??
99
- `Perform "${operation}" operation at "${path}".`;
151
+ **Best Practices:**
152
+ - Use \`read_multiple_files\` to batch read (more efficient than sequential reads)
153
+ - Stop early if results are sufficient
154
+ - Report any inaccessible paths encountered`;
100
155
  return {
101
156
  messages: [
102
157
  {
@@ -1 +1 @@
1
- {"version":3,"file":"filesystem-query.js","sourceRoot":"","sources":["../../src/prompts/filesystem-query.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iDAAiD,CAAC;AAG9E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAElE,MAAM,UAAU,6BAA6B,CAAC,MAAiB;IAC7D,MAAM,CAAC,cAAc,CACnB,kBAAkB,EAClB;QACE,WAAW,EACT,qJAAqJ;QACvJ,UAAU,EAAE;YACV,IAAI,EAAE,WAAW,CACf,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,+BAA+B,CAAC,EAC3D,CAAC,KAAK,EAAE,EAAE;gBACR,MAAM,IAAI,GAAG,qBAAqB,EAAE,CAAC;gBACrC,OAAO,IAAI,CAAC,MAAM,CAChB,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;oBAC7C,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAC7D,CAAC;YACJ,CAAC,CACF;YACD,SAAS,EAAE,CAAC;iBACT,IAAI,CAAC;gBACJ,SAAS;gBACT,YAAY;gBACZ,aAAa;gBACb,cAAc;gBACd,gBAAgB;aACjB,CAAC;iBACD,QAAQ,CACP,wJAAwJ,CACzJ;YACH,OAAO,EAAE,CAAC;iBACP,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CACP,6DAA6D,CAC9D;YACH,KAAK,EAAE,CAAC;iBACL,MAAM,EAAE;iBACR,GAAG,EAAE;iBACL,GAAG,CAAC,CAAC,CAAC;iBACN,GAAG,CAAC,EAAE,CAAC;iBACP,QAAQ,EAAE;iBACV,OAAO,CAAC,CAAC,CAAC;iBACV,QAAQ,CAAC,4CAA4C,CAAC;SAC1D;KACF,EACD,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE;QACtC,MAAM,gBAAgB,GAA2B;YAC/C,OAAO,EAAE,wCAAwC,IAAI;;;sCAGvB,MAAM,CAAC,KAAK,CAAC;;;;;;;;wDAQK;YAEhD,YAAY,EAAE,gCAAgC,OAAO,IAAI,MAAM,SAAS,IAAI;;;oCAGhD,OAAO,IAAI,MAAM;;;;;;;;yDAQI;YAEjD,aAAa,EAAE,4BAA4B,OAAO,IAAI,EAAE,SAAS,IAAI;;;sCAGvC,OAAO,IAAI,EAAE;;;;;;;;wDAQK;YAEhD,cAAc,EAAE,yCAAyC,IAAI;;;;;;;;;;;qEAWA;YAE7D,gBAAgB,EAAE,oCAAoC,IAAI;;;;;;;;;;;gEAWF;SACzD,CAAC;QAEF,MAAM,UAAU,GACd,gBAAgB,CAAC,SAAS,CAAC;YAC3B,YAAY,SAAS,mBAAmB,IAAI,IAAI,CAAC;QAEnD,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE;wBACP,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,UAAU;qBACjB;iBACF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"filesystem-query.js","sourceRoot":"","sources":["../../src/prompts/filesystem-query.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"find-duplicates.d.ts","sourceRoot":"","sources":["../../src/prompts/find-duplicates.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMzE,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA8EpE"}
1
+ {"version":3,"file":"find-duplicates.d.ts","sourceRoot":"","sources":["../../src/prompts/find-duplicates.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AASzE,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAgFpE"}
@@ -1,68 +1,77 @@
1
1
  import { completable } from '@modelcontextprotocol/sdk/server/completable.js';
2
2
  import { z } from 'zod';
3
- import { getAllowedDirectories } from '../lib/path-validation.js';
3
+ import { buildExcludes, pathCompleter } from './shared.js';
4
+ // Extended excludes for duplicate scanning (adds minified/bundled files to base excludes)
5
+ const DUPLICATE_EXCLUDES = buildExcludes('minified', 'bundled');
4
6
  export function registerFindDuplicatesPrompt(server) {
5
7
  server.registerPrompt('find-duplicates', {
6
- description: 'Find duplicate or similar code patterns, files, and potential refactoring opportunities',
8
+ description: 'Find duplicate code, similar patterns, and refactoring opportunities',
7
9
  argsSchema: {
8
- path: completable(z.string().min(1).describe('Root path to search for duplicates'), (value) => {
9
- const dirs = getAllowedDirectories();
10
- return dirs.filter((d) => d.toLowerCase().includes(value.toLowerCase()) ||
11
- value.toLowerCase().includes(d.toLowerCase().slice(0, 10)));
12
- }),
10
+ path: completable(z.string().min(1).describe('Root path to search'), pathCompleter),
13
11
  pattern: z
14
12
  .string()
15
13
  .optional()
16
14
  .default('**/*.{ts,js,tsx,jsx,py,java}')
17
- .describe('Glob pattern for files to check (default: source files)'),
15
+ .describe('Source file glob pattern'),
18
16
  searchTerm: z
19
17
  .string()
20
18
  .optional()
21
- .describe('Optional specific pattern or function name to find duplicates of'),
19
+ .describe('Specific function/pattern to find duplicates of'),
20
+ minLines: z
21
+ .number()
22
+ .int()
23
+ .min(2)
24
+ .max(50)
25
+ .optional()
26
+ .default(5)
27
+ .describe('Minimum lines to consider as duplicate (default: 5)'),
22
28
  },
23
- }, ({ path, pattern, searchTerm }) => ({
24
- messages: [
25
- {
26
- role: 'user',
27
- content: {
28
- type: 'text',
29
- text: `Find duplicate code and refactoring opportunities in "${path}".
29
+ }, ({ path, pattern, searchTerm, minLines }) => {
30
+ const excludePatterns = JSON.stringify(DUPLICATE_EXCLUDES);
31
+ const searchInstructions = searchTerm
32
+ ? `\`search_content\` pattern="${searchTerm}" contextLines=2 → find all occurrences`
33
+ : `\`search_content\` → find duplicates using these patterns:
34
+ - Function signatures: \`(export )?(async )?(function|const)\\s+\\w+\`
35
+ - Import blocks: \`^import .+ from\`
36
+ - Error handlers: \`catch\\s*\\(\` or \`\\.catch\\(\`
37
+ - Repeated utility patterns: loops, conditionals, API calls`;
38
+ return {
39
+ messages: [
40
+ {
41
+ role: 'user',
42
+ content: {
43
+ type: 'text',
44
+ text: `Find duplicate code in "${path}".
30
45
 
31
- Use the available filesystem tools:
46
+ ⚠️ First run \`list_allowed_directories\` to verify path is accessible.
32
47
 
33
- 1. **File Discovery**
34
- - Use \`search_files\` with pattern "${pattern}" to find all relevant files
35
- - Use \`analyze_directory\` to identify files of similar sizes (potential duplicates)
48
+ **Workflow:**
49
+ 1. \`search_files\` pattern="${pattern}" excludePatterns=${excludePatterns}
50
+ 2. \`analyze_directory\` excludePatterns=${excludePatterns} identify similar-sized files (potential copies)
51
+ 3. ${searchInstructions}
52
+ 4. \`read_multiple_files\` → batch compare suspect files
36
53
 
37
- 2. **Content Analysis**
38
- ${searchTerm
39
- ? `- Use \`search_content\` to find all occurrences of "${searchTerm}"`
40
- : `- Use \`search_content\` to find common duplicate patterns:
41
- - Similar function signatures
42
- - Repeated import statements
43
- - Common utility patterns (error handling, logging, validation)
44
- - Copied configuration blocks`}
54
+ **Duplicate Detection Criteria (minimum ${minLines} lines):**
55
+ - Code blocks that are character-for-character identical
56
+ - Code with only variable/parameter name differences
57
+ - Structural duplicates: same logic, different formatting
45
58
 
46
- 3. **Detailed Inspection**
47
- - Use \`read_multiple_files\` to compare files with similar sizes or names
48
- - Look for:
49
- - Copy-pasted code blocks
50
- - Functions with similar logic but different names
51
- - Repeated patterns that could be abstracted
52
- - Similar error handling or validation logic
59
+ **Report Format:**
60
+ | Category | Description |
61
+ |----------|-------------|
62
+ | **Exact duplicates** | Identical code blocks with file:line locations |
63
+ | **Near duplicates** | 80%+ similar code, highlight differences |
64
+ | **Extractable patterns** | Repeated logic → shared utility/hook candidates |
65
+ | **Refactoring plan** | Priority order, files affected, breaking change risks |
53
66
 
54
- 4. **Report Findings**
55
- - **Exact Duplicates**: Files or code blocks that are identical
56
- - **Near Duplicates**: Similar code with minor variations
57
- - **Pattern Opportunities**: Repeated patterns that could be abstracted into utilities
58
- - **Refactoring Suggestions**: Specific recommendations with:
59
- - Which files are affected
60
- - Proposed abstraction or consolidation
61
- - Estimated complexity reduction
62
- - Potential risks of refactoring`,
67
+ **For each duplicate found, provide:**
68
+ 1. File locations (all occurrences)
69
+ 2. Code snippet (first occurrence)
70
+ 3. Suggested abstraction (function name, module location)`,
71
+ },
63
72
  },
64
- },
65
- ],
66
- }));
73
+ ],
74
+ };
75
+ });
67
76
  }
68
77
  //# sourceMappingURL=find-duplicates.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"find-duplicates.js","sourceRoot":"","sources":["../../src/prompts/find-duplicates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iDAAiD,CAAC;AAG9E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAElE,MAAM,UAAU,4BAA4B,CAAC,MAAiB;IAC5D,MAAM,CAAC,cAAc,CACnB,iBAAiB,EACjB;QACE,WAAW,EACT,yFAAyF;QAC3F,UAAU,EAAE;YACV,IAAI,EAAE,WAAW,CACf,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,oCAAoC,CAAC,EAChE,CAAC,KAAK,EAAE,EAAE;gBACR,MAAM,IAAI,GAAG,qBAAqB,EAAE,CAAC;gBACrC,OAAO,IAAI,CAAC,MAAM,CAChB,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;oBAC7C,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAC7D,CAAC;YACJ,CAAC,CACF;YACD,OAAO,EAAE,CAAC;iBACP,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,OAAO,CAAC,8BAA8B,CAAC;iBACvC,QAAQ,CAAC,yDAAyD,CAAC;YACtE,UAAU,EAAE,CAAC;iBACV,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CACP,kEAAkE,CACnE;SACJ;KACF,EACD,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;QAClC,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE;oBACP,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,yDAAyD,IAAI;;;;;0CAKrC,OAAO;;;;KAK5C,UAAU;wBACR,CAAC,CAAC,wDAAwD,UAAU,GAAG;wBACvE,CAAC,CAAC;;;;mCAKN;;;;;;;;;;;;;;;;;;sCAkBmC;iBAC3B;aACF;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"find-duplicates.js","sourceRoot":"","sources":["../../src/prompts/find-duplicates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iDAAiD,CAAC;AAG9E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE3D,0FAA0F;AAC1F,MAAM,kBAAkB,GAAG,aAAa,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;AAEhE,MAAM,UAAU,4BAA4B,CAAC,MAAiB;IAC5D,MAAM,CAAC,cAAc,CACnB,iBAAiB,EACjB;QACE,WAAW,EACT,sEAAsE;QACxE,UAAU,EAAE;YACV,IAAI,EAAE,WAAW,CACf,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EACjD,aAAa,CACd;YACD,OAAO,EAAE,CAAC;iBACP,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,OAAO,CAAC,8BAA8B,CAAC;iBACvC,QAAQ,CAAC,0BAA0B,CAAC;YACvC,UAAU,EAAE,CAAC;iBACV,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,iDAAiD,CAAC;YAC9D,QAAQ,EAAE,CAAC;iBACR,MAAM,EAAE;iBACR,GAAG,EAAE;iBACL,GAAG,CAAC,CAAC,CAAC;iBACN,GAAG,CAAC,EAAE,CAAC;iBACP,QAAQ,EAAE;iBACV,OAAO,CAAC,CAAC,CAAC;iBACV,QAAQ,CAAC,qDAAqD,CAAC;SACnE;KACF,EACD,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE;QAC1C,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;QAE3D,MAAM,kBAAkB,GAAG,UAAU;YACnC,CAAC,CAAC,+BAA+B,UAAU,yCAAyC;YACpF,CAAC,CAAC;;;;4DAIkD,CAAC;QAEvD,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE;wBACP,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,2BAA2B,IAAI;;;;;+BAKpB,OAAO,qBAAqB,eAAe;2CAC/B,eAAe;KACrD,kBAAkB;;;0CAGmB,QAAQ;;;;;;;;;;;;;;;;0DAgBQ;qBAC7C;iBACF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"project-overview.d.ts","sourceRoot":"","sources":["../../src/prompts/project-overview.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMzE,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAyDrE"}
1
+ {"version":3,"file":"project-overview.d.ts","sourceRoot":"","sources":["../../src/prompts/project-overview.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA4CzE,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA+FrE"}