bgrun 3.10.1 → 3.10.2

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.
@@ -0,0 +1,50 @@
1
+ /**
2
+ * POST /api/guard — Toggle BGR_KEEP_ALIVE for a process
3
+ * Body: { name: string, enabled: boolean }
4
+ *
5
+ * When enabled=true, the built-in guard will auto-restart this process if it dies.
6
+ * When enabled=false, the process is left alone.
7
+ */
8
+ import { getProcess, updateProcessEnv } from '../../../src/db';
9
+
10
+ export async function POST(req: Request) {
11
+ try {
12
+ const body = await req.json() as { name: string; enabled: boolean };
13
+ if (!body.name) {
14
+ return Response.json({ error: 'Missing process name' }, { status: 400 });
15
+ }
16
+
17
+ const proc = getProcess(body.name);
18
+ if (!proc) {
19
+ return Response.json({ error: `Process "${body.name}" not found` }, { status: 404 });
20
+ }
21
+
22
+ // Parse existing env
23
+ let env: Record<string, string> = {};
24
+ if (proc.env) {
25
+ try { env = JSON.parse(proc.env); } catch { env = {}; }
26
+ }
27
+
28
+ // Toggle BGR_KEEP_ALIVE
29
+ if (body.enabled) {
30
+ env.BGR_KEEP_ALIVE = 'true';
31
+ } else {
32
+ delete env.BGR_KEEP_ALIVE;
33
+ }
34
+
35
+ // Save back
36
+ updateProcessEnv(body.name, JSON.stringify(env));
37
+
38
+ return Response.json({
39
+ ok: true,
40
+ name: body.name,
41
+ guarded: body.enabled
42
+ });
43
+ } catch (err: any) {
44
+ return Response.json({ error: err.message }, { status: 500 });
45
+ }
46
+ }
47
+
48
+ export async function GET() {
49
+ return Response.json({ error: 'Use POST to toggle guard' }, { status: 405 });
50
+ }
package/dist/index.js CHANGED
@@ -406,6 +406,7 @@ var init_utils = __esm(() => {
406
406
  var exports_db = {};
407
407
  __export(exports_db, {
408
408
  updateProcessPid: () => updateProcessPid,
409
+ updateProcessEnv: () => updateProcessEnv,
409
410
  retryDatabaseOperation: () => retryDatabaseOperation,
410
411
  removeProcessByName: () => removeProcessByName,
411
412
  removeProcess: () => removeProcess,
@@ -459,6 +460,12 @@ function removeAllProcesses() {
459
460
  db.process.delete(p.id);
460
461
  }
461
462
  }
463
+ function updateProcessEnv(name, envJson) {
464
+ const proc = db.process.select().where({ name }).limit(1).get();
465
+ if (proc) {
466
+ db.process.update(proc.id, { env: envJson });
467
+ }
468
+ }
462
469
  function getDbInfo() {
463
470
  return {
464
471
  dbPath,
@@ -753,9 +760,18 @@ function startGuard() {
753
760
  for (const proc of processes) {
754
761
  if (GUARD_SKIP_NAMES.has(proc.name))
755
762
  continue;
763
+ const env = proc.env ? typeof proc.env === "string" ? (() => {
764
+ try {
765
+ return JSON.parse(proc.env);
766
+ } catch {
767
+ return {};
768
+ }
769
+ })() : proc.env : {};
770
+ if (env.BGR_KEEP_ALIVE !== "true")
771
+ continue;
756
772
  const alive = await isProcessRunning(proc.pid, proc.command);
757
773
  if (!alive) {
758
- console.log(`[guard] \u26A0 Process "${proc.name}" (PID ${proc.pid}) is dead, restarting...`);
774
+ console.log(`[guard] \u26A0 Guarded process "${proc.name}" (PID ${proc.pid}) is dead, restarting...`);
759
775
  try {
760
776
  await handleRun({
761
777
  action: "run",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bgrun",
3
- "version": "3.10.1",
3
+ "version": "3.10.2",
4
4
  "description": "bgrun — A lightweight process manager for Bun",
5
5
  "type": "module",
6
6
  "main": "./src/api.ts",
package/src/db.ts CHANGED
@@ -119,6 +119,14 @@ export function removeAllProcesses() {
119
119
  }
120
120
  }
121
121
 
122
+ /** Update the stored env JSON for a process (used by guard toggle) */
123
+ export function updateProcessEnv(name: string, envJson: string) {
124
+ const proc = db.process.select().where({ name }).limit(1).get();
125
+ if (proc) {
126
+ db.process.update(proc.id, { env: envJson });
127
+ }
128
+ }
129
+
122
130
  // =============================================================================
123
131
  // DEBUG / INFO
124
132
  // =============================================================================
package/src/server.ts CHANGED
@@ -44,15 +44,15 @@ export async function startServer() {
44
44
  * Built-in Process Guard
45
45
  *
46
46
  * Runs as a background loop inside the dashboard process.
47
- * Every GUARD_INTERVAL_MS, it checks all registered bgrun processes.
48
- * If any process is dead (PID not running), it auto-restarts it using
49
- * handleRun with force=true (same as `bgrun --restart <name>`).
47
+ * Every GUARD_INTERVAL_MS, checks processes with BGR_KEEP_ALIVE=true
48
+ * in their env and auto-restarts any that died.
50
49
  *
51
- * Why here and not as a separate process?
52
- * - No external dependency the dashboard IS the guardian
53
- * - If the dashboard is running, all processes are monitored
54
- * - If the dashboard dies, `bgrun --dashboard` will restart everything
55
- * - Zero configuration just works
50
+ * Only guarded processes (opted-in via dashboard toggle or env var) are
51
+ * monitored. Other processes are left alone even if they crash.
52
+ *
53
+ * Toggle guard per-process:
54
+ * - Dashboard UI: click the shield icon on any process row
55
+ * - CLI: set BGR_KEEP_ALIVE=true in the process env/config
56
56
  */
57
57
  function startGuard() {
58
58
  console.log(`[guard] ✓ Built-in process guard started (checking every ${GUARD_INTERVAL_MS / 1000}s)`);
@@ -66,9 +66,13 @@ function startGuard() {
66
66
  // Skip the dashboard itself
67
67
  if (GUARD_SKIP_NAMES.has(proc.name)) continue;
68
68
 
69
+ // Only guard processes with BGR_KEEP_ALIVE=true
70
+ const env = proc.env ? (typeof proc.env === 'string' ? (() => { try { return JSON.parse(proc.env); } catch { return {}; } })() : proc.env) : {};
71
+ if (env.BGR_KEEP_ALIVE !== 'true') continue;
72
+
69
73
  const alive = await isProcessRunning(proc.pid, proc.command);
70
74
  if (!alive) {
71
- console.log(`[guard] ⚠ Process "${proc.name}" (PID ${proc.pid}) is dead, restarting...`);
75
+ console.log(`[guard] ⚠ Guarded process "${proc.name}" (PID ${proc.pid}) is dead, restarting...`);
72
76
  try {
73
77
  await handleRun({
74
78
  action: 'run',