-
Notifications
You must be signed in to change notification settings - Fork 0
feat(install): receipt-owned uninstall lifecycle, format/2 receipts, and doctor activation states (#101) #452
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d795dac
9e5c952
2f9541b
f74f362
96d31e0
d7068b7
9e69e8a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "agent-bundle": patch | ||
| --- | ||
|
|
||
| Add `agent-bundle uninstall <host> [--from <bundle-dir>] [--scope <scope>] [--mode local|marketplace] [--keep-data | --purge-data --confirm-purge] [--force] [--plan] [--json]`, the package-relative installer bin's `uninstall <host>`, and the emitted standalone `install.mjs --uninstall`: the receipt-owned reverse of `install`. Uninstall removes exactly the receipt's files and installer-created directories (Cursor local, including the `~/.cursor/plugins[/local]` directories the install created), the staged marketplace repository after its `HEAD` matches the recorded commit (Cursor `--mode marketplace`), or the recorded host registrations (`claude plugin uninstall --keep-data` + `claude plugin marketplace remove`, `codex plugin remove` + `codex plugin marketplace remove`, the marketplace retained while another installed plugin uses it — for Claude, including installs at another scope or in another project known only to Claude's `plugins/installed_plugins.json` registry) — and nothing else. Durable runtime state (`state/`, and the `PLUGIN_DATA` directory the receipt of a Cursor Agent Plugins copy records) is kept unless `--purge-data --confirm-purge` (`AB7008` without confirmation) with a typed per-host `data.outcome` (`kept`/`purged`/`absent`, Claude `retained-by-host`, Codex `removed-by-host`/`unavailable`); a missing receipt is `AB7009` and an owned-content, version, or `HEAD` mismatch is `AB7007` unless `--force`; foreign directories are refused regardless; `--plan` prints the exact paths and host verbs without changing anything; a rerun is a `not-installed` no-op. Install receipts move to format `agent-bundle-install-receipt/2` as the single lifecycle source of truth (mode, scope, registrations, created host directories, `updatedAt`), Claude/Codex/Cursor-marketplace installs write store receipts under `<host root>/agent-bundle/receipts/`, and format 1 receipts are read with synthesized fields and diagnosed (`AB7329`), never rejected. `agent-bundle doctor --from` reports the lifecycle stage per host (placed → registered → enabled → active, unobservable stages typed `unavailable`; `AB7330`), inventories store receipts and flags orphaned ones (`AB7328`), and explains a Cursor directory holding only preserved runtime state as `missing` (`AB7307`) instead of foreign. Host capability tables gain dated `lifecycle` rows and every adapter revision advances (#452) |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,6 +12,40 @@ | |
| "source": "https://code.claude.com/docs/en/discover-plugins", | ||
| "state": "supported" | ||
| }, | ||
| "lifecycle": { | ||
| "uninstall": { | ||
|
Comment on lines
+15
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This adds a lifecycle contract to the Claude capability table, but Claude's Useful? React with 👍 / 👎. |
||
| "commands": [ | ||
| "claude plugin uninstall <plugin>@<marketplace> --scope <scope> --keep-data", | ||
| "claude plugin marketplace remove <marketplace>" | ||
| ], | ||
| "evidence": [ | ||
| "2026-09-03: local Claude Code 2.1.257 `claude plugin uninstall --help` documents --keep-data (preserve ~/.claude/plugins/data/{id}/), --scope user|project|local, and --prune/-y; `claude plugin marketplace remove --help` documents removal from every scope by default. `agent-bundle uninstall claude` runs exactly those two verbs, in that order, from the registrations its install receipt recorded (#101).", | ||
| "2026-09-03: in an isolated CLAUDE_CONFIG_DIR, `claude plugin uninstall <id> --scope user --keep-data` marked the cached copy orphaned (`.orphaned_at`) instead of deleting it and left `plugins/installed_plugins.json` as `{\"plugins\":{}}`, `plugins/known_marketplaces.json` as `{}`, and `settings.json` with empty `enabledPlugins`/`extraKnownMarketplaces`; `claude plugin marketplace remove` then removed the marketplace declaration. Removing a marketplace or plugin that is not registered exits 1 (`not found`), so the uninstaller consults `claude plugin list --json` and `claude plugin marketplace list --json` first and reports already-absent registrations instead of failing." | ||
| ], | ||
| "state": "supported" | ||
| }, | ||
| "keepData": { | ||
| "evidence": [ | ||
| "2026-09-03: Claude Code 2.1.257 retains the orphaned cache copy, its `state/` included, for the documented ~14-day grace period, and --keep-data preserves ~/.claude/plugins/data/{id}/; the uninstaller reports this as data outcome `retained-by-host` and, under --purge-data --confirm-purge, removes `state/` under the cached copy and the plugins/data entry itself (`purged`)." | ||
| ], | ||
| "state": "supported" | ||
| }, | ||
| "activationState": { | ||
| "evidence": [ | ||
| "2026-09-03: `claude plugin list --json` rows carry `enabled` (observed true after `claude plugin install`), `scope`, `installPath`, and `version`; Doctor reads placed (installPath exists), registered (row present), and enabled (row flag) from them. No read-only verb reports which plugins a live session has loaded, so `active` is typed unavailable." | ||
| ], | ||
| "observable": [ | ||
| "placed", | ||
| "registered", | ||
| "enabled" | ||
| ], | ||
| "reason": "Live activation has no pinned read-only surface on Claude Code 2.1.257.", | ||
| "state": "degraded", | ||
| "unavailable": [ | ||
| "active" | ||
| ] | ||
| } | ||
| }, | ||
| "deferredNativeEvents": { | ||
| "ConfigChange-policy_settings": { | ||
| "reason": "retrieved 2026-09-02 from https://code.claude.com/docs/en/hooks: ConfigChange block decisions cannot stop policy_settings changes; recorded so the config/change family's deny channel is not overstated.", | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.