The name is written in lowercase everywhere, easl.app included. Nothing else changes.
Tagged v0.5.1: easl-0.5.1.zip on GitHub Releases, ad-hoc signed, for macOS 14 or later on Apple silicon, with gettext-0.24.tar.gz and THIRD_PARTY_NOTICES.md beside it.
The app’s name is now written in lowercase (22cffcd). The menu bar and menus (Quit easl, Help › easl Basics), windows, sheets, notifications, the CLI, the agent skill and the docs say easl; the app is easl.app and the release easl-<version>.zip. Nothing else changes: the bundle id (net.waldin.easl), ~/Library/Application Support/Easl, ~/.easl, the EASL_* variables, the easl CLI, easl_sdk and @easl/client stay as they were.
Upgrading from Easl 0.5.0
Quit the app (its terminal sessions keep running), delete /Applications/Easl.app, unzip easl-0.5.1.zip, move easl.app to /Applications, run xattr -dr com.apple.quarantine /Applications/easl.app and open it. Your boards, open tabs, settings, window frames and browser logins stay: the bundle id and folders are the same, so nothing moves.
omp: point the extension at the new path: ln -sf /Applications/easl.app/Contents/Resources/extensions/omp/easl.ts ~/.omp/agent/extensions/easl.ts.
Terminals and agents carry on: their environment names /Applications/Easl.app, which macOS’s default (case-insensitive) disk finds as easl.app. On a case-sensitive volume, restart the agents.
0.5.0
Released
Canvas is now easl, pronounced “easel”. Its first launch brings a Canvas install along (0.4, or 0.2), or a Chalkwork 0.3 one.
Tagged v0.5.0: Easl-0.5.0.zip on GitHub Releases, ad-hoc signed, for macOS 14 or later on Apple silicon, with gettext-0.24.tar.gz and THIRD_PARTY_NOTICES.md beside it. Everything on main since 0.4.0. The repository is github.com/twaldin/easl; twaldin/canvas and twaldin/chalkwork redirect there.
Canvas is now easl (0d95748): the same app under a new name. Its first launch brings one earlier install along, the newest: a Canvas 0.4 one (which already took Chalkwork’s along), else a Chalkwork 0.3 one, else a Canvas 0.2 one.
Upgrading from Canvas or Chalkwork
Quit Canvas and any Chalkwork still around (their terminal sessions keep running), unzip Easl-0.5.0.zip, move Easl.app to /Applications, clear its quarantine flag and open it. The first launch moves ~/Library/Application Support/Canvas to ~/Library/Application Support/Easl (every board, archived boards, snapshots, open tabs) and ~/.canvas to ~/.easl, moves the browser tiles’ logins and site data, and brings over Canvas’s settings and window frames. From a Canvas 0.2 that never ran 0.4 it takes Chalkwork’s instead when there is one; the other stays where it is. Anything already at easl’s locations is moved aside first, whole, to ~/Library/Application Support/Easl-stale-<time>/; nothing is deleted. While Canvas or Chalkwork is still running it moves nothing: quit it and open easl again.
Your terminals come back attached: their sessions keep their canvas-obj_… names. Restart the agents in them: an agent started under Canvas still has CANVAS_SOCKET and the canvas CLI, so it can’t reach easl until it restarts.
omp: point the extension at easl: rm -f ~/.omp/agent/extensions/canvas.ts ~/.omp/agent/extensions/chalkwork.ts, then ln -sf /Applications/Easl.app/Contents/Resources/extensions/omp/easl.ts ~/.omp/agent/extensions/easl.ts.
Every CANVAS_* variable is now EASL_* (e.g. EASL_LSP_<LANGUAGE> in your shell profile).
The CLI is easl (no canvas alias), the Python package easl_sdk (class Easl), the TypeScript client @easl/client, the agent skill easl, and board.export writes .easl/board.json.
Once your agents run under easl, delete /Applications/Canvas.app, and /Applications/Chalkwork.app if it’s still there.
macOS asks again before a terminal program or page uses the microphone, the camera or another app: those permissions belonged to Canvas.
0.4.0
Released
Chalkwork is Canvas again; its first launch brings a Chalkwork 0.3 install along. Plus fixes for restarted agents, fitted call graphs and agent.wait.
Tagged v0.4.0: Canvas-0.4.0.zip on GitHub Releases, ad-hoc signed, for macOS 14 or later on Apple silicon, with gettext-0.24.tar.gz and THIRD_PARTY_NOTICES.md beside it. Everything on main since 0.3.3. The repository is github.com/twaldin/canvas again; twaldin/chalkwork redirects there.
Chalkwork is Canvas again (7b701c9): the same app under the name it had through 0.2.1. Its first launch brings a Chalkwork 0.3 install along; a Canvas 0.2 one that never moved to Chalkwork is already where Canvas looks.
Upgrading from Chalkwork or Canvas
Quit Chalkwork and any old Canvas still around (their terminal sessions keep running), unzip Canvas-0.4.0.zip, move Canvas.app to /Applications (replacing an old Canvas.app there), clear its quarantine flag and open it. The first launch moves ~/Library/Application Support/Chalkwork to ~/Library/Application Support/Canvas (every board, archived boards, snapshots, open tabs) and ~/.chalkwork to ~/.canvas, moves the browser tiles’ logins and site data, and brings over Chalkwork’s settings and window frames. If Canvas 0.2 ran again after Chalkwork took its data, what it left there is moved aside first, whole, to ~/Library/Application Support/Canvas-stale-<time>/; nothing is deleted. While Chalkwork or an old Canvas is still running it moves nothing: quit it and open Canvas again.
Your terminals come back attached. Restart the agents in them: an agent started under Chalkwork still has CHALKWORK_SOCKET and the chalkwork CLI, so it can’t reach Canvas until it restarts.
omp: point the extension at Canvas: rm -f ~/.omp/agent/extensions/chalkwork.ts, then ln -sf /Applications/Canvas.app/Contents/Resources/extensions/omp/canvas.ts ~/.omp/agent/extensions/canvas.ts.
Every CHALKWORK_* variable is now CANVAS_* (e.g. CANVAS_LSP_<LANGUAGE> in your shell profile).
The CLI is canvas (no chalkwork alias), the Python package canvas_sdk, the TypeScript client @canvas/client, the agent skill canvas, and board.export writes .canvas/board.json.
Once your agents run under Canvas, delete /Applications/Chalkwork.app.
macOS asks again before a terminal program or page uses the microphone, the camera or another app: those permissions belonged to Chalkwork.
Fixed
A restarted agent keeps the tile’s flags (3003ace): after a reboot, an agent tile resumes its recorded session with the options of the tile’s own command. Codex keeps its -c overrides, Claude Code keeps --model and --dangerously-skip-permissions, omp keeps -e, opencode keeps its project.
A call graph created with size: "fit" comes up fitted, first time (a0a8b12, 7094ec6): the create computes the graph, waiting for the language server up to 60 s, and returns the tile fitted to it.
object.reload of a call graph returns at its timeoutMs (5b1e626): while the language server hasn’t answered, it answers loaded: false at the timeout, and the tile shows the graph when it comes.
agent.wait after a prompt that starts no turn doesn’t hang (d16f452): after a / command or ! escape, it fails with unavailable once 60 s pass without the turn starting.
A Codex tile trusted by -c doesn’t show a false folder question (262f786): Canvas now reads the -c overrides Codex keeps, as Codex reads them.
0.3.3
Released
An agent's question shows as needing you even with approvals off; opened from a worktree, Chalkwork reads that worktree's code.
Tagged v0.3.3: Chalkwork-0.3.3.zip on GitHub Releases, ad-hoc signed, for macOS 14 or later on Apple silicon, with gettext-0.24.tar.gz and THIRD_PARTY_NOTICES.md beside it. Everything on main since 0.3.2.
Still on Canvas 0.2? Read 0.3.0’s Upgrading from Canvas first: the first launch of Chalkwork moves your boards over, and agents started under Canvas need a restart.
Fixed
Questions, even with approvals off (bfd1835): when Claude Code or Codex asks you something mid-turn, its tile goes orange with the question itself in the bubble, and ⌘J and the edge pill find it, also with --dangerously-skip-permissions / --yolo. Answering takes it back to working. Before, Claude Code’s bubble said “approve AskUserQuestion?” and stayed orange until the turn ended, and Codex’s questions never showed.
Opened from a worktree, Chalkwork reads that worktree’s code (f71fcaa): the board is still the repository’s, rooted at the main checkout, but Go to (⌘P) lists and opens the worktree’s files and symbols, a worktree file’s language server is rooted at that worktree’s project, and call graphs are computed in the checkout their file is in. Code, image and diagram tiles an agent in a worktree creates with relative paths read its worktree. Before, they used the main checkout, and go-to-definition on worktree tiles found nothing.
0.3.2
Released
Codex asks once for chalkwork commands; a resumed Codex session keeps reporting; a second launch goes to the Chalkwork already running; approval bubbles stay beside the agent that asks.
Tagged v0.3.2: Chalkwork-0.3.2.zip on GitHub Releases, ad-hoc signed, for macOS 14 or later on Apple silicon, with gettext-0.24.tar.gz and THIRD_PARTY_NOTICES.md beside it. Everything on main since 0.3.1.
Still on Canvas 0.2? Read 0.3.0’s Upgrading from Canvas first: the first launch of Chalkwork moves your boards over, and agents started under Canvas need a restart.
Fixed
One Chalkwork per home (71906b7, closes #1): opening Chalkwork while it already runs on the same boards no longer starts a second instance that took over the first one’s socket (chalkwork calls failing unavailable). The new launch hands its folder to the running one, which opens that board and comes forward, and exits. Development homes still run side by side.
Codex asks once for chalkwork commands (f94df04): Codex now gets the session’s temp directory as a literal path, so “don’t ask again for commands that start with chalkwork” matches every later call. With a fresh Codex home: one approval in the first session and none in the next (before, every call with a payload asked again).
Approval bubbles stay beside the agent that asks (7b92915, closes #3): zoomed out to fit on a packed board, a blocked agent’s ✋ bubble stays within 200 pt of its ring instead of landing beside an unrelated tile.
A resumed Codex session reports its state (d3b3d12): codex resume <id> -c … in a tile used to drop Chalkwork’s hooks, so the tile stayed idle through the turn and showed no ring while Codex waited on an approval. The hooks now go beside your -c options.
0.3.1
Released
Fixes from the first-use study. Typing goes where you aimed; numbered tray chips you can click to find; mentions follow the worktree an agent works in; a finished agent stays green until you look.
Tagged v0.3.1: Chalkwork-0.3.1.zip on GitHub Releases, ad-hoc signed, for macOS 14 or later on Apple silicon, with gettext-0.24.tar.gz and THIRD_PARTY_NOTICES.md beside it. Everything on main since 0.3.0: fixes from watching people use Chalkwork for the first time.
Still on Canvas 0.2? Read 0.3.0’s Upgrading from Canvas first: the first launch of Chalkwork moves your boards over, and agents started under Canvas need a restart.
Fixed
Typing goes where you aimed (e17e4ce, 4d135ca): a press anywhere on a tile’s title bar (but its buttons) takes the tile and the keyboard, first click included. The tray says “→ codex · you’re typing in zsh” when the keyboard isn’t in the terminal it will send to. Tab never types into a selected tile; Esc and Tab reach Get Started; Go to (⌘P) selects the lines it showed, so ⇧⌘M mentions just those, and clicking a row goes there.
Discard from the keyboard asks first (e17e4ce, da58d71): in a changes tile r only asks and ⌘⌫ confirms, so prose typed into the wrong tile can’t discard your work. A growing changes tile never covers its neighbours.
Numbered tray chips (7dce9bd, af73360, bdf5cfb): chips are numbered [1], [2]… as the agent receives them. Clicking a chip shows what it points at: it selects it, brings it into view, and scrolls to and flashes the lines. The tray never widens the window: its “→ target” label stays whole, and chips shrink (keeping file:line) and then scroll. ⌘Z brings back chips a delete or Hyper-V took out; the Edit menu has Remove Last Mention (⌥⇧⌘M), Remove Mention ▸, Clear Mentions and Send Mentions To ▸.
Mentions follow the worktree (6c1476d, 8ac9198): after cd ../wt && codex, the terminal records the worktree and branch its program works in, so mentions from that worktree go to that agent. Review Changes and Review Branch review the focused or selected terminal’s worktree.
A finished agent stays green (9255ef0): looking at an agent while it works no longer marks its answer seen; a turn that ends while its tile is off-screen stays green until you look. ⌘J covers the board you’re on.
Browser tiles (8d3cb5e): ⌘A selects the address; ⌥⌘I shows and hides the Web Inspector, docked under the address bar; ⌘R reloads; Back drops the previous page’s error badge.
Walkthroughs (51d8dde): ⌥⌘→ starts at a walkthrough’s first stop and frames each stop readably.
0.3.0
Released
Canvas is now Chalkwork, with its own app icon. Mention a whole group with one Hyper-click; content zoom for a tile's text; arrows routed together; call graphs from a bare symbol name; terminals that wait for their session after a restart.
Tagged v0.3.0: Chalkwork-0.3.0.zip on GitHub Releases, ad-hoc signed, for macOS 14 or later on Apple silicon, with gettext-0.24.tar.gz and THIRD_PARTY_NOTICES.md beside it. Everything on main since 0.2.1.
Canvas is now Chalkwork: the same app under a new name, with its own app icon. Its first launch brings a Canvas 0.2 install along.
Upgrading from Canvas
Quit Canvas (its terminal sessions keep running), move Chalkwork.app to /Applications, clear its quarantine flag and open it. The first launch moves ~/Library/Application Support/Canvas to ~/Library/Application Support/Chalkwork (every board, archived boards, backups, snapshots, open tabs) and ~/.canvas to ~/.chalkwork, moves the browser tiles’ logins and site data, and brings over Canvas’s settings and window frames. While Canvas is still running it moves nothing: quit Canvas and open Chalkwork again.
Your terminals come back attached. Restart the agents in them: an agent started under Canvas still points at Canvas’s socket and CLI, so it can’t reach Chalkwork until it restarts.
omp: remove ~/.omp/agent/extensions/canvas.ts and link chalkwork.ts from /Applications/Chalkwork.app/Contents/Resources/extensions/omp/ into ~/.omp/agent/extensions/.
Every CANVAS_* variable is now CHALKWORK_*: rename CANVAS_LSP_<LANGUAGE> in your shell profile to CHALKWORK_LSP_<LANGUAGE>.
The CLI is chalkwork (no canvas alias), the Python package chalkwork_sdk, and the agent skill chalkwork.
Once your agents run under Chalkwork, delete /Applications/Canvas.app.
macOS asks again before a terminal program or page uses the microphone, the camera or another app: those permissions belonged to Canvas.
New
Mention a whole group (4f28ee5, 142f1e3): Hyper-click a group’s title or empty interior (or select it and press ⇧⌘M) and the agent gets the group: each member with a short excerpt, plus the arrows among them, capped at 120 lines. The innermost group under the pointer wins; the chip shows the group’s title.
Content zoom (44c8f4f): zoom a tile’s content in place (Object › Content Zoom, ⌃⌘= / ⌃⌘- through 25–500%, ⌃⌘0 back to 100%, or the title bar’s − % +). The tile keeps its size and its text reflows; a terminal gets bigger text and fewer columns; images don’t zoom. It replaces Scale: saved boards’ scale becomes zoom once, with the frame kept. The board itself still stops at 100%.
Improved
Readable arrows (71e1c2d, 24d6b5a, 087f3e7): a board’s avoid-routed arrows are routed together: no two share a segment, ports spread along a box’s side, a group can set a flow direction (GroupProps.flow), and each label stays by its own line. layout.check reports arrowOverlaps and arrowIntersections.
Diagram tiles (f143326, 9573f7d, 4de075c): a bare symbol (no path) is found through the language server’s workspace symbols, and an ambiguous one lists its candidates. A growing diagram takes only free space, and after your + click the view pans to show the new nodes.
Development bundles (5c1a2e6): an instance started on its own home runs from a copy of its bundle there, so macOS relaunching it at login brings it back on that home, not beside your installed app.
Fixed
Restarts (f5529a5, a98d16d): a terminal whose zmx session doesn’t answer waits for it, saying so, and attaches when it answers; omp and opencode report their state again when Chalkwork comes back (Claude Code and Codex at their next event).
CLI (69bcb47, 8ec8023): array params take one item, a comma-separated string or a repeated flag (--until working used to be sent as a bare string); board.get with branch returns that branch’s regions.
0.2.1
Released
Claude Code, Codex and any CLI drive browser tiles with canvas browser; one board per repository; tiles that follow a branch; pull-request diffs without a checkout; live call graphs from your language server; Help › Get Started.
Tagged v0.2.1: Canvas-0.2.1.zip on GitHub Releases, ad-hoc signed, for macOS 14 or later on Apple silicon, with gettext-0.24.tar.gz and THIRD_PARTY_NOTICES.md beside it. Everything on main since 0.2.0.
Upgrading from 0.2.0: quit Canvas and choose Keep Running, replace Canvas.app, clear the quarantine flag again, and reopen it: your terminals and agents reattach where they were.
New
Agents
canvas browser: Claude Code, Codex and any other CLI drive browser tiles: open, list, snapshot, click, type, fill, press, wait, eval, screenshot, close. Codex runs it escalated, like its other canvas commands; omp keeps its own browser tool. Browser tiles are WebKit, not Chrome, so CDP tools (Playwright, browser-use, Chrome DevTools MCP) can’t attach.
Help › Get Started: a new user’s first launch shows a short guide to Hyper-click (the ⌃⌥⇧⌘ chord, ⇧⌘M with no setup, or Caps Lock through Karabiner-Elements, linked and never installed), then a practice note to Hyper-click and send to an agent. Help › Get Started reopens it; existing users never see it on their own.
Boards
One board per repository: every worktree and branch of a repo opens the same board; worktrees and branches are attributes of it, and terminals record the worktree and branch they started in. The first launch merges the per-branch boards 0.2.0 kept into their repository’s board once, each as a titled region, with backups in boards/pre-repo-migration/; running terminals keep their sessions, and old board ids still resolve.
Keyed objects: any object can carry props.key, unique per board; object.find and object.upsert let a script or agent rebuild a region of the board by key instead of by id.
Code and review
Live call graphs: a diagram tile built from the language server shows who calls a function, what it calls, or both. Nodes are anchored to their symbols (name, file:line, a short excerpt); a node’s + adds one more level; a node whose symbol disappears keeps a stale badge; the graph recomputes when the files change. Hyper-click a node to mention it, and board arrows can end on a node. Needs a language server with call hierarchy (sourcekit-lsp verified).
Review a branch or pull request without checking it out: a changes tile with a head (any branch, or a fetched pull/N/head) shows base...head from git objects, read-only, with Viewed boxes. For a ref Canvas doesn’t have, it gives the exact git fetch to run; Canvas never fetches by itself.
Tiles that follow a branch: code, note and HTML tiles take ref: "<branch>". The tile reads the worktree that has the branch checked out; once that worktree is gone, the branch’s commits; after a merge, the merge commit (“merged in ”); after a squash merge and branch deletion, its last known commit (“branch gone, showing ”).
Fixed
Language-server hovers keep code exactly as written and render escaped Markdown without backslashes.
A Codex tile turns idle once you trust its folder, and a Codex turn that fails (the usage limit) ends its working state with the error.
A Gemini CLI approval cancelled with Esc no longer leaves the tile orange.
Licenses
THIRD_PARTY_NOTICES.md covers libghostty’s bundled pieces and fonts, and GNU libintl’s source, relinking steps and written offer. Every release now carries it and the gettext source.
0.2.0
Released
Terminal tiles open in the downloaded app; Claude Code, Codex, opencode, Gemini CLI and aider join omp; a changes tile for reviewing agents' work; ⌘J, Canvas Basics, Back and Forward, walkthrough steps, Scale; and 0.2 idle wakeups/s with 3 idle omp agents + 1 shell, window shown, nothing focused.
Tagged v0.2.0: Canvas-0.2.0.zip on GitHub Releases, ad-hoc signed, for macOS 14 or later on Apple silicon. Everything that landed on main since 0.1.0, plus the fix that lets the downloaded app open terminal tiles.
New
More agents
Claude Code and Codex get the same integration as omp with zero setup, only inside Canvas: lifecycle, mentions, follow tiles and the canvas skill, with nothing written to your global agent config. After a reboot their tiles resume the recorded session.
opencode and Gemini CLI (before 0.60) integrations: working, blocked and done, mentions and follow tiles.
aider and any CLI that sends a terminal notification or bell now shows as an agent: its tile turns green when it waits for you.
Hyper-V (⌃⌥⇧⌘V) pastes staged mentions into the terminal you’re typing in, for agents without an integration.
Agents can hand each other board objects with a prompt, and read just another agent’s final answer.
Reviewing
Changes tile (File › Review Changes, ⇧⌘R): what changed, file by file, as a unified diff. Compare uncommitted changes, the branch against its default branch (File › Review Branch), or any commit; review other worktrees of the repository.
Stage, Unstage and Discard per file, hunk or selected lines, each one ⌘Z. Discard asks first and only puts back work that isn’t committed yet. Viewed boxes, a file list, a filter, and j/k, J/K, s, u, r keys.
Knowing what needs you
⌘J (Go to Next Needs-You): blocked agents, then marked tiles, then finished agents you haven’t seen. “Nothing needs you” when there’s nothing.
A blocked agent gets an orange ring and a ✋ bubble with its question; off screen, a pill at the edge of the view points at it. Markers are pink.
A dot on a board’s tab when an agent there is blocked (orange) or finished unseen (green).
Help › Canvas Basics (⌥⌘/): a one-screen legend of the dots, markers, tray and keys, with the same words as tooltips, and a hint on an empty board.
Getting around
Back and Forward (⌘[ / ⌘]) through Go to, definitions, links, ⌘J, ⌘9 and steps.
⌥⌘-arrows move between tiles, and step along an agent’s walkthrough in order (“Last step” at the end).
Go to (⌘P) lists what needs you first, your recent code locations, the board’s files (core.py:120 opens at a line), @symbols and note headings.
Scale a tile for bigger text: ⌃⌘= / ⌃⌘- / ⌃⌘0 through 50–200%, or ⌥-drag a corner. The tile makes room instead of covering its neighbours.
View › Hide Canvas Chrome (⌥⌘T), for presenting.
Edit › Mention (⇧⌘M) stages whatever the keyboard is on.
Every action is in the menu bar, and tiles are labelled for VoiceOver, which reads code tiles and terminals.
Tiles
Image tiles for charts and figures, reloading when the file changes; images in notes and HTML tiles.
Terminals use your Ghostty config (theme, colors, font family, keybinds) and load Ghostty’s shell integration: a failed or long command shows exit 1 · 42 s in the header, and ⌘↑ / ⌘↓ jump between prompts.
⌘-click a path:line in a terminal to open it beside the terminal, including Python tracebacks and pdb frames; ⌥⌘-click opens a tile you keep.
Hyper-click a finished command’s output to hand the agent the whole command block.
Browser tiles record console errors and failed requests from page load, with a quiet error count you can Hyper-click; ⌥⌘I opens the Web Inspector; Snapshot to Image freezes a page for before/after evidence; Canvas › Clear Browsing Data….
Find in a code tile (⌘F), File › Open File as Code Tile… (⌘O), and navigation without a language server by text search.
Notes: Copy and Save as Markdown; path:line links anywhere in a note; tables wrap to the note’s width.
Copy as Image (⇧⌘C) and Export Selection as PNG… (⇧⌘E), drawn without canvas chrome.
Objects an agent makes say “by ” in their title bar.
Improved
Idle wakeups: with 3 idle omp agents and 1 shell, window shown and nothing focused, Canvas measures 0.2 idle wakeups/s and 0.0% CPU (top), down from 24/s and 0.9%. The same setup with the window minimized: 2–5 interrupt wakeups/s, down from about 50–56.
Browser pages nobody can see are hidden from WebKit and released after 2 minutes.
Every undo and redo shows a notice naming what it did, including an agent’s batch and a Stage or Discard. ⌘Z inside a terminal stays with the terminal.
Agents that finish or ask a question while Canvas is closed come back done or blocked, with their answer. A prompt sent to a working agent joins its current turn.
New tiles, yours and agents’, land in view next to where you’re working, clear of other tiles; the view never moves by itself.
Code tile ranges and note excerpts stay on their code as lines move, and say “stale” when it’s gone; applied proposals show “✓ applied”.
The tray’s target is a menu of terminals, prefers the agent over a dev-server shell beside it, and is remembered across restarts. Mentions from another worktree go to the agent working there.
Keyboard focus follows what you select; Return enters a tile, ⌘Esc leaves any tile, and Canvas’s shortcuts win over your Ghostty keybinds.
A mouse wheel pans, ⌘-scroll zooms around the pointer, and a Ctrl shortcut on the canvas names its ⌘ key.
Language servers are found through your login shell, nvim’s mason, ~/go/bin, rustup which or CANVAS_LSP_<LANGUAGE>, and a server installed while Canvas runs is picked up without a restart.
Notes never lose your typing when an agent edits them at the same time; new notes start in editing.
The text tool keeps what you type, arrow ends bind to what they nearly touch, and the default ink stays visible over light pages.
Closing a tab or window with terminals asks: Keep Running, End Sessions or Cancel. The README has an Uninstall section.
Small text meets 4.5:1 contrast.
Fixed
Terminal tiles open in the downloaded app. 0.1.0 crashed at the first terminal tile on any Mac but the one that built it: it couldn’t find libghostty-spm’s resource bundle, which the app now finds in Contents/Resources.
xattr -dr com.apple.quarantine /Applications/Canvas.app clears every file in the app. Some of its resource files were copied read-only, so the command couldn’t clear them.
Shell history from Canvas terminals was saved inside the app bundle; it now goes to ~/.zsh_history.
Terminal tiles inherited the environment of whatever launched Canvas (for example EDITOR=true, which stopped git commit); they now start like a fresh login session.
A code tile could keep saying “no commits yet” after a cancelled git load, and a newly committed file kept saying “not tracked by git yet”.
Codex’s internal memory session could mark a Codex tile done mid-turn and break its resume.
⌘Z could undo a terminal’s ⌘-click preview instead of the Discard its notice named.
With Canvas Basics or two boards open, ⌘Z and menu commands could act on a board that wasn’t in front.
A tile scaled up could cover its neighbours; a multi-line blocked bubble could spill over the canvas.
Keep Running on the last window lost the board for the next launch.
⇧⌘[ and ⇧⌘] reach Send to Back and Bring to Front again.
0.1.0
Released
The first release. A native macOS infinite canvas where omp and any other terminal agent run in real terminal tiles, next to live code, notes, HTML, browser tiles and drawings.
The first public release, tagged v0.1.0: Canvas-0.1.0.zip on GitHub Releases, ad-hoc signed, for macOS 14 or later on Apple silicon. MIT licensed.
The canvas
A native AppKit canvas, one per directory (a repo or a worktree), with boards as tabs of one window and File › Open Board….
Pan, pinch and zoom up to 100%; zoomed far out, tiles become cards tinted by their agent’s state.
Selection with a box or a lasso, groups as titled regions, context menus, and undo for every change, yours or an agent’s.
Go to… (⌘P) searches every group and tile by title, path or note heading.
Zoom to Fit (⌘9) frames the main cluster of work instead of a few far-off strays, and a “Nothing here · Back to content” pill brings you home from empty space.
Terminals and agents
Terminal tiles rendered by libghostty, running in zmx sessions: agents keep running when Canvas quits, crashes or is rebuilt, and are back when you open the folder again.
omp is the first-class agent, through Canvas’s omp extension (one symlink). omp tiles report their lifecycle (working, blocked, done, idle) on the title bar and zoomed-out cards, raise attention markers, drive a follow tile, receive your mentions, get the canvas skill, and resume their session after a reboot.
macOS notifications when an agent needs you and Canvas isn’t in front.
Any other terminal program runs in a tile unmodified.
Code
Code tiles show the whole file scrolled to a range, with syntax highlighting, soft-wrapped long lines and a gitsigns-style gutter against the merge-base (or HEAD); click a sign to peek at the old lines.
Language-server hover, go to definition, references and outline.
A follow tile per agent terminal tracks the file and line the agent last read or edited, with a history strip, edit flashes, Pin and Edit Here.
Notes, HTML and browser tiles
Markdown notes whose code fences stay live against the files they quote (file=path#L10-40 or symbol=Name), with propose fences rendered as diffs and a stale badge when an anchor is lost.
Sandboxed HTML tiles, network blocked by default, with a bundled kit: Tailwind, Mermaid and grounded code components.
WebKit browser tiles that omp’s browser tool drives.
Drawing and mentions
Shapes, arrows (straight, orthogonal, or routed around tiles), ink, text and titled group regions, with a hand-drawn feel.
Hyper-click (⌃⌥⇧⌘-click) a code line, a DOM element, a note paragraph, a terminal line or a shape to stage a mention in the tray; your next omp prompt carries it.
Agent API
A local Unix socket with a JSON schema, a Python SDK, a TypeScript client and the canvas CLI.
Atomic batches, measure and fit, layout helpers and layout.check; offscreen view.render that never moves your view; the board’s activity history; attention markers; agent-to-agent agent.list, prompt, wait and read; shared compositions in ~/.canvas/compositions/.
Known issue
In the downloaded app, terminal tiles fail to open on any Mac but the one that built it: a missing resource bundle. Fixed in 0.2.0.