When switching between job tabs (e.g. Discovered → Applied), the detail
panel would briefly show the previously selected job with the new tab's
action buttons — confusing and error-prone.
Three coordinated fixes:
- setActiveTab now checks if the selected job's status fits the target
tab, keeping it when valid (e.g. Discovered → All Jobs) and clearing
it otherwise.
- New visibleSelectedJob useMemo guard synchronously nulls out the
selected job when it doesn't belong to the active tab, eliminating
the one-frame flash caused by the data hook's useEffect lag.
- Auto-select effect now handles the case where a job passes the status
check but gets filtered out by source/sponsor/salary filters.
* Add startup.jobs extractor support
* Harden startup.jobs extractor inputs
* Wire startupjobs into Docker and CI
* Tighten startupjobs review follow-ups
* fix: publish ghcr during release workflow
* feat: add startupjobs max jobs configuration and update related tests
* feat(orchestrator): add visual feedback when moving jobs to Ready
- Added `toast.message("Moving job to Ready...")` in `OrchestratorPage.tsx` for single item keyboard shortcut action.
- Added `toast.message("Moving jobs to Ready...")` in `useBulkJobSelection.ts` for bulk `move_to_ready` action.
- Updated `OrchestratorPage.test.tsx` to verify the toast notification.
This addresses the issue where pressing 'R' provided no visual feedback until the action completed.
* fix(orchestrator): remove accidental db files
Removed `orchestrator/data/jobs.db`, `orchestrator/data/jobs.db-shm`, and `orchestrator/data/jobs.db-wal` which were accidentally created during testing.
* fix(orchestrator): remove accidental root sqlite.db
Removed `orchestrator/sqlite.db` which was also accidentally created.
* feat(shortcuts): add tinykeys + core infrastructure (useHotkeys, shortcut-map, KbdHint)
Install tinykeys (~400B) for declarative keyboard shortcut handling.
Add useHotkeys React hook with input-guarding logic, centralized
shortcut definitions, and a reusable KbdHint badge component.
Ref #113
* feat(shortcuts): wire j/k navigation and 1-4 tab switching
Add useHotkeys call to OrchestratorPage with:
- j/ArrowDown to navigate to next job in list
- k/ArrowUp to navigate to previous job
- 1/2/3/4 to switch between Ready/Discovered/Applied/All tabs
Auto-scrolls the list to keep the selected job visible.
Ref #113
* feat(shortcuts): add context action shortcuts (s/a/t/p/d/o/x/Esc)
Wire keyboard shortcuts for all primary actions:
- s: skip job (discovered/ready tabs)
- a: mark applied (ready tab)
- t: toggle tailor mode (discovered/ready tabs)
- p: view PDF in new tab (ready tab)
- d: download PDF (ready tab)
- o: open job listing (all tabs)
- x: toggle select current job
- /: open search (command bar)
- Escape: clear selection
Actions are tab-scoped and guard against in-flight state.
Thread tailorTrigger counter prop through JobDetailPanel to
DiscoveredPanel and ReadyPanel for keyboard-driven tailor toggle.
Ref #113
* feat(shortcuts): add bottom hint bar and help dialog (? key)
Add KeyboardShortcutBar -- a Superhuman-style bottom bar showing
available shortcuts for the current tab. Dismissible with X button,
preference stored in localStorage.
Add KeyboardShortcutDialog -- a grouped help overlay triggered by '?'
showing all shortcuts with their key bindings in a two-column layout.
Both components are context-aware, only displaying shortcuts valid
for the active tab.
Ref #113
* feat(shortcuts): add visual KbdHint badges on action buttons
Show keyboard shortcut key caps on primary action buttons:
- DecideMode: 's' on Skip, 't' on Start Tailoring
- ReadyPanel: 'p' on View PDF, 'd' on Download, 'o' on Open Listing,
'a' on Mark Applied
- OrchestratorFilters: '1'-'4' on tab triggers
All hints are desktop-only (hidden below lg breakpoint).
Ref #113
* refactor(shortcuts): migrate Cmd+K to useHotkeys in JobCommandBar
Replace manual window.addEventListener keydown handler with the
shared useHotkeys hook for consistency across all keyboard shortcuts.
Ref #113
* fix(test): mock getProfile in OrchestratorPage tests
* style: move tab shortcut indicator before label
* feat: add ArrowLeft/Right shortcuts for tab navigation
* feat: show keyboard helpers only when Control is held down
* feat: expand shortcut bar with multiline layout
* feat: show keyboard shortcut help on first launch
* 1
* 2
* 3
* better modifier pattern
* 5
* tailoring is a toggle
* tests
* tests is passing
* r to move to ready
* tests
* initial change
* nav highlighting
* icon change
* deeeedoooop
* text
* show version number on all pages
* icon
* remove unused code
* add knip
* formatting
* remove unused code
* types fix
* remove notion completely from the codebase.
* update test for new url structure
* clean up the fucking shop boys
* make a "create job" factory and use that
* moar factories
* formatting
* feat(api): add lightweight jobs list view without pagination
* refactor(client): use lightweight jobs list and on-demand job detail
* refactor(ui): separate job list rows from full job detail
* perf(home): reduce jobs payload to applied lightweight rows
* perf(db): add safe composite index for jobs list queries
* feat(api): default jobs endpoint to lightweight list view
* style: apply biome formatting for jobs list-view changes
* feat(api): add jobs revision endpoint for lightweight change detection
* refactor(client): switch jobs auto-refresh to revision checks
* perf(client): drive pipeline freshness via sse with polling fallback
* refactor(orchestrator): remove pipeline status polling loop from page
* chore(client): add periodic safety refresh and refresh lifecycle hardening
* refactor(types): define JobListItem via Pick<Job> to prevent drift
* initial commit
* use colours!
* match by scoring
* scroll job card into view
* introduce @ based 'locks' to restrict search to specific statuses
* clear lock states on close
* split up component
* inline pill
* resuse job row content
* fix intro anim
* larger size, instruction
* refactor existing search feature
* lock colour border
* if active, clear active on escape
* remove query param
* documenration update
* scoring logic
* check exists before scroll
* status dot and checkbox occupy the same space!
* feat(shared): centralize supported country list and source-country rules
* feat(orchestrator): add country selector and UK-only source gating in automatic run modal
* feat(orchestrator): persist country selection and run only compatible extractors
* fix(pipeline): enforce country-source compatibility during discovery
* test(orchestrator): cover country-based source gating and pipeline enforcement
* formatting
* test fix
* lint
* comments
* prevent auto focus grab
* verification
* command and popover
* make sure scroll is working
* feat(orchestrator): add unified run modal shell with Automatic/Manual tabs
* feat(orchestrator): implement Automatic tab presets, estimate, and save+run flow
* refactor(manual-import): reuse manual import flow inside unified run modal
* refactor(settings): move pipeline tuning out of settings page into run modal
* stage 5
* jobs per term simplified
* copy improvement
* pill input
* better UI
* style(orchestrator): align run settings inputs on one row
* style(orchestrator): remove hover and pointer affordance from term pills
* style(orchestrator): restore hover and pointer affordance for term pills
* style(orchestrator): make search term pill hover more prominent
* better hover
* refactor(orchestrator): use react-hook-form in automatic run panel
* formatting
* fix(orchestrator): resolve biome issues in automatic run modal
* better copy
* feat(orchestrator): auto-select custom preset on manual config changes
* remove badge
* feat(orchestrator): redesign automatic run panel with collapsible advanced settings
* refactor(orchestrator): move estimate summary to footer and dedupe sources
* style(orchestrator): separate search term input from term pills
* style(orchestrator): remove save preset action from automatic footer
* ux(orchestrator): make entire search term pill tap-to-remove
* remove badge
* remove badge
* fix(orchestrator): return zero estimate when search terms are empty