
Brewcode:Convention
- 15 installs
- 29 repo stars
- Updated August 2, 2026
- kochetkov-ma/claude-brewcode
Helps with ai & agent building tasks.
About
brewcode:convention is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- brewcode:convention
- AI & Agent Building
- AI-coding skill
Brewcode:Convention by the numbers
- 15 all-time installs (skills.sh)
- +1 installs in the week ending Aug 2, 2026 (Skillselion tracking)
- Ranked #11,187 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/kochetkov-ma/claude-brewcode --skill brewcodeconventionAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 15 |
|---|---|
| repo stars | ★ 29 |
| Last updated | August 2, 2026 |
| Repository | kochetkov-ma/claude-brewcode ↗ |
What it does
Helps with ai & agent building tasks.
Files
<instructions>
Mode Detection
Arguments: $ARGUMENTS
| Mode | Invocation | Phases | Prerequisites |
|---|---|---|---|
full (default) | /brewcode:convention | P0-P8 | None |
conventions | /brewcode:convention conventions | P0-P7 | None |
rules | /brewcode:convention rules | P0, P7, P7.5, P8 | .claude/convention/ exists |
paths | /brewcode:convention paths src/a,src/b | P0-P7 scoped | None |
---
P0: Mode + Stack Detection
Parse $ARGUMENTS for mode keyword. Default = full. For paths mode: split comma-separated paths after keyword.
Step 0.1: Detect Stack
EXECUTE using Bash tool:
bash "${CLAUDE_SKILL_DIR}/scripts/convention.sh" detect-stack && echo "---DETECT-OK---" || echo "---DETECT-FAILED---"Output: JSON {"stacks":[...],"primary":"...","build_file":"...","modules":[...]}.
| Primary Stack | Active Layers |
|---|---|
| java, kotlin | L1-L14, T1-T6 (all) |
| typescript | L1-L6, L8, L10-L11, L13-L14, T1-T3, T5-T6 |
| python | L1-L2, L4-L6, L8, L10, L13-L14, T1-T3, T5-T6 |
| rust | L1-L2, L4-L6, L8, L10-L11, T5 |
| go | L1-L2, L4-L6, L8, L10, T5 |
| Multi-stack | Union of all detected |
| other/unknown | All main layers (L1-L14), all test layers (T1-T6) — agent determines relevance per layer |
Step 0.2: Scan Project
EXECUTE using Bash tool:
bash "${CLAUDE_SKILL_DIR}/scripts/convention.sh" scan && echo "---SCAN-OK---" || echo "---SCAN-FAILED---"Output: JSON with source_dirs, file_counts, modules, total_files.
Iftotal_files> 1000: warn user, suggestpathsmode.
Step 0.3: Setup Convention Directory
EXECUTE using Bash tool:
bash "${CLAUDE_SKILL_DIR}/scripts/convention.sh" setup && echo "---SETUP-OK---" || echo "---SETUP-FAILED---"STOP if FAILED -- cannot proceed without output directory.
Step 0.4: Validate (rules mode only)
EXECUTE using Bash tool:
bash "${CLAUDE_SKILL_DIR}/scripts/convention.sh" validate && echo "---VALID---" || echo "---INVALID---"Ifrulesmode +INVALID-- exit: "Run/brewcode:convention conventionsfirst."
---
P1: Load Layer Definitions
Read references/analysis-layers.md. Filter layers by detected stack from P0. For paths mode: further filter by specified paths — match layer file patterns against provided paths. Build ACTIVE_LAYERS for P2.
---
P2: Parallel Layer Analysis (10 agents, ONE message)
Dynamic Agent Resolution
Before spawning agents, check for project team agents: 1. If .claude/teams/ exists — read team.md for agent roster with domains 2. If team has architecture/testing domain agents — prefer over plugin architect/tester 3. Priority: team agent > project agent > plugin agent > system agent 4. If agent refuses (Task Acceptance Protocol) — re-delegate to suggested colleague (max 2 retries)
Spawn ALL agents in a SINGLE message. Skip agents for inactive layers (filtered in P1).
| # | Agent | Layers | Focus |
|---|---|---|---|
| 1 | architect | L1-L3 | Build config, dependency management, code generation |
| 2 | architect | L4 | @UtilityClass, static helpers, shared converters |
| 3 | architect | L5+L14 | REST endpoints, security, config, caching |
| 4 | architect | L6+L9 | DI patterns, @Transactional, domain services |
| 5 | architect | L7 | Feign clients, external API integrations |
| 6 | architect | L8 | JOOQ DSL, raw SQL, mappers, query patterns |
| 7 | architect | L10+L11 | Records, @Value @Builder, naming conventions |
| 8 | architect | L12+L13 | DDL scripts, config files, templates |
| 9 | tester | T1-T4 | Test data, base classes, helpers, ExpectedData |
| 10 | tester | T5-T6 | BDD style, assertion patterns, @ParameterizedTest |
Per-agent prompt template:
Analyze {LAYERS} in the project.
Stack: {DETECTED_STACK}
Layer definitions:
{LAYER_CRITERIA_FROM_ANALYSIS_LAYERS_MD}
Use grepai_search FIRST for file discovery, then Glob/Grep for verification.
For paths mode, scope analysis to: {SCOPED_PATHS}
Output format:
## Etalon Candidates
| Class | Path | Why Etalon | Score (1-10) |
## Naming Conventions
| Pattern | Example | Frequency |
## Directory Rules
| Rule | Path Pattern |
## Patterns (code snippets, max 3, 5-15 lines each)
### Pattern Name
` ```code```
Why: explanation
## Anti-Patterns
| Class | Problem | Fix |---
P3: Etalon Selection (1 architect agent)
After all P2 agents complete, spawn 1 architect agent with combined results.
Prompt:
Receive analysis from 10 layer-analysis agents. Select 1-2 etalons per layer based on:
- Highest score from candidates
- Most complete pattern coverage
- Best naming convention adherence
- Fewest anti-patterns
If same class appears as etalon for multiple layers, assign to most relevant layer.
Input: {ALL_10_AGENT_OUTPUTS}
Output:
## Final Etalon Summary
| Layer | Etalon Class | Path | Score | Role |
## Conflict Resolutions
| Class | Claimed By | Assigned To | Reason |
## Coverage Gaps
| Layer | Issue | Recommendation |---
P4: Document Generation (3 developer agents, PARALLEL)
Read references/conventions-guide.md for templates. Spawn 3 developer agents in ONE message.
| # | Document | Target |
|---|---|---|
| 1 | .claude/convention/reference-patterns.md | ~300 lines -- main code layers (L4-L11, L14): etalons, patterns, anti-patterns, quick reference |
| 2 | .claude/convention/testing-conventions.md | ~150 lines -- test layers (T1-T6): test etalons, patterns, assertion conventions |
| 3 | .claude/convention/project-architecture.md | ~200 lines -- build layers (L1-L3, L12-L13): build, deps, codegen, migrations, structure |
Per-agent prompt:
Generate {DOCUMENT_NAME} following the template from conventions-guide.
Target structure: {TEMPLATE_FROM_CONVENTIONS_GUIDE}
Etalon selection: {P3_ETALON_SUMMARY}
Layer analyses: {RELEVANT_P2_OUTPUTS}
Stack: {DETECTED_STACK}
Write to: .claude/convention/{filename}.md
Structure: organized by layer -- each with Etalon Classes table, Patterns (5-15 lines each, max 3/layer), Anti-Patterns table, Quick Reference table at end.
Target: ~{LINE_COUNT} lines.---
P5: Text Optimization
IF text-optimizer agent is available (brewtools installed):
Spawn 3 text-optimizer agents in ONE message (medium mode):
Task(subagent_type="text-optimizer", prompt="FIRST: Read $BT_PLUGIN_ROOT/skills/text-optimize/references/rules-review.md. THEN optimize .claude/convention/reference-patterns.md using medium mode. Output report with metrics.")
Task(subagent_type="text-optimizer", prompt="FIRST: Read $BT_PLUGIN_ROOT/skills/text-optimize/references/rules-review.md. THEN optimize .claude/convention/testing-conventions.md using medium mode. Output report with metrics.")
Task(subagent_type="text-optimizer", prompt="FIRST: Read $BT_PLUGIN_ROOT/skills/text-optimize/references/rules-review.md. THEN optimize .claude/convention/project-architecture.md using medium mode. Output report with metrics.")ELSE (brewtools not installed -- fallback):
Read ${CLAUDE_SKILL_DIR}/../convention/references/text-optimize-fallback.md for compact rules. Apply rules manually to all 3 generated documents.
---
P6: User Review
Present summary:
## Convention Documents Generated
| Document | Lines | Key Etalons (top 5) |
|----------|-------|---------------------|
| reference-patterns.md | {N} | {class1}, {class2}, ... |
| testing-conventions.md | {N} | {class1}, {class2}, ... |
| project-architecture.md | {N} | {file1}, {file2}, ... |AskUserQuestion options:
- A: Approve all -- continue to rules extraction
- B: Revise -- provide feedback (max 2 iterations, re-run P5 after edits)
- C: Skip to rules -- jump to P7
---
P7: Rules Organization
Read references/rules-guide.md for interactive flow.
Step 7.1: Extract Rule Candidates
| Source Section | Rule Type |
|---|---|
| Anti-Patterns tables | avoid |
| Patterns sections | best-practice |
| Naming Conventions | best-practice |
| Constraints | avoid |
Step 7.2: Duplicate Detection
Read existing .claude/rules/*.md files.
| Similarity | Action |
|---|---|
| >70% | Skip (already covered) |
| 40-70% | Merge into existing entry |
| <40% | New rule candidate |
Step 7.3: Interactive Batching
Present 5-7 rules per batch via AskUserQuestion:
## Rules Batch {N}/{TOTAL}
| # | Type | Rule | Target File |
|---|------|------|-------------|
| 1 | avoid | ... | {prefix}-avoid.md |
| 2 | bp | ... | {prefix}-best-practice.md |
Options: Accept all | Select by number | Skip batch | StopStep 7.4: Spawn bc-rules-organizer
Spawn bc-rules-organizer per references/rules-guide.md Section 4. Pass {ACCEPTED_RULES_JSON} from interactive batching.
---
P7.5: Update Project CLAUDE.md
AskUserQuestion: "Update project CLAUDE.md with etalon summary table + convention references?"
- A: Yes -- add etalon table + lazy-load refs
- B: No -- skip
If yes: 1. Read project CLAUDE.md 2. Find or create ## Reference Patterns & Etalon Classes section 3. Add/update:
## Reference Patterns & Etalon Classes
> **Full doc**: `.claude/convention/reference-patterns.md` (lazy-load when writing new code)
| When writing... | Copy from (etalon) |
|-----------------|---------------------|
| {role} | `{ClassName}` -- {key traits} |
### DTO Evolution (prefer top)
1. **{preferred}** -- PREFER for new code
2. **{established}** -- OK for complex entities
3. **{legacy}** -- AVOID4. Use Edit tool -- preserve all existing CLAUDE.md content.
---
P8: Output Summary
## Convention Analysis Complete
| Document | Path | Lines | Key Etalons |
|----------|------|-------|-------------|
| reference-patterns.md | `.claude/convention/reference-patterns.md` | {N} | {list} |
| testing-conventions.md | `.claude/convention/testing-conventions.md` | {N} | {list} |
| project-architecture.md | `.claude/convention/project-architecture.md` | {N} | {list} |
| When writing... | Copy from... |
|-----------------|-------------|
| {condensed top etalons} | {class} |
| Metric | Value |
|--------|-------|
| Rules extracted | {X} |
| Rules applied | {Y} |
| Duplicates skipped | {Z} |
Next Steps: Review `.claude/convention/` | `/brewcode:convention rules` to re-extract later | `/brewcode:convention paths src/new-module` for new modules---
Error Handling
| Condition | Action |
|---|---|
| No source files found | Exit: "No source files found for {STACK}" |
rules mode without .claude/convention/ | Exit: "Run /brewcode:convention conventions first" |
| >1000 source files | Warn user, suggest paths mode |
| Unknown stack | Continue with generic analysis (no stack-specific layers) |
| Agent timeout | Log warning, continue with available results |
| grepai unavailable | Fall back to Glob + Grep for file discovery |
| Convention doc generation fails | Retry once, then present partial results |
</instructions>
MIT License
Copyright (c) 2025-2026 Maxim Kochetkov (kochetkov-ma)
https://github.com/kochetkov-ma/claude-brewcode
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Convention
Analyzes a project codebase to extract etalon (reference) classes, coding patterns, and architecture conventions by layer. Produces structured documentation in .claude/convention/ and organizes extracted rules into .claude/rules/.
Quick Start
/brewcode:conventionRuns the full pipeline: detect stack, analyze all layers, generate convention docs, optimize text, review with user, extract rules, update CLAUDE.md.
Modes
| Mode | Invocation | What it does |
|---|---|---|
full (default) | /brewcode:convention | Complete analysis: docs + rules + CLAUDE.md update (P0-P8) |
conventions | /brewcode:convention conventions | Generate convention docs only, skip rules extraction (P0-P7) |
rules | /brewcode:convention rules | Re-extract rules from existing convention docs (P0, P7-P8). Requires .claude/convention/ to exist |
paths | /brewcode:convention paths src/a,src/b | Full analysis scoped to specified comma-separated paths (P0-P7) |
Examples
Good Usage
# First-time full analysis of the entire project
/brewcode:convention
# Analyze only specific modules after adding a new service
/brewcode:convention paths src/payment,src/billing
# Regenerate conventions without touching rules
/brewcode:convention conventions
# Refresh rules after manually editing convention docs
/brewcode:convention rules
# Scope analysis to test directories only
/brewcode:convention paths src/test,src/integrationTestCommon Mistakes
# Running rules mode before generating convention docs -- will fail
/brewcode:convention rules
# Fix: run `/brewcode:convention conventions` first, then `/brewcode:convention rules`
# Providing paths without the keyword -- interpreted as full mode
/brewcode:convention src/main
# Fix: always prefix with `paths` keyword
/brewcode:convention paths src/main
# Using spaces instead of commas for multiple paths
/brewcode:convention paths src/a src/b
# Fix: comma-separated, no spaces
/brewcode:convention paths src/a,src/bPhases
| Phase | Name | Agents | Output |
|---|---|---|---|
| P0 | Stack + Scan | -- | Detect tech stack, scan project structure, setup .claude/convention/ |
| P1 | Load Layers | -- | Filter analysis layers (L1-L14, T1-T6) by detected stack |
| P2 | Layer Analysis | 10 parallel (architect + tester) | Etalon candidates, patterns, naming conventions, anti-patterns |
| P3 | Etalon Selection | 1 architect | Final etalon summary with conflict resolution |
| P4 | Doc Generation | 3 parallel developer | Three convention documents |
| P5 | Text Optimization | 3 parallel text-optimizer (brewtools) | Token-efficient versions of all docs (requires brewtools plugin) |
| P6 | User Review | -- | Approve, revise (up to 2 iterations), or skip to rules |
| P7 | Rules Organization | bc-rules-organizer | Interactive rule extraction into .claude/rules/ |
| P7.5 | CLAUDE.md Update | -- | Optional etalon summary table in project CLAUDE.md |
| P8 | Summary | -- | Final report with metrics |
Output
.claude/convention/
reference-patterns.md # Main code layers (L4-L11, L14): etalons, patterns, anti-patterns
testing-conventions.md # Test layers (T1-T6): test etalons, assertion conventions
project-architecture.md # Build layers (L1-L3, L12-L13): build config, deps, migrations
.claude/rules/
{prefix}-avoid.md # Extracted anti-patterns as avoid rules
{prefix}-best-practice.md # Extracted best practices as rulesRules extraction uses a 3-Check Deduplication Protocol:
| Check | Threshold | Action |
|---|---|---|
| Within-file similarity | >70% | Skip (already covered) |
| Within-file similarity | 40-70% | Merge into existing entry |
| Cross-file antonym | avoid vs best-practice | Keep avoid only |
| CLAUDE.md duplicate | Exists in CLAUDE.md | Skip |
Tips
- When to run: After initial project setup, after major refactoring, or when onboarding new team conventions. Re-run
rulesmode after manually editing convention docs. - Large projects (>1000 files): The skill warns automatically. Use
pathsmode to scope analysis to specific modules for faster, more focused results. - Iterative workflow: Start with
conventionsmode to review docs first. Once satisfied, runrulesmode separately. This gives you full control over what gets promoted to rules. - Supported stacks: Java, Kotlin, TypeScript, Python, Rust, Go, and multi-stack projects. Unknown stacks get generic analysis across all layers.
Documentation
Full docs: convention
Analysis Layers
20 layers (14 main + 6 test) for project convention extraction.
Main Layers (L1–L14)
| ID | Layer | File Patterns | Analyze | Etalon Criteria | Naming | Stack Notes |
|---|---|---|---|---|---|---|
| L1 | Build | pom.xml, build.gradle*, Makefile, Cargo.toml | Build tool/version, plugin config, profiles, multi-module structure | Clean plugin org (build vs reporting), consistent property mgmt, proper profile separation (dev/test/prod), correct multi-module inheritance | pom.xml, build.gradle.kts, Makefile, Cargo.toml | Java: Maven/Gradle plugins, BOM imports \ |
| L2 | Dependencies | pom.xml, package.json, requirements.txt, go.mod | BOM/platform imports, shared vs module-specific deps, version property strategy, vulnerability/license compliance | BOM-first version mgmt, no duplicate version declarations, clear compile/test/runtime scope separation, minimal direct version overrides | version props: {lib}.version, BOM: *-bom, *-dependencies | Java: <dependencyManagement>, Spring Boot BOM \ |
| L3 | CodeGen | **/openapi*, **/jooq*, **/proto*, **/codegen* | Generator types (OpenAPI, JOOQ, protobuf, GraphQL), config org, output dir conventions, custom templates | Generator config separated from build config, output in generated-sources, clean build lifecycle integration | openapi-generator-config.yml, jooq-config.xml, output: target/generated-sources/{generator}/ | Java: maven-plugin execution \ |
| L4 | Utilities | **/util*, **/common*, **/shared*, **/helpers* | @UtilityClass vs static vs singleton, converter patterns, shared constants/enums, cross-module reuse | @UtilityClass or equivalent static-only pattern, no DI deps, clear single responsibility, follows project naming | *Utils, *Helper, *Converter, *Support, *Constants | Java: @UtilityClass (Lombok) \ |
| L5 | Controllers | **/controller*, **/resource*, **/handler*, **/route* | DI style, security annotations, HTTP mapping approach (generated interface vs manual), error handling, response types | Constructor injection with @RequiredArgsConstructor, implements generated API interface or clean manual endpoints, security annotations per method | *Controller, *Resource, *Api, *Handler | Java: Spring MVC @RestController \ |
| L6 | Services | **/service* | DI patterns, transaction boundaries, interface+impl separation, Stream API vs loops, error handling strategy | @RequiredArgsConstructor + final fields, clear interface/impl separation, Stream API over loops, proper @Transactional boundaries, single responsibility | *Service, *ServiceImpl, *UseCase, *Interactor | Java: @Service, @Transactional \ |
| L7 | Providers/Clients | **/client*, **/provider*, **/gateway*, **/adapter* | Client type (Feign, RestTemplate, WebClient), resilience patterns, fallback strategies, integration facade wrapping | Declarative client (@FeignClient or equiv), resilience on every method (@CircuitBreaker + @RateLimiter), integration facade with null guards/logging/conversion, clean fallbacks | *Client, *Provider, *Gateway, *Adapter | Java: @FeignClient, Resilience4j \ |
| L8 | Repositories/Data | **/repositor*, **/dao*, **/store*, **/query* | Data access strategy (JOOQ, Spring Data, raw SQL, ORM), Support/Helper companions, mapper patterns, dynamic query building (noCondition), multi-DB support | Support @UtilityClass with field constants and mappers, clean dynamic condition building, proper PREWHERE/WHERE separation (ClickHouse), interface+impl for multiple backends | *Repository, *RepositoryImpl, *Support, *Dao | Java: JOOQ DSL, Spring Data JPA, @Repository \ |
| L9 | Business Logic | **/domain/service*, **/rules*, **/engine*, **/workflow* | Domain service vs application service patterns, rule engines, validation strategies, domain event handling | Pure domain logic (no infrastructure deps), clear validation rules, immutable domain operations, strategy/specification patterns where appropriate | *DomainService, *Rule, *Engine, *Calculator, *Validator | Java: DDD patterns, Spring \ |
| L10 | DTOs | **/dto*, **/model*, **/request*, **/response* | DTO style (records, @Value @Builder, mutable), naming conventions, validation annotations, nested DTOs | Immutable (records or @Value @Builder), clear suffix conventions (Request, Response, Filter), compact constructors with validation, no business logic | *Request, *Response, *Dto, *Filter, *View | Java: records (preferred), @Value @Builder \ |
| L11 | Entities | **/entity*, **/domain/model*, **/schema* | Entity style (@Value @Builder, records, JPA @Entity), ID strategy (generated/natural/composite), relationship mapping, evolution toward immutable | Entity suffix consistently applied, immutable where possible, clean constructor with required field validation, no @Data on entities | *Entity, domain models: descriptive nouns without suffix | Java: @Value @Builder, records, JPA @Entity \ |
| L12 | Migrations | **/migration*, **/db*, **/liquibase*, **/flyway* | Migration tool (Flyway, Liquibase, raw DDL, Alembic), naming conventions (versioned vs repeatable), schema mgmt strategy, data migration patterns | Consistent naming V{N}__{description}.sql or changelog format, separate DDL from DML, idempotent repeatable migrations, proper FK-safe table ordering | V{N}__{desc}.sql, {N}-{desc}.xml, *_ddl_v{N}.sql | Java: Flyway/Liquibase \ |
| L13 | Resources | **/resources/**, **/static/**, **/templates/** | Config file org (application.yml, profiles), template engine usage, static asset mgmt, property naming conventions | Profile-based config separation, consistent property naming (kebab-case for Spring), no secrets in committed configs, clear template org | application-{profile}.yml, bootstrap.yml, *.properties | Java: Spring profiles, YAML \ |
| L14 | Infrastructure | **/config*, **/security*, **/cache*, **/scheduling* | @Configuration patterns, security config (OAuth2, JWT, RBAC), cache strategy (local + distributed), scheduling patterns, cross-cutting concerns (AOP, interceptors) | Focused @Configuration (one concern per class), role-based security, dual cache (Caffeine + Redis), scheduled jobs with locks and feature flags, clean @ConditionalOnProperty | *Configuration, *Config, *SecurityConfig, *CacheConfig | Java: @Configuration, @EnableScheduling \ |
L6/L9 Overlap: L9 (Business Logic) applies only when project has explicitdomain/service/,rules/,engine/packages (DDD structure). Otherwise, merge L9 analysis into L6 (Services) findings.
Test Layers (T1–T6)
| ID | Layer | File Patterns | Analyze | Etalon Criteria | Naming | Stack Notes |
|---|---|---|---|---|---|---|
| T1 | Test Data | **/test**/datasets/**, **/test**/fixtures/**, **/test**/data/** | Data format (CSV, JSON, SQL, YAML), organization (per-test vs shared), placeholder/variable substitution, table ordering for FK constraints | Organized by feature/module, placeholder substitution for dynamic values, table-ordering.txt for FK-safe loading, minimal dataset per test | {feature}/{test-name}/, table-ordering.txt, *.csv | Java: DBRider CSV/JSON, @DataSet \ |
| T2 | Base Classes | **/test**/Base*, **/test**/Abstract* | Test hierarchy (base → domain-specific → concrete), shared setup (@BeforeAll, @BeforeEach), container mgmt (Testcontainers), composite annotations | Clear hierarchy (max 2-3 levels), composite annotations for common setup, Testcontainers in base class, cache cleanup in base setup | Base*IntegrationTest, Abstract*Test | Java: @SpringBootTest, Testcontainers \ |
| T3 | Test Helpers | **/test**/support*/**, **/test**/util*/** | Helper types (mock builders, assertion helpers, data generators), test client wrappers, WireMock setup utilities, view refresh helpers | Focused single-responsibility helpers, @UtilityClass for stateless helpers, clean API for test setup, reused across multiple test classes | *TestSupport, *TestHelper, *TestClient, *TestUtils | Java: @UtilityClass, test builders \ |
| T4 | Data Preparation | **/test**/*Expected*, **/test**/*Requests* | ExpectedData patterns (inner classes per scenario, constants), Requests companion classes (factory methods), three-class structure (Test + ExpectedData + Requests) | @UtilityClass with inner class per scenario, named constants over magic values, factory methods for request building, complete three-class triad for endpoint testing | *ExpectedData, *Requests, *TestData | Java: @UtilityClass, inner classes \ |
| T5 | Test Classes | **/test**/*Test.*, **/test**/*Spec.* | BDD style (GIVEN/WHEN/THEN comments), @DisplayName usage (methods only), AssertJ patterns (.as(), satisfies, extracting), test isolation, no IF in tests | GIVEN/WHEN/THEN/AND in every test, @DisplayName on methods only ("should..." sentences), .as() on every AssertJ assertion, no conditional logic, clean setup/teardown | *Test, *IntegrationTest, *Spec | Java: JUnit5, AssertJ, @DisplayName \ |
| T6 | Test Parameters | **/test**/*Factory*, **/test**/*Provider*, **/test**/*Source* | @ParameterizedTest with @MethodSource/@CsvSource, negative test factories, data provider patterns, stream-based test data generation | Interface-based factories for reusable test data streams, clear naming (*TestFactory, *TestProvider), @MethodSource with descriptive method names, negative test patterns (401/403/422) via shared factories | *TestFactory, *TestProvider, *Arguments, Negative*TestFactories | Java: @ParameterizedTest, @MethodSource \ |
Conventions Guide
Document templates and generation rules for convention output files.
1. General Rules
| Rule | Details |
|---|---|
| Code snippets | Max 5-15 lines, stripped indentation, max 3 per layer |
| Tables | Use for etalons, patterns, anti-patterns |
| Cross-references | Lazy-load: > See: testing-conventions.md#section |
| No duplicates | Each pattern in ONE doc only |
| Headers | Max 3 levels (##, ###, ####) |
| Imperative form | "Use X" not "You should use X" |
| No filler | Cut "please note", "it's important", "remember to" |
| Status markers | ✅ ❌ ⚠️ only |
2. reference-patterns.md Template (~300 lines)
Structure follows .claude/convention/reference-patterns-example.md if available in workspace (optional -- not included in plugin distribution).
# Reference Patterns & Etalon Classes
> Comprehensive reference for developers. Organized by layer with etalon classes and code snippets.
## {N}. {Layer Name} Layer
### Etalon Classes
| Aspect | Etalon | Path |
|--------|--------|------|
| {aspect} | `{ClassName}` | `{relative/path}` |
### Patterns
**{N}. {Pattern Name}:** {1-line description}. Etalon: `{ClassName}`
// 5-15 lines of actual code from etalon class
| Variant | Usage | Etalon |
|---------|-------|--------|
| {approach} | {when to use} | `{ClassName}` |
### Anti-Patterns (Avoid)
| Class | Problem | Fix |
|-------|---------|-----|
| `{ClassName}` | {what's wrong} | {how to fix} |
## Quick Reference: Top Etalons by Role
| When writing... | Copy from... |
|-----------------|-------------|
| New {component type} | `{EtalonClass}` |Layers to Include
| Priority | Layers | Content Focus |
|---|---|---|
| Required | L5 Controllers | REST, security, DI, OpenAPI |
| Required | L8 Repositories | Data access, mappers, dynamic queries |
| Required | L6+L9 Services | DI, transactions, business logic |
| Required | L14 Infrastructure | Config, security, cache, scheduling |
| Required | L10+L11 DTOs/Entities | Immutability, naming, evolution |
| Optional | L4 Utilities | Helpers, converters (if significant) |
| Optional | L7 Providers | Clients, resilience (if project uses) |
Quality Rules
| Check | Requirement |
|---|---|
| Etalon per layer | 1-2 primary etalons minimum |
| Code snippets | Real code from etalon files, 5-15 lines |
| Anti-patterns | At least 1 per major layer (L5, L6, L8) |
| Quick reference | Complete table at end covering all layers |
| Paths | Relative from project root |
3. testing-conventions.md Template (~150 lines)
# Testing Conventions & Etalon Classes
> Test patterns reference. Organized by test infrastructure layer.
## {N}. {Test Layer Name}
### Etalon Classes
| Aspect | Etalon | Path |
|--------|--------|------|
| {aspect} | `{ClassName}` | `{relative/path}` |
### Patterns
**{N}. {Pattern Name}:** {1-line description}. Etalon: `{ClassName}`
// 5-15 lines of test code
| Pattern | When | Example |
|---------|------|---------|
| {pattern} | {scenario} | `{ClassName}` |
## Quick Reference: Test Etalons
| When writing... | Copy from... |
|-----------------|-------------|
| New integration test | `{TestClass}` |
| New test data | `{ExpectedDataClass}` |Layers to Include (T1-T6)
| Layer | Content Focus |
|---|---|
| T1 Test Data | Fixtures, datasets, placeholders |
| T2 Base Classes | Hierarchy, composite annotations, containers |
| T3 Test Helpers | Utilities, mock builders, WireMock setup |
| T4 Data Preparation | ExpectedData, Requests, three-class structure |
| T5 Test Classes | BDD, assertions, @DisplayName |
| T6 Test Parameters | @ParameterizedTest, factories, negative tests |
4. project-architecture.md Template (~200 lines)
# Project Architecture & Build Conventions
> Build, dependency, codegen, migration, and structural conventions.
## 1. Build Configuration
### Etalon Files
| Aspect | File | Path |
|--------|------|------|
| {aspect} | `{filename}` | `{relative/path}` |
### Build Patterns
- {pattern description}
## 2. Dependency Management
| Strategy | Example | When |
|----------|---------|------|
| BOM import | `spring-boot-dependencies` | Framework deps |
| Property | `{lib}.version` | Direct deps |
| Category | Libraries | Version Source |
|----------|-----------|----------------|
| {category} | {libs} | {source} |
## 3. Code Generation
| Generator | Config | Output | Trigger |
|-----------|--------|--------|---------|
| {name} | `{config file}` | `{output dir}` | {when runs} |
## 4. Migrations
| Tool | Location | Naming | Format |
|------|----------|--------|--------|
| {tool} | `{path}` | `{pattern}` | {SQL/XML/YAML} |
### Schema Management Rules
- {rule}
## 5. Directory Structure
| Module | Package Structure |
|--------|-------------------|
| {module} | `{package layout}` |
src/main/java/{base}/ configuration/ controllers/ services/ repositories/ ...
## 6. Naming Conventions
| Entity Type | Pattern | Example |
|-------------|---------|---------|
| Controller | `*Controller` | `HistoryController` |
| Service | `*Service` | `ProfileKeyCloakService` |
| Repository | `*Repository` | `LoadsHistoryRepository` |
## 7. Constraints
| Constraint | Details |
|------------|---------|
| {constraint} | {explanation} |Layers to Include
| Layer | Content Focus |
|---|---|
| L1 Build | Build tool, plugins, profiles |
| L2 Dependencies | BOMs, versions, scopes |
| L3 CodeGen | Generators, configs, output |
| L12 Migrations | DDL, changelog, schema management |
| L13 Resources | Config organization, profiles |
5. Quality Checklist
| Check | Details |
|---|---|
| Etalon coverage | Every included layer has 1-2 etalons |
| Code snippets | 5-15 lines each, real code, no boilerplate |
| Anti-patterns | At least 1 per major layer (L5, L6, L8 in reference-patterns) |
| Quick reference | "When writing... / Copy from..." table in each doc |
| Cross-refs | No broken references between docs |
| No duplicates | Each pattern in exactly one doc |
| Paths | All relative from project root |
| Line targets | reference-patterns ~300, testing ~150, architecture ~200 |
| Naming | Consistent etalon class names across all docs |
| Stack-appropriate | Include only patterns relevant to detected stack |
Rules Guide
Rule extraction, deduplication, and interactive organization from convention docs.
1. Rule Extraction Flow
Convention docs → scan sections → identify patterns/anti-patterns → classify → format
| Source Section | Rule Type | Example |
|---|---|---|
| Anti-Patterns table | avoid | "Avoid @Data on entities -- Use @Value @Builder" |
| Patterns section | best-practice | "Use @RequiredArgsConstructor + final fields for DI" |
| Naming Conventions | best-practice | "Controllers: *Controller suffix" |
| Constraints | avoid | "Avoid mutable DTOs -- Use records or @Value" |
| Quick Reference | best-practice | "New repository: copy from LoadsHistoryRepository" |
Extraction Priority
| Priority | Source | Yield |
|---|---|---|
| 1 | Anti-Patterns tables (all docs) | avoid rules |
| 2 | Patterns with "AVOID" or "PREFER" markers | avoid/bp rules |
| 3 | Naming Conventions tables | bp rules |
| 4 | Constraints sections | avoid rules |
| 5 | Evolution tables (e.g., DTO Evolution) | avoid + bp rules |
2. Duplicate Detection
| Similarity | Action |
|---|---|
| >70% | Skip -- already covered |
| 40-70% | Merge into existing entry (enhance description) |
| <40% | New rule candidate |
Comparison process: read all .claude/rules/*.md → compare each candidate against ALL existing entries semantically (same intent = duplicate) → consider: same class, same pattern, same "Instead" suggestion.
When merging (40-70% similar): keep existing rule number, expand "Instead" if new info available, add "Why" if missing, do NOT create duplicate entry.
3. Interactive Batching (AskUserQuestion)
Present 5-7 rules per batch:
## Rules Batch {N}/{TOTAL}
| # | Type | Rule | Target File |
|---|------|------|-------------|
| 1 | avoid | `@Data` on entities -- use `@Value @Builder` | {stack}-avoid.md |
| 2 | bp | `@RequiredArgsConstructor` + final for DI | {stack}-best-practice.md |
| 3 | avoid | Mutable DTOs -- use records | {stack}-avoid.md |
| 4 | bp | Three-class test structure (Test+Expected+Requests) | {stack}-best-practice.md |
| 5 | bp | `.as()` on every AssertJ assertion | {stack}-best-practice.md |
Options: Accept all | Select by number (e.g., "1,3,5") | Skip batch | StopBatching Strategy
| Total Rules | Batches | Per Batch |
|---|---|---|
| 1-7 | 1 | All |
| 8-14 | 2 | 7 |
| 15-21 | 3 | 7 |
| 22+ | 4+ | 5-7 |
Target File Selection
| Rule Type | Stack | Target File |
|---|---|---|
| avoid | Java | java-avoid.md |
| avoid | TypeScript | typescript-avoid.md |
| avoid | Python | python-avoid.md |
| avoid | Generic | avoid.md |
| best-practice | Java | java-best-practice.md |
| best-practice | TypeScript | typescript-best-practice.md |
| best-practice | Python | python-best-practice.md |
| best-practice | Generic | best-practice.md |
4. bc-rules-organizer Spawn
After all batches processed, spawn with accepted rules:
Task(subagent_type="bc-rules-organizer", prompt="
Update PROJECT .claude/rules/ -- NEVER ~/.claude/rules/
Plugin templates: $BC_PLUGIN_ROOT/templates/rules/
Validation: bash \"$BC_PLUGIN_ROOT/skills/rules/scripts/rules.sh\" validate
Create missing: bash \"$BC_PLUGIN_ROOT/skills/rules/scripts/rules.sh\" create
Accepted rules:
{ACCEPTED_RULES_JSON}
Format each rule in table row:
avoid.md: | # | Avoid | Instead | Why |
best-practice.md: | # | Practice | Context | Source |
Source column: 'convention' for all extracted rules.
Check for duplicates with existing rules.
")5. CLAUDE.md Update Flow
1. AskUserQuestion: "Add etalon quick-reference table to project CLAUDE.md?"
- A: "Yes -- add etalon table + lazy-load refs"
- B: "No -- skip CLAUDE.md update"
2. If yes: read project CLAUDE.md → find/create ## Reference Patterns & Etalon Classes section → add/update:
## Reference Patterns & Etalon Classes
> **Full doc**: `.claude/convention/reference-patterns.md` (lazy-load when writing new code)
| When writing... | Copy from (etalon) |
|-----------------|---------------------|
| New controller | `{ClassName}` -- {key traits} |
| New repository | `{ClassName}` + `{SupportClass}` -- {key traits} |
| New service | `{ClassName}` -- {key traits} |
### DTO Evolution (prefer top)
1. **{preferred style}** -- PREFER for new code
2. **{established style}** -- OK for complex entities
3. **{legacy style}** -- AVOID3. Use Edit tool -- preserve ALL existing CLAUDE.md content. Keep concise: summary table + lazy-load ref only, no full patterns.
Text Optimization: Compact Rules (Fallback)
Use when brewtools is NOT installed and text-optimizer agent is unavailable.
For full rules: install brewtools plugin and use text-optimizer agent.Key Rules by Category
C -- Claude Behavior
| ID | Rule | Key Point |
|---|---|---|
| C.1 | Literal following | Instructions execute exactly as written -- be precise |
| C.3 | Positive framing | "Do Y" not "Don't do X" |
| C.5 | Descriptive over emphatic | "Use when..." not "CRITICAL: MUST..." |
| C.6 | No overengineering | Claude follows literally -- simpler is better |
| C.7 | No ALL-CAPS emphasis | Normal tone; aggressive caps causes overapplication |
T -- Token Efficiency
| ID | Rule | Key Point |
|---|---|---|
| T.1 | Tables over prose | Multi-column data ~30% savings; single-column use bullets |
| T.2 | Bullets over numbered | - (1 char) vs 1. (3 chars), ~5-10% savings |
| T.3 | One-liners for rules | bad -> good is self-documenting |
| T.4 | Inline code over blocks | Inline code for <3 lines |
| T.6 | Remove filler | Cut "please note", "it's important", "basically" |
| T.7 | Comma-separated inline | a, b, c for 3-7 short items |
| T.8 | Arrows for flow | A -> B -> C not prose sequences |
S -- Structure
| ID | Rule | Key Point |
|---|---|---|
| S.1 | XML tags for sections | <rules>...</rules> -- clear parsing boundaries |
| S.2 | Imperative form | "Do X" not "You should do X" |
| S.3 | Single source of truth | Merge duplicates; repetition wastes tokens |
| S.6 | Progressive disclosure | Overview -> details -> examples; SKILL.md <500 lines |
| S.7 | Consistent terminology | One term per concept, no synonyms |
R -- Reference Integrity
| ID | Rule | Key Point |
|---|---|---|
| R.1 | Verify file paths | Use Read/Glob to confirm before writing |
| R.2 | Check URLs | Validate accessible URLs |
P -- Perception
| ID | Rule | Key Point |
|---|---|---|
| P.1 | Examples near rules | Inline, not in appendix |
| P.2 | Max 3-4 header levels | Structured documents improve retrieval |
| P.3 | Bold for keywords | Max 2-3 per 100 lines |
| P.5 | Critical info first | First-position = strongest anchoring |
L -- LLM Comprehension
| ID | Rule | Key Point |
|---|---|---|
| L.1 | Critical info at START or END | Middle content gets 40-50% less attention |
| L.5 | Add WHY to instructions | Claude generalizes the reason to edge cases |
Self-Apply Instructions
1. Read entire text to understand context 2. Apply T.6 first (remove filler) -- easiest wins 3. Apply T.1 (convert prose lists -> tables where applicable) 4. Apply T.2-T.4 (compress remaining lists/code) 5. Apply S.2 (imperative form) 6. Verify: no information loss, all refs valid 7. Target: 20-40% token reduction
Anti-Patterns
| Avoid | Why |
|---|---|
| Remove examples | Hurts generalization (P.1) |
| Over-abbreviate | Reduces readability |
| Flatten hierarchy | Loses structure (P.2) |
| Compress domain terms | 30+ point accuracy drops (T.5) |
Compression Ratios
| Content Type | Typical Savings |
|---|---|
| Prose docs | 40-50% |
| Technical specs | 20-30% |
| System prompts | 30-40% |
#!/usr/bin/env sh
# Brewcode Convention Script — stack detection, scanning, setup, validation
# Usage: convention.sh <detect-stack|scan|setup|validate>
set -eu
usage() {
echo "Usage: convention.sh <command>"
echo ""
echo "Commands:"
echo " detect-stack Detect tech stack from build/config files"
echo " scan Scan project directory structure"
echo " setup Create .claude/convention/ directory"
echo " validate Check if convention files exist"
exit 2
}
err() { echo "$*" >&2; }
HAS_JQ=false
command -v jq >/dev/null 2>&1 && HAS_JQ=true
is_skip_dir() {
case "$1" in .*|node_modules|target|build|dist|vendor|__pycache__) return 0 ;; esac
return 1
}
# Check if dir has a build file; prints stack name if found
has_build_file() {
[ -f "$1/pom.xml" ] || [ -f "$1/build.gradle" ] || [ -f "$1/build.gradle.kts" ] || \
[ -f "$1/package.json" ] || [ -f "$1/go.mod" ] || [ -f "$1/Cargo.toml" ] || \
[ -f "$1/pyproject.toml" ] || [ -f "$1/mix.exs" ] || [ -f "$1/Gemfile" ] || \
find "$1" -maxdepth 1 \( -name '*.sln' -o -name '*.csproj' \) -print -quit 2>/dev/null | grep -q .
}
# Append stack if not already present: add_stack "java"
add_stack() {
case ",$stacks," in *",$1,"*) return ;; esac
stacks="${stacks:+$stacks,}$1"
}
detect_stack() {
stacks="" build_file="" modules=""
# Root-level detection (priority order)
if [ -f pom.xml ]; then add_stack java; build_file="pom.xml"
elif [ -f build.gradle ] || [ -f build.gradle.kts ]; then
add_stack java; build_file=$([ -f build.gradle.kts ] && echo "build.gradle.kts" || echo "build.gradle")
fi
if [ -f package.json ]; then
if [ -f tsconfig.json ] || find . -maxdepth 2 -name '*.tsx' -print -quit 2>/dev/null | grep -q .; then
add_stack typescript
else add_stack javascript; fi
[ -z "$build_file" ] && build_file="package.json"
fi
if [ -f pyproject.toml ] || [ -f setup.py ] || [ -f requirements.txt ]; then
add_stack python
if [ -z "$build_file" ]; then
if [ -f pyproject.toml ]; then build_file="pyproject.toml"
elif [ -f setup.py ]; then build_file="setup.py"
else build_file="requirements.txt"; fi
fi
fi
[ -f go.mod ] && { add_stack go; [ -z "$build_file" ] && build_file="go.mod"; }
[ -f Cargo.toml ] && { add_stack rust; [ -z "$build_file" ] && build_file="Cargo.toml"; }
if find . -maxdepth 1 \( -name '*.sln' -o -name '*.csproj' \) -print -quit 2>/dev/null | grep -q .; then
add_stack dotnet
[ -z "$build_file" ] && build_file=$(find . -maxdepth 1 \( -name '*.sln' -o -name '*.csproj' \) -print -quit 2>/dev/null | sed 's|^\./||')
fi
[ -f mix.exs ] && { add_stack elixir; [ -z "$build_file" ] && build_file="mix.exs"; }
[ -f Gemfile ] && { add_stack ruby; [ -z "$build_file" ] && build_file="Gemfile"; }
# One level deep: monorepo modules
for d in */; do
[ -d "$d" ] || continue
d_name=$(echo "$d" | sed 's|/$||')
is_skip_dir "$d_name" && continue
has_build_file "$d_name" || continue
modules="${modules:+$modules,}\"$d_name\""
[ -f "$d/pom.xml" ] || [ -f "$d/build.gradle" ] || [ -f "$d/build.gradle.kts" ] && add_stack java
if [ -f "$d/package.json" ]; then
if [ -f "$d/tsconfig.json" ]; then add_stack typescript; else add_stack javascript; fi
fi
{ [ -f "$d/pyproject.toml" ] || [ -f "$d/setup.py" ] || [ -f "$d/requirements.txt" ]; } && add_stack python
[ -f "$d/go.mod" ] && add_stack go
find "$d" -maxdepth 1 \( -name '*.sln' -o -name '*.csproj' \) -print -quit 2>/dev/null | grep -q . && add_stack dotnet
done
primary=$(echo "$stacks" | cut -d',' -f1)
if [ -z "$stacks" ]; then
stacks_json=""
else
stacks_json=$(echo "$stacks" | sed 's/,/","/g')
stacks_json="\"$stacks_json\""
fi
if $HAS_JQ; then
printf '{"stacks":[%s],"primary":"%s","build_file":"%s","modules":[%s]}' \
"$stacks_json" "$primary" "$build_file" "$modules" | jq -c .
else
printf '{"stacks":[%s],"primary":"%s","build_file":"%s","modules":[%s]}\n' \
"$stacks_json" "$primary" "$build_file" "$modules"
fi
}
scan_project() {
src_dirs=""
for d in src/main/java src/main/kotlin src/test/java src/test/kotlin \
src/main/resources src/test/resources src lib app test tests cmd pkg internal api; do
[ -d "$d" ] && src_dirs="${src_dirs:+$src_dirs,}\"$d\""
done
file_counts="" total_files=0
counts_raw=$(find . -type f -not -path '*/\.*' -not -path '*/node_modules/*' \
-not -path '*/target/*' -not -path '*/build/*' -not -path '*/__pycache__/*' \
-not -path '*/dist/*' -not -path '*/vendor/*' 2>/dev/null \
| sed 's/.*\.//' | sort | uniq -c | sort -rn | head -10)
if [ -n "$counts_raw" ]; then
while IFS= read -r line; do
count=$(echo "$line" | awk '{print $1}')
ext=$(echo "$line" | awk '{print $2}')
case "$ext" in */*|"") continue ;; esac
file_counts="${file_counts:+$file_counts,}\"$ext\":$count"
total_files=$((total_files + count))
done <<EOF
$counts_raw
EOF
fi
mod_list=""
for d in */; do
[ -d "$d" ] || continue
d_name=$(echo "$d" | sed 's|/$||')
is_skip_dir "$d_name" && continue
has_build_file "$d_name" && mod_list="${mod_list:+$mod_list,}\"$d_name\""
done
if $HAS_JQ; then
printf '{"source_dirs":[%s],"file_counts":{%s},"modules":[%s],"total_files":%d}' \
"$src_dirs" "$file_counts" "$mod_list" "$total_files" | jq .
else
printf '{"source_dirs":[%s],"file_counts":{%s},"modules":[%s],"total_files":%d}\n' \
"$src_dirs" "$file_counts" "$mod_list" "$total_files"
fi
}
setup_convention() {
mkdir -p .claude/convention
printf '{"created":"%s","path":".claude/convention/"}\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
}
validate_convention() {
errors=0 f1=false f2=false f3=false
[ -f .claude/convention/reference-patterns.md ] && f1=true || errors=$((errors + 1))
[ -f .claude/convention/testing-conventions.md ] && f2=true || errors=$((errors + 1))
[ -f .claude/convention/project-architecture.md ] && f3=true || errors=$((errors + 1))
valid=true; [ "$errors" -gt 0 ] && valid=false
if [ "$valid" = "true" ]; then err "All convention files present"
else err "Missing $errors convention file(s)"; fi
if $HAS_JQ; then
printf '{"valid":%s,"files":{"reference-patterns.md":%s,"testing-conventions.md":%s,"project-architecture.md":%s}}' \
"$valid" "$f1" "$f2" "$f3" | jq .
else
printf '{"valid":%s,"files":{"reference-patterns.md":%s,"testing-conventions.md":%s,"project-architecture.md":%s}}\n' \
"$valid" "$f1" "$f2" "$f3"
fi
return $errors
}
case "${1:-}" in
detect-stack) detect_stack ;;
scan) scan_project ;;
setup) setup_convention ;;
validate) validate_convention || exit $? ;;
*) usage ;;
esac