Even a weekend project can pick up a Vercel deployment, a Supabase database, a domain that renews every year and a Stripe key. Archiving the repo on GitHub makes the code read-only, but it turns none of those off. The site stays up, the domain renews, and the key still works.
The keys can stay live for years. GitGuardian, a company that scans code for leaked keys, took the working keys and tokens it found leaked in 2022 and tested them again. In January 2026, over three years later, more than 64% still worked. Wild!
Archiving doesn't lock anyone out, either. A friend you added as a collaborator can still fork the repo, along with every key anyone ever committed to it.
So I wrote the shutdown as a Claude Code skill: a file of instructions Claude follows when you type /wind-down-project. It's free, and the whole file is at the end of this post.
Wind-down skill, step by step
- Claude writes a checklist and changes nothing else. It reads files like
vercel.json,supabase/,.github/workflows/and the key names in.env.example, then writesWIND_DOWN.mdwith where it found each thing. It also searches the git history for.envfiles, and for names containing KEY, TOKEN, SECRET, PASS, DSN, URL or URI that were committed with a value, because a committed key still works after the file is deleted, until you revoke it. If thevercel,supabase,gh,stripeorflycommand-line tools are signed in, it uses them read only to check what really exists. You add what it missed and mark what stays. - It exports what you want to keep. You pick the database, storage and email lists, it exports them, and it checks each file opens. If the project has users, it drafts the notice for you to send.
- It shuts things down in order. Scheduled jobs go first, so nothing runs against a database that's already gone. Then hosting, domains, databases, API keys, paid plans, collaborators and app store listings.
- It asks whether to archive the repo, make it private or leave it, then moves the folder to the Trash. Collaborators come off before any archive, because GitHub won't let you add or remove collaborators on an archived repo. Before the folder goes, it checks your work is pushed and names the full path. It uses the Trash, not
rm, so you can get the folder back.
Paid plans and passwords stay with you
Anything with money or a password is yours to do. Claude names the page and the button, then waits until you say it's done. The skill tells Claude to name keys by their variable, like STRIPE_SECRET_KEY, and never print the value.
For everything else that can't be undone, the skill tells Claude to ask first, and one yes covers one step.
Manual mode makes Claude Code ask
The skill's "ask first" is only an instruction to Claude. If Claude skips the question, nothing in Claude Code stops the command.
Unless your settings say otherwise, Claude Code 2.1.283 and later start in auto mode in the terminal and VS Code. In auto mode, a second model reviews commands instead of you. For a hard stop, start this session in Manual mode. Then Claude Code itself asks before every shell command that isn't read-only or already allowed.
One exception: if you've turned on Claude Code's sandbox with /sandbox in auto-allow mode, commands inside it run without asking. The sandbox limits the files and sites a command can reach. Pick "regular permissions" in /sandbox to get the questions back.
Bare-minimum shutdown for busy developers
Nobody wants to spend an afternoon on a project they already quit, so do just these:
Start Claude Code in Manual mode and run the skill:
claude --permission-mode manual/wind-down-projectLet it write the checklist. In this part the skill tells Claude to change nothing except
WIND_DOWN.md, and Manual mode makes Claude Code ask before any other edit or any command that isn't read-only or already allowed, unless the sandbox exception above applies.- Say yes when it offers to export the database.
- Do only the lines that cost money or let someone in: scheduled jobs, hosting, the database, API keys, paid plans and collaborators.
- For the domain, just turn off auto-renew and let it expire.
- Leave the repo archive and the local folder for another day.
The checklist only knows what the repo and its history mention and what your signed-in tools can see. A domain you bought and never pointed at the site isn't in the repo, so open your registrar's domain list and turn off auto-renew there too. And it finds keys by their names, so a key pasted straight into the code, or saved under a name the search doesn't cover, can slip past.
Install the skill in your repo
These steps and the skill are for a Mac. On Linux or Windows, create the file in your editor and paste the skill in, and change the skill's last step, which moves the folder to the Trash through Finder.
In the project you want to shut down, make the skill's folder:
mkdir -p .claude/skills/wind-down-projectPress Copy on the skill at the end of this post. Then type this line instead of copying it, because copying it would replace the skill on your clipboard:
Start Claude Code in the project, in Manual mode:
claude --permission-mode manualRun the skill:
/wind-down-project
If Claude Code was already running when you made the .claude/skills folder, run /reload-skills first. To have the skill in every project, save it as ~/.claude/skills/wind-down-project/SKILL.md instead.
When you correct it, the skill tells Claude to fix its own instructions in that file, so your copy gets better each time.
Shabash, the Mac app I'm building, shows every project's open work in one list. Marking a company done there takes its projects off the list, but their hosting, database and domain keep running, just like after archiving on GitHub. The skill below is how I shut a project down for good; save it in ~/.claude/skills and it works in every project.
SKILL.md to copy
---
name: wind-down-project
title: Wind down a project
description: Wind down a project for good. Finds every service, key, account and person it touches, then shuts each one down with you, one confirmed step at a time, and deletes the local folder last.
---
# Wind down a project
Use this when the person wants a project gone, not just paused: services cancelled, keys revoked, data exported or deleted, collaborators removed, the repo archived, and the folder off their machine.
Hiding or archiving a project doesn't stop anything it runs or pays for. This skill turns those things off, so it goes slowly and asks before anything that can't be undone.
## Rules
- Ask before every step that can't be undone. That means deleting, revoking, cancelling, archiving, removing a person, or removing a DNS record. Say exactly what will happen, then wait for a clear yes. A yes covers only that one step.
- The person does anything involving money or passwords. They cancel paid plans, close billing, delete payment methods, sign in to dashboards, and delete accounts that need a password. Give them the exact page and the button to press, then wait for them to say it's done.
- Never print secret values. Name keys by their variable name and where they're used, never by their value.
- Export before delete. Before removing any data (a database, a storage bucket, analytics, a mailing list, user accounts), offer an export and save it where the person says.
- Other people come first. If the project has users, customers or collaborators, raise that before anything else: they may need notice, a data export, or a refund. Draft those messages for the person to send; never send them yourself.
- Delete the local folder last, only after everything else is done, and only after checking the work is pushed or backed up where the person wants it.
## 1. Take inventory
Read the repo and write `WIND_DOWN.md` at its root: a checklist grouped by kind, each line with where you found it. Change nothing else in this step. Look at:
- Hosting and deploys: `vercel.json`, `.vercel/`, `netlify.toml`, `fly.toml`, `render.yaml`, `Dockerfile`, `app.yaml`, `Procfile`, and `.github/workflows/` (deploy steps, scheduled jobs, secrets they use).
- Databases and backends: `supabase/`, `prisma/`, `firebase.json`, `.firebaserc`, `amplify/`, and connection strings named in env examples.
- Keys and accounts: variable names (not values) in `.env.example` and config. Read `.env*.local` files only with `cut -d= -f1 .env*.local`, which prints the names without the values. Look for payments (Stripe), email (Resend, Postmark, SendGrid), AI (Anthropic, OpenAI), analytics, auth, maps and storage. Each one is an account or key to revoke.
- Keys in the git history: a key that was committed once still works after the file is deleted. List every `.env` file ever committed, then every key name that was ever committed with a value, names only:
git log --all --format= --name-only | grep -E '(^|/)\.env' | sort -u
git log -p --all | grep -E '^[+-][A-Z0-9_]*(KEY|TOKEN|SECRET|PASS|DSN|URL|URI)[A-Z0-9_]*=[^[:space:]]' | grep -oE '^[+-][A-Z0-9_]*=' | cut -c2- | sort -u
The history shows a value was committed, not that it was a real key: it may be a placeholder like `your-key-here`, or a URL with no password in it. List these names for the person, ask which held real keys, and revoke those at their provider even if they're no longer in the files.
- Domains and DNS: custom domains in hosting config, `CNAME` files, and domains mentioned in the README or site. Note the registrar if you can tell.
- App stores and extensions: `ios/`, `android/`, `*.xcodeproj`, `app.json` (Expo), browser extension manifests. Store listings need removing by the person.
- People: the git remote, and if the GitHub CLI is signed in, the collaborators (`gh api repos/{owner}/{repo}/collaborators`), open pull requests and issues.
- Scheduled and recurring things: cron jobs, scheduled workflows, uptime monitors, webhooks pointing at this project, and anything that bills per use.
- Where the data lives: databases, buckets, analytics, email lists, and the user accounts the project holds.
Where a command-line tool is installed and signed in (`vercel`, `supabase`, `gh`, `stripe`, `fly`), use it read only to confirm what exists. If it isn't, list the dashboard page for the person to check.
Then show the person the checklist and ask:
1. Anything missing, or anything that should stay?
2. What should be exported, and where should exports go?
3. Does anyone need to be told first?
## 2. Tell people and export data
Draft notices for users, customers and collaborators if any are needed, for the person to send. Run the exports they chose, and confirm each file opens.
## 3. Shut things down, one at a time
Work through the checklist in this order, so nothing keeps running or billing while something it depends on is gone:
1. Scheduled jobs, webhooks and monitors
2. Deploys and hosting projects (they may serve the domain)
3. DNS records and domains (the person decides: keep, let expire, or transfer)
4. Databases and storage, after their exports
5. API keys and tokens: revoke each at its provider, then delete it from CI secrets and env files
6. Paid plans and accounts (the person does these)
7. Collaborators and access
8. App store and extension listings (the person does these)
For each line: say what you're about to do, get a yes, do it or hand it to the person, verify it's gone, and tick it in `WIND_DOWN.md` with the date.
## 4. Archive the repo
Ask whether to archive the GitHub repo (`gh repo archive`), make it private, or leave it. Archiving keeps the history readable and stops new changes. Only delete a repo if the person asks for exactly that, by name.
## 5. Remove the local folder
Last step. Check that `git status` is clean and the default branch is pushed (or that the person has the backup they want). Ask one more time, naming the full path. Then move the folder to the Trash with Finder, not `rm`, so there's a way back:
osascript -e 'tell application "Finder" to delete POSIX file "/full/path/to/project"'
## Keep this skill current
This is the person's own copy. When they correct you, or a step here turns out wrong or missing for their setup, edit this skill's own `SKILL.md` with the fix (in `.claude/skills/wind-down-project/` in the project, or `~/.claude/skills/wind-down-project/` if it's installed for every project), and tell them in one line what you changed.


