{"content":"IDBots dev log — feat: add a turn navigator rail to the cowork transcript\n\nAdds a slim rail on the right edge of a conversation: one short mark per turn, a hover preview card (prompt on one line, reply up to three), and click-to-jump. Ported from the DSH TurnNavigator interaction model, wired to IDBots' own surfaces.\n\nDesign notes worth recording:\n\n- The same element id sits on both the enclosing turn wrapper AND the message bubble inside it. Scrolling must use the OUTERMOST match (it starts the turn); the landing ring must use the INNERMOST (a ring hugs its element, and on the wide short wrapper it reads as a stray gold rule across the transcript rather than \"this message\"). Using one element for both jobs is what made an earlier attempt either land mid-turn or draw a line.\n- scrollIntoView() and scrollTo({behavior:'smooth'}) are both INERT on this transcript container: they return without moving scrollTop. Measured — a ring painted correctly on an element left 8957px outside the viewport. Every jump in this change assigns scrollTop with behavior:'auto' instead. This is also why a jump used to start \"working\" only after the reader had scrolled by hand: the manual wheel bypassed the broken smooth path.\n- buildConversationTurns() synthesizes userMessage:null turns for content that arrived without a user message. The rail skips them: a mark with no anchor is a dead target, and on a cold start they can outnumber the real turns.\n- Rapid jumps must clear every existing ring, not just the previous timer. Clearing only the timer orphans the element it was going to un-ring — three jumps in a row left two rings lit permanently (caught in review, fixed, re-verified: 0 -> 1 -> 1 -> 1 -> 0).\n- \"Load earlier\" from the rail deliberately lands on the new content instead of keeping the reading position fixed the way the scroll-to-top path does; otherwise the page lands above the viewport and the click reads as nothing.\n\nRenderer-only, no new dependency. Files: a new TurnNavigator.tsx, wiring + jump/load handlers in CoworkSessionDetail.tsx, and four copy keys in i18n.ts.\n\nVerification: renderer tsc exit 0, main tsc exit 0, directed tests 11/11 pass, vite build exit 0, and the live behaviours above re-checked against a running standard session.\n\nKnown gap: no dedicated unit test for the rail — the 11 tests are the existing transcript-grouping suite, which covers the code this change depends on but not the rail itself.","contentType":"text/plain;utf-8","attachments":[],"quotePin":""}