- 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 <noreply@anthropic.com>
- lib/apply/index.mjs: add STATUS_MAP to normalize platform-specific statuses
to generic ones (no_button/no_submit/no_modal → skipped_no_apply).
Documented all generic statuses for AI/developer reference.
- job_applier.mjs: handleResult now handles skipped_no_apply, default case
logs + saves instead of silently dropping
- lib/linkedin.mjs: remove dead applyLinkedIn() and detectAts(), clean imports
(~110 lines removed). Search-only module now.
- lib/wellfound.mjs: remove dead applyWellfound(), clean imports.
Search-only module now.
- lib/lock.mjs: fix async signal handler — shutdown handlers now actually
complete before process.exit()
- test_linkedin_login.mjs: add try/catch/finally with proper browser cleanup
- README: update status table with all current statuses
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- job_applier.mjs: stack traces on per-job and browser-level errors
- session.mjs: log pending status and poll count during session refresh
- linkedin.mjs: log warning when job card click fails instead of silent catch
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- form_filler.mjs: reject regex patterns over 200 chars to mitigate ReDoS
- notify.mjs: check res.ok before parsing Telegram API response
- README: update project structure with new lib/apply/ modules, session.mjs,
keywords.mjs; fix max_applications_per_run docs (no limit by default);
clarify ATS stub status in roadmap
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add res.ok check before parsing Anthropic API response
- Validate data.content[0].text exists before accessing
- Remove classifier.mjs (86 lines of dead code, never imported)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Prepares the repo for ClawHub publishing:
- claw.json manifest with permissions and metadata
- .env.example for KERNEL_API_KEY
- Remove broken node_modules symlink (pointed to server path)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Full README with quick start, configuration tables, status reference,
project structure, and roadmap
- SKILL.md updated with preview mode, retry logic, constants module
- SPEC.md updated with pagination, infinite scroll, retry flow,
in-memory caching, config validation, and v1 checklist
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove unused readFileSync import from job_applier.mjs
- Remove unused makeJobId (dead code, nothing imports it)
- setup.mjs: use shared loadConfig instead of inline cfg()
- queue.mjs: add in-memory cache for queue and log to avoid
redundant disk reads during a single run
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add loadConfig() helper with clear errors for missing/malformed JSON
- Replace raw JSON.parse(readFileSync(...)) in both entry points
- Track retry_count on jobs; re-queue as 'new' up to max_retries (default 2)
- Add max_retries and DEFAULT_MAX_RETRIES constant
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove random suffix from Wellfound job IDs (broke dedup)
- Add null coalescing to all profile field returns in form_filler
- Fix honeypot case referencing nonexistent results.skipped counter
- Remove unused makeJobId import from linkedin.mjs
- Navigate directly to job URL instead of search+click in linkedin apply
- Add Telegram notification rate limiting (1.5s between sends)
- Replace Mode B blocking sleep with --preview flag
- Add max_applications_per_run enforcement
- Remove tracked search_config.json (keep .example.json only)
- Add search_config.json to .gitignore, fix duplicate node_modules entry
- Extract all magic numbers/strings to lib/constants.mjs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>