@zhihaohong52/sonata 0.15.5 → 0.16.1

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 (75) hide show
  1. package/README.md +83 -329
  2. package/dist/adapters/claude.js +16 -14
  3. package/dist/adapters/claude.js.map +1 -1
  4. package/dist/cli.js +108 -20
  5. package/dist/cli.js.map +1 -1
  6. package/dist/commands/auth.js +4 -0
  7. package/dist/commands/auth.js.map +1 -1
  8. package/dist/commands/doctor.js +67 -1
  9. package/dist/commands/doctor.js.map +1 -1
  10. package/dist/commands/init.js +1 -1
  11. package/dist/commands/init.js.map +1 -1
  12. package/dist/commands/serve.js +5 -2
  13. package/dist/commands/serve.js.map +1 -1
  14. package/dist/commands/status.js +32 -0
  15. package/dist/commands/status.js.map +1 -1
  16. package/dist/commands/sync.js +33 -28
  17. package/dist/commands/sync.js.map +1 -1
  18. package/dist/commands/upgrade.js +41 -0
  19. package/dist/commands/upgrade.js.map +1 -0
  20. package/dist/commands/usage.js +6 -8
  21. package/dist/commands/usage.js.map +1 -1
  22. package/dist/config.js +91 -56
  23. package/dist/config.js.map +1 -1
  24. package/dist/detect.js +2 -0
  25. package/dist/detect.js.map +1 -1
  26. package/dist/init/apply.js +13 -7
  27. package/dist/init/apply.js.map +1 -1
  28. package/dist/init/candidates.js +6 -3
  29. package/dist/init/candidates.js.map +1 -1
  30. package/dist/init/discover.js +7 -2
  31. package/dist/init/discover.js.map +1 -1
  32. package/dist/init/guidance.js +2 -2
  33. package/dist/init/guidance.js.map +1 -1
  34. package/dist/init/helpers.js +2 -7
  35. package/dist/init/helpers.js.map +1 -1
  36. package/dist/init/plan.js +3 -1
  37. package/dist/init/plan.js.map +1 -1
  38. package/dist/init/scripted-state.js +2 -2
  39. package/dist/init/scripted-state.js.map +1 -1
  40. package/dist/init/toml.js +18 -8
  41. package/dist/init/toml.js.map +1 -1
  42. package/dist/ledger.js.map +1 -1
  43. package/dist/loop-skill.js +111 -0
  44. package/dist/loop-skill.js.map +1 -0
  45. package/dist/native/auto-route.js +59 -2
  46. package/dist/native/auto-route.js.map +1 -1
  47. package/dist/native/litellm.js +10 -4
  48. package/dist/native/litellm.js.map +1 -1
  49. package/dist/native/models.js +4 -5
  50. package/dist/native/models.js.map +1 -1
  51. package/dist/native/providers.js +3 -0
  52. package/dist/native/providers.js.map +1 -1
  53. package/dist/native/router.js +230 -71
  54. package/dist/native/router.js.map +1 -1
  55. package/dist/pricing.js +15 -7
  56. package/dist/pricing.js.map +1 -1
  57. package/dist/tui-ink/components/byok-step.js +4 -14
  58. package/dist/tui-ink/components/byok-step.js.map +1 -1
  59. package/dist/tui-ink/components/models-step.js +3 -5
  60. package/dist/tui-ink/components/models-step.js.map +1 -1
  61. package/dist/tui-ink/components/providers-step.js +19 -5
  62. package/dist/tui-ink/components/providers-step.js.map +1 -1
  63. package/dist/tui-ink/screens/status-poll.js +5 -2
  64. package/dist/tui-ink/screens/status-poll.js.map +1 -1
  65. package/dist/tui-ink/screens/status.js +13 -7
  66. package/dist/tui-ink/screens/status.js.map +1 -1
  67. package/dist/tui-ink/screens/usage-view.js +1 -1
  68. package/package.json +2 -1
  69. package/skills/loop/.claude-plugin/plugin.json +17 -0
  70. package/skills/loop/SKILL.md +30 -0
  71. package/skills/loop/hooks/hooks.json +1 -0
  72. package/skills/loop/hooks/model.ts +236 -0
  73. package/skills/loop/hooks/panel.tsx +375 -0
  74. package/skills/loop/hooks/register.tsx +236 -0
  75. package/skills/loop/types/index.d.ts +87 -0
