feat: implement the IMPROVEMENTS.md backlog (all 50 items) - #43
Conversation
X1 — release-prep now runs lint, test, build, check-tokens, check-strings, and cargo fmt --check in a gate job before any version bump, tag, or push lands on main. X3 — ci.yml frontend job runs check-strings next to check-tokens so the strings-module house rule has a CI backstop. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The new-version check (OFF by default) is the one sanctioned outbound request beyond P2P + Nostr signaling: an unauthenticated GET to the public GitHub Releases API carrying no identifiers, no query parameters, and no payload; failures are silent. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
N1 — single-instance guard; relaunch focuses the existing window. F10 — studyvis:// registered as an OS deep link (plugin config, capability, argv forwarding; subscribePairDeepLink helper lands unwired until the friends cluster routes it into the accept flow). N4 — quit-confirm scaffolding: SessionActiveFlag, session_set_active, app_quit, quit-requested event; macOS Cmd+Q rerouted through a custom menu item since NSApp.terminate can't be intercepted. D2 — corrupt app.db is set aside and recreated with an explanatory dialog instead of a startup panic; healthy-but-unopenable data is never destroyed. D6 — a DB created by a newer build is refused with a distinct 'update needed' dialog, no rename/recreate. R4 — sessions_delete / sessions_clear_all commands (tx-scoped, audit events included). D3 — friends_export / friends_import commands (sealed-box to the user's own X25519 key, SVFB v1 format, upsert on import). A4 — model downloads resume via HTTP Range from the surviving .tmp, hasher seeded from existing bytes. X4 — system_fetch_latest_version command (bare GET, no identifiers, 10s timeout; UI toggle ships OFF by default later). X5 — ad-hoc signingIdentity '-' with hardenedRuntime false so the sidecar's DYLD-based dylib resolution survives release signing. X6 — dormant tauri-plugin-updater removed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ath, confidence floor, cadence backoff, resume affordance A1 — benchmark, live loop, and the ai-eval harness all build their chat request through one shared focusRequest builder (two images, same system prompt, max_tokens, response_format); the benchmark's screen slot is letterboxed to live capture width so Qwen's dynamic-resolution prefill is no longer understated. A2 — malformed/empty model responses become an internal 'uncertain' verdict: streak and latches untouched, sample excluded from focusedPct via a separate skipped tally; 'uncertain' provably never reaches the signed ai-alert wire or the audit vocabulary. A3 — off-task judgments carrying >= floor on-topic confidence are skipped as uncertain; floor persisted as off_task_confidence_floor (default 0.6) with a Settings -> AI slider (UI min 0.05; 0 stays a programmatic disable). A5 — the tick re-reads the sidecar port after the capture await and bails/reschedules when the watcher respawned the server. A6 — duration-based cadence backoff (2 slow ticks engage x2 interval, 3 normal ticks recover) with a one-shot in-voice notice; replaces the dangling 'thermal-aware notice' comment. A4 — interrupted downloads persist their real byte offset (terminal events hardcode 0; the container stashes downloading-phase counts) and the picker shows an honest 'Resume download' affordance. 487 unit tests pass (35 added); tsc/lint/tokens/strings/prettier green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…, camera toggle, output audio, connection states, quit confirm S1 — a 20s grace window before auto-ending when the room empties; any rejoin cancels it, seenPeerEdPubkeys survives the gap, and buildLeaveHandler's alreadyLeft latch stays the one idempotency point. S2 — PTT can no longer latch the mic open: pttStore.reset() on every session start/teardown (host/join/SessionView), plus a 120s stuck-key guard tuned for macOS global hotkeys (no key-repeat events); a stale latch can never bring a fresh session's first audio track up live. R1 — snapshotFocusForReport returns score:null when no confident samples exist; the report renders a calm no-score state instead of a fabricated 100/100 gauge and stats averages skip nulls. S3 — camera on/off toggle flips track.enabled (stream stays monotonic), broadcasts a backward-compatible camera-state action so peers render an explicit camera-off tile, and pauses the AI loop without counting ticks against the user. S4 — audio output picker (feature-detected; hidden on macOS WKWebView) and a per-peer local-only volume slider. U2 — a §10-pattern waiting tile when alone in an active session. F4 — per-peer RTCPeerConnection state surfaces as connecting/failed tile badges; transient 'disconnected' stays 'connecting', no TURN. N4 — session_set_active wired at one status-keyed chokepoint and a quit-requested listener with an in-app confirm dialog backing the wave-1 Rust scaffolding. 504 unit tests pass (17 added); all frontend gates green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…retry, presence goodbye, OS deep link F1 — relay-down detection driven by the live socket map (relaysUnreachable): the pairing dialog's 30s hint now distinguishes 'can't reach the network' (your side) from 'friend hasn't arrived'; onJoinError is forwarded through the wrapper and correctly mapped to handshake failure, which is the only thing trystero fires it for. F2 — NetworkCategory connection panel: per-relay state rows polled while visible, state shown by glyph + text, never color alone. F3 — user-supplied relay URLs and a TURN server persist in settings and flow through the existing relayConfig/buildIceOptions seams; URL validation mirrors new WebSocket() so a malformed saved relay can't white-screen the boot (inbox/presence joins also guarded); the turnPreference radio finally does something when TURN exists. F5 — 45s post-peer-arrival stall timer: 'connected to the network but couldn't establish a direct link' with a pointer to relay/TURN settings. F6 — invites re-attempt when the friend flips online within the retry window, deduped per recipient+session so a friend can never receive the same invite twice; offline-friend vs relay-down failures read differently. F7 — best-effort goodbye on quit flips presence offline immediately; wire-compatible both directions (goodbye omits ts so older receivers drop it and age out via the 60s window; I2 receiver-clock intact). F9 — QR error correction M→Q, larger module size, and a freshness note for the ~10-minute secret. F10 — OS-delivered studyvis://pair links prefill (never auto-connect) the join form; a second link can't discard a half-typed code. F8 — settings copy, README, PLAN §2/§7, and ARCHITECTURE stop promising a public TURN fallback that no longer ships. 540 unit tests pass (36 added); build, tsc, lint, tokens, strings, contrast, prettier all green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…eletion
R7 — local-only focus-insights section in the stats dashboard:
when-distractions-happen timing buckets anchored on session start,
recurring distraction reasons aggregated across sessions (lifting
reportData's per-session aggregation), and a focused-time/score trend
chart; data shaped in a pure statsInsights seam reading audit_events
via a new audit_events_list_all command.
R3 — 'Save as…' for the report (markdown), a per-session raw audit
JSON dump, and a stats CSV of daily study minutes + partner counts,
all through the system save dialog and a new system_write_text_file
command (no fs-plugin surface added).
R4 — per-session delete (SessionsCategory, confirm dialog) and
clear-all-history (AdvancedCategory, stronger confirm) over the
wave-1 sessions_delete/sessions_clear_all commands; lists refresh
after deletion.
R2 — stats label renamed 'Study minutes'; 'Focused' is reserved for
the AI on-task concept.
R5 — serialized report sections now match the on-screen order.
R6 — the average-score tile says how many sessions it covers
('from N of M sessions') with a muted limited-data state.
Review caught and fixed a wire-shape blocker: AuditEventRecord
declared camelCase sessionId against serde's snake_case session_id,
which would have left the timing section permanently empty while
fixture-based tests passed.
567 unit tests pass (27 added); a11y suite 242 axe checks green;
cargo + all frontend gates green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…g back, friends backup UI D1 — a corrupt/unreadable identity.json routes to a calm error screen (Retry + Restore) and can never reach create-new onboarding; the commit path is double-guarded (frontend re-check + identity_save_keys overwrite flag in Rust) so create refuses to clobber keychain keys, with steering copy toward Restore when orphaned keys exist. D4 — the dead 'Recovery phrase' settings row is honest (24 words can't be re-shown, by design) and actionable: 'Restore a different identity' opens the existing Recover flow from Settings. D5 — recovery compares the typed words' fingerprint to the stored one: same words skip the warning, unknown gets the generic confirm, different words get escalated replace-identity copy; the done screen no longer tells same-identity users to re-pair, and a Settings restore preserves the display name instead of silently blanking it. D3 — Export/Import friends buttons (sealed .svfriends backup via the wave-1 commands), different-identity decrypt errors mapped to friendly copy, list refreshes after import, zero-friends export writes nothing. U1 — invite button always visible (outline at rest, accent on hover/focus) instead of hover-only. U3 — onboarding gains Back per the §8.1 wireframe, suppressed once a mnemonic is committed. U4 — zero-friends empty state keeps one CTA. U6 — SessionTimer presets use the RadioGroup primitive (themed focus ring, arrow-key nav). 572 unit tests pass; cargo, a11y (246 axe checks), and all frontend gates green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s, custom durations, audio cue, opt-in version check N2 — OS notification on local work↔rest boundaries (opt-out, ON by default), suppressed while the window is visible and focused; reuses the InboxBoot permission pattern; no I9 protocol change. N3 — 'friend came online' notification (opt-in, OFF by default), baseline-aware so boot sweeps, resubscribe ticks, and 60s-window flapping never fire it; help copy honest about presence latency. N5 — custom pomodoro durations (5–120 work / 1–60 rest) with a backward-compatible wire: explicit work_ms/rest_ms ride alongside a strictly-legacy preset fallback, so old peers render legacy timings and never see 'custom'; new receivers prefer explicit durations; a 90/20 handover survives a broadcaster drop without retiming. Compat matrix tested against a frozen copy of the shipped parser. N6 — gentle two-note chime on phase transitions (opt-in, OFF by default), 1.7KB opus inlined as a data URI per the V2-P6 pattern. X4 — 'Check for new versions' toggle (OFF by default) in About; when on, a single bare GET on mount compares tags and shows a quiet update row; zero outbound while off, silent on failure (PLAN §3 carve-out). 600 unit tests pass (4 suites added); a11y 247 checks, build with inlined chime verified, all frontend gates green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… (U5) scripts/check-contrast.ts gains an AST-based coverage scanner: every text-*/bg-*/border-* token co-occurrence in src/ (plain className, cn()/cva() args incl. variant objects and ternary arms, template literals, modifier-prefixed classes like hover:/focus-visible:/ data-[state]:) must have a PAIRINGS entry or the script fails, naming the file, the combo, and the fix path. A narrowly-scoped IGNORED_COOCCURRENCES list (file + combo + required reason, stale entries fail) handles cross-state false adjacencies. Surfaced 18 unlisted real pairings across the earlier clusters — all added and AA-verified in both themes (idle hairline borders stay informational per WCAG 1.4.11). Review probes confirmed the scanner catches planted violations in all class-shape forms and that cva variants and hover-prefixed utilities — the two proven blind spots — are now visible. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
PLAN — Linux deferral becomes a concrete unblock checklist and the signing/notarization/auto-update stack is one credential-gated roadmap item (trigger: certs acquired), both under a new deferred- scope section; §3 carve-out verified against the shipped X4. ARCHITECTURE — plaintext-at-rest threat-model row (§14); the implemented cadence backoff + uncertain-skip replace the dangling thermal-notice claim (§8); camera-state, pomodoro work_ms/rest_ms, and presence goodbye join the wire inventory with compat rationale (§7); invite retry vs relay-down distinction (§6); cross-session audit reads for focus insights (§9); new plugins and the nine new IPC commands inventoried (§2/§11). DESIGN-SYSTEM — stale BipBackupPanel note fixed (U7); new visual components added to the §4 inventory. INSTALL/README — Intel x64.dmg claim dropped (Apple Silicon only); Gatekeeper language softened for ad-hoc-signed builds, xattr quarantine fallback kept. ISSUES — I19 Sev4: npm-audit advisories are dev-chain only (npm audit --omit=dev is clean), count-free so it doesn't go stale. CHANGELOG — Unreleased section covering all eight clusters with their settings defaults. Audit pass cite-checked every claim against the committed code; stale counts and a wrong ON CONFLICT column name were corrected. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…backups, DB lock safety F3 boot race (major) — boot-mounted presence/inbox joined trystero before async settings hydration, and trystero pins its relay sockets on the first joinRoom for the process lifetime, so saved custom relays were silently ignored on most boots. InboxBoot now waits for settings hydration before the first join. friends_import authenticity (major) — a sealed box proves confidentiality, not authorship: any friend holding the user's X25519 pubkey could mint an importable backup and hijack x_pubkeys via the ed_pubkey upsert. SVFB v2 Ed25519-signs the payload with the user's own key and import verifies it; per-row pubkey validation and a 10k-row cap added. v1 never shipped, so no migration. DB lock split-brain (advisor) — the corruption probe now only declares corruption on an actual non-ok integrity_check verdict; a locked/busy DB bails as unrecoverable instead of being renamed and recreated. PTT re-acquire (minor) — the S2 reset moved off the media-retry effect so a mid-hold 'Try again' re-acquire keeps the documented unmuted contract; leave/auto-end/unmount resets unchanged. Doc/CI residues — PLAN §2 Apple-Silicon-only wording, release-notes body reflects ad-hoc signing, release-prep gate gains check-contrast. All gates green: 600 vitest, build, lint, tokens, strings, contrast, prettier, storybook a11y, cargo test/fmt/clippy. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Important Review skippedToo many files! This PR contains 169 files, which is 19 over the limit of 150. To get a review, narrow the scope: ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (169)
You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
This PR is a broad “backlog catch-up” that touches the desktop (Tauri) runtime, networking/presence flows, AI sampling + scoring, session robustness, stats/reporting/export, and corresponding unit/integration tests and Storybook coverage.
Changes:
- Adds friend-finding and session reliability improvements (relay diagnostics, relay/TURN settings, invite retry, presence goodbye, connection-state UX, PTT failsafes, quit confirmation, deep-link pairing).
- Refactors and hardens AI request/parsing/scoring behavior (shared focus request builder, “uncertain” parse fallback, confidence floor, download resume bookkeeping).
- Expands stats/reporting/export and identity safety flows (no-score sessions, report serialize order, CSV/text export helpers, identity load error + safer recovery/overwrite semantics).
Reviewed changes
Copilot reviewed 168 out of 171 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/version.test.ts | Unit coverage for semver-ish version comparison used by opt-in update check. |
| tests/unit/v2p9-ai-toggle.test.ts | Verifies off-task confidence floor persistence in settings store. |
| tests/unit/trystero-wrapper.test.ts | Tests joinTopic callback forwarding + relay socket map exposure. |
| tests/unit/stats-data.test.ts | Renames “focused minutes” helpers to “study minutes” and updates tests. |
| tests/unit/settings-network.test.ts | Adds relay/TURN URL validation + parsing tests. |
| tests/unit/settings-migration.test.ts | Adds migration/hydration tests for off-task confidence floor defaults/round-trip. |
| tests/unit/session-connection-state.test.ts | Pins mapping from RTCPeerConnection states to tile focus states. |
| tests/unit/report-serialize.test.ts | Tests report serializer section ordering + score/no-score lines. |
| tests/unit/report-data.test.ts | Aligns audit event record field names to snake_case session_id. |
| tests/unit/relay-diagnostics.test.ts | Tests relay readyState mapping + unreachable detection. |
| tests/unit/recoverLogic.test.ts | Tests overwrite-decision logic based on mnemonic fingerprint matching. |
| tests/unit/ptt-store.test.ts | Tests PTT reset + max-hold failsafe via injectable scheduler. |
| tests/unit/presence.test.ts | Tests presence goodbye behavior for immediate offline transitions. |
| tests/unit/pomodoro-notify.test.ts | Unit tests for local pomodoro boundary detection + notification/chime gating. |
| tests/unit/pomodoro-custom-bounds.test.ts | Tests custom pomodoro duration clamping bounds. |
| tests/unit/ice.test.ts | Adds tests for mapping user TURN server config to ICE options. |
| tests/unit/ai-parse.test.ts | Updates parse fallback expectations to “uncertain” verdict behavior. |
| tests/unit/ai-models.test.ts | Tests interrupted-download recording/clearing behavior in model store. |
| tests/unit/ai-benchmark.test.ts | Updates benchmark fixture/runtime to match new shared focus request shape. |
| tests/integration/session.test.ts | Updates integration expectations for disconnect grace + AI-off score persistence. |
| tests/integration/pomodoro.test.ts | Updates pomodoro start API + adds custom-duration handover test. |
| tests/integration/pair.test.ts | Adds post-arrival stall detection test for pairing flow. |
| tests/integration/invite.test.ts | Adds relay-unreachable vs friend-offline error distinction coverage. |
| tests/ai-eval/RESULTS.md | Documents “uncertain” column semantics in eval confusion matrix. |
| src/stories/WaitingTile.stories.tsx | Storybook stories for new waiting tile variants and layouts. |
| src/stories/VideoTile.stories.tsx | Adds stories for connecting/failed/camera-off/volume states. |
| src/stories/SettingsCategories.stories.tsx | Updates IdentityCategory story signature to include restore callback. |
| src/stories/SessionTimer.stories.tsx | Adds custom pomodoro story and updates interactive start API. |
| src/stories/Report.stories.tsx | Aligns audit event record keys + no-AI baseline score null behavior. |
| src/stories/RelayDiagnostics.stories.tsx | Stories for relay diagnostics panel states. |
| src/stories/Recover.stories.tsx | Adds story for “different identity” overwrite confirmation. |
| src/stories/Onboarding.stories.tsx | Wires back navigation into onboarding step stories. |
| src/stories/ModelPicker.stories.tsx | Adds story for resumable/interrupted model download state. |
| src/stories/IdentityLoadError.stories.tsx | Storybook coverage for identity load error screen. |
| src/stories/IdentityChoiceStep.stories.tsx | Adds “WithBack” story for identity choice step. |
| src/stories/FocusInsights.stories.tsx | Storybook coverage for focus insights view with synthetic data. |
| src/stories/Dashboard.stories.tsx | Updates dashboard stories to include focus insights data. |
| src/stories/AudioOutputPicker.stories.tsx | Storybook story for audio output picker. |
| src/stories/AddFriendDialog.stories.tsx | Adds network-trouble/link-stalled phase stories for pairing UI. |
| src/stores/pttStore.ts | Adds reset() + max-hold failsafe with injectable scheduler seams. |
| src/stores/pomodoroStore.ts | Extends snapshot shape to include explicit work/rest durations. |
| src/stores/identityStore.ts | Adds error identity status + overwrite-safe commit path. |
| src/stores/auditStore.ts | Aligns audit event insert payload to snake_case session_id record. |
| src/lib/version.ts | Adds minimal version parsing/comparison helper for opt-in update check. |
| src/lib/trystero/relays.ts | Adds user-configurable relay override resolver from settings store. |
| src/lib/trystero/index.ts | Adds relay socket map accessor + join error handler forwarding. |
| src/lib/trystero/ice.ts | Incorporates user TURN server into ICE option building. |
| src/lib/relayDiagnostics.ts | Adds pure helpers for relay status snapshotting and reachability checks. |
| src/lib/pomodoro-types.ts | Adds custom preset + bounds clamping + enriched snapshot/start args types. |
| src/lib/fileExport.ts | Adds save-text-file orchestration + slug/date/CSV helpers. |
| src/lib/db/sessions.ts | Adds session delete + clear-all DB commands. |
| src/lib/db/identity.ts | Extends identity key save API to require explicit overwrite flag. |
| src/lib/db/audit.ts | Aligns AuditEventRecord keys + adds list-all audit events API. |
| src/features/system/QuitConfirmListener.tsx | Adds quit-confirm dialog flow triggered by Rust event while in session. |
| src/features/system/PttListener.tsx | Documents no blur-release; relies on store failsafe + per-session reset. |
| src/features/system/PomodoroNotifyListener.tsx | Adds app-wide local pomodoro transition observer. |
| src/features/system/index.ts | Exports new system listeners. |
| src/features/stats/statsData.ts | Renames study-minutes helpers + adds stats CSV model builder. |
| src/features/stats/index.ts | Re-exports insights + CSV model + renamed study-minutes helpers. |
| src/features/settings/Settings.tsx | Adds “restore identity” full-screen flow and wires callback into IdentityCategory. |
| src/features/settings/categories/NotificationsCategory.tsx | Adds toggles for pomodoro + friend-online notification settings. |
| src/features/settings/categories/AiCategory.tsx | Adds off-task confidence floor slider with UI min clamp. |
| src/features/settings/categories/AboutCategory.tsx | Adds opt-in version check toggle + “update available” row. |
| src/features/session/pomodoroSound.ts | Adds local chime sound runtime (injectable for tests). |
| src/features/session/pomodoroNotify.ts | Adds transition detection + side-effect handler for notifications/chime. |
| src/features/session/join.ts | Resets PTT store at session join for privacy/safety. |
| src/features/session/host.ts | Resets PTT store at session host start for privacy/safety. |
| src/features/session/audioDevices.ts | Adds audio output enumeration + setSinkId feature detection. |
| src/features/onboarding/TutorialStep.tsx | Adds optional back navigation secondary action. |
| src/features/onboarding/PermissionsStepView.tsx | Adds optional back navigation secondary action. |
| src/features/onboarding/PermissionsStep.tsx | Threads back navigation through permissions step container. |
| src/features/onboarding/Onboarding.tsx | Implements back navigation with guard rails for identity “point of no return”. |
| src/features/onboarding/IdentityStep.tsx | Threads back action into identity choice and fingerprints into recovery. |
| src/features/onboarding/IdentityChoiceStep.tsx | Adds optional back navigation secondary action. |
| src/features/onboarding/DisplayNameStep.tsx | Adds optional back navigation secondary action. |
| src/features/onboarding/AddFriendStepView.tsx | Adds optional back navigation secondary action. |
| src/features/onboarding/AddFriendStep.tsx | Threads back action into add-friend onboarding step. |
| src/features/identity/RecoverView.tsx | Adds differentiated confirm copy + same-identity done copy support. |
| src/features/identity/recoverLogic.ts | Adds overwrite-decision logic based on mnemonic fingerprint comparison. |
| src/features/identity/Recover.tsx | Wires overwrite-decision into recovery state machine. |
| src/features/identity/index.ts | Exports new identity load error components. |
| src/features/identity/IdentitySetup.tsx | Adds special-case toast for “keys already exist” marker. |
| src/features/identity/IdentityLoadErrorView.tsx | Adds presentational identity load error screen. |
| src/features/identity/IdentityLoadError.tsx | Adds container for identity load error with retry/recover modes. |
| src/features/friends/pairLink.ts | Updates docs to reflect OS deep-link support. |
| src/features/friends/PairDeepLinkBoot.tsx | Adds boot-time subscriber mount for pairing deep links. |
| src/features/friends/pairDeepLink.ts | Implements deep-link subscription + one-time launch URL consumption. |
| src/features/friends/pair.ts | Adds relay override usage + join error forwarding + post-arrival stall hint. |
| src/features/friends/invite.ts | Adds relay-unreachable error type + retry manager + relay override usage. |
| src/features/friends/index.ts | Re-exports deep-link boot + retry manager APIs. |
| src/features/friends/InboxBoot.tsx | Adds presence transition detection for invite retry + friend-online notifications + pagehide goodbye + retry cancel on session end. |
| src/features/friends/inbox.ts | Adds relay override usage + guards joinTopic throw to avoid boot blanking. |
| src/features/friends/FriendsListView.tsx | Improves empty-state CTA and makes Invite button discoverable/accessible. |
| src/features/friends/friendOnlineNotify.ts | Adds opt-in OS notification helper for friend-online edges. |
| src/features/ai/parseJudgment.ts | Changes parse fallback to “uncertain” verdict and adds narrowing helper. |
| src/features/ai/modelStore.ts | Adds interrupted-download tracking APIs and persistence semantics. |
| src/features/ai/ModelPickerContainer.tsx | Records last byte count to persist resumable download offsets on failure/cancel. |
| src/features/ai/ModelPicker.tsx | Surfaces “Resume download” UI based on interrupted-download marker. |
| src/features/ai/index.ts | Re-exports new focus request builder + uncertain verdict types + backoff exports. |
| src/features/ai/focusRequest.ts | Introduces single source of truth for focus chat request body shape. |
| src/features/ai/aiAgent.ts | Updates docs to reference new focus request builder terminology. |
| src/design/tokens.ts | Adds shared score gauge sizing token. |
| src/components/WaitingTile.tsx | Adds new calm waiting tile component. |
| src/components/ScoreGauge.tsx | Switches default size to design token. |
| src/components/RelayDiagnostics.tsx | Adds relay diagnostics panel component with polling and controlled seam. |
| src/components/PairQrCode.tsx | Improves QR size/EC level for scan reliability. |
| src/components/FocusIndicator.tsx | Adds connection focus states (connecting/failed) with glyphs + labels. |
| src/components/AudioOutputPicker.tsx | Adds audio output device picker component (feature-detected). |
| src/App.tsx | Mounts new system listeners (quit confirm + pomodoro notify). |
| src-tauri/tauri.conf.json | Enables deep-link plugin and macOS signing config. |
| src-tauri/src/db/sessions.rs | Adds delete/clear_all with audit event cleanup, plus tests. |
| src-tauri/src/db/migrations.rs | Adds explicit “newer schema” refusal error type and tests. |
| src-tauri/src/db/audit_events.rs | Adds list_all query and tests; documents serde naming contract. |
| src-tauri/src/commands/sessions.rs | Exposes sessions delete/clear + audit events list_all commands. |
| src-tauri/src/commands/identity.rs | Adds overwrite guard + stable error marker + signing key loader helper. |
| src-tauri/Cargo.toml | Adds deep-link/dialog/single-instance plugins; adjusts crypto_box features. |
| src-tauri/capabilities/default.json | Grants dialog + deep-link plugin capabilities. |
| README.md | Updates network disclosures and macOS release matrix notes. |
| package.json | Adds @tauri-apps/plugin-deep-link and @tauri-apps/plugin-dialog deps. |
| package-lock.json | Locks new Tauri plugin dependencies. |
| INSTALL.md | Updates macOS install guidance for Apple Silicon-only + ad-hoc signing. |
| DESIGN-SYSTEM.md | Updates component catalog entries and some UI behavior docs. |
| .github/workflows/release.yml | Updates release body copy regarding signing status. |
| .github/workflows/release-prep.yml | Adds pre-tag quality gate job and wires prep behind it. |
| .github/workflows/ci.yml | Adds check-strings enforcement in CI. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| for (let i = 0; i < parts.length; i++) { | ||
| const n = Number(parts[i]) | ||
| if (!Number.isInteger(n) || n < 0) return null | ||
| out[i] = n | ||
| } |
| if (decision === 'commit') { | ||
| setSameIdentity(identityExists) | ||
| void commit() | ||
| return | ||
| } |
| onCancelOverwrite={() => { | ||
| pendingCommit.current = null | ||
| setConfirmDifferent(false) | ||
| setPhase('input') | ||
| }} |
Summary
Implements every item in
IMPROVEMENTS.md(F1–F10, U1–U7, S1–S4, A1–A6, D1–D7, R1–R7, X1–X7, N1–N6, P1–P2) across 12 commits. Final accounting: 0 partial, 0 missing; 9 items landed adapted with documented rationale. The accepted deviationsI9/I18are untouched per the working agreement.Highlights by area:
studyvis://as a real OS deep link (prefill, never auto-connect).NSApp.terminatecan't be intercepted).on_task); off-task judgments gated on anon_topic_confidencefloor (Settings slider, default 0.6); duration-based thermal cadence backoff; sidecar port re-read before POST; resumable model downloads (HTTP Range) with an honest Resume affordance.score=nullinstead of a fabricated 100; cross-session focus-insights view (distraction timing, recurring reasons, trend); report/CSV/audit-log file exports; session delete + clear-all history.hardenedRuntime: false(the default would have broken sidecar dylib loading in release builds); dormant updater removed; single-instance guard; graceful corrupt-DB recovery + newer-schema refusal at startup.check-contrastnow scans every token co-occurrence (cva variants, modifier-prefixed classes included) and fails on combos missing from the allowlist.Every cluster went through implement → gates → 3-lens adversarial review with per-finding verification → advisor pass → fix, plus a 6-lens whole-branch review at the end. Notable catches that would have shipped otherwise: the hardened-runtime sidecar blocker, the dead Cmd+Q intercept, trystero's
onJoinErrornever firing for blocked relays (backlog premise corrected), a custom-relay boot race against settings hydration, an R7 wire-shape bug invisible to fixture-based tests, and forgeable friend backups.Test plan
Machine-verified (all green on the branch):
npm run build,lint,test(600 tests, ~170 added),check-tokens,check-strings,check-contrast(incl. new coverage scanner),format:checkbuild-storybook+check-a11y(247 axe checks)cargo test && cargo fmt --check && cargo clippyinsrc-tauri/User walks recommended before merge (not yet machine-walkable):
studyvis://pairlink with app closed and running — prefill only, never auto-connectapp.db→ recovery dialog;schema_version=99→ "update needed" with file untouched🤖 Generated with Claude Code