From 51ca354c52a8876a046e9c35bbb2a9b06b3af010 Mon Sep 17 00:00:00 2001 From: Matthew Jackson Date: Fri, 6 Mar 2026 12:13:01 -0800 Subject: [PATCH] Audit fixes: remove dead code, fix run timeout bug, add log tee to all entry points MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove unused APPLY_PRIORITY array (replaced by score-based sort) - Fix run timeout only breaking inner loop — now breaks outer platform loop too - Remove dead lastProgress variable in easy_apply step loop - Add stdout/stderr log tee to job_searcher, job_filter, telegram_poller Co-Authored-By: Claude Opus 4.6 --- job_applier.mjs | 6 +++--- job_filter.mjs | 9 ++++++++- job_searcher.mjs | 8 ++++++++ lib/apply/easy_apply.mjs | 3 --- telegram_poller.mjs | 8 ++++++++ 5 files changed, 27 insertions(+), 7 deletions(-) diff --git a/job_applier.mjs b/job_applier.mjs index 8b56bf3..a349316 100644 --- a/job_applier.mjs +++ b/job_applier.mjs @@ -36,9 +36,6 @@ const DEFAULT_ENABLED_APPLY_TYPES = ['easy_apply']; const isPreview = process.argv.includes('--preview'); -// Priority order — Easy Apply first, then by ATS volume (data-driven later) -const APPLY_PRIORITY = ['easy_apply', 'wellfound', 'greenhouse', 'lever', 'ashby', 'workday', 'jobvite', 'unknown_external']; - async function main() { const lock = acquireLock('applier', resolve(__dir, 'data')); @@ -124,7 +121,9 @@ async function main() { } // Process each platform group + let timedOut = false; for (const [platform, platformJobs] of Object.entries(byPlatform)) { + if (timedOut) break; console.log(`\n--- ${platform.toUpperCase()} (${platformJobs.length} jobs) ---\n`); let browser; try { @@ -149,6 +148,7 @@ async function main() { // Check overall run timeout if (Date.now() - startedAt > APPLY_RUN_TIMEOUT_MS) { console.log(` ⏱️ Run timeout (${Math.round(APPLY_RUN_TIMEOUT_MS / 60000)}min) — stopping`); + timedOut = true; break; } diff --git a/job_filter.mjs b/job_filter.mjs index 4443832..b7fb208 100644 --- a/job_filter.mjs +++ b/job_filter.mjs @@ -19,10 +19,17 @@ loadEnv(); import { dirname, resolve } from 'path'; import { fileURLToPath } from 'url'; -import { readFileSync, writeFileSync, existsSync, unlinkSync } from 'fs'; +import { readFileSync, writeFileSync, existsSync, unlinkSync, createWriteStream } from 'fs'; const __dir = dirname(fileURLToPath(import.meta.url)); +// Tee all output to a log file so it's always available regardless of how the process is launched +const logStream = createWriteStream(resolve(__dir, 'data/filter.log'), { flags: 'w' }); +const origStdoutWrite = process.stdout.write.bind(process.stdout); +const origStderrWrite = process.stderr.write.bind(process.stderr); +process.stdout.write = (chunk, ...args) => { logStream.write(chunk); return origStdoutWrite(chunk, ...args); }; +process.stderr.write = (chunk, ...args) => { logStream.write(chunk); return origStderrWrite(chunk, ...args); }; + import { getJobsByStatus, updateJobStatus, loadConfig, loadQueue, saveQueue, dedupeAfterFilter } from './lib/queue.mjs'; import { loadProfile, submitBatches, checkBatch, downloadResults } from './lib/filter.mjs'; import { sendTelegram } from './lib/notify.mjs'; diff --git a/job_searcher.mjs b/job_searcher.mjs index 9f02508..318b9f5 100644 --- a/job_searcher.mjs +++ b/job_searcher.mjs @@ -9,9 +9,17 @@ loadEnv(); // load .env before anything else import { dirname, resolve } from 'path'; import { fileURLToPath } from 'url'; +import { createWriteStream } from 'fs'; const __dir = dirname(fileURLToPath(import.meta.url)); +// Tee all output to a log file so it's always available regardless of how the process is launched +const logStream = createWriteStream(resolve(__dir, 'data/searcher.log'), { flags: 'w' }); +const origStdoutWrite = process.stdout.write.bind(process.stdout); +const origStderrWrite = process.stderr.write.bind(process.stderr); +process.stdout.write = (chunk, ...args) => { logStream.write(chunk); return origStdoutWrite(chunk, ...args); }; +process.stderr.write = (chunk, ...args) => { logStream.write(chunk); return origStderrWrite(chunk, ...args); }; + import { addJobs, loadQueue, loadConfig } from './lib/queue.mjs'; import { writeFileSync, readFileSync, existsSync } from 'fs'; import { acquireLock } from './lib/lock.mjs'; diff --git a/lib/apply/easy_apply.mjs b/lib/apply/easy_apply.mjs index 9423abb..fe28d34 100644 --- a/lib/apply/easy_apply.mjs +++ b/lib/apply/easy_apply.mjs @@ -211,7 +211,6 @@ export async function apply(page, job, formFiller) { } // Step through modal - let lastProgress = '-1'; let samePageCount = 0; for (let step = 0; step < LINKEDIN_MAX_MODAL_STEPS; step++) { const modalStillOpen = await page.$(MODAL); @@ -297,7 +296,6 @@ export async function apply(page, job, formFiller) { } else { samePageCount = 0; } - lastProgress = newProgress; continue; } @@ -310,7 +308,6 @@ export async function apply(page, job, formFiller) { console.log(` [step ${step}] clicking Review`); await reviewBtn.click({ timeout: APPLY_CLICK_TIMEOUT }).catch(() => {}); await page.waitForTimeout(CLICK_WAIT); - lastProgress = progress; samePageCount = 0; continue; } diff --git a/telegram_poller.mjs b/telegram_poller.mjs index 8942f3d..6124dab 100644 --- a/telegram_poller.mjs +++ b/telegram_poller.mjs @@ -10,10 +10,18 @@ loadEnv(); import { resolve, dirname } from 'path'; import { fileURLToPath } from 'url'; +import { createWriteStream } from 'fs'; import { loadConfig } from './lib/queue.mjs'; import { processTelegramReplies } from './lib/telegram_answers.mjs'; const __dir = dirname(fileURLToPath(import.meta.url)); + +// Tee all output to a log file +const logStream = createWriteStream(resolve(__dir, 'data/telegram_poller.log'), { flags: 'w' }); +const origStdoutWrite = process.stdout.write.bind(process.stdout); +const origStderrWrite = process.stderr.write.bind(process.stderr); +process.stdout.write = (chunk, ...args) => { logStream.write(chunk); return origStdoutWrite(chunk, ...args); }; +process.stderr.write = (chunk, ...args) => { logStream.write(chunk); return origStderrWrite(chunk, ...args); }; const settings = loadConfig(resolve(__dir, 'config/settings.json')); const answersPath = resolve(__dir, 'config/answers.json');