{
  "markdown": "# brand-voice\n\n**Brand writing enforcement for Claude Code — automatic, configurable, zero-friction.**\n\n[![npm version](https://img.shields.io/npm/v/brand-voice.svg)](https://www.npmjs.com/package/brand-voice)\n[![npm downloads](https://img.shields.io/npm/dm/brand-voice.svg)](https://www.npmjs.com/package/brand-voice)\n[![CI](https://github.com/zoharbabin/brand-voice/actions/workflows/ci.yml/badge.svg)](https://github.com/zoharbabin/brand-voice/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n[![Node.js 18+](https://img.shields.io/badge/node-%3E%3D18-brightgreen)](https://nodejs.org)\n\nEvery time Claude writes or edits a Markdown file, `brand-voice` checks it against your brand guidelines and signals Claude to fix violations **before** the file saves. No manual review. No rule reminders in every prompt.\n\n![brand-voice demo](docs/demo.svg)\n\nClaude reads the violation list, corrects the file, and retries the write — automatically.\n\n---\n\n## Why brand-voice?\n\nYour brand guidelines live in a doc somewhere. Claude doesn't read them unless you paste them into every prompt. Even then, the rules drift over time.\n\n`brand-voice` makes the rules structural:\n\n- **Works for any company** — configure your own vocabulary, voice, and visual identity\n- **Auto-corrects, doesn't just report** — the PostToolUse hook blocks bad writes and triggers a retry\n- **Covers the full stack** — hook for Claude Code, MCP server for on-demand checks, CLI for CI pipelines\n- **Smart about code** — ignores fenced blocks, indented code, inline code spans, and table cells\n- **Escape hatches** — `.brand-voice-ignore` for whole files, `<!-- brand-voice-disable-line -->` for individual lines\n- **Visual identity included** — colors, fonts, logo URLs live in the same guidelines file\n\n---\n\n## Install\n\n```sh\nnpm install -g brand-voice\n```\n\nOr run without installing:\n\n```sh\nnpx brand-voice@latest check\n```\n\n**Requires Node.js 18+.**\n\n---\n\n## Quick Start\n\n### Option A — Guided setup in Claude Code (recommended)\n\nRun the setup skill inside any Claude Code session:\n\n```\n/brand-voice-setup\n```\n\nThe skill does everything:\n1. Asks whether you have existing brand docs or want to answer four questions\n2. Optionally researches your brand automatically via web\n3. Writes `brand-guidelines.md` to your project\n4. Injects a summary block into `CLAUDE.md`\n5. Registers the PostToolUse hook in `.claude/settings.json`\n6. Registers the MCP server in `.mcp.json`\n\nAfter setup, every `.md` and `.mdx` file Claude touches is checked automatically.\n\n### Option B — Manual setup\n\n```sh\n# 1. Install\nnpm install -g brand-voice\n\n# 2. Create brand-guidelines.md in your project root (see schema below)\n\n# 3. Register the hook\nbrand-voice setup\n```\n\n---\n\n## How It Works\n\nThree components work together:\n\n| Component | What it does |\n|---|---|\n| **PostToolUse hook** (`brand-voice-check`) | Runs after every Write/Edit/MultiEdit on `.md`/`.mdx`; exits `2` with violations so Claude auto-corrects, exits `0` when clean |\n| **MCP server** (`brand-voice-mcp`) | Exposes `analyze_readability` and `apply_suggestions` for on-demand analysis and word-level fixes |\n| **CLI** (`brand-voice`) | Standalone checker for CI pipelines, ratchet baselines, and GitHub PR annotations |\n\n### What gets checked\n\n| Rule | Severity | Description |\n|---|---|---|\n| **Forbidden terms** | error | Whole-word, case-insensitive match — blocks the write |\n| **Avoid terms** | warning | Same matching — signals a preferred alternative |\n| **Sentence length** | warning | Configurable max words per sentence (default: 25) |\n| **Passive voice** | warning | Auxiliary + past-participle pattern detection |\n| **Readability grade** | warning | Flesch-Kincaid grade per sentence vs. your target |\n\nCode blocks, inline code, indented blocks, and table rows are **never checked** — only prose.\n\n**Never checked:** physical line length or line breaks. The CLAUDE.md injection always includes a formatting rule telling Claude to write continuous paragraphs and let the renderer word-wrap, but the analyzer itself has no line-width rule and never will — sentence length is measured in words, not characters or lines, so hard-wrapped and unwrapped prose score identically.\n\n### PostToolUse hook exit codes\n\n| Code | Meaning |\n|---|---|\n| `0` | No violations — file accepted |\n| `2` | Violations found — Claude reads output, corrects, and retries |\n\nExit `1` is never used (it aborts the session rather than triggering a retry).\n\n---\n\n## brand-guidelines.md\n\nOne Markdown file holds your entire brand configuration. Keep it **under 600 words** so it fits cleanly in context.\n\n```markdown\n# Brand Guidelines\n\n## Persona\nWho you are and who you write for.\n\n## Tone & Voice\n- Direct, honest, clear\n- Person: second          ← \"first\" | \"second\" | \"third\"\n- Voice: active           ← \"active\" | \"passive\"\n- Sentences: max 25 words\n- Contractions: yes       ← \"yes\" | \"no\"\n- Exclamation marks: no\n\n## Vocabulary\n**Always use:** Acme, Acme Platform, APIs\n**Avoid:** leverage, utilize, synergy, seamless\n**Forbidden:** [competitor names, unverified claims]\n\n## On-Tone Examples\n> Connect your data in minutes — Acme handles the routing.\n\n## Off-Tone Examples\n> Leverage our cutting-edge platform to seamlessly integrate.\n\n## Visual Identity\n- Primary color: #006EFA\n- Secondary color: #0050C3\n- Accent color: #FF9DFF\n- Background color: #FFFFFF\n- Text color: #282828\n- Logo (light): https://cdn.example.com/logo-light.svg\n- Logo (dark):  https://cdn.example.com/logo-dark.svg\n- Heading font: Inter\n- Body font: Source Sans Pro\n\n## Formatting Rules\n- Heading style: sentence case\n- Oxford comma: yes\n- Readability target: 8th grade\n\n## Quick Reference\nRepeat your top 5 rules here. This section appears last —\nwhere LLM attention is highest — to reinforce critical rules\nagainst context-window attention drop-off.\n```\n\nSee [`example/brand-guidelines.md`](example/brand-guidelines.md) for a complete working example.\n\n### Section aliases\n\n`## On-Brand Examples` and `## Off-Brand Examples` are accepted as aliases for `## On-Tone Examples` / `## Off-Tone Examples`. All other section names are case-insensitive exact matches.\n\n### Search path\n\nThe hook and CLI search for `brand-guidelines.md` in this order:\n\n1. Current working directory\n2. `~/.claude/brand-guidelines.md` (user scope — enforces rules across all your projects)\n3. Parent directories up to the git root\n\n---\n\n## Suppressing Violations\n\n### Skip files or directories — `.brand-voice-ignore`\n\nCreate a `.brand-voice-ignore` file in your project root. Uses gitignore-style patterns:\n\n```\n# Auto-generated content\ndist/\nCHANGELOG.md\n\n# Agent prompt files — intentional brand vocabulary exceptions\ndata/prompts/**\n\n# Vendor docs\nvendor/\n```\n\n### Skip a single line — inline comment\n\n```markdown\n<!-- brand-voice-disable-line -->\n```\n\nAdd this comment anywhere on a line to suppress all violations on that line. Useful for one-off exceptions where the violation is intentional.\n\n---\n\n## MCP Server\n\n### `analyze_readability`\n\nCheck a file or inline text for violations and readability scores.\n\n**Inputs:**\n\n| Field | Type | Required | Description |\n|---|---|---|---|\n| `file` | string | one of `file`/`text` | Absolute or relative path to a `.md`/`.mdx` file |\n| `text` | string | one of `file`/`text` | Inline Markdown to analyze |\n| `cwd` | string | no | Working directory for locating `brand-guidelines.md` |\n\n**Returns:** `{ filePath, passed, violations[], readabilityScores, visualIdentity }`\n\n### `apply_suggestions`\n\nApply safe word-level substitutions for forbidden/avoid terms. Does not fix sentence length, passive voice, or grade — those need human judgment.\n\n**Inputs:**\n\n| Field | Type | Required | Description |\n|---|---|---|---|\n| `file` | string | yes | Path to the file to fix |\n| `dryRun` | boolean | no | Preview diff without writing (default: `false`) |\n\n**Returns:** diff + change list (dry run) or confirmation + change list (live)\n\n**Tip:** Run `dryRun: true` first to preview, then apply.\n\n---\n\n## CI Integration\n\n`brand-voice` works independently of Claude Code — add it to any pipeline.\n\n**Check all `.md` files:**\n\n```sh\nnpx brand-voice@latest check\n```\n\n**Check only files changed in the current branch:**\n\n```sh\nnpx brand-voice@latest check --changed-only\n```\n\n**GitHub Actions inline annotations (PR diff comments):**\n\n```sh\nnpx brand-voice@latest check --reporter github-pr-review\n```\n\n**Ratchet enforcement** — block regressions without requiring a clean slate:\n\n```sh\n# Run once, commit the file\nnpx brand-voice@latest baseline --save\n\n# In CI: fail only if violations increase above baseline\nnpx brand-voice@latest check --baseline .brand-voice-baseline.json\n```\n\n**Example GitHub Actions workflow:**\n\n```yaml\nname: Brand Voice\non:\n  pull_request:\n    paths: ['**.md', '**.mdx']\n\njobs:\n  prose:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n        with: { fetch-depth: 0 }\n      - run: npx brand-voice@latest check --changed-only --reporter github-pr-review\n```\n\nExit `0` = clean or within baseline. Exit `1` = errors found or baseline exceeded.\n\n---\n\n## CLI Reference\n\n```\nbrand-voice <command> [options]\n\nCommands:\n  check [file]          Check a file or all .md files in cwd\n  setup                 Print instructions to run /brand-voice-setup in Claude Code\n  import <file>         Normalize a brand-guidelines.md into cwd\n  baseline --save       Save current violation count as ratchet baseline\n  vale-sync             Check that the Vale binary is available\n\nCheck options:\n  --changed-only        Only check files changed in git (requires git)\n  --baseline <file>     Compare against a baseline JSON file (ratchet check)\n  --reporter github-pr-review  Emit GitHub Actions annotation format\n```\n\n---\n\n## Programmatic API\n\n```ts\nimport { parseGuidelines, analyzeText, loadGuidelines } from 'brand-voice';\n\nconst guidelines = loadGuidelines(process.cwd());\nif (guidelines) {\n  const result = analyzeText(markdownString, 'doc.md', guidelines);\n  console.log(result.violations);        // Violation[]\n  console.log(result.readabilityScores); // ReadabilityScores\n  console.log(result.passed);            // false if any error-severity violations\n}\n```\n\nSee [src/types.ts](src/types.ts) for full type definitions.\n\n---\n\n## Distribution Patterns\n\n| Scenario | What to do |\n|---|---|\n| **Solo developer** | Run `/brand-voice-setup` once per project; commit `brand-guidelines.md` |\n| **Team** | Commit `brand-guidelines.md`, `.claude/settings.json`, and `.mcp.json`; teammates get enforcement on `git pull` |\n| **Global (all projects)** | Run `/brand-voice-setup` with the global flag; writes to `~/.claude/brand-guidelines.md` |\n| **claude.ai (browser)** | Setup skill outputs a paste block for Claude Project instructions — no hook or MCP needed |\n| **Enterprise / CI** | Use `brand-voice check` in pipelines; commit `.brand-voice-baseline.json` for ratchet enforcement |\n\n---\n\n## Requirements\n\n- **Node.js 18+**\n- **`brand-guidelines.md`** — created by `/brand-voice-setup` or written manually\n- **Vale** — optional; only required for `vale-sync`\n\n---\n\n## Contributing\n\nBug reports, feature requests, and pull requests are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for setup instructions, key invariants to preserve, and code style guidance.\n\n---\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n",
  "bytes": 11394,
  "sha": "f5ba1a90a8337769ef8401366d14bed4cab244343a19fe8bde7da0a4c078d50d",
  "repo_slug": "zoharbabin/brand-voice",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_zoharbabin_brand_voice_ba95e25b/readme"
}