fix: address Bugbot review — Windows paths, bytesRead, hardcoded paths

- 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 <noreply@anthropic.com>
This commit is contained in:
Prateek 2026-02-14 11:22:05 +05:30
parent 468229ca6e
commit 16b7d06f80
8 changed files with 14 additions and 10 deletions

View File

@ -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",
],
},

View File

@ -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<string | null> {
for (const bin of ["aider", AIDER_BINARY]) {
for (const bin of ["aider"]) {
try {
await execFileAsync("which", [bin], { timeout: 5_000 });
return bin;

View File

@ -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<string | null> {
for (const bin of ["claude", CLAUDE_BINARY]) {
for (const bin of ["claude"]) {
try {
await execFileAsync("which", [bin], { timeout: 5_000 });
return bin;

View File

@ -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<string | null> {
for (const bin of ["codex", CODEX_BINARY]) {
for (const bin of ["codex"]) {
try {
await execFileAsync("which", [bin], { timeout: 5_000 });
return bin;

View File

@ -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<boolean> {
if (!session.runtimeHandle) return false;
return this.isProcessRunning(session.runtimeHandle);

View File

@ -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--) {

View File

@ -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<boolean> {
if (!session.runtimeHandle) return false;
return this.isProcessRunning(session.runtimeHandle);

View File

@ -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<boolean> {
if (!session.runtimeHandle) return false;
return this.isProcessRunning(session.runtimeHandle);