toyon 0.23.0 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/README.md +26 -21
  2. package/dist/CHANGELOG.md +32 -0
  3. package/dist/cli.js +1 -1
  4. package/dist/daemon.js +1609 -1229
  5. package/dist/shell/assets/{Editor-C2e_GpDQ.js → Editor-Dq4a0gFv.js} +164 -164
  6. package/dist/shell/assets/Editor-Dq4a0gFv.js.br +0 -0
  7. package/dist/shell/assets/Editor-Dq4a0gFv.js.gz +0 -0
  8. package/dist/shell/assets/{XTerm-B84G0H5I.js → XTerm-BfuBg96X.js} +2 -2
  9. package/dist/shell/assets/XTerm-BfuBg96X.js.br +0 -0
  10. package/dist/shell/assets/XTerm-BfuBg96X.js.gz +0 -0
  11. package/dist/shell/assets/{cssMode-DhDLwjyN.js → cssMode-An1EUPnJ.js} +1 -1
  12. package/dist/shell/assets/cssMode-An1EUPnJ.js.br +0 -0
  13. package/dist/shell/assets/cssMode-An1EUPnJ.js.gz +0 -0
  14. package/dist/shell/assets/{freemarker2-rc8sP22g.js → freemarker2-PYOY2M7v.js} +1 -1
  15. package/dist/shell/assets/freemarker2-PYOY2M7v.js.br +0 -0
  16. package/dist/shell/assets/freemarker2-PYOY2M7v.js.gz +0 -0
  17. package/dist/shell/assets/{grammar-Cty-NAQC.js → grammar-e2yQ-Xdq.js} +1 -1
  18. package/dist/shell/assets/grammar-e2yQ-Xdq.js.br +0 -0
  19. package/dist/shell/assets/grammar-e2yQ-Xdq.js.gz +0 -0
  20. package/dist/shell/assets/{handlebars-BOQxV3p5.js → handlebars-BtSTwhBl.js} +1 -1
  21. package/dist/shell/assets/handlebars-BtSTwhBl.js.br +0 -0
  22. package/dist/shell/assets/handlebars-BtSTwhBl.js.gz +0 -0
  23. package/dist/shell/assets/{html-CxndUpse.js → html-lmman0qi.js} +1 -1
  24. package/dist/shell/assets/html-lmman0qi.js.br +0 -0
  25. package/dist/shell/assets/html-lmman0qi.js.gz +0 -0
  26. package/dist/shell/assets/{htmlMode-CG7eVDLo.js → htmlMode-CYUUrmIv.js} +1 -1
  27. package/dist/shell/assets/htmlMode-CYUUrmIv.js.br +0 -0
  28. package/dist/shell/assets/htmlMode-CYUUrmIv.js.gz +0 -0
  29. package/dist/shell/assets/index-BDzHAr7c.css +1 -0
  30. package/dist/shell/assets/index-BDzHAr7c.css.br +0 -0
  31. package/dist/shell/assets/index-BDzHAr7c.css.gz +0 -0
  32. package/dist/shell/assets/index-o7SjsIYr.js +294 -0
  33. package/dist/shell/assets/index-o7SjsIYr.js.br +0 -0
  34. package/dist/shell/assets/index-o7SjsIYr.js.gz +0 -0
  35. package/dist/shell/assets/{javascript-CafoevnZ.js → javascript-CHVOacyY.js} +1 -1
  36. package/dist/shell/assets/{jsonMode-Cg_4sMB_.js → jsonMode-WaLJvHyp.js} +1 -1
  37. package/dist/shell/assets/jsonMode-WaLJvHyp.js.br +0 -0
  38. package/dist/shell/assets/jsonMode-WaLJvHyp.js.gz +0 -0
  39. package/dist/shell/assets/{liquid-DxW_HNid.js → liquid-Bhzd8TLd.js} +1 -1
  40. package/dist/shell/assets/liquid-Bhzd8TLd.js.br +0 -0
  41. package/dist/shell/assets/liquid-Bhzd8TLd.js.gz +0 -0
  42. package/dist/shell/assets/{lspLanguageFeatures-Dhat9l4L.js → lspLanguageFeatures-DS22S_fR.js} +2 -2
  43. package/dist/shell/assets/lspLanguageFeatures-DS22S_fR.js.br +0 -0
  44. package/dist/shell/assets/lspLanguageFeatures-DS22S_fR.js.gz +0 -0
  45. package/dist/shell/assets/{mdx-ZdMhgPNL.js → mdx-1x45Dt5R.js} +1 -1
  46. package/dist/shell/assets/mdx-1x45Dt5R.js.br +0 -0
  47. package/dist/shell/assets/mdx-1x45Dt5R.js.gz +0 -0
  48. package/dist/shell/assets/{python-Bae_7wMM.js → python-B0fHYRyj.js} +1 -1
  49. package/dist/shell/assets/python-B0fHYRyj.js.br +0 -0
  50. package/dist/shell/assets/python-B0fHYRyj.js.gz +0 -0
  51. package/dist/shell/assets/{razor-CtwiCIJH.js → razor-C48vGnF3.js} +1 -1
  52. package/dist/shell/assets/razor-C48vGnF3.js.br +0 -0
  53. package/dist/shell/assets/razor-C48vGnF3.js.gz +0 -0
  54. package/dist/shell/assets/toyon-mono-bold-u3Ky0k2u.woff2 +0 -0
  55. package/dist/shell/assets/toyon-mono-regular-BC3CdGld.woff2 +0 -0
  56. package/dist/shell/assets/{tsMode-DH9rMbRS.js → tsMode-2SIN2sKE.js} +1 -1
  57. package/dist/shell/assets/tsMode-2SIN2sKE.js.br +0 -0
  58. package/dist/shell/assets/tsMode-2SIN2sKE.js.gz +0 -0
  59. package/dist/shell/assets/{xml-rA-vNTCn.js → xml-DPJN-pu8.js} +1 -1
  60. package/dist/shell/assets/xml-DPJN-pu8.js.br +0 -0
  61. package/dist/shell/assets/xml-DPJN-pu8.js.gz +0 -0
  62. package/dist/shell/assets/{yaml-pOtRRozm.js → yaml-CDzmW7EM.js} +1 -1
  63. package/dist/shell/assets/yaml-CDzmW7EM.js.br +0 -0
  64. package/dist/shell/assets/yaml-CDzmW7EM.js.gz +0 -0
  65. package/dist/shell/index.html +2 -2
  66. package/package.json +1 -1
  67. package/dist/shell/assets/Editor-C2e_GpDQ.js.br +0 -0
  68. package/dist/shell/assets/Editor-C2e_GpDQ.js.gz +0 -0
  69. package/dist/shell/assets/XTerm-B84G0H5I.js.br +0 -0
  70. package/dist/shell/assets/XTerm-B84G0H5I.js.gz +0 -0
  71. package/dist/shell/assets/cssMode-DhDLwjyN.js.br +0 -0
  72. package/dist/shell/assets/cssMode-DhDLwjyN.js.gz +0 -0
  73. package/dist/shell/assets/freemarker2-rc8sP22g.js.br +0 -0
  74. package/dist/shell/assets/freemarker2-rc8sP22g.js.gz +0 -0
  75. package/dist/shell/assets/grammar-Cty-NAQC.js.br +0 -0
  76. package/dist/shell/assets/grammar-Cty-NAQC.js.gz +0 -0
  77. package/dist/shell/assets/handlebars-BOQxV3p5.js.br +0 -0
  78. package/dist/shell/assets/handlebars-BOQxV3p5.js.gz +0 -0
  79. package/dist/shell/assets/html-CxndUpse.js.br +0 -0
  80. package/dist/shell/assets/html-CxndUpse.js.gz +0 -0
  81. package/dist/shell/assets/htmlMode-CG7eVDLo.js.br +0 -0
  82. package/dist/shell/assets/htmlMode-CG7eVDLo.js.gz +0 -0
  83. package/dist/shell/assets/index-DpSfPmkM.css +0 -1
  84. package/dist/shell/assets/index-DpSfPmkM.css.br +0 -0
  85. package/dist/shell/assets/index-DpSfPmkM.css.gz +0 -0
  86. package/dist/shell/assets/index-DzfHDra7.js +0 -294
  87. package/dist/shell/assets/index-DzfHDra7.js.br +0 -0
  88. package/dist/shell/assets/index-DzfHDra7.js.gz +0 -0
  89. package/dist/shell/assets/jsonMode-Cg_4sMB_.js.br +0 -0
  90. package/dist/shell/assets/jsonMode-Cg_4sMB_.js.gz +0 -0
  91. package/dist/shell/assets/liquid-DxW_HNid.js.br +0 -0
  92. package/dist/shell/assets/liquid-DxW_HNid.js.gz +0 -0
  93. package/dist/shell/assets/lspLanguageFeatures-Dhat9l4L.js.br +0 -0
  94. package/dist/shell/assets/lspLanguageFeatures-Dhat9l4L.js.gz +0 -0
  95. package/dist/shell/assets/mdx-ZdMhgPNL.js.br +0 -0
  96. package/dist/shell/assets/mdx-ZdMhgPNL.js.gz +0 -0
  97. package/dist/shell/assets/python-Bae_7wMM.js.br +0 -0
  98. package/dist/shell/assets/python-Bae_7wMM.js.gz +0 -0
  99. package/dist/shell/assets/razor-CtwiCIJH.js.br +0 -0
  100. package/dist/shell/assets/razor-CtwiCIJH.js.gz +0 -0
  101. package/dist/shell/assets/toyon-mono-bold-9c1iJO0D.woff2 +0 -0
  102. package/dist/shell/assets/toyon-mono-regular-BXyxgSUK.woff2 +0 -0
  103. package/dist/shell/assets/tsMode-DH9rMbRS.js.br +0 -0
  104. package/dist/shell/assets/tsMode-DH9rMbRS.js.gz +0 -0
  105. package/dist/shell/assets/xml-rA-vNTCn.js.br +0 -0
  106. package/dist/shell/assets/xml-rA-vNTCn.js.gz +0 -0
  107. package/dist/shell/assets/yaml-pOtRRozm.js.br +0 -0
  108. package/dist/shell/assets/yaml-pOtRRozm.js.gz +0 -0
