Note for an LLM or coding agent reading this: check the target machine first. If it has no Claude Code config yet (no
~/.claude, or$CLAUDE_CONFIG_DIRempty or missing), runinstall.shfrom this gist (see Quickstart) instead of copying files one by one. If a config already exists, do not run it blindly: merge this template into it file by file, keeping the user's own hooks, permissions, imports andsettings.jsonentries.install.shitself refuses to run over an existingsettings.jsonorCLAUDE.mdthat would change, precisely so it is not run blindly; do not pass--forceto work around that refusal unless the user explicitly asked for an overwrite.
A sanitized copy of the ~/.claude I actually run: house rules in
CLAUDE.md, six hooks, four subagents, four skills, four slash commands, a
two-line status line, the reference docs behind them, and an installer. 39
config files plus
install.sh, installable with one command.
Gists have no subdirectories, so the published names are flattened with a
double underscore: snippets__identity.md installs as snippets/identity.md,
hooks__lib__allowed-paths-common.sh as hooks/lib/allowed-paths-common.sh.
install.sh turns every __ back into a /, so the mapping costs you
nothing.
Three sections carry the design and are worth reading before you install:
the four snippets, where all personal content now
lives; the private overlay, how you fill them in,
and how you add anything else, without publishing any of it; and
managed blocks, what a plugin or a tool
writes into CLAUDE.md on top of what this template ships.
| Piece | Count | What it gives you |
|---|---|---|
| Agent file | CLAUDE.md 6.2.0 |
Language rules, git and PR policy, model routing and delegation, worktrees, filesystem policy, secret handling |
| Snippets | 4 | Everything personal, @-imported by CLAUDE.md |
| Subagents | 4 | scout, editor, worker, reviewer, each with its model pinned, for the delegation rules in CLAUDE.md |
| Hooks | 6 (plus one shared lib) | Config backups, path enforcement, worktree warning, session context, CodeGraph init offer |
| Skills | 4 | pr, fj, ntfy, cheap-orchestration |
| Slash commands | 4 | /worktree-start, /worktree-finish, /ntfy, /ntfy-sub |
| Status line | 2 (plus a standalone fallback) | HUD line, then colored pwd and git info |
| Scripts | 3 | Git platform detection, desktop notifications, worktree creation |
| Reference docs | 3 (plus a guidelines seed) | Filesystem policy mechanics, shared-checkout lock protocol, separate-session rules |
| Installer | 1 | install.sh: template, then an optional private overlay, with backups |
On a fresh machine, one command:
curl -fsSL https://gist.githubusercontent.com/obeone/40e576f2db145a3ec1c100ee46b1a6bb/raw/install.sh | bashWith your private overlay installed on top (a bare gist id or any gist URL):
curl -fsSL https://gist.githubusercontent.com/obeone/40e576f2db145a3ec1c100ee46b1a6bb/raw/install.sh | bash -s -- <your-overlay-gist-id>To overwrite a machine that already has a config (see below), add --force
anywhere in the arguments:
curl -fsSL https://gist.githubusercontent.com/obeone/40e576f2db145a3ec1c100ee46b1a6bb/raw/install.sh | bash -s -- --force <your-overlay-gist-id>What install.sh does:
- Fetches the template gist, and the overlay if you gave one, with a shallow
git clone, or through the GitHub API withcurlandpython3when git is missing. Secret gists work by id, no token needed. Both are fetched before anything is written, so a wrong id leaves your config untouched. - Installs into
${CLAUDE_CONFIG_DIR:-$HOME/.claude}, turning__back into/. The overlay wins on any path both gists ship;README.mdandinstall.shthemselves are never installed. - Backs up every existing file it changes as
<file>.bak.<timestamp>, one timestamp per run. Identical files are left alone, so a re-run is cheap. - Marks hooks, scripts, HUD files and the status line executable.
CLAUDE_TEMPLATE_GIST points it at another template gist (your own fork, for
instance). It warns, without failing, when the claude CLI is not on your
PATH yet.
This is built for a fresh machine, and it enforces that. If
settings.json or CLAUDE.md already exist in the target directory and
differ from what this run would install, it refuses and exits without
writing anything, and tells you which of the two files conflict. An absent
file, or one identical to what this run would write, never trips this: a
re-run on a machine you already installed onto, or a fresh machine that
happens to share a default, both proceed. On a machine that already has a
~/.claude you care about, merge by hand instead (see
Handing this to an agent); pass --force only
when you actually want the existing file backed up and overwritten.
The same result without the script, if you prefer to see every file land:
cp -a ~/.claude "$HOME/.claude.bak.$(date +%Y%m%d-%H%M%S)" # if one exists
CLAUDE_DIR="$HOME/.claude"
GIST="https://gist.githubusercontent.com/obeone/40e576f2db145a3ec1c100ee46b1a6bb/raw"
mkdir -p "$CLAUDE_DIR"/{agents,commands,docs,guidelines,hooks/lib,hud,scripts,snippets} \
"$CLAUDE_DIR"/skills/{pr,fj,ntfy,cheap-orchestration/references}
for f in \
CLAUDE.md allowed-paths settings.json statusline-command.sh \
snippets__identity.md snippets__voice.md snippets__local-env.md \
snippets__local-skills.md \
commands__worktree-start.md commands__worktree-finish.md \
commands__ntfy.md commands__ntfy-sub.md \
agents__scout.md agents__editor.md agents__worker.md agents__reviewer.md \
hooks__backup-claude-config.sh hooks__enforce-worktree.sh \
hooks__enforce-allowed-paths.sh hooks__lib__allowed-paths-common.sh \
hooks__karpathy-guidelines.sh hooks__session-git-platform.sh \
hooks__codegraph-autoinit.sh \
scripts__git-platform-detect.sh scripts__notify.sh \
scripts__worktree-start.sh scripts__glab-ci-follow.sh \
hud__statusline-wrapper.sh hud__reposition.pl \
skills__pr__SKILL.md skills__fj__SKILL.md skills__ntfy__SKILL.md \
skills__cheap-orchestration__SKILL.md \
skills__cheap-orchestration__references__templates.md \
skills__cheap-orchestration__references__evidence.md \
docs__filesystem-policy.md docs__shared-checkout-lock.md docs__sessions.md \
guidelines__karpathy.md
do
curl -fsSL "$GIST/$f" -o "$CLAUDE_DIR/${f//__//}"
done
chmod +x "$CLAUDE_DIR/statusline-command.sh" \
"$CLAUDE_DIR/hud/statusline-wrapper.sh" \
"$CLAUDE_DIR/hud/reposition.pl" \
"$CLAUDE_DIR/hooks"/*.sh \
"$CLAUDE_DIR/hooks/lib"/*.sh \
"$CLAUDE_DIR/scripts"/*.shEither way, that drops 39 files into ~/.claude and does nothing useful yet. Go fill the
snippets, then restart Claude Code: settings and hooks are read at session
start, so nothing you just wrote applies to a session that is already open.
CLAUDE.md carries no personal content. Names, tone, machine paths, local
quirks: all of it moved into four files that CLAUDE.md pulls in from its
## Imports section, at the very top:
@~/.claude/snippets/identity.md
@~/.claude/snippets/voice.md
@~/.claude/snippets/local-env.md
@~/.claude/snippets/local-skills.md| Snippet | What belongs in it |
|---|---|
snippets/identity.md |
Your names, handles and emails, personal and professional, with the triggers that say which one applies to which project |
snippets/voice.md |
Chat language and register, the shape of messages addressed to you, the style skills to load before writing in your name, and the exact active-worktree marker line |
snippets/local-env.md |
Self-hosted git hosts and the software behind them, which repos count as yours, sibling checkout roots, directories that must never be swept, the env var the secret examples should name |
snippets/local-skills.md |
Usage notes for skills that exist only on your machine, the ones this template does not ship |
All four ship as templates full of placeholders. Filling them in is the
configuration step, not an optional polish pass: until you do, the agent
answers in the wrong language, signs commits with Your Name, and guesses
which software runs behind your git host.
A missing snippet does not announce itself. If one of the four paths has no
file behind it, you get no error message and no warning in the session, only
rules quietly absent from context, and you notice three sessions later when the
agent behaves like a stock install. snippets/local-skills.md is the one that
gets deleted, because it may legitimately hold nothing. Keep it anyway, empty
if you want. After installing, check that your own values show up in context
rather than waiting for something to fail.
This template is one half of a pair. The other half is a private gist I keep
for myself, installed on top with the same flattened __ naming this one
uses: a file at the same path overwrites what came before it, a file at a new
path is a pure addition. There is no manifest and no special format for an
overlay, it is just files, dropped on ~/.claude after this gist is already
in place.
- This public template, which lays down the whole tree with placeholders.
- Your private companion on top, same paths, overwriting.
Filling the four snippets is only the smallest thing an overlay does. It
can add anything this template does not ship at all: a whole extra skill with
its own references/ and assets/ files, a slash command, a hook, a script,
a doc, or its own complete settings.json. The mechanics differ slightly per
kind of file:
- A new skill needs nothing beyond its own files. Drop
skills__<name>__SKILL.md(plus whatever it carries underreferences/orassets/, flattened the same way) at the matching path and it is installed. IfCLAUDE.mdshould know when to reach for it, that usage note goes insnippets/local-skills.md, which your overlay ships already filled in. Nothing inCLAUDE.mditself has to change. - A new hook needs one more step: wiring into
settings.json. JSON has no import mechanism, so there is no way to append a hook entry from a second file. An overlay that adds a hook ships its own completesettings.json, carrying every entry from the public one plus its own. From then on, that file is maintained by hand on both sides: pulling an update to the publicsettings.jsonmeans re-merging it into your private copy, and adding a hook privately means remembering to carry the public entries forward too. - Anything personal you want
CLAUDE.mdto know goes in a snippet, or in a new file your overlay ships and imports with an@line placed inside one of the snippets (imports nest, sosnippets/local-env.mdcan pull in@~/.claude/snippets/work-context.md). Never editCLAUDE.mditself to add something personal, not even an import line: that is exactly the split this template exists to enforce, and it keeps your local file identical to this one outside the tool-managed blocks. - The overlay stays private by staying secret. Nothing else enforces that. Its URL is the whole of its protection, so it never gets linked from anything public: not a commit, not an issue, not another gist. If you want to see what a filled-in overlay looks like without exposing your own, read the worked example instead, not mine.
A public worked example of an overlay exists at
https://gist.github.com/obeone/838c7a016ba1f23b32ae3c8d7fcfc9e0: a fictional
persona, a backend developer who chats in German, self-hosts Gitea, and runs a
home Kubernetes cluster. It shows both things an overlay does: the four
snippets filled in, plus one extra skill this template does not ship, with its
own README explaining the install order. It carries no settings.json, since
that file cannot be made interesting without real machine detail. Every value
in it is invented, it is a demonstration, not anyone's real configuration, so
nobody should install it by mistake. To see the layering for real, install it
into a throwaway directory:
curl -fsSL https://gist.githubusercontent.com/obeone/40e576f2db145a3ec1c100ee46b1a6bb/raw/install.sh \
| CLAUDE_CONFIG_DIR="$(mktemp -d)" bash -s -- 838c7a016ba1f23b32ae3c8d7fcfc9e0Installing your own overlay, once you have one, is the same one-liner with its id (secret gists are readable by id, no token needed):
curl -fsSL https://gist.githubusercontent.com/obeone/40e576f2db145a3ec1c100ee46b1a6bb/raw/install.sh | bash -s -- <your-private-gist-id>That installs this template, then your overlay on top, in a single run.
Nothing about any of this is specific to me. Make your own secret gist, fill in the four snippets, add whatever else you want kept private, and you end up with a public base you can re-pull whenever it moves and a private layer that never leaves your account.
On a real machine, ~/.claude/CLAUDE.md stops being byte-identical to this
template the moment a plugin or a tool writes into it. Each one keeps to its
own block so it can find and replace just that block on the next update,
without touching the rest of the file:
- oh-my-claudecode writes a block at the top, between HTML-comment markers
named
OMC:STARTandOMC:END, once you runsetup omc. - CodeGraph writes a block further down, between markers named
CODEGRAPH_STARTandCODEGRAPH_END, the first time you index a repository. - RTK adds a single
@RTK.mdimport line near the end, through the same@mechanism the four snippets use, sinceRTK.mdis just another fileCLAUDE.mdpulls in.
None of that is in this template on purpose: what ships here is the plain
body, so that a real CLAUDE.md, once you strip the tool-managed blocks back
out, matches this file byte for byte. That is also the check for syncing a
machine's config back to a fresh copy of the template: diff the two, and
every difference should be either a managed block a tool put there or a
change you made on purpose, never silent drift.
Everything you must edit, in the order that matters:
| File | What ships | What to do |
|---|---|---|
snippets/identity.md |
Your Name, yourhandle, you@personal.example, Acme |
Replace both sections with your real identities and their triggers |
snippets/voice.md |
Four commented slots with examples | Write your chat language and tone, your output style, the style skills to load before writing in your name, and your worktree marker line |
snippets/local-env.md |
<your-git-username-or-org>, git.example.com, code.example.org |
Name your git hosts and the software behind each, your checkout roots, your protected directories |
snippets/local-skills.md |
One example bullet in a comment | Write one bullet per local-only skill, or leave it empty. Do not delete the file |
allowed-paths |
Comments only | Uncomment or add the directories you actually work in |
hooks/enforce-allowed-paths.sh |
[ "$(hostname -s)" = "my-workstation" ] |
Set your own hostname, or delete the guard to enforce everywhere |
scripts/git-platform-detect.sh |
CUSTOM_HOSTS with two example hosts |
List your self-hosted GitLab, Forgejo or Gitea instances |
skills/ntfy/SKILL.md |
ntfy.example.com, a placeholder envchain namespace |
Replace both, and create ~/.claude/ntfy-trust.json before arming a listener |
settings.json |
Three CUSTOMIZE markers |
A generic cluster context (admin@my-cluster) and a generic jumphost (jumphost.example.com) in autoMode: replace or remove them |
The hostname guard is the trap worth repeating: until you set it,
enforce-allowed-paths.sh exits immediately on every machine and the whole
path policy is a no-op.
Required: the Claude Code CLI,
jq (five of the shipped scripts parse hook JSON with it), python3 (three
hooks, scripts/glab-ci-follow.sh, and the installer when git is missing), curl, git, unzip.
Optional, per feature:
- Node.js 18+ for the plugins
glab, logged in, forscripts/glab-ci-follow.sh- A Nerd Font for the HUD glyphs
perlforhud/reposition.pl. Without it, status-line row 1 renders raw and unaligned; row 2 is unaffectedgh,glab,fj, depending on your git hostsalerteron macOS for actionable desktop notifications (notify --reply,--actions)- A ntfy server, the
ntfyCLI on your PATH, andenvchainto hold the token, if you keep the phone-push stack
The notify shell function, for your own terminal as much as for the agent:
echo 'source ~/.claude/scripts/notify.sh' >> ~/.zshrc # or ~/.bashrcSkill archives from my claude-skills releases, plus a markdownlint-compliance skill:
SKILLS_DIR="$HOME/.claude/skills"
for url in \
"https://github.com/obeone/claude-skills/releases/latest/download/apple-shortcuts.skill" \
"https://github.com/obeone/claude-skills/releases/latest/download/automode-config.skill" \
"https://github.com/obeone/claude-skills/releases/latest/download/dockerfile-best-practices.skill" \
"https://github.com/obeone/claude-skills/releases/latest/download/helm-bjw-s-chart.skill" \
"https://github.com/RedondoK/claude-md-skill/releases/latest/download/markdown.zip"; do
tmp=$(mktemp /tmp/skill-XXXXXX.zip)
curl -fsSL "$url" -o "$tmp"
unzip -qo "$tmp" -d "$SKILLS_DIR"
rm -f "$tmp"
donePlugins. settings.json declares five of them, all enabled; drop from
enabledPlugins whatever you skip here.
for plugin in security-guidance context7; do
claude plugin install "${plugin}@claude-plugins-official"
done
claude plugin marketplace add https://github.com/Yeachan-Heo/oh-my-claudecode.git
claude plugin install oh-my-claudecode@omc
claude plugin marketplace add mksglu/context-mode
claude plugin install context-mode@context-mode
claude plugin marketplace add openai/codex-plugin-cc
claude plugin install codex@openai-codexWith oh-my-claudecode installed, run setup omc once in a session: it injects
its managed block into CLAUDE.md, wires its own hooks, and provides the HUD
renderer that hud/statusline-wrapper.sh calls.
Git-host CLIs: glab auth login --hostname <your-gitlab> for GitLab (never put
GITLAB_TOKEN in env, it overrides the stored glab token and breaks auth),
fj auth login for Forgejo.
Six hooks, all resolved through ${CLAUDE_CONFIG_DIR:-$HOME/.claude}:
| Event | Matcher | Hook |
|---|---|---|
| PreToolUse | Edit|Write|NotebookEdit |
hooks/backup-claude-config.sh |
| PreToolUse | Edit|Write |
hooks/enforce-worktree.sh |
| PreToolUse | Read|Write|Edit|NotebookEdit |
hooks/enforce-allowed-paths.sh |
| SessionStart | (all) | hooks/karpathy-guidelines.sh |
| SessionStart | (all) | hooks/session-git-platform.sh |
| SessionStart | (all) | hooks/codegraph-autoinit.sh |
Plus statusLine, pointing at hud/statusline-wrapper.sh.
File-op path enforcement is enforce-allowed-paths.sh. The Bash side of the
same policy runs through autoMode.hard_deny in settings.json, via the
command classifier. docs/filesystem-policy.md documents both layers and their
blind spots, and they do have blind spots: an SSH command carrying a remote
path reads as local, and a shell script that the agent writes then runs is not
inspected line by line.
permissions.allow ships empty on purpose, because an allowlist is personal.
Build your own with /fewer-permission-prompts, and use the automode-config
skill for project-level autoMode blocks.
| Command | Version | What it does |
|---|---|---|
/worktree-start |
2.1.0 | Creates an isolated worktree under <project>/.claude/worktrees/<branch>, with per-repo init steps proposed before anything runs |
/worktree-finish |
1.1.0 | Merges the worktree branch back and cleans up |
/ntfy |
1.0.0 | Publishes one ntfy push |
/ntfy-sub |
1.0.0 | Starts, stops or reports a background ntfy listener |
Versions are declared inline where they exist: # Version: X.Y.Z on line 2 of
a shell file, <!-- Version: X.Y.Z --> at the top of a Markdown file, a
version: key in the frontmatter of a skill or a command. The rest of the
assets carry no marker, and this table is the only place they are tracked.
| Published file | Installs as | Version | What it is |
|---|---|---|---|
CLAUDE.md |
CLAUDE.md |
6.2.0 | The agent file: language, git policy, model routing, worktrees, filesystem policy, secret handling |
snippets__identity.md |
snippets/identity.md |
1.0.0 | Personal and professional identities |
snippets__voice.md |
snippets/voice.md |
1.0.0 | Chat language, output style, writing-in-your-name rules, worktree marker |
snippets__local-env.md |
snippets/local-env.md |
1.0.0 | Git hosts, machine paths, backup and sweep conventions |
snippets__local-skills.md |
snippets/local-skills.md |
1.0.0 | Notes for skills that exist only on your machine |
settings.json |
settings.json |
table only | Hook wiring, permissions, autoMode, plugins, status line |
allowed-paths |
allowed-paths |
table only | Global path grants for the file-op hook |
hooks__backup-claude-config.sh |
hooks/backup-claude-config.sh |
table only | Snapshots any ~/.claude file before it is overwritten, with retention pruning |
hooks__enforce-worktree.sh |
hooks/enforce-worktree.sh |
1.1.1 | Warns (without blocking) when a project file is edited outside a .claude/worktrees/ checkout |
hooks__enforce-allowed-paths.sh |
hooks/enforce-allowed-paths.sh |
1.0.1 | Allowlist on file ops, asks on violations |
hooks__lib__allowed-paths-common.sh |
hooks/lib/allowed-paths-common.sh |
table only | Shared allowlist logic and grant-file parsing |
hooks__karpathy-guidelines.sh |
hooks/karpathy-guidelines.sh |
table only | Injects the behavioral guidelines at session start, refreshed weekly from upstream |
hooks__codegraph-autoinit.sh |
hooks/codegraph-autoinit.sh |
1.0.0 | Offers codegraph init at session start in a git repo that has no .codegraph/ index; silent without the codegraph CLI |
hooks__session-git-platform.sh |
hooks/session-git-platform.sh |
table only | Exports the detected git platform into session context |
scripts__git-platform-detect.sh |
scripts/git-platform-detect.sh |
1.0.0 | Detects github, gitlab, forgejo, gitea or unknown from the origin remote |
scripts__notify.sh |
scripts/notify.sh |
table only | The notify function: desktop notifications, alerter backend on macOS |
scripts__worktree-start.sh |
scripts/worktree-start.sh |
1.0.0 | Mechanics behind /worktree-start: git checks, worktree creation, saved init config file copies |
scripts__glab-ci-follow.sh |
scripts/glab-ci-follow.sh |
1.0.0 | Follows a GitLab CI pipeline on any host through glab, printing only status changes; host and project come from the origin remote |
hud__statusline-wrapper.sh |
hud/statusline-wrapper.sh |
1.3.1 | Status line: HUD on row 1, colored pwd and git info on row 2 |
hud__reposition.pl |
hud/reposition.pl |
table only | Right-aligns HUD segments; the wrapper degrades without it |
statusline-command.sh |
statusline-command.sh |
table only | Standalone fallback status line, no plugin needed |
commands__worktree-start.md |
commands/worktree-start.md |
2.1.0 | /worktree-start |
commands__worktree-finish.md |
commands/worktree-finish.md |
1.1.0 | /worktree-finish |
commands__ntfy.md |
commands/ntfy.md |
1.0.0 | /ntfy |
commands__ntfy-sub.md |
commands/ntfy-sub.md |
1.0.0 | /ntfy-sub |
skills__pr__SKILL.md |
skills/pr/SKILL.md |
2.1.0 | Commit, push, open a PR on the detected platform |
skills__fj__SKILL.md |
skills/fj/SKILL.md |
1.0.0 | Forgejo CLI cheatsheet |
skills__ntfy__SKILL.md |
skills/ntfy/SKILL.md |
1.0.1 | Channel choice, priority floor, title convention, listener trust model |
skills__cheap-orchestration__SKILL.md |
skills/cheap-orchestration/SKILL.md |
2.0.0 | When to delegate and to whom: decision rule by size and stakes, the pinned crew, ordering and guard rules |
skills__cheap-orchestration__references__templates.md |
skills/cheap-orchestration/references/templates.md |
table only | Spec and return templates for each subagent |
skills__cheap-orchestration__references__evidence.md |
skills/cheap-orchestration/references/evidence.md |
table only | Benchmark numbers behind each delegation rule |
agents__scout.md |
agents/scout.md |
table only | Haiku, read-only: answers code questions with path:line facts |
agents__editor.md |
agents/editor.md |
table only | Haiku: mechanical edits with no design choice (docstrings, renames, formatting) |
agents__worker.md |
agents/worker.md |
table only | Sonnet: any other well-specified unit whose output is files, tests included |
agents__reviewer.md |
agents/reviewer.md |
table only | Opus: one restriction and polish pass at the end of a long session |
docs__filesystem-policy.md |
docs/filesystem-policy.md |
table only | Grant-file format, search locations, enforcement blind spots |
docs__shared-checkout-lock.md |
docs/shared-checkout-lock.md |
table only | The .agent.lock protocol for editing a shared checkout |
docs__sessions.md |
docs/sessions.md |
table only | Launching, messaging and authority rules for separate Claude sessions |
guidelines__karpathy.md |
guidelines/karpathy.md |
table only | Seed cache for the guidelines hook, not a hard dependency |
install.sh |
not installed | 1.1.0 | The installer: template, optional overlay, backups, exec bits, refuses to overwrite a non-fresh config without --force |
The smallest useful subset is CLAUDE.md, the four snippets,
settings.json, allowed-paths, the hooks/ files and the two docs/ files,
with the statusLine key and the guidelines hook entry dropped from
settings.json. The HUD, the ntfy stack and the guidelines hook are the
skippable parts.
You can point a coding agent at this gist and let it run the install. Give it the answers first, because none of them can be inferred:
- Names and emails for
snippets/identity.md, personal and professional - Chat language, tone and output style for
snippets/voice.md - Your git hosts and what runs behind them, for
snippets/local-env.mdand forCUSTOM_HOSTSinscripts/git-platform-detect.sh - The hostname of the machine where path enforcement should be active
- The directories to grant in
allowed-paths - ntfy server and topic, if you keep the notification stack
- Which optional plugins you want
On a fresh machine, have it run install.sh (with your overlay id if you
have one) and then fill the snippets. On a machine that already has a
~/.claude, tell it to merge instead of running the installer:
settings.json, CLAUDE.md and allowed-paths are the three files where a
blind overwrite costs you something real; the hooks, scripts, commands,
subagents and skills are additive and safe to drop in.
- Anything a plugin manages itself, including the managed blocks each
tool writes into
CLAUDE.md(see above). oh-my-claudecode's.mjshooks, the HUD core (hud/omc-hud.mjs,hud/find-node.sh, both called by the wrapper), and its skills. Same for whatever CodeGraph installs alongside its own block. Let each tool write its own; a hand-pasted copy drifts at the next update. - Third-party hook integrations I run locally, stripped from
settings.jsonon purpose. What remains is exactly the six hooks above. - The ntfy skill's satellites:
references/(publishing, listening, quick-replies, trust) andscripts/(ntfy-listen.sh,ntfy-buffer.py). The shippedSKILL.mdsays so and carries the load-bearing rules, so the internal links have no target and your install is fine. guidelines/karpathy.mdas a dependency. The hook fetches the current version on first run and refreshes weekly; the shipped copy only matters if that first fetch fails. Its state files land next to it (.karpathy-checked,.karpathy-refresh.log,.karpathy-last.diff).
Most of CLAUDE.md (language rules, git policy, delegation discipline,
filesystem policy, secret handling) applies to any coding agent. To port it:
mkdir -p ~/.codex/snippets # or ~/.opencode, ~/.gemini
cp ~/.claude/CLAUDE.md ~/.codex/AGENTS.md # Codex
cp ~/.claude/CLAUDE.md ~/.opencode/AGENTS.md # OpenCode
cp ~/.claude/CLAUDE.md ~/.gemini/GEMINI.md # Gemini CLI
cp ~/.claude/snippets/*.md ~/.codex/snippets/The four @ imports point at ~/.claude/snippets/, so either keep that
directory in place or rewrite the import paths in the copy. Whatever you do,
carry all four files across: the same silent absence applies here. Drop the
Claude-only assets, since settings.json, the hooks, the HUD and the slash
commands are Claude Code mechanisms. The pr and fj skills use the portable
SKILL.md format and move over fine if the agent supports skills.
Start a session and check:
- Your own name and email appear in context, not
Your Name, and your chat language and worktree marker come fromsnippets/voice.md /helplists/worktree-start,/worktree-finish,/ntfy,/ntfy-sub- Opening a session inside a repo with a remote mentions the git platform
- Editing any file under
~/.claudeleaves a snapshot in~/.claude/.backups/ - On the machine named in
enforce-allowed-paths.sh, touching a file outside the project,~/.claudeand your grants triggers a confirmation prompt ~/.claude/guidelines/gained its refresh state files after the first sessionnotify "Test" "Hello"from a fresh shell pops a desktop notification- Status line row 2 renders immediately; row 1 stays empty until
oh-my-claudecode is installed and
setup omchas run. Without it, pointstatusLineatstatusline-command.shinstead
flowchart TB
subgraph PUB["Public template (this gist)"]
A["CLAUDE.md body, docs,<br/>hooks, skills, commands"]
C["snippets/ with placeholders"]
end
subgraph PRIV["Private overlay (optional,<br/>yours, never linked)"]
D["snippets/ with real values"]
E["settings.json, replaced whole"]
F["extra skills, commands,<br/>hooks, docs, scripts"]
end
PUB -->|"install first"| H["~/.claude"]
PRIV -.->|"install on top,<br/>same __ paths"| H
H --> I["CLAUDE.md"]
I -->|"@ imports"| J["identity, voice,<br/>local-env, local-skills"]
subgraph TOOLS["Plugins and tools, at runtime"]
K["oh-my-claudecode"]
L["CodeGraph"]
M["RTK"]
end
K -->|"OMC:START / OMC:END block"| I
L -->|"CODEGRAPH_START / END block"| I
M -->|"@RTK.md import line"| I
This gist has a private counterpart, the overlay described above: the same snippet paths, my own values inside. The two are kept in sync, so expect version numbers here to move along with changes you cannot see. The only intended differences are the filled-in values, the files that stay private, and this README.
Made by Grégoire Compagnon (obeone), obeone@obeone.org