Imported from YaroslavSavchenk/ai-cli-application (
.claude/skills/restructure-repo/SKILL.md). Install upstream withnpx skills add YaroslavSavchenk/ai-cli-application --skill restructure-repo. Copyright stays with the author.
Restructuring the repo
Moving files is cheap; the references to them are the work. A restructure is done when every reference resolves, the suite is as green as before, and one map says where everything lives. Behavior never changes — only locations.
Scope argument: $ARGUMENTS (empty = all). Read the ## Hard technical constraints and ## Process sections of .claude/PROJECT-SCOPE.md first.
0. Preconditions — all must hold before step 1
- Tree clean, branch
main,HEADequalsorigin/main. - Node 24 on PATH:
export PATH=$HOME/.nvm/versions/node/v24.14.0/bin:$PATH(system node is v18 and cannot run the suite). - Baseline:
npm run typecheck && npm run build && npm test— record the pass/fail counts. A red baseline is fixed or reported first, never moved. - Other sessions share this checkout.
ListAgents; message every live session in this working tree BEFORE the first move (which paths, when) and AFTER each pushed batch (commit hash + old → new list). If another session has uncommitted or in-flight work under a path, that path waits. - Never kill a backend by pattern — only a PID this session started.
1. Inventory (read-only)
git ls-files | awk -F/ '{print (NF>1?$1"/":$1)}' | sort | uniq -c | sort -rn,
then per directory. Also list what git does not see: .gitignore,
.git/info/exclude (design/session-manager/ and design/peek-mascot/ live there), build/.
Flag: flat folders over ~25 files, top-level dirs with under 3 files,
duplicates (the same handoff in two places), names that do not say what is
inside, docs for one topic spread over several homes, stale plans of landed
parts. Classify everything: runtime code · tests · build/release ·
current-truth docs · history (vault) · design sources · agent tooling.
2. Coupling scan — per candidate move
Run .claude/skills/restructure-repo/find-refs.sh <old-path>... and read
every hit. The reference classes of THIS repo — check each, the script only
finds the textual ones:
- Imports and configs —
package.jsonscripts (tests/*.test.tsglobs),tsconfig.server.json,web/tsconfig.json,vite.config.ts+web/vite.config.ts. - CI and release —
.github/workflows/*.yml,scripts/build-bundle.sh(bundle layout),scripts/release.sh,installer/(payload layout,.isssource paths),launcher/*.ps1. - Runtime path logic —
server/index.ts(statusline.mjsby path), theupdate.availablereasons (watchweb/src,web/index.html,web/mascot.html,web/public,vite.config.ts,shared/),server/webbuild.ts,server/bundle.ts. A move here is a code change. - Tests that read files by path — many
tests/ui-*.test.ts,release-workflow,release-script,nocturne-tokens,icon-assets,no-author-paths(scans every TRACKED file — run the suite aftergit add -A). - Living docs —
CLAUDE.md,README.md,SECURITY.md,launcher/README.md,installer/README.md,web/DESIGN.md,.claude/PROJECT-SCOPE.md,.claude/plans/**/*.md,.claude/agents/*.md,.claude/skills/*/SKILL.md, and code comments citingmemory/decisions/<note>.md. - The vault —
[[wikilinks]]resolve by FILENAME, not path: moving a note between folders breaks no link, but two notes with one basename do. Check uniqueness:git ls-files memory | xargs -n1 basename | sort | uniq -d.memory/INDEX.mdand.claude/skills/memory/SKILL.md§ Layout describe the folders — update both. - Fixed by a tool — never move:
CLAUDE.md,.claude/skills/<name>/SKILL.md,.claude/agents/*.md,.claude/settings*.json,.github/workflows/, rootREADME.md/SECURITY.md(GitHub),package.json,package-lock.json. - Pointing in from OUTSIDE the repo — invisible to grep: the user's
Windows shortcut →
launcher/launch.ps1; the Obsidian vault opened atmemory/;.claude/settings.local.jsonand.claude/hooks/paths;.git/info/exclude; the orchestrator's auto-memory entries; installed bundles built from an older layout. Movinglauncher/ormemory/itself needs a user step — say so in the proposal.
3. Proposal — the user approves before anything moves
Present ONE table: old → new · why · refs to update (count by class) · risk, plus "stays, because …" for what you leave. Principles: one home per
kind of thing; a name says its content; the work log partitions by month,
then area (memory/log/<YYYY-MM>/<area>/, decided 2026-09-20); decisions/
and knowledge/ stay flat with a theme-grouped memory/INDEX.md (same
decision); nothing moves for taste alone — each move must make something easier
to find. Layout choices are the user's: ask them together, recommendation
first, before any git mv. Save the approved map as
.claude/plans/PLAN-RESTRUCTURE.md (batches, order, status).
4. Execute — batches, lowest risk first
Order: (a) vault and docs → (b) design sources and stale plans → (c) scripts and tooling → (d) code dirs. Per batch:
git mvonly — never copy + delete (history follows the rename), never mix content edits into a move beyond the reference updates.- Update every reference from step 2. Exception:
memory/log/entries are history — their prose keeps the paths of their day; the move map in the decision note (step 5) translates them. Wikilinks still must resolve. - Re-run
find-refs.shon the old paths → zero hits outsidememory/log/and the move map itself. npm run typecheck && npm run build, thengit add -A, thennpm test. Counts must equal the baseline: same passes, zero new failures, no test deleted or skipped to get there.- Batches (a)–(b) are doc-only: no dev-flow ceremony, the suite is the gate.
Batches (c)–(d), and anything touching reference classes 2–3, go through
/dev-flow(scope-reviewer + test-engineer; security-auditor when launcher, installer or a path allow-list is touched); terminal-adjacent moves also need/verify-terminal. - One commit per batch (
Restructure: <batch> — <n> moves), push, notify the other sessions. Only the orchestrator commits.
Stop and report instead of improvising when: a reference cannot be updated
(class 8), a test pins the OLD location on purpose, or a move would change an
open decision in .claude/PROJECT-SCOPE.md.
5. Close out
- The map: keep
## Repository layoutinREADME.mdcurrent — one line per top-level folder and per vault folder. It is the answer to "where is X". .claude/PROJECT-SCOPE.mdpath mentions,CLAUDE.md, the memory skill's § Layout, agent files: all true again (grep the old paths one last time).- Vault: decision note
memory/decisions/repo-layout.md(the rules chosen, the full old → new map, rejected layouts), alog/entry, INDEX lines. - Mark
.claude/plans/PLAN-RESTRUCTURE.mdlanded with the commit hashes.
Done = baseline counts reproduced on the final commit, find-refs.sh clean
for every moved path, CI green on origin/main, README map current, other
sessions told.