Files
gstack/docs/uninstall.md
T
Garry Tanandcapy-ai[bot] 490bbd5202 Stop gstack-uninstall deleting a repo's committed .gstack files and unsaved worktrees (GST-2197) (#4241)
* Stop gstack-uninstall deleting a repo's committed .gstack files and unsaved worktrees (GST-2197)

--keep-state now keeps the repo's .gstack/ and .gstack-worktrees/. A plain
uninstall keeps git-tracked .gstack files, removes only ignored state, and
stops before removing anything when a worktree has uncommitted changes
unless --force-worktrees is given.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* Keep moved, config-hidden and committed worktree work from gstack-uninstall (GST-2197)

The dirty-worktree guard now checks every checkout on disk under .gstack-worktrees/, pins git status flags so config cannot hide new files, refuses a checkout whose commits no branch or tag holds, and keeps .gstack/ when git cannot list its tracked files.

Review-Finding: p1/red-team#2 reader=red-team
Review-Finding: p1/red-team#3 reader=red-team
Review-Finding: p1/specialist-batched#1 reader=security
Review-Finding: p1/red-team#4 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* Make gstack-uninstall list worktree checkouts safely and never run their config (GST-2197)

Checkouts are listed NUL-separated and through a symlinked .gstack-worktrees, only worktrees this repository registered are opened with git, and those git calls turn off fsmonitor, hooks and optional index writes.

Review-Finding: v1/adversarial-native#1 reader=adversarial-native
Review-Finding: v1/adversarial-native#5 reader=adversarial-native
Review-Finding: v1/adversarial-native#2 reader=adversarial-native
Review-Loop-Grant: a-f3b2ff8e662e
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* Check a .gstack-worktrees that is itself a git repo before gstack-uninstall deletes it (GST-2197)

Review-Finding: fc1/fix-check#1 reader=fix-check
Review-Loop-Grant: a-3b80e7929588
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* Document what gstack-uninstall keeps and refuses, and the new --force-worktrees flag (GST-2197)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* Stop gstack-uninstall dropping the registration of worktrees it did not delete (GST-2197)

Uninstall ran a repo-wide git worktree prune, which unregistered every worktree whose folder was missing at that moment, including ones outside .gstack-worktrees on an unmounted drive, and left their detached commits unreachable. It now unregisters only the gstack checkouts it just removed.

Review-Finding: p1/red-team#1 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* Say that gstack-uninstall does not yet check worktrees nested inside another checkout (GST-2197)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* Stop gstack-uninstall deleting checkouts through a .gstack-worktrees symlink that points outside the repo (GST-2197)

Review-Finding: p1/red-team#1 reader=red-team
Review-Finding: p1/red-team#2 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* Make gstack-uninstall remove only the link when .gstack-worktrees is a symlink, as before (GST-2197)

Review-Finding: p2/red-team#1 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* Drop release-note wording from the gstack-uninstall docs (GST-2197)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-11-09 23:42:47 +00:00

95 lines
4.6 KiB
Markdown

