devbonzai 2.2.204 → 2.2.206
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devbonzai",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.206",
|
|
4
4
|
"description": "Quickly set up a local file server in any repository for browser-based file access",
|
|
5
5
|
"main": "cli.js",
|
|
6
6
|
"bin": {
|
|
@@ -22,7 +22,6 @@
|
|
|
22
22
|
"author": "",
|
|
23
23
|
"license": "ISC",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@anthropic-ai/sdk": "^0.52.0",
|
|
26
25
|
"express": "^4.18.2",
|
|
27
26
|
"cors": "^2.8.5",
|
|
28
27
|
"body-parser": "^1.20.2",
|
package/templates/config.js
CHANGED
|
@@ -3,9 +3,6 @@ const path = require('path');
|
|
|
3
3
|
// Root directory (one level up from templates/)
|
|
4
4
|
const ROOT = path.join(__dirname, '..');
|
|
5
5
|
|
|
6
|
-
// Anthropic API key for Claude
|
|
7
|
-
const ANTHROPIC_API_KEY = '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';
|
|
8
|
-
|
|
9
6
|
// Initialize babelParser (optional dependency)
|
|
10
7
|
let babelParser = null;
|
|
11
8
|
try {
|
|
@@ -16,7 +13,6 @@ try {
|
|
|
16
13
|
|
|
17
14
|
module.exports = {
|
|
18
15
|
ROOT,
|
|
19
|
-
babelParser
|
|
20
|
-
ANTHROPIC_API_KEY
|
|
16
|
+
babelParser
|
|
21
17
|
};
|
|
22
18
|
|
|
@@ -1,29 +1,33 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const glob = require('glob');
|
|
4
|
-
const {
|
|
4
|
+
const { spawn } = require('child_process');
|
|
5
5
|
const { listAllFiles } = require('../utils/fileList');
|
|
6
6
|
const { getIgnorePatterns, shouldIgnore } = require('../utils/ignore');
|
|
7
|
-
const { ANTHROPIC_API_KEY } = require('../config');
|
|
8
7
|
|
|
9
8
|
module.exports = async function scanStandards(req, res) {
|
|
9
|
+
console.log('🔵 [scan_standards] Endpoint hit');
|
|
10
|
+
|
|
10
11
|
try {
|
|
11
|
-
const { projectPath, standards
|
|
12
|
+
const { projectPath, standards } = req.body;
|
|
13
|
+
console.log('🔵 [scan_standards] projectPath:', projectPath);
|
|
14
|
+
console.log('🔵 [scan_standards] standards:', Array.isArray(standards) ? standards.length + ' rules' : 'string input');
|
|
12
15
|
|
|
13
16
|
if (!projectPath || !standards) {
|
|
17
|
+
console.log('❌ [scan_standards] Error: projectPath and standards required');
|
|
14
18
|
return res.status(400).json({ error: 'projectPath and standards required' });
|
|
15
19
|
}
|
|
16
20
|
|
|
17
|
-
// Use provided apiKey or fall back to config
|
|
18
|
-
const anthropicApiKey = apiKey || ANTHROPIC_API_KEY;
|
|
19
|
-
|
|
20
21
|
// Get file structure for context
|
|
22
|
+
console.log('🔵 [scan_standards] Getting file tree...');
|
|
21
23
|
const fileTree = getFileTree(projectPath);
|
|
24
|
+
console.log('🔵 [scan_standards] File tree entries:', fileTree.split('\n').length);
|
|
22
25
|
|
|
23
26
|
// Sample a few key files for AI to analyze (don't send entire codebase)
|
|
27
|
+
console.log('🔵 [scan_standards] Getting sample files...');
|
|
24
28
|
const sampleFiles = getSampleFiles(projectPath, 10);
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
console.log('🔵 [scan_standards] Sample files found:', sampleFiles.length);
|
|
30
|
+
sampleFiles.forEach(f => console.log(' 📄', f.path, `(${f.size} bytes)`));
|
|
27
31
|
|
|
28
32
|
const prompt = `You are analyzing a codebase for architectural violations.
|
|
29
33
|
|
|
@@ -50,25 +54,72 @@ Respond ONLY with a JSON array of violations:
|
|
|
50
54
|
|
|
51
55
|
If no violations found, return empty array: []`;
|
|
52
56
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
+
console.log('🔵 [scan_standards] Prompt length:', prompt.length, 'chars');
|
|
58
|
+
|
|
59
|
+
// Use cursor-agent like prompt_agent does
|
|
60
|
+
const args = ['--print', '--force', '--workspace', projectPath, prompt];
|
|
61
|
+
console.log('🔵 [scan_standards] Spawning cursor-agent...');
|
|
62
|
+
|
|
63
|
+
const proc = spawn('cursor-agent', args, {
|
|
64
|
+
cwd: projectPath,
|
|
65
|
+
env: process.env,
|
|
66
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
console.log('🔵 [scan_standards] Process spawned, PID:', proc.pid);
|
|
70
|
+
|
|
71
|
+
let stdout = '';
|
|
72
|
+
let stderr = '';
|
|
73
|
+
|
|
74
|
+
proc.stdout.on('data', (d) => {
|
|
75
|
+
const data = d.toString();
|
|
76
|
+
console.log('📤 [scan_standards] stdout chunk:', data.length, 'bytes');
|
|
77
|
+
stdout += data;
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
proc.stderr.on('data', (d) => {
|
|
81
|
+
const data = d.toString();
|
|
82
|
+
console.log('⚠️ [scan_standards] stderr chunk:', data.length, 'bytes');
|
|
83
|
+
stderr += data;
|
|
57
84
|
});
|
|
58
85
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
86
|
+
proc.on('error', (error) => {
|
|
87
|
+
console.error('❌ [scan_standards] Process error:', error.message);
|
|
88
|
+
return res.status(500).json({ error: error.message });
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
proc.on('close', (code) => {
|
|
92
|
+
console.log('🔵 [scan_standards] Process closed with code:', code);
|
|
93
|
+
console.log('🔵 [scan_standards] stdout total:', stdout.length, 'bytes');
|
|
94
|
+
console.log('🔵 [scan_standards] stderr total:', stderr.length, 'bytes');
|
|
95
|
+
|
|
96
|
+
if (code !== 0) {
|
|
97
|
+
console.error('❌ [scan_standards] Failed with code:', code);
|
|
98
|
+
console.error('❌ [scan_standards] stderr:', stderr);
|
|
99
|
+
return res.status(500).json({ error: `Process exited with code ${code}`, stderr });
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Parse AI response
|
|
103
|
+
console.log('🔵 [scan_standards] Parsing response...');
|
|
104
|
+
const jsonMatch = stdout.match(/\[[\s\S]*\]/);
|
|
105
|
+
|
|
106
|
+
if (!jsonMatch) {
|
|
107
|
+
console.log('⚠️ [scan_standards] No JSON array found in response');
|
|
108
|
+
console.log('⚠️ [scan_standards] Raw stdout:', stdout.substring(0, 500));
|
|
109
|
+
}
|
|
63
110
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
111
|
+
try {
|
|
112
|
+
const violations = jsonMatch ? JSON.parse(jsonMatch[0]) : [];
|
|
113
|
+
console.log('✅ [scan_standards] Found', violations.length, 'violations');
|
|
114
|
+
res.json({ violations });
|
|
115
|
+
} catch (parseError) {
|
|
116
|
+
console.error('❌ [scan_standards] JSON parse error:', parseError.message);
|
|
117
|
+
res.status(500).json({ error: 'Failed to parse response', raw: stdout });
|
|
118
|
+
}
|
|
68
119
|
});
|
|
69
120
|
|
|
70
121
|
} catch (error) {
|
|
71
|
-
console.error('
|
|
122
|
+
console.error('❌ [scan_standards] Error:', error.message);
|
|
72
123
|
res.status(500).json({ error: error.message });
|
|
73
124
|
}
|
|
74
125
|
};
|
|
@@ -84,7 +135,7 @@ function getFileTree(projectPath) {
|
|
|
84
135
|
);
|
|
85
136
|
return realFiles.slice(0, 200).join('\n'); // Limit to 200 entries
|
|
86
137
|
} catch (e) {
|
|
87
|
-
console.error('Error getting file tree:', e);
|
|
138
|
+
console.error('❌ [scan_standards] Error getting file tree:', e);
|
|
88
139
|
return 'Unable to read file tree';
|
|
89
140
|
}
|
|
90
141
|
}
|
|
@@ -133,11 +184,3 @@ function getSampleFiles(projectPath, limit = 10) {
|
|
|
133
184
|
.sort((a, b) => b.size - a.size)
|
|
134
185
|
.slice(0, limit);
|
|
135
186
|
}
|
|
136
|
-
|
|
137
|
-
function estimateCost(usage) {
|
|
138
|
-
// Claude Sonnet 4 pricing
|
|
139
|
-
const inputCost = (usage.input_tokens / 1000000) * 3.00;
|
|
140
|
-
const outputCost = (usage.output_tokens / 1000000) * 15.00;
|
|
141
|
-
return (inputCost + outputCost).toFixed(4);
|
|
142
|
-
}
|
|
143
|
-
|