Summary
craft has no working story for updating or installing a Claude Code plugin on Cowork / Claude Desktop, and no Homebrew-based install path for that surface. The release skill currently punts it as a manual, unverifiable step. A real-world release this week (savant v1.7.0 → v1.7.1) exposed every failure mode end-to-end. This issue proposes overhauling both: (1) the Cowork/Desktop plugin-update flow, and (2) a Homebrew "post-install" path for plugins on Cowork/Desktop.
Motivation — what actually happened (savant v1.7.x)
savant is a private plugin consumed by two surfaces: Claude Code CLI (savant@local-plugins) and Cowork/Claude Desktop (savant@savant-private, a private self-marketplace). The CLI surface self-heals and updated cleanly to 1.7.1. The Cowork surface could not be brought current despite multiple attempts:
- The marketplace clone goes stale and never pulls. Desktop's local clone at
…/local-agent-mode-sessions/<s>/<s>/cowork_plugins/marketplaces/<mp>/ was frozen 299 commits behind origin/main. A plain git fetch from it succeeds, so the source is reachable — Desktop's "refresh marketplace" simply isn't advancing it.
- Plugin "update" silently no-ops. Because the clone still advertised the old manifest, the in-app Update found "nothing newer" and wrote nothing. Registry
installed_plugins.json pin stayed at the old version with an unchanged lastUpdated; no new cache/<mp>/<plugin>/<version>/ dir was ever created.
- "Updated" in the UI ≠ installed. After the marketplace clone was refreshed, Desktop's plugins UI showed the new version as available, which reads as "updated" — but the installed cache + registry were still the old version. The two are easy to confuse and there is no surfaced distinction.
- No compliant shell completion. Governance (R04 "update via plugin update, never re-copy"; R05 "
cache/** is read-only") correctly forbids hand-writing the cache dir + editing the registry JSON, so there is no safe manual workaround — the only compliant path is Desktop's own update, which is the thing that's broken.
- Not auto-verifiable.
skills-audit.py reads the registry/cache and reports drift, but craft offers nothing to act on it for this surface, and the release skill's verify-surfaces step (below) treats it as a non-blocking WARN.
Net: a released, tagged, CI-green plugin could not reach one of its two consumer surfaces, and craft had no command, no verification, and no recovery path for it.
Current state in craft (what exists, and why it doesn't cover this)
| Surface |
File |
Covers |
| Release consumer-refresh |
skills/release/SKILL.md Step 5 |
One-line "re-pull the marketplace in the Desktop UI, then restart" — no automation, no verify |
| Verify surfaces |
skills/release/SKILL.md Step 13.6 |
Desktop/Cowork = WARN (one-time, not auto-verifiable) — explicitly punted |
| Homebrew |
commands/dist/homebrew.md, skills/distribution/homebrew-* |
Formula (CLI tools) + Cask (Tauri native desktop apps) — not plugin distribution to Cowork/Desktop |
| Marketplace |
skills/distribution/dist-extras/ (replaces deprecated commands/dist/marketplace.md) |
Claude Code plugin marketplace listings only — no Cowork/Desktop |
| Desktop tracking |
commands/code/desktop-watch.md → release-watch.py |
Monitors Desktop release notes — not install/update |
There is no surface that (a) updates a plugin in Cowork/Claude Desktop, (b) verifies the install actually landed in cache+registry, or (c) installs/updates a plugin there via Homebrew.
Proposed overhaul
Part 1 — Cowork / Desktop plugin-update flow (make it real, make it verifiable)
- Detect the storage layout across Desktop versions (the
local-agent-mode-sessions/*/*/cowork_plugins/ path is version-specific and undocumented; the audit's glob already drifted once). Resolve the active registry + cache + marketplace-clone paths dynamically.
- Diagnose the marketplace clone: report clone HEAD vs
origin/main, commits-behind, fetch reachability, and whether the advertised manifest version matches canon.
- Refresh the marketplace source compliantly (the read-side
git pull of the clone is not a cache write — R04/R05-clean) so the in-app update has something newer to install, OR document the exact Desktop UI sequence that forces it.
- Verify the install landed: assert a new
cache/<mp>/<plugin>/<version>/ dir exists AND the registry pin + lastUpdated advanced — not just that the UI lists it as available. Distinguish available vs installed explicitly.
- Recovery path when update no-ops: documented quit-and-relaunch (full
Cmd-Q, not in-app restart) and uninstall→reinstall, with a verification re-check after each.
- Wire into the release skill: upgrade Step 13.6 for Desktop/Cowork from WARN to an actual verify + remediate step (still non-blocking on the release, but actionable and honest about installed-vs-available).
Part 2 — Homebrew "post-install" path for plugins on Cowork/Desktop
- A Homebrew-driven install/update mechanism for a Claude Code plugin consumed by Cowork/Desktop (distinct from the existing Tauri cask for native apps and formula for CLIs).
- Likely a small formula/cask whose install step performs the compliant
marketplace add + plugin install/update (or refreshes the marketplace clone) so brew upgrade keeps the Desktop surface current without the broken in-app path.
- Reuse the existing
homebrew-* skills + tap-update machinery from the release pipeline; add a plugin-distribution mode.
Acceptance criteria
Evidence / references
- Failure trace: savant
v1.7.0→v1.7.1 Cowork refresh (marketplace clone 299 commits behind; registry untouched; no 1.7.1 cache dir; UI "available" ≠ installed).
- Audit tool that detects (but can't fix) the drift:
~/.claude/scripts/skills-audit.py.
- craft files:
skills/release/SKILL.md (Steps 5, 13.6, 10b), commands/dist/homebrew.md, skills/distribution/dist-extras/, commands/code/desktop-watch.md.
🤖 Generated with Claude Code
Summary
craft has no working story for updating or installing a Claude Code plugin on Cowork / Claude Desktop, and no Homebrew-based install path for that surface. The release skill currently punts it as a manual, unverifiable step. A real-world release this week (savant
v1.7.0→v1.7.1) exposed every failure mode end-to-end. This issue proposes overhauling both: (1) the Cowork/Desktop plugin-update flow, and (2) a Homebrew "post-install" path for plugins on Cowork/Desktop.Motivation — what actually happened (savant v1.7.x)
savant is a private plugin consumed by two surfaces: Claude Code CLI (
savant@local-plugins) and Cowork/Claude Desktop (savant@savant-private, a private self-marketplace). The CLI surface self-heals and updated cleanly to 1.7.1. The Cowork surface could not be brought current despite multiple attempts:…/local-agent-mode-sessions/<s>/<s>/cowork_plugins/marketplaces/<mp>/was frozen 299 commits behindorigin/main. A plaingit fetchfrom it succeeds, so the source is reachable — Desktop's "refresh marketplace" simply isn't advancing it.installed_plugins.jsonpin stayed at the old version with an unchangedlastUpdated; no newcache/<mp>/<plugin>/<version>/dir was ever created.cache/**is read-only") correctly forbids hand-writing the cache dir + editing the registry JSON, so there is no safe manual workaround — the only compliant path is Desktop's own update, which is the thing that's broken.skills-audit.pyreads the registry/cache and reports drift, but craft offers nothing to act on it for this surface, and the release skill's verify-surfaces step (below) treats it as a non-blocking WARN.Net: a released, tagged, CI-green plugin could not reach one of its two consumer surfaces, and craft had no command, no verification, and no recovery path for it.
Current state in craft (what exists, and why it doesn't cover this)
skills/release/SKILL.mdStep 5skills/release/SKILL.mdStep 13.6commands/dist/homebrew.md,skills/distribution/homebrew-*skills/distribution/dist-extras/(replaces deprecatedcommands/dist/marketplace.md)commands/code/desktop-watch.md→release-watch.pyThere is no surface that (a) updates a plugin in Cowork/Claude Desktop, (b) verifies the install actually landed in cache+registry, or (c) installs/updates a plugin there via Homebrew.
Proposed overhaul
Part 1 — Cowork / Desktop plugin-update flow (make it real, make it verifiable)
local-agent-mode-sessions/*/*/cowork_plugins/path is version-specific and undocumented; the audit's glob already drifted once). Resolve the active registry + cache + marketplace-clone paths dynamically.origin/main, commits-behind, fetch reachability, and whether the advertised manifest version matches canon.git pullof the clone is not a cache write — R04/R05-clean) so the in-app update has something newer to install, OR document the exact Desktop UI sequence that forces it.cache/<mp>/<plugin>/<version>/dir exists AND the registry pin +lastUpdatedadvanced — not just that the UI lists it as available. Distinguish available vs installed explicitly.Cmd-Q, not in-app restart) and uninstall→reinstall, with a verification re-check after each.Part 2 — Homebrew "post-install" path for plugins on Cowork/Desktop
marketplace add+plugin install/update(or refreshes the marketplace clone) sobrew upgradekeeps the Desktop surface current without the broken in-app path.homebrew-*skills + tap-update machinery from the release pipeline; add a plugin-distribution mode.Acceptance criteria
/craft:dist:coworkor an extension ofdist:homebrew/dist-extras) updates a plugin on Cowork/Claude Desktop and verifies the install landed (cache dir + registry pin advanced), not just availability.Evidence / references
v1.7.0→v1.7.1Cowork refresh (marketplace clone 299 commits behind; registry untouched; no 1.7.1 cache dir; UI "available" ≠ installed).~/.claude/scripts/skills-audit.py.skills/release/SKILL.md(Steps 5, 13.6, 10b),commands/dist/homebrew.md,skills/distribution/dist-extras/,commands/code/desktop-watch.md.🤖 Generated with Claude Code