One repository that wraps all local agent work: global agent rules,
skills, guidelines, memory, and a projects/ directory that holds every
project checkout. Clone this repo on a new machine and you have the
whole setup; project code re-clones on demand from each project's
manifest.
Agent- and model-agnostic by construction: every major agent CLI
(opencode, Codex, Gemini, ...) discovers AGENTS.md by walking up the
directory tree, so any session launched under projects/ inherits the
global rules. Claude Code reads the same file through the one-line
CLAUDE.md shim.
This repository is designed to be a GitHub template. To create your own control center:
- Click "Use this template" on GitHub (or fork/copy the files).
- Clone your new repo anywhere you like — the conventional location is
~/projects/agent-control-center, but nothing depends on it. - Run
./bin/bootstrap.sh --name <name>. The name identifies this center in~/.config/agent-control-center/centers/and must be unique per machine. It also gets written to the committed.control-centerfile, so every machine that clones this center uses the same name. - Make it yours: edit
guidelines/to your taste, and adjustAGENTS.mdif your machine-sharing or commit rules differ.
You can run several centers on one machine (say, work and
personal), each created from this template with its own name:
- Resolution is contextual. Skills and scripts resolve "which
center am I in" by walking up from the current directory to the
nearest
.control-centermarker that is registered in~/.config/agent-control-center/centers/. Unregistered markers are skipped — a clone of this template under a project'scode/tree must not capture the walk-up. The registry's default center (set withbootstrap.sh --default, shown in~/.config/agent-control-center/default) is used only for sessions outside every registered center. - Guards compose. Every registered center's path guard runs in every session, so worktrees in all centers stay protected no matter where you work.
- Global rule imports go to the default center only (
~/.claude/CLAUDE.mdand opencode's globalAGENTS.md). A session inside a non-default center still gets that center's rules through normalAGENTS.mddirectory walk-up. - Sync covers all centers. Session hooks pull and push every registered center's docs.
git clone <your-control-center-remote> ~/projects/agent-control-center
cd ~/projects/agent-control-center
./bin/bootstrap.sh # checks deps, registers the center, wires hooks + links (idempotent)The name travels in the committed .control-center file, so no
--name is needed on additional machines.
Then, in any agent session: /resume-project to pick up existing work,
or /start-project to begin something new.
| Path | Committed | Purpose |
|---|---|---|
AGENTS.md |
yes | Global rules every agent session inherits |
guidelines/ |
yes | Writing and coding guidelines |
skills/ |
yes | Lifecycle skills: start / resume / finish project |
memory/ |
yes | Global memory (INDEX.md + topic files) |
templates/ |
yes | PROJECT.md, handoff, notes templates |
bin/ |
yes | Scripts: worktrees, branch status, path guard, sync, bootstrap |
projects/INDEX.md |
yes | Registry of all projects |
projects/<slug>/ |
yes | Manifest, handoffs, notes — the durable record |
projects/<slug>/code/ |
no | Clones + worktrees — disposable, rebuilt from manifest |
- /start-project — asks for a name and repos (or a project to
extend), scaffolds the project directory from templates, blobless-clones
each repo into
code/<repo>/main, registers it inprojects/INDEX.md. - /resume-project — pulls this repo first (latest handoffs from any
machine), reads the manifest + handoffs + notes, reconciles
code/(re-clones anything missing), verifies each active handoff's branch against git/PR state (bin/branch-status) and marks shipped work done, then summarizes. Continues a task's Next Steps only when the task is named:/resume-project <task>. - /finish-project — refuses to run if any worktree has uncommitted or
unpushed work; distills handoffs into the PROJECT.md outcome; promotes
durable learnings to global memory; deletes
code/; marks the project done.
Worktrees are created per task with bin/wt-new <repo> <task-slug>. It
binds the task's handoff to the new worktree (frontmatter repo,
branch, worktree) and heals a legacy worktree: none binding. A
handoff without a worktree: key is unbound — normal for setup and
docs-only tasks.
Agents working in the wrong worktree is the failure mode this repo is built against. Three layers:
- Layout — each project's checkouts live under its own
code/directory; wrong siblings are not onecd ..away. - Instruction —
AGENTS.mdworkspace rules (writes scoped to your project, repo-relative paths in docs,mainis read-only). - Mechanical —
bin/guard-path.shscopes writes to the current project's worktrees and blocks any file operation that resolves into another project'scode/tree, wired as a Claude Code PreToolUse hook and an opencodetool.execute.beforeplugin. In bash commands it vets both absolute and relative paths, and treats paths in mutating commands (rm,mv,sed -i, redirects, …) as writes, socode/<repo>/mainstays a read-only reference. The project is taken from the session's working directory, so a session may span its project's worktrees without relaunching.
bin/sync.sh keeps the remote current: pull at session start, push
(scoped to projects/ + memory/ docs only) at session end, both wired
via hooks by bootstrap.sh. A lock directory prevents concurrent
sessions from racing.
Claude Code allow rules cannot match a command wrapped in a variable
assignment (CC=$(...)), and every subcommand of a compound command
must match a rule on its own. The skills therefore run the resolver
bare, and two layers ship the rules:
.claude/settings.json(committed) allows the resolver for every session rooted in a center repo.link.shmerges per-machine allow rules for routine helper commands (wt-ls,wt-new, barewt-prunedry run,sync.sh pull) of every registered center into~/.claude/settings.json.
Mutating forms (wt-prune --apply, sync.sh push) still prompt on
purpose.