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

TASKS: VoiceTask

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).

  • T1 Scaffold

    • 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.
    • Depends: nothing
    • Verify: npm run typecheck and npm test and npm run build all exit 0.
  • T2 Shared types and session store

    • 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).
    • Depends: T1
    • Verify: npm test (store unit tests: create/reload roundtrip, sequential segment ids S1..Sn, list).
  • T3 Provider interfaces, factory, mocks

    • 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).
    • Depends: T2
    • Verify: npm test (mock behavior tests: echo, turn script reaches done, factory returns mocks under MOCK_PROVIDERS=1).
  • T4 Session and answer routes

    • 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).
    • Depends: T3
    • Verify: npm test (route tests via fastify.inject: create, answer produces interviewer segment + coverage update, done ends session).
  • T5 Interview engine

    • 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).
    • Depends: T4
    • Verify: npm test (engine tests with llmMock: coverage progresses in category order, >40 segments triggers summary path, contradiction from mock is surfaced).
  • T6 Audio route and OpenAI STT

    • @fastify/multipart upload route POST /api/sessions/:id/audio, sttOpenai.ts per PLAN.md, empty-transcript rejection, provider errors mapped to 502 with {error}.
    • Depends: T4
    • Verify: npm test (audio route with sttMock: uploaded text buffer becomes a segment and triggers a turn; empty buffer returns 4xx and stores nothing).
  • T7 Client: interview UI

    • Session list/create screen, interview screen with Transcript, QuestionCard, CoveragePanel, text input, Done button. Typed api.ts wrappers. Vite dev proxy to the server.
    • Depends: T4 (T5 makes it meaningful, but the API contract is enough to build against)
    • 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.
  • T8 Client: push-to-talk and TTS

    • 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.
    • Depends: T6, T7
    • Verify: npm run typecheck and npm run build exit 0. Manual: recording in Chrome produces a segment (mock mode).
  • T9 Spec pack generator

    • 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.
    • Depends: T5
    • 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).
  • T10 Generate route and UI

    • POST /api/sessions/:id/generate, GeneratePanel with missing-category confirmation dialog per FR-008, result/warnings display.
    • Depends: T7, T9
    • Verify: npm test (route test) and npm run typecheck.
  • T11 Blocker import

    • 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.
    • Depends: T5, T7
    • Verify: npm test (parser tests incl. empty file; route test: import then next turn asks a blocker question).
  • T12 End-to-end smoke test

    • 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.
    • Depends: T9, T10
    • Verify: npm test runs it green; then npm run typecheck, npm test, npm run build all exit 0 as the final full check.
  • T13 Non-technical onboarding pass

    • 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.
    • Depends: T7
    • Verify: npm run typecheck and npm run build exit 0. Manual: every category in CoveragePanel shows a plain-language label, not a CategoryId.
  • T14 Folder browser

    • 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.
    • Depends: T7
    • 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.
  • T15 Export: spec pack zip and transcript

    • 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.
    • Depends: T9, T10
    • 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.
  • T16 Cross-platform offline demo and verification

    • 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.
    • Depends: T15
    • 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.
  • T17 Mainstream first-run explanation

    • 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.
    • Depends: T16
    • 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.
  • T18 Easier interview controls and progress

    • 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.
    • Depends: T17
    • 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.
  • T19 Clear completion and user-driven sharing

    • 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.
    • Depends: T18
    • 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.
  • T20 Mainstream documentation and final product check

    • 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.
    • Depends: T19
    • Verify: npm run check exits 0 and git diff --check reports no errors.
  • T21 Language-correct speech and keyboard access

    • 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.
    • Depends: T20
    • 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.
  • T22 In-app provider setup

    • 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.
    • Depends: T21
    • 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.