Setting Up Agentic Coding Assistants for Your Team
At Willow, we recently configured our codebase for Claude Code. This post covers our setup and the key decisions we made.
The Challenge
When working with AI coding assistants, the default experience is generic. The assistant doesn't know your team's conventions, coding style, or workflows. Every session starts from scratch, and you end up repeating the same instructions.
We wanted an assistant that:
- Understands our coding conventions from day one
- Follows the same review standards we apply to human contributors
- Automates repetitive git workflows
- Integrates with our tools (GitHub, Slack, Notion)
Our Setup
The configuration lives in a few key locations:
├── CLAUDE.md # Coding guidelines
├── .claude/
│ └── commands/ # Slash commands
│ ├── commit.md
│ ├── review.md
│ ├── pr.md
│ ├── new-feature.md
│ └── release-notes.md
├── .agent/
│ └── .env.example # Integration credentials templateCLAUDE.md: Teaching Your Coding Style
The CLAUDE.md file at the root of your repository is automatically read by Claude Code. It becomes part of the system context for every conversation. We use it to encode our team's coding standards.
Our CLAUDE.md covers 22 guidelines including:
- Import organization - External imports first, then internal. Prefer namespace imports for cohesive modules.
- Naming conventions - Use domain-correct names with units where relevant (
ttlSeconds, nottimeToLife). - Function signatures - Options objects over long parameter lists.
- Error handling - Validate early, fail fast, catch only where you add value.
- Logging - Structured, grammatical messages with actionable context.
- Testing - Deterministic, isolated tests that assert observable behavior.
- Date/time handling - Use millisecond timestamps internally, moment-timezone only for calendar-aware operations.
Each guideline includes Do and Don't code examples:
// Do:
const ttlSeconds = isProd ? 30 * 24 * 60 * 60 : 60
// Don't:
const timeToLife = isProd ? 2592000 : 60The key insight: these aren't arbitrary rules. They're patterns extracted from hundreds of real PR reviews on our codebase. We used codestyle to analyze our merged PRs and generate these guidelines automatically.
Slash Commands: Automating Workflows
Claude Code supports custom slash commands in .claude/commands/. Each .md file becomes a command you can invoke with /command-name.
/commit - Pre-commit Checklist
Before committing, developers (human or AI) can run /commit to do a quick self-check. It covers:
- Diffs focused (no whitespace churn)?
- Imports organized correctly?
- Domain-correct naming?
- Error handling with actionable logging?
- Tests added for new behavior?
This catches the "obvious" PR comments before they happen.
/review - Code Review Checklist
The /review command provides a comprehensive review checklist. Beyond the style items from /commit, it includes:
- Section 1: Style Checklist - All the formatting and convention checks
- Section 2: Implicit Decisions - Surfaces architectural decisions that might be implicit in the code
The implicit decisions section is particularly valuable. It asks reviewers to identify choices like:
- Data structure decisions
- Sync vs async approaches
- Where logic lives (controller vs service)
- Error handling strategy
- Test strategy
For each decision, we document the alternatives that could have been chosen and the tradeoffs.
/pr - Pull Request Creation
The /pr command automates the full PR workflow:
- Checks for uncommitted changes
- Merges latest
developinto the branch (catching conflicts early) - Pushes the branch if needed
- Analyzes commits to suggest a PR title and description
- Creates the PR via
ghCLI - Adds all team members as reviewers
- Sends a Slack notification with @mentions
The Slack integration maps GitHub usernames to Slack user IDs for proper mentions:
# .agent/.env
SLACK_USER_alice=U012AB3CD4E
SLACK_USER_bob=U056FG7HI8J/new-feature - Branch Creation
The /new-feature command handles the start of a new feature:
- Checks current state and uncommitted changes
- Asks for branch name (suggesting
feature/<name>orfix/<name>format) - Offers to branch from
develop(recommended) or current branch - Handles stashing/committing uncommitted changes
- Optionally pushes and sets upstream
/release-notes - Notion Integration
The /release-notes command generates release notes for non-technical users:
- Fetches recent merges to
main - Compares with existing Notion entries to find gaps
- Analyzes diffs to understand actual changes
- Generates user-friendly descriptions (no jargon like "API", "refactor", "component")
- Creates entries in our Notion release notes database
The descriptions focus on user impact: "You can now..." or "Fixed an issue where..." rather than "Refactored the service layer to use..."
Integration Credentials
We use .agent/.env (gitignored) for integration credentials, with .agent/.env.example committed as a template:
# Notion Integration for release-notes skill
NOTION_API_KEY=secret_...
NOTION_RELEASE_NOTES_DATABASE_ID=your_database_id_here
# Slack Integration for pr skill
SLACK_USER_TOKEN=xoxp-...
SLACK_ENGINEERING_CHANNEL_ID=C012ABC3DEFWhat We Learned
Guidelines must be specific and actionable. Vague rules like "write clean code" don't help. Concrete examples with Do/Don't comparisons work much better.
Extract patterns from real history. Our guidelines came from analyzing actual PR feedback, not from imagining what good code looks like. This grounded them in real team practices.
Automate the tedious parts. The /pr and /release-notes commands save significant time on repetitive tasks. The AI handles the boilerplate; we handle the decisions.
Integration matters. Connecting to Slack and Notion made the tools part of our actual workflow, not a separate step.
Coming soon: How these tools are working for us in practice.