0.10.0: code quality, Trust/updater on OpenCode 2, removals announced in 0.9 - #40
Merged
Merged
Conversation
…roof a refactor changed nothing 51 previews across Review, Shell, Status, Subagents, Trail, Trust and the client, run under a pseudo-terminal so they draw in colour (a tone that moved is a difference), Status on an empty config of its own. `bun scripts/golden.ts` before, `--check` after. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eview found untested Review: every binding runs a command and every command has a key; no key means two things; a key goes through the guard and leaves the keys screen first, except ?, close and the numbers; and the keys screen shows every bound key — or names it as unlisted, with where it is said instead. Trail: each tone is its theme colour, ink falls back panel → background → text, and a chip is its tone faded into the dialog by its TINTS amount, made once, never on a theme with nothing to tint. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… on OpenCode 1 too SERVER_BAYS left Status out, so a Status in tui.json but not opencode.json — no /status-setup, no skill — drew no warning. And the test now checks the other way round: every bay that publishes ./server is one doctor checks, which would have caught this. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…he bundle, or one bay alone SMOKE_INSTALL=bays (the default, as before) | bundle | <bay>. The harness, the install and the command helpers are modules of their own; each probe owns its steps and what they assert, and the entry only orders the stages and runs a probe when its bay is installed. A bay alone must not bring the others' palette entries, and /cockpit-setup is offered only where an agent side ships it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…gent keeps under .claude/ Biome read the worktree's own biome.json as a second root and refused to run; bun test ran its 135 test files beside ours, and the two copies collided on the real daemons and terminals they start (a 79-second run went past 20 minutes). Biome now follows .gitignore, and tests are found under packages/, where every one of them lives. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… imported are gone review/frame — broken since it was added (it named dist/core/frame.js; the file was always dist/core/view/frame.js, 0.6 through 0.9); trail/core, trust/core and updater/core with the index files that only served them; status/fixtures; client/elements. client/brief stays: Status's interface imports it. status/segment stays for custom segments, shell/connect for pack-check. Proven: every published entry point's runtime and .d.ts exports, against main, differ by these six alone; pack-check loads the bundle and each bay alone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
journal.ts appends to and reads the trail's file; it goes to src/io/, which may import core/ but is never imported by it. paths.ts stays in core/: it only works out where the file goes. CONTRIBUTING gains the line for io/ and says what core/ may not do: touch the filesystem, git, the network or another process — the clock or an environment variable as a parameter's default is fine. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…es.ts splits by what it does git/sources.ts (473 lines) asked git, read files, and decided what the answers meant. The deciding — decide, pickBase, withCounts, nameStatus, statusChange, the caps — is core/git/changes.ts, pure; the asking — runGit, readBlob, readWorking, worktreeChanges, branchChanges, baseCandidates — is io/git.ts. Every line of the old file is in one of the two. The store's persistence and the system viewer move to io/ whole; the store's paths stay in core/, where they only work out a location. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s the Disk it is handed Core already took its filesystem as an argument; disk.ts also held the real one. nodeDisk goes to io/disk.ts, and core/disk.ts keeps the Disk interface, the in-memory disk the tests use, and readJson. spawn.ts, which runs opencode, moves to io/ whole. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… to io/ — core/ only decides core/budget, core/command and core/custom read files, run commands and import modules; they now live in io/, and core/ keeps the types and the decisions (which path a module resolves to, what a missing one says). previewSettings no longer reads the disk itself: `as` takes a readFile from its caller. pack-check loads custom modules from their new place. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…etup/ src/ was 25 flat files. The daemon's client, connection and spawn go to daemon/; what OpenCode hands a plugin (host, server, surfaces, elements, sidebar, service) to opencode/; the settings and what reads them to settings/; brief and conventions join setup/. Pure moves: the exports map points every public subpath at its new file, so `client/host`, `client/settings`, `client/setup`, … are unchanged — the public API snapshot is identical. service.ts finds its package one folder further up. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nknown names like a typo 0.9 kept detecting the old names for one release, each a `!` row naming the new key; 0.10 drops settings/old-names.ts and its two calls. Their values were never read and still are not. What changes is what is said: a top-level one (`statusline`, `ui`, Status's keys at the root) is "not a setting", with the nearest name offered, in Status's column and in doctor; one inside a bay's section (`review.sidebarOrder`, `subagents.hideFinishedAfter`) is named by /cockpit-setup only, like any key the bay does not read. `OLD_NAMES` and `SETUP_COMMAND` leave client/settings; the settings reference loses its old-names table (the site's configuration page keeps it for anyone moving an old file). Three previews showed an old-name notice; they show a wrong-kind one now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
0.9 renamed the command and kept the old name for one release, as a command of its own whose line said the new name. It goes in 0.10, as announced. The skill no longer lists it as a trigger; the smoke runs /status-setup with AGENT=1 instead, and looks for the old section's new notice. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dist/ was cleared already; types/ is tsc -b's, and an incremental build never deletes what a moved or removed source left behind — a stale file kept review/frame looking fine for three releases. The build now removes types/ and the build info, then runs tsc -b, so packing and releasing (which run the build and nothing else before npm pack) ship declarations that match the code. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the shape in host/index host.ts was 800 lines: the Host shape, the key helpers, the v1 wrapper, the v2 builder and the entry both load. Each is its own file now; index keeps the shape, dualTui and onPaste and re-exports the rest, so `client/host` exports exactly what it did (public API snapshot unchanged). No line of logic changed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…aces, and the entry in index server.ts was 841 lines: what a feature answers with, the v1 hooks, the v2 context and its tools and commands, reading a skill's folder, and the entry both OpenCodes load. Each is its own file; surfaces moves in beside them. index re-exports exactly what `client/server` exported before (public API snapshot unchanged). No line of logic changed; v1's contentText is exported inside the folder only, for v2's tool text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…it, and the lines it draws 616 lines held four concerns. core/config/ now has shape.ts (the section's types and the kind of each key), load.ts (loadStatus and the notices `cockpit_settings` lists), problems.ts (what only Status can tell is wrong), lines.ts (presets, overrides, lines resolved). index.ts is `status/config`, which the bundle's bin imports: it exports exactly what it did (public API snapshot unchanged). No cycles: shape ← lines ← problems ← load. No line of logic changed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the project uses conventions.ts (403) did three things under three headings: find and write the marked section, locate the instruction files, and scan the project (long-running commands, ticket keys, the repo). Each heading is a file in setup/conventions/; importers name the one they use. No line changed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s had it pasted Shell, Subagents, Trail and Trust each measured their block the same five lines: the container's width over the block's own, a quarter of the window before the first layout. `blockWidth` and `measureBlock` in client/sidebar now; Shell keeps its narrower guess (30) as an argument, Subagents keeps its debug line. client/sidebar gains the two exports. The row painters stay per bay: they draw different tones, and faint differently (italic in three, the terminal's dim in Updater) — merging them would change what the sidebar looks like. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y>.ts catalog.ts carried every bay's keys inline (Status's alone ran 107 lines). They still live in client — it cannot import the bays, and packages/opencode's test still holds each list to its bay's defaults — but one file per bay, so a bay's keys are found and changed next to nothing else. OWN_KEYS is the same object; the generated reference is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s.ts dialog.ts laid out the whole of `/trail` and every row in it. How wide each column is at a width, and a thing's or a touch's row in those columns, move to columns.ts; dialog.ts keeps the header, the keys, the empty prose and the assembly. No line of logic changed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s do packages/trail/measure/agent.ts was written before scripts/measure-agent.ts and kept its own copies: finding OpenCode, the world's config and environment, the turn, reading tool calls and text, the retry loop. It uses the shared ones now. `measure` takes how many runs must pass (Trail asks two of three of a free model) and stops once enough have. Run on 2.0.18 and 1.18.32: both passed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ncode run` and read it scripts/smoke/agent.ts spawned OpenCode and parsed its JSON events itself, a third copy of what scripts/measure-agent.ts does. It calls `turn` now, which says whether the turn finished in its five minutes, so the smoke still fails a turn that hung. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tor, what was removed Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tice a wrong kind On OpenCode 2 every entry goes in opencode.json, which loads both halves — what `opencode plugin add` writes — instead of splitting the halves across opencode.json and cli.json, which no user does and which loaded a bay's interface twice. Review's section carried an old name for its `!` row; old names are unknown names now, said by /cockpit-setup only, so it carries a value of the wrong kind. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…een that lays them out explorer.ts was 1021 lines in four marked sections. The tree (families as folds, a row each) is tree.ts, the card (what the selected row is and why, and its buttons) card.ts; explorer.ts keeps the screen. Importers name the file that has what they use. No line of logic changed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…er to footer screen.ts (978) drew every item of a subagent's conversation and laid the pane out around them. A call's row or box at each fold, its todo list, a card and the thinking move to calls.ts; screen.ts keeps the body, the header, the footer, the keys and the scroll. No line of logic changed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…edger dialog, and the wiring tui/index.tsx was one 851-line closure. paint.ts draws the sidebar block and the dialog; requests.ts decides and answers what OpenCode asks; ledger.tsx is `/trust` and its keys; index.tsx keeps the ledger file and the wiring — as Trail's was split for 0.9. No line of logic changed: what the closure held is a small shared object now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…essages, and the wiring tui/index.tsx was one 966-line closure. paint.ts draws the sidebar block and the pane; pane.ts is the pane and its keys (open, move, fold, stop, remove, background); messages.ts is typing to a subagent and relaying its answer; surface.ts the pane's state they share; index.tsx follows the conversation and wires the slots. No line of logic changed; the spinners' frame belongs to the painter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…that joins them actions.ts (765) held every verb. Moving through the list and the diff is navigation.ts; comments, replies, marking read or viewed, folding and submit are threads.ts, which reads the rows through navigation; actions.ts keeps sources, the base, stats, the viewer and the keys screen, and returns the one table keys.ts binds. No line of logic changed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…gets an empty agent half
OpenCode 2 sets up a plugin's interface only once its agent half has loaded; one with no `./server`
is skipped on both sides without a word in either log (measured on 2.0.18). These two had none, so
`opencode plugin add @opencode-cockpit/trust` (or `/updater`), as the install docs say, loaded
nothing. The smoke never saw it: it put interfaces in cli.json, which no install does.
Each now publishes `./server` — `dualServer(id, async () => ({}))`, which also brings `/cockpit-setup`.
Doctor lists them as EMPTY_SERVER_BAYS: on OpenCode 1 the interface alone is the whole bay, so a
tui.json-only install is not told to add an agent half. Smoke: trust, updater, bays and bundle pass on
2.0.18; trust and updater on 1.18.32.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ads the new agent halves, docs say what doctor lists From the independent review of the branch: - site/scripts/engine.ts mapped `@opencode-cockpit/<pkg>/<sub>` to `src/<sub>.ts`, which the client's new folders broke for every subpath but `.`; it reads the package's `exports` now (output unchanged). - pack-check imports `trust/server` and `updater/server` from an install of each alone, and checks OpenCode 2's door is shipped — the fix this release makes had no pack-time check. - Two site pages said doctor lists every name from before 0.9; it lists top-level ones, and `/cockpit-setup` names a key a bay does not read in its own section. - A smoke comment still said Trust and the updater have no agent side. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…be in 0.10; the client preview shows a real notice The folder was kept in 0.9 for anyone who had copied it; its own description said "removed in 0.10". status-setup carries the same design rules. The client preview's sample settings used `shell.sidebarOrder` to show a `!` row, which an unknown key in a section no longer draws; it uses a `sidebar` list in Shell's section, which does. Both from the independent review. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ger hides the keys The pane stopped at 200 files, and this release's own branch (222) was cut short. Files were read one after another, 6 ms each; eight at a time, 200 take 390 ms instead of 1.3 s. A paint measured 4 ms at 200 files, 9 ms at 1,000 and 117 ms at 2,000, so the cap moves to 1,000, where a paint still fits in a frame. The footer's notice took the keys' row. "More than N files changed" stays for the whole review, so every key — the way out included — was gone. Trouble now takes the rule's row above the keys, and the footer is still two rows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
0.10.0 — code quality, one OpenCode 2 fix, and what 0.9 said it would remove
Released together with the after-0.9 work already on main (new README, docs site at cockpit.codestz.dev, per-bay GIFs).
What changes for users
opencode plugin add @opencode-cockpit/trust(or/updater), as the install docs say, loaded nothing. Each now publishes an empty agent half (trust/server,updater/server). The bundle was never affected./statusline(now/status-setuponly), thestatusline-designskill folder, recognition of names from before 0.9 (now unknown names like a typo: a top-level one is a!row and a doctor line; one inside a bay's section is named by/cockpit-setup), and six entry points nothing imported (review/frame— broken since added —trail/core,trust/core,updater/core,status/fixtures,client/elements).[Unreleased].Internals
core/is pure: file, git and process access moved toio/in each bay (CONTRIBUTING has the rule).daemon/,opencode/{host,server}/,settings/{keys}/,setup/{conventions}/. Every publicclient/*subpath unchanged.blockWidth/measureBlockinclient/sidebar(pasted in four bays). Row painters stay per bay: tones and faint differ.dist/andtypes/and runstsc -bitself — a stale file had hiddenreview/frame.scripts/measure-agent.ts. Newscripts/golden.tssnapshots every preview. tui-smoke split into per-bay probes with install modes (bundle / all bays / one bay), and OpenCode 2 configured as the install docs say — which is how the Trust/updater bug surfaced.Checked
pack:check: every package packed; bundle and each bay installed alone; new agent halves load.tui-smokeon OpenCode 1.18.32 and 2.0.18 × bundle, all bays, each of the 7 bays alone: 18/18 pass.trust/server+updater/serveradded,OLD_NAMES/SETUP_COMMANDgone fromclient/settings,blockWidth/measureBlockadded toclient/sidebar.After merge
Release 0.10.0; then delete
media/dock.gifandmedia/statusline.png.🤖 Generated with Claude Code