The timeline's terminating dot used a single left offset (-17px) at both
breakpoints, but the thread's padding-left differs (22px desktop, 18px
mobile) and the step dots already carry a per-breakpoint offset. The 6px
dot therefore landed 2px right of the 2px rail on desktop and 2px left of
it on mobile, which is the visible kink under an expanded last step.
Derive each offset from the rail's centre instead: the rail sits at
left:5px and is 2px wide, so the dot's left edge belongs at 3px, giving
3px - padding-left per breakpoint.
* perf(ui): stop session loading from blocking shell
* fix(startup): open routes on their own data, retire the loader for good
Follow-up to review on #5927.
- Route openers are now classified by the data they actually read. Only
/email touches the hydrated session list (its new-chat path falls back to
the most recent session's model when no default chat is set), so every
other route opens as soon as module wiring completes instead of queueing
behind /api/sessions. This is the deferred-route half of #5926, which the
first pass left unimplemented.
- index.html's 5s fallback removes the loader node again. Leaving it in the
DOM indefinitely kept _shouldPreserveStartupComposer true forever on a
hung /api/sessions, so the composer stopped clearing on session switch.
- A missing session module settles hydration instead of leaving the sidebar
on "Loading chats…" and dropping the user's route on the floor.
- Startup sequencing moved to static/js/startupShell.js so it can be run by
tests. The source-text assertions in test_startup_shell_session_loading.py
are replaced by node-driven behavioural tests, per tests/TESTING_STANDARD.md.
- Reverted the unrequested loader a11y rework, removed the duplicated inert
writes (the module stops the wave interval through a callback), and moved
the bootstrap row's inline styles into .session-list-bootstrap.
* fix: preserve session bootstrap failure state
---------
Co-authored-by: Léo <leograndcontact@gmail.com>
* fix(chat): Expand user chat bubble edit textbox width
- Update user chat bubble width from `fit-content` to `85%` to ensure consistency with the AI chat bubble edit textbox width.
* style(chat): Refine user message bubble width logic
- Change general bubble width to `fit-content`
- Set width to 85% specifically for user messages containing a `textarea`
Align regression tests with the current Odysseus behavior after merging origin/dev into local main.
- keep phone/name-only contacts valid and cover null email without crashes
- pin explicit web-search false form submission in chat.js
- update Cookbook dependency/download completion tests for combined live + persisted output
- expose SGLang OS package repair hints from backend diagnosis
- treat MLX and MLX-community repos as servable on Apple Metal while keeping CUDA behavior unchanged
- keep desktop new-chat coverage on the shared preferred-model helper
- remove a hardcoded crop overlay portal z-index literal
- include the local agent-loop cleanup that removes the old manage_notes reminder repair shim
Verified with: docker run --rm -v /home/pewds/odysseus-cookbook-fresh:/app -w /app odysseus-cookbook-fresh-odysseus python3 -m pytest -q (4515 passed, 4 skipped).
The comparison grid hard-codes 2-4 equal columns with no phone breakpoint, so at
390px two models get ~178px columns and four get ~88px columns. Each column is a
full scrolling chat, so content is unreadably over-wrapped and clipped. On
phones (<=768px), stack the panes into a single scrollable column. Desktop is
unaffected.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>