Commit c6a61bc
Add code quality automation: analyzers, Dependabot auto-merge, PR labeler, multi-agent Claude review
Three layers of automation, each with its own ai-docs/implementations/ writedown.
Code quality enforcement
- Directory.Build.props: AnalysisLevel=latest-recommended +
EnforceCodeStyleInBuild=true + GenerateDocumentationFile=true. Combined with
the existing TreatWarningsAsErrors=true, the curated Microsoft analyzer set
now fails the build (and CI).
- New root .editorconfig tunes per-rule severities so the level-up is workable
on a WPF + native-interop codebase (silences CA1051 on the Signal hot-path
struct, CA1859 in WPF builder methods, IDE0051 around Win32 documentary
constants, etc., each with a one-line rationale).
- Surfaced 4 real correctness fixes in interop code where return values were
being silently discarded: WaitForSingleObject (WaitableTickTimer.cs),
InterceptionNative.Send (InterceptionInputBackend.cs), GetDpiForMonitor and
SetWindowLong (MonitorInfo.cs / WindowStyles.cs).
- ~120 files auto-fixed via dotnet format style (IDE0011 add-braces, IDE0005
unused-usings, IDE0044 add-readonly) and dotnet format whitespace (CRLF
normalization). No semantic changes in the bulk pass.
Process automation
- New repo labels: dependencies, ci, feature, fix, internal, refactor, chore,
tests, docs, skip-changelog, build, plus per-project area labels (ui,
engine, input, persistence, app, virtualpad). Created via gh label create;
unblocks the 6 open Dependabot PRs that were failing to apply the
`dependencies` label.
- .github/workflows/dependabot-automerge.yml -- auto-approves and enables
GitHub's native auto-merge on patch + minor + security Dependabot PRs once
CI passes. Major versions still require manual review.
- .github/workflows/labeler.yml + .github/labeler.yml -- path-based labeling
(touches src/Mouse2Joy.UI -> ui label, etc.) plus title-based Conventional
Commit prefix labeling. Drives the existing release-notes categorization
without manual labeling.
Multi-agent Claude PR review
- .github/workflows/claude-review.yml -- listens for the existing CI
workflow's completion via workflow_run. Gates on: CI succeeded, not
Dependabot, not draft, no skip-claude-review label, diff >= 10 lines,
not docs/dependency-only. If the gate passes, runs the review pipeline.
- .github/claude-review/ -- TypeScript review script using @anthropic-ai/sdk
directly. Runs 8 reviewer agents in parallel (security, correctness,
regression, ux, stability, convention-compliance, performance, code-reuse),
each with a tool surface (get_file_diff, read_file, grep_repo, list_dir) so
they pull only what they need from the repo rather than getting the full
diff dumped in. CLAUDE.md is cached once via cache_control: ephemeral and
hits the cache across all 8 agents. Findings are validated via zod and
aggregated into a single GitHub review (event: COMMENT, advisory).
- Model: Claude Opus 4.7 with adaptive thinking and effort: "high". Per-agent
output schema enforced via output_config.format (json_schema), not just
prompt instruction.
- New skip-claude-review label as an opt-out per PR.
- .claude/skills/review-pr/SKILL.md -- companion local skill that reuses the
same 8 reviewer prompt files from .github/claude-review/reviewers/. Invoked
from a Claude Code session (`/review-pr` or via natural language) and
reports findings in the conversation instead of posting to GitHub. Single
source of truth for the reviewer prompts across CI and interactive use.
Manual setup required after merge (cannot be scripted):
- Enable repo setting "Allow auto-merge" (Settings -> General -> Pull
Requests). The dependabot-automerge workflow runs but is a no-op until
this is on.
- Add ANTHROPIC_API_KEY repo secret (Settings -> Secrets and variables ->
Actions) for the multi-agent review pipeline. Without it, the workflow
runs but posts a one-line "skipped" comment instead of reviewing.
Verification
- dotnet build Mouse2Joy.sln -c Release -- 0 errors, 0 warnings
- dotnet format --verify-no-changes -- passes
- dotnet test -- 259 passed, 0 failed
- npm run typecheck in .github/claude-review/ -- clean
- No-key smoke test of the review script -- correctly skips with one-line
exit message
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 5eb5a0b commit c6a61bc
113 files changed
Lines changed: 5226 additions & 467 deletions
File tree
- .claude/skills/review-pr
- .github
- claude-review
- reviewers
- workflows
- ai-docs/implementations
- src
- Mouse2Joy.App
- Mouse2Joy.Engine
- Hotkeys
- Mapping
- Modifiers
- Evaluators
- SourceAdapters
- State
- Threading
- Mouse2Joy.Input
- Mouse2Joy.Persistence
- Migration
- Models
- Mouse2Joy.UI
- Controls
- Interop
- Overlay
- Widgets
- Tooltips
- ViewModels
- Editor
- Views
- Editor
- Mouse2Joy.VirtualPad
- tests
- Mouse2Joy.Engine.Tests
- Modifiers
- Mouse2Joy.Persistence.Tests
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
0 commit comments