Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
709b8d6
canvas: run Claude Code from the dev server, with its output kept per…
Jing-yilin Sep 17, 2026
7738628
canvas: a chat panel on the left, following its runs across reloads
Jing-yilin Sep 17, 2026
8c56243
canvas: record the chat panel's decisions, and tell the skill about it
Jing-yilin Sep 17, 2026
4bbd88d
canvas: the agent names its run, and the server lists the runs it holds
Jing-yilin Sep 17, 2026
09ccc6e
canvas: a title, the history and a rail in the chat panel's header
Jing-yilin Sep 17, 2026
e67116f
canvas: record the header decisions, and that the toolkit needs reins…
Jing-yilin Sep 17, 2026
91aab6c
canvas: render the agent's text as markdown
Jing-yilin Sep 17, 2026
c91a6b7
canvas: record why markdown is marked, remend and DOMPurify
Jing-yilin Sep 17, 2026
7d3f192
canvas: stop naming the board in the chat panel's header
Jing-yilin Sep 17, 2026
4b98b99
canvas: take the shape editing out of the top bar
Jing-yilin Sep 17, 2026
2500c39
canvas: read codex's exec --json stream
Jing-yilin Sep 17, 2026
61303f5
canvas: one table of agents, and the server spawns from it
Jing-yilin Sep 17, 2026
891db8d
canvas: the header's mark switches between claude and codex
Jing-yilin Sep 17, 2026
64fb42d
canvas: write down the second agent
Jing-yilin Sep 17, 2026
79acc85
canvas: what the two agents look like once you use them
Jing-yilin Sep 17, 2026
ecd428b
canvas: pick the model and the effort in the panel, and say what it cost
Jing-yilin Sep 17, 2026
a60c4cb
canvas: opening a run from history picks the agent that held it
Jing-yilin Sep 17, 2026
e9f5b71
canvas: take the zoom readout and minimap out of the corner
Jing-yilin Sep 17, 2026
cf07cdd
canvas: list the agent's slash commands as you type one
Jing-yilin Sep 17, 2026
f57922d
canvas: reopen the slash palette after a message is sent
Jing-yilin Sep 17, 2026
1ca671e
canvas: make the slash palette's keyboard selection visible
Jing-yilin Sep 17, 2026
0b647f3
canvas: list every slash command, not the first eight
Jing-yilin Sep 17, 2026
7e76f11
canvas: start a new session from the panel header
Jing-yilin Sep 17, 2026
b59cc3a
canvas: give codex a palette too, listing its skills
Jing-yilin Sep 17, 2026
da0df5d
canvas: refuse cross-site requests to the dev server's endpoints
Jing-yilin Sep 17, 2026
033b807
canvas: let the server decide that one agent runs at a time
Jing-yilin Sep 17, 2026
66cae13
canvas: shape the composer like Claude Code's
Jing-yilin Sep 17, 2026
f7cf8f5
canvas: put the panels on Geist, dark by default
Jing-yilin Sep 17, 2026
b73ca2a
canvas: let a board sit on the canvas, not on a white card
Jing-yilin Sep 17, 2026
3da8523
canvas: one Enter sends a command typed out in full
Jing-yilin Sep 18, 2026
ec62ed5
canvas: build on Tailwind and shadcn/ui, over the same scale
Jing-yilin Sep 18, 2026
c2a150b
canvas: draw from Vercel's icon set, not a transcription of it
Jing-yilin Sep 18, 2026
d70f0d8
canvas: one ground, one icon button, one scrollbar
Jing-yilin Sep 18, 2026
690482a
canvas: leave the top bar a switch and two destinations
Jing-yilin Sep 18, 2026
1bc0c7a
canvas: make the two asks one pair of buttons
Jing-yilin Sep 18, 2026
04e8c38
docs: write down what the Geist pass decided, and what changed for a …
Jing-yilin Sep 18, 2026
d685be9
docs: say it plainly across the Geist branch
Jing-yilin Sep 18, 2026
785548a
canvas: put pictures in the chat, both directions
Jing-yilin Sep 18, 2026
4f8e02e
docs: say what the chat panel does with pictures
Jing-yilin Sep 18, 2026
92f6ce3
canvas: make the slash palette open every time
Jing-yilin Sep 18, 2026
d2b413b
docs: correct what the note said about asking for commands
Jing-yilin Sep 18, 2026
7db61e6
canvas: what the review of #97 found, fixed
Jing-yilin Sep 18, 2026
624c8b5
canvas: hand a board or a picture to the chat from the canvas
Jing-yilin Sep 18, 2026
6c91422
canvas: a picture handed over from the canvas names itself too
Jing-yilin Sep 18, 2026
975b5ca
canvas: start the picture numbers over once nothing points at one
Jing-yilin Sep 18, 2026
cc3938b
canvas: one number per picture, and the sentence keeps the tray honest
Jing-yilin Sep 18, 2026
09f7446
canvas: two fingers over the attach buttons still pan the board
Jing-yilin Sep 18, 2026
e81d3bc
canvas: a picture is the whole of its box, not just its pixels
Jing-yilin Sep 18, 2026
3477eae
canvas: a mockup added to the chat looks like the mockup
Jing-yilin Sep 18, 2026
0075875
canvas: one button on a mockup, because there is one thing to do with it
Jing-yilin Sep 18, 2026
14b6e58
Merge origin/canvas-geist-ui into fix/canvas-geist-ui-review
Jing-yilin Sep 18, 2026
2b19654
canvas: the second review of the fix branch
Jing-yilin Sep 18, 2026
fc449a0
canvas: the server's image folder is made, not named
Jing-yilin Sep 18, 2026
e34d264
canvas: a picture already in the tray is not a twenty-first, and the …
Jing-yilin Sep 18, 2026
8f1bfe2
canvas: a pick that cannot fit is refused before it is read
Jing-yilin Sep 18, 2026
d38fd09
canvas: the tray is one tray, whoever is adding to it
Jing-yilin Sep 18, 2026
17adf38
canvas: a picture opened in a tab cannot be a program, and a run forg…
Jing-yilin Sep 18, 2026
ca167de
canvas: a preference that cannot be remembered is still a preference
Jing-yilin Sep 18, 2026
1be809c
canvas: the token block the inspector reads is the board's own
Jing-yilin Sep 18, 2026
2b3a511
skills: the refresh button is a menu item everywhere it is named
Jing-yilin Sep 18, 2026
036e94d
Merge #98: two fixes of one review, resolved to the better half of each
Jing-yilin Sep 18, 2026
7b05506
Merge pull request #97 from ReScienceLab/canvas-geist-ui
Jing-yilin Sep 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,10 +198,9 @@ status` and `sp-canvas stop` do what they say.

Deep-link a page with `?canvas=<slug>`, and one board of it with
`?canvas=<slug>#<file>`: it opens in the inspector with the camera on it, and
clicking any board writes that link into the address bar. The bottom toolbar carries a
styles-panel toggle alongside tldraw's own tools; the top bar carries a
force-relayout button. Press it after editing a `layout.json`. A board folder
added after boot appears on its own.
clicking any board writes that link into the address bar. Right-clicking the
canvas offers Force refresh; choose it after editing a `layout.json`. A board
folder added after boot appears on its own.

