mirror of
https://github.com/MadsLorentzen/ai-job-search.git
synced 2026-09-17 08:36:25 +00:00
* fix: silent zero output in salary converter and NaN filter bypass in LinkedIn CLI Bug #10 (convert_salary_excel.py): openpyxl ws[row_index] random access fails silently under read_only=True, leaving headers empty and producing no output. Fix: save the header row values during the existing iter_rows scan so ws[header_row] is never called. Bug #5 (.agents/skills/linkedin-search/cli/src/cli.ts): parseInt on --jobage/--page/--limit flags returns NaN on non-numeric input. NaN propagates silently — the jobage filter is dropped, page/limit are broken. Fix: validate each parsed int, exit 1 with a structured BAD_ARG error on NaN. Also adds: - tests/test_bug10_salary_converter.py: 10 scenarios, 31 assertions (all green) - tests/test_bug5_linkedin_cli.sh: 8 scenarios, 16 assertions (all green) - docs/bugfixes.md: root cause, impact, and fix explanation for both bugs, plus a note on the pre-existing detect_column_type "n" pattern issue Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: address PR review — drop salary converter change, move test to bun - Drop tools/convert_salary_excel.py change (bug not reproducible on modern openpyxl; reviewer confirmed master works correctly) - Drop tests/test_bug10_salary_converter.py and top-level tests/ dir - Drop docs/bugfixes.md (analysis belongs in PR description, not repo) - Replace tests/test_bug5_linkedin_cli.sh with a proper bun test file at .agents/skills/linkedin-search/cli/tests/cli-flag-validation.test.ts following the jobindex-search/cli/tests/ convention (runCLI/parseJSON helpers, describe/test/expect, descriptive names) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
40 lines
959 B
TypeScript
40 lines
959 B
TypeScript
import { join } from "path";
|
|
|
|
const CLI_PATH = join(import.meta.dir, "../src/cli.ts");
|
|
|
|
export interface CLIResult {
|
|
stdout: string;
|
|
stderr: string;
|
|
exitCode: number;
|
|
}
|
|
|
|
export async function runCLI(args: string[]): Promise<CLIResult> {
|
|
const proc = Bun.spawn(["bun", "run", CLI_PATH, ...args], {
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
const [stdout, stderr, exitCode] = await Promise.all([
|
|
new Response(proc.stdout).text(),
|
|
new Response(proc.stderr).text(),
|
|
proc.exited,
|
|
]);
|
|
|
|
return { stdout: stdout.trim(), stderr: stderr.trim(), exitCode };
|
|
}
|
|
|
|
export function parseJSON<T = unknown>(result: CLIResult): T {
|
|
if (result.exitCode !== 0) {
|
|
throw new Error(
|
|
`CLI exited with code ${result.exitCode}. stderr: ${result.stderr}`
|
|
);
|
|
}
|
|
try {
|
|
return JSON.parse(result.stdout) as T;
|
|
} catch {
|
|
throw new Error(
|
|
`Failed to parse JSON. stdout: ${result.stdout}\nstderr: ${result.stderr}`
|
|
);
|
|
}
|
|
}
|