From 1c3e9f35612ee0d881cf9f64588e43daea289bf6 Mon Sep 17 00:00:00 2001 From: Matthew Jackson Date: Thu, 5 Mar 2026 17:44:25 -0800 Subject: [PATCH] fix: split skip counters for accurate reporting, complete status docs - Split skipped_no_easy_apply into skipped_no_apply (no button/modal) and skipped_other (honeypot/stuck/incomplete) for clearer reporting - Update Telegram summary, status.mjs display, and job_applier counters - Add missing skipped_easy_apply_unsupported to README status table Co-Authored-By: Claude Opus 4.6 --- README.md | 1 + job_applier.mjs | 10 ++++++++-- lib/notify.mjs | 10 +++++++--- status.mjs | 6 ++++-- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 695b3e5..fa6c1b4 100644 --- a/README.md +++ b/README.md @@ -202,6 +202,7 @@ claw-apply/ | `skipped_honeypot` | Honeypot question detected | | `skipped_recruiter_only` | LinkedIn recruiter-only listing | | `skipped_external_unsupported` | External ATS (Greenhouse, Lever, etc. — stubs ready) | +| `skipped_easy_apply_unsupported` | LinkedIn job without Easy Apply button | | `skipped_no_apply` | No apply button, modal, or submit found on page | | `stuck` | Modal progress stalled | | `incomplete` | Ran out of modal steps without submitting | diff --git a/job_applier.mjs b/job_applier.mjs index a3ecba5..0c29bf3 100644 --- a/job_applier.mjs +++ b/job_applier.mjs @@ -40,7 +40,7 @@ async function main() { const startedAt = Date.now(); const results = { submitted: 0, failed: 0, needs_answer: 0, total: 0, - skipped_recruiter: 0, skipped_external: 0, skipped_no_easy_apply: 0, + skipped_recruiter: 0, skipped_external: 0, skipped_no_apply: 0, skipped_other: 0, already_applied: 0, atsCounts: {} }; @@ -201,13 +201,19 @@ async function handleResult(job, result, results, settings) { case 'skipped_no_apply': case 'skipped_easy_apply_unsupported': + console.log(` ⏭️ Skipped — ${status}`); + updateJobStatus(job.id, status, { title, company }); + appendLog({ ...job, title, company, status }); + results.skipped_no_apply++; + break; + case 'skipped_honeypot': case 'stuck': case 'incomplete': console.log(` ⏭️ Skipped — ${status}`); updateJobStatus(job.id, status, { title, company }); appendLog({ ...job, title, company, status }); - results.skipped_no_easy_apply++; + results.skipped_other++; break; default: diff --git a/lib/notify.mjs b/lib/notify.mjs index 307ea6a..9df779e 100644 --- a/lib/notify.mjs +++ b/lib/notify.mjs @@ -47,20 +47,24 @@ export function formatSearchSummary(added, skipped, platforms) { export function formatApplySummary(results) { const { submitted, failed, needs_answer, total, - skipped_recruiter, skipped_external, skipped_no_easy_apply, - already_applied, atsCounts } = results; + skipped_recruiter, skipped_external, skipped_no_apply, + skipped_other, already_applied, atsCounts } = results; const lines = [ `✅ *Apply Run Complete* — ${total} jobs processed`, ``, `📬 Applied: ${submitted}`, - `⏭️ Skipped (no Easy Apply): ${skipped_no_easy_apply}`, + `⏭️ No apply button: ${skipped_no_apply || 0}`, `🚫 Recruiter-only: ${skipped_recruiter}`, `🔁 Already applied: ${already_applied || 0}`, `❌ Failed: ${failed}`, `💬 Needs your answer: ${needs_answer}`, ]; + if (skipped_other > 0) { + lines.push(`⚠️ Other skips (honeypot/stuck/incomplete): ${skipped_other}`); + } + if (skipped_external > 0 && atsCounts) { const sorted = Object.entries(atsCounts).sort((a, b) => b[1] - a[1]); lines.push(``, `🌐 *External ATS — ${skipped_external} jobs* (saved for later):`); diff --git a/status.mjs b/status.mjs index a418a58..5cb25c2 100644 --- a/status.mjs +++ b/status.mjs @@ -80,7 +80,8 @@ function buildStatus() { needs_answer: byStatus['needs_answer'] || 0, skipped_external: byStatus['skipped_external_unsupported'] || 0, skipped_recruiter: byStatus['skipped_recruiter_only'] || 0, - skipped_no_easy_apply: byStatus['skipped_easy_apply_unsupported'] || 0, + skipped_no_apply: (byStatus['skipped_easy_apply_unsupported'] || 0) + (byStatus['skipped_no_apply'] || 0), + skipped_other: (byStatus['skipped_honeypot'] || 0) + (byStatus['stuck'] || 0) + (byStatus['incomplete'] || 0), already_applied: byStatus['already_applied'] || 0, by_platform: byPlatform, }, @@ -159,7 +160,8 @@ function formatReport(s) { ` 💬 Needs your answer: ${q.needs_answer}`, ` ❌ Failed: ${q.failed}`, ` 🚫 Recruiter-only: ${q.skipped_recruiter}`, - ` ⏭️ No Easy Apply: ${q.skipped_no_easy_apply}`, + ` ⏭️ No apply button: ${q.skipped_no_apply}`, + ` ⚠️ Other skips: ${q.skipped_other || 0}`, ` 🌐 External ATS: ${q.skipped_external}`, );