Skip to content

Four claude plugin uninstall sites outside the worktree reap omit --keep-data and delete plugin data #3238

Description

@kyle-sexton

Four executable or copy-paste claude plugin uninstall sites outside the worktree teardown reap omit --keep-data, so each deletes the target plugin's ${CLAUDE_PLUGIN_DATA} directory whenever the scope being removed is that plugin's last remaining one. #3212 fixed the one site reachable from /source-control:worktree cleanup; these are the rest, found by the independent review on that fix.

Per claude plugin uninstall --help (Claude Code 2.1.241): --keep-data Preserve the plugin's persistent data directory (~/.claude/plugins/data/{id}/). Omitting it is a deletion, not a no-op.

Sites

1. .claude/cloud-bootstrap.sh:211 (executable, highest impact). The stale-snapshot refresh runs "$claude_bin" plugin uninstall "$id" with no scope, so the default user scope applies, then reinstalls. In a cloud session the user-scope record is the plugin's only scope, so every refresh deletes that plugin's data directory and its stored pluginConfigs entry before reinstalling it empty. The comment above the call anticipates the loss of enabled state and re-enables explicitly; the data loss is not anticipated at all. Any plugin state a resumed cloud session was meant to carry is wiped on the next refresh.

2. plugins/source-control/skills/worktree/fixtures/project-scope-reap-probe.sh:93,99,102,114,123 (executable). Five real uninstalls against the machine's real record store. The probe installs its two plugins at project scope itself, so for a plugin with no other scope the probe's own uninstall is a last-scope removal. Defaults are real plugins. fixtures/README.md names a recheck trigger instructing a maintainer to re-run this probe verbatim, which makes the destruction reachable by following the skill's own documentation.

3. docs/MIGRATION-PLAYBOOK.md:464 (copy-paste instruction). "Force a fresh snapshot: claude plugin uninstall <name>@<marketplace> then install again." User scope is typically the last scope, so following this refreshes the code by destroying the plugin's data and stored configuration, neither of which the stated intent covers.

4. plugins/claude-ops/skills/plugins/context/converge.md:48,62 (command template). The consolidation template (cd "<projectPath>" && claude plugin uninstall <id> -s project) removes a scope pin, never data. The strategy normally fires only where a user-scope record also exists, so the removed scope is usually not the last one; the per-plugin confirm can still route to a divergence with no user-scope entry, and state is re-read per mutation, leaving a window in which the removed record is the last.

docs/extensibility-contract-smoke-tests.md:26,32 also omits the flag, but wiping the throwaway smoketest plugin's state is that procedure's stated purpose, so it is listed for completeness rather than as a defect.

Suggested fix

Add --keep-data to each of sites 1 through 4. None of them intends data removal: two are refresh cycles that reinstall immediately, one is a measurement probe, one removes a scope pin. No branch in any of them wants the deleting default.

Site 2 is the one that is not a one-flag change. fixtures/README.md carries an As-of record binding a measured command to an observed per-arm outcome, so changing the command the probe runs without re-running it would leave that record describing something the script no longer does. Fixing site 2 therefore means adding the flag, re-running the probe, and re-stamping the As-of block with the resulting counts, rather than editing five lines and asserting the outcome is unaffected.

Provenance

Surfaced by the independent review on the #3212 fix and verified against the call sites before filing. Deliberately not folded into that pull request: #3212's brief scopes to the one script reachable from /source-control:worktree cleanup, and these span three other plugins and the repository's own bootstrap, with different blast radii and different owners.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions