Part of the WebLLM-native JD-matching redesign (anchor: #156, milestone M6 · JD Matching v2).
Goal
Move JD-match interaction state out of App.tsx into a hook, supporting the async semantic path.
Scope
- New
src/hooks/useJdMatch.ts — async state machine mirroring useResumeRewrite (idle → loading → running → ready → error) plus a synchronous keyword fast-resolve branch when WebGPU is absent or the user hasn't opted in.
- Replace the synchronous
useMemo JD pipeline in App.tsx:82-90 with the hook.
- Reuse
useModelSelection, detectWebGpu, loadEngine progress callback.
Constraints
App.tsx stays thin (CLAUDE.md: cross-cutting interaction state belongs in src/hooks/).
- Keyword behavior unchanged when path resolves to
keyword.
Done when
App.tsx consumes useJdMatch; keyword users see no change; semantic users get the loading/running/ready states.
Part of the WebLLM-native JD-matching redesign (anchor: #156, milestone M6 · JD Matching v2).
Goal
Move JD-match interaction state out of
App.tsxinto a hook, supporting the async semantic path.Scope
src/hooks/useJdMatch.ts— async state machine mirroringuseResumeRewrite(idle → loading → running → ready → error) plus a synchronouskeywordfast-resolve branch when WebGPU is absent or the user hasn't opted in.useMemoJD pipeline inApp.tsx:82-90with the hook.useModelSelection,detectWebGpu,loadEngineprogress callback.Constraints
App.tsxstays thin (CLAUDE.md: cross-cutting interaction state belongs insrc/hooks/).keyword.Done when
App.tsxconsumesuseJdMatch; keyword users see no change; semantic users get the loading/running/ready states.