# Uninstall
## Option 1: Run the uninstall script
If gstack is installed on your machine:
```bash
~/.claude/skills/gstack/bin/gstack-uninstall
```
This handles skills, symlinks, harness registrations (the files `gstack-harness` wrote into OpenClaw, Hermes, a Dot or another harness, from their ledgers, plus the opt-in [start hook](hosts.md#start-hook), which it turns off through the harness's own CLI), global state (`~/.gstack/`), project-local state, browse daemons, and temp files. Use `--keep-state` to preserve config and analytics; it also keeps the repo's `.gstack/` and `.gstack-worktrees/`. Use `--force` to skip confirmation.
A plain uninstall keeps the git-tracked files under `.gstack/` (such as ship policy) and removes only the ones git ignores. It stops with exit 2, before removing anything, when a checkout under `.gstack-worktrees/` has uncommitted changes, has commits no branch or tag holds, or is not a worktree this repo registered. Pass `--force-worktrees` to delete those checkouts anyway. When `.gstack-worktrees` is a symlink, uninstall removes only the link and never follows it, so the folder it points at and the worktrees there are kept. It checks only the top-level checkouts: a worktree created inside another checkout under `.gstack-worktrees/` is not checked and is deleted with its parent, so commit or stash its work before you uninstall.
## Option 2: Manual removal (no local repo)
If you don't have the repo cloned (e.g. you installed via a Claude Code paste and later deleted the clone):
```bash
# 1. Stop browse daemons
pkill -f "gstack.*browse" 2>/dev/null || true
# 2. Remove per-skill directories whose SKILL.md points into gstack/
# (rm -rf, not rmdir — installed dirs also contain runtime-asset links)
find ~/.claude/skills -mindepth 1 -maxdepth 1 -type d ! -name gstack 2>/dev/null |
while IFS= read -r dir; do
link="$dir/SKILL.md"
[ -L "$link" ] || continue
target=$(readlink "$link" 2>/dev/null) || continue
case "$target" in
gstack/*|*/gstack/*)
rm -rf "$dir"
;;
esac
done
# Directories gstack created carry a .gstack-owned marker (the only signal on
# Windows, where installs are file copies with no symlink to read)
for marker in ~/.claude/skills/*/.gstack-owned; do
[ -f "$marker" ] && rm -rf "$(dirname "$marker")"
done
# Alias skills install as copies (no symlink to detect) — remove by name
rm -rf ~/.claude/skills/_gstack-command ~/.claude/skills/connect-chrome 2>/dev/null
# 3. Remove gstack
rm -rf ~/.claude/skills/gstack
# 4. Remove global state
rm -rf ~/.gstack
# 5. Remove integrations (skip any you never installed)
rm -rf "${CODEX_HOME:-$HOME/.codex}/skills/gstack"* 2>/dev/null
rm -rf ~/.factory/skills/gstack* 2>/dev/null
rm -rf ~/.kiro/skills/gstack* 2>/dev/null
rm -rf "${OPENCLAW_STATE_DIR:-$HOME/.openclaw}/skills/gstack"* "${OPENCLAW_STATE_DIR:-$HOME/.openclaw}/skills/.gstack-skills" 2>/dev/null
rm -rf "${HERMES_HOME:-$HOME/.hermes}/skills/gstack" 2>/dev/null
rm -rf ~/.cursor/skills/gstack* 2>/dev/null
rm -rf ~/.config/opencode/skills/gstack* 2>/dev/null
rm -rf ~/.gemini/antigravity-cli/skills/gstack* 2>/dev/null
rm -rf ~/.gemini/skills/gstack* 2>/dev/null
# 6. Remove temp files
rm -f /tmp/gstack-* 2>/dev/null
# 7. Per-project cleanup (run from each project root)
rm -rf .gstack .gstack-worktrees .claude/skills/gstack 2>/dev/null
rm -rf .agents/skills/gstack* .factory/skills/gstack* 2>/dev/null
```
Manual removal leaves gstack's hook entries behind in `~/.claude/settings.json`
(the uninstall script removes all of them for you, including entries whose
`_gstack_source` tag was stripped). Edit that file and delete every hook whose
command path points into `.claude/skills/gstack/`: the SessionStart auto-update
hook, the AskUserQuestion PreToolUse/PostToolUse hooks, and the Stop hooks
(session timeline, plus verify-gate if you opted in). Left in place, they error
on every matching event once the install directory is gone.
If you turned on the OpenClaw or Hermes [start hook](hosts.md#start-hook),
manual removal also leaves its `gstack-start` plugin turned on. Turn it off
with `openclaw config unset plugins.entries.gstack-start` or `hermes plugins
disable gstack-start`, then delete
`${OPENCLAW_STATE_DIR:-~/.openclaw}/extensions/gstack-start` or
`${HERMES_HOME:-~/.hermes}/plugins/gstack-start`.
## Clean up CLAUDE.md
The uninstall script does not edit CLAUDE.md. In each project where gstack was added, remove the `## gstack` and `## Skill routing` sections.
## Playwright
`~/Library/Caches/ms-playwright/` (macOS) is left in place because other tools may share it. Remove it if nothing else needs it.
## Aside
gstack never installed Aside, so it never uninstalls it. Keep it or remove it like any other app.