Repository navigation
Jump from a reply to the boards it made or changed, and a theme switch - #197
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hem on the canvas The server hashes the project's boards when a run starts and again when it ends, and the end event lists each board whose bytes changed, new or rewritten. Off the files rather than the tool lines, which cannot say what a generator wrote. The hashing the watcher did is now hashBoards in boards.ts, shared by both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Deploying super-prototyping with
|
| Latest commit: |
84944df
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://6e2ec674.super-prototyping.pages.dev |
| Branch Preview URL: | https://jump-to.super-prototyping.pages.dev |
An agent places boards under ids of its own in canvas.json, so the library's id missed them and the button did nothing. A generator rewriting every board made the list long. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r project, theme follows other windows Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # canvas/src/App.tsx
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
| :root[data-theme="light"] { | ||
| color-scheme: light; | ||
| } |
There was a problem hiding this comment.
🔴 Light theme keeps dark colors
Selecting Light sets data-theme="light", but the later :root rule overrides its color scheme with dark. Tokens stay dark while tldraw switches to light, leaving the theme switch ineffective and the canvas mismatched.
Learn more
The page stores a theme on its root element, and its colors resolve through light-dark() in tokens. The new light and system rules precede the unconditional :root dark rule at the same specificity. The later rule wins, so neither new setting can change the page palette. Separately, handleMount switches tldraw to the selected theme, leaving its canvas unlike the surrounding controls.
Example: On a light OS, select Light. The switch indicates Light and tldraw gets a light scheme, but the top bar and chat still resolve their colors from the dark half of every token.
Recommended fix: Move the fallback color-scheme: dark to a :root:not([data-theme]) rule or place it before the specific theme selectors. Verify Light and System on both OS preferences.
Was this helpful? React with 👍 or 👎 to provide feedback.
| const made = [...hashBoards(before.dir)] | ||
| .filter(([board, hash]) => before.hashes.get(board) !== hash) |
There was a problem hiding this comment.
🟡 New projects lose board jump buttons
When a first turn names an unnamed project, named moves its folder before the end event. hashBoards(before.dir) then sees no boards at the old path, so the reply has no jump buttons.
Learn more
An unnamed project starts in an Untitled folder. On a successful run, the child close handler calls named before it finishes the run. named moves the entire project folder, while before.dir still names the old canvases directory. hashBoards treats the missing directory as empty, and the end event loses all created or updated boards.
Example: Start a new Untitled project and ask the agent to name it and make canvases/launch/01-home.html on the first turn. The folder becomes its new project name, but the reply has no 01 Home button.
Recommended fix: Compute the after-hashes before calling named, or update the run's tracked directory when named moves it. Preserve the original before-hashes for the comparison.
Was this helpful? React with 👍 or 👎 to provide feedback.
| const follow = () => setTheme(storedTheme()); | ||
| window.addEventListener("storage", follow); | ||
| return () => window.removeEventListener("storage", follow); |
There was a problem hiding this comment.
🟡 Other windows retain stale title bars
When another window changes the theme, follow updates the switch but never calls startup.theme. Electron's native title bar keeps its previous appearance until a local click or reload.
Learn more
The theme switch uses localStorage so every same-origin window receives a storage event. pickTheme notifies Electron when the local window changes the theme. The storage listener in this component updates its React state only. Thus another Electron window's selection reaches the switch but not the native title bar.
Example: Open the app's main window and a second app window, then choose Light in the second window. The main window's switch indicates Light, but its native title bar retains Dark.
Recommended fix: Have the storage-event handler notify startup.theme with the newly stored theme as well, or centralize native-theme synchronization in one listener.
Was this helpful? React with 👍 or 👎 to provide feedback.
| {t.end?.made && t.end.made.length > 0 && ( | ||
| <MadeBoards made={t.end.made} away={t.project !== project} /> | ||
| )} |
There was a problem hiding this comment.
🟡 Board links disabled on Home
After leaving a project for Home, project becomes undefined and every board button from that project is disabled. Completed replies cannot take the user back to their boards from Home.
Learn more
The chat remains mounted across tab and Home navigation in AppShell. project describes only what is currently open, not the project where a prior turn ran. The new button uses that equality to disable navigation, so a completed reply is not a usable route back to its project once the person leaves it.
Example: Send a turn from project Alpha that makes launch/01-home.html, go Home while it runs, then read the reply. Its board button is disabled even though Alpha and its board still exist.
Recommended fix: Route a click for a board in another project through the shell's project-tab navigation, then focus the board after its canvas frame mounts. Keep the buttons enabled for existing projects.
Was this helpful? React with 👍 or 👎 to provide feedback.
| export function ThemeSwitcher() { | ||
| const [theme, setTheme] = useState(storedTheme); |
There was a problem hiding this comment.
🔍 Release notes omit both new features
The theme switch and reply-to-board buttons need entries under Unreleased. The repository requires release notes in the same PR as user-facing changes.
Was this helpful? React with 👍 or 👎 to provide feedback.
| export function hashBoards(canvasesDir: string) { | ||
| const list = (dir: string) => { |
| const [theme, setTheme] = useState(storedTheme); | ||
| // The app starts on the OS's until the page says, since the pick lives in the page's storage. | ||
| useEffect(() => window.startup?.theme(storedTheme()), []); | ||
| // Picked in another window of the same app, which shares the storage. |
| /** This page's theme now, every other page's on the storage event, and the app's title bar's. */ | ||
| export function pickTheme(theme: Theme) { | ||
| document.documentElement.dataset.theme = theme; | ||
| try { | ||
| localStorage.setItem(THEME_KEY, theme); | ||
| } catch {} // the pick then lasts only as long as this page | ||
| window.startup?.theme(theme); |
Under each agent reply in the chat, a button for every board the run made or rewrote. Clicking one brings its canvas forward and fits the board to the view, as a double-click does. The dot is blue for a new board and green for a rewritten one, the colours of their rings on the canvas. More than three rows of buttons fold behind "Show all N".
This PR also carries the theme switch (system, light or dark) from
theme-toggle, merged in as a dependency. It was never opened as a PR of its own.agent.ts): hashes the project's boards when a run starts and again as its end event is written, and addsmade: [{board, status}]to that event. It works off the files rather than the tool lines, so a board a generator (gen.py) wrote counts, and one it wrote again with the same bytes doesn't.boards.ts:hashBoards/boardHash, now shared with the watcher insp.ts.ChatPanel.tsx):MadeBoardsrenders the buttons, folded to three rows, and sendssp:focus-boardon the window.App.tsx): finds thecanvas-fileshape by its path, trying the board's own canvas first, then opens that canvas tab and callszoomToFill. It goes by path rather than the library's id because an agent places boards under ids of its own incanvas.json.ThemeSwitcher.tsxandtheme.ts.Stacked on #195. I'll retarget it to main once #195 merges.
Tested:
02 Whats New(green) and04 Test Board(blue), and each button found its board.canvas.json: a 53-board reply folded to three rows, the toggle opened and closed the list, and buttons jumped across canvas tabs.🤖 Generated with Claude Code