## The workflow

Expand Down
108 changes: 108 additions & 0 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,114 @@ toolkit carry the same version; `sp-canvas start` says so when they drift.

Everything below is on `main` and reaches no install until a version is cut.

The canvas has a chat panel on the left when it runs from `sp-canvas start`:
a message to Claude Code, run in your project with its permission prompts
off, and what it does as it happens — each tool call as a line, its reply as
text. A board it rewrites reloads the canvas as any rewrite does, and the
panel picks the run back up. `sp-canvas start` now tells the server which
project it is in (`PROTOTYPING_PROJECT_DIR`); without that, the panel says it
cannot run.

The panel's header names the conversation — the agent's own title for it once
it has given one — behind the agent's mark, lists the server's recent runs
behind a history button, and folds to a rail. The rail is the mark; click it
to open the panel again. The list lives in the dev server's memory and starts
empty when it restarts.

The panel talks to Codex as well as Claude Code. The mark on the header is the
switch: click it for a menu of the agents the server found on your PATH, pick
one, and the mark becomes that agent's; the choice is kept and sent with each
message, and every turn and history row shows the mark of the agent that ran
it. An agent that is not installed is in the menu greyed, with how to get it.
Codex runs in its own workspace sandbox with the boards folder added, takes
the panel's briefing ahead of your message since it has no system prompt, and
answers in paragraphs rather than word by word, which is how `codex exec`
works. If your Codex is older than the model its config names, the first
message fails with the server's own sentence saying so; update the CLI or set
`model` in `~/.codex/config.toml`.