package/README.md CHANGED
@@ -4,7 +4,7 @@ Toyon is where you ask for changes to your web app and try them as they happen.
4
4
 
5
5
  Each copy runs on your own machine, and the next one is pre-warmed. Works with Claude Code, Codex and OpenCode over the Agent Client Protocol (ACP).
6
6
 
7
- [toyon.dev](https://toyon.dev) · [How it works](#how-it-works) · [Install](#install) · [Under the hood](#under-the-hood) · [Trust](#trust) · [Uninstall](#uninstall)
7
+ [toyon.dev](https://toyon.dev) · [Docs](https://toyon.dev/docs/) · [How it works](#how-it-works) · [Install](#install) · [Under the hood](#under-the-hood) · [Trust](#trust) · [Uninstall](#uninstall) · [Changelog](https://github.com/toyon-dev/toyon/blob/main/CHANGELOG.md)
8
8
 
9
9
  ![Toyon with four chats on a plant shop, each changing its own copy. The desk opens a code, a phone signs in with it and starts a copy of its own, both screens follow that chat, and both end on the last copy with its Wildflowers filter pressed, ready to land](https://raw.githubusercontent.com/toyon-dev/toyon/main/docs/images/toyon.gif)
10
10
 
@@ -34,6 +34,8 @@ When your check passes, land merges into main on your machine by default, or pus
34
34
 
35
35
  Built for web apps. A project without a page still works; the chat takes the middle instead of the preview.
36
36
 
37
+ How to use it is in [docs/using.md](https://github.com/toyon-dev/toyon/blob/main/docs/using.md). Every feature and shortcut is in [docs/features.md](https://github.com/toyon-dev/toyon/blob/main/docs/features.md).
38
+
37
39
  ## Install
38
40
 
39
41
  Try it in a project:
@@ -59,7 +61,7 @@ You need:
59
61
  - An account for the agent you pick: a Claude plan or an Anthropic API key for Claude Code, a ChatGPT plan or an OpenAI API key for Codex, or any provider OpenCode signs into.
60
62
  - On Linux, bubblewrap and socat for the agents' sandbox (`sudo apt install bubblewrap socat`). `toyon doctor` checks both and prints the AppArmor profile Ubuntu 24.04 and later ask for.
61
63
 
62
- Each agent signs in from the chat. Claude Code and Codex install on first start; OpenCode is a larger download with no subagents, effort levels or steering mid-turn. What each one reads and can do is in [docs/agents.md](https://github.com/toyon-dev/toyon/blob/main/docs/agents.md).
64
+ Each agent signs in from the chat. Claude Code and Codex install on first start; OpenCode is a larger download with no subagents, effort levels or steering mid-turn. What each one reads and can do is in [docs/agents.md](https://github.com/toyon-dev/toyon/blob/main/docs/agents.md). Requirements, updating and uninstalling are in [docs/install.md](https://github.com/toyon-dev/toyon/blob/main/docs/install.md), and every command is in [docs/commands.md](https://github.com/toyon-dev/toyon/blob/main/docs/commands.md).
63
65
 
64
66
  ## How is this different from what you use now?
65
67
 
@@ -72,7 +74,7 @@ Each agent signs in from the chat. Claude Code and Codex install on first start;
72
74
 
73
75
  ## Under the hood
74
76
 
75
- The contract for anything Toyon runs: *stay in the foreground, listen on `$PORT`, reload yourself however you like.* A `.toyon/settings.json` in the project names the setup commands, the commands to `run`, an optional `check` and how work lands. The first open guesses one from `package.json`, asks you to confirm it, and writes it into the project; other stacks start from an empty guess the agent can fill in. If a server comes up on some other port anyway, the preview follows it there and says which flag to add.
77
+ A `.toyon/settings.json` in the project lists the setup commands, the commands to `run`, an optional `check` and how work lands. Toyon guesses it the first time you open a project. Each `run` command must stay in the foreground and listen on `$PORT`.
76
78
 
77
79
  A project with a page and an API behind it:
78
80
 
@@ -88,39 +90,42 @@ A project with a page and an API behind it:
88
90
  }
89
91
  ```
90
92
 
91
- Each command gets its own `$PORT`, and the addresses of the others as `<NAME>_URL` (`API_URL` here), so the page can proxy to its API. The preview shows `web`. A command that names a folder of the tree, `server/` here, runs once, in the main checkout, and every copy's page reaches that one until the copy's own changes touch that folder; then the copy starts its own. A copy that only changes the page costs one Vite.
93
+ - Backend commands run once, in the main checkout, and every chat shares them until a chat changes backend files.
94
+ - A chat's servers stop when it has not been opened for two hours. The chat and the agent keep running.
95
+ - `toyon doctor` reports what is running and why a page cannot connect.
92
96
 
93
- Copies start when you open them, and stop their servers when nobody has looked at them for a while; the chat and the agent keep going. Close the window and the daemon stops itself once nothing has needed it for half an hour; `toyon stop` stops it now, and everything it runs. `toyon doctor` says what is running and why a page cannot connect. Every setting, the port rules and the sleep delay are in [docs/settings.md](https://github.com/toyon-dev/toyon/blob/main/docs/settings.md).
97
+ Every setting is in [docs/settings.md](https://github.com/toyon-dev/toyon/blob/main/docs/settings.md). Sharing a backend and a database per chat are in [docs/backends.md](https://github.com/toyon-dev/toyon/blob/main/docs/backends.md).
94
98
 
95
99
  ## What it does not do
96
100
 
97
- - It is not an editor. You can browse the files, read and edit a diff and run a terminal, but there is no multi-file editing, no debugger, no extensions, no inline completion.
98
- - Only land pushes, when you press it. The agent is told not to push or delete branches.
99
- - It works on git repositories, and the product uses git's words for what it does. A new project starts one for you.
100
- - It does not keep copies apart from services they share. Each copy runs your setup and your commands on its own, so a database or a compose stack they all point at is shared, migrations included. `TOYON_WORKTREE` in every command's environment lets a project give each copy its own (`app_$TOYON_WORKTREE` as the database name); [docs/settings.md](https://github.com/toyon-dev/toyon/blob/main/docs/settings.md#keeping-copies-apart) has the recipes.
101
- - It does not carry a login between copies. Each preview has its own cookies, so a new chat's app starts signed out, and an OAuth provider cannot redirect into a preview at all.
101
+ - It does not push unless you land with a route that pushes. Agents are told not to push or delete branches.
102
+ - It does not give each chat its own database. A database or a compose stack that every chat connects to is shared, migrations included. [docs/backends.md](https://github.com/toyon-dev/toyon/blob/main/docs/backends.md#a-database-per-copy) has recipes for Postgres, Neon, Docker Compose and SQLite.
103
+ - It does not carry a login between chats. Each preview has its own cookies, so a new chat's app starts signed out, and an OAuth provider cannot redirect into a preview.
102
104
 
103
105
  ## Your own server
104
106
 
105
- Toyon can also run on a box you open from your phone, or on your own Fly account with the laptop closed. This moves Toyon and its copies off your laptop; it does not publish your app. None of it passes through a Toyon server; there is none. `toyon remote` puts a box on your own domain behind Caddy or on your Tailscale tailnet, `toyon deploy fly up` builds a machine on your Fly account and prints the link, and the Dockerfile in the package runs on any host with a disk and a port range. A Fly machine measured about $4-6 a month in ordinary use, plus whatever your agents spend, and its first chat can sign in with your Claude plan. A phone or a second machine pairs by opening the address and being let in from Toyon's window.
107
+ Toyon can also run on a box you open from your phone, or on your own Fly account with the laptop closed. This moves Toyon and its copies off your laptop; it does not publish your app. There is no hosted Toyon service, and your code and keys are never sent to Toyon. `toyon remote` puts a box on your own domain behind Caddy or on your Tailscale tailnet, `toyon deploy fly up` builds a machine on your Fly account and prints the link, and the Dockerfile in the package runs on any host with a disk and a port range. A Fly machine measured about $4-6 a month in ordinary use, plus whatever your agents spend, and its first chat can sign in with your Claude plan. A phone or a second machine pairs by opening the address and being let in from Toyon's window.
106
108
 
107
- These routes are new. How to set each one up, and what it has been checked with, is in [docs/remote.md](https://github.com/toyon-dev/toyon/blob/main/docs/remote.md).
109
+ These routes are new. How to set each one up, and what it has been checked with, is in [docs/remote.md](https://github.com/toyon-dev/toyon/blob/main/docs/remote.md). Pairing a phone is in [docs/phone.md](https://github.com/toyon-dev/toyon/blob/main/docs/phone.md).
108
110
 
109
111
  ## Disk
110
112
 
111
- Each copy is a real `git worktree` under `~/.toyon/worktrees.noindex` with its own `node_modules`, cloned from the main checkout with copy-on-write where the filesystem has it: `cp -c` on APFS, `--reflink=auto` on btrfs and XFS. A new copy then costs seconds and almost no space until files diverge. On ext4 and other filesystems without reflinks it is a plain copy, and each one costs a full `node_modules`. The setup log says which path ran. Nothing is deleted without you.
113
+ Each chat's copy is a git worktree under `~/.toyon/worktrees.noindex`. On APFS, btrfs and XFS it is cloned copy-on-write, so it takes seconds and almost no space. On ext4 each one is a full copy, `node_modules` included. See [docs/using.md](https://github.com/toyon-dev/toyon/blob/main/docs/using.md#disk).
112
114
 
113
115
  ## Trust
114
116
 
115
- The daemon listens on loopback only and every request carries a per-machine token. Nothing is exposed to your network, and turning on remote access admits one name over https and nothing else.
117
+ Agents run in an OS sandbox, Seatbelt on macOS and bubblewrap on Linux, and can write only inside their copy of the project. Toyon listens on loopback only, and every request carries a per-machine token.
116
118
 
117
- Agents run confined. Everything a shell command spawns runs inside an OS sandbox (Seatbelt on macOS, bubblewrap on Linux) that can write to the worktree, the temp directories and package-manager caches, and nothing else, and the file tools are held to the same boundary. An agent cannot widen its own sandbox or another's. MCP servers run as each agent runs them, outside Toyon's sandbox. Opening a repository runs its setup, its dev server and whatever it configures for the agents, so open the ones you trust.
119
+ Known gaps:
118
120
 
119
- Each chat has a permission mode, shown next to the prompt. **auto**, the default, lets edits and sandboxed commands run and asks only when the agent proposes a plan. **ask** turns every edit and every command into a card in the chat before it runs. **plan** puts the agent in its read-only mode, and approving its plan chooses whether the work runs in auto or ask.
121
+ - `git push` is blocked by a command filter for Claude Code and OpenCode, and is not blocked for Codex. If your git credentials are on the machine, an agent could still find a way to push.
122
+ - Codex's shell commands can read Toyon's token.
123
+ - MCP servers run outside the sandbox.
124
+ - Opening a repository runs its setup commands, its dev server and its agent configuration. Open only repositories you trust.
120
125
 
121
- One limit worth knowing: the sandbox cannot tell a commit from a push. `git push`, branch deletion and `gh pr` are refused by rules in the configuration Toyon gives Claude Code and OpenCode, and every agent is told not to push. Codex has no equivalent list, and its shell commands can read Toyon's token. That is a command filter, not a wall: if your credentials are on the machine, a determined agent could still find a spelling that pushes. The whole boundary, per agent, is in [docs/trust.md](https://github.com/toyon-dev/toyon/blob/main/docs/trust.md).
126
+ Each chat has a permission mode: auto, ask or plan. On a company machine, IT can turn features off with a policy file.
122
127
 
123
- On a company machine, IT can turn updates, deploying, remote access, particular agents and the personal Claude sign-in off for everyone with one root-owned file, pushed the way Chrome's policies are; `toyon doctor` shows what is in effect. The file and its keys are in [docs/policy.md](https://github.com/toyon-dev/toyon/blob/main/docs/policy.md).
128
+ The details are in [docs/trust.md](https://github.com/toyon-dev/toyon/blob/main/docs/trust.md) and [docs/policy.md](https://github.com/toyon-dev/toyon/blob/main/docs/policy.md).
124
129
 
125
130
  ## Uninstall
126
131
 
@@ -129,15 +134,15 @@ toyon uninstall
129
134
  npm uninstall -g toyon
130
135
  ```
131
136
 
132
- The first command lists what it will remove from `~/.toyon` and asks before doing it. It keeps your projects, every branch Toyon made under `toyon/`, and Toyon's settings in each project. It does not delete a machine you deployed to Fly; run `toyon deploy fly destroy <name>` first.
137
+ `toyon uninstall` asks before it removes anything, and keeps your projects and your `toyon/` branches. Delete a Fly machine first, with `toyon deploy fly destroy <name>`. See [docs/commands.md](https://github.com/toyon-dev/toyon/blob/main/docs/commands.md#toyon-uninstall).
133
138
 
134
139
  ## Telemetry
135
140
 
136
- None: nothing about you or your work is sent anywhere. Toyon's one call of its own is an update check every six hours against the registry npm is set up for, and `TOYON_UPDATES=off` stops it. The rest of the traffic is to the agents you sign into, to npm on first start to fetch the Claude Code and Codex adapters and again when you first pick OpenCode, to Fly when you deploy there, and to whatever your own dev servers, `git fetch` and `git push` talk to.
141
+ Toyon sends no telemetry. It checks for updates every six hours. To disable it, use `TOYON_UPDATES=off`. Every request Toyon makes is listed in [docs/trust.md](https://github.com/toyon-dev/toyon/blob/main/docs/trust.md#telemetry).
137
142
 
138
143
  ## Help build it
139
144
 
140
- Toyon is early, and there is more worth doing than there are hands. The most useful thing right now is an issue: what you ran, what broke, and what your project is built with, especially anything that is not a Node app. Pull requests are welcome too; [CONTRIBUTING.md](https://github.com/toyon-dev/toyon/blob/main/CONTRIBUTING.md) has the setup, and `bun run check` is the bar.
145
+ Toyon is early, and there is more worth doing than there are hands. The most useful thing right now is an issue: what you ran, what broke, and what your project is built with, especially anything that is not a Node app. Pull requests are welcome too; [CONTRIBUTING.md](https://github.com/toyon-dev/toyon/blob/main/CONTRIBUTING.md) has the setup. Run `bun run check` before you open one.
141
146
 
142
147
  ## License
143
148
 
package/dist/CHANGELOG.md CHANGED
@@ -2,6 +2,38 @@
2
2
 
3
3
  What changed in each release of Toyon, newest first.
4
4
 
5
+ ## 0.24.0 (2026-11-12)
6
+
7
+ Changed markdown files open as a rendered diff, landing no longer drops work, and the daemon and the shell close several holes around tokens and links.
8
+
9
+ ### New
10
+ - A changed markdown file opens as a rendered diff that marks which words, table cells and list items came and went. It follows the code diff's inline or split choice, and the editor head has one file, inline and split control in place of the separate markdown knobs.
11
+ - Once you open a changes row rendered, the next file you arrow or click to opens rendered too; a file that cannot render opens on its diff, and picking diff or file by hand ends the hold. Rows whose file can render show an eye on hover, and a second click on a previewed row takes it back to the diff.
12
+ - Back and forward step onto archived pages, switching project first when the archive belongs to another.
13
+ - Code blocks in chat keep their copy button visible on a touch screen, where there is no hover to reveal it.
14
+
15
+ ### Changed
16
+ - Landing writes the commit message at press time. When the box is empty the quick model writes it under a "writing the message" step, and the land goes on without running the check again; with no answer the land is refused and nothing is committed.
17
+ - A land, commit, sync or PR press moves the row to the top of the rail as the work starts, whatever the outcome, instead of when it finishes. Automatic runs still move nothing.
18
+ - The handoff card opens its list page on arrival on the active worktree, except on a phone. Typing a letter or pressing n opens the note under "not now", a slide opens it on touch, and words sent with "not now" reach the worktree's agent once its turn ends.
19
+ - Panel chords such as cmd+L, cmd+J and cmd+B leave zen when a file fills the page and land in the panel asked for. Quick open keeps zen, and Esc on a file closes the file and leaves zen on the page.
20
+ - Toyon Mono was rebuilt three times: a slashed zero inside the ring, a wider asterisk, a thinner underscore, a new question mark hook, resized colon dots and new braces and j. Wrap and full-size are icon switches in the editor head, so a file name fits in a narrow pane.
21
+ - Links that are not routed go through one guard in the card band, PR comments and paste chips. Rendered documents drop styles, form controls and foreign classes, and every link that opens outside Toyon opens with noopener and noreferrer.
22
+ - The daemon refuses a let-me-in knock that arrives from its own preview, process or forwarder ports, another .localhost name or a preview under the public name; file routes carry a sandbox content security policy, and a short token file is regenerated.
23
+ - A read row that repeats keeps its shine through the gap between reads, as an edit row does. A kbd tag in a markdown preview draws as a boxed key, and a heading made only of a code span reads as a heading.
24
+ - The docs gained features, shortcuts, commands, using, backends and phone pages, and the remote, settings, agents, trust and policy pages were rewritten in shorter sentences.
25
+
26
+ ### Fixed
27
+ - Landing or archiving a worktree could silently discard committed or unpushed work, or leave main half-merged. The leftover check now compares commits by content, so a rebased copy after a sync does not count as new work, and the push asks origin where the branch stands first: a plain push, a leased forced push over your own earlier tip, or a refusal that says why.
28
+ - A file with an accented or quoted name, such as café.txt, made the changes panel throw. Paths are read from git without quoting now, and git messages stay in English whatever the system language.
29
+ - Once Toyon Mono loaded, every mono line reflowed, because the stand-in faces had a different letter height. The fallbacks are now faces with the same cell, so nothing moves when the font arrives.
30
+ - A restart no longer kills an agent that is still starting, and a crashed adapter keeps its own exit text.
31
+ - Slow sideways trackpad scrolls in the editor were dropped once the gesture had settled as vertical; the turn is judged on travel summed over the gesture.
32
+ - Monaco's right-click menu, sticky scroll and inlay hint menus overlapped the files dock without a background. They are drawn as the shell's own menu in the top layer.
33
+ - @ offers the project's other worktrees on an archived or found chat, where before the mention went to the agent as plain text.
34
+ - A pull request merged while the row was open was recorded once, not again when the poll heard of it, and the comments row no longer runs "1 comment" into "on PR".
35
+ - Committing on a large repository no longer rebuilds the file tree, the folder list and the mention index when no paths changed, which blocked the page for about a fifth of a second on a 150k file repository.
36
+
5
37
  ## 0.23.0 (2026-11-10)
6
38
 
7
39
  The shell reads in Toyon Mono, a face of its own, and a worktree reaches main's servers by default instead of starting every command again.
package/dist/cli.js CHANGED
@@ -5290,7 +5290,7 @@ function parseVersion(v) {
5290
5290
  // package.json
5291
5291
  var package_default = {
5292
5292
  name: "toyon",
5293
- version: "0.23.0",
5293
+ version: "0.24.0",
5294
5294
  description: "Toyon is where coding agents work on your web app while you check each change by using it. Every chat gets its own running copy with a live preview.",
5295
5295
  license: "MIT",
5296
5296
  type: "module",