bonzai-burn 1.0.25 → 1.0.27

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 (21) hide show
  1. package/package.json +3 -2
  2. package/payload-bonzai/config.json +7 -0
  3. package/src/analyzer.js +150 -19
  4. package/src/bburn.js +0 -2
  5. package/src/bgraph.js +1 -1
  6. /package/{payload-bonzai/graph-templates → graph-templates}/config.js +0 -0
  7. /package/{payload-bonzai/graph-templates → graph-templates}/handlers/delete.js +0 -0
  8. /package/{payload-bonzai/graph-templates → graph-templates}/handlers/git.js +0 -0
  9. /package/{payload-bonzai/graph-templates → graph-templates}/handlers/index.js +0 -0
  10. /package/{payload-bonzai/graph-templates → graph-templates}/handlers/list.js +0 -0
  11. /package/{payload-bonzai/graph-templates → graph-templates}/handlers/open-cursor.js +0 -0
  12. /package/{payload-bonzai/graph-templates → graph-templates}/handlers/read.js +0 -0
  13. /package/{payload-bonzai/graph-templates → graph-templates}/handlers/scan_code_quality.js +0 -0
  14. /package/{payload-bonzai/graph-templates → graph-templates}/handlers/shutdown.js +0 -0
  15. /package/{payload-bonzai/graph-templates → graph-templates}/handlers/terminal.js +0 -0
  16. /package/{payload-bonzai/graph-templates → graph-templates}/handlers/write.js +0 -0
  17. /package/{payload-bonzai/graph-templates → graph-templates}/ignore.txt +0 -0
  18. /package/{payload-bonzai/graph-templates → graph-templates}/receiver.js +0 -0
  19. /package/{payload-bonzai/graph-templates → graph-templates}/utils/fileList.js +0 -0
  20. /package/{payload-bonzai/graph-templates → graph-templates}/utils/ignore.js +0 -0
  21. /package/{payload-bonzai/graph-templates → graph-templates}/utils/parsers.js +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bonzai-burn",
3
- "version": "1.0.25",
3
+ "version": "1.0.27",
4
4
  "description": "Git branch-based cleanup tool with bburn, baccept, and brevert commands",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -20,7 +20,8 @@
20
20
  },
21
21
  "files": [
22
22
  "src",
23
- "payload-bonzai"
23
+ "payload-bonzai",
24
+ "graph-templates"
24
25
  ],