The agent's replies render as markdown — bold, lists, fences and tables, with
wide ones scrolling inside the message — rather than as source.

The conversation gets its name from a turn that had work to do: a reply that
opens by saying what it is about to do, runs a tool and titles itself after
that is titled in the header and the history list, where the title used to be
left sitting in the middle of the reply instead.

This needs the toolkit reinstalled, not only the plugin updated: `sp-canvas`
1.2.0 predates `PROTOTYPING_PROJECT_DIR`, so a canvas it starts comes up with
the panel but every message answers 503. Re-run the README's `uv tool install`
line with `--force`.

The canvas top bar is down to a switch, the page name and two destinations:
collapse the chat panel, Export to Figma, Brand kit. Everything else on it
moved. Shape editing, meaning undo, redo, delete, duplicate and the overflow
of aligns, distributes and reorders, is on the keyboard and the right-click
menu, where it already was. These boards are written from files by a
generator, so six buttons for nudging them crowded out the two the bar is
for. Comment, clone and force refresh join them on the right button. All
three act on what is under the cursor, or on the page it is on, which is what
a right-click has already picked out. The hamburger beside the page name goes
too, and so do the zoom readout and minimap toggle in the bottom-left corner,
where they sat under the chat panel's composer. Zoom is the trackpad, ⌘+ and
⌘-, and ⇧1 to fit the page.

The switch for the chat panel is in the canvas's own top-left corner, which is
the one place it can be whether the panel is open or shut. In the panel's
header it went away with the panel and needed a second control to bring it
back.

Under the message box: which model, which effort, and what the last message
cost. The model list is the agent's own — for Codex it is the list its own
picker shows, read from its cache, so a model you gained by updating the CLI is
there without waiting for us — and the effort levels are the ones that model
actually takes. Both start at Default, which sends nothing and leaves your
`~/.codex/config.toml` or Claude's settings in charge; pick one and it is
remembered per agent. The number on the right is the tokens that message used
against the model's window. It is that message, not the conversation: each one
still runs as its own process with no memory of the last.

Type `/` in the chat panel and the commands Claude Code can run there are
listed — your own, the project's, the plugins' and the skills, `/clone-prototype`
among them — with the arrow keys and Enter to take one. They already worked if
you knew the name; now you can see them. The list is the CLI's own, learned from
the runs you make, so it is there from the first answer of a session and matches
whatever you have installed.

Codex gets the same palette, listing its skills — your own, the plugins' and
this project's. It is not the same mechanism underneath: Claude Code runs a
slash command itself, while Codex is told what its skills are and what they are
for, and a `/name` goes to the model as the text it is. The list is Codex's
own, composed by the CLI without a turn being run, so it is there before the
first message rather than after it.

A plus in the panel's header starts a new session: the log clears and the next
message has nothing above it. Anything still running keeps running and stays in
the history list — the button clears the view, it does not stop the agent.

The canvas is dark, and its panels are drawn in Vercel's Geist: its greys and
its accents, its icons, and Geist Sans and Geist Mono bundled so a board looks
the same offline as online. The chat panel, the inspector, the top bar and the
canvas they sit around all read as one app now, on one ground, separated by
hairlines rather than by shade. tldraw's own chrome comes with them. Its menus,
its toolbar and its context menu read the same tokens, so a page menu is the
same black card with the same hairline as a panel's menu, and an icon button
in the top bar is the same grey, and lights the same way, as one in the chat
panel's header beside it. The glyphs are Geist's own set rather than a
transcription of it, and the scrollbars are the app's rather than the
platform's: one thin grey thumb on whatever ground it is over, in the
transcript, the slash menu, the history, the notes and the inspector alike.
Your boards are untouched. A mockup is drawn by its own generator and keeps
whatever palette it was measured in, scrollbars included.

One thing about a board does change, and it is what the dark ground exposed. A
mockup used to sit on a white card. A frame paints an opaque white background
of its own underneath whatever the board draws, invisible while the canvas was
white and a card around every phone once it is not. The canvas releases it, so
the canvas shows through wherever a board paints nothing and every pixel the
board does paint stays as it was. A board that wants a ground, such as a token
sheet or an evidence sheet, still declares one and looks exactly as it did.

## v1.3.0

2026-09-15. The inspector moves onto the canvas: you click the board itself,
Expand Down
Loading
Loading