Skip to main content

Claude Code: Configuration That Works

· 6 min read
Craig P. Motlin
Software Engineer

Simon Willison wrote "I'm disappointed at how little good writing there is out there about effective prompting."

I worked hard on these prompts and think they're effective. This post covers how I configure claude using CLAUDE.md files and settings.json to control the behavior of the Claude code CLI.

This post is part of my Claude Code setup series.

Global CLAUDE.md

The global ~/.claude/CLAUDE.md file sets default behavior for claude across all projects. Mine is split into several files, with the top-level CLAUDE.md including them all using @ syntax.

Instructions for Humans

Code Style

I start with code style instructions that are applicable to LLMs and human developers.

orchestration/SKILL.md (Code Style section)
---
name: orchestration
description: Coordinates other skills and agents. ALWAYS use this skill on startup.
---

# Skill Guidelines

Invoke these skills liberally - most tasks use multiple skills:

| Skill | When to use |
| ----------------------------------- | ------------------------------------- |
| `@code:code-quality` | Before editing code |
| `@code:testing` | When writing or reviewing tests |
| `@code:cli` | When running shell commands |
| `@build:precommit` | Before running builds or tests |
| `@git:git-workflow` | For all git operations |
| `@orchestration:conversation-style` | For response guidelines |
| `@orchestration:llm-context` | When working with `.llm/` directories |

## Git Commits

**ALWAYS** delegate to the `@git:commit-handler` agent for all commit operations. Never run `git commit` directly.

**ALWAYS** delegate to the `@git:conflict-resolver` agent to resolve any git merge or rebase conflicts.

**ALWAYS** delegate to the `@git:rebaser` agent to rebase the current branch on upstream.

## Workflow Orchestration

When a code change is ready, and we are about to return control to the user, do these things in order:

1. Verify the build passes using the `@build:precommit-runner` agent
2. Commit to git using the `@git:commit-handler` agent
3. Rebase on top of the upstream branch with the `@git:rebaser` agent

## Plugin Health Check

Run the master doctor script to verify all plugins are properly configured:

```bash
${CLAUDE_PLUGIN_ROOT}/../orchestration/scripts/doctor-all.sh
```

This runs `doctor.sh` from each plugin, checking for:

- Required binaries (just, git, gh, python3, tmux, etc.)
- Required files and scripts
- Proper file permissions

View on GitHub

Instructions specific to LLMs

Testing Practices

When writing tests, LLMs remind me of Mr. Meeseeks. The LLM will go to any length to get tests to pass, including deleting all of the assertions.

The advice here is applicable to human developers too, but we're getting into LLM quirks now.

orchestration/SKILL.md (Testing Philosophy section)
---
name: orchestration
description: Coordinates other skills and agents. ALWAYS use this skill on startup.
---

# Skill Guidelines

Invoke these skills liberally - most tasks use multiple skills:

| Skill | When to use |
| ----------------------------------- | ------------------------------------- |
| `@code:code-quality` | Before editing code |
| `@code:testing` | When writing or reviewing tests |
| `@code:cli` | When running shell commands |
| `@build:precommit` | Before running builds or tests |
| `@git:git-workflow` | For all git operations |
| `@orchestration:conversation-style` | For response guidelines |
| `@orchestration:llm-context` | When working with `.llm/` directories |

## Git Commits

**ALWAYS** delegate to the `@git:commit-handler` agent for all commit operations. Never run `git commit` directly.

**ALWAYS** delegate to the `@git:conflict-resolver` agent to resolve any git merge or rebase conflicts.

**ALWAYS** delegate to the `@git:rebaser` agent to rebase the current branch on upstream.

## Workflow Orchestration

When a code change is ready, and we are about to return control to the user, do these things in order:

1. Verify the build passes using the `@build:precommit-runner` agent
2. Commit to git using the `@git:commit-handler` agent
3. Rebase on top of the upstream branch with the `@git:rebaser` agent

## Plugin Health Check

Run the master doctor script to verify all plugins are properly configured:

