plan 0011: Pill Alignment tool — eccentric-pill camber/caster calculator#353
Merged
Conversation
The logger only writes the .dovex metadata header on "end session"; an unclosed session leaves the reserved preamble as blank padding (newlines and/or null bytes). isDovexFormat required the datetime/driver/course signature on line 1, so these files fell through dovex AND dove detection and were claimed by the looser Alfano check, which then failed with "Alfano csv error". Detection now also accepts a padding-only preamble followed by a valid embedded Dove CSV. Plain .dove CSVs (which start with the timestamp header directly) still route to the Dove parser. The session parses with no dovexMetadata and in-app course detection fills in the track. Verified against a real un-ended session file (1024-byte newline preamble); regression tests cover newline padding, null padding, garbage preambles, and router-level routing built from the bundled sample. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XZGcVEbpSJgNRkLeMJn3ew
…headers-w32u4q Fix headerless .dovex files mis-detecting as Alfano CSV
Pull the "upload your own .dovex" picker from Phase B forward as a bug-hunting tool: replay a real problem log through the real firmware in the browser. The /simulator page gains a Load .dovex… button (accepts .dovex/.dovep/.dove) plus a Back-to-demo shortcut, with inline errors when a picked file has no Dove GPS data. Picked files parse leniently via lib/sim/simSession.ts — bypassing global format auto-detection (nothing to mis-detect against once the user asserts a dove-family file) and normalizing channels like parseDatalogFile does — so a log whose metadata preamble was never written or was corrupted still replays as long as the embedded CSV column headers are intact. To support the worst corruption case, dovexParser's embedded-CSV discovery now tries the candidate anchored at the "timestamp" match before the line-start candidate, coping with garbage glued straight onto the CSV header row; garbage preambles also no longer emit an all-undefined dovexMetadata object. Global isDovexFormat detection is unchanged (strict, padding-only preambles). Also replaces two literal NUL bytes in dovexParser.test.ts with their backslash-u escape sequences so git stops treating the file as binary. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ht3FbZtSfvVzvfiryvvaHK
…cessing-clh8jc plan 0010: simulator session picker — load any dove-family log
…envelope sweep, toe Pure TS geometry for the OTK-style eccentric-pill calculator: forwardCorner (pills → camber/caster/track), two-circle Find Setup solver with hole snapping and cost ranking, the reachable-envelope sweep with color bucketing, tie-rod toe conversions, and session-setup alignment-field resolution. All Vitest-covered, including forward↔inverse round-trip invariants. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D2gb7LNbhFeapCaKAn9tvH
…etup, toe visual The calculator itself: draggable camber/caster envelope scatter (two-canvas layered, dots batched by color bucket), 2×2 SVG pill hub dials with drag-to-rotate and hole snapping, per-side readouts, ranked Find Setup candidates with one-tap Apply, editable chassis calibration with approximate presets, toe entry (tie-rod or per-side) with an overhead toe widget, and a read-only load-from-session-setup seed. Registered as a lazy tools-plugin entry so it surfaces on both the landing Tools drawer and the in-session Tools tab. NumRow/Section lifted to tools/shared for reuse with the seat tool. Translated across all 7 locales. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D2gb7LNbhFeapCaKAn9tvH
Calibration constants become first-class ChassisProfile records instead of two hardcoded presets, so brands get added as they're measured. Built-ins cover OTK/Tony Kart, Kart Republic, CompKart, Birel ART, Praga, and Sodi — all flagged 'estimated' until real numbers exist. The calibration panel gains measurement helpers (dial-indicator sweep → e = sweep/2; zero-point back-out of the built-in offsets from gauge readings at size-0 pills) and a 'save as measured profile' flow that freezes the current constants as a named user profile in the plugin store. Legacy preset ids migrate on load. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D2gb7LNbhFeapCaKAn9tvH
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
lapwing | 05e1053 | Commit Preview URL Branch Preview URL |
Jul 24 2026, 06:46 PM |
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
Coverage SummaryLines: 56.42% (6765/11990) · Statements: 55.52% · Functions: 53.19% · Branches: 52.58% Per-file coverage
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a Pill Alignment calculator to the tools plugin (plan 0011): OTK-style eccentric kingpin pills → camber / caster / track width, with an inverse "Find Setup" solver that answers "what pill positions give me my target camber?". Registered as one lazy
ToolDefentry, so it surfaces automatically both on the landing-page Tools drawer and the in-session Tools tab.model/inverse/envelope/toe): forward two-link kingpin geometry, two-circle inverse solver with hole snapping + cost ranking, ~32k-point envelope sweep, tie-rod toe conversions. All Vitest-covered, including forward↔inverse round-trip invariants.profiles.ts): built-in brand profiles (Generic, OTK/Tony Kart, Kart Republic, CompKart, Birel ART, Praga, Sodi) all flagged estimated until measured; measurement helpers (dial-indicator sweep → e = sweep/2, zero-point back-out of built-in offsets) turn paddock readings into constants, saveable as named measured user profiles in the plugin store.f-toe/f-camber/f-castor, name-matched for custom templates).NumRow/Sectionlifted from the seat tool intotools/shared/for reuse. Translated across all 7 locales. Design record indocs/plans/0011-kart-pill-alignment-tool.md; the "sniper" laser-board visual is sketched there as a deferred phase 3.Related Issues
None — from a design spec + reference-app teardown.
Type of Change
Checklist
npm run lintpassesnpm run typecheckpassesnpm run test:runpasses (2276 tests)npm run buildsucceedsCHANGELOG.md,CLAUDE.md,docs/plans/0011; README unaffected)datalogParser.ts, added tests, updated the formats table — N/ANotes for Reviewers
mirrorRightcalibration flag covers the fixed-handedness alternative. Tests lock the internal convention.toeCouplingMmPerMm · Δwheelbase), matching the reference app's own heuristic color layers.PillAlignmentTool-*.js) — no landing-payload impact.🤖 Generated with Claude Code
https://claude.ai/code/session_01D2gb7LNbhFeapCaKAn9tvH
Generated by Claude Code