anthropics / anthropics/claude-code
[FEATURE] Account-synced plugins have no update API: skills have upload-skill, plugins have nothing, so a hook fix cannot be shipped without a human clicking Accept
- Dominant language
- Python
- Stars
- 145k
- Forks
- 23.1k
- PR merge metrics
- PR metrics pending
Description
Concerns Cowork on the web (cloud sessions), account-synced plugins.
## The asymmetry
Skills have a working write route that an automated pipeline can drive:
```
POST /api/organizations/{org}/skills/upload-skill (multipart, file=.skill)
GET /api/organizations/{org}/skills/list-skills
POST /api/organizations/{org}/skills/rename-skill
POST /api/organizations/{org}/skills/delete-skill
```
I deploy ~50 skills to my account this way from a GitHub Action, unattended, and it has worked for a month.
Plugins have no equivalent. `GET /api/organizations/{org}/plugins/list-plugins` returns 200, but it serves the **public marketplace catalog** — my own account-synced plugin is not in it. Every write-shaped path I could find 404s:
- `/api/organizations/{org}/plugins/upload-plugin` — 404 `Plugin not found` (the segment is being read as a plugin id, so there is no such verb)
- `/api/organizations/{org}/plugins/create-plugin`, `/install-plugin` — 404
- `/api/organizations/{org}/plugins`, `/cowork/plugins`, `/cowork/installed_plugins`, `/marketplaces`, `/cowork/marketplaces` — 404
- `/v1/plugins`, `/v1/code/plugins`, `/v1/code/marketplaces`, `/api/plugins` — 404
## Why it matters
My account-synced plugin carries `Stop` hooks that gate every reply. One of them had a bug: it classified a tool result as a "live read" by grepping the **result text** for the tool name, which only ever worked for one connector whose payload happens to echo its own method. Every Gmail read was therefore invisible to it, and it blocked correct replies in every session on the account.
I can fix the file on a cloud sandbox's synced copy, but each new session re-syncs from the account, so the fix evaporates. The only route to make it stick is to repackage the plugin as a `.plugin` file, deliver it into a chat, and have a human press **Accept**.
That means a one-character bug in a hook that fires on every reply, in every session, cannot be repaired without a human being at a keyboard — including for scheduled/unattended runs, which is exactly when a broken gate does the most damage and nobody is there.
## Ask
Either of these closes it:
1. `POST /api/organizations/{org}/plugins/upload-plugin` taking a `.plugin` zip, mirroring `upload-skill` exactly (same auth, same multipart shape), plus a `list-plugins` scope or filter that returns the account's own synced plugins rather than the marketplace catalog.
2. Failing that, let an account-synced plugin be backed by a git marketplace the account controls, so a push updates it — the marketplace path today has its own open issues (#86818, #91308, #28125).
Related: #95157 (account-synced plugins cannot be removed), #20697.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by comparing the listed skills endpoints with /api/organizations/{org}/plugins/list-plugins and the failed plugin paths, then review related issues #95157, #86818, #91308, and #28125. Done means account-synced plugins can be updated unattended through an upload and account-scoped listing, or through a controlled git marketplace.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- git, github-actions
- Domain
- api, cloud
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100