```bash
${CLAUDE_PLUGIN_ROOT}/../orchestration/scripts/doctor-all.sh
```

This runs `doctor.sh` from each plugin, checking for:

- Required binaries (just, git, gh, python3, tmux, etc.)
- Required files and scripts
- Proper file permissions

View on GitHub

Rhetorical questions?

Sometimes I ask claude why it implemented a feature one way and not another and it answers "You're right! I'll implement it <the other way>." Infuriating!

GPT-4o had a now-famous bug that made it "overly supportive but disingenuous." It's "fixed," but all models can trend toward sycophancy.

Tackling these these together:

orchestration/SKILL.md (Conversation Style section)
---
name: orchestration
description: Coordinates other skills and agents. ALWAYS use this skill on startup.
---

# Skill Guidelines

Invoke these skills liberally - most tasks use multiple skills:

| Skill | When to use |
| ----------------------------------- | ------------------------------------- |
| `@code:code-quality` | Before editing code |
| `@code:testing` | When writing or reviewing tests |
| `@code:cli` | When running shell commands |
| `@build:precommit` | Before running builds or tests |
| `@git:git-workflow` | For all git operations |
| `@orchestration:conversation-style` | For response guidelines |
| `@orchestration:llm-context` | When working with `.llm/` directories |

## Git Commits

**ALWAYS** delegate to the `@git:commit-handler` agent for all commit operations. Never run `git commit` directly.

**ALWAYS** delegate to the `@git:conflict-resolver` agent to resolve any git merge or rebase conflicts.

**ALWAYS** delegate to the `@git:rebaser` agent to rebase the current branch on upstream.

## Workflow Orchestration

When a code change is ready, and we are about to return control to the user, do these things in order:

1. Verify the build passes using the `@build:precommit-runner` agent
2. Commit to git using the `@git:commit-handler` agent
3. Rebase on top of the upstream branch with the `@git:rebaser` agent

## Plugin Health Check

Run the master doctor script to verify all plugins are properly configured:

```bash
${CLAUDE_PLUGIN_ROOT}/../orchestration/scripts/doctor-all.sh
```

This runs `doctor.sh` from each plugin, checking for:

- Required binaries (just, git, gh, python3, tmux, etc.)
- Required files and scripts
- Proper file permissions

View on GitHub

Long-lived processes

claude handles console output from linters and compiler well. But sometimes it will try to run a long-lived command like npm run start and basically hang.

orchestration/SKILL.md (Workflow Orchestration section)
---
name: orchestration
description: Coordinates other skills and agents. ALWAYS use this skill on startup.
---

# Skill Guidelines

Invoke these skills liberally - most tasks use multiple skills:

| Skill | When to use |
| ----------------------------------- | ------------------------------------- |
| `@code:code-quality` | Before editing code |
| `@code:testing` | When writing or reviewing tests |
| `@code:cli` | When running shell commands |
| `@build:precommit` | Before running builds or tests |
| `@git:git-workflow` | For all git operations |
| `@orchestration:conversation-style` | For response guidelines |
| `@orchestration:llm-context` | When working with `.llm/` directories |

## Git Commits

**ALWAYS** delegate to the `@git:commit-handler` agent for all commit operations. Never run `git commit` directly.

**ALWAYS** delegate to the `@git:conflict-resolver` agent to resolve any git merge or rebase conflicts.

**ALWAYS** delegate to the `@git:rebaser` agent to rebase the current branch on upstream.

## Workflow Orchestration

When a code change is ready, and we are about to return control to the user, do these things in order:

1. Verify the build passes using the `@build:precommit-runner` agent
2. Commit to git using the `@git:commit-handler` agent
3. Rebase on top of the upstream branch with the `@git:rebaser` agent

## Plugin Health Check

Run the master doctor script to verify all plugins are properly configured:

```bash
${CLAUDE_PLUGIN_ROOT}/../orchestration/scripts/doctor-all.sh
```

This runs `doctor.sh` from each plugin, checking for:

- Required binaries (just, git, gh, python3, tmux, etc.)
- Required files and scripts
- Proper file permissions

