staghorn

module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 13, 2026 License: MIT

README

Staghorn

A shared team layer for Claude Code.

Staghorn syncs your team's shared CLAUDE.md guidelines from GitHub and merges them with your personal preferences. It writes the result to ~/.claude/CLAUDE.md so Claude Code automatically picks it up.

Why Staghorn?

Without staghorn, teams copy-paste shared guidelines or use git submodules. With staghorn:

  • Team guidelines live in one place — A GitHub repo your team owns
  • Personal preferences layer on top — Your coding style, verbosity settings, etc.
  • One command to updatestag sync

Quick Start

# 1. Install
brew install staghorn

# 2. Set up (one time)
stag init

# 3. Sync and apply team config
stag sync

That's it. Claude Code now uses your team's guidelines plus your personal preferences.

How It Works

Staghorn manages CLAUDE.md files at all levels:

Team config (from GitHub)     ─┐
                               ├─► ~/.claude/CLAUDE.md (global)
Personal additions (optional) ─┘

.staghorn/project.md          ─► ./CLAUDE.md (per-project)

You never need to edit the output files directly - Staghorn manages them.

Commands

Command Description
stag init Set up staghorn (team repo, authentication)
stag sync Fetch and apply team config from GitHub
stag edit Edit personal config (auto-applies on save)
stag info Show current config state
stag languages Show detected and configured languages
stag actions List actions or show info for a specific action
stag run <action> Run an action (outputs prompt to stdout)
stag project Manage project-level config (see below)
Typical Workflow
# Update config (do this periodically)
stag sync

# Check current state
stag info

# Add personal preferences (auto-applies)
stag edit
Power User Flags
stag sync --fetch-only     # Fetch without applying
stag sync --apply-only     # Apply cached config without fetching
stag sync --force          # Re-fetch even if cache is fresh
stag edit --no-apply       # Edit without auto-applying
stag info --content        # Show full merged config
stag info --layer team     # Show only team config

Adding Personal Preferences

Your personal additions layer on top of team guidelines:

# Open your personal config in $EDITOR (auto-applies on save)
stag edit

This opens ~/.config/staghorn/personal.md. Add whatever you like:

## My Preferences

- I prefer concise responses unless I ask for detail
- Always use TypeScript strict mode
- Explain your reasoning before showing code

Language-Specific Config

Staghorn supports separate configuration files for each programming language, in addition to the shared config that applies to all projects.

Shared vs Language-Specific

Your main config files (CLAUDE.md, personal.md, project.md) are shared — they apply to every project regardless of language. Language-specific configs add guidelines that only apply when that language is detected:

Shared config (always applied)
├── Team CLAUDE.md
├── Personal personal.md
└── Project project.md