25
26
  "dependencies": {
26
27
  "@modelcontextprotocol/sdk": "^1.25.3"
@@ -2,6 +2,13 @@
2
2
  "customChecks": {
3
3
  "requirements": "Remove unused imports and variables. Remove all console log statements."
4
4
  },
5
+ "eslint": {
6
+ "enabled": true,
7
+ "rules": ["no-unused-vars"]
8
+ },
9
+ "typescript": {
10
+ "enabled": true
11
+ },
5
12
  "lineLimit": {
6
13
  "enabled": true,
7
14
  "limit": 300,
package/src/analyzer.js CHANGED
@@ -7,6 +7,92 @@ import path from 'path';
7
7
  * Runs ESLint, TypeScript, and custom checks based on config.json
8
8
  */
9
9
 
10
+ /**
11
+ * Check if a command exists
12
+ */
13
+ function commandExists(cmd) {
14
+ try {
15
+ execSync(`which ${cmd}`, { encoding: 'utf-8', stdio: 'pipe' });
16
+ return true;
17
+ } catch {
18
+ return false;
19
+ }
20
+ }
21
+
22
+ /**
23
+ * Check if package is installed locally
24
+ */
25
+ function isInstalledLocally(pkg, rootDir) {
26
+ return fs.existsSync(path.join(rootDir, 'node_modules', pkg));
27
+ }
28
+
29
+ /**
30
+ * Install a package as dev dependency
31
+ */
32
+ function installPackage(pkg, rootDir) {
33
+ try {
34
+ console.log(` Installing ${pkg}...`);
35
+ execSync(`cd "${rootDir}" && npm install --save-dev ${pkg}`, {
36
+ encoding: 'utf-8',
37
+ stdio: 'pipe'
38
+ });
39
+ return true;
40
+ } catch (e) {
41
+ return false;
42
+ }
43
+ }
44
+
45
+ /**
46
+ * Ensure ESLint is available
47
+ */
48
+ function ensureEslint(rootDir, config) {
49
+ const cfg = config.eslint || {};
50
+ if (!cfg.enabled) {
51
+ return { available: false, reason: 'Disabled in config' };
52
+ }
53
+
54
+ // Check if eslint exists globally or locally
55
+ if (commandExists('eslint') || isInstalledLocally('eslint', rootDir)) {
56
+ return { available: true };
57
+ }
58
+
59
+ // Try to install
60
+ console.log('📦 ESLint not found, installing...');
61
+ if (installPackage('eslint', rootDir)) {
62
+ return { available: true, installed: true };
63
+ }
64
+
65
+ return { available: false, reason: 'Failed to install ESLint' };
66
+ }
67
+
68
+ /**
69
+ * Ensure TypeScript is available
70
+ */
71
+ function ensureTypeScript(rootDir, config) {
72
+ const cfg = config.typescript || {};
73
+ if (!cfg.enabled) {
74
+ return { available: false, reason: 'Disabled in config' };
75
+ }
76
+
77
+ // Check if tsconfig exists (otherwise no point)
78
+ if (!fs.existsSync(path.join(rootDir, 'tsconfig.json'))) {
79
+ return { available: false, reason: 'No tsconfig.json found' };
80
+ }
81
+
82
+ // Check if tsc exists globally or locally
83
+ if (commandExists('tsc') || isInstalledLocally('typescript', rootDir)) {
84
+ return { available: true };
85
+ }
86
+
87
+ // Try to install
88
+ console.log('📦 TypeScript not found, installing...');
89
+ if (installPackage('typescript', rootDir)) {
90
+ return { available: true, installed: true };
91
+ }
92
+
93
+ return { available: false, reason: 'Failed to install TypeScript' };
94
+ }
95
+
10
96
  /**
11
97
  * List all files recursively, respecting common ignore patterns
12
98
  */
@@ -44,18 +130,26 @@ function listAllFiles(dir, basePath = '') {
44
130
  /**
45
131
  * Run ESLint to detect unused imports and variables
46
132
  */
47
- function runEslintAnalysis(rootDir) {
133
+ function runEslintAnalysis(rootDir, config) {
48
134
  const issues = [];
135
+ const cfg = config.eslint || {};
49
136
 
50
- try {
51
- execSync('which eslint', { encoding: 'utf-8', stdio: 'pipe' });
52
- } catch {
53
- return { issues, skipped: true, reason: 'ESLint not installed' };
137
+ if (!cfg.enabled) {
138
+ return { issues, skipped: true, reason: 'Disabled in config' };
54
139
  }
55
140
 
141
+ // Build rules from config
142
+ const rules = cfg.rules || ['no-unused-vars'];
143
+ const ruleArgs = rules.map(r => `--rule "${r}: error"`).join(' ');
144
+
145
+ // Try local eslint first, then global
146
+ const eslintCmd = isInstalledLocally('eslint', rootDir)
147
+ ? `"${path.join(rootDir, 'node_modules', '.bin', 'eslint')}"`
148
+ : 'eslint';
149
+
56
150
  try {
57
151
  const result = execSync(
58
- `eslint "${rootDir}" --format json --rule "no-unused-vars: error" 2>/dev/null || true`,
152
+ `${eslintCmd} "${rootDir}" --format json ${ruleArgs} --ignore-pattern node_modules --ignore-pattern bonzai 2>/dev/null || true`,
59
153
  { encoding: 'utf-8', stdio: 'pipe', maxBuffer: 50 * 1024 * 1024 }
60
154
  );
61
155
 
@@ -64,7 +158,7 @@ function runEslintAnalysis(rootDir) {
64
158
 
65
159
  for (const file of eslintOutput) {
66
160
  for (const msg of file.messages || []) {
67
- if (msg.ruleId && msg.ruleId.includes('no-unused')) {
161
+ if (msg.ruleId && rules.some(r => msg.ruleId.includes(r.replace('no-', '')))) {
68
162
  issues.push({
69
163
  file: path.relative(rootDir, file.filePath),
70
164
  line: msg.line,
@@ -85,23 +179,27 @@ function runEslintAnalysis(rootDir) {
85
179
  /**
86
180
  * Run TypeScript compiler to check for unused locals
87
181
  */
88
- function runTypeScriptAnalysis(rootDir) {
182
+ function runTypeScriptAnalysis(rootDir, config) {
89
183
  const issues = [];
90
- const tsconfigPath = path.join(rootDir, 'tsconfig.json');
184
+ const cfg = config.typescript || {};
185
+
186
+ if (!cfg.enabled) {
187
+ return { issues, skipped: true, reason: 'Disabled in config' };
188
+ }
91
189
 
190
+ const tsconfigPath = path.join(rootDir, 'tsconfig.json');
92
191
  if (!fs.existsSync(tsconfigPath)) {
93
192
  return { issues, skipped: true, reason: 'No tsconfig.json found' };
94
193
  }
95
194
 
96
- try {
97
- execSync('which tsc', { encoding: 'utf-8', stdio: 'pipe' });
98
- } catch {
99
- return { issues, skipped: true, reason: 'TypeScript not installed' };
100
- }
195
+ // Try local tsc first, then global
196
+ const tscCmd = isInstalledLocally('typescript', rootDir)
197
+ ? `"${path.join(rootDir, 'node_modules', '.bin', 'tsc')}"`
198
+ : 'tsc';
101
199
 
102
200
  try {
103
201
  const result = execSync(
104
- `cd "${rootDir}" && tsc --noEmit --noUnusedLocals --noUnusedParameters 2>&1 || true`,
202
+ `cd "${rootDir}" && ${tscCmd} --noEmit --noUnusedLocals --noUnusedParameters 2>&1 || true`,
105
203
  { encoding: 'utf-8', stdio: 'pipe', maxBuffer: 50 * 1024 * 1024 }
106
204
  );
107
205
 
@@ -256,10 +354,42 @@ function checkMissingTests(files, config) {
256
354
  export async function analyze(rootDir = process.cwd(), config = {}) {
257
355
  const startTime = Date.now();
258
356
  const files = listAllFiles(rootDir);
357
+ const toolStatus = {};
358
+
359
+ // Ensure tools are available (auto-install if needed)
360
+ console.log('🔧 Checking tools...');
361
+
362
+ const eslintStatus = ensureEslint(rootDir, config);
363
+ toolStatus.eslint = eslintStatus;
364
+ if (eslintStatus.installed) {
365
+ console.log(' ✓ ESLint installed');
366
+ } else if (eslintStatus.available) {
367
+ console.log(' ✓ ESLint ready');
368
+ } else if (config.eslint?.enabled) {
369
+ console.log(` ✗ ESLint: ${eslintStatus.reason}`);
370
+ }
371
+
372
+ const tsStatus = ensureTypeScript(rootDir, config);
373
+ toolStatus.typescript = tsStatus;
374
+ if (tsStatus.installed) {
375
+ console.log(' ✓ TypeScript installed');
376
+ } else if (tsStatus.available) {
377
+ console.log(' ✓ TypeScript ready');
378
+ } else if (config.typescript?.enabled) {
379
+ console.log(` ✗ TypeScript: ${tsStatus.reason}`);
380
+ }
381
+
382
+ console.log('');
383
+
384
+ // Run checks
385
+ const eslint = eslintStatus.available
386
+ ? runEslintAnalysis(rootDir, config)
387
+ : { issues: [], skipped: true, reason: eslintStatus.reason };
388
+
389
+ const typescript = tsStatus.available
390
+ ? runTypeScriptAnalysis(rootDir, config)
391
+ : { issues: [], skipped: true, reason: tsStatus.reason };
259
392
 
260
- // Run all checks
261
- const eslint = runEslintAnalysis(rootDir);
262
- const typescript = runTypeScriptAnalysis(rootDir);
263
393
  const lineLimit = checkLineLimits(files, config);
264
394
  const folderLimit = checkFolderLimits(files, config);
265
395
  const missingTests = checkMissingTests(files, config);
@@ -274,7 +404,8 @@ export async function analyze(rootDir = process.cwd(), config = {}) {
274
404
  missingTests,
275
405
  customRequirements: config.customChecks?.requirements || null,
276
406
  filesScanned: files.length,
277
- durationMs: duration
407
+ durationMs: duration,
408
+ toolStatus
278
409
  };
279
410
  }
280
411
 
package/src/bburn.js CHANGED
@@ -34,8 +34,6 @@ async function main() {
34
34
  // Load config - source of truth
35
35
  const config = loadConfig();
36
36
 
37
- console.log('Scanning...\n');
38
-
39
37
  // Run analysis
40
38
  const results = await analyze(process.cwd(), config);
41
39
  const { output, totalIssues } = formatAnalysisResults(results);
package/src/bgraph.js CHANGED
@@ -8,7 +8,7 @@ const __filename = fileURLToPath(import.meta.url);
8
8
  const __dirname = path.dirname(__filename);
9
9
 
10
10
  // Template folder in the package
11
- const TEMPLATE_DIR = path.join(__dirname, '..', 'payload-bonzai', 'graph-templates');
11
+ const TEMPLATE_DIR = path.join(__dirname, '..', 'graph-templates');
12
12
 
13
13
  // Helper function to recursively copy directory
14
14
  function copyDirectory(src, dest) {