View on GitHub

Sometimes Claude still tries to run long-lived commands so I've started to explicitly deny them.

src/.claude-prompts/settings.json (deny section)
{
"permissions": {
"deny": [
"Bash(git add --all:*)",
"Bash(git add --force:*)",
"Bash(git add -A:*)",
"Bash(git add -f:*)",
"Bash(git commit -a:*)",
"Bash(git push:*)",
"Bash(git reset --hard:*)",
"Bash(git worktree remove --force:*)",
"Bash(npm i --global:*)",
"Bash(npm i -g:*)",
"Bash(npm install --global:*)",
"Bash(npm install -g:*)",
"Bash(npm run dev:*)",
"Bash(npm run serve:*)",
"Bash(npm run start &)",
"Bash(npm run start:*)",
"Bash(op)",
"Bash(op:*)",
"Bash(rm -rf:*)",
"Edit(CLAUDE.md)",
"Edit(~/.claude/settings.json)",
"MultiEdit(CLAUDE.md)",
"MultiEdit(~/.claude/settings.json)",
"Write(CLAUDE.md)"
]
}
}

Extra context just for you

claude can search the internet, and can read files from outside the current git repository, but it's an extra hop. I find it convenient to gather files into a subdirectory just for the LLM.

orchestration/SKILL.md (LLM Context section)
---
name: orchestration
description: Coordinates other skills and agents. ALWAYS use this skill on startup.
---

# Skill Guidelines

Invoke these skills liberally - most tasks use multiple skills:

| Skill | When to use |
| ----------------------------------- | ------------------------------------- |
| `@code:code-quality` | Before editing code |
| `@code:testing` | When writing or reviewing tests |
| `@code:cli` | When running shell commands |
| `@build:precommit` | Before running builds or tests |
| `@git:git-workflow` | For all git operations |
| `@orchestration:conversation-style` | For response guidelines |
| `@orchestration:llm-context` | When working with `.llm/` directories |

## Git Commits

**ALWAYS** delegate to the `@git:commit-handler` agent for all commit operations. Never run `git commit` directly.

**ALWAYS** delegate to the `@git:conflict-resolver` agent to resolve any git merge or rebase conflicts.

**ALWAYS** delegate to the `@git:rebaser` agent to rebase the current branch on upstream.

## Workflow Orchestration

When a code change is ready, and we are about to return control to the user, do these things in order:

1. Verify the build passes using the `@build:precommit-runner` agent
2. Commit to git using the `@git:commit-handler` agent
3. Rebase on top of the upstream branch with the `@git:rebaser` agent

## Plugin Health Check

Run the master doctor script to verify all plugins are properly configured:

```bash
${CLAUDE_PLUGIN_ROOT}/../orchestration/scripts/doctor-all.sh
```

This runs `doctor.sh` from each plugin, checking for:

- Required binaries (just, git, gh, python3, tmux, etc.)
- Required files and scripts
- Proper file permissions

View on GitHub

These instructions work well. Though I'm deliberate about telling the LLM to look in .llm/.

// Too Many Comments

LLMs write obvious comments.

// Calculate elapsed time
const elapsedTimeMs = Date.now() - startTime

Here are my instructions telling Claude not to, but it really, really likes writing comments. The built-in system prompt flat out says "Do not add comments to the code you write" and that doesn't work either.

orchestration/SKILL.md (Code Style section)
---
name: orchestration
description: Coordinates other skills and agents. ALWAYS use this skill on startup.
---

# Skill Guidelines

Invoke these skills liberally - most tasks use multiple skills:

| Skill | When to use |
| ----------------------------------- | ------------------------------------- |
| `@code:code-quality` | Before editing code |
| `@code:testing` | When writing or reviewing tests |
| `@code:cli` | When running shell commands |
| `@build:precommit` | Before running builds or tests |
| `@git:git-workflow` | For all git operations |
| `@orchestration:conversation-style` | For response guidelines |
| `@orchestration:llm-context` | When working with `.llm/` directories |

## Git Commits

