From b64cecade966786b3d5839444b917f1bf4cce535 Mon Sep 17 00:00:00 2001 From: George Date: Mon, 30 Mar 2026 16:26:53 +0200 Subject: [PATCH] feat: propose initial Claude Code shared standards --- AI/Claude/CLAUDE.md | 32 +++++++ AI/Claude/README.md | 119 ++++++++++++++++++++++++ AI/Claude/hooks/README.md | 134 +++++++++++++++++++++++++++ AI/Claude/hooks/block_commit_main.rs | 32 +++++++ AI/Claude/hooks/block_push.py | 11 +++ AI/Claude/skills/README.md | 69 ++++++++++++++ AI/Claude/skills/analyze-issue.md | 19 ++++ 7 files changed, 416 insertions(+) create mode 100644 AI/Claude/CLAUDE.md create mode 100644 AI/Claude/README.md create mode 100644 AI/Claude/hooks/README.md create mode 100644 AI/Claude/hooks/block_commit_main.rs create mode 100644 AI/Claude/hooks/block_push.py create mode 100644 AI/Claude/skills/README.md create mode 100644 AI/Claude/skills/analyze-issue.md diff --git a/AI/Claude/CLAUDE.md b/AI/Claude/CLAUDE.md new file mode 100644 index 0000000..b439e11 --- /dev/null +++ b/AI/Claude/CLAUDE.md @@ -0,0 +1,32 @@ +# Claude Team Standards + +This file defines shared rules for Claude across the team. All rules here apply to everyone — engineering, QA, and support. + +## Safety + +- Never run `git push` — all pushes must be done manually by the user +- Never commit secrets, API keys, or tokens — use environment variables +- Never bypass pre-commit hooks with `--no-verify` +- Never force push to `main` + +## Code quality + +- Always run tests before considering a task done +- Always run the linter after editing code +- Don't add features, refactoring, or improvements beyond what was asked + +## Git discipline + +- Write clear, descriptive commit messages +- One logical change per commit +- Branch names must describe the work (e.g. `feature/x`, `fix/y`, `chore/z`) + +## Communication + +- If a task is ambiguous, ask before starting — don't assume +- When blocked, state why clearly instead of guessing a workaround + +## Workflow + +- Use `/analyze-issue` before picking up any GitHub issue +- Read existing code before writing new code — don't duplicate logic diff --git a/AI/Claude/README.md b/AI/Claude/README.md new file mode 100644 index 0000000..81512c0 --- /dev/null +++ b/AI/Claude/README.md @@ -0,0 +1,119 @@ +# 🤖 Claude Team Standards + +This directory contains shared Claude Code configuration for the team — skills, hooks, and rules that make Claude behave consistently for everyone, whether you're in engineering, QA, or support. + +--- + +## Why shared configs? + +When everyone uses Claude differently, you get inconsistent output, repeated mistakes, and no way to enforce team standards. Shared configs fix that: + +- 📏 **Consistency** — Claude follows the same rules and formats for everyone +- 🛡️ **Safety** — hard rules (like never pushing code) are enforced, not just suggested +- ⚡ **Speed** — common workflows become one-liner slash commands +- 🧠 **Shared knowledge** — team conventions live in one place, not in individual heads + +--- + +## What's in here + +### 📄 CLAUDE.md + +The rules file. Claude reads this automatically and uses it to guide its behavior throughout a session. Think of it as a team handbook for Claude — coding standards, git discipline, safety rules, workflow expectations. + +It's **advisory** — Claude will follow it, but it's not enforced at a technical level. Pair it with hooks for anything that must never slip. + +👉 See [CLAUDE.md](./CLAUDE.md) + +--- + +### ⚡ Skills + +Skills are custom slash commands. You create a markdown file, and the filename becomes the command. Invoke it with `/skill-name` in Claude Code. + +They're great for repeated workflows — instead of explaining the same task to Claude every time, you write the instructions once and reuse them forever. + +``` +/analyze-issue #123 → structured analysis of a GitHub issue +``` + +Skills are **project-scoped** — everyone who clones this repo gets them automatically. No setup needed beyond having Claude Code installed. + +> 🔌 Some skills require an MCP server (e.g. the GitHub MCP server for issue-related skills). Check the skills README for details. + +👉 See [skills/README.md](./skills/README.md) + +--- + +### 🪝 Hooks + +Hooks are scripts that run automatically when Claude tries to do something — before or after a tool executes. Unlike CLAUDE.md, hooks are **enforced** — they can block actions outright. + +Use them for things that must never happen: + +- 🚫 Blocking `git push` (all pushes must come from the user) +- 🌿 Blocking direct commits to `main` or `master` +- 🔑 Detecting secrets before they get written to a file +- 🧹 Running the linter automatically after every file edit + +Hooks can be written in **any language** — Python, shell, Rust, Go, etc. Python and shell are preferred for simplicity since they run without a build step. Compiled language hooks (like Rust) require each team member to compile the binary locally. See the hooks README for details. + +Hooks are configured in `.claude/settings.json` and live in the `hooks/` directory. + +👉 See [hooks/README.md](./hooks/README.md) + +--- + +## How to set everything up + +### 1. Install Claude Code + +If you haven't already: +```bash +npm install -g @anthropic-ai/claude-code +``` + +### 2. Clone the repo + +Skills and hooks are automatically available once you clone — no extra setup needed for those. + +### 3. Compile Rust hooks (if applicable) + +Some hooks are written in Rust for teams that already have a Rust toolchain. These need to be compiled once per machine: + +```bash +rustc AI/Claude/hooks/block_commit_main.rs -o AI/Claude/hooks/block_commit_main +``` + +Or if there's a Makefile: +```bash +make hooks +``` + +Compiled binaries are gitignored — only the `.rs` source files are committed. + +### 4. Configure hooks + +Copy or reference the hook settings into your project's `.claude/settings.json`. See [hooks/README.md](./hooks/README.md) for the exact JSON. + +### 5. Set up MCP servers (if needed) + +If you're using skills that interact with GitHub or other external services, you'll need the relevant MCP server configured. See [skills/README.md](./skills/README.md) for details. + +### 6. Start using skills + +Open Claude Code in your project and type `/` to see available commands. + +--- + +## The golden rule 🏅 + +> **CLAUDE.md tells Claude what to do. Hooks make sure it actually does it.** + +Use CLAUDE.md for conventions and guidance. Use hooks for anything where "Claude forgot" is not an acceptable excuse. + +--- + +## Contributing + +Adding a new skill or hook? Great — follow the guidelines in their respective READMEs, keep things focused and simple, and update this README if you're adding something significant. diff --git a/AI/Claude/hooks/README.md b/AI/Claude/hooks/README.md new file mode 100644 index 0000000..559ce8c --- /dev/null +++ b/AI/Claude/hooks/README.md @@ -0,0 +1,134 @@ +# Hooks + +Hooks are scripts that run automatically in response to Claude's actions. They enforce rules that must never be bypassed — unlike CLAUDE.md which is advisory, hooks are deterministic. + +## Structure + +``` +hooks/ +├── README.md +├── block_push.py # Blocks git push attempts (Python) +└── block_commit_main.rs # Blocks direct commits to main/master (Rust) +``` + +## How hooks work + +Claude pipes a JSON payload to the hook's stdin before (or after) executing a tool. The hook responds with an exit code: + +| Exit code | Meaning | +|-----------|---------| +| `0` | Allow — proceed normally | +| `2` | Block — stop the action, show stderr to Claude | + +## How to register a hook + +Hooks are configured in `.claude/settings.json`. The example below uses `block_push.py` — a hook that prevents Claude from running `git push`: + +**`AI/Claude/hooks/block_push.py`:** +```python +import sys +import json + +data = json.load(sys.stdin) +command = data.get("tool_input", {}).get("command", "") + +if "git push" in command: + print("Blocked: git push is not allowed from Claude. Push manually.") + sys.exit(2) + +sys.exit(0) +``` + +**`.claude/settings.json`:** +```json +{ + "hooks": { + "PreToolUse": [ + { + "matcher": "Bash", + "hooks": [ + { + "type": "command", + "command": "python3 AI/Claude/hooks/block_push.py" + } + ] + } + ] + } +} +``` + +## Hook events + +| Event | Fires | +|-------|-------| +| `PreToolUse` | Before Claude executes a tool — can block | +| `PostToolUse` | After Claude executes a tool — cannot block, used for logging/linting | + +--- + +## Using Rust hooks + +Hooks can be written in any language — including Rust. The tradeoff is that compiled hooks require a build step and each team member must compile for their own platform. + +### Example — `block_commit_main.rs` + +This hook blocks Claude from committing directly to `main` or `master`, enforcing the use of feature branches. + +**Compile it:** +```bash +rustc AI/Claude/hooks/block_commit_main.rs -o AI/Claude/hooks/block_commit_main +``` + +**Register it in `.claude/settings.json`:** +```json +{ + "hooks": { + "PreToolUse": [ + { + "matcher": "Bash", + "hooks": [ + { + "type": "command", + "command": "AI/Claude/hooks/block_commit_main" + } + ] + } + ] + } +} +``` + +### Team setup for Rust hooks + +Since compiled binaries are platform-specific, follow these steps: + +1. **Add binaries to `.gitignore`** — commit the `.rs` source files, not the compiled output: + ```gitignore + AI/Claude/hooks/block_commit_main + ``` + +2. **Each team member compiles locally** after cloning: + ```bash + rustc AI/Claude/hooks/block_commit_main.rs -o AI/Claude/hooks/block_commit_main + ``` + +3. **Alternatively, use a Makefile** to automate this: + ```makefile + hooks: + rustc AI/Claude/hooks/block_commit_main.rs -o AI/Claude/hooks/block_commit_main + ``` + Then team members just run `make hooks` after cloning. + +> **Tip:** If the extra build step is a friction point, rewrite the hook in Python instead. Rust hooks make sense when you need performance or already have a Rust toolchain in your workflow. + +--- + +## Guidelines + +- Use hooks for hard rules (secrets, destructive commands, force pushes, branch protection) +- Use CLAUDE.md for guidance and conventions — hooks are the backstop +- Prefer Python or shell for hooks — no compilation required, works cross-platform out of the box +- Use Rust (or other compiled languages) only when justified — document the build step clearly +- Keep hooks fast — they run on every matching tool call +- Always handle the case where stdin is empty or malformed diff --git a/AI/Claude/hooks/block_commit_main.rs b/AI/Claude/hooks/block_commit_main.rs new file mode 100644 index 0000000..ca0df43 --- /dev/null +++ b/AI/Claude/hooks/block_commit_main.rs @@ -0,0 +1,32 @@ +use std::io::{self, Read}; +use std::process::Command; + +fn main() { + let mut input = String::new(); + io::stdin().read_to_string(&mut input).unwrap(); + + // Only act on git commit commands + if !input.contains("git commit") { + std::process::exit(0); + } + + // Get the current branch name + let output = Command::new("git") + .args(["branch", "--show-current"]) + .output(); + + let branch = match output { + Ok(o) => String::from_utf8_lossy(&o.stdout).trim().to_string(), + Err(_) => std::process::exit(0), // can't determine branch, allow + }; + + if branch == "main" || branch == "master" { + eprintln!( + "Blocked: direct commits to '{}' are not allowed. Create a feature branch first.", + branch + ); + std::process::exit(2); + } + + std::process::exit(0); +} diff --git a/AI/Claude/hooks/block_push.py b/AI/Claude/hooks/block_push.py new file mode 100644 index 0000000..de01f40 --- /dev/null +++ b/AI/Claude/hooks/block_push.py @@ -0,0 +1,11 @@ +import sys +import json + +data = json.load(sys.stdin) +command = data.get("tool_input", {}).get("command", "") + +if "git push" in command: + print("Blocked: git push is not allowed from Claude. Push manually.") + sys.exit(2) + +sys.exit(0) diff --git a/AI/Claude/skills/README.md b/AI/Claude/skills/README.md new file mode 100644 index 0000000..e96a8a7 --- /dev/null +++ b/AI/Claude/skills/README.md @@ -0,0 +1,69 @@ +# Skills + +Skills are custom slash commands that extend Claude's behavior for repeated workflows. Each skill is a markdown file — the filename becomes the command name. + +## Structure + +``` +skills/ +├── README.md +└── analyze-issue.md → /analyze-issue +``` + +## How to create a skill + +Create a markdown file describing what Claude should do. Use `$ARGUMENTS` to capture anything typed after the command name. + +**Example — `skills/analyze-issue.md`:** +```markdown +Analyze the GitHub issue provided in $ARGUMENTS (issue number or URL). + +1. **Type** — classify as: Bug, Feature Request, Improvement, or Question +2. **Summary** — one sentence describing the core problem or request +3. **Impact** — who is affected and how severely (P1/P2/P3) +4. **Affected area** — which part of the codebase or system is likely involved +5. **Next steps** — what is needed to start working on this + +... +``` + +Invoke it with: `/analyze-issue #123` or `/analyze-issue https://github.com/org/repo/issues/123` + +## How to use skills + +Type `/skill-name` in Claude Code. If the skill accepts arguments, add them after the command name. + +## MCP server requirement + +Some skills interact with external services like GitHub. For these to work, the relevant **MCP (Model Context Protocol) server** must be configured. + +For `analyze-issue` and any other GitHub-related skills, the GitHub MCP server must be set up in `.mcp.json`: + +```json +{ + "mcpServers": { + "github": { + "command": "npx", + "args": ["-y", "@modelcontextprotocol/server-github"], + "env": { + "GITHUB_PERSONAL_ACCESS_TOKEN": "" + } + } + } +} +``` + +> Keep your token out of version control. Use environment variables or a secrets manager. Add `.mcp.json` to `.gitignore` if it contains sensitive values, or use a `.mcp.local.json` for personal credentials. + +## Scope + +- Skills in this directory are **project-scoped** — available to everyone who clones this repo. +- Personal skills go in `~/.claude/commands/` and are not shared with the team. + +## Guidelines + +- One skill per file, one clear purpose +- Name the file after what it does (`analyze-issue.md`, not `issue.md`) +- Keep prompts concise — Claude reads the whole file as a system instruction +- Use `$ARGUMENTS` when the skill needs user input +- Document any external dependencies (MCP servers, environment variables) in this README diff --git a/AI/Claude/skills/analyze-issue.md b/AI/Claude/skills/analyze-issue.md new file mode 100644 index 0000000..de21350 --- /dev/null +++ b/AI/Claude/skills/analyze-issue.md @@ -0,0 +1,19 @@ +Analyze the GitHub issue provided in $ARGUMENTS (issue number or URL). + +1. **Type** — classify as: Bug, Feature Request, Improvement, or Question +2. **Summary** — one sentence describing the core problem or request +3. **Impact** — who is affected and how severely (P1/P2/P3) +4. **Affected area** — which part of the codebase or system is likely involved +5. **Next steps** — what is needed to start working on this (missing info, decisions, who should pick it up) + +Format your response exactly as: + +**Type:** ... +**Summary:** ... +**Impact:** P1/P2/P3 — reason +**Affected area:** ... +**Next steps:** +- ... +- ... + +Be concise. Do not speculate beyond what the issue contains. If information is missing to make a determination, state what is needed.