package/README.md CHANGED
@@ -7,24 +7,19 @@
7
7
  [![license: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
8
8
  [![node](https://img.shields.io/badge/node-%3E%3D22-brightgreen.svg)](https://nodejs.org)
9
9
 
10
- Claude Code's subagents are excellent, but they are always Claude. Sonata lets
11
- you dispatch a subagent backed by a different model, through the ordinary
12
- Agent tool — same interface, same working directory, same report contract.
13
- Different brain.
14
-
15
- Two ways to run it:
16
-
17
- - **Native** — the foreign model runs *inside Claude Code's own loop*: its
18
- tools, its permission modes, no separate TUI. A local routing proxy
19
- (`sonata serve`) makes this possible; see the [Native path guide](docs/guide/native-path.md).
20
- This is the default: `sonata init` generates one agent per role and present tier
21
- (up to 12 agents), each backed by a ranked list of models the router tries in
22
- order.
23
- - **Harness** — the foreign model runs in *its own* CLI (OpenCode, Codex, Pi,
24
- Reasonix), launched in a detached tmux session and driven through
25
- `sonata dispatch`. No proxy required — this is the fallback lane: when
26
- every native route for a tier has failed, the router says so and names the
27
- `sonata dispatch --tier <role>-<tier>` command, which the agent runs itself.
10
+ Claude Code's subagents always run on Claude. Sonata gives you subagents that
11
+ run on other models — GPT, DeepSeek, GLM, Kimi, or anything else you can reach
12
+ — called through the ordinary Agent tool, in the same working directory, with
13
+ the same tools and permission modes. Your main session stays on Claude; only
14
+ the subagents change.
15
+
16
+ `sonata init` generates agents such as `code-simple`, `code-complex` and
17
+ `review-complex`, each backed by a ranked list of models. A local router
18
+ (`sonata serve`) runs them inside Claude Code's own loop and tries the next
19
+ model when one fails. If every model in the list fails, the agent falls back to
20
+ running the task in that model's own CLI (OpenCode, Codex, Pi or Reasonix).
21
+
22
+ ![The code-complex tier in sonata agents: ranked models with intelligence, cost per task and live state](docs/public/screenshots/tier-ranking.png)
28
23
 
29
24
  Two reasons you might want that:
30
25
 
@@ -35,281 +30,72 @@ Two reasons you might want that:
35
30
  fewer problems than asking a different model family. Review is where a second
36
31
  opinion actually pays.
37
32
 
38
- ```
39
- ● code-deepseek-v4-flash (running)
40
- └ sonata: tail a1f3e2
41
- → read src/parser.ts
42
- → edit src/parser.ts +31 −12
43
- → bash pytest -q → 47 passed
44
- done — "Refactored the parser. Tests pass."
45
- ```
33
+ Sonata itself is free and MIT-licensed; you pay your providers as usual, and
34
+ `sonata usage` shows what each model, tier and role cost you — including work
35
+ a subscription already covers, valued at list price:
36
+
37
+ ![sonata usage by tier over 30 days](docs/public/screenshots/usage.png)
46
38
 
47
39
  ## Status
48
40
 
49
- **Working, early.** The engine and the OpenCode, Codex, Pi and Reasonix
50
- harness adapters are complete and tested, each verified end to end against a
51
- real model. The native path (`sonata serve`/`sonata code`/`sonata restart`
52
- and the `claude` harness adapter) is also complete and verified live —
53
- routing, permission modes, and the router's Codex-overload handling have all
54
- been confirmed against real dispatches.
41
+ **Public beta.** Sonata is pre-1.0 and changing quickly. The native path and
42
+ the OpenCode, Codex, Pi and Reasonix adapters are complete, tested, and verified
43
+ end to end against real models. Expect rough edges in setups nobody has tried
44
+ yet, and please [report them](https://github.com/zhihaohong52/sonata/issues).
55
45
 
56
46
  Read [Limitations](docs/guide/limitations.md) and
57
- [Security](docs/guide/security.md) before depending on it.
58
-
59
- ## Requirements
60
-
61
- - **Node 22+**
62
- - **tmux** — every harness runs inside a tmux session (`brew install tmux`,
63
- `apt install tmux`)
64
- - **LiteLLM — managed, and only when a gateway needs it.** Sonata installs its
65
- own pinned copy into `~/.config/sonata/litellm` (`sonata litellm install`,
66
- offered by `sonata init`), so `pip install` by hand is no longer a step. A
67
- gateway that speaks the Anthropic Messages API natively is reached directly
68
- with no LiteLLM in the path at all — such a config needs no Python whatsoever.
69
- When one *is* needed, `uv` (fastest, and can fetch a conforming interpreter)
70
- or a `python3` in `>=3.10,<3.15` is required.
71
- - **macOS or Linux.** Sonata launches bash scripts inside tmux and manages
72
- process groups directly; Windows is not supported. WSL should work but is
73
- untested.
74
- - **A provider.** Either an API key for one of ~30 well-known providers (see
75
- [BYOK](#byok-bring-your-own-key) — no harness needed), or at least one of the
76
- harnesses below, authenticated:
77
- - **[OpenCode](https://opencode.ai)** — any provider it supports
78
- - **[Codex CLI](https://github.com/openai/codex)** — `codex login`
79
- - **[Pi](https://github.com/earendil-works/pi-mono)** — any provider it
80
- supports; model ids take the `provider/id` form
81
- - **[Reasonix](https://github.com/esengine/DeepSeek-Reasonix)** — `reasonix setup`;
82
- any OpenAI-compatible endpoint is a config entry, and model ids take the
83
- `provider/id` form
84
- - **Claude Code** — the `claude` harness adapter (native path; see the
85
- [Native path guide](docs/guide/native-path.md))
86
-
87
- ## Install
88
-
89
- ```bash
90
- npm install -g @zhihaohong52/sonata
91
- ```
47
+ [Security](docs/guide/security.md) before depending on it. The models sonata
48
+ launches run on your machine, as you, and your code is sent to whichever
49
+ providers you configure.
92
50
 
93
- ### From source
51
+ ## Quickstart
94
52
 
95
- For working on sonata itself, or to run a change that has not been released:
96
-
97
- ```bash
98
- git clone https://github.com/zhihaohong52/sonata.git
99
- cd sonata
100
- npm install
101
- npm run build
102
- npm link # puts `sonata` on your PATH
103
- ```
104
-
105
- `sonata` on your PATH runs `dist/`, not `src/` — after changing anything under
106
- `src/`, run `npm run build` or the command keeps its old behaviour.
107
-
108
- Then, in the repository where you want to use it:
53
+ Requires **Claude Code**, **Node 22+**, **tmux**, and **macOS or Linux**, plus a provider: an
54
+ API key for one of ~30 well-known providers, your Claude Code account, or an
55
+ authenticated harness ([OpenCode](https://opencode.ai),
56
+ [Codex CLI](https://github.com/openai/codex),
57
+ [Pi](https://github.com/earendil-works/pi-mono) or
58
+ [Reasonix](https://github.com/esengine/DeepSeek-Reasonix)). Full requirements
59
+ are in [Getting started](docs/guide/getting-started.md#requirements).
109
60
 
110
61
  ```bash
62
+ npm install -g @zhihaohong52/sonata
63
+ cd your-project
111
64
  sonata init
112
65
  ```
113
66
 
114
- `sonata init` detects your environment, reports anything broken with the command
115
- that fixes it, and asks which providers, models and roles you want.
116
-
117
- Provider setup is a menu, modeled on opencode's own `/connect`: bulk-import
118
- everything you're already logged into elsewhere, or add providers one at a
119
- time — including one sonata has never heard of.
120
-
121
- ```
122
- ███████╗ ██████╗ ███╗ ██╗ █████╗ ████████╗ █████╗
123
- ██╔════╝██╔═══██╗████╗ ██║██╔══██╗╚══██╔══╝██╔══██╗
124
- ███████╗██║ ██║██╔██╗ ██║███████║ ██║ ███████║
125
- ╚════██║██║ ██║██║╚██╗██║██╔══██║ ██║ ██╔══██║
126
- ███████║╚██████╔╝██║ ╚████║██║ ██║ ██║ ██║ ██║
127
- ╚══════╝ ╚═════╝ ╚═╝ ╚═══╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝
128
-
129
- foreign-model subagents for Claude Code
130
-
131
- ✓ tmux 3.7b
132
- ✓ opencode 1.18.19 · 520 models
133
- ✓ codex codex-cli 0.149.0 · 6 models
134
-
135
- Set up providers
136
- ❯ Import from other harnesses
137
- Add provider
138
-
139
- ↑↓ choose · enter confirm · ← back · esc cancel
140
- ```
141
-
142
- **Import from other harnesses** bulk-selects providers your installed
143
- harnesses are already authenticated for — nothing to type, nothing to
144
- re-enter. It lists every provider with a detected credential (an OAuth grant
145
- or a plain API key sitting in another harness's own store), whether or not
146
- it is already configured, and pre-checks the ones that are — so the same
147
- screen doubles as a toggle: unchecking an already-imported provider removes
148
- it, along with its models and any role assignments that used them:
149
-
150
- ```
151
- Import from other harnesses
152
-
153
- filter: █
154
-
155
- ❯ ◉ codex · expires in 8d
156
- ○ openai · expires in 8d
157
-
158
- 2 of 2 · space toggle · type to filter · enter confirm · esc cancel
159
- ```
160
-
161
- **Add provider** searches the merged catalogue of every provider a harness
162
- knows about plus ~30 well-known BYOK providers — or lets you type in one
163
- sonata has never seen:
164
-
165
- ```
166
- Add provider
167
-
168
- filter: █
169
-
170
- ❯ acme · opencode
171
- anthropic · opencode
172
- codex · codex
173
- deepseek · byok
174
- ⋮
175
- Add a custom provider…
176
-
177
- 38 of 38 · ↑↓ choose · type to filter · enter confirm · ← back · esc cancel
178
- ```
179
-
180
- Picking a known provider offers **Run OAuth login** (for `codex` and
181
- `github-copilot`, the two providers sonata can authenticate on its own — see
182
- the [Native path guide](docs/guide/native-path.md)) or **Enter an API key**.
183
- Picking a harness-catalogued provider then shows its models to select from:
184
-
185
- ```
186
- Models to enable
187
-
188
- filter: gpt█
189
-
190
- ❯ ◉ openai/gpt-5.6-sol · GPT-5.6 Sol
191
- ○ openai/gpt-5.6-luna · GPT-5.6 Luna
192
-
193
- 2 of 13 · space toggle · type to filter · enter confirm · esc cancel
194
- ```
195
-
196
- Then it asks you to rank your selected models into `simple`, `normal` and
197
- `complex` tiers per role — pre-sorted by a cached Artificial Analysis catalog
198
- (`sonata catalog
199
- update`, with a free key from [artificialanalysis.ai](https://artificialanalysis.ai))
200
- when one exists, or built-in defaults otherwise. `complex` is ordered by raw
201
- capability. `normal` is ordered by capability **per task-dollar** without a cost
202
- cap, while `simple` uses that same value order under a cost cap of 12 times the
203
- best-value model's cost per task. Thus `simple` is a cost-capped prefix of
204
- `normal`: demanding work goes to the strongest model you picked, ordinary work
205
- gets the best value, and grunt work stays within the cheaper fallback chain. Set
206
- `avoid_gateways` in
207
- `sonata.toml` to rank a particular gateway's models last without dropping them
208
- as fallbacks. It then asks whether the config
209
- applies to this project or the whole machine, writes `sonata.toml`, generates
210
- one agent per role × tier, offers to install the permission hook, installs the
211
- `sonata-loop` skill, and offers to run `sonata route auto` so the generated
212
- agents have a router to reach. Project scope writes `./sonata.toml` and
213
- `./.claude/agents/`; machine scope writes `~/.config/sonata/sonata.toml` and
214
- `~/.claude/agents/`, where Claude Code offers the agents in every repository.
215
-
216
- Claude Code picks up the new agents automatically; no restart is needed.
217
-
218
- Every prompt has a flag, so it also works unattended:
219
-
220
- ```bash
221
- sonata init --yes --providers opencode/openai --models opencode-openai-gpt-5.6-sol --roles code,review --scope project
222
- ```
223
-
224
- ### BYOK (bring your own key)
67
+ `sonata init` checks your environment, reports anything broken with the
68
+ command that fixes it, then walks you through providers, models, roles and a
69
+ ranking of models into tiers. It writes `sonata.toml` and generates the tier
70
+ agents. Every prompt has a flag, so it also runs unattended.
225
71
 
226
- Sonata does not need a harness. **Add provider** lists ~30 well-known
227
- providers alongside anything your harnesses discovered; pick one, enter its
228
- API key, and choose from the models it reports. A provider not on that
229
- list — an internal proxy, a self-hosted endpoint — doesn't need to be:
230
- **Add a custom provider…**, at the bottom of that same search list, asks for
231
- a name, a base URL, and whether it speaks OpenAI's or Anthropic's wire
232
- format, then drops into the same key-entry flow.
72
+ Accept its offer to route your sessions (`sonata route auto`), then **start a
73
+ new Claude Code session**: routing is set up when a session starts. Without it,
74
+ tier agents fail with `model_not_found`; `sonata doctor` says what is missing.
233
75
 
234
- The key is stored in sonata's own key store — never in `sonata.toml`, never in
235
- an agent file, and never on the command line. It is written only after you
236
- confirm the summary, so cancelling the wizard stores nothing.
237
-
238
- Unattended, with the key stored first so it stays out of argv and shell history:
239
-
240
- ```bash
241
- sonata auth add deepseek
242
- sonata init --yes --providers byok/deepseek --models deepseek-deepseek-v4-flash --roles code
243
- ```
244
-
245
- BYOK models use the [native path](docs/guide/native-path.md), so they run
246
- inside Claude Code's own loop, tools and permission modes.
247
-
248
- Two things worth knowing before you pick a provider:
249
-
250
- - **Model discovery is a convention, not a guarantee.** Sonata asks the provider
251
- for `GET <base_url>/models`, which every provider in its list implements. If
252
- yours does not answer — offline, or a different shape — the wizard asks you to
253
- type the model ids instead, saying which of those happened. That is a
254
- fallback, not an error.
255
- - **A rejected key gets its own screen.** If the provider answers 401 or 403,
256
- sonata says so and offers to take a different key. It also offers to keep the
257
- one you gave and type ids by hand, because some providers refuse to list
258
- models for a key that works perfectly well for inference.
259
- - **`claude-*` models are not offered.** The router forwards that prefix to
260
- Anthropic, so a `claude-` id cannot be served through a gateway. Aggregators
261
- such as OpenRouter list plenty of them; sonata filters them out rather than
262
- writing a config it would then refuse to load.
263
-
264
- ### Adding Codex models
265
-
266
- **The wizard discovers OpenCode, Pi and Reasonix models** by provider then by
267
- model, and **Codex through `codex app-server`'s `model/list`** (JSON-RPC over
268
- stdio — codex has no provider dimension and takes a bare model id). Hand-written
269
- codex entries survive `sonata init`, so a bare-id model can also be added by
270
- hand:
271
-
272
- ```toml
273
- [models."gpt-5-6-sol"]
274
- harness = "codex"
275
- id = "gpt-5.6-sol"
276
- ```
277
-
278
- Hand-written entries survive `sonata init` — the wizard carries through any
279
- model whose harness it does not manage.
280
-
281
- Then run `sonata sync` to regenerate the agent files; Claude Code picks them up automatically.
282
-
283
- ## Using it
284
-
285
- The generated agents are ordinary registry entries, so Claude selects them the
286
- same way it selects any other subagent. Ask for one by name, or describe work
287
- that suits it:
76
+ Then ask Claude Code for one by name, or describe work that suits it:
288
77
 
289
78
  > "Use code-simple to convert these callbacks to async/await."
290
79
 
291
- > "Use code-normal to add this flag and its tests."
292
-
293
80
  > "Get review-complex to look at the auth refactor."
294
81
 
295
82
  Choose a tier by the task, not its size: `simple` is specified closely enough
296
- that the diff can be written without asking a question; `normal` is the default
297
- when you know what to change but need to fit it into the surrounding code;
298
- `complex` needs a design decision or the meaning of done is ambiguous. Size is
299
- not difficulty: a large mechanical change is `simple`, while a three-line
300
- interface decision is `complex`. When unsure, use `-normal`; a task that fails
301
- review twice is re-run one tier up. The `sonata-loop` skill `sonata init` installs
302
- (`skills/loop/SKILL.md`) drives this across a whole feature: plan, route each task
303
- to a tier, gate behind review, and escalate `simple` to `normal` to `complex`
304
- after repeated failures.
305
-
306
- They compose with everything Claude Code already does — parallel fan-out,
307
- workflows, and `isolation: "worktree"`.
83
+ that the diff could be written without asking a question; `normal` is the
84
+ default when you know what to change but need to fit it into the surrounding
85
+ code; `complex` needs a design decision, or "done" is still ambiguous. The
86
+ `sonata-loop` skill that `sonata init` installs drives this across a whole
87
+ feature — plan, route each task to a tier, gate behind review, escalate on
88
+ repeated failure.
89
+
90
+ The [Getting started guide](docs/guide/getting-started.md) walks through the
91
+ wizard screen by screen, including BYOK keys and hand-added models.
308
92
 
309
93
  ## How it works
310
94
 
311
- `sonata init` generates one agent per role × present tier — up to 12 agents
312
- across `simple`, `normal` and `complex` — such as `code-simple`, `code-normal`,
95
+ `sonata init` generates one agent per role (`code`, `review`, `explore`,
96
+ `plan`) and tier (`simple`, `normal`, `complex`) — up to 12 — plus, with
97
+ `[auto_route]` configured, a `<role>-auto` agent per role that picks the tier
98
+ itself. Tier agents are named `code-simple`, `code-normal`,
313
99
  `code-complex`, `review-simple`, and so on. Each agent's frontmatter names a
314
100
  router alias (`model: sonata-code-simple`), not a specific model:
315
101
 
@@ -371,44 +157,34 @@ killed and the run is reported `DONE`, `degraded`, with a report beginning
371
157
 
372
158
  ## Commands
373
159
 
160
+ The ones you will use most:
161
+
374
162
  | Command | Purpose |
375
163
  |---|---|
376
- | `sonata --version` (`-v`) | The running version and the directory it ran from. The path matters: `sonata` on PATH runs `dist/`, not `src/`, so this is how you tell which install answered |
377
- | `sonata init` | Set up sonata in this project (interactive); `--prune` removes stale generated agents |
378
- | `sonata reset [--global] [--yes]` | Remove sonata's configuration and generated files at one scope — the config, the generated agents, the loop skill, the CLAUDE.md block, and the routing env/hooks/allow-list. Keeps your gateway keys, the usage ledger and the caches, and shows the full plan before touching anything |
379
- | `sonata doctor [--json]` | Check tmux, harnesses, auth and versions; `--json` prints the same checks as structured output |
380
- | `sonata sync` | Regenerate agent files from `sonata.toml`; `--prune` removes stale generated agents |
381
- | `sonata agents [--list] [--json]` | Every generated tier agent, what each of its ranked candidates resolves to, its context window, and whether the alias carries `[1m]`. In a terminal it is also the editor: re-rank a tier without walking the whole wizard |
382
- | `sonata run` | Launch a run, print its id |
383
- | `sonata dispatch (--tier <role>-<tier> \| --model <key>)` | Blocking harness dispatch with ranked fallback — the fallback lane a tier agent reaches for when every native route fails |
384
- | `sonata tail` | Human/debugging view of a run |
385
- | `sonata approve` | Answer a pending approval |
386
- | `sonata log <id>` | Print what a run printed |
387
- | `sonata verify <id> [--model <key>]` | Verify a completed run |
388
- | `sonata auth` | Manage native-path gateway keys (`list`, `add <gateway>`, `remove <gateway>`, `login <gateway>`) |
389
- | `sonata catalog [update]` | Show the cached Artificial Analysis catalog's age, or refresh it (needs a stored `artificialanalysis` key). `sonata init` refreshes it itself when a discovered model is missing from it; `sonata doctor` warns when it goes stale |
390
- | `sonata litellm install\|status` | Install or report sonata's own pinned LiteLLM venv. `status` answering `not-required` is healthy — it means no gateway in this config routes through it |
391
- | `sonata serve` | Run the native router and its managed LiteLLM child (`--daemon` detaches); UI: `http://localhost:4100/` |
392
- | `sonata restart` | Kill whatever sonata router currently holds the port and start a fresh daemon |
393
- | `sonata code` | Launch a Claude Code session routed through the local proxy (passes `claude` args through) |
394
- | `sonata route on\|off\|status [--global]` | Route every plain `claude` session in the project (or, with `--global`, every project) through the proxy via settings.local.json/settings.json |
395
- | `sonata route auto\|manual [--global]` | Route each session for its lifetime via SessionStart/SessionEnd hooks, keeping Remote Control |
396
- | `sonata usage [--since 7d] [--by model\|role\|tier\|effort\|gateway\|lane\|session\|project] [--session <id>] [--json]` | Tokens and cost from the ledger: native requests as the router saw them, and `sonata dispatch` runs read from each harness's own store once they finish (`--by lane` splits the two); unpriced volume is reported separately, never folded into the total |
397
- | `sonata status [--session <id>\|--all]` | Whether the router is up and on which port, then the recent alias → candidate served → tokens → failed attempts decisions from the ledger; reachability and routing state live in `sonata route status` |
398
- | `sonata runs [--json]` | List this project's dispatch runs |
399
- | `sonata gc` | Kill finished tmux sessions |
164
+ | `sonata init` | Set up sonata in this project |
165
+ | `sonata doctor` | Check everything sonata depends on, and say how to fix what's broken |
166
+ | `sonata agents` | See and re-rank the tier agents' models |
167
+ | `sonata route auto` | Route every plain `claude` session in this project through the router, keeping Remote Control — set once, then launch `claude` as usual |
168
+ | `sonata code` | Launch one routed session without changing any settings |
169
+ | `sonata usage` / `sonata status` | Tokens and cost, and what the router served |
170
+ | `sonata dispatch` | Run a task through a model's own harness — the fallback lane |
171
+ | `sonata upgrade` | Install the latest release |
172
+
173
+ Every command and flag: [Commands](docs/guide/commands.md).
400
174
 
401
175
  ## Documentation
402
176
 
403
- The essentials are above. Deep-dive reference lives in
404
- [`docs/guide/`](docs/guide/):
177
+ **[zhihaohong52.github.io/sonata](https://zhihaohong52.github.io/sonata/)** — the user guide, also
178
+ readable here in [`docs/guide/`](docs/guide/):
405
179
 
406
180
  | Guide | Covers |
407
181
  |---|---|
408
- | [Native path](docs/guide/native-path.md) | Running foreign models inside Claude Code's own loop through the local routing proxy |
409
- | [Codex subscription auth](docs/guide/codex-subscription.md) | Authenticating the `codex-oauth` gateway against a ChatGPT subscription |
182
+ | [Getting started](docs/guide/getting-started.md) | Install, `sonata init` screen by screen, BYOK, first dispatch |
183
+ | [Commands](docs/guide/commands.md) | Every command and flag |
184
+ | [Configuration](docs/guide/configuration.md) | The `sonata.toml` schema, resolution order, roles and tiers |
185
+ | [Native path](docs/guide/native-path.md) | Running foreign models inside Claude Code's own loop through the local router |
186
+ | [Codex subscription auth](docs/guide/codex-subscription.md) | Authenticating against a ChatGPT subscription instead of a metered key |
410
187
  | [Permission modes](docs/guide/permission-modes.md) | How each harness honours Claude Code's permission modes |
411
- | [Configuration](docs/guide/configuration.md) | The `sonata.toml` schema, resolution order, and roles/tiers |
412
188
  | [Troubleshooting](docs/guide/troubleshooting.md) | Symptom → cause table |
413
189
  | [Security](docs/guide/security.md) | What sonata does and doesn't protect against |
414
190
  | [Limitations](docs/guide/limitations.md) | Known gaps worth knowing before depending on this |
@@ -416,39 +192,17 @@ The essentials are above. Deep-dive reference lives in
416
192
 
417
193
  Where this is headed: [Roadmap to 1.0](docs/roadmap.md).
418
194
 
419
- Design history — every feature's spec and implementation plan, kept as a
420
- permanent record — is indexed in [`docs/superpowers/`](docs/superpowers/).
421
- Architecture reviews are in [`docs/reviews/`](docs/reviews/). What using
422
- sonata to implement sonata taught about sizing and verifying dispatched work
423
- is in [`docs/dispatching-work-through-sonata.md`](docs/dispatching-work-through-sonata.md).
424
-
425
- ## Development
426
-
427
- ```bash
428
- npm install
429
- npm test # 1523 tests; needs tmux
430
- npm run typecheck
431
- npm run build
432
- ```
433
-
434
- The test suite runs against a **fake harness** — a scripted binary replaying a
435
- normal run, a crash, a real captured approval prompt, a hang that the watchdog
436
- must kill, a clean exit with no report, and a harness-written report — so the
437
- whole engine is covered with no API spend and no harness installed.
438
-
439
- See [Adding a harness](docs/guide/adding-a-harness.md) for the extension
440
- point, and [Documentation](#documentation) above for the design-history index.
195
+ For maintainers and the curious: the design record behind the code is in
196
+ [`docs/internals/`](docs/internals/), every feature's spec and plan in
197
+ [`docs/superpowers/`](docs/superpowers/), and point-in-time audits in
198
+ [`docs/reviews/`](docs/reviews/). `DESIGN.md` and `PRODUCT.md` at the root are
199
+ the design brief for the terminal UI.
441
200
 
442
201
  ## Contributing
443
202
 
444
- Issues and pull requests are welcome.
445
-
446
- - Run `npm test` and `npm run typecheck` before opening a PR; CI runs both on
447
- Linux with tmux installed.
448
- - Add tests for behaviour you change. The suite needs no API keys.
449
- - Prefer evidence to inference: if a change depends on how a harness behaves,
450
- say how you verified it. A captured fixture beats a plausible regex.
451
- - Keep harness-specific knowledge inside its adapter.
203
+ Issues and pull requests are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md)
204
+ for the development setup and what a good PR looks like. Report security
205
+ issues privately, as described in [SECURITY.md](SECURITY.md).
452
206
 
453
207
  ## Changelog
454
208
 
@@ -1,7 +1,7 @@
1
1
  import { existsSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
3
  import { asRecord, count, epochMs, filesIn, readJsonl } from './usage-files.js';
4
- import { isAnthropicRoutedName, isReadOnlyRole, loadConfig } from '../config.js';
4
+ import { isReadOnlyRole, loadConfig, nativeRouteFor } from '../config.js';
5
5
  import { joinCandidate } from '../effort.js';
6
6
  import { homedir } from 'node:os';
7
7
  import { routerPorts } from '../commands/ports.js';
@@ -26,20 +26,22 @@ export function planClaude(input, env = { managedMcpFile: MANAGED_MCP_FILES[proc
26
26
  // `reasoning_effort` (PR 2) — so the wire path exists and a second mechanism
27
27
  // here would be one more place for the two to disagree.
28
28
  //
29
- // Except for an Anthropic-routed name, where that split does NOT happen:
30
- // `routeRequest` skips it for a `claude-` model, because such a request is
31
- // forwarded byte-identical to Anthropic by contract. Appending a level there
32
- // would not reach the splitter, it would reach Anthropic as part of the
33
- // model name, which rejects it — turning a working Claude dispatch into a
34
- // 404 for asking a question sonata cannot answer anyway. Effort for Claude
35
- // models is out of scope by design: Claude Code's own setting governs them.
36
- // So the name stays bare and the plan says the level went unhonoured, which
37
- // is what makes `sonata tail` annotate the report instead of lying about it.
38
- const anthropicRouted = isAnthropicRoutedName(input.modelId);
39
- const effortHonoured = !anthropicRouted;
29
+ // Configured keys on direct routes cannot carry an effort suffix because
30
+ // Anthropic has no reasoning_effort field; other configured routes can.
31
+ let config;
32
+ try {
33
+ config = loadConfig(input.cwd, homedir());
34
+ }
35
+ catch {
36
+ // Keep the adapter usable without a config; the model then routes as a
37
+ // direct Anthropic name when it has the reserved prefix.
38
+ }
39
+ const route = config === undefined ? undefined : nativeRouteFor(config, input.modelId);
40
+ const effortHonoured = route?.transport !== 'direct'
41
+ && !(input.modelId.startsWith('claude-') && config?.unifiedModels[input.modelId] === undefined);
40
42
  const flags = [
41
43
  '-p',
42
- `--model ${shellQuote(anthropicRouted ? input.modelId : joinCandidate(input.modelId, input.effort))}`,
44
+ `--model ${shellQuote(effortHonoured ? joinCandidate(input.modelId, input.effort) : input.modelId)}`,
43
45
  `--permission-mode ${permissionMode}`,
44
46
  ];
45
47
  // `--allowedTools <value>` (space form) is variadic in claude's own CLI
@@ -86,7 +88,7 @@ export function planClaude(input, env = { managedMcpFile: MANAGED_MCP_FILES[proc
86
88
  let routerUrl = '';
87
89
  let contextWindow = '';
88
90
  try {
89
- const config = loadConfig(input.cwd, homedir());
91
+ config ??= loadConfig(input.cwd, homedir());
90
92
  if (config.native) {
91
93
  routerUrl = `http://localhost:${routerPorts(homedir()).router}`;
92
94
  const windows = Object.values(config.native.models).map(m => m.contextWindow);
@@ -1 +1 @@
1
- {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/adapters/claude.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/adapters/claude.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,MAAM,eAAe,GAAa,EAAE,CAAC;AAErC,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC;AAC7C,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAA6C;IACzE,MAAM,EAAE,0DAA0D;IAClE,KAAK,EAAE,mCAAmC;CAC3C,CAAC;AAOF,MAAM,UAAU,UAAU,CACxB,KAAgB,EAChB,MAAqB,EAAE,cAAc,EAAE,iBAAiB,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;IAE5E,MAAM,QAAQ,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,cAAc,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;IACtD,4EAA4E;IAC5E,uEAAuE;IACvE,4DAA4D;IAC5D,6EAA6E;IAC7E,wDAAwD;IACxD,EAAE;IACF,yEAAyE;IACzE,wEAAwE;IACxE,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,uEAAuE;QACvE,yDAAyD;IAC3D,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IACvF,MAAM,cAAc,GAAG,KAAK,EAAE,SAAS,KAAK,QAAQ;WAC/C,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,SAAS,CAAC,CAAC;IAClG,MAAM,KAAK,GAAG;QACZ,IAAI;QACJ,WAAW,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE;QACpG,qBAAqB,cAAc,EAAE;KACtC,CAAC;IACF,wEAAwE;IACxE,wEAAwE;IACxE,oEAAoE;IACpE,+DAA+D;IAC/D,0EAA0E;IAC1E,0EAA0E;IAC1E,EAAE;IACF,sEAAsE;IACtE,4EAA4E;IAC5E,2EAA2E;IAC3E,yEAAyE;IACzE,0EAA0E;IAC1E,6EAA6E;IAC7E,EAAE;IACF,4EAA4E;IAC5E,4EAA4E;IAC5E,4EAA4E;IAC5E,4EAA4E;IAC5E,kEAAkE;IAClE,0EAA0E;IAC1E,2EAA2E;IAC3E,0EAA0E;IAC1E,qEAAqE;IACrE,EAAE;IACF,yEAAyE;IACzE,6EAA6E;IAC7E,6EAA6E;IAC7E,2EAA2E;IAC3E,wEAAwE;IACxE,6EAA6E;IAC7E,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,CAAC,cAAc,KAAK,SAAS,IAAI,UAAU,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QACnF,KAAK,CAAC,IAAI,CACR,wBAAwB,EACxB,+BAA+B,EAC/B,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAAC,qBAAqB,CACzE,CAAC;IACJ,CAAC;IACD,0EAA0E;IAC1E,sEAAsE;IACtE,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAE7F,wEAAwE;IACxE,sEAAsE;IACtE,+BAA+B;IAC/B,IAAI,SAAS,GAAG,EAAE,CAAC;IACnB,IAAI,aAAa,GAAG,EAAE,CAAC;IACvB,IAAI,CAAC;QACH,MAAM,KAAK,UAAU,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;QAC5C,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClB,SAAS,GAAG,oBAAoB,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;YAChE,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;YAC9E,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;gBAAE,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,oEAAoE;QACpE,mEAAmE;QACnE,kEAAkE;QAClE,qCAAqC;IACvC,CAAC;IAED,MAAM,QAAQ,GAAG,SAAS;QACxB,CAAC,CAAC;YACA,6BAA6B,UAAU,CAAC,SAAS,CAAC,EAAE;YACpD,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,yCAAyC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;SACjG;QACD,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,MAAM,GAAG;QACb,aAAa;QACb,iBAAiB;QACjB,GAAG,QAAQ;QACX,MAAM,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa;QACxC,sEAAsE;QACtE,0EAA0E;QAC1E,0EAA0E;QAC1E,2EAA2E;QAC3E,uEAAuE;QACvE,oEAAoE;QACpE,UAAU,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,UAAU,CAAC,KAAK,CAAC,gBAAgB,CAAC,QAAQ,UAAU,CAAC,GAAG,KAAK,CAAC,MAAM,mBAAmB,CAAC,OAAO;QACnI,aAAa,UAAU,CAAC,GAAG,KAAK,CAAC,MAAM,OAAO,CAAC,EAAE;QACjD,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,2EAA2E;IAC3E,yEAAyE;IACzE,qDAAqD;IACrD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,KAAK,EAAE,EAAE,CAAC;AACpI,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,WAAW,CAAC,KAAiB;IAC3C,4EAA4E;IAC5E,yEAAyE;IACzE,IAAI,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC;IACnC,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC/B,IAAI,CAAC;YACH,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC;QAClE,CAAC;QAAC,MAAM,CAAC;YACP,gEAAgE;QAClE,CAAC;IACH,CAAC;IACD,IAAI,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC;IAChE,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAClC,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,6DAA6D,EAAE,CAAC;IACzG,CAAC;IACD,MAAM,IAAI,GAAG,GAAG,KAAK,CAAC,SAAS,QAAQ,CAAC;IACxC,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC;SACxE,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC;IAC3D,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,+CAA+C,EAAE,CAAC;IACjH,MAAM,SAAS,GAAG,IAAI,GAAG,EAAuB,CAAC;IACjD,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC7B,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACzC,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACvC,IAAI,KAAK,EAAE,IAAI,KAAK,WAAW,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QACjE,MAAM,EAAE,GAAG,OAAO,OAAO,EAAE,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;QAC9E,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE;YAChB,EAAE,EAAE,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE;YACnE,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;YACrE,MAAM,EAAE;gBACN,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC;gBAChC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC;gBAClC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,uBAAuB,CAAC;gBAC/C,aAAa,EAAE,KAAK,CAAC,KAAK,CAAC,2BAA2B,CAAC;aACxD;SACF,CAAC,CAAC;IACL,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;AAC1F,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAmB;IAC3C,IAAI,EAAE,QAAQ;IACd,cAAc,EAAE,CAAC,QAAQ,EAAE,WAAW,CAAC;IACvC,iBAAiB,EAAE,gBAAgB;IACnC,WAAW,EAAE,EAAE;IACf,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC;IAClC,oBAAoB,EAAE,KAAK;IAC3B,cAAc,EAAE,eAAe;IAC/B,cAAc;QACZ,OAAO,IAAI,CAAC;IACd,CAAC;IACD,WAAW,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;IAChC,kBAAkB,EAAE,kBAAkB;IACtC,KAAK,EAAE,WAAW;CACnB,CAAC"}