@azerate/claudette-mcp 1.8.2 → 1.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/__tests__/logger-setup.test.d.ts +1 -0
- package/dist/__tests__/logger-setup.test.js +183 -0
- package/dist/crawler.js +35 -12
- package/dist/index.js +1 -1
- package/dist/logger-setup.d.ts +2 -0
- package/dist/logger-setup.js +77 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
MCP server for Claudette IDE - providing Claude with 40+ comprehensive workspace management tools.
|
|
4
4
|
|
|
5
|
-
> **v1.8.
|
|
5
|
+
> **v1.8.4** - Fixed `generate_commit_message` tool returning HTML errors instead of JSON by adding the missing `/api/git/changes` endpoint.
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { setupLogger, crawlConsoleLogs, formatCrawlConsoleLogsResult } from '../logger-setup.js';
|
|
2
|
+
import { existsSync, mkdirSync, writeFileSync, rmSync, readFileSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { tmpdir } from 'os';
|
|
5
|
+
describe('logger-setup', () => {
|
|
6
|
+
let testDir;
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
// Create a unique temp directory for each test
|
|
9
|
+
testDir = join(tmpdir(), `logger-setup-test-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
10
|
+
mkdirSync(testDir, { recursive: true });
|
|
11
|
+
});
|
|
12
|
+
afterEach(() => {
|
|
13
|
+
// Clean up
|
|
14
|
+
try {
|
|
15
|
+
rmSync(testDir, { recursive: true, force: true });
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
// Ignore cleanup errors
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
describe('setupLogger', () => {
|
|
22
|
+
it('should create logger file in src/utils directory', () => {
|
|
23
|
+
// Create minimal project structure
|
|
24
|
+
mkdirSync(join(testDir, 'src'), { recursive: true });
|
|
25
|
+
writeFileSync(join(testDir, 'package.json'), JSON.stringify({
|
|
26
|
+
name: 'test-project',
|
|
27
|
+
dependencies: { pino: '^9.0.0' } // Pretend pino is installed
|
|
28
|
+
}));
|
|
29
|
+
writeFileSync(join(testDir, 'tsconfig.json'), '{}');
|
|
30
|
+
const result = setupLogger(testDir);
|
|
31
|
+
expect(result.success).toBe(true);
|
|
32
|
+
// Normalize path separators for cross-platform
|
|
33
|
+
expect(result.loggerPath?.replace(/\\/g, '/')).toBe('src/utils/logger.ts');
|
|
34
|
+
expect(result.alreadyExists).toBe(false);
|
|
35
|
+
expect(existsSync(join(testDir, 'src/utils/logger.ts'))).toBe(true);
|
|
36
|
+
});
|
|
37
|
+
it('should return alreadyExists when logger file exists', () => {
|
|
38
|
+
// Create existing logger
|
|
39
|
+
mkdirSync(join(testDir, 'src/utils'), { recursive: true });
|
|
40
|
+
writeFileSync(join(testDir, 'src/utils/logger.ts'), 'export const logger = {}');
|
|
41
|
+
const result = setupLogger(testDir);
|
|
42
|
+
expect(result.success).toBe(true);
|
|
43
|
+
expect(result.alreadyExists).toBe(true);
|
|
44
|
+
expect(result.loggerPath).toBe('src/utils/logger.ts');
|
|
45
|
+
});
|
|
46
|
+
it('should include bundler warning note in generated logger', () => {
|
|
47
|
+
mkdirSync(join(testDir, 'src'), { recursive: true });
|
|
48
|
+
writeFileSync(join(testDir, 'package.json'), JSON.stringify({
|
|
49
|
+
name: 'test-project',
|
|
50
|
+
dependencies: { pino: '^9.0.0' }
|
|
51
|
+
}));
|
|
52
|
+
writeFileSync(join(testDir, 'tsconfig.json'), '{}');
|
|
53
|
+
setupLogger(testDir);
|
|
54
|
+
const loggerContent = readFileSync(join(testDir, 'src/utils/logger.ts'), 'utf-8');
|
|
55
|
+
expect(loggerContent).toContain('BUNDLER NOTE');
|
|
56
|
+
expect(loggerContent).toContain('pino');
|
|
57
|
+
expect(loggerContent).toContain('pino-pretty');
|
|
58
|
+
expect(loggerContent).toContain('thread-stream');
|
|
59
|
+
expect(loggerContent).toContain('external');
|
|
60
|
+
});
|
|
61
|
+
it('should detect esbuild configs that need pino externalized', () => {
|
|
62
|
+
mkdirSync(join(testDir, 'src'), { recursive: true });
|
|
63
|
+
mkdirSync(join(testDir, 'scripts'), { recursive: true });
|
|
64
|
+
writeFileSync(join(testDir, 'package.json'), JSON.stringify({
|
|
65
|
+
name: 'test-project',
|
|
66
|
+
dependencies: { pino: '^9.0.0' }
|
|
67
|
+
}));
|
|
68
|
+
writeFileSync(join(testDir, 'tsconfig.json'), '{}');
|
|
69
|
+
// Create esbuild config without pino external
|
|
70
|
+
writeFileSync(join(testDir, 'scripts/build-server.js'), `
|
|
71
|
+
import { build } from 'esbuild';
|
|
72
|
+
build({
|
|
73
|
+
entryPoints: ['src/index.ts'],
|
|
74
|
+
external: ['node-pty'],
|
|
75
|
+
});
|
|
76
|
+
`);
|
|
77
|
+
const result = setupLogger(testDir);
|
|
78
|
+
expect(result.success).toBe(true);
|
|
79
|
+
expect(result.bundlerWarning).toBeDefined();
|
|
80
|
+
expect(result.bundlerWarning).toContain('pino');
|
|
81
|
+
expect(result.bundlerWarning).toContain('scripts/build-server.js');
|
|
82
|
+
expect(result.esbuildConfigs).toContain('scripts/build-server.js');
|
|
83
|
+
});
|
|
84
|
+
it('should not warn about esbuild configs that already have pino external', () => {
|
|
85
|
+
mkdirSync(join(testDir, 'src'), { recursive: true });
|
|
86
|
+
mkdirSync(join(testDir, 'scripts'), { recursive: true });
|
|
87
|
+
writeFileSync(join(testDir, 'package.json'), JSON.stringify({
|
|
88
|
+
name: 'test-project',
|
|
89
|
+
dependencies: { pino: '^9.0.0' }
|
|
90
|
+
}));
|
|
91
|
+
writeFileSync(join(testDir, 'tsconfig.json'), '{}');
|
|
92
|
+
// Create esbuild config WITH pino external
|
|
93
|
+
writeFileSync(join(testDir, 'scripts/build-server.js'), `
|
|
94
|
+
import { build } from 'esbuild';
|
|
95
|
+
build({
|
|
96
|
+
entryPoints: ['src/index.ts'],
|
|
97
|
+
external: ['node-pty', 'pino', 'pino-pretty'],
|
|
98
|
+
});
|
|
99
|
+
`);
|
|
100
|
+
const result = setupLogger(testDir);
|
|
101
|
+
expect(result.success).toBe(true);
|
|
102
|
+
expect(result.bundlerWarning).toBeUndefined();
|
|
103
|
+
expect(result.esbuildConfigs).toBeUndefined();
|
|
104
|
+
});
|
|
105
|
+
it('should create JavaScript logger for non-TypeScript projects', () => {
|
|
106
|
+
mkdirSync(join(testDir, 'src'), { recursive: true });
|
|
107
|
+
writeFileSync(join(testDir, 'package.json'), JSON.stringify({
|
|
108
|
+
name: 'test-project',
|
|
109
|
+
dependencies: { pino: '^9.0.0' }
|
|
110
|
+
}));
|
|
111
|
+
// No tsconfig.json = JavaScript project
|
|
112
|
+
const result = setupLogger(testDir);
|
|
113
|
+
expect(result.success).toBe(true);
|
|
114
|
+
// Normalize path separators for cross-platform
|
|
115
|
+
expect(result.loggerPath?.replace(/\\/g, '/')).toBe('src/utils/logger.js');
|
|
116
|
+
expect(existsSync(join(testDir, 'src/utils/logger.js'))).toBe(true);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
describe('crawlConsoleLogs', () => {
|
|
120
|
+
it('should find console.log statements', () => {
|
|
121
|
+
mkdirSync(join(testDir, 'src'), { recursive: true });
|
|
122
|
+
writeFileSync(join(testDir, 'src/index.ts'), `
|
|
123
|
+
console.log('Hello world');
|
|
124
|
+
console.error('Error message');
|
|
125
|
+
`);
|
|
126
|
+
const result = crawlConsoleLogs(testDir);
|
|
127
|
+
expect(result.totalCount).toBe(2);
|
|
128
|
+
expect(result.byType.log).toBe(1);
|
|
129
|
+
expect(result.byType.error).toBe(1);
|
|
130
|
+
});
|
|
131
|
+
it('should not scan node_modules', () => {
|
|
132
|
+
mkdirSync(join(testDir, 'node_modules/some-lib'), { recursive: true });
|
|
133
|
+
writeFileSync(join(testDir, 'node_modules/some-lib/index.js'), `
|
|
134
|
+
console.log('Should not be found');
|
|
135
|
+
`);
|
|
136
|
+
const result = crawlConsoleLogs(testDir);
|
|
137
|
+
expect(result.totalCount).toBe(0);
|
|
138
|
+
});
|
|
139
|
+
it('should suggest logger replacements', () => {
|
|
140
|
+
mkdirSync(join(testDir, 'src'), { recursive: true });
|
|
141
|
+
writeFileSync(join(testDir, 'src/index.ts'), `console.log('message')`);
|
|
142
|
+
const result = crawlConsoleLogs(testDir);
|
|
143
|
+
expect(result.matches.length).toBe(1);
|
|
144
|
+
expect(result.matches[0].suggestedReplacement).toContain('logger.info');
|
|
145
|
+
});
|
|
146
|
+
it('should detect existing logger', () => {
|
|
147
|
+
mkdirSync(join(testDir, 'src/utils'), { recursive: true });
|
|
148
|
+
writeFileSync(join(testDir, 'src/utils/logger.ts'), 'export const logger = {}');
|
|
149
|
+
const result = crawlConsoleLogs(testDir);
|
|
150
|
+
expect(result.hasLogger).toBe(true);
|
|
151
|
+
expect(result.loggerPath).toBe('src/utils/logger.ts');
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
describe('formatCrawlConsoleLogsResult', () => {
|
|
155
|
+
it('should format empty results', () => {
|
|
156
|
+
const result = formatCrawlConsoleLogsResult({
|
|
157
|
+
matches: [],
|
|
158
|
+
totalCount: 0,
|
|
159
|
+
byType: { log: 0, debug: 0, info: 0, warn: 0, error: 0, trace: 0 },
|
|
160
|
+
hasLogger: false,
|
|
161
|
+
});
|
|
162
|
+
expect(result).toContain('No console statements found');
|
|
163
|
+
});
|
|
164
|
+
it('should format results with matches', () => {
|
|
165
|
+
const result = formatCrawlConsoleLogsResult({
|
|
166
|
+
matches: [{
|
|
167
|
+
file: 'src/index.ts',
|
|
168
|
+
line: 5,
|
|
169
|
+
column: 1,
|
|
170
|
+
code: "console.log('test')",
|
|
171
|
+
type: 'log',
|
|
172
|
+
suggestedReplacement: "logger.info('test')",
|
|
173
|
+
}],
|
|
174
|
+
totalCount: 1,
|
|
175
|
+
byType: { log: 1, debug: 0, info: 0, warn: 0, error: 0, trace: 0 },
|
|
176
|
+
hasLogger: false,
|
|
177
|
+
});
|
|
178
|
+
expect(result).toContain('Found **1** console statements');
|
|
179
|
+
expect(result).toContain('console.log: 1');
|
|
180
|
+
expect(result).toContain('src/index.ts:5');
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
});
|
package/dist/crawler.js
CHANGED
|
@@ -5,7 +5,22 @@ import { join, extname, relative } from 'path';
|
|
|
5
5
|
// Default config
|
|
6
6
|
export const DEFAULT_CONFIG = {
|
|
7
7
|
enabled: ['quality', 'security', 'react', 'typescript'],
|
|
8
|
-
ignore: [
|
|
8
|
+
ignore: [
|
|
9
|
+
'node_modules',
|
|
10
|
+
'dist',
|
|
11
|
+
'dist-electron',
|
|
12
|
+
'dist-server',
|
|
13
|
+
'build',
|
|
14
|
+
'.git',
|
|
15
|
+
'coverage',
|
|
16
|
+
'*.min.js',
|
|
17
|
+
'*.map',
|
|
18
|
+
'scripts', // Dev scripts legitimately use console.log
|
|
19
|
+
'hooks', // Claude hooks use console.log for JSON output
|
|
20
|
+
'benchmarks', // Benchmarks use console for reporting
|
|
21
|
+
'templates', // Template files
|
|
22
|
+
'__mocks__', // Test mocks
|
|
23
|
+
],
|
|
9
24
|
include: ['*.ts', '*.tsx', '*.js', '*.jsx'],
|
|
10
25
|
thresholds: {
|
|
11
26
|
maxFileLength: 500,
|
|
@@ -138,7 +153,8 @@ export function findPatternMatches(content, pattern, filePath, rule, severity, m
|
|
|
138
153
|
}
|
|
139
154
|
return issues;
|
|
140
155
|
}
|
|
141
|
-
// Format crawl results for display
|
|
156
|
+
// Format crawl results for display (with output limiting)
|
|
157
|
+
const MAX_ISSUES_TO_SHOW = 50;
|
|
142
158
|
export function formatCrawlResult(result) {
|
|
143
159
|
const { category, issues, scannedFiles, duration } = result;
|
|
144
160
|
let output = `${category.toUpperCase()} CRAWL RESULTS\n`;
|
|
@@ -147,20 +163,24 @@ export function formatCrawlResult(result) {
|
|
|
147
163
|
output += `✅ No issues found!\n`;
|
|
148
164
|
}
|
|
149
165
|
else {
|
|
150
|
-
const errors = issues.filter(i => i.severity === 'error')
|
|
151
|
-
const warnings = issues.filter(i => i.severity === 'warning')
|
|
152
|
-
const infos = issues.filter(i => i.severity === 'info')
|
|
166
|
+
const errors = issues.filter(i => i.severity === 'error');
|
|
167
|
+
const warnings = issues.filter(i => i.severity === 'warning');
|
|
168
|
+
const infos = issues.filter(i => i.severity === 'info');
|
|
153
169
|
output += `Found ${issues.length} issue(s):\n`;
|
|
154
|
-
if (errors > 0)
|
|
155
|
-
output += ` 🔴 ${errors} error(s)\n`;
|
|
156
|
-
if (warnings > 0)
|
|
157
|
-
output += ` 🟡 ${warnings} warning(s)\n`;
|
|
158
|
-
if (infos > 0)
|
|
159
|
-
output += ` 🔵 ${infos} info(s)\n`;
|
|
170
|
+
if (errors.length > 0)
|
|
171
|
+
output += ` 🔴 ${errors.length} error(s)\n`;
|
|
172
|
+
if (warnings.length > 0)
|
|
173
|
+
output += ` 🟡 ${warnings.length} warning(s)\n`;
|
|
174
|
+
if (infos.length > 0)
|
|
175
|
+
output += ` 🔵 ${infos.length} info(s)\n`;
|
|
160
176
|
output += '\n';
|
|
177
|
+
// Prioritize: errors first, then warnings, then info
|
|
178
|
+
// Limit total output to MAX_ISSUES_TO_SHOW
|
|
179
|
+
const prioritizedIssues = [...errors, ...warnings, ...infos].slice(0, MAX_ISSUES_TO_SHOW);
|
|
180
|
+
const skippedCount = issues.length - prioritizedIssues.length;
|
|
161
181
|
// Group by file
|
|
162
182
|
const byFile = new Map();
|
|
163
|
-
for (const issue of
|
|
183
|
+
for (const issue of prioritizedIssues) {
|
|
164
184
|
const existing = byFile.get(issue.file) || [];
|
|
165
185
|
existing.push(issue);
|
|
166
186
|
byFile.set(issue.file, existing);
|
|
@@ -176,6 +196,9 @@ export function formatCrawlResult(result) {
|
|
|
176
196
|
}
|
|
177
197
|
output += '\n';
|
|
178
198
|
}
|
|
199
|
+
if (skippedCount > 0) {
|
|
200
|
+
output += `... and ${skippedCount} more issue(s) not shown (errors/warnings prioritized)\n\n`;
|
|
201
|
+
}
|
|
179
202
|
}
|
|
180
203
|
output += `────────────────────────────────────────\n`;
|
|
181
204
|
output += `Scanned: ${scannedFiles} files in ${duration}ms\n`;
|
package/dist/index.js
CHANGED
|
@@ -1564,7 +1564,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1564
1564
|
return { content: [{ type: "text", text: "Error: workspace_path is required" }] };
|
|
1565
1565
|
}
|
|
1566
1566
|
try {
|
|
1567
|
-
const changesResponse = await fetchApi(`/api/changes?path=${encodeURIComponent(workspacePath)}`);
|
|
1567
|
+
const changesResponse = await fetchApi(`/api/git/changes?path=${encodeURIComponent(workspacePath)}`);
|
|
1568
1568
|
const changes = await changesResponse.json();
|
|
1569
1569
|
let output = `## Changes to Commit\n\n`;
|
|
1570
1570
|
if (changes.staged?.length > 0) {
|
package/dist/logger-setup.d.ts
CHANGED
package/dist/logger-setup.js
CHANGED
|
@@ -20,6 +20,10 @@ const LOGGER_TEMPLATE_TS = `/**
|
|
|
20
20
|
* Environment variables:
|
|
21
21
|
* LOG_LEVEL: 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace' (default: 'info')
|
|
22
22
|
* NODE_ENV: 'development' | 'production' (affects formatting)
|
|
23
|
+
*
|
|
24
|
+
* BUNDLER NOTE (esbuild/webpack):
|
|
25
|
+
* Pino uses worker threads that don't work when bundled. Add these to your
|
|
26
|
+
* bundler's \`external\` array: 'pino', 'pino-pretty', 'thread-stream'
|
|
23
27
|
*/
|
|
24
28
|
|
|
25
29
|
import pino from 'pino'
|
|
@@ -101,6 +105,10 @@ const LOGGER_TEMPLATE_JS = `/**
|
|
|
101
105
|
* Environment variables:
|
|
102
106
|
* LOG_LEVEL: 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace' (default: 'info')
|
|
103
107
|
* NODE_ENV: 'development' | 'production' (affects formatting)
|
|
108
|
+
*
|
|
109
|
+
* BUNDLER NOTE (esbuild/webpack):
|
|
110
|
+
* Pino uses worker threads that don't work when bundled. Add these to your
|
|
111
|
+
* bundler's \`external\` array: 'pino', 'pino-pretty', 'thread-stream'
|
|
104
112
|
*/
|
|
105
113
|
|
|
106
114
|
import pino from 'pino'
|
|
@@ -186,6 +194,40 @@ function getSourceDir(workspacePath) {
|
|
|
186
194
|
}
|
|
187
195
|
return 'src'; // Default to src
|
|
188
196
|
}
|
|
197
|
+
/**
|
|
198
|
+
* Find esbuild config files that may need pino externalized
|
|
199
|
+
*/
|
|
200
|
+
function findEsbuildConfigs(workspacePath) {
|
|
201
|
+
const configs = [];
|
|
202
|
+
const possiblePaths = [
|
|
203
|
+
'scripts/build-server.js',
|
|
204
|
+
'scripts/build-electron.js',
|
|
205
|
+
'scripts/build.js',
|
|
206
|
+
'esbuild.config.js',
|
|
207
|
+
'esbuild.config.mjs',
|
|
208
|
+
'build.js',
|
|
209
|
+
'build.mjs',
|
|
210
|
+
];
|
|
211
|
+
for (const p of possiblePaths) {
|
|
212
|
+
const fullPath = join(workspacePath, p);
|
|
213
|
+
if (existsSync(fullPath)) {
|
|
214
|
+
// Check if it actually uses esbuild and doesn't already have pino external
|
|
215
|
+
try {
|
|
216
|
+
const content = readFileSync(fullPath, 'utf-8');
|
|
217
|
+
if (content.includes('esbuild') || content.includes('build(') || content.includes('context(')) {
|
|
218
|
+
// Check if pino is already in externals
|
|
219
|
+
if (!content.includes("'pino'") && !content.includes('"pino"')) {
|
|
220
|
+
configs.push(p);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
// Skip unreadable files
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return configs;
|
|
230
|
+
}
|
|
189
231
|
/**
|
|
190
232
|
* Find existing logger file in the project
|
|
191
233
|
*/
|
|
@@ -259,11 +301,20 @@ export function setupLogger(workspacePath) {
|
|
|
259
301
|
console.error('Failed to install pino:', e);
|
|
260
302
|
}
|
|
261
303
|
}
|
|
304
|
+
// Check for esbuild configs that need updating
|
|
305
|
+
const esbuildConfigs = findEsbuildConfigs(workspacePath);
|
|
306
|
+
let bundlerWarning;
|
|
307
|
+
if (esbuildConfigs.length > 0) {
|
|
308
|
+
bundlerWarning = `IMPORTANT: Add 'pino', 'pino-pretty', 'thread-stream' to the external array in: ${esbuildConfigs.join(', ')}. ` +
|
|
309
|
+
`Pino uses worker threads that crash when bundled.`;
|
|
310
|
+
}
|
|
262
311
|
return {
|
|
263
312
|
success: true,
|
|
264
313
|
loggerPath: relativePath,
|
|
265
314
|
installed,
|
|
266
315
|
alreadyExists: false,
|
|
316
|
+
bundlerWarning,
|
|
317
|
+
esbuildConfigs: esbuildConfigs.length > 0 ? esbuildConfigs : undefined,
|
|
267
318
|
};
|
|
268
319
|
}
|
|
269
320
|
catch (err) {
|
|
@@ -326,7 +377,29 @@ export function crawlConsoleLogs(workspacePath) {
|
|
|
326
377
|
const pattern = /console\.(log|debug|info|warn|error|trace)\s*\(([^)]*)\)/g;
|
|
327
378
|
// Get files to scan (reuse crawler logic)
|
|
328
379
|
const extensions = ['.ts', '.tsx', '.js', '.jsx'];
|
|
329
|
-
const ignoreDirs = [
|
|
380
|
+
const ignoreDirs = [
|
|
381
|
+
'node_modules',
|
|
382
|
+
'dist',
|
|
383
|
+
'dist-electron',
|
|
384
|
+
'dist-server',
|
|
385
|
+
'build',
|
|
386
|
+
'.next',
|
|
387
|
+
'coverage',
|
|
388
|
+
'scripts', // Dev scripts legitimately use console.log
|
|
389
|
+
'hooks', // Claude hooks MUST use console.log for JSON output
|
|
390
|
+
'benchmarks', // Benchmarks use console for reporting
|
|
391
|
+
'templates', // Template files
|
|
392
|
+
'__tests__', // Test files
|
|
393
|
+
];
|
|
394
|
+
const ignoreFiles = [
|
|
395
|
+
'vite.config.ts',
|
|
396
|
+
'vite.config.js',
|
|
397
|
+
'jest.config.ts',
|
|
398
|
+
'jest.config.js',
|
|
399
|
+
'vitest.config.ts',
|
|
400
|
+
'vitest.config.js',
|
|
401
|
+
'.eslintrc.js',
|
|
402
|
+
];
|
|
330
403
|
function scanDir(dir) {
|
|
331
404
|
const entries = readdirSync(dir, { withFileTypes: true });
|
|
332
405
|
for (const entry of entries) {
|
|
@@ -338,7 +411,9 @@ export function crawlConsoleLogs(workspacePath) {
|
|
|
338
411
|
}
|
|
339
412
|
else if (entry.isFile()) {
|
|
340
413
|
const ext = entry.name.substring(entry.name.lastIndexOf('.'));
|
|
341
|
-
|
|
414
|
+
const isIgnoredFile = ignoreFiles.includes(entry.name);
|
|
415
|
+
const isTestFile = entry.name.includes('.test.') || entry.name.includes('.spec.');
|
|
416
|
+
if (extensions.includes(ext) && !isIgnoredFile && !isTestFile) {
|
|
342
417
|
scanFile(fullPath);
|
|
343
418
|
}
|
|
344
419
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@azerate/claudette-mcp",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.4",
|
|
4
4
|
"description": "MCP server for Claudette IDE - 40+ tools for TypeScript errors, git changes, workflow automation, testing, benchmarks, refactoring, code quality crawlers, logging setup, checkpoints, memory, and script management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|