-
Notifications
You must be signed in to change notification settings - Fork 5
PM-35200 - Create contributing guide for Claude tooling #195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| # Contributing Claude Context to This Repo | ||
|
|
||
| Every time you catch Claude making the same mistake twice, explain the same convention in chat, or hand a teammate a mental map they didn't have β that's knowledge worth encoding. This guide covers what belongs in this repo's `.claude/`, where to put it, and how to land it alongside the code it describes. | ||
|
|
||
| ## When to contribute here vs. elsewhere | ||
|
|
||
| Ask: **is this knowledge specific to this codebase, or generic enough to work across repos?** | ||
|
|
||
| - **Specific to this codebase** β contribute here, in `.claude/`. | ||
| Example: "how we add a new module in this codebase," "how our feature-flag system works." | ||
| - **Generic, reusable across repos** β [`bitwarden/ai-plugins`](https://github.com/bitwarden/ai-plugins) β persona plugins (e.g., a code-review agent), tool integrations, or shared utilities. | ||
|
|
||
| When unsure, keep it here. Promoting up to `ai-plugins` later is easier than pulling it back β see its [CONTRIBUTING.md](https://github.com/bitwarden/ai-plugins/blob/main/CONTRIBUTING.md) when you're ready. | ||
|
|
||
| ## Choose scope, then shape | ||
|
|
||
| ### 1. Scope β where does it apply? | ||
|
|
||
| Claude loads every `CLAUDE.md` and `CLAUDE.local.md` by [walking up from the working directory](https://code.claude.com/docs/en/memory#how-claude-md-files-load) β looking in each ancestor directly, not in a nested `.claude/` subdirectory. Files below the working directory (including nested `.claude/skills/`) are loaded lazily when Claude reads into that subtree. Use that hierarchy: | ||
|
|
||
| - **Applies everywhere in this repo** β root `CLAUDE.md` or `.claude/skills/` | ||
| - **Applies only within one app, library, utility, or subtree** β nested `CLAUDE.md` or `.claude/skills/` in that directory | ||
|
|
||
| Push rules as deep as they'll go β keeping app-specific rules local saves context for everyone else's sessions, not just yours. | ||
|
|
||
| For rules that should apply only to certain file types, use [`.claude/rules/<name>.md` with a `paths:` frontmatter glob](https://code.claude.com/docs/en/memory#organize-rules-with-claude/rules/) instead of a nested `CLAUDE.md`. | ||
|
|
||
| ### 2. Shape β how should Claude use it? | ||
|
|
||
| | You want to⦠| Use | | ||
| | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | | ||
| | State a rule Claude must always follow in its scope | `CLAUDE.md` | | ||
| | State a rule that applies only to certain file globs | `.claude/rules/<name>.md` with `paths:` frontmatter | | ||
| | Teach a procedure Claude invokes on demand | `.claude/skills/<name>/SKILL.md` | | ||
| | Give Claude a specialized subagent with its own context | `.claude/agents/<name>.md` (YAML frontmatter; `name` + `description` required) | | ||
| | Add a user-invocable slash command | `.claude/commands/<name>.md` | | ||
| | Trigger a shell script on a Claude Code event | _We have them, but no strict project enforcement yet β register yours in `settings.local.json`._ | | ||
|
|
||
| Rule of thumb: **if Claude only needs it sometimes, it's a skill.** Once a `CLAUDE.md` loads, it stays in context for the rest of the session β keep each one lean, especially the root. | ||
|
|
||
| ## Security conventions | ||
|
|
||
| Skills and agents that touch vault data, authentication, or cryptography must use Bitwarden's [Core Vocabulary](https://contributing.bitwarden.com/architecture/security/definitions) (Vault Data, Protected Data, Secure Channel, etc.) and re-state the zero-knowledge invariant inline. **Subagents run in a fresh context** and do not inherit this repo's `CLAUDE.md` β include the relevant definitions directly in the agent's system prompt. | ||
|
|
||
| ## What good contributions look like | ||
|
|
||
| - **Grounded in the code.** Real files, real patterns, real commands. | ||
| If it could apply to any repo, it belongs in `ai-plugins`. | ||
| - **Describes the "what" and "why," not the "who."** | ||
| Avoid team-persona framing. Describe the domain and its constraints; the team is an implementation detail. | ||
| - **Short and specific.** | ||
| 2,000 words of general advice isn't a skill. | ||
| - **Active voice, direct language.** | ||
| "Invoke this skill when..." β not "This skill may be invoked when..." | ||
| - **Reviewed like code.** | ||
| Teams of domain experts own `.claude/` in their areas β they're the ones shaping how Claude behaves for everyone who works there, so treat changes with the same seriousness as source. | ||
|
|
||
| ## Anti-patterns | ||
|
|
||
| - **Team-persona agents** ("Team ABC engineer"). | ||
| If a team's process is unique enough to warrant a persona, that's an SDLC signal to address, not a persona to encode. | ||
| - **Root-level rules that only matter in one subtree.** | ||
| If the rule only ever applies to a single subtree, then the rule belongs in a nested `CLAUDE.md` next to that subtree. | ||
| - **Duplicating `ai-plugins` content.** | ||
| Check existing plugin skills before writing a new one. | ||
| - **Generic advice disguised as repo-local knowledge.** | ||
| "Write good tests" isn't repo-specific. | ||
| "Our integration tests must hit a real database becauseβ¦" is. | ||
|
|
||
| ## Building a contribution | ||
|
|
||
| The Claude Code ecosystem moves fast β last session's habits may already be out of date. Here's the workflow we follow. | ||
|
|
||
| ### 1. Start with the canonical docs | ||
|
|
||
| A quick refresh before you begin goes a long way β the rules shift more often than you'd think: | ||
|
|
||
| - [How Claude Code Works](https://code.claude.com/docs/en/how-claude-code-works) β the mental model. | ||
| - [Best Practices for Claude Code](https://code.claude.com/docs/en/best-practices) β what Anthropic recommends. | ||
| - [Extend Claude Code](https://code.claude.com/docs/en/features-overview) β what you can build (skills, agents, commands, hooks). | ||
| - [The Complete Guide to Building Skills for Claude](https://resources.anthropic.com/hubfs/The-Complete-Guide-to-Building-Skill-for-Claude.pdf) - a must read for skill building | ||
|
|
||
| ### 2. Survey the landscape | ||
|
|
||
| A quick skim of both goes a long way: | ||
|
|
||
| - This repo's [`.claude/`](.) tree. | ||
| - [`bitwarden/ai-plugins`](https://github.com/bitwarden/ai-plugins). | ||
|
|
||
| Try to match the voice you see. "Invoke when the user asks to X" β not "This skill may be invoked when X." Direct, active, specific. Your contribution should read like the neighbors. | ||
|
|
||
| ### 3. Build iteratively | ||
|
|
||
| When you're authoring a skill, start with `/skill-creator:skill-creator`. It runs an iterative loop β draft β test against evals β review outputs β refine β with benchmark stats and a side-by-side reviewer. You end up with a skill that's been exercised against concrete inputs before you open the PR. | ||
|
|
||
| For agents, commands, hooks, and `CLAUDE.md` entries, start from an existing one in the repo and adapt it. No need to invent a new structure when a neighbor already solves the shape problem. | ||
|
|
||
| ### 4. Validate before you push | ||
|
|
||
| - Run a local Bitwarden Claude Code review with `/bitwarden-code-review:code-review-local` β it writes findings to files so you can fix them before pushing, without posting anything to GitHub. | ||
| - When you raise the PR, apply the `ai-review` label. Our reusable GitHub workflow watches for it and runs a Claude Code review automatically; without the label, the review doesn't fire. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
β Why is this
+101but bitwarden/sdk-internal#1008 is+130? Do those larger PR's need to have prettier run on them, or does this repo have different prettier rules?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ran prettier on all of those repos's PRs and this one. I also saw similar minor differences.
I didn't dig too deep, but I think the answer to your second question is Yes.