@aion0/forge 0.5.50 → 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,54 +1,11 @@
1
- # Forge v0.5.50
1
+ # Forge v0.6.1
2
2
 
3
3
  Released: 2026-04-28
4
4
 
5
- ## Changes since v0.5.49
6
-
7
- ### Features
8
- - feat: API migration cockpit MVP for legacy → new parity testing
9
-
10
- ### Refactoring
11
- - refactor: remove Migration Cockpit from Forge core (replaced by craft)
12
-
13
- ### Documentation
14
- - feat: API migration cockpit MVP for legacy → new parity testing
5
+ ## Changes since v0.6.0
15
6
 
16
7
  ### Other
17
- - ui(crafts): move hide/close buttons into the terminal panel toolbar
18
- - feat(crafts): multi-file support — recursive bundle + nested file links
19
- - fix(crafts): kill stale-registry display after publish + auto-bust on mutations
20
- - fix(crafts): widen manifest editor 640px → 900px
21
- - feat(crafts): in-Forge manifest editor (bump version etc. without leaving the UI)
22
- - feat(crafts): in-place update + reminder badge in dropdown
23
- - refactor(crafts): drop redundant outer + Craft button
24
- - feat(crafts): add Crafts category to global Marketplace panel
25
- - feat(crafts): one-click publish PR via gh CLI
26
- - fix(crafts): publish flow always uses PR, not direct push
27
- - feat(crafts): publish via GitHub auto-fork (no write access required)
28
- - feat(crafts): marketplace + project-type requires + publish flow
29
- - refactor(crafts): drop file-counter sample, collapse craft tabs into dropdown
30
- - fix(crafts): keep craft tabs (incl. terminal panel) mounted across tab switches
31
- - fix(crafts): list sessions scoped to the craft's cwd, not the project root
32
- - fix(crafts): resume sessionId actually applied — closure staleness
33
- - fix(crafts): always show picker on open + hide vs close split
34
- - fix(crafts): picker re-creates tmux session with chosen --resume
35
- - fix(crafts): keep craft tmux sessions alive across tab switches + restarts
36
- - feat(crafts): terminal closed by default + agent/session picker on first open
37
- - feat(crafts): integrated terminal at bottom of every craft tab
38
- - fix(crafts): agent picker reads agents[] from /api/agents response
39
- - fix(tasks): truncate long task prompt in detail view, click to expand
40
- - feat(crafts): name + agent picker + terminal session as default builder mode
41
- - fix(crafts): bundle SDK inline + cache-bust transpile output
42
- - fix(crafts): move system routes out of _ namespace + delete + better builder
43
- - feat(crafts): project-scoped mini-apps with AI builder
44
- - feat(migration): per-endpoint flag for known deviations
45
- - feat(migration): smart prompt + lenient nullable + per-violation ignore
46
- - feat(migration): editable diagnosis prompt before send
47
- - feat(migration): inline request/response inspector for debugging
48
- - feat(migration): default Fix actions to inject into bound terminal
49
- - feat(migration): rich diagnosis context + connectivity banner + fix-task hand-off
50
- - feat(migration): OpenAPI as primary source + shape diff mode
51
- - fix(migration): parser missed 159 per-controller docs and dropped stubbed endpoints
8
+ - fix(server): daemonize standalones in \`forge server start\` (background)
52
9
 
53
10
 
54
- **Full Changelog**: https://github.com/aiwatching/forge/compare/v0.5.49...v0.5.50
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.5.50",
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": {