This is part of my "Claude Code environment" series. Last time I wrote about an autopilot that lets Claude Code improve itself autonomously and unattended. But if the "pile of automation scripts" that showed up there isn't organized, you can't even decide what to hand the autopilot. So this time the topic is the system I use to classify projects and manage where they live.
Counting the entries in my current ledger ~/PROJECTS.md
, there are over 40 projects lined up — web apps, Chrome extensions, iOS apps, digital products, client work, AI tooling, PC automation, and OSS evaluations. Before things grew this far, I built a structure of "8 categories + a ledger + a symlink tree." This article is about that design.
Claude Code kept hunting for directories scattered across ~/dev/
, ~/Projects/
, ~/digital-products/
, and ~/oss-trial/
with find ~
every single time. It wasn't just the search time — the state (live/stalled/retired), the production URL, and whether it was monetized were all scattered too, so every time I asked "whatever happened to that app?" I had to reconstruct the context from scratch.
The goal is to consolidate the ledger into a single file so I reach a state where "ask, and the answer comes out immediately."
Here's the definition table straight from ~/PROJECTS.md
.
| Code | Definition |
|---|---|
01-webapp |
|
| Web apps / web games that are deployed and used | |
02-chrome-ext |
|
| Chrome extensions (MV3) + their dedicated backend API | |
03-ios-app |
|
| iOS native / delivery wrappers | |
04-digital-product |
|
| note monetization, digital products, content for sale | |
05-client-work |
|
| Contract / commissioned work / company repos (third-party owner remote = push with care) | |
06-claude-tooling |
|
| Infrastructure, skills, and integrations that act on Claude / the AI agent itself | |
07-pc-automation |
|
| PC automation, scrapers, CLI scripts | |
08-oss-eval |
|
| Evaluation, experimentation, and sandboxing of external OSS |
Adding categories dilutes their meaning, so I only create a new one "when something genuinely fits none of the eight."
The decision is made by how it's delivered, not by its name. For example, autolike-license-server
sounds like an API name, but it's a backend dedicated to license verification for a Chrome extension, so it goes under 02-chrome-ext
. Judging by name would misclassify it as "API → server → 01-webapp
."
It's tempting to think "organizing = moving folders," but in side-project development, dependencies on absolute paths hide in three places.
.vercel/project.json
vercel deploy
points at a different project.ProgramArguments
is registered as the real path. Move it, and the cron job dies.git worktree add
holds the real path in .git/worktrees/<name>/gitdir
.⚠️ Physically moving a real directory is strictly forbidden.
.vercel
, launchd plists, and git worktrees break because they depend on absolute paths. "Classification" is expressed with symlinks + the ledger.
You never touch the real directory — you just create a symlink under ~/Desktop/All-Projects/<category>/.
ln -sfn ~/dev/takugumi ~/Desktop/All-Projects/01-webapp/
ls ~/Desktop/All-Projects/01-webapp/
In ln -sfn
, the -f
overwrites an existing symlink, and -n
prevents it from burrowing into the target when the target is a directory. Without these two flags you get a double-nested link.
The ledger ~/PROJECTS.md
is one line per project, holding the path, state, monetization, production URL, and cautions (currently 8 categories × over 40 projects total). By reading this one file, Claude Code can instantly answer "Where's the iOS app for the job-hunt tracker?" or "Which ones are in a live state?"
The procedure is written in ~/.claude/skills/auto/project-categorization/SKILL.md
, and it fires automatically every time a new project is created. The heart of the procedure is only this:
When starting a new project, before you begin writing code:
1. Decide what you're building → pick one of the 8 categories above
(Decide by how it's delivered — not by name or first impression)
2. Only if it fits none of the existing 8, create a new 09-<kebab>
3. Create the real directory under the appropriate parent dir
Web app / extension → ~/dev or ~/Projects
Product → ~/digital-products
OSS evaluation → ~/oss-trial
4. ln -sfn <real path> ~/Desktop/All-Projects/<category>/
5. Add a row to the relevant category table in ~/PROJECTS.md
Because CLAUDE.md also says "when creating a new project, always classify it into one of the 8 categories before starting," Claude begins with classification without being told.
ls ~/Desktop/All-Projects/01-webapp/
grep "takugumi" ~/PROJECTS.md
git -C ~/dev/<project> check-ignore credentials.json
Drawn from what I collected in the auto-skill's Pitfalls
section.
autolike-license-server
(a Chrome extension backend) under "server = 01-webapp
." Read package.json
or the README and judge by how it's delivered.05-client-work
toc-seo/credentials.json
(a GCP key) was sitting bare in the root of a company repo. Every time you create client-work, check that secret-key patterns are in .gitignore
.ababa-pr/*
and fujibee/*
are treated as 05-client-work
and pushing is forbidden. Check the owner with git remote -v
before pushing.~/PROJECTS.md
- the
~/Desktop/All-Projects/<category>/
symlink tree is the source of truthNext time, I'll write about the setup that auto-generates a Mermaid diagram of these organized projects every morning and drops it on the Desktop.
*Written by Lily — I ship iOS apps and automate my content stack with Claude Code.
Follow along: Portfolio · X · GitHub*