profileShare

rasmusjy / voicetask

Read-only snapshot

No repository description.

main default branch 105 files Expires Sep 13, 2026, 9:06 AM
TASKS.md 12,037 bytes
1 # TASKS: VoiceTask
2
3 Work strictly in order unless a task's Depends line allows otherwise. One task at a time. Run the Verify commands before checking a task off. All tests run with `MOCK_PROVIDERS=1` (vitest config sets it globally).
4
5 - [x] T1 Scaffold
6 - npm package with `server/`, `client/` (Vite React TS template), `shared/`. Scripts: `dev` (server + Vite concurrently), `build`, `typecheck` (tsc --noEmit over all three), `test` (vitest run). Add zod, fastify + plugins, @anthropic-ai/sdk, vitest. One placeholder test that asserts true.
7 - Depends: nothing
8 - Verify: `npm run typecheck` and `npm test` and `npm run build` all exit 0.
9
10 - [x] T2 Shared types and session store
11 - Implement `shared/` types + zod schemas from PLAN.md. Implement `server/store/sessionStore.ts`: create, get, list, append segment, update coverage/summary/status, persisted to `data/sessions/<id>/session.json` atomically (write temp file, rename).
12 - Depends: T1
13 - Verify: `npm test` (store unit tests: create/reload roundtrip, sequential segment ids S1..Sn, list).
14
15 - [x] T3 Provider interfaces, factory, mocks
16 - `server/providers/types.ts`, `factory.ts`, `sttMock.ts`, `llmMock.ts` exactly as specified in PLAN.md (including the echo-text behavior of sttMock and the deterministic interview script and bad-marker SPEC.md of llmMock).
17 - Depends: T2
18 - Verify: `npm test` (mock behavior tests: echo, turn script reaches done, factory returns mocks under MOCK_PROVIDERS=1).
19
20 - [x] T4 Session and answer routes
21 - `POST /api/sessions`, `GET /api/sessions`, `GET /api/sessions/:id`, `POST /api/sessions/:id/answer` wired to store + interview engine stub that calls the InterviewLlm provider. "done" detection per SPEC (exact match, case-insensitive, trimmed).
22 - Depends: T3
23 - Verify: `npm test` (route tests via fastify.inject: create, answer produces interviewer segment + coverage update, done ends session).
24
25 - [x] T5 Interview engine
26 - `server/engine/`: coverage state handling, prompt construction (summary + last 40 segments), summary maintenance, contradiction passthrough from the LLM response, weakest-category question selection enforced in the prompt. Anthropic implementation `llmAnthropic.ts` per PLAN.md (compiles and is unit-tested for prompt construction only; no network in tests).
27 - Depends: T4
28 - Verify: `npm test` (engine tests with llmMock: coverage progresses in category order, >40 segments triggers summary path, contradiction from mock is surfaced).
29
30 - [x] T6 Audio route and OpenAI STT
31 - `@fastify/multipart` upload route `POST /api/sessions/:id/audio`, `sttOpenai.ts` per PLAN.md, empty-transcript rejection, provider errors mapped to 502 with `{error}`.
32 - Depends: T4
33 - Verify: `npm test` (audio route with sttMock: uploaded text buffer becomes a segment and triggers a turn; empty buffer returns 4xx and stores nothing).
34
35 - [x] T7 Client: interview UI
36 - Session list/create screen, interview screen with Transcript, QuestionCard, CoveragePanel, text input, Done button. Typed api.ts wrappers. Vite dev proxy to the server.
37 - Depends: T4 (T5 makes it meaningful, but the API contract is enough to build against)
38 - Verify: `npm run typecheck` and `npm run build` exit 0. Manual: `npm run dev` with MOCK_PROVIDERS=1, typing answers advances coverage in the panel.
39
40 - [x] T8 Client: push-to-talk and TTS
41 - MediaRecorder hold-to-record button (spacebar and mouse), upload to the audio route, recording state indicator. TTS toggle speaking each new interviewer question via speechSynthesis.
42 - Depends: T6, T7
43 - Verify: `npm run typecheck` and `npm run build` exit 0. Manual: recording in Chrome produces a segment (mock mode).
44
45 - [x] T9 Spec pack generator
46 - `server/generator/`: five per-file prompts, generation orchestration through the InterviewLlm provider, `sources.json` emission, provenance validation per FR-013, existing-file refusal + `overwrite` flag + backup to `spec/backup-<timestamp>/` on regenerate.
47 - Depends: T5
48 - Verify: `npm test` (with llmMock into a temp dir: all six files written; bogus `[S999]` marker removed and `[unverified]` appended; second run without overwrite fails; with overwrite creates backup dir).
49
50 - [x] T10 Generate route and UI
51 - `POST /api/sessions/:id/generate`, GeneratePanel with missing-category confirmation dialog per FR-008, result/warnings display.
52 - Depends: T7, T9
53 - Verify: `npm test` (route test) and `npm run typecheck`.
54
55 - [x] T11 Blocker import
56 - `server/blockers/parse.ts` for the BLOCKED.md format defined in the repo root `BLOCKED.md` template, `POST /api/sessions/:id/blockers`, engine mode that asks only imported questions, UI entry point. Missing/empty file handled per SPEC edge case.
57 - Depends: T5, T7
58 - Verify: `npm test` (parser tests incl. empty file; route test: import then next turn asks a blocker question).
59
60 - [x] T12 End-to-end smoke test
61 - Single vitest test: boot the server with mocks, create session (temp target dir), answer until done via the answer route, generate, assert all six files exist, all remaining `[S<n>]` markers resolve against sources.json, and HANDOFF.md contains the string `claude`.
62 - Depends: T9, T10
63 - Verify: `npm test` runs it green; then `npm run typecheck`, `npm test`, `npm run build` all exit 0 as the final full check.
64
65 - [x] T13 Non-technical onboarding pass
66 - `client/src/labels.ts` maps each `CategoryId` to a plain-language label and one-line explanation used by `CoveragePanel`. Rewrite session-list and interview-screen copy (headings, empty states, button text) to not assume the reader is a developer. Update `buildInterviewSystemPrompt` in `llmAnthropic.ts` to instruct plain-language, jargon-free questions per updated SPEC FR-006.
67 - Depends: T7
68 - Verify: `npm run typecheck` and `npm run build` exit 0. Manual: every category in CoveragePanel shows a plain-language label, not a `CategoryId`.
69
70 - [x] T14 Folder browser
71 - `server/routes/fs.ts`: `GET /api/fs/browse` (defaults to the OS home directory, lists subdirectories, returns `{path, parent, directories}`), `POST /api/fs/mkdir` (creates one subdirectory). Shared zod schemas for both. `client/src/components/FolderBrowser.tsx`: modal that navigates the tree, creates a folder, and returns the chosen path to the session-create form; the raw text input stays available alongside it.
72 - Depends: T7
73 - Verify: `npm test` (route tests: browse lists directories and a parent, browsing an unreadable path returns a 4xx, mkdir creates a directory and 4xxs on a duplicate name) and `npm run typecheck`. Manual: browsing, creating a folder, and selecting it fills the target directory field.
74
75 - [x] T15 Export: spec pack zip and transcript
76 - `shared/transcript.ts`: `formatTranscript(segments)` plain-text renderer. `server/exporter/zip.ts`: dependency-free ZIP (STORE method) writer. `GET /api/sessions/:id/export/spec-pack.zip` (404 with a clear error if `spec/` doesn't exist yet in the target directory) and `GET /api/sessions/:id/export/transcript.md`. Client: a transcript "Copy" / "Download" control usable at any time, and a "Download spec pack (.zip)" button in `GeneratePanel` that appears once a pack exists.
77 - Depends: T9, T10
78 - Verify: `npm test` (zip writer roundtrips through Node's own unzip via a temp-file check or a byte-level structural check; export route: 404 before generate, 200 with correct `Content-Type`/`Content-Disposition` after) and `npm run typecheck`. Manual: after generating, the zip downloads and contains all six files; transcript copy/download works mid-interview.
79
80 - [x] T16 Cross-platform offline demo and verification
81 - Add `npm run demo`, with an explicit server flag that forces mock providers after `.env` is loaded. Replace test calls to the external `unzip` command with dependency-free byte-level ZIP checks so the full suite passes on Windows, macOS, and Linux.
82 - Depends: T15
83 - Verify: `npm run typecheck`, `npm test`, and `npm run build` exit 0. Manual: with a real-provider `.env` present, `npm run demo` reports mock providers and opens no provider connection.
84
85 - [x] T17 Mainstream first-run explanation
86 - Redesign the home screen around a direct outcome statement, the three-part flow, local privacy, and a representative source-backed requirement. Make folder browsing the obvious path, add plain helper copy to both fields, and keep earlier sessions easy to resume. Implement the visual system and responsive layout in PLAN.md without a UI dependency.
87 - Depends: T16
88 - Verify: `npm run typecheck` and `npm run build` exit 0. Static audit: every first-run claim maps to an existing requirement and all interactive controls have visible keyboard focus.
89
90 - [x] T18 Easier interview controls and progress
91 - Change the microphone to click once to record and click again to send, while keeping Space as hold-to-talk outside controls. Add explicit idle, recording, sending, and error copy. Replace the coverage count and color-only dots with plain progress language and per-category status labels.
92 - Depends: T17
93 - Verify: `npm run typecheck` and `npm run build` exit 0. Manual: mouse click toggles one recording, Space still records only while held, and coverage statuses are understandable without color.
94
95 - [x] T19 Clear completion and user-driven sharing
96 - Add a HEAD readiness check for the existing spec-pack export. Redesign the completed state around the primary zip download, recipient guidance, a copyable project handoff message, and a secondary generated-file disclosure. Add a separate optional VoiceTask recommendation action using the canonical repository link. Clipboard failures must be visible.
97 - Depends: T18
98 - Verify: `npm test`, `npm run typecheck`, and `npm run build` exit 0. Tests cover the readiness check plus deterministic handoff and recommendation copy. Manual: refresh a completed session with an existing pack and confirm the download remains visible.
99
100 - [x] T20 Mainstream documentation and final product check
101 - Rewrite README.md for a first-time evaluator: outcome, audience, what the pack contains, one-command offline demo, real-provider setup, privacy, and the send-to-someone flow. Update VERIFICATION.md to use cross-platform commands and run the complete product gate.
102 - Depends: T19
103 - Verify: `npm run check` exits 0 and `git diff --check` reports no errors.
104
105 - [x] T21 Language-correct speech and keyboard access
106 - Distinguish audio sending from typed-answer waiting in microphone copy. Select speech voices by browser locale and default status instead of hardcoding English. Announce new questions, expose focus on the read-aloud switch, and contain and restore focus in the folder dialog.
107 - Depends: T20
108 - Verify: `npm test`, `npm run typecheck`, and `npm run build` exit 0. Voice-selection tests cover locale match, default fallback, and an empty voice list.
109
110 - [x] T22 In-app provider setup
111 - Start the server without keys instead of exiting. Add `GET /api/config` and `POST /api/config` (`server/routes/config.ts`, `server/config/runtimeConfig.ts`): report the provider mode and key hints, save the offline demo or one or both keys into the local `.env` without losing the rest of that file, and apply them to the running process. Resolve providers per request so a saved key works without a restart. A server started with `npm run demo` stores keys but stays on mocks and reports that a restart is needed. Accept writes only from the local app origin. Add `client/src/components/ProviderSetup.tsx`, show it in place of the create form until a mode is chosen, and show the current mode in the home header. Turn a missing key into a plain-language 503 instead of a generic server error.
112 - Depends: T21
113 - Verify: `npm test`, `npm run typecheck`, and `npm run build` exit 0. Tests cover the .env merge, demo-locked saving, key hints that never contain the key, the missing-key error, and origin rejection. Manual: with no `.env`, `npm run dev` starts, the browser asks for setup, and saving keys starts an interview without restarting the server.
114