devbonzai 2.0.3 → 2.0.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.
Files changed (2) hide show
  1. package/cli.js +80 -4
  2. package/package.json +1 -1
package/cli.js CHANGED
@@ -64,7 +64,7 @@ const express = require('./node_modules/express');
64
64
  const cors = require('./node_modules/cors');
65
65
  const fs = require('fs');
66
66
  const path = require('path');
67
- const { exec, spawn } = require('child_process');
67
+ const { exec, spawn, execSync } = require('child_process');
68
68
  let babelParser = null;
69
69
  try {
70
70
  babelParser = require('./node_modules/@babel/parser');
@@ -92,6 +92,7 @@ app.get('/', (req, res) => {
92
92
  'POST /move': 'Move file or folder (body: {source, destination})',
93
93
  'POST /open-cursor': 'Open Cursor (body: {path, line?})',
94
94
  'POST /prompt_agent': 'Execute cursor-agent command (body: {prompt})',
95
+ 'POST /revert_job': 'Revert to a previous commit (body: {beforeCommit})',
95
96
  'POST /shutdown': 'Gracefully shutdown the server'
96
97
  },
97
98
  example: 'Try: /list or /read?path=README.md'
@@ -1284,6 +1285,32 @@ app.post('/prompt_agent', (req, res) => {
1284
1285
  return res.status(400).json({ error: 'prompt required' });
1285
1286
  }
1286
1287
 
1288
+ // Capture beforeCommit
1289
+ let beforeCommit = '';
1290
+ try {
1291
+ beforeCommit = execSync('git rev-parse HEAD', { cwd: ROOT }).toString().trim();
1292
+ console.log('🔵 [prompt_agent] beforeCommit:', beforeCommit);
1293
+ } catch (e) {
1294
+ console.log('⚠️ [prompt_agent] Could not get beforeCommit:', e.message);
1295
+ }
1296
+
1297
+ // Set up file change tracking
1298
+ const changedFiles = new Set();
1299
+ const pollInterval = setInterval(() => {
1300
+ try {
1301
+ const status = execSync('git status --short', { cwd: ROOT }).toString();
1302
+ status.split('\\n').filter(Boolean).forEach(line => {
1303
+ const filePath = line.substring(3).trim(); // Remove status prefix (XY + space)
1304
+ if (filePath) changedFiles.add(filePath);
1305
+ });
1306
+ if (changedFiles.size > 0) {
1307
+ console.log('📁 [prompt_agent] Changed files:', Array.from(changedFiles));
1308
+ }
1309
+ } catch (e) {
1310
+ // Ignore git status errors
1311
+ }
1312
+ }, 500);
1313
+
1287
1314
  // Configurable timeout (default 5 minutes)
1288
1315
  const timeoutMs = parseInt(req.body.timeout) || 5 * 60 * 1000;
1289
1316
  let timeoutId = null;
@@ -1312,6 +1339,7 @@ app.post('/prompt_agent', (req, res) => {
1312
1339
  timeoutId = setTimeout(() => {
1313
1340
  if (!responseSent && proc && !proc.killed) {
1314
1341
  console.log('⏱️ [prompt_agent] Timeout reached, killing process...');
1342
+ clearInterval(pollInterval);
1315
1343
  proc.kill('SIGTERM');
1316
1344
 
1317
1345
  // Force kill after a short grace period if SIGTERM doesn't work
@@ -1329,7 +1357,10 @@ app.post('/prompt_agent', (req, res) => {
1329
1357
  message: \`cursor-agent exceeded timeout of \${timeoutMs / 1000} seconds\`,
1330
1358
  code: -1,
1331
1359
  stdout,
1332
- stderr
1360
+ stderr,
1361
+ changedFiles: Array.from(changedFiles),
1362
+ beforeCommit,
1363
+ afterCommit: ''
1333
1364
  });
1334
1365
  }
1335
1366
  }
@@ -1349,6 +1380,7 @@ app.post('/prompt_agent', (req, res) => {
1349
1380
 
1350
1381
  proc.on('error', (error) => {
1351
1382
  console.log('❌ [prompt_agent] Process error:', error.message);
1383
+ clearInterval(pollInterval);
1352
1384
  if (timeoutId) clearTimeout(timeoutId);
1353
1385
  if (!responseSent) {
1354
1386
  responseSent = true;
@@ -1361,8 +1393,19 @@ app.post('/prompt_agent', (req, res) => {
1361
1393
  console.log('🔵 [prompt_agent] stdout length:', stdout.length);
1362
1394
  console.log('🔵 [prompt_agent] stderr length:', stderr.length);
1363
1395
 
1396
+ // Stop polling for file changes
1397
+ clearInterval(pollInterval);
1364
1398
  if (timeoutId) clearTimeout(timeoutId);
1365
1399
 
1400
+ // Capture afterCommit
1401
+ let afterCommit = '';
1402
+ try {
1403
+ afterCommit = execSync('git rev-parse HEAD', { cwd: ROOT }).toString().trim();
1404
+ console.log('🔵 [prompt_agent] afterCommit:', afterCommit);
1405
+ } catch (e) {
1406
+ console.log('⚠️ [prompt_agent] Could not get afterCommit:', e.message);
1407
+ }
1408
+
1366
1409
  if (!responseSent) {
1367
1410
  responseSent = true;
1368
1411
  // Check if process was killed due to timeout
@@ -1372,19 +1415,52 @@ app.post('/prompt_agent', (req, res) => {
1372
1415
  message: signal === 'SIGTERM' ? 'Process was terminated due to timeout' : 'Process was force killed',
1373
1416
  code: code || -1,
1374
1417
  stdout,
1375
- stderr
1418
+ stderr,
1419
+ changedFiles: Array.from(changedFiles),
1420
+ beforeCommit,
1421
+ afterCommit
1376
1422
  });
1377
1423
  } else {
1378
1424
  res.json({
1379
1425
  code,
1380
1426
  stdout,
1381
- stderr
1427
+ stderr,
1428
+ changedFiles: Array.from(changedFiles),
1429
+ beforeCommit,
1430
+ afterCommit
1382
1431
  });
1383
1432
  }
1384
1433
  }
1385
1434
  });
1386
1435
  });
1387
1436
 
1437
+ // Revert job endpoint to reset to a previous commit
1438
+ app.post('/revert_job', (req, res) => {
1439
+ console.log('🔵 [revert_job] Endpoint hit');
1440
+ const { beforeCommit } = req.body;
1441
+
1442
+ if (!beforeCommit || typeof beforeCommit !== 'string') {
1443
+ console.log('❌ [revert_job] Error: beforeCommit required');
1444
+ return res.status(400).json({ error: 'beforeCommit required' });
1445
+ }
1446
+
1447
+ // Validate commit hash format (basic sanitization to prevent command injection)
1448
+ if (!/^[a-f0-9]{7,40}$/i.test(beforeCommit)) {
1449
+ console.log('❌ [revert_job] Error: invalid commit hash format');
1450
+ return res.status(400).json({ error: 'Invalid commit hash format' });
1451
+ }
1452
+
1453
+ try {
1454
+ console.log('🔵 [revert_job] Resetting to commit:', beforeCommit);
1455
+ execSync(\`git reset --hard \${beforeCommit}\`, { cwd: ROOT });
1456
+ console.log('✅ [revert_job] Successfully reverted to commit:', beforeCommit);
1457
+ res.json({ success: true });
1458
+ } catch (e) {
1459
+ console.log('❌ [revert_job] Error:', e.message);
1460
+ res.status(500).json({ error: e.message });
1461
+ }
1462
+ });
1463
+
1388
1464
  // Shutdown endpoint to kill the server
1389
1465
  app.post('/shutdown', (req, res) => {
1390
1466
  console.log('🛑 Shutdown endpoint called - terminating server...');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devbonzai",
3
- "version": "2.0.3",
3
+ "version": "2.0.4",
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": {