From 16b7d06f803499f428bee2ad511faf0c6462ddd7 Mon Sep 17 00:00:00 2001 From: Prateek Date: Sat, 14 Feb 2026 11:22:05 +0530 Subject: [PATCH] =?UTF-8?q?fix:=20address=20Bugbot=20review=20=E2=80=94=20?= =?UTF-8?q?Windows=20paths,=20bytesRead,=20hardcoded=20paths?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - toClaudeProjectPath: handle Windows backslashes and drive letters - readLastJsonlEntry: use bytesRead to avoid null character corruption - Remove duplicate next-env.d.ts eslint ignore entry - Remove hardcoded developer-specific binary paths from integration tests - Add isProcessing limitation comments with issue references (#17-19) Co-Authored-By: Claude Opus 4.6 --- eslint.config.js | 1 - .../integration-tests/src/agent-aider.integration.test.ts | 3 +-- .../src/agent-claude-code.integration.test.ts | 3 +-- .../integration-tests/src/agent-codex.integration.test.ts | 3 +-- packages/plugins/agent-aider/src/index.ts | 2 ++ packages/plugins/agent-claude-code/src/index.ts | 8 +++++--- packages/plugins/agent-codex/src/index.ts | 2 ++ packages/plugins/agent-opencode/src/index.ts | 2 ++ 8 files changed, 14 insertions(+), 10 deletions(-) diff --git a/eslint.config.js b/eslint.config.js index a2ad5d7e2..a5d073b63 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -13,7 +13,6 @@ export default tseslint.config( "packages/web/next-env.d.ts", "packages/web/next.config.js", "packages/web/postcss.config.mjs", - "packages/web/next-env.d.ts", ], }, diff --git a/packages/integration-tests/src/agent-aider.integration.test.ts b/packages/integration-tests/src/agent-aider.integration.test.ts index a07c117c6..abeba27e2 100644 --- a/packages/integration-tests/src/agent-aider.integration.test.ts +++ b/packages/integration-tests/src/agent-aider.integration.test.ts @@ -28,10 +28,9 @@ const execFileAsync = promisify(execFile); // --------------------------------------------------------------------------- const SESSION_PREFIX = "ao-inttest-aider-"; -const AIDER_BINARY = "/Users/equinox/Library/Python/3.9/bin/aider"; async function findAiderBinary(): Promise { - for (const bin of ["aider", AIDER_BINARY]) { + for (const bin of ["aider"]) { try { await execFileAsync("which", [bin], { timeout: 5_000 }); return bin; diff --git a/packages/integration-tests/src/agent-claude-code.integration.test.ts b/packages/integration-tests/src/agent-claude-code.integration.test.ts index c4280718b..289cb1942 100644 --- a/packages/integration-tests/src/agent-claude-code.integration.test.ts +++ b/packages/integration-tests/src/agent-claude-code.integration.test.ts @@ -28,10 +28,9 @@ const execFileAsync = promisify(execFile); // --------------------------------------------------------------------------- const SESSION_PREFIX = "ao-inttest-claude-"; -const CLAUDE_BINARY = "/Users/equinox/.local/bin/claude"; async function findClaudeBinary(): Promise { - for (const bin of ["claude", CLAUDE_BINARY]) { + for (const bin of ["claude"]) { try { await execFileAsync("which", [bin], { timeout: 5_000 }); return bin; diff --git a/packages/integration-tests/src/agent-codex.integration.test.ts b/packages/integration-tests/src/agent-codex.integration.test.ts index fab7f8e95..65eb9df30 100644 --- a/packages/integration-tests/src/agent-codex.integration.test.ts +++ b/packages/integration-tests/src/agent-codex.integration.test.ts @@ -28,10 +28,9 @@ const execFileAsync = promisify(execFile); // --------------------------------------------------------------------------- const SESSION_PREFIX = "ao-inttest-codex-"; -const CODEX_BINARY = "/opt/homebrew/bin/codex"; async function findCodexBinary(): Promise { - for (const bin of ["codex", CODEX_BINARY]) { + for (const bin of ["codex"]) { try { await execFileAsync("which", [bin], { timeout: 5_000 }); return bin; diff --git a/packages/plugins/agent-aider/src/index.ts b/packages/plugins/agent-aider/src/index.ts index 4206c4a81..665105788 100644 --- a/packages/plugins/agent-aider/src/index.ts +++ b/packages/plugins/agent-aider/src/index.ts @@ -122,6 +122,8 @@ function createAiderAgent(): Agent { } }, + // NOTE: Aider lacks introspection to distinguish "processing" from "idle at prompt". + // Falling back to process liveness until richer detection is implemented (see #18). async isProcessing(session: Session): Promise { if (!session.runtimeHandle) return false; return this.isProcessRunning(session.runtimeHandle); diff --git a/packages/plugins/agent-claude-code/src/index.ts b/packages/plugins/agent-claude-code/src/index.ts index e80d9a424..f90f0e7bd 100644 --- a/packages/plugins/agent-claude-code/src/index.ts +++ b/packages/plugins/agent-claude-code/src/index.ts @@ -45,7 +45,9 @@ export const manifest = { * the resulting directory exists. */ function toClaudeProjectPath(workspacePath: string): string { - return workspacePath.replace(/^\//, "").replace(/[/.]/g, "-"); + // Handle Windows drive letters (C:\Users\... → C-Users-...) + const normalized = workspacePath.replace(/\\/g, "/"); + return normalized.replace(/^\//, "").replace(/:/g, "").replace(/[/.]/g, "-"); } /** Find the most recently modified .jsonl session file in a directory */ @@ -112,9 +114,9 @@ async function readLastJsonlEntry( const readSize = Math.min(TAIL_READ_BYTES, size); const buffer = Buffer.alloc(readSize); - await fh.read(buffer, 0, readSize, size - readSize); + const { bytesRead } = await fh.read(buffer, 0, readSize, size - readSize); - const chunk = buffer.toString("utf-8"); + const chunk = buffer.toString("utf-8", 0, bytesRead); // Walk backwards through lines to find the last valid JSON object with a type const lines = chunk.split("\n"); for (let i = lines.length - 1; i >= 0; i--) { diff --git a/packages/plugins/agent-codex/src/index.ts b/packages/plugins/agent-codex/src/index.ts index 97e3e6b44..e1ebed499 100644 --- a/packages/plugins/agent-codex/src/index.ts +++ b/packages/plugins/agent-codex/src/index.ts @@ -126,6 +126,8 @@ function createCodexAgent(): Agent { } }, + // NOTE: Codex lacks introspection to distinguish "processing" from "idle at prompt". + // Falling back to process liveness until richer detection is implemented (see #17). async isProcessing(session: Session): Promise { if (!session.runtimeHandle) return false; return this.isProcessRunning(session.runtimeHandle); diff --git a/packages/plugins/agent-opencode/src/index.ts b/packages/plugins/agent-opencode/src/index.ts index e19eb358d..49e868b61 100644 --- a/packages/plugins/agent-opencode/src/index.ts +++ b/packages/plugins/agent-opencode/src/index.ts @@ -118,6 +118,8 @@ function createOpenCodeAgent(): Agent { } }, + // NOTE: OpenCode lacks introspection to distinguish "processing" from "idle at prompt". + // Falling back to process liveness until richer detection is implemented (see #19). async isProcessing(session: Session): Promise { if (!session.runtimeHandle) return false; return this.isProcessRunning(session.runtimeHandle);