@equilateral_ai/mindmeld 3.1.2 ā 3.2.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.
- package/hooks/pre-compact.js +28 -11
- package/hooks/session-start.js +10 -2
- package/package.json +2 -1
- package/scripts/harvest.js +59 -19
- package/scripts/init-project.js +80 -14
- package/scripts/inject.js +30 -9
- package/scripts/repo-analyzer.js +870 -0
package/hooks/pre-compact.js
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
const path = require('path');
|
|
18
18
|
const fs = require('fs').promises;
|
|
19
|
+
const crypto = require('crypto');
|
|
19
20
|
|
|
20
21
|
// LLM Pattern Detection (optional - requires ANTHROPIC_API_KEY)
|
|
21
22
|
let LLMPatternDetector = null;
|
|
@@ -200,7 +201,11 @@ async function checkMindmeldConfiguration() {
|
|
|
200
201
|
const mindmeldConfig = path.join(process.cwd(), '.mindmeld', 'config.json');
|
|
201
202
|
await fs.access(mindmeldConfig);
|
|
202
203
|
return true;
|
|
203
|
-
} catch {
|
|
204
|
+
} catch (error) {
|
|
205
|
+
// Expected: config doesn't exist
|
|
206
|
+
if (error.code !== 'ENOENT') {
|
|
207
|
+
console.error('Unexpected error checking MindMeld config:', error.message);
|
|
208
|
+
}
|
|
204
209
|
return false;
|
|
205
210
|
}
|
|
206
211
|
}
|
|
@@ -248,10 +253,10 @@ async function checkPromotionCandidates(mindmeld, validPatterns) {
|
|
|
248
253
|
}
|
|
249
254
|
|
|
250
255
|
/**
|
|
251
|
-
* Generate session ID
|
|
256
|
+
* Generate session ID using crypto for consistency
|
|
252
257
|
*/
|
|
253
258
|
function generateSessionId() {
|
|
254
|
-
return `session_${Date.now()}_${
|
|
259
|
+
return `session_${Date.now()}_${crypto.randomBytes(6).toString('hex')}`;
|
|
255
260
|
}
|
|
256
261
|
|
|
257
262
|
/**
|
|
@@ -261,8 +266,11 @@ function parseSessionTranscript(input) {
|
|
|
261
266
|
if (typeof input === 'string') {
|
|
262
267
|
try {
|
|
263
268
|
return JSON.parse(input);
|
|
264
|
-
} catch {
|
|
265
|
-
//
|
|
269
|
+
} catch (error) {
|
|
270
|
+
// Expected: not valid JSON, treat as raw transcript text
|
|
271
|
+
if (!(error instanceof SyntaxError)) {
|
|
272
|
+
console.error('Unexpected error parsing transcript:', error.message);
|
|
273
|
+
}
|
|
266
274
|
return {
|
|
267
275
|
transcript: input,
|
|
268
276
|
sessionId: generateSessionId()
|
|
@@ -329,11 +337,17 @@ async function generatePostCompactContext(summary, llmAnalysis) {
|
|
|
329
337
|
}
|
|
330
338
|
sections.push('');
|
|
331
339
|
}
|
|
332
|
-
} catch {
|
|
333
|
-
//
|
|
340
|
+
} catch (error) {
|
|
341
|
+
// Expected: no index file
|
|
342
|
+
if (error.code !== 'ENOENT' && !(error instanceof SyntaxError)) {
|
|
343
|
+
console.error('Unexpected error reading standards index:', error.message);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
} catch (error) {
|
|
347
|
+
// Expected: no standards directory
|
|
348
|
+
if (error.code !== 'ENOENT') {
|
|
349
|
+
console.error('Unexpected error accessing standards:', error.message);
|
|
334
350
|
}
|
|
335
|
-
} catch {
|
|
336
|
-
// No standards directory - that's OK
|
|
337
351
|
}
|
|
338
352
|
|
|
339
353
|
// Load project-specific patterns from .mindmeld if available
|
|
@@ -349,8 +363,11 @@ async function generatePostCompactContext(summary, llmAnalysis) {
|
|
|
349
363
|
sections.push('**Team**: ' + config.team.map(t => t.name || t.email).join(', '));
|
|
350
364
|
}
|
|
351
365
|
sections.push('');
|
|
352
|
-
} catch {
|
|
353
|
-
//
|
|
366
|
+
} catch (error) {
|
|
367
|
+
// Expected: no mindmeld config
|
|
368
|
+
if (error.code !== 'ENOENT' && !(error instanceof SyntaxError)) {
|
|
369
|
+
console.error('Unexpected error reading mindmeld config:', error.message);
|
|
370
|
+
}
|
|
354
371
|
}
|
|
355
372
|
|
|
356
373
|
sections.push('---');
|
package/hooks/session-start.js
CHANGED
|
@@ -45,7 +45,11 @@ async function loadFingerprintConfig() {
|
|
|
45
45
|
companyId: config.company_id || process.env.MINDMELD_COMPANY_ID || 'unknown',
|
|
46
46
|
tier: config.subscription_tier || process.env.MINDMELD_TIER || 'free'
|
|
47
47
|
};
|
|
48
|
-
} catch {
|
|
48
|
+
} catch (error) {
|
|
49
|
+
// Expected: config doesn't exist or invalid JSON
|
|
50
|
+
if (error.code !== 'ENOENT' && !(error instanceof SyntaxError)) {
|
|
51
|
+
console.error('Unexpected error loading fingerprint config:', error.message);
|
|
52
|
+
}
|
|
49
53
|
// Fallback to environment variables
|
|
50
54
|
return {
|
|
51
55
|
userId: process.env.MINDMELD_USER_ID || 'anonymous',
|
|
@@ -136,7 +140,11 @@ async function checkMindmeldConfiguration() {
|
|
|
136
140
|
const mindmeldConfig = path.join(process.cwd(), '.mindmeld', 'config.json');
|
|
137
141
|
await fs.access(mindmeldConfig);
|
|
138
142
|
return true;
|
|
139
|
-
} catch {
|
|
143
|
+
} catch (error) {
|
|
144
|
+
// Expected: config doesn't exist
|
|
145
|
+
if (error.code !== 'ENOENT') {
|
|
146
|
+
console.error('Unexpected error checking MindMeld config:', error.message);
|
|
147
|
+
}
|
|
140
148
|
return false;
|
|
141
149
|
}
|
|
142
150
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@equilateral_ai/mindmeld",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "Intelligent standards injection for AI coding sessions - context-aware, self-documenting, scales to large codebases",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"scripts/init-project.js",
|
|
13
13
|
"scripts/inject.js",
|
|
14
14
|
"scripts/harvest.js",
|
|
15
|
+
"scripts/repo-analyzer.js",
|
|
15
16
|
"README.md"
|
|
16
17
|
],
|
|
17
18
|
"publishConfig": {
|
package/scripts/harvest.js
CHANGED
|
@@ -71,13 +71,27 @@ async function getGitHistory(projectPath, options = {}) {
|
|
|
71
71
|
try {
|
|
72
72
|
const { stdout: log } = await execAsync(
|
|
73
73
|
`git log --since="${since}" -n ${maxCommits} --format="%H|%s|%an|%ai" --stat`,
|
|
74
|
-
{ cwd: projectPath, maxBuffer: 1024 * 1024 }
|
|
74
|
+
{ cwd: projectPath, maxBuffer: 10 * 1024 * 1024 }
|
|
75
75
|
);
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
77
|
+
// For large repos, limit diff output to avoid buffer overflow
|
|
78
|
+
let diff = '';
|
|
79
|
+
try {
|
|
80
|
+
const { stdout } = await execAsync(
|
|
81
|
+
`git log --since="${since}" -n ${maxCommits} -p --diff-filter=M -- '*.js' '*.ts' '*.py' '*.java' '*.go' '*.rs'`,
|
|
82
|
+
{ cwd: projectPath, maxBuffer: 20 * 1024 * 1024 }
|
|
83
|
+
);
|
|
84
|
+
diff = stdout;
|
|
85
|
+
} catch (diffError) {
|
|
86
|
+
// If diff is too large, try with fewer commits
|
|
87
|
+
if (diffError.message.includes('maxBuffer')) {
|
|
88
|
+
const { stdout } = await execAsync(
|
|
89
|
+
`git log --since="${since}" -n 10 -p --diff-filter=M -- '*.js' '*.ts'`,
|
|
90
|
+
{ cwd: projectPath, maxBuffer: 10 * 1024 * 1024 }
|
|
91
|
+
);
|
|
92
|
+
diff = stdout;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
81
95
|
|
|
82
96
|
return { log, diff };
|
|
83
97
|
} catch (error) {
|
|
@@ -268,8 +282,11 @@ async function harvest(options = {}) {
|
|
|
268
282
|
console.error('\n[MindMeld] LLM-powered detection available for deeper analysis.');
|
|
269
283
|
console.error('[MindMeld] Set MINDMELD_USE_LLM=true for semantic pattern detection.');
|
|
270
284
|
}
|
|
271
|
-
} catch {
|
|
272
|
-
// LLM module not available
|
|
285
|
+
} catch (error) {
|
|
286
|
+
// Expected: LLM module not available
|
|
287
|
+
if (error.code !== 'MODULE_NOT_FOUND') {
|
|
288
|
+
console.error('Unexpected error loading LLM module:', error.message);
|
|
289
|
+
}
|
|
273
290
|
}
|
|
274
291
|
}
|
|
275
292
|
|
|
@@ -304,8 +321,11 @@ async function promotePatterns(projectPath, patterns, options = {}) {
|
|
|
304
321
|
try {
|
|
305
322
|
await fs.access(filePath);
|
|
306
323
|
continue;
|
|
307
|
-
} catch {
|
|
308
|
-
//
|
|
324
|
+
} catch (error) {
|
|
325
|
+
// Expected: file doesn't exist, safe to create
|
|
326
|
+
if (error.code !== 'ENOENT') {
|
|
327
|
+
console.error(`Unexpected error checking ${filePath}:`, error.message);
|
|
328
|
+
}
|
|
309
329
|
}
|
|
310
330
|
|
|
311
331
|
const content = [
|
|
@@ -358,7 +378,11 @@ async function harvestPlans(projectPath) {
|
|
|
358
378
|
const indexContent = await fs.readFile(sessionIndexPath, 'utf-8');
|
|
359
379
|
const index = JSON.parse(indexContent);
|
|
360
380
|
sessions = index.entries || [];
|
|
361
|
-
} catch {
|
|
381
|
+
} catch (error) {
|
|
382
|
+
// Expected: no sessions file
|
|
383
|
+
if (error.code !== 'ENOENT' && !(error instanceof SyntaxError)) {
|
|
384
|
+
console.error('Unexpected error reading sessions:', error.message);
|
|
385
|
+
}
|
|
362
386
|
return []; // No sessions found for this project
|
|
363
387
|
}
|
|
364
388
|
|
|
@@ -383,7 +407,11 @@ async function harvestPlans(projectPath) {
|
|
|
383
407
|
planFiles.push({ path: filePath, name: entry, mtime });
|
|
384
408
|
}
|
|
385
409
|
}
|
|
386
|
-
} catch {
|
|
410
|
+
} catch (error) {
|
|
411
|
+
// Expected: no plans directory
|
|
412
|
+
if (error.code !== 'ENOENT') {
|
|
413
|
+
console.error('Unexpected error reading plans:', error.message);
|
|
414
|
+
}
|
|
387
415
|
return []; // No plans directory
|
|
388
416
|
}
|
|
389
417
|
|
|
@@ -409,8 +437,11 @@ async function harvestPlans(projectPath) {
|
|
|
409
437
|
try {
|
|
410
438
|
await fs.access(path.join(projectPath, cleanRef));
|
|
411
439
|
relevance += 3; // File exists in this project
|
|
412
|
-
} catch {
|
|
413
|
-
//
|
|
440
|
+
} catch (error) {
|
|
441
|
+
// Expected: file doesn't exist here
|
|
442
|
+
if (error.code !== 'ENOENT') {
|
|
443
|
+
console.error(`Unexpected error checking ${cleanRef}:`, error.message);
|
|
444
|
+
}
|
|
414
445
|
}
|
|
415
446
|
}
|
|
416
447
|
|
|
@@ -422,8 +453,11 @@ async function harvestPlans(projectPath) {
|
|
|
422
453
|
planFile.content = content;
|
|
423
454
|
relevantPlans.push(planFile);
|
|
424
455
|
}
|
|
425
|
-
} catch {
|
|
426
|
-
//
|
|
456
|
+
} catch (error) {
|
|
457
|
+
// Expected: file not readable
|
|
458
|
+
if (error.code !== 'ENOENT' && error.code !== 'EACCES') {
|
|
459
|
+
console.error(`Unexpected error reading plan ${planFile.path}:`, error.message);
|
|
460
|
+
}
|
|
427
461
|
}
|
|
428
462
|
}
|
|
429
463
|
|
|
@@ -484,8 +518,11 @@ async function harvestPlans(projectPath) {
|
|
|
484
518
|
});
|
|
485
519
|
}
|
|
486
520
|
}
|
|
487
|
-
} catch {
|
|
488
|
-
//
|
|
521
|
+
} catch (error) {
|
|
522
|
+
// Expected: file not readable
|
|
523
|
+
if (error.code !== 'ENOENT' && error.code !== 'EACCES') {
|
|
524
|
+
console.error(`Unexpected error processing plan:`, error.message);
|
|
525
|
+
}
|
|
489
526
|
}
|
|
490
527
|
}
|
|
491
528
|
|
|
@@ -526,8 +563,11 @@ async function promoteDecisions(projectPath, decisions, options = {}) {
|
|
|
526
563
|
try {
|
|
527
564
|
await fs.access(filePath);
|
|
528
565
|
continue;
|
|
529
|
-
} catch {
|
|
530
|
-
//
|
|
566
|
+
} catch (error) {
|
|
567
|
+
// Expected: file doesn't exist, safe to create
|
|
568
|
+
if (error.code !== 'ENOENT') {
|
|
569
|
+
console.error(`Unexpected error checking ${filePath}:`, error.message);
|
|
570
|
+
}
|
|
531
571
|
}
|
|
532
572
|
|
|
533
573
|
const content = [
|
package/scripts/init-project.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* mindmeld harvest # Capture patterns from git history
|
|
9
9
|
* mindmeld logout # Clear stored authentication
|
|
10
10
|
*
|
|
11
|
-
* @equilateral_ai/mindmeld v3.
|
|
11
|
+
* @equilateral_ai/mindmeld v3.2.0
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
const fs = require('fs').promises;
|
|
@@ -55,7 +55,11 @@ function loadAuth() {
|
|
|
55
55
|
try {
|
|
56
56
|
const data = fsSync.readFileSync(CONFIG.authFile, 'utf-8');
|
|
57
57
|
return JSON.parse(data);
|
|
58
|
-
} catch {
|
|
58
|
+
} catch (error) {
|
|
59
|
+
// Expected: auth file doesn't exist yet
|
|
60
|
+
if (error.code !== 'ENOENT' && !(error instanceof SyntaxError)) {
|
|
61
|
+
console.error('Unexpected error loading auth:', error.message);
|
|
62
|
+
}
|
|
59
63
|
return null;
|
|
60
64
|
}
|
|
61
65
|
}
|
|
@@ -75,8 +79,11 @@ async function saveAuth(auth) {
|
|
|
75
79
|
async function clearAuth() {
|
|
76
80
|
try {
|
|
77
81
|
await fs.unlink(CONFIG.authFile);
|
|
78
|
-
} catch {
|
|
79
|
-
//
|
|
82
|
+
} catch (error) {
|
|
83
|
+
// Expected: file doesn't exist
|
|
84
|
+
if (error.code !== 'ENOENT') {
|
|
85
|
+
console.error('Unexpected error clearing auth:', error.message);
|
|
86
|
+
}
|
|
80
87
|
}
|
|
81
88
|
}
|
|
82
89
|
|
|
@@ -301,7 +308,11 @@ async function openBrowser(url) {
|
|
|
301
308
|
try {
|
|
302
309
|
await execAsync(command);
|
|
303
310
|
return true;
|
|
304
|
-
} catch {
|
|
311
|
+
} catch (error) {
|
|
312
|
+
// Expected: browser command not available on some systems
|
|
313
|
+
if (error.code !== 'ENOENT' && !error.message.includes('spawn')) {
|
|
314
|
+
console.error('Unexpected error opening browser:', error.message);
|
|
315
|
+
}
|
|
305
316
|
return false;
|
|
306
317
|
}
|
|
307
318
|
}
|
|
@@ -419,7 +430,11 @@ function callApi(method, endpoint, token, body = null) {
|
|
|
419
430
|
} else {
|
|
420
431
|
resolve({ success: false, error: parsed.message || parsed.error || 'API error', status: res.statusCode });
|
|
421
432
|
}
|
|
422
|
-
} catch {
|
|
433
|
+
} catch (error) {
|
|
434
|
+
// Expected: API returned non-JSON response
|
|
435
|
+
if (!(error instanceof SyntaxError)) {
|
|
436
|
+
console.error('Unexpected error parsing API response:', error.message);
|
|
437
|
+
}
|
|
423
438
|
resolve({ success: false, error: data, status: res.statusCode });
|
|
424
439
|
}
|
|
425
440
|
});
|
|
@@ -538,7 +553,15 @@ async function initProject(projectPath) {
|
|
|
538
553
|
|
|
539
554
|
console.log('\nšÆ MindMeld CLI\n');
|
|
540
555
|
|
|
541
|
-
// 1.
|
|
556
|
+
// 1. Analyze repository first (shows value immediately)
|
|
557
|
+
console.log('š Analyzing your repository...\n');
|
|
558
|
+
const { RepoAnalyzer } = require('./repo-analyzer');
|
|
559
|
+
const analyzer = new RepoAnalyzer(projectPath);
|
|
560
|
+
const analysis = await analyzer.analyze({ verbose: false });
|
|
561
|
+
console.log(analyzer.getSummary());
|
|
562
|
+
|
|
563
|
+
// 2. Authenticate
|
|
564
|
+
console.log('\n');
|
|
542
565
|
const auth = await ensureAuth();
|
|
543
566
|
console.log(`ā
Authenticated as ${auth.email}\n`);
|
|
544
567
|
|
|
@@ -604,7 +627,11 @@ async function initProject(projectPath) {
|
|
|
604
627
|
console.log('Aborted.');
|
|
605
628
|
process.exit(0);
|
|
606
629
|
}
|
|
607
|
-
} catch {
|
|
630
|
+
} catch (error) {
|
|
631
|
+
// Expected: config doesn't exist (not initialized)
|
|
632
|
+
if (error.code !== 'ENOENT') {
|
|
633
|
+
console.error('Unexpected error checking config:', error.message);
|
|
634
|
+
}
|
|
608
635
|
// Not initialized, continue
|
|
609
636
|
}
|
|
610
637
|
|
|
@@ -665,7 +692,11 @@ async function initProject(projectPath) {
|
|
|
665
692
|
});
|
|
666
693
|
console.log('');
|
|
667
694
|
}
|
|
668
|
-
} catch {
|
|
695
|
+
} catch (error) {
|
|
696
|
+
// Expected: not a git repo or git not available
|
|
697
|
+
if (!error.message.includes('not a git repository') && error.code !== 'ENOENT') {
|
|
698
|
+
console.error('Unexpected error reading git history:', error.message);
|
|
699
|
+
}
|
|
669
700
|
console.log('ā¹ļø No git history found (not a git repo or no commits)\n');
|
|
670
701
|
}
|
|
671
702
|
|
|
@@ -680,16 +711,35 @@ async function initProject(projectPath) {
|
|
|
680
711
|
subscriptionTier: tier,
|
|
681
712
|
collaborators,
|
|
682
713
|
created: new Date().toISOString(),
|
|
683
|
-
mindmeldVersion: '3.
|
|
714
|
+
mindmeldVersion: '3.2.0',
|
|
715
|
+
// Rich analysis results
|
|
716
|
+
techStack: analysis.techStack,
|
|
717
|
+
structure: analysis.structure,
|
|
718
|
+
documentation: analysis.documentation.map(d => d.relativePath),
|
|
719
|
+
securitySummary: analysis.securityFindings.summary,
|
|
720
|
+
recommendations: analysis.recommendations
|
|
684
721
|
};
|
|
685
722
|
|
|
686
723
|
await fs.writeFile(configPath, JSON.stringify(config, null, 2));
|
|
687
724
|
|
|
725
|
+
// Save full analysis separately
|
|
726
|
+
const analysisPath = path.join(mindmeldDir, 'analysis.json');
|
|
727
|
+
await fs.writeFile(analysisPath, JSON.stringify(analysis, null, 2));
|
|
728
|
+
|
|
688
729
|
console.log('ā
MindMeld initialized!\n');
|
|
689
730
|
console.log(` Config: ${configPath}`);
|
|
731
|
+
console.log(` Analysis: ${path.join(mindmeldDir, 'analysis.json')}`);
|
|
690
732
|
console.log(` Project ID: ${config.projectId}`);
|
|
691
733
|
console.log(` User: ${auth.email}`);
|
|
692
734
|
console.log(` Plan: ${tier}`);
|
|
735
|
+
|
|
736
|
+
// Show tech-specific standards that will be injected
|
|
737
|
+
if (analysis.recommendations.length > 0) {
|
|
738
|
+
console.log('\nš¦ Standards packs to be injected:');
|
|
739
|
+
for (const rec of analysis.recommendations.filter(r => r.standardsPack)) {
|
|
740
|
+
console.log(` - ${rec.standardsPack}: ${rec.description}`);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
693
743
|
console.log('');
|
|
694
744
|
|
|
695
745
|
// 9. Check for community standards
|
|
@@ -697,7 +747,11 @@ async function initProject(projectPath) {
|
|
|
697
747
|
try {
|
|
698
748
|
await fs.access(standardsDir);
|
|
699
749
|
console.log('ā¹ļø Community standards (.equilateral-standards) available');
|
|
700
|
-
} catch {
|
|
750
|
+
} catch (error) {
|
|
751
|
+
// Expected: standards dir doesn't exist
|
|
752
|
+
if (error.code !== 'ENOENT') {
|
|
753
|
+
console.error('Unexpected error checking standards:', error.message);
|
|
754
|
+
}
|
|
701
755
|
if (tier !== 'free') {
|
|
702
756
|
try {
|
|
703
757
|
await execAsync(
|
|
@@ -705,7 +759,11 @@ async function initProject(projectPath) {
|
|
|
705
759
|
{ cwd: projectPath }
|
|
706
760
|
);
|
|
707
761
|
console.log('ā
Cloned community standards repo');
|
|
708
|
-
} catch {
|
|
762
|
+
} catch (cloneError) {
|
|
763
|
+
// Expected: git not available or network issues
|
|
764
|
+
if (cloneError.code !== 'ENOENT' && !cloneError.message.includes('Could not resolve')) {
|
|
765
|
+
console.error('Unexpected error cloning standards:', cloneError.message);
|
|
766
|
+
}
|
|
709
767
|
console.log('ā¹ļø Community standards not available (clone from:');
|
|
710
768
|
console.log(' https://github.com/Equilateral-AI/EquilateralAgents-Community-Standards)');
|
|
711
769
|
}
|
|
@@ -792,7 +850,11 @@ async function configureClaudeHooks(projectPath) {
|
|
|
792
850
|
try {
|
|
793
851
|
await fs.access(sessionStartHook);
|
|
794
852
|
await fs.access(preCompactHook);
|
|
795
|
-
} catch {
|
|
853
|
+
} catch (error) {
|
|
854
|
+
// Expected: hooks not found in package
|
|
855
|
+
if (error.code !== 'ENOENT') {
|
|
856
|
+
console.error('Unexpected error checking hooks:', error.message);
|
|
857
|
+
}
|
|
796
858
|
console.log('ā ļø Hook scripts not found in package. Skipping hook configuration.');
|
|
797
859
|
console.log(` Expected at: ${packageRoot}/hooks/`);
|
|
798
860
|
return;
|
|
@@ -821,7 +883,11 @@ async function configureClaudeHooks(projectPath) {
|
|
|
821
883
|
try {
|
|
822
884
|
const existing = await fs.readFile(settingsPath, 'utf-8');
|
|
823
885
|
settings = JSON.parse(existing);
|
|
824
|
-
} catch {
|
|
886
|
+
} catch (error) {
|
|
887
|
+
// Expected: settings file doesn't exist yet
|
|
888
|
+
if (error.code !== 'ENOENT' && !(error instanceof SyntaxError)) {
|
|
889
|
+
console.error('Unexpected error reading settings:', error.message);
|
|
890
|
+
}
|
|
825
891
|
// No existing settings
|
|
826
892
|
}
|
|
827
893
|
|
package/scripts/inject.js
CHANGED
|
@@ -83,8 +83,11 @@ async function detectProjectContext(projectPath) {
|
|
|
83
83
|
}
|
|
84
84
|
context.frameworks.push(...check.frameworks);
|
|
85
85
|
context.files.push(check.file);
|
|
86
|
-
} catch {
|
|
87
|
-
//
|
|
86
|
+
} catch (error) {
|
|
87
|
+
// Expected: file doesn't exist
|
|
88
|
+
if (error.code !== 'ENOENT' && error.code !== 'EACCES') {
|
|
89
|
+
console.error(`Unexpected error checking ${check.file}:`, error.message);
|
|
90
|
+
}
|
|
88
91
|
}
|
|
89
92
|
}
|
|
90
93
|
|
|
@@ -96,8 +99,11 @@ async function detectProjectContext(projectPath) {
|
|
|
96
99
|
if (deps['express'] || deps['fastify']) context.frameworks.push('api');
|
|
97
100
|
if (deps['@aws-sdk']) context.frameworks.push('aws');
|
|
98
101
|
if (deps['pg'] || deps['mysql2'] || deps['mongoose']) context.frameworks.push('database');
|
|
99
|
-
} catch {
|
|
100
|
-
//
|
|
102
|
+
} catch (error) {
|
|
103
|
+
// Expected: no package.json or invalid JSON
|
|
104
|
+
if (error.code !== 'ENOENT' && !(error instanceof SyntaxError)) {
|
|
105
|
+
console.error('Unexpected error reading package.json:', error.message);
|
|
106
|
+
}
|
|
101
107
|
}
|
|
102
108
|
|
|
103
109
|
return context;
|
|
@@ -112,7 +118,11 @@ async function getRelevantStandards(projectPath, context) {
|
|
|
112
118
|
|
|
113
119
|
try {
|
|
114
120
|
await fs.access(standardsDir);
|
|
115
|
-
} catch {
|
|
121
|
+
} catch (error) {
|
|
122
|
+
// Expected: standards dir doesn't exist
|
|
123
|
+
if (error.code !== 'ENOENT') {
|
|
124
|
+
console.error('Unexpected error accessing standards:', error.message);
|
|
125
|
+
}
|
|
116
126
|
return [];
|
|
117
127
|
}
|
|
118
128
|
|
|
@@ -135,8 +145,11 @@ async function getRelevantStandards(projectPath, context) {
|
|
|
135
145
|
path: relativePath,
|
|
136
146
|
score: 0
|
|
137
147
|
});
|
|
138
|
-
} catch {
|
|
139
|
-
//
|
|
148
|
+
} catch (error) {
|
|
149
|
+
// Expected: file not readable
|
|
150
|
+
if (error.code !== 'ENOENT' && error.code !== 'EACCES') {
|
|
151
|
+
console.error(`Unexpected error reading ${fullPath}:`, error.message);
|
|
152
|
+
}
|
|
140
153
|
}
|
|
141
154
|
}
|
|
142
155
|
}
|
|
@@ -194,7 +207,11 @@ async function loadTeamPatterns(projectPath) {
|
|
|
194
207
|
collaborators: config.collaborators || [],
|
|
195
208
|
team: config.team || false
|
|
196
209
|
};
|
|
197
|
-
} catch {
|
|
210
|
+
} catch (error) {
|
|
211
|
+
// Expected: config doesn't exist or invalid JSON
|
|
212
|
+
if (error.code !== 'ENOENT' && !(error instanceof SyntaxError)) {
|
|
213
|
+
console.error('Unexpected error loading team patterns:', error.message);
|
|
214
|
+
}
|
|
198
215
|
return {
|
|
199
216
|
projectName: path.basename(projectPath),
|
|
200
217
|
collaborators: [],
|
|
@@ -360,7 +377,11 @@ async function inject(options = {}) {
|
|
|
360
377
|
recentLearning: [],
|
|
361
378
|
collaborators: projectInfo.collaborators || []
|
|
362
379
|
});
|
|
363
|
-
} catch {
|
|
380
|
+
} catch (error) {
|
|
381
|
+
// Expected: module not found in standalone mode
|
|
382
|
+
if (error.code !== 'MODULE_NOT_FOUND') {
|
|
383
|
+
console.error('Unexpected error with claude format:', error.message);
|
|
384
|
+
}
|
|
364
385
|
output = formatRaw(standards, projectInfo, context);
|
|
365
386
|
}
|
|
366
387
|
break;
|