@aion0/forge 0.1.0 → 0.1.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/README.md CHANGED
@@ -252,6 +252,20 @@ notifyOnFailure: true
252
252
  | Tunnel | Cloudflare (cloudflared) |
253
253
  | Bot | Telegram Bot API (extensible) |
254
254
 
255
+ ## Troubleshooting
256
+
257
+ ### macOS: "fork failed: Device not configured"
258
+
259
+ This means the system ran out of pseudo-terminal (PTY) devices. macOS defaults to 511, which can be tight when running IDEs and many terminal sessions. Increase the limit:
260
+
261
+ ```bash
262
+ # Temporary (until reboot)
263
+ sudo sysctl kern.tty.ptmx_max=2048
264
+
265
+ # Permanent
266
+ echo 'kern.tty.ptmx_max=2048' | sudo tee -a /etc/sysctl.conf
267
+ ```
268
+
255
269
  ## Roadmap
256
270
 
257
271
  - [ ] **Multi-Agent Workflow** — DAG-based pipelines where multiple Claude Code instances collaborate, passing outputs between nodes with conditional routing and parallel execution. See [docs/roadmap-multi-agent-workflow.md](docs/roadmap-multi-agent-workflow.md).
@@ -42,19 +42,6 @@ export default function LoginPage() {
42
42
  </button>
43
43
  </form>
44
44
 
45
- <div className="flex items-center gap-3 text-[var(--text-secondary)] text-xs">
46
- <div className="flex-1 h-px bg-[var(--border)]" />
47
- <span>or</span>
48
- <div className="flex-1 h-px bg-[var(--border)]" />
49
- </div>
50
-
51
- {/* Google OAuth */}
52
- <button
53
- onClick={() => signIn('google', { callbackUrl: window.location.origin + '/' })}
54
- className="w-full py-2 bg-[var(--bg-tertiary)] border border-[var(--border)] rounded text-sm text-[var(--text-primary)] hover:bg-[var(--border)] transition-colors"
55
- >
56
- Sign in with Google
57
- </button>
58
45
  </div>
59
46
  </div>
60
47
  );
@@ -920,8 +920,11 @@ const MemoTerminalPane = memo(function TerminalPane({
920
920
  const sn = sessionNameRef.current;
921
921
  if (sn) {
922
922
  socket.send(JSON.stringify({ type: 'attach', sessionName: sn, cols, rows }));
923
- } else {
923
+ } else if (createRetries < MAX_CREATE_RETRIES) {
924
+ createRetries++;
924
925
  socket.send(JSON.stringify({ type: 'create', cols, rows }));
926
+ } else {
927
+ term.write('\r\n\x1b[91m[failed to create session — check server logs]\x1b[0m\r\n');
925
928
  }
926
929
  }
927
930
  };
@@ -957,15 +960,7 @@ const MemoTerminalPane = memo(function TerminalPane({
957
960
  }, 500);
958
961
  }
959
962
  } else if (msg.type === 'error') {
960
- if (!connectedSession && createRetries < MAX_CREATE_RETRIES) {
961
- createRetries++;
962
- term.write(`\r\n\x1b[93m[${msg.message || 'error'} — retry ${createRetries}/${MAX_CREATE_RETRIES}...]\x1b[0m\r\n`);
963
- if (ws?.readyState === WebSocket.OPEN) {
964
- ws.send(JSON.stringify({ type: 'create', cols: term.cols, rows: term.rows }));
965
- }
966
- } else {
967
- term.write(`\r\n\x1b[93m[${msg.message || 'error'}]\x1b[0m\r\n`);
968
- }
963
+ term.write(`\r\n\x1b[93m[${msg.message || 'error'}]\x1b[0m\r\n`);
969
964
  } else if (msg.type === 'exit') {
970
965
  term.write('\r\n\x1b[90m[session ended]\x1b[0m\r\n');
971
966
  }
@@ -215,6 +215,12 @@ wss.on('connection', (ws: WebSocket) => {
215
215
  return;
216
216
  }
217
217
 
218
+ // Kill previous pty process before attaching to new session (prevents PTY leak)
219
+ if (term) {
220
+ try { term.kill(); } catch {}
221
+ term = null;
222
+ }
223
+
218
224
  // Ensure mouse and scrollback are enabled (for old sessions too)
219
225
  try {
220
226
  execSync(`${TMUX} set-option -t ${name} mouse on 2>/dev/null`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aion0/forge",
3
- "version": "0.1.0",
3
+ "version": "0.1.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": {