@aion0/forge 0.6.0 → 0.6.1

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/RELEASE_NOTES.md CHANGED
@@ -1,8 +1,11 @@
1
- # Forge v0.6.0
1
+ # Forge v0.6.1
2
2
 
3
3
  Released: 2026-04-28
4
4
 
5
- ## Changes since v0.5.50
5
+ ## Changes since v0.6.0
6
6
 
7
+ ### Other
8
+ - fix(server): daemonize standalones in \`forge server start\` (background)
7
9
 
8
- **Full Changelog**: https://github.com/aiwatching/forge/compare/v0.5.50...v0.6.0
10
+
11
+ **Full Changelog**: https://github.com/aiwatching/forge/compare/v0.6.0...v0.6.1
@@ -314,42 +314,41 @@ function cleanupOrphans() {
314
314
  // ── Start standalone services (single instance each) ──
315
315
  const services = [];
316
316
 
317
- function startServices() {
317
+ // When forge runs in the background, services need to fully detach from the
318
+ // invoking shell. Otherwise: closing that shell sends SIGHUP to its process
319
+ // group → terminal-standalone / telegram / workspace die → all browser
320
+ // terminals disconnect.
321
+ //
322
+ // `daemonize` (passed by startBackground) flips on:
323
+ // - detached: true → new process group, survives parent SIGHUP
324
+ // - stdio redirected to forge.log fds (no inherited tty fds that go away)
325
+ // - child.unref() → child doesn't keep the launcher alive
326
+ function startServices(daemonize = false) {
318
327
  cleanupOrphans();
319
328
 
320
329
  const instanceTag = `--forge-port=${webPort}`;
330
+ const stdio = daemonize
331
+ ? ['ignore', openSync(LOG_FILE, 'a'), openSync(LOG_FILE, 'a')]
332
+ : ['ignore', 'inherit', 'inherit'];
333
+ const detached = daemonize;
334
+
335
+ const spawnService = (label, script) => {
336
+ const child = spawn('npx', ['tsx', script, instanceTag], {
337
+ cwd: ROOT,
338
+ stdio,
339
+ detached,
340
+ env: { ...process.env },
341
+ });
342
+ if (daemonize) child.unref();
343
+ services.push(child);
344
+ console.log(`[forge] ${label} started (pid: ${child.pid})`);
345
+ return child;
346
+ };
321
347
 
322
- // Terminal server
323
- const termScript = join(ROOT, 'lib', 'terminal-standalone.ts');
324
- const termChild = spawn('npx', ['tsx', termScript, instanceTag], {
325
- cwd: ROOT,
326
- stdio: ['ignore', 'inherit', 'inherit'],
327
- env: { ...process.env },
328
- });
329
- services.push(termChild);
330
- console.log(`[forge] Terminal server started (pid: ${termChild.pid})`);
331
-
332
- // Telegram bot
333
- const telegramScript = join(ROOT, 'lib', 'telegram-standalone.ts');
334
- const telegramChild = spawn('npx', ['tsx', telegramScript, instanceTag], {
335
- cwd: ROOT,
336
- stdio: ['ignore', 'inherit', 'inherit'],
337
- env: { ...process.env },
338
- });
339
- services.push(telegramChild);
340
- console.log(`[forge] Telegram bot started (pid: ${telegramChild.pid})`);
341
-
342
- // Workspace daemon
343
- const workspaceScript = join(ROOT, 'lib', 'workspace-standalone.ts');
344
- const workspaceChild = spawn('npx', ['tsx', workspaceScript, instanceTag], {
345
- cwd: ROOT,
346
- stdio: ['ignore', 'inherit', 'inherit'],
347
- env: { ...process.env },
348
- });
349
- services.push(workspaceChild);
350
- console.log(`[forge] Workspace daemon started (pid: ${workspaceChild.pid})`);
348
+ spawnService('Terminal server', join(ROOT, 'lib', 'terminal-standalone.ts'));
349
+ spawnService('Telegram bot', join(ROOT, 'lib', 'telegram-standalone.ts'));
350
+ spawnService('Workspace daemon', join(ROOT, 'lib', 'workspace-standalone.ts'));
351
351
 
352
- // Track all child PIDs for clean shutdown
353
352
  const childPids = services.map(c => c.pid).filter(Boolean);
354
353
  savePids(childPids);
355
354
  }
@@ -426,8 +425,9 @@ function startBackground() {
426
425
  protectedPids.add(String(child.pid));
427
426
  child.unref();
428
427
 
429
- // Start services in background too (cleanupOrphans will skip protectedPids)
430
- startServices();
428
+ // Start services in background too detached so closing the launcher's
429
+ // shell can't take the daemons (and all attached browser terminals) down.
430
+ startServices(true);
431
431
 
432
432
  console.log(`[forge] Started in background (pid ${child.pid})`);
433
433
  if (!getArg('--port')) {
package/next-env.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /// <reference types="next" />
2
2
  /// <reference types="next/image-types/global" />
3
- import "./.next/dev/types/routes.d.ts";
3
+ import "./.next/types/routes.d.ts";
4
4
 
5
5
  // NOTE: This file should not be edited
6
6
  // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aion0/forge",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "description": "Unified AI workflow platform — multi-model task orchestration, persistent sessions, web terminal, remote access",
5
5
  "type": "module",
6
6
  "scripts": {