From 10ad8d0bf65d7078023d64cc96d615064ed26114 Mon Sep 17 00:00:00 2001 From: Tym Rabchuk Date: Mon, 6 Apr 2026 13:53:47 -0400 Subject: [PATCH 1/3] Add setup-rules command and reference rule files /devkit:setup-rules copies language-specific coding rules from resources/rules/ to ~/.claude/rules/ for auto-activation per file type. Covers Go, TypeScript, Python, Rust, Shell. Rules complement hooks: they guide how to write, hooks catch what you missed. --- README.md | 27 +++++++++++++++++++++++-- ROADMAP.md | 2 +- commands/setup-rules.md | 37 +++++++++++++++++++++++++++++++++++ resources/rules/go.md | 18 +++++++++++++++++ resources/rules/python.md | 18 +++++++++++++++++ resources/rules/rust.md | 18 +++++++++++++++++ resources/rules/shell.md | 18 +++++++++++++++++ resources/rules/typescript.md | 19 ++++++++++++++++++ 8 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 commands/setup-rules.md create mode 100644 resources/rules/go.md create mode 100644 resources/rules/python.md create mode 100644 resources/rules/rust.md create mode 100644 resources/rules/shell.md create mode 100644 resources/rules/typescript.md diff --git a/README.md b/README.md index 26fb1d1..d4d4355 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,7 @@ Verify with `/context-mode:ctx-doctor` (plugin install) or check MCP tools are a | `/devkit:audit` | Full project health audit — deps, vulnerabilities, licenses, lint, security | | `/devkit:deep-research` | ACH-enhanced deep research — competing hypotheses, directed disconfirmation, evidence matrix, sensitivity analysis | | `/devkit:status` | Health check — installed CLIs, available agents, ready commands | +| `/devkit:setup-rules` | Install language-specific coding rules to `~/.claude/rules/` | ### Self-Improvement Loops (Claude-only) @@ -205,6 +206,26 @@ Loaded as reference material when relevant: For brainstorming, planning, TDD, verification, and skill authoring — install [superpowers](https://github.com/obra/superpowers). +### Coding Rules (user-level) + +Language-specific rules that auto-activate when Claude reads matching files. Installed to `~/.claude/rules/` (not part of the plugin — plugins don't support `rules/`). These complement hooks: **rules guide how to write, hooks catch what you missed**. + +Install with one command: + +``` +/devkit:setup-rules +``` + +| File | Paths | What it covers | +|---|---|---| +| `go.md` | `**/*.go` | Error wrapping, context.Context, defer traps, import grouping, table-driven tests | +| `typescript.md` | `**/*.{ts,tsx,js,jsx,mjs,cjs}` | Type safety (unknown not any), discriminated unions, catch narrowing, nullish coalescing | +| `python.md` | `**/*.py` | Exception chains, type hints, dataclasses, pathlib, comprehensions | +| `rust.md` | `**/*.rs` | Ownership patterns, ? propagation, newtypes, iterator preference, clippy-as-errors | +| `shell.md` | `**/*.sh` | set -euo pipefail, quoting, macOS portability, subshell traps | + +Each file uses `paths:` frontmatter for scoped activation. Rules are ~10 lines each — minimal token overhead. + --- ## Hooks @@ -314,7 +335,7 @@ devkit/ │ └── plugin.json # Plugin metadata (name, version, author) ├── ROADMAP.md # Implemented features and future plans ├── PREFERENCES.md # Agent behavior guidelines -├── commands/ # 23 slash commands (tab-completable) +├── commands/ # 24 slash commands (tab-completable) │ ├── tri-*.md # Multi-agent dispatch (5) │ ├── self-*.md # Self-improvement loops (6) │ ├── pr-ready.md # PR preparation pipeline @@ -326,7 +347,8 @@ devkit/ │ ├── workflow.md # YAML workflow runner │ ├── audit.md # Project health audit │ ├── repo-map.md # AST-based symbol index -│ └── status.md # Health check +│ ├── status.md # Health check +│ └── setup-rules.md # Install coding rules to ~/.claude/rules/ ├── skills/ # 18 context-activated skills │ ├── executing/SKILL.md # Principle: methodical execution │ ├── clean-code/SKILL.md # Principle: readability @@ -364,6 +386,7 @@ devkit/ │ ├── lang-review.sh # Language-aware code quality (Go/TS/Rust/Python/Shell) │ ├── subagent-stop.sh # Subagent work verification │ └── stop-gate.sh # Consolidated quality gate (cross-domain + vet/lint) +├── resources/rules/ # Reference rule files (installed via /devkit:setup-rules) ├── workflows/ # 15 YAML workflow definitions ├── presets/ # Reserved for future use ├── .github/workflows/ # CI/CD diff --git a/ROADMAP.md b/ROADMAP.md index c1cd853..c52a165 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -2,7 +2,7 @@ ## Implemented -- **23 slash commands** — Lifecycle workflows, self-improvement loops, multi-agent dispatch, project health audit, post-PR monitoring, AST repo mapping, autoresearch-inspired self-audit, autoloop +- **24 slash commands** — Lifecycle workflows, self-improvement loops, multi-agent dispatch, project health audit, post-PR monitoring, AST repo mapping, autoresearch-inspired self-audit, autoloop, setup-rules - **18 context-activated skills** — 9 auto-trigger workflows (test-gen, doc-gen, changelog, onboard, research, deep-research, scrape, autoloop, adr) + 6 coding principles (executing, clean-code, DRY, YAGNI, dont-reinvent, stuck) + 2 tools (gcli, creating-workflows) + 1 iteration memory (scratchpad) - **6 agents** — Scoped tool access, worktree isolation, model assignment - **10 hooks** — Safety (destructive command blocking, edit-time security patterns, PR gate), observability (audit trail, slop detection, post-validation, subagent verification, language-aware code review), optimization (RTK token compression) diff --git a/commands/setup-rules.md b/commands/setup-rules.md new file mode 100644 index 0000000..679835d --- /dev/null +++ b/commands/setup-rules.md @@ -0,0 +1,37 @@ +--- +description: Install devkit coding rules to ~/.claude/rules/ for language-specific auto-activation +--- + +# Setup Coding Rules + +Install language-specific coding rules to `~/.claude/rules/`. These auto-activate when Claude reads matching files and complement devkit's hooks — rules guide *how to write*, hooks catch *what you missed*. + +## What it does + +Copies rule files from this plugin's `resources/rules/` to `~/.claude/rules/`. Existing files are overwritten (the plugin version is the source of truth). + +## Steps + +1. Create the rules directory: + +```bash +mkdir -p ~/.claude/rules +``` + +2. Copy each rule file from the plugin: + +```bash +cp "${CLAUDE_PLUGIN_ROOT}/resources/rules/go.md" ~/.claude/rules/go.md +cp "${CLAUDE_PLUGIN_ROOT}/resources/rules/typescript.md" ~/.claude/rules/typescript.md +cp "${CLAUDE_PLUGIN_ROOT}/resources/rules/python.md" ~/.claude/rules/python.md +cp "${CLAUDE_PLUGIN_ROOT}/resources/rules/rust.md" ~/.claude/rules/rust.md +cp "${CLAUDE_PLUGIN_ROOT}/resources/rules/shell.md" ~/.claude/rules/shell.md +``` + +3. Confirm installation: + +```bash +echo "Installed rules:" && ls ~/.claude/rules/*.md +``` + +Report which files were installed. diff --git a/resources/rules/go.md b/resources/rules/go.md new file mode 100644 index 0000000..92d0f63 --- /dev/null +++ b/resources/rules/go.md @@ -0,0 +1,18 @@ +--- +paths: + - "**/*.go" +--- + +# Go Rules + +Hooks already catch: error-path result access, concurrent map without mutex, filepath traversal, nil-error returns, security patterns. These rules guide *how to write* — hooks catch *what you missed*. + +- Wrap errors: `fmt.Errorf("doing X: %w", err)` — bare `return err` loses context. +- `context.Context` first param for I/O or blocking calls. +- `defer mu.Unlock()` immediately after `mu.Lock()`. +- Table-driven tests with `t.Run`. Use `t.Helper()` in test helpers. +- One package per directory. `main.go` stays thin: flags, wiring, `run()`. +- Imports: stdlib, blank, external, blank, internal. +- `defer` in loops defers until function exit — use closure or extract. +- `json.Unmarshal` into `interface{}` gives `float64` for numbers — use concrete types. +- `range` vars reused pre-1.22 — capture in closure for goroutines. diff --git a/resources/rules/python.md b/resources/rules/python.md new file mode 100644 index 0000000..3347ed5 --- /dev/null +++ b/resources/rules/python.md @@ -0,0 +1,18 @@ +--- +paths: + - "**/*.py" +--- + +# Python Rules + +Hooks already catch: bare except, pass-in-except, mutable defaults, security patterns (eval, exec, pickle, os.system, yaml.load). These rules guide *how to write*. + +- `raise ... from err` to preserve exception chains. +- Type hints on function signatures. `X | None` over `Optional[X]`. +- `TypedDict` for dict shapes passed around, not bare `dict`. +- `dataclass` or `NamedTuple` over plain tuples/dicts for structured data. +- f-strings over `.format()`. `pathlib` over `os.path.join`. +- `with` for resource cleanup — files, locks, connections. +- Comprehensions over `map/filter` with lambdas. `enumerate()` over manual index. +- `is` only for `None`/`True`/`False`. `==` for value comparison. +- `ruff check` for linting. `ruff format` only if the project is configured for it. diff --git a/resources/rules/rust.md b/resources/rules/rust.md new file mode 100644 index 0000000..e8ec7c8 --- /dev/null +++ b/resources/rules/rust.md @@ -0,0 +1,18 @@ +--- +paths: + - "**/*.rs" +--- + +# Rust Rules + +Hooks already catch: unwrap-after-error, `let _ =` discard, unwrap on Option/Result in non-test code. These rules guide *how to write*. + +- `?` for propagation. `thiserror` for libraries, `anyhow` for applications. +- Borrow (`&T`) over clone. `&str` in params, not `String`, unless ownership needed. +- `if let` / `let else` over `match` with one interesting arm. +- Iterators over manual loops. `enum` over boolean flags. +- Newtype for type safety: `struct UserId(u64)` not bare `u64`. +- `Debug` on all structs. `Clone`/`PartialEq` only when needed. +- `to_owned()` for `&str` → `String`. `to_string()` for Display types. +- Don't fight the borrow checker with `Rc>` unless genuinely needed. +- `cargo clippy` warnings are errors. `cargo fmt` for formatting. diff --git a/resources/rules/shell.md b/resources/rules/shell.md new file mode 100644 index 0000000..937ecc0 --- /dev/null +++ b/resources/rules/shell.md @@ -0,0 +1,18 @@ +--- +paths: + - "**/*.sh" +--- + +# Shell Rules + +Hooks already catch: macOS portability (grep -P, sed -i, readlink -f, stat --format, date -d, timeout, xargs -d). These rules guide *how to write*. + +- `set -euo pipefail` always. No exceptions. +- Quote everything: `"$var"` not `$var`. `[[ ]]` not `[ ]`. +- `$(command)` not backticks. `printf` over `echo`. +- `local` for function vars. `readonly` for constants. +- `mktemp` + `trap 'rm -f "$tmpfile"' EXIT` for temp files. +- `command -v` not `which`. `${var:-default}` for defaults. +- `cd` changes dir permanently — use subshell: `(cd dir && command)`. +- Pipes create subshells — variables set in `while read | pipe` are lost. +- macOS: `sed -i ''`, `grep -E`, no `readlink -f`/`timeout`/`xargs -d`. diff --git a/resources/rules/typescript.md b/resources/rules/typescript.md new file mode 100644 index 0000000..5ffe1e3 --- /dev/null +++ b/resources/rules/typescript.md @@ -0,0 +1,19 @@ +--- +paths: + - "**/*.{ts,tsx,js,jsx,mjs,cjs}" +--- + +# TypeScript / JavaScript Rules + +Hooks already catch: empty catch blocks, unhandled promises, `any` usage, security patterns (eval, innerHTML, etc). These rules guide *how to write*. + +- `unknown` not `any`. Narrow with type guards. +- Discriminated unions over optional fields when exactly one variant applies. +- `catch (e: unknown)` and narrow — never `catch (e: any)`. +- `try/catch` at boundaries (API route, handler), not deep in logic. +- `const` over `let`. Never `var`. Named exports over default. +- `async/await` over `.then()` chains. +- Options object when 3+ params: `fn({ name, age, role })`. +- Early returns to flatten nesting. `??` over `||` when 0/"" are valid. +- `===` always. `JSON.parse` returns `any` — type immediately or validate (zod/valibot). +- `Array.sort()` mutates and sorts lexicographically — always pass comparator. From 3640babb9befa353ab0404d1872f614c769d2c0e Mon Sep 17 00:00:00 2001 From: Tym Rabchuk Date: Mon, 6 Apr 2026 13:56:23 -0400 Subject: [PATCH 2/3] Fix README table accuracy and add overwrite warning Comment-analyzer findings: table summaries were selective (renamed column to "Examples"), line count was slightly off (~10 rules, ~20 lines), and setup-rules command needed overwrite warning for customized rules. --- README.md | 14 +++++++------- commands/setup-rules.md | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index d4d4355..42c38b4 100644 --- a/README.md +++ b/README.md @@ -216,15 +216,15 @@ Install with one command: /devkit:setup-rules ``` -| File | Paths | What it covers | +| File | Paths | Examples (see file for full list) | |---|---|---| -| `go.md` | `**/*.go` | Error wrapping, context.Context, defer traps, import grouping, table-driven tests | -| `typescript.md` | `**/*.{ts,tsx,js,jsx,mjs,cjs}` | Type safety (unknown not any), discriminated unions, catch narrowing, nullish coalescing | -| `python.md` | `**/*.py` | Exception chains, type hints, dataclasses, pathlib, comprehensions | -| `rust.md` | `**/*.rs` | Ownership patterns, ? propagation, newtypes, iterator preference, clippy-as-errors | -| `shell.md` | `**/*.sh` | set -euo pipefail, quoting, macOS portability, subshell traps | +| `go.md` | `**/*.go` | Error wrapping, context.Context, defer traps, JSON float64 gotcha, range var reuse | +| `typescript.md` | `**/*.{ts,tsx,js,jsx,mjs,cjs}` | unknown not any, discriminated unions, catch narrowing, nullish coalescing, sort mutation | +| `python.md` | `**/*.py` | Exception chains, type hints, dataclasses, pathlib, ruff, is vs == | +| `rust.md` | `**/*.rs` | Ownership/borrowing, ? propagation, newtypes, if let/let else, clippy-as-errors | +| `shell.md` | `**/*.sh` | set -euo pipefail, quoting, macOS portability, subshell traps, mktemp + trap | -Each file uses `paths:` frontmatter for scoped activation. Rules are ~10 lines each — minimal token overhead. +Each file uses `paths:` frontmatter for scoped activation. ~10 rules per file, ~20 lines — minimal token overhead. --- diff --git a/commands/setup-rules.md b/commands/setup-rules.md index 679835d..e709c2d 100644 --- a/commands/setup-rules.md +++ b/commands/setup-rules.md @@ -8,7 +8,7 @@ Install language-specific coding rules to `~/.claude/rules/`. These auto-activat ## What it does -Copies rule files from this plugin's `resources/rules/` to `~/.claude/rules/`. Existing files are overwritten (the plugin version is the source of truth). +Copies rule files from this plugin's `resources/rules/` to `~/.claude/rules/`. Existing files are overwritten — if the user has customized rules, warn them before overwriting. `CLAUDE_PLUGIN_ROOT` is set automatically by the Claude Code plugin runtime. ## Steps From 62c3dbc604a142ec9dee0375ce74e9d88b3c61ef Mon Sep 17 00:00:00 2001 From: Tym Rabchuk Date: Mon, 6 Apr 2026 13:56:55 -0400 Subject: [PATCH 3/3] Add CLAUDE_PLUGIN_ROOT guard and overwrite check to setup-rules Code-reviewer finding: cp commands would silently fail if variable unset. Also adds step to warn before overwriting customized rules. --- commands/setup-rules.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/commands/setup-rules.md b/commands/setup-rules.md index e709c2d..e87649c 100644 --- a/commands/setup-rules.md +++ b/commands/setup-rules.md @@ -12,13 +12,21 @@ Copies rule files from this plugin's `resources/rules/` to `~/.claude/rules/`. E ## Steps -1. Create the rules directory: +1. Verify plugin context and create the rules directory: ```bash +if [ -z "${CLAUDE_PLUGIN_ROOT:-}" ]; then + echo "ERROR: CLAUDE_PLUGIN_ROOT is not set. Run this as /devkit:setup-rules." >&2 + exit 1 +fi mkdir -p ~/.claude/rules ``` -2. Copy each rule file from the plugin: +2. Check for existing customized rules — warn before overwriting: + +If any files in `~/.claude/rules/` differ from the plugin versions, tell the user which files will be overwritten and ask for confirmation before proceeding. + +3. Copy each rule file from the plugin: ```bash cp "${CLAUDE_PLUGIN_ROOT}/resources/rules/go.md" ~/.claude/rules/go.md @@ -28,7 +36,7 @@ cp "${CLAUDE_PLUGIN_ROOT}/resources/rules/rust.md" ~/.claude/rules/rust.md cp "${CLAUDE_PLUGIN_ROOT}/resources/rules/shell.md" ~/.claude/rules/shell.md ``` -3. Confirm installation: +4. Confirm installation: ```bash echo "Installed rules:" && ls ~/.claude/rules/*.md