Language configs (appended when language is active)
├── python.md   ← only if Python detected
├── go.md       ← only if Go detected
└── etc.
flowchart TB
    subgraph shared["Shared Config (always applied)"]
        T1[Team CLAUDE.md] --> M[Merged Output]
        P1[Personal personal.md] --> M
        PR1[Project project.md] --> M
    end

    subgraph lang["Language Configs (when detected)"]
        T2[Team languages/*.md] --> L[Language Section]
        P2[Personal languages/*.md] --> L
        PR2[Project languages/*.md] --> L
    end

    M --> OUT["~/.claude/CLAUDE.md"]
    L --> OUT

This lets you keep general guidelines (code review process, commit style, etc.) separate from language-specific rules (use pytest, prefer f-strings, etc.).

How It Works

Language configs are markdown files named by language ID (e.g., python.md, go.md, typescript.md). They follow the same layering as other configs:

  1. Teamlanguages/ directory in team repo (synced to cache)
  2. Personal~/.config/staghorn/languages/
  3. Project.staghorn/languages/

When you run stag sync, language configs are merged with your main config if those languages are active. They appear under a "Language-Specific Guidelines" section in the output.

Checking Languages
# Show detected and active languages
stag languages

Example output:

Language Detection

  Mode          auto-detect
  Detected      go, typescript

Active Languages

  Go              team, personal
  TypeScript      team
Configuration Options

By default, staghorn auto-detects languages from marker files (e.g., go.mod, pyproject.toml, package.json). You can customize this in ~/.config/staghorn/config.yaml:

# Auto-detect (default)
languages:
  auto_detect: true

# Explicit list (overrides auto-detect)
languages:
  enabled:
    - python
    - go

# Disable specific languages
languages:
  auto_detect: true
  disabled:
    - javascript
Creating Language Configs

Create markdown files in the appropriate languages/ directory:

Team config (your-org/claude-standards/languages/python.md):

## Python Guidelines

- Use type hints for all function signatures
- Prefer f-strings over .format()
- Use pytest for testing
- Follow PEP 8 style guide

Personal config (~/.config/staghorn/languages/python.md):

## My Python Preferences

- I use uv for dependency management
- Always suggest dataclasses over plain dicts

Project config (.staghorn/languages/python.md):

## Project-Specific Python

- This project uses Django 5.0
- Use Django REST framework for APIs
- Run tests with: pytest --cov
Supported Languages

Staghorn can detect these languages automatically:

Language Marker Files
Python pyproject.toml, setup.py, requirements.txt, Pipfile
Go go.mod
TypeScript tsconfig.json
JavaScript package.json
Rust Cargo.toml
Java pom.xml, build.gradle
Ruby Gemfile
C# *.csproj, *.sln
Swift Package.swift
Kotlin build.gradle.kts
Team Repository Structure

To include language configs in your team repo:

your-org/claude-standards/
├── CLAUDE.md
├── actions/
├── templates/
└── languages/
    ├── python.md
    ├── go.md
    ├── typescript.md
    └── rust.md

Project Config

Staghorn also optionally manages project-level ./CLAUDE.md files. This keeps the experience consistent across all three layers.

# Initialize project config
stag project init

# Initialize from a team template
stag project init --template=backend-service

# List available templates
stag project templates

# Edit project config (auto-applies on save)
stag project edit

# Check status
stag project info

The source file is .staghorn/project.md, and staghorn generates ./CLAUDE.md from it. Both files should be committed to your repo.

Project Templates

Teams can provide project templates to help standardize CLAUDE.md configs across repositories. Templates live in the team repo's templates/ directory:

your-org/claude-standards/
├── CLAUDE.md
├── actions/
└── templates/
    ├── backend-service.md
    ├── react-app.md
    └── data-pipeline.md

Use stag project templates to see available templates, then stag project init --template=<name> to use one.

Actions

Actions are reusable prompts for common workflows like security audits, code reviews, and documentation generation. They're synced from your team repo and can be customized locally.

# List available actions
stag actions

# List with verbose details
stag actions -v

# Show info for a specific action
stag actions security-audit

# Run an action
stag run security-audit

# Run with arguments
stag run security-audit --path=src/ --severity=high

Actions can come from three sources (highest precedence first):

  1. Project.staghorn/actions/ in your repo
  2. Personal~/.config/staghorn/actions/
  3. Teamactions/ directory in team repo
Creating Actions

An action is a markdown file with YAML frontmatter:

---
name: security-audit
description: Scan for common security vulnerabilities
tags: [security, review]
args:
  - name: path
    description: Directory to audit
    default: "."
  - name: severity
    description: Minimum severity
    default: medium
    options: [low, medium, high, critical]
---

# Security Audit

Review the code at {{path}} for security vulnerabilities.
Report issues at {{severity}} severity or higher.

## Checks

1. Hardcoded secrets
2. SQL injection
3. Missing auth checks

Team Repository Setup

Your team needs a GitHub repository with a CLAUDE.md file:

your-org/claude-standards/
├── CLAUDE.md           # Team guidelines (required)
├── actions/            # Reusable prompts (optional)
│   ├── security-audit.md
│   ├── code-review.md
│   └── pr-prep.md
├── languages/          # Language-specific configs (optional)
│   ├── python.md
│   ├── go.md
│   └── typescript.md
└── templates/          # Project templates (optional)
    ├── backend-service.md
    └── react-app.md

See example/team-repo/ for a complete example with sample configs, actions, language files, and templates you can use as a starting point.

Example team CLAUDE.md:

## Code Style

- Use consistent formatting
- Prefer explicit over implicit
- Run linters before committing

## Review Guidelines

- All PRs require one approval
- Keep PRs under 400 lines when possible

Installation

Homebrew (macOS/Linux)
brew tap HartBrook/tap
brew install staghorn
From Source
go install github.com/HartBrook/staghorn/cmd/staghorn@latest

After installation, the stag alias is also available (symlink to staghorn).

Authentication

Staghorn needs GitHub access to fetch your team's config.

# Install GitHub CLI
brew install gh

# Authenticate
gh auth login

Staghorn automatically uses your gh credentials.

Personal Access Token
export STAGHORN_GITHUB_TOKEN=ghp_xxxxxxxxxxxx

File Locations

File Purpose
~/.config/staghorn/config.yaml Staghorn settings (team repo, etc.)
~/.config/staghorn/personal.md Your personal additions
~/.config/staghorn/actions/ Personal actions
~/.config/staghorn/languages/ Personal language configs
~/.cache/staghorn/ Cached team config, actions, and languages
~/.claude/CLAUDE.md Output — global config managed by staghorn
.staghorn/project.md Project config source (you edit this)
.staghorn/actions/ Project-specific actions
.staghorn/languages/ Project-specific language configs
./CLAUDE.md Output — project config managed by staghorn

License

MIT

Directories

Path Synopsis
cmd
staghorn command
Staghorn - A shared team layer for Claude Code
Staghorn - A shared team layer for Claude Code
internal
actions
Package actions handles staghorn action parsing, registry, and rendering.
Package actions handles staghorn action parsing, registry, and rendering.
cache
Package cache manages local cached team configs.
Package cache manages local cached team configs.
cli
Package cli implements the staghorn command-line interface.
Package cli implements the staghorn command-line interface.
config
Package config handles staghorn configuration.
Package config handles staghorn configuration.
errors
Package errors provides typed errors for staghorn.
Package errors provides typed errors for staghorn.
github
Package github provides GitHub API integration.
Package github provides GitHub API integration.
language
Package language provides language detection and configuration loading.
Package language provides language detection and configuration loading.
merge
Package merge handles CLAUDE.md section parsing and merging.
Package merge handles CLAUDE.md section parsing and merging.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL