Problem: AI agents write code without tests, skip design validation, and lack consistency across projects.
Solution: Portable patterns and guides that enforce test-first development (BDD/TDD), quality standards, and best practices across all your projects.
Repository: https://github.com/TheMostlyGreat/safeword
1. Install in your project:
cd /path/to/your/project
bunx safeword@latest setup2. Verify installation:
# Check for SAFEWORD files
test -f .safeword/SAFEWORD.md && echo ".safeword/SAFEWORD.md ✓"
test -f AGENTS.md && echo "AGENTS.md ✓"Result: Your project now has:
.safeword/SAFEWORD.md- Global patterns and workflows.safeword/guides/- Testing methodology (BDD/TDD), code philosophy.safeword/hooks/- Auto-linting, quality review hooks.claude/settings.json- Hook configuration for Claude Code.claude/commands/- Slash commands for Claude Code.cursor/hooks.json- Hook configuration for Cursor.cursor/rules/- Behavior rules for Cursor.cursor/commands/- Slash commands for CursorAGENTS.md- Project context with framework reference
Commit these to your repo for team consistency.
Stack-agnostic — Safeword is a process layer, not a framework opinion. It works alongside any stack — Next, Elysia, Astro, Django, Gin, whatever you use. Your application code and runtime dependencies are never touched.
Your agent config stays yours — Safeword uses AGENTS.md as the primary entry point. If you have an existing CLAUDE.md, it adds one import line at the top — your content is untouched.
Dev-only tools — For JS/TS projects, safeword installs ESLint, Prettier, and supporting plugins as devDependencies. These are code quality tools for development — they never ship with your application or affect your runtime.
AI guardrails, not human blockers — Hooks and stricter linting rules only fire during AI agent sessions (Claude Code / Cursor events). They never run during normal human development. Safeword does not install git hooks or modify your commit workflow.
Use in CI if you want — Safeword adds lint and format scripts to your package.json. You can wire these into your CI pipeline or precommit hooks — but it's your choice, not forced.
Project-local framework: Scripts write to .safeword/, .claude/, and .cursor/ in your project (no global install needed)
Team consistency: Teammates get the framework from your project repo (no global install needed)
Living documentation: Update guides as you learn, extract learnings from debugging, archive completed work
Key directories created in your project:
.safeword/guides/- Core methodology and best practices.safeword/templates/- Fillable document structures.safeword-project/tickets/- Tickets for complex/multi-step work (context anchors).safeword/hooks/- Automation scripts (Claude Code + Cursor).claude/commands/,.cursor/commands/- Slash commands.claude/skills/,.cursor/rules/- Specialized agent capabilities
Purpose: Reusable methodology applicable to all projects
| Guide | Purpose | When to Read |
|---|---|---|
| planning-guide.md | Feature planning workflow, spec creation, BDD/TDD integration | Starting any feature |
| testing-guide.md | Test-first workflow (RED/GREEN/REFACTOR), test pyramid, test types | Writing tests |
| learning-extraction.md | Extract learnings from debugging, recognition triggers | After complex debugging |
Purpose: Writing effective feature documentation
| Guide | Purpose | When to Read |
|---|---|---|
| design-doc-guide.md | Design doc structure and best practices | Designing complex features |
| architecture-guide.md | Architecture decisions (tech choices, data models) | Making architectural decisions |
| data-architecture-guide.md | Data model design (schemas, validation, flows) | Database/schema design |
| context-files-guide.md | CLAUDE.md/AGENTS.md structure and best practices | Setting up project context |
Purpose: Working with LLMs and documentation structure
| Guide | Purpose | When to Read |
|---|---|---|
| llm-writing-guide.md | Writing docs that LLMs follow (MECE, examples, recency bias) | Writing skills, commands, hooks |
| zombie-process-cleanup.md | Port-based cleanup, multi-project isolation | Managing dev servers |
| cli-reference.md | Safeword CLI command reference and usage | Using CLI commands |
Purpose: Fillable structures for feature documentation
| Template | Purpose | Used By |
|---|---|---|
| feature-spec-template.md | Feature spec (user stories + constraints) | planning-guide.md |
| task-spec-template.md | Bug, improvement, refactor, or internal task | planning-guide.md |
| test-definitions-feature.md | Test definition structure (suites, tests, steps) | planning-guide.md |
| design-doc-template.md | Design doc structure (architecture, components) | design-doc-guide.md |
| architecture-template.md | ADR for decisions with long-term impact | planning-guide.md |
| ticket-template.md | Context anchor for complex/multi-step work | SAFEWORD.md |
| work-log-template.md | Scratch pad and working memory during execution | SAFEWORD.md |
Purpose: Extracted knowledge that compounds across sessions
Location: .safeword-project/learnings/[concept].md
What goes here:
- Debugging discoveries (non-obvious gotchas, integration struggles)
- Trial-and-error findings (tried 3+ approaches before right one)
- Architecture insights (discovered during implementation)
- Testing traps (tests pass but UX broken, or vice versa)
How to extract: Follow learning-extraction.md recognition triggers and templates
Purpose: Context anchors for complex/multi-step work to prevent LLM loops
Location: .safeword-project/tickets/{id}-{slug}/
Structure:
.safeword-project/
├── tickets/
│ ├── 001-feature-name/
│ │ ├── ticket.md # Ticket definition (frontmatter + work log)
│ │ ├── test-definitions.md # BDD scenarios (Given/When/Then)
│ │ ├── spec.md # Feature spec for epics (optional)
│ │ └── design.md # Design doc for complex features (optional)
│ └── completed/ # Archive for done tickets
├── learnings/ # Extracted knowledge (gotchas, discoveries)
└── tmp/ # Scratch space (research, logs, etc.)
When to create: Multiple attempts likely, multi-step with dependencies, investigation needed, or risk of losing context
Hooks (in .safeword/hooks/): TypeScript automation scripts (Bun runtime)
session-verify-agents.ts- Verifies AGENTS.md link on session startsession-version.ts- Shows safeword version on session startsession-lint-check.ts- Checks for lint errors on session startsession-cleanup-quality.ts- Garbage-collects old quality state files on session endsession-compact-context.ts- Re-injects active ticket context after context compactionprompt-timestamp.ts- Injects timestamp into promptsprompt-questions.ts- Reminds agent to ask clarifying questionspost-tool-lint.ts- Auto-lints after file editspost-tool-quality.ts- Tracks LOC, detects phase changes and TDD stepspost-tool-bypass-warn.ts- Warns when agent bypasses quality gatespre-tool-quality.ts- Blocks edits when quality gate is active (LOC, phase, or TDD)pre-tool-config-guard.ts- Guards against settings.json modificationsstop-quality.ts- Quality review prompt on stopcursor/after-file-edit.ts- Auto-lints after Cursor file editscursor/stop.ts- Quality review prompt on Cursor stop
Skills (in .claude/skills/): Specialized agent capabilities
bdd/- BDD orchestrator for feature-level work (Discovery, Scenarios, Decomposition, TDD, Splitting, Done)debug/- Four-phase debugging (investigate before fixing)quality-review/- Deep code review with web researchrefactor/- Small-step refactoring with test verificationtesting/- Test writing methodology (iron laws, anti-patterns)ticket-system/- Ticket system and work logs for context anchoring
Commands (in .claude/commands/): Slash commands
/audit- Run architecture and dead code analysis/bdd- Force BDD flow for current task/cleanup-zombies- Kill zombie processes on ports/debug- Four-phase debugging framework/lint- Run linters and formatters/quality-review- Deep code review with web research/refactor- Systematic refactoring with small-step discipline/testing- Test writing guidance and best practices/verify- Verify ticket criteria (tests, build, lint, scenarios, dep drift)
MCP Servers (in .mcp.json / .cursor/mcp.json): Auto-configured integrations
- context7 - Up-to-date library documentation lookup
- playwright - Browser automation for testing
# Set up safeword in current project
bunx safeword@latest setup
bunx safeword@latest setup -y # Non-interactive mode
# Check project health and versions
bunx safeword@latest check
bunx safeword@latest check --offline # Skip remote version check
# Upgrade to latest version
bunx safeword@latest upgrade
# Preview changes before upgrading
bunx safeword@latest diff
bunx safeword@latest diff -v # Show full diff output
# Regenerate architecture config for /audit
bunx safeword@latest sync-config
# Remove safeword from project
bunx safeword reset
bunx safeword reset -y # Skip confirmation
bunx safeword reset --full # Also remove linting config + packages# From packages/cli/
bun publishAuto-detection: Detects project type from package.json and enables relevant ESLint plugins only when the framework is installed:
- TypeScript, React, Next.js, Astro
- Vitest, Playwright, Storybook, Tailwind, Turbo, TanStack Query
- Publishable libraries (adds publint)
AGENTS.md contains a link to .safeword/SAFEWORD.md (also added to CLAUDE.md if present).
SAFEWORD.md then imports guides via the Guides table. Both Claude Code and Cursor auto-load these as context.
ls .safeword-project/learnings/- Follow recognition triggers in
learning-extraction.md - Create
.safeword-project/learnings/[concept].md - Use template: Problem → Gotcha → Examples → Testing Trap
Commit .safeword/, .claude/, and .cursor/ in your project repo for team consistency.
How it works:
AGENTS.mdlinks to.safeword/SAFEWORD.md(also adds one import line toCLAUDE.mdif present)SAFEWORD.mdimports guides via Guides table- Guides cross-reference each other and templates
- Learnings stored in
.safeword-project/learnings/
Result: Modular, maintainable documentation with clear separation of concerns
- Guides - Reusable methodology (test pyramid, BDD/TDD workflow)
- Templates - Fillable structures (user stories, test definitions)
- Learnings - Extracted knowledge (gotchas, discoveries)
- Planning - Feature planning and design (user stories, test definitions, design docs)
- Hooks/Skills - Automation and specialized capabilities
Living Documentation: Update as you learn, archive completed work, consolidate when needed
Will safeword change my stack or framework? No. Safeword is a process overlay — it adds quality enforcement (BDD/TDD, linting, code review) on top of whatever you already use. It doesn't install application dependencies or modify your source code.
Will it overwrite my CLAUDE.md?
No. Safeword uses AGENTS.md as the primary entry point. If you have an existing CLAUDE.md, it prepends a single 4-line block that links to .safeword/SAFEWORD.md. Your existing content stays exactly where it is.
What packages does it install?
For JS/TS projects: ESLint, Prettier, and supporting plugins — all as devDependencies (the -D flag). These are code quality tools, not application dependencies. Python, Go, and Rust (beta) use their language-native linters (ruff, golangci-lint, clippy).
I use biome/dprint — is that a problem?
Safeword detects biome/dprint and skips Prettier installation. ESLint is still installed because biome doesn't support security scanning (eslint-plugin-security), cyclomatic complexity checks (sonarjs), or framework-specific rules (React hooks, Next.js, Astro). Both tools coexist without conflict.
Do teammates need to install safeword separately?
No. Commit the .safeword/, .claude/, and .cursor/ directories to git. When teammates pull, they get the full setup. The linting devDependencies install automatically with npm install / bun install.
Will it interfere with my development workflow?
No. Safeword's hooks and stricter linting rules only fire during AI agent sessions. They don't run when you code normally, and safeword does not install git hooks. It adds lint and format scripts to package.json that you can optionally use in CI or precommit hooks.
This section is for contributors to safeword itself.
| Component | Technology |
|---|---|
| Runtime | Bun (dev), Node 20+ (users) |
| CLI | TypeScript, Commander.js |
| Build | tsup (ESM-only output) |
| Tests | Vitest |
| Linting | ESLint 9 + Prettier |
These tools enhance development scripts but are not required:
| Binary | Purpose | Script | Install |
|---|---|---|---|
shfmt |
Format shell scripts in repo | bun format:sh |
brew install shfmt |
dot |
Generate dependency graph SVG | bun deps:graph |
brew install graphviz |
Without these binaries, the scripts print a message and skip.
Editing Source Templates:
- Edit in
packages/cli/templates/(source of truth) - Run
bunx safeword upgradeto sync to.safeword/ - Test changes
Running Tests:
# Important: Use `bun run test` (Vitest), NOT `bun test` (Bun's runner)
bun run test # All tests
bunx vitest run tests/foo.test.ts # Single file
bun run test:integration # Integration tests
bun run test:watch # Watch modePublishing:
Always run bun publish from packages/cli/ directory, not the monorepo root.
The CLI installs matching skills for both Claude Code and Cursor IDEs.
Source of truth: packages/cli/src/schema.ts
Parity tests: packages/cli/tests/schema.test.ts
| IDE | Skills Location | Commands Location |
|---|---|---|
| Claude Code | .claude/skills/safeword-*/ |
.claude/commands/*.md |
| Cursor | .cursor/rules/{safeword-*,bdd-*}.mdc |
.cursor/commands/*.md |
Editing skills:
- Edit templates in
packages/cli/templates/skills/(Claude) andpackages/cli/templates/cursor/rules/(Cursor) - Update
packages/cli/src/schema.tsif adding/removing skills - Run parity tests:
bun run test -- --testNamePattern="parity" - Run
bunx safeword upgradeto sync to local project
- Claude Code docs: https://docs.claude.com/en/docs/claude-code
- Issues: https://github.com/anthropics/claude-code/issues
- This repo: https://github.com/TheMostlyGreat/safeword