From 42d601869dfdbe01e680084933e07f80c4a2b99e Mon Sep 17 00:00:00 2001 From: Prateek Date: Fri, 13 Feb 2026 19:17:59 +0530 Subject: [PATCH] fix: add execFileAsync timeouts, use satisfies for plugin exports - Add { timeout: 30_000 } to all execFileAsync calls (tmux, ps) per CLAUDE.md convention to prevent hanging on stuck processes - Replace `const plugin: PluginModule` with inline `export default { ... } satisfies PluginModule` to preserve narrow literal types on manifest fields Addresses Bugbot review comments on PR #5. Co-Authored-By: Claude Opus 4.6 --- packages/plugins/agent-aider/src/index.ts | 7 +++---- packages/plugins/agent-claude-code/src/index.ts | 9 ++++----- packages/plugins/agent-codex/src/index.ts | 7 +++---- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/packages/plugins/agent-aider/src/index.ts b/packages/plugins/agent-aider/src/index.ts index 64d4619fe..925b2074c 100644 --- a/packages/plugins/agent-aider/src/index.ts +++ b/packages/plugins/agent-aider/src/index.ts @@ -80,7 +80,7 @@ function createAiderAgent(): Agent { handle.id, "-F", "#{pane_tty}", - ]); + ], { timeout: 30_000 }); const ttys = ttyOut .trim() .split("\n") @@ -88,7 +88,7 @@ function createAiderAgent(): Agent { .filter(Boolean); if (ttys.length === 0) return false; - const { stdout: psOut } = await execFileAsync("ps", ["-eo", "pid,tty,args"]); + const { stdout: psOut } = await execFileAsync("ps", ["-eo", "pid,tty,args"], { timeout: 30_000 }); const ttySet = new Set(ttys.map((t) => t.replace(/^\/dev\//, ""))); const processRe = /(?:^|\/)aider(?:\s|$)/; for (const line of psOut.split("\n")) { @@ -137,5 +137,4 @@ export function create(): Agent { return createAiderAgent(); } -const plugin: PluginModule = { manifest, create }; -export default plugin; +export default { manifest, create } satisfies PluginModule; diff --git a/packages/plugins/agent-claude-code/src/index.ts b/packages/plugins/agent-claude-code/src/index.ts index 34b528750..612cd1a41 100644 --- a/packages/plugins/agent-claude-code/src/index.ts +++ b/packages/plugins/agent-claude-code/src/index.ts @@ -245,7 +245,7 @@ async function findClaudeProcess(handle: RuntimeHandle): Promise handle.id, "-F", "#{pane_tty}", - ]); + ], { timeout: 30_000 }); // Iterate all pane TTYs (multi-pane sessions) — succeed on any match const ttys = ttyOut .trim() @@ -257,7 +257,7 @@ async function findClaudeProcess(handle: RuntimeHandle): Promise // Use `args` instead of `comm` so we can match the CLI name even when // the process runs via a wrapper (e.g. node, python). `comm` would // report "node" instead of "claude" in those cases. - const { stdout: psOut } = await execFileAsync("ps", ["-eo", "pid,tty,args"]); + const { stdout: psOut } = await execFileAsync("ps", ["-eo", "pid,tty,args"], { timeout: 30_000 }); const ttySet = new Set(ttys.map((t) => t.replace(/^\/dev\//, ""))); // Match "claude" as a word boundary — prevents false positives on // names like "claude-code" or paths that merely contain the substring. @@ -362,7 +362,7 @@ function createClaudeCodeAgent(): Agent { "-p", "-S", "-15", - ]); + ], { timeout: 30_000 }); output = stdout; } } catch { @@ -445,5 +445,4 @@ export function create(): Agent { return createClaudeCodeAgent(); } -const plugin: PluginModule = { manifest, create }; -export default plugin; +export default { manifest, create } satisfies PluginModule; diff --git a/packages/plugins/agent-codex/src/index.ts b/packages/plugins/agent-codex/src/index.ts index 5a0a38a76..daad45be7 100644 --- a/packages/plugins/agent-codex/src/index.ts +++ b/packages/plugins/agent-codex/src/index.ts @@ -84,7 +84,7 @@ function createCodexAgent(): Agent { handle.id, "-F", "#{pane_tty}", - ]); + ], { timeout: 30_000 }); const ttys = ttyOut .trim() .split("\n") @@ -92,7 +92,7 @@ function createCodexAgent(): Agent { .filter(Boolean); if (ttys.length === 0) return false; - const { stdout: psOut } = await execFileAsync("ps", ["-eo", "pid,tty,args"]); + const { stdout: psOut } = await execFileAsync("ps", ["-eo", "pid,tty,args"], { timeout: 30_000 }); const ttySet = new Set(ttys.map((t) => t.replace(/^\/dev\//, ""))); const processRe = /(?:^|\/)codex(?:\s|$)/; for (const line of psOut.split("\n")) { @@ -141,5 +141,4 @@ export function create(): Agent { return createCodexAgent(); } -const plugin: PluginModule = { manifest, create }; -export default plugin; +export default { manifest, create } satisfies PluginModule;