· claude-code · pm-workflow · ai-agents

Scaffolding for Claude Code

Four pieces of scaffolding I've built around Claude Code to turn one-off sessions into consistent work. A docs tree, a dotfiles repo, a skills layer, and a preview loop.

Working with Claude Code is the difference between having a smart coworker and having a smart coworker who shows up on day one, every day, forever. The sessions are powerful. They’re also stateless. Last Tuesday’s conventions, decisions, and context all vanish the moment I close the terminal.

So I’ve been building scaffolding. Not the agent itself, because that’s Anthropic’s job, and they’re doing it. The scaffolding is the layer between me and the agent that turns a one-off session into something that feels like consistent work. Four pieces are doing most of the work right now.

A docs layer my agents read from, a dotfiles repo that keeps the global layer portable, a skills layer that encodes my deliverables, and a preview loop between Claude’s output and my eyeballs.

Docs as the system of record

Every project I run through Claude Code has a docs/ directory. Inside it:

  • role.md: who I am, what I own, who my stakeholders are
  • golden-principles.md: my writing and output preferences, auto-updated from feedback
  • domains/*.md: per product area, current state, about 200 lines each
  • projects/*.md: per active project, the context that isn’t obvious from the code
  • decisions/, references/, repos/: the long tail

The point isn’t that I could write all of these without Claude. The point is that the agent is useless without them. When I ask for a PRD and the agent doesn’t know what our platform looks like, the output reflects that. When the agent knows, the output is usable on the first pass.

I treat docs/ the way the company treats its production database. It’s canon. Claude Code does the writing. I do the reviewing. Every change gets read deliberately before it lands, and that’s the part that keeps the tree accurate.

Dotfiles as the substrate

Docs are per-project. Everything else in the scaffolding isn’t.

My first pass was keeping it all in one repo anyway. The PM workspace had its own .claude/skills/, its own rules files, its own CLAUDE.md, all tuned to how I was working that month. It felt tidy. It wasn’t.

The problem showed up every time I switched projects. I’d open a new repo, and Claude Code wouldn’t know who I was. The voice I’d spent weeks tuning didn’t travel. The commit conventions I’d encoded in a skill weren’t available. Every new project was a cold start, and every time I corrected something in one place it stayed there.

The fix is a single dotfiles repo. Everything I want portable gets committed to ~/dotfiles/ and symlinked into its machine-global runtime location by a setup script. The Claude Code skills directory. The shell rc files. The CLAUDE.md rules. The launch.json. One git clone and a ./setup.sh away from being live on a fresh machine. More to the point, available from inside any project I open.

Nothing fancy. The dotfiles pattern is decades old. What’s new is that the stuff I’m committing is agent behavior: voice rules, slash commands, preference files that shape every Claude session I run. When I teach the agent something, the teaching gets versioned with my shell prompt and my vim config. It ships with me.

Skills as the interface to deliverables

Two kinds of skills live on my machine. The global ones come from dotfiles and cover the work I do regardless of project: /write-voice, /write-prd, /one-pager, /experiment-template, /start, /commit, /shepherd. They travel with me. Project skills live inside specific repos and encode conventions that only make sense there. The repo behind my Slack agent has its own set tuned to how that agent handles memory writes. Other repos have their own.

The split matters because my defaults change at different speeds than my projects. Voice rules shift maybe twice a year. A repo’s deployment pattern shifts every few weeks. Keeping them separate means I can edit one without dragging the other along.

There’s a separate question of where the skill came from in the first place. Public skill directories exist, and they’re useful as starting points for common patterns like PR reviews or standard document templates. But the skills that actually change my output aren’t the ones I downloaded. They’re the ones shaped to how I specifically work. A /sync that encodes the particular meeting shape my team runs. A /health-check that knows which corners of my docs tree tend to go stale. A /publish-confluence that handles the specific macros our team uses. Downloaded skills cover a baseline. The ones I’ve built compound.

The more interesting thing is how those skills get built. I don’t sit down and write them from scratch. I notice a correction. The fifth time I ask Claude to undo the same kind of polish, I open a conversation with the agent about it. “Every time you draft a post, you do X. Let’s encode that. What would the skill look like?” Claude drafts. I edit. I commit. The next session stops doing X.

That feedback loop is the point. The skills layer isn’t a prompt library I maintain by hand. It’s a record of corrections I’ve already made, written in a form the agent picks up automatically on the next session. The time from “I need to write X” to “X is shared with stakeholders” dropped from days to hours the week I started building skills this way.

dev-overlay: closing the preview loop

Writing docs and triggering skills handles text work. Visual work, such as slides, HTML prototypes, rendered markdown, was still a round trip. I’d ask Claude to build a prototype, open the HTML in a browser, squint at it, come back to the terminal, describe what was wrong in words, wait for the rewrite. A lot of time got lost in that translation.

I built a tool called dev-overlay to collapse it. It’s a portable dev loop with three modes:

webapp serves any HTML or JSX prototype with a comment toolbar injected at the top. Click any element on the page, leave a note. The comment streams back to Claude’s terminal as a notification.

markdown renders .md files with a side-by-side editor, live preview, and per-line comments that survive edits.

reveal serves reveal.js decks with slide-aware comments and auto-loads data/*.json at render time so a deck can reference a chart or a table without a build step.

All three modes emit comments in the same format, stream to the same comments/inbox.jsonl, and plug into the same Claude Code Monitor. One loop, three surfaces. I sit in Claude Code, say “start the dev loop,” and the skill spins up the right mode for whatever I’m building.

The point isn’t the features. The point is that a piece of Claude’s output lands in front of me, I click the spot where something’s wrong, I type a sentence, and Claude sees it without me switching contexts. The friction that used to sit between drafts vanished.

What ties the pieces together

The four layers share one principle. The state of my work lives in files I control, and the agent reads those files on demand. No custom memory layer, no server, no “prompt library” I maintain by hand. Everything is markdown in git. Everything is re-readable by the next session. Everything is versioned.

The rest of the scaffolding is smaller. Worktrees so I can run four sessions in parallel on different branches. A golden-principles.md that auto-updates when I correct the same mistake twice. A reflect skill that scans my recent work and flags where the platform needs sharpening.

Summary

  • Docs are the agent’s system of record. A docs/ tree the agent reads from on every session. Claude writes. I review.
  • Dotfiles are the substrate. One repo, symlinked into place, carrying global skills, CLAUDE.md, rules, dev-overlay, and shell config. Clone and setup on a new machine in ten minutes.
  • Skills split into two layers. Global in dotfiles for work I do everywhere. Project-specific in each repo for local conventions. Most of them Claude helped write.
  • dev-overlay closes the visual loop. Three modes, one format, comments stream back to Claude as notifications. Point-and-comment replaces describe-and-wait.
  • The state of my work lives in files I control. Markdown in git, re-readable by every session, versioned, committed to dotfiles. No opaque memory layer.

None of this is finished. The docs are always a little stale. Some skills haven’t been touched in a month because they’ve drifted from my current workflow. dev-overlay has bugs I only notice when I’m using it for real work. But the scaffolding holds the shape, and the shape is what lets a one-off session turn into consistent work over time.