**ALWAYS** delegate to the `@git:commit-handler` agent for all commit operations. Never run `git commit` directly.

**ALWAYS** delegate to the `@git:conflict-resolver` agent to resolve any git merge or rebase conflicts.

**ALWAYS** delegate to the `@git:rebaser` agent to rebase the current branch on upstream.

## Workflow Orchestration

When a code change is ready, and we are about to return control to the user, do these things in order:

1. Verify the build passes using the `@build:precommit-runner` agent
2. Commit to git using the `@git:commit-handler` agent
3. Rebase on top of the upstream branch with the `@git:rebaser` agent

## Plugin Health Check

Run the master doctor script to verify all plugins are properly configured:

```bash
${CLAUDE_PLUGIN_ROOT}/../orchestration/scripts/doctor-all.sh
```

This runs `doctor.sh` from each plugin, checking for:

- Required binaries (just, git, gh, python3, tmux, etc.)
- Required files and scripts
- Proper file permissions

View on GitHub

I've come to accept that comments are crucial to how LLMs "think" and I cannot stop the LLM from writing them, at least in the first draft. My comment cleanup commands are great at getting rid of them in a second step.

Claude's Commit messages

Claude code's commit messages are remarkably consistent, to the point where you know what the system prompt is going to say before you read it.

The system prompt includes inconsistent and incorrect information about pre-commit hooks and staging changes, so I give my own corrections.

orchestration/SKILL.md (Workflow Orchestration section)
---
name: orchestration
description: Coordinates other skills and agents. ALWAYS use this skill on startup.
---

# Skill Guidelines

Invoke these skills liberally - most tasks use multiple skills:

| Skill | When to use |
| ----------------------------------- | ------------------------------------- |
| `@code:code-quality` | Before editing code |
| `@code:testing` | When writing or reviewing tests |
| `@code:cli` | When running shell commands |
| `@build:precommit` | Before running builds or tests |
| `@git:git-workflow` | For all git operations |
| `@orchestration:conversation-style` | For response guidelines |
| `@orchestration:llm-context` | When working with `.llm/` directories |

## Git Commits

**ALWAYS** delegate to the `@git:commit-handler` agent for all commit operations. Never run `git commit` directly.

**ALWAYS** delegate to the `@git:conflict-resolver` agent to resolve any git merge or rebase conflicts.

**ALWAYS** delegate to the `@git:rebaser` agent to rebase the current branch on upstream.

## Workflow Orchestration

When a code change is ready, and we are about to return control to the user, do these things in order:

1. Verify the build passes using the `@build:precommit-runner` agent
2. Commit to git using the `@git:commit-handler` agent
3. Rebase on top of the upstream branch with the `@git:rebaser` agent

## Plugin Health Check

Run the master doctor script to verify all plugins are properly configured:

```bash
${CLAUDE_PLUGIN_ROOT}/../orchestration/scripts/doctor-all.sh
```

This runs `doctor.sh` from each plugin, checking for:

- Required binaries (just, git, gh, python3, tmux, etc.)
- Required files and scripts
- Proper file permissions

View on GitHub

I didn't expect this to work since it contradicts the system prompt, but it works fine. I hope the system prompt gets fixed upstream anyway.

Project-specific CLAUDE.md

You can override global settings for a specific project by creating a CLAUDE.md and CLAUDE.local.md in the root of that project. The first is intended to be committed and the second is intended to be ignored.

I don't want to assume my teammates use a specific tool like Claude, so I never create project-specific CLAUDE.md files. I don't even want the word Claude to appear in .gitignore so instead I ignore the file with:

echo CLAUDE.local.md >> .git/info/exclude

I hope a standard emerges. I would be willing to check in a file called LLM.md.

The contents of CLAUDE.local.md vary. It's a good place to share:

  • What the build tool is, and which commands to run before committing.
  • Libraries to use and APIs to prefer.
  • Whether to use a justfile or the language-native build tool.

Next Steps

Now that you've seen how to configure Claude Code's behavior, check out my development workflow in Workflow Commands and my additional Utility Commands.