* feat(settings): add rxresume mode and v5 api key settings
* feat(server): add mode-aware rxresume adapter with auto v5-first selection
* refactor(server): route settings profile and pdf generation through rxresume adapter
* feat(api): support rxresume v4/v5 in onboarding and settings routes with ok/meta responses
* feat(client): add rxresume mode selector and v5 api key setup flow
* docs: document rxresume auto mode with v5-first self-hosted setup
* test: verify dual-mode rxresume support and ci parity checks
* comments
* services folder
* correct types for v5
* tests and docs fix
* Fix RxResume auto fallback and route API consistency
* warning for both being set
* simpler response
* onboarding component improvements, v5 check still not working
* fix list resume endpoint...
* fix api endpoints to latest v5 docs
* don't show the entire project field on v5
* remove auto entirely
* formatting
* ci green
* v5 has a different resume schema
* remove redundant check
* remove requirement that only one must be specified
* consolidate sections
* base resume can be v4 or v5
* saving now works
* status indicator
* actually render some pills
* reason for failure
* fix apikey verification
* dedupe isValidatingMode
* reefactoor
* simplification?
* refactor?
* ci passing
* remove auto from docs
* tailoring is schema dependent
* skills object tighter
* remove redundant text
* fix lint
* mode
* Deduplicate string cleanup helpers and not-found responses
* Enforce aliased imports for infra and shared modules
* Enforce @client/@server aliases for deep relative imports
* Deduplicate visa sponsor and location filter definitions
* Use shared city filter export in extractor location checks
* chore: move @types/canvas-confetti to devDependencies, remove unused get-tsconfig direct dep
* chore: configure knip with workspace entry points for all packages
* refactor(shared): split 1119-line types.ts into domain modules under types/
* refactor: remove llm-service.ts shim, migrate all import sites to llm/service directly
* refactor(settings): migrate 4 manually-resolved settings into conversion registry
* refactor: split gmail-sync.ts into gmail-api, email-router, and thin orchestrator
* refactor(orchestrator): extract useKeyboardShortcuts and usePipelineControls from OrchestratorPage
Splits the 840-line OrchestratorPage into a thin orchestration shell (~480 lines) by
extracting keyboard shortcut handling into useKeyboardShortcuts.ts and pipeline
control logic into usePipelineControls.ts. Net negative line count across all files.
* feat: create settings registry (Step 1)
Introduces a single source of truth for all settings, combining schema definitions, default logic, parsing, and serialization into a single configuration object.
* feat: derive schema, keys, and types from settings registry (Step 2)
Derives AppSettings nested shape, SettingKey DB union, and updateSettingsSchema Zod shape automatically from the settings registry.
* refactor: gut envSettings and remove settings-conversion (Step 3)
Replaces manual env arrays with registry-driven maps in envSettings.ts.
Deletes settings-conversion.ts since all parsing/defaults now live in the registry.
* refactor: simplify getEffectiveSettings with generic loop (Step 4)
Replaces ~334 lines of manual key-by-key unpacking with a generic registry-driven iteration loop (~40 lines). Models, typed, string, and virtual kinds are automatically derived.
* refactor: simplify settingsUpdateRegistry (Step 5)
Replaces ~350 lines of explicit per-key update handlers with a dynamic generic loop over the settings registry, properly routing persistence and side effects.
* refactor(settings): implement nested settings registry and clean up tests
- Migrate settings system to use a centralized nested registry (`settings-schema.ts`, `registry.ts`)
- Remove obsolete flat-to-nested conversion logic (`settings-conversion.ts`)
- Address Biome warnings by explicitly ignoring intentional `any` usage in generic runtime schema builder and registry logic
- Clean up unused variables in test files (`SettingsPage.test.tsx`) to achieve a 100% green CI pipeline
* refactor(settings): address PR comments on env data and registry parsing
- Narrow `getEnvSettingsData` return type to `Partial<AppSettings>` to satisfy strict typing and omit 'typed' registry entries
- Introduce `parseNonEmptyStringOrNull` for typed string settings so empty-string overrides cleanly fall back to defaults (matching original `||` logic)
- Add missing unit tests for registry parse/serialize helpers (JSON, bools, numeric clamping)
* don't run for generated docusaurus
* format
* workflow to autoupdate docs version
* fix versioning
* add link back to app
* remove old docs
* html link???
* don't track .docusaurus
* documantation build
* fix(tailoring): remove auto-sync effect causing race conditions
Remove the problematic useEffect that was syncing incoming job data
automatically. The effect caused race conditions where user edits were
overwritten after auto-save completed. Now, state only resets when the
job ID changes (user switches to a different job). User edits persist
until explicitly saved.
Fixes#133
* fix(tailoring): remove auto-save from tailor mode
Remove the 1500ms auto-save timeout that was causing race conditions
with the state sync. Users must now explicitly save changes via the
Save Selection button or finalize to persist changes.
* refactor(tailoring): remove draft status state and UI
Remove the draftStatus state and related UI elements that showed
saving/saved/unsaved status. With auto-save removed, this status
indicator is no longer needed. Users now explicitly save via buttons.
* test(tailoring): remove auto-save test
Remove the test that verified auto-save behavior since auto-save
has been removed from the tailor mode. Users now explicitly save
via the Finalize button.
* refactor(tailoring): remove dead focus tracking code
Remove the activeField state and all related focus/blur tracking that
was orphaned after removing auto-sync. The focus tracking was only
used to prevent the auto-sync effect from running while editing.
Changes:
- Remove TailoringActiveField type export
- Remove activeField state and setActiveField from useTailoringDraft
- Remove handleFieldBlur callback from TailoringWorkspace
- Remove onFieldFocus/onFieldBlur props and handlers from TailoringSections
39 lines of dead code removed.
* docs(tailoring): clarify save behavior comment
Update comment to distinguish between editor mode (Save Selection
button) and tailor mode (only persists on finalize). Addresses
review feedback.
* docs(tailoring): clarify useEffect dependencies
Add note explaining why 'job' is included in dependencies despite
the effect being guarded by job.id check. Addresses review feedback
about dependency array clarity.
* fix(tailoring): sync server-normalized values after save
Update persistCurrent and saveChanges to use the returned job from
api.updateJob and call applyIncomingDraft. This ensures local state
stays in sync with server-normalized values (e.g., trimmed fields).
Also removes unused markCurrentAsSaved dependency.
* refactor(tailoring): simplify draft sync effect
Remove unused save snapshot helpers and stop exposing them from the
hook. Track the latest job in a ref and only sync drafts when the job
id changes to avoid unnecessary effect runs while keeping data
correctness.
Addresses review feedback on dependency churn and dead API surface.
* 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
* api(jobs): normalize PATCH /jobs/:id response contract and error mapping
* api(jobs): support core job detail edits in update schema
* feat(client): add JobDetailsEditDrawer with core metadata form
* feat(orchestrator): open edit drawer from JobDetailPanel more actions
* feat(orchestrator): add edit drawer trigger to ready and discovered more actions
* initial commit
* accordionising
* merge extra cards
* visual highlight
* everybody becomes an accordion
* bugbashing
* text area
* split up tailoring editor
* feat: enhance `parseTailoredSkills` to support legacy string arrays and add comprehensive tests for parsing logic.
* 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