Jobber/orchestrator/package.json
Shaheer Sarfaraz e114c5d592
Keyboard shortcuts (#131)
* 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
2026-02-10 22:13:05 +00:00

110 lines
3.6 KiB
JSON

{
"name": "job-ops-orchestrator",
"version": "1.0.0",
"type": "module",
"description": "Unified orchestrator for job application pipeline",
"main": "src/server/index.ts",
"scripts": {
"dev": "concurrently \"npm run dev:server\" \"npm run dev:client\"",
"dev:server": "tsx watch src/server/index.ts",
"dev:client": "vite --host",
"check:all": "npm run check:types && npm run check:fix && npm run format:fix",
"ci": "biome ci",
"check": "biome check",
"check:fix": "biome check --write",
"check:types": "tsc --noEmit",
"format": "biome format",
"format:fix": "biome format --write",
"build:client": "vite build",
"start": "tsx src/server/index.ts",
"db:migrate": "tsx src/server/db/migrate.ts",
"db:migrate:prod": "tsx src/server/db/migrate.ts",
"db:clear": "tsx src/server/db/clear.ts",
"db:drop": "tsx src/server/db/clear.ts --drop",
"pipeline:run": "tsx src/server/pipeline/run.ts",
"test": "vitest",
"test:run": "vitest run"
},
"dependencies": {
"@hookform/resolvers": "^5.2.2",
"@paralleldrive/cuid2": "^3.0.6",
"@radix-ui/react-accordion": "^1.2.12",
"@radix-ui/react-alert-dialog": "^1.1.15",
"@radix-ui/react-checkbox": "1.3.2",
"@radix-ui/react-collapsible": "^1.1.12",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "2.1.15",
"@radix-ui/react-label": "^2.1.8",
"@radix-ui/react-popover": "1.1.15",
"@radix-ui/react-progress": "^1.1.8",
"@radix-ui/react-radio-group": "^1.3.8",
"@radix-ui/react-select": "^2.2.6",
"@radix-ui/react-separator": "^1.1.8",
"@radix-ui/react-slot": "^1.2.4",
"@radix-ui/react-tabs": "^1.1.13",
"@radix-ui/react-tooltip": "^1.2.8",
"@tailwindcss/vite": "^4.1.18",
"@types/canvas-confetti": "^1.9.0",
"better-sqlite3": "^11.6.0",
"canvas-confetti": "^1.9.4",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
"cors": "^2.8.5",
"dotenv": "^17.2.3",
"drizzle-orm": "^0.38.2",
"express": "^4.18.2",
"get-tsconfig": "^4.10.0",
"jsdom": "^25.0.1",
"lucide-react": "^0.561.0",
"next-themes": "^0.4.6",
"react-hook-form": "^7.71.1",
"react-markdown": "^10.1.0",
"react-transition-group": "^4.4.5",
"recharts": "^2.12.5",
"remark-gfm": "^4.0.1",
"sonner": "^2.0.7",
"tailwind-merge": "^3.4.0",
"tailwindcss-animate": "^1.0.7",
"tinykeys": "^3.0.0",
"tsx": "^4.19.2",
"vaul": "^1.1.2",
"zod": "^3.23.8"
},
"devDependencies": {
"@biomejs/biome": "2.3.12",
"@tailwindcss/postcss": "^4.1.18",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.1",
"@types/better-sqlite3": "^7.6.8",
"@types/cors": "^2.8.17",
"@types/express": "^4.17.21",
"@types/jsdom": "^27.0.0",
"@types/node": "^22.10.1",
"@types/react": "18.3.12",
"@types/react-dom": "18.3.1",
"@types/react-transition-group": "^4.4.12",
"@vitejs/plugin-react": "^4.3.4",
"autoprefixer": "^10.4.22",
"concurrently": "^9.1.0",
"drizzle-kit": "^0.30.1",
"postcss": "^8.5.6",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^7.0.2",
"tailwindcss": "^4.1.18",
"tw-animate-css": "^1.4.0",
"typescript": "^5.7.2",
"vite": "^6.0.3",
"vitest": "^4.0.16"
},
"optionalDependencies": {
"@rollup/rollup-linux-arm64-gnu": "^4.30.0",
"@rollup/rollup-linux-x64-gnu": "^4.30.0",
"@tailwindcss/oxide-linux-arm64-gnu": "4.1.18",
"@tailwindcss/oxide-linux-x64-gnu": "4.1.18",
"lightningcss-linux-arm64-gnu": "^1.29.3",
"lightningcss-linux-x64-gnu": "^1.29.3"
}
}