v0.17.0
Changelog
Features
- 9a16792 feat(cli)!: remove the Antigravity legacy flat-config layer
- 88debe0 feat(cli): add
plumb setup kimi-workfor the Kimi Work desktop app - c13ccc7 feat(cli): doctor MCP Clients alphabetical, with diagnostics as branches
- 48684b5 feat(cli): doctor moves live LSP sessions to their own section; capability-trust row realigned
- add2db9 feat(cli): grouped-table renderer, shared status colours, terminal-accurate TTY checks
- 0f8346a feat(cli): interactive client picker for bare plumb setup
- 70615a5 feat(cli): plumb mail, so a hook can ask whether an agent has mail
- 1e5c289 feat(cli): plumb serve --workspace flag pins the attach hint
- 6b62ef4 feat(cli): plumb setup --uninstall
- b33ecc0 feat(cli): plumb skills groups the status table per client with status colours
- 9bc4c33 feat(cli): plumb skills sync reports through the grouped per-client table
- da9536b feat(cli): plumb trust joins the shared CLI presentation, confirmed by the Yes/No selector
- 130b6f0 feat(cli): sessions --json machine-readable mode (PLAN-336)
- 5670c86 feat(cli): skills sync summary section, unregistered rows, doctor branch wrapping, trust record
- e14ae5a feat(collab): count what the mailbox is doing, instead of capping it
- 4c911ad feat(collab): let a restarted session inherit its predecessor's mailbox identity
- 3c48f10 feat(collab): tell a sender which of its messages nobody has read
- 165677e feat(git): report a plumb-caused git timeout as plumb's, and make the bound configurable
- 90f32fc feat(mcp): carry the per-call logical agent in the tools/call ctx
- ecdb618 feat(scripts): catch a CHANGELOG entry added under the wrong heading
- 2a7a2be feat(scripts): guard against a duplicate CHANGELOG version heading
- 3ea1249 feat(session): adopt the replayed stable session ID (PLAN-296)
- 39b8421 feat(session): capture the logical-agent identity from tools/call _meta
- 8fbf254 feat(session): consume per-agent trackers/rate/undo/pins in the live tool path (PLAN-286)
- 74ff9c2 feat(session): daemon reads the replayed stable session ID (PLAN-296 round-trip)
- ffed479 feat(session): fail closed on anonymous state-changing calls over a shared connection
- bb709c3 feat(session): key pin/trackers/undo/rate/language per logical agent (PLAN-286 step 2b-c)
- a992a32 feat(session): reconcile mailbox inheritance with the adopted ID (PLAN-286 step 4)
- 0e556c5 feat(session): serve proxy holds and replays the stable plumb session ID
- b67b147 feat(sessionstate): persist per-agent reads and pins (schema v6, PLAN-286 step 2e)
- 56bfe70 feat(setup): add DeepSeek Harness as a setup client
- f01b70a feat(setup): add Junie as a setup client
- 469992f feat(setup): add ZCode as a setup client
- 11a651c feat(tasks): run commands where the module is, and make scoping reachable
- 0153ba7 feat(tools): mutation_test — explicit-mutant mutation testing with a mandatory compile gate
- 15e6a26 feat(tools): resolve per-agent workspace/boundary via request ctx (PLAN-286 step 2d)
- a86237e feat(tools): session_start flags an unlinked session (PLAN-337)
- 7b38d4d feat(tools): surface task state, batch deletes, and lift the context_lines cap
- 15042b8 feat(topology): surface skipped-file reasons in status, web API and doctor
- 7e8d1ea feat(web,tui): show daemon-wide conversation volume when every participant opted in
Fixes
- 688b448 fix(attach): bind the claim message by its remedy; CUT the dashboard change
- bcd5ada fix(attach): state the refusal's real cost, and pin it with a test
- 8a4b44e fix(attach): stop the alarm accusing a caller of forgery the daemon disarmed
- 9dfbf3f fix(attach): surface a forged wide claim, and sweep pre-fix forged pins once
- 641de94 fix(attach): the replayed _meta pin no longer carries the home exemption
- 91dd499 fix(attach): withhold the home exemption from the replayed pin on policy rebuilds too
- af18679 fix(build): retry golangci-lint on the shared-cache lock
- cebc18a fix(ci,test): let a failing test name itself, and stop asserting wall clock
- ca53da3 fix(cli): apply the saved [ui] theme to the whole CLI, not just the dashboard
- 3d9ad36 fix(cli): cap the setup table's Config column at 60 columns
- 35f9bae fix(cli): close sticky-pin residuals and PLAN-300 follow-ups
- 391db75 fix(cli): do not start the Xcode flow from a config that failed to load
- 0564926 fix(cli): make --workspace resolve a workspace, and stop overclaiming the hook
- 5268fde fix(cli): name why no LSP is attached for a home-directory pin
- 67851f3 fix(cli): print setup --all errors below the table, not in its Config column
- 4292423 fix(cli): refuse a restore whose re-resolution drifts from the verified root
- 84f2009 fix(cli): refuse undeclared roots that CONTAIN a home directory
- b1e7717 fix(cli): space key was dead in the setup picker and the Yes/No selector
- 2372688 fix(collab): a conversation id addresses a thread, it does not grant one
- 3fa005e fix(collab): address a message to a session, not to a name
- f167e7a fix(collab): close the second name-shadowing lane, in workspace_sessions
- bb09d71 fix(collab): count claimable "next" notes in the plumb mail wake probe (PLAN-343)
- 8794aa0 fix(collab): count only the sender's bytes in the truncation report
- c39d584 fix(collab): merge the receipt across both stores, and stop overstating it
- 774a575 fix(collab): never hand a note back to the session that wrote it
- ddce59b fix(collab): refuse a cross-project leave_note the recipient will never read
- 839d027 fix(collab): refuse a thread whose other participant could not be placed
- 61b1dba fix(collab): refuse an unregistered sender, and stop hiding the wait
- 4edfbbd fix(collab): review follow-through on the cross-project consent refusal
- 53f5ea3 fix(collab): stop hiding truncated notes, and surface the mailbox policy up front
- 2508049 fix(collab): the unregistered-session guard tested the wrong field
- 702a708 fix(config): a config plumb cannot read means no config, not the last one
- f3010b1 fix(config): collapse fold variants in document order; refuse to clobber non-table segments
- d0b125d fix(config): do not fold map keys when collapsing fold variants
- 9107022 fix(config): do not reuse a fold-variant key that holds an array of tables
- 2c602f0 fix(config): fold key case in the project-config sparse read/write/unset trio
- 18c9a40 fix(config): fold key case the way go-toml does, not the way EqualFold does
- ab3ab39 fix(config): fold the two remaining raw-map walkers, and make the fold deterministic
- 70c5a11 fix(config): match the decoder's ToLower fold in the project policy spec
- 343d1b8 fix(config): show a provenance row for every [git] field, and guard the drift
- 3f423de fix(delete_file): dedup batch paths by canonical key, not raw string
- 28dfbed fix(deps): bump nanoid to 3.3.18 (GHSA-2v37-7h3g-55p8)
- 87ac195 fix(detect): break contested root markers by what the project contains
- 293459b fix(detect): tie-break scan budget starved by a large resources tree (PLAN-340)
- abd603a fix(edit_apply): narrow the bare-mention carve-out, stop aliasing the caller's edits
- d0f3918 fix(edit_apply): refuse a WorkspaceEdit naming one file under two paths
- a1b50a4 fix(edit_apply): refuse one file named twice in EITHER form, not just two spellings
- 36e0dd4 fix(edit_file): advise when an anchor edit swallows a line break, and point big edits at range mode
- e566f00 fix(edit_file): compare the composed seam, not new_string alone
- f811693 fix(edit_file): make the join note see CRLF, which it was blind to
- f9451a4 fix(git): move the entries to 0.16.7, name the env var, pin the tier guard
- 0e00b2b fix(mail): address the mailbox with the session's ID, not just its name
- 30972a1 fix(mutation_test): check both halves of a kill, and never let a command that could not start be one
- a22f67a fix(mutation_test): name the step that failed, and drop advice that cannot fire
- be1f11f fix(mutation_test): name which of the three causes failed the baseline
- 1e6d12b fix(paths): key two case spellings of one file to one lock key
- 0d17cd6 fix(perf): make the settle-wait fix actually reachable in production
- 0aaec95 fix(quality): close non-blocking findings from the #297 stale-cache review
- 672be5c fix(quality): name golangci-lint's stale cache instead of reporting phantoms
- dbf01d3 fix(quality): stat absolute paths, not a guessed base, for the stale-cache check
- 17ab625 fix(release): bump server.json to 0.16.6, matching VERSION
- 258df95 fix(rename_file): keep the same-path guard on the path, not the folded key
- dc50c5b fix(scripts): fail an entry moved OUT of the unreleased section, and guard pushes
- 63d2d23 fix(scripts): review findings — advisory push step, and two holes in R3
- bf567da fix(scripts): stop the placement guard failing an edit to a released entry
- 57b6d0a fix(search): keep a budget-truncated line valid UTF-8; de-race the lock test
- 1110b1d fix(session): stop overstating shared-connection isolation
- b4873e6 fix(session_start): make every claim in the ignored-[git] notice true
- 08ecb62 fix(session_start): make the ignored-[git] notice agree with the policy it annotates
- b279258 fix(session_start): name the third provenance an unparseable config can leave standing
- 9cc5d6c fix(session_start): tell the agent when a project [git] block was ignored
- 78452e2 fix(skills): install a skill's references/ notes, not just SKILL.md
- 5b4de81 fix(stats): correct the failures truncation footer and blank-kind classification leak
- c0fd23f fix(stats): don't let normaliseCall swallow an undeclared class on a blank kind
- e2f006f fix(stats): keep agent-to-agent message bodies out of telemetry
- ad61d91 fix(tools): address independent review of the brace and hint fixes
- aa8f678 fix(tools): address independent review — TOCTOU, hard output cap, slot agreement
- ff310d7 fix(tools): align doc-span columns; close git guard gaps
- 3639b01 fix(tools): bring six truncated descriptions under the cap, and pin a ceiling
- 8abec1b fix(tools): make the recent-writes feed show writes, not write-tool calls
- e99eb5c fix(tools): round-2 review — odd pipe runs, escaped-brace counting, boundary test
- 2e76bf1 fix(tools): route lockPathKey through paths.Canonical, and pin EvalSymlinks to internal/paths
- 1f249ca fix(tools): three silent-wrong-answer traps in the MCP tool surface
- f7b0cbf fix(tools): treat a cancelled mutation_test run as invalid, not a kill
- 16c8764 fix(topology): record deadline-killed parses as timeout, not cancelled
- eedb484 fix(topology): review nits — empty-sample note, message hygiene, web DTO test
- 0175ba9 fix(tui): collapse linked-worktree sessions onto their main worktree in Settings scopes
- 531287a fix(tui): the blocked-session alert shows the session's own remedy
- 1310a48 fix(tui,attach): bind the alarm's wording, and stop the dashboard looping advice
- 18edbcd fix(tui,attach): bind the message by its REMEDY, and stop truncating it away
- 9ad15df fix(xcodebsp): assert on the marker flag, not the rendered command
Others
- 8504d80 Merge feat/plan-286-logical-agent-identity: PLAN-286 logical-agent identity isolation
- 2960380 Merge feat/plan-286-per-agent-live-wiring: consume per-agent trackers/rate/undo/pins in the live tool path (closes PLAN-286 review finding)
- 7f789df chore(deps): bump @sveltejs/vite-plugin-svelte
- 96484b9 chore(deps): bump svelte from 5.56.8 to 5.56.9 in /internal/web/ui in the npm group (#363)
- 7e93006 chore(deps): bump the charm group with 2 updates (#364)
- 2827e02 chore(docker): add root Dockerfile for stdio MCP server
- 60352a6 chore(glama): add glama.json maintainers
- 6fd53d9 chore(release): cut 0.17.0
- 963345e chore(style): gofumpt two committed test files blocking lint
- 74987bd ci(deps): bump actions/setup-node from 6 to 7 in the actions group (#365)
- c9ff4c8 ci(pages): build the blog on Python 3.14
- 29989fa docs(agents): give the brief real headroom by moving reference detail to docs/
- b7acf2e docs(changelog): merge the two 0.16.6 headings into one
- 3e885ac docs(changelog): move the #301 entries under the 0.16.7 heading
- 1987390 docs(changelog): move the mutation_test entry into 0.16.7
- 3eb3f19 docs(changelog): move the recent-writes entry into 0.16.7
- abb85a9 docs(changelog): move this branch's entries into 0.16.7
- 35c04f6 docs(changelog): record the edit_file anchor note and the range-mode steer
- 33e5e3f docs(changelog): record the four-walker fold defects found in review
- bace474 docs(changelog): record the review fixes to the baseline diagnosis
- 8d67e28 docs(changelog): settings scopes collapse linked worktrees (0.16.7)
- 7d99a71 docs(changelog): the mutation_test baseline diagnosis fix
- 731fc04 docs(collab): a peer is bound when CONNECTED, not when attached
- 43872e6 docs(collab): close the last 3 stale cross_project claims the fix left behind
- 98cf8a9 docs(collab): correct three claims the review found overstated
- d58e1b7 docs(collab): correct what the delivery check actually costs
- 95e022f docs(collab): fix the last two stale cross_project claims, in the skill itself
- 0fc3618 docs(collab): say that cross_project is display consent too
- 755965a docs(git): document write_timeout and why plumb stops waiting
- 53bb60a docs(mutation_test): changelog, tool reference, and the counts the guards pin
- 1819f01 docs(paths): correct two claims the case-fold change invalidated
- cf1474b docs(skills): give the wake recipe the session linkage it was missing
- 69881c0 docs(skills): ship plumb-chat, the mailbox's missing instruction manual
- 113150c docs(skills): wake-hook reference matches re-arm-on-consume and next-note counting (PLAN-333)
- 99c1cce docs(textfmt): say plainly where the six bytes go
- eff43cd docs(tools): measure the truncation cap instead of bracketing it
- 237b36f docs+test(skills): correct the reference-install docs, pin the drift path
- 4767547 docs: CLI UX unification — setup picker/uninstall/--all, skills grouping, doctor live section, trust selector
- 78ae73a docs: apply the write-capable-tools formula everywhere, not just the site
- 74c7c0b docs: finish the correction — docs/index.md was missed
- d72bdb5 docs: lead with coordination, because it is the differentiated thing
- b9b174a docs: say what the recent-writes feed actually contains
- 8b5aca7 docs: stop the parenthetical implying it lists every non-write
- f5ff720 docs: the recent-writes feed is now accurate — say so plainly
- ebee91a perf(collab): prepare the mailbox probe once instead of parsing it per call
- e2b9f68 perf(collab): probe before claiming, and share one delivery predicate
- d4e9975 perf(edit_file): bound the Myers diff and stop sleeping out the settle grace
- 3c3e94f refactor(cli): fold setup --repair into --all; split the bulk engine out of setup_clients.go
- 2539a5e refactor(cli): split session identity accessors out of conn.go
- 390445b refactor(collab): one implementation of the cross-project consent check
- 4e54114 refactor(edit_file): spell the seam check as before/after, and fix the note's wording
- 0857647 refactor(mcp): export WithLogicalAgent for in-process per-agent ctx construction
- ea49327 refactor(session): git tool reads the session ID via an accessor
- 4e8ed65 refactor(session): read the session ID via accessors across all tools
- 2069346 style(cli): breathing room around the trust warnings header and prompt
- f6b7cc0 style(cli): setup output breathing room
- b4e539c style(cli): trust record on the shared 2-space gutter, blank line before its heading
- 66bce0a style(mutation_test): satisfy gofumpt, perfsprint and recvcheck
- 4551d4a style: gofumpt — space around string concatenation operator
- 98f883d test(attach): pin the canonical comparison in the forged-claim alarm
- 0fe5c1e test(cli): close the review's corpus gap — .git at the seed's own level
- e6a2038 test(cli): fuzz workspace-root synthesis against the kernel
- bd98852 test(cli): hold the three assertions that survived the green suite
- fad0495 test(cli): negative test for the LSP-skip note on the first-attach path
- d4d2a2e test(collab): fix what the mailbox benchmark blamed, and what it published
- 75443b0 test(collab): pin check_messages' own inherited-identity plumbing
- 51d16e3 test(collab): pin that by-name addressing does not rescue a self-authored note (PLAN-307)
- 80ad8b5 test(collab): pin the peer gate on session_start's collab section
- 7d52d0d test(collab): put numbers on the mailbox probe, three ways
- d417a06 test(collab): rebuild the benchmark's statements from the production predicate
- 75b307e test(detect): pin the tie-break budget's value and the prune list (PLAN-340) (#367)
- d482fe1 test(edit_apply): cover the adoption branch of the no-alias contract
- ba9a945 test(git): cover the timeout attribution, the lock-wait class, and the new knob
- eb8170e test(mcp): prove the OnToolRefusal seam refuses unattributed calls
- 34f2841 test(mutation_test): assert the restore notification outlives cancellation, and make the concurrency guard fail cleanly
- 5ab4d90 test(mutation_test): establish the outside-a-repo precondition instead of assuming it
- 294e49a test(mutation_test): the cwd assertion was vacuous — a mutant proved it
- 35342b9 test(rename_symbol): cover the dry-run duplicate-file refusal
- 9094503 test(tools): assert the fsync seams by directory IDENTITY, not by spelling
- f1a57ba tui(git): add the Settings row for git.write_timeout
- 98c05a9 wip(git): [git] write_timeout knob — config layer only
- 40030ee wip(mutation_test): tool surface, run cycle, report formatting
Install
Homebrew (macOS + Linux):
brew install plumbkit/plumb/plumbDirect download: grab the archive for your OS/arch below, extract it, and
put the plumb binary on your PATH.
| Platform | Archive |
|---|---|
| macOS, Apple Silicon (M-series) | plumb_0.17.0_darwin_arm64.tar.gz |
| macOS, Intel | plumb_0.17.0_darwin_amd64.tar.gz |
| Linux, Intel/AMD 64-bit | plumb_0.17.0_linux_amd64.tar.gz |
| Linux, ARM 64-bit | plumb_0.17.0_linux_arm64.tar.gz |
Verify your download against checksums.txt.
macOS note: these binaries are not yet code-signed. On a direct download
Gatekeeper may block the first run — clear the quarantine flag once:
xattr -dr com.apple.quarantine ./plumb. Homebrew installs are unaffected.