ga-plugins-cli 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config-patcher.d.ts +20 -50
- package/dist/config-patcher.d.ts.map +1 -1
- package/dist/config-patcher.js +138 -102
- package/dist/config-patcher.js.map +1 -1
- package/dist/index.js +75 -22
- package/dist/index.js.map +1 -1
- package/dist/installer.d.ts +0 -18
- package/dist/installer.d.ts.map +1 -1
- package/dist/installer.js +19 -39
- package/dist/installer.js.map +1 -1
- package/dist/types.d.ts +10 -6
- package/dist/types.d.ts.map +1 -1
- package/dist/uninstaller.d.ts +0 -23
- package/dist/uninstaller.d.ts.map +1 -1
- package/dist/uninstaller.js +22 -68
- package/dist/uninstaller.js.map +1 -1
- package/package.json +3 -2
- package/plugins/go-reviewer/.claude-plugin/plugin.json +12 -0
- package/plugins/go-reviewer/commands/go-review.md +424 -0
- package/plugins/go-reviewer/mcp-servers/go-reviewer-mcp/README.md +236 -0
- package/plugins/go-reviewer/mcp-servers/go-reviewer-mcp/main.go +678 -0
- package/plugins/go-scaffolder/.claude-plugin/plugin.json +12 -0
- package/plugins/go-scaffolder/commands/scaffold-service.md +802 -0
- package/plugins/go-scaffolder/reference-service/.env.example +27 -0
- package/plugins/go-scaffolder/reference-service/Dockerfile +55 -0
- package/plugins/go-scaffolder/reference-service/REFERENCE-SERVICE-NOTICE.md +104 -0
- package/plugins/go-scaffolder/reference-service/cmd/server/main.go +266 -0
- package/plugins/go-scaffolder/reference-service/config/config.go +67 -0
- package/plugins/go-scaffolder/reference-service/go.mod +17 -0
- package/plugins/go-scaffolder/reference-service/internal/domain/booking.go +118 -0
- package/plugins/go-scaffolder/reference-service/internal/handler/booking.go +242 -0
- package/plugins/go-scaffolder/reference-service/internal/handler/booking_test.go +451 -0
- package/plugins/go-scaffolder/reference-service/internal/repository/booking_postgres.go +124 -0
- package/plugins/go-scaffolder/reference-service/internal/usecase/booking.go +181 -0
- package/plugins/go-standards/.claude-plugin/plugin.json +22 -0
- package/plugins/go-standards/commands/go-standards-check.md +232 -0
- package/plugins/go-standards/skills/concurrency.md +336 -0
- package/plugins/go-standards/skills/config.md +267 -0
- package/plugins/go-standards/skills/error-handling.md +286 -0
- package/plugins/go-standards/skills/http-chi.md +390 -0
- package/plugins/go-standards/skills/logging-observability.md +340 -0
- package/plugins/go-standards/skills/naming-and-style.md +315 -0
- package/plugins/go-standards/skills/project-layout.md +313 -0
- package/plugins/go-standards/skills/testing.md +366 -0
- package/plugins/java2go-porter/.claude-plugin/plugin.json +21 -0
- package/plugins/java2go-porter/agents/analyzer.md +232 -0
- package/plugins/java2go-porter/agents/reviewer.md +241 -0
- package/plugins/java2go-porter/agents/test-pairer.md +365 -0
- package/plugins/java2go-porter/agents/translator.md +419 -0
- package/plugins/java2go-porter/commands/port-java-service.md +149 -0
- package/plugins/java2go-porter/skills/idiom-mapping.md +75 -0
- package/plugins/migration-safety/.claude-plugin/plugin.json +20 -0
- package/plugins/migration-safety/commands/gen-characterization-test.md +452 -0
- package/plugins/migration-safety/commands/strangler-plan.md +356 -0
- package/plugins/migration-safety/skills/strangler-fig.md +382 -0
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
# /go-review — Incremental Go Code Review with Auto-Fix
|
|
2
|
+
|
|
3
|
+
You are an expert Go code reviewer specializing in Java-to-Go migrations for Garuda Airlines. You perform diff-aware, incremental reviews that surface only new findings since the last review, and can apply auto-fixes in an isolated git worktree.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## STEP 0 — ONE-TIME SETUP (skip if .go-reviewer-config.json already exists in project root)
|
|
8
|
+
|
|
9
|
+
Check whether `.go-reviewer-config.json` exists in the current working directory.
|
|
10
|
+
|
|
11
|
+
If it does NOT exist, run the one-time setup:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
I need to configure your Go reviewer before we start. This is a one-time setup.
|
|
15
|
+
|
|
16
|
+
Which linters do you want to use? (you can choose multiple)
|
|
17
|
+
|
|
18
|
+
A) golangci-lint — Comprehensive meta-linter: runs errcheck, staticcheck, gosec, govet,
|
|
19
|
+
revive, ineffassign, and 50+ others. Requires binary on PATH.
|
|
20
|
+
Install: go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
|
|
21
|
+
|
|
22
|
+
B) gopls — Go language server: type-aware analysis, unused variables/imports,
|
|
23
|
+
shadow checks, type mismatches. Requires binary on PATH.
|
|
24
|
+
Install: go install golang.org/x/tools/gopls@latest
|
|
25
|
+
|
|
26
|
+
C) semgrep — Pattern-based cross-language scanner: detects common Go anti-patterns,
|
|
27
|
+
security issues, and migration smells. Requires binary on PATH.
|
|
28
|
+
Install: pip install semgrep OR brew install semgrep
|
|
29
|
+
|
|
30
|
+
D) Claude-only — No external tools required. Claude reads, reasons, and assesses
|
|
31
|
+
all files directly. Best when external binaries are unavailable.
|
|
32
|
+
|
|
33
|
+
Enter your choices (e.g. "A B" or "A C D" or just "D"):
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
After user responds, for each binary chosen (A, B, C):
|
|
37
|
+
- Check if the binary is available: use `which golangci-lint` / `where golangci-lint` on Windows, etc.
|
|
38
|
+
- If NOT found on PATH, print:
|
|
39
|
+
```
|
|
40
|
+
⚠️ golangci-lint not found on PATH. Skipping. Install with:
|
|
41
|
+
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
|
|
42
|
+
```
|
|
43
|
+
(substitute correct tool name and install command for each)
|
|
44
|
+
- Only record tools that are actually available (or Claude-only)
|
|
45
|
+
|
|
46
|
+
Save the configuration as `.go-reviewer-config.json` in the project root:
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"version": "0.1.0",
|
|
51
|
+
"configuredAt": "<ISO timestamp>",
|
|
52
|
+
"tools": {
|
|
53
|
+
"golangci_lint": true,
|
|
54
|
+
"gopls": false,
|
|
55
|
+
"semgrep": false,
|
|
56
|
+
"claude_only": false
|
|
57
|
+
},
|
|
58
|
+
"semgrepRules": "p/golang"
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Print: `✅ Configuration saved to .go-reviewer-config.json`
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## STEP 1 — LOAD CONFIG
|
|
67
|
+
|
|
68
|
+
Read `.go-reviewer-config.json` to determine which tools are active.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## STEP 2 — CHOOSE REVIEW MODE
|
|
73
|
+
|
|
74
|
+
Ask the user:
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
Which review mode?
|
|
78
|
+
|
|
79
|
+
A) Incremental — review only files changed since a base commit/branch
|
|
80
|
+
(reports NEW findings only, compared to last review)
|
|
81
|
+
|
|
82
|
+
B) Full audit — review ALL Go files in the target path
|
|
83
|
+
(auto-fix applied in an isolated git worktree, never touches your working tree)
|
|
84
|
+
|
|
85
|
+
Enter A or B:
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Then ask:
|
|
89
|
+
```
|
|
90
|
+
Target path to review (press Enter for current directory):
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## STEP 3A — INCREMENTAL REVIEW (if user chose A)
|
|
96
|
+
|
|
97
|
+
### 3A.1 — Get base reference
|
|
98
|
+
|
|
99
|
+
Ask:
|
|
100
|
+
```
|
|
101
|
+
Enter base commit SHA or branch name to diff against (e.g. "main", "HEAD~5", "abc1234"):
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### 3A.2 — Discover changed Go files
|
|
105
|
+
|
|
106
|
+
Run:
|
|
107
|
+
```
|
|
108
|
+
git diff --name-only <base>..HEAD -- '*.go'
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
If no .go files changed, print:
|
|
112
|
+
```
|
|
113
|
+
ℹ️ No Go files changed since <base>. Nothing to review.
|
|
114
|
+
```
|
|
115
|
+
And stop.
|
|
116
|
+
|
|
117
|
+
List the changed files:
|
|
118
|
+
```
|
|
119
|
+
📂 Changed Go files since <base>:
|
|
120
|
+
- internal/service/booking.go
|
|
121
|
+
- internal/handler/flight.go
|
|
122
|
+
- ...
|
|
123
|
+
(N files)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### 3A.3 — Run enabled tools on changed files only
|
|
127
|
+
|
|
128
|
+
For each enabled tool (from config):
|
|
129
|
+
|
|
130
|
+
**golangci-lint:**
|
|
131
|
+
```bash
|
|
132
|
+
golangci-lint run --out-format json <file1> <file2> ...
|
|
133
|
+
```
|
|
134
|
+
Parse JSON output to extract findings: file path, line number, linter name, severity, message.
|
|
135
|
+
|
|
136
|
+
**gopls:**
|
|
137
|
+
```bash
|
|
138
|
+
gopls check <file1> <file2> ...
|
|
139
|
+
```
|
|
140
|
+
Parse line-by-line output: `<file>:<line>:<col>: <message>`
|
|
141
|
+
|
|
142
|
+
**semgrep:**
|
|
143
|
+
```bash
|
|
144
|
+
semgrep --config <semgrepRules> --json <file1> <file2> ...
|
|
145
|
+
```
|
|
146
|
+
Parse JSON `results` array: path, start.line, check_id, extra.message, extra.severity
|
|
147
|
+
|
|
148
|
+
**Claude-only (or supplement):**
|
|
149
|
+
Read each changed file and assess against these Go standards:
|
|
150
|
+
- Error handling: all errors must be checked; no `_ = err` unless intentional and commented
|
|
151
|
+
- No `panic()` in library code (only in main or init for fatal misconfiguration)
|
|
152
|
+
- Context propagation: functions that do I/O must accept `context.Context` as first argument
|
|
153
|
+
- Goroutine leaks: every goroutine must have a clear exit condition
|
|
154
|
+
- Interface satisfaction: prefer small, single-method interfaces
|
|
155
|
+
- Naming: unexported types use camelCase; exported use PascalCase; no Hungarian notation
|
|
156
|
+
- No `init()` functions that have side effects visible outside the package
|
|
157
|
+
- Struct field alignment: group fields by type to minimize padding
|
|
158
|
+
- Java migration smells: no direct port of Java patterns (e.g., getter/setter methods, `Exception` types, `Abstract*` naming, `*Manager`, `*Factory` as top-level struct names)
|
|
159
|
+
- Module path consistency: all imports reference `github.com/zokypesch/go-ga-lib`
|
|
160
|
+
|
|
161
|
+
### 3A.4 — Load previous review history
|
|
162
|
+
|
|
163
|
+
Read `.go-review-history.json` if it exists:
|
|
164
|
+
```json
|
|
165
|
+
{
|
|
166
|
+
"lastReviewAt": "...",
|
|
167
|
+
"baseCommit": "...",
|
|
168
|
+
"findings": [
|
|
169
|
+
{ "file": "...", "line": 42, "rule": "...", "severity": "...", "message": "..." }
|
|
170
|
+
]
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
If the file does not exist, treat previous findings as empty (all current findings are "new").
|
|
175
|
+
|
|
176
|
+
### 3A.5 — Diff findings — report ONLY new ones
|
|
177
|
+
|
|
178
|
+
A finding is considered "same as previous" if it matches on ALL of: `file`, `rule`, and `message` (line number may shift due to edits — do NOT use line as identity key).
|
|
179
|
+
|
|
180
|
+
Filter current findings to only those not present in previous review.
|
|
181
|
+
|
|
182
|
+
If no new findings:
|
|
183
|
+
```
|
|
184
|
+
✅ No new findings since last review (base: <base>).
|
|
185
|
+
Previous review had N findings — all still present but not re-reported.
|
|
186
|
+
```
|
|
187
|
+
Stop.
|
|
188
|
+
|
|
189
|
+
Otherwise, proceed to report.
|
|
190
|
+
|
|
191
|
+
### 3A.6 — Save updated history
|
|
192
|
+
|
|
193
|
+
Write `.go-review-history.json` with ALL current findings (not just new ones) plus metadata:
|
|
194
|
+
```json
|
|
195
|
+
{
|
|
196
|
+
"lastReviewAt": "<ISO timestamp>",
|
|
197
|
+
"baseCommit": "<base>",
|
|
198
|
+
"headCommit": "<HEAD SHA>",
|
|
199
|
+
"findings": [ ... ]
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### 3A.7 — Print incremental report
|
|
204
|
+
|
|
205
|
+
```
|
|
206
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
207
|
+
GO REVIEW — INCREMENTAL (new findings only)
|
|
208
|
+
Base: <base> → HEAD: <short SHA>
|
|
209
|
+
Files reviewed: N | New findings: X (Critical: C, Warning: W, Info: I)
|
|
210
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
211
|
+
|
|
212
|
+
🔴 CRITICAL — Must fix before merge (C findings)
|
|
213
|
+
───────────────────────────────────────────────
|
|
214
|
+
[C1] internal/service/booking.go:87
|
|
215
|
+
Rule: error-unchecked
|
|
216
|
+
Description: Return value of db.QueryRowContext() ignored — SQL errors silently swallowed.
|
|
217
|
+
Fix: Assign to err and check: if err := row.Scan(&...); err != nil { return nil, err }
|
|
218
|
+
|
|
219
|
+
[C2] ...
|
|
220
|
+
|
|
221
|
+
🟡 WARNING — Should fix (W findings)
|
|
222
|
+
─────────────────────────────────────
|
|
223
|
+
[W1] internal/handler/flight.go:34
|
|
224
|
+
Rule: context-missing
|
|
225
|
+
Description: Function fetchFlightData() performs HTTP I/O but does not accept context.Context.
|
|
226
|
+
Fix: Add ctx context.Context as first parameter; pass to http.NewRequestWithContext().
|
|
227
|
+
|
|
228
|
+
🔵 INFO — Consider (I findings)
|
|
229
|
+
────────────────────────────────
|
|
230
|
+
[I1] internal/model/passenger.go:12
|
|
231
|
+
Rule: java-migration-smell
|
|
232
|
+
Description: Struct named PassengerManager — Java naming pattern. In Go, prefer domain
|
|
233
|
+
nouns (PassengerService or plain functions in a passengers package).
|
|
234
|
+
Fix: Rename to PassengerService or refactor to package-level functions.
|
|
235
|
+
|
|
236
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
237
|
+
History saved to .go-review-history.json
|
|
238
|
+
Run /go-review again after fixing to verify no new regressions.
|
|
239
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## STEP 3B — FULL AUDIT WITH AUTO-FIX (if user chose B)
|
|
245
|
+
|
|
246
|
+
### 3B.1 — Discover all Go files
|
|
247
|
+
|
|
248
|
+
Enumerate all `.go` files under the target path, excluding:
|
|
249
|
+
- `vendor/`
|
|
250
|
+
- `_test.go` files (reviewed separately)
|
|
251
|
+
- `generated/` or `gen/` directories
|
|
252
|
+
- `.pb.go` files (protobuf generated)
|
|
253
|
+
|
|
254
|
+
Print: `📂 Found N Go source files for full audit.`
|
|
255
|
+
|
|
256
|
+
### 3B.2 — Create isolated git worktree
|
|
257
|
+
|
|
258
|
+
IMPORTANT: NEVER modify files in the original repository. All fixes happen in an isolated worktree.
|
|
259
|
+
|
|
260
|
+
Run:
|
|
261
|
+
```bash
|
|
262
|
+
WORKTREE_PATH=$(mktemp -d /tmp/go-review-XXXXXX)
|
|
263
|
+
git worktree add "$WORKTREE_PATH" HEAD
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Print:
|
|
267
|
+
```
|
|
268
|
+
🌿 Created isolated worktree at: /tmp/go-review-abc123
|
|
269
|
+
(Your working tree is untouched)
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### 3B.3 — Run enabled tools in the worktree
|
|
273
|
+
|
|
274
|
+
Run each enabled tool against the worktree path (substitute `$WORKTREE_PATH` for the original path in all commands).
|
|
275
|
+
|
|
276
|
+
Collect ALL findings across all tools, deduplicating by (file, line, rule).
|
|
277
|
+
|
|
278
|
+
### 3B.4 — Apply auto-fixes in worktree
|
|
279
|
+
|
|
280
|
+
For each CRITICAL and WARNING finding where a safe, mechanical fix exists:
|
|
281
|
+
- Apply the fix to the file inside `$WORKTREE_PATH` (NOT the original)
|
|
282
|
+
- Track which fixes were applied
|
|
283
|
+
|
|
284
|
+
Safe mechanical fixes include:
|
|
285
|
+
- Adding `if err != nil { return ..., err }` after unchecked error returns
|
|
286
|
+
- Adding `context.Context` parameter to function signatures (where the call chain is clear)
|
|
287
|
+
- Fixing import grouping (stdlib, external, internal — separated by blank lines)
|
|
288
|
+
- Removing unused imports
|
|
289
|
+
- Fixing `gofmt` formatting issues
|
|
290
|
+
|
|
291
|
+
Do NOT auto-fix:
|
|
292
|
+
- Logic errors or architectural issues (report only)
|
|
293
|
+
- Anything requiring business context
|
|
294
|
+
- Renaming exported types (breaking change)
|
|
295
|
+
|
|
296
|
+
### 3B.5 — Generate diff
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
git -C "$WORKTREE_PATH" diff HEAD
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Store the diff.
|
|
303
|
+
|
|
304
|
+
### 3B.6 — Write full report to .go-review.md
|
|
305
|
+
|
|
306
|
+
Write to `.go-review.md` in the project root (outside the worktree):
|
|
307
|
+
|
|
308
|
+
```markdown
|
|
309
|
+
# Go Code Review Report
|
|
310
|
+
|
|
311
|
+
**Generated:** <ISO timestamp>
|
|
312
|
+
**Target:** <target path>
|
|
313
|
+
**Mode:** Full Audit
|
|
314
|
+
**Worktree:** <worktree path>
|
|
315
|
+
**Tools:** golangci-lint, Claude analysis
|
|
316
|
+
|
|
317
|
+
## Summary
|
|
318
|
+
|
|
319
|
+
| Metric | Value |
|
|
320
|
+
|--------|-------|
|
|
321
|
+
| Files reviewed | N |
|
|
322
|
+
| Total findings | X |
|
|
323
|
+
| Auto-fixed | F |
|
|
324
|
+
| Critical | C |
|
|
325
|
+
| Warning | W |
|
|
326
|
+
| Info | I |
|
|
327
|
+
|
|
328
|
+
## 🔴 CRITICAL — Must fix before merge
|
|
329
|
+
|
|
330
|
+
### [C1] `internal/service/booking.go:87`
|
|
331
|
+
**Rule:** `error-unchecked`
|
|
332
|
+
**Tool:** golangci-lint / errcheck
|
|
333
|
+
**Description:** Return value of db.QueryRowContext() ignored.
|
|
334
|
+
**Suggested fix:**
|
|
335
|
+
```go
|
|
336
|
+
row := db.QueryRowContext(ctx, query, args...)
|
|
337
|
+
if err := row.Scan(&dest); err != nil {
|
|
338
|
+
return nil, fmt.Errorf("scan booking: %w", err)
|
|
339
|
+
}
|
|
340
|
+
```
|
|
341
|
+
**Auto-fixed:** ✅ Yes
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## 🟡 WARNING — Should fix
|
|
346
|
+
|
|
347
|
+
...
|
|
348
|
+
|
|
349
|
+
## 🔵 INFO — Consider
|
|
350
|
+
|
|
351
|
+
...
|
|
352
|
+
|
|
353
|
+
## Auto-fix Diff
|
|
354
|
+
|
|
355
|
+
```diff
|
|
356
|
+
<diff output here>
|
|
357
|
+
```
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
Print: `📄 Full report written to .go-review.md`
|
|
361
|
+
|
|
362
|
+
### 3B.7 — Ask to apply fixes
|
|
363
|
+
|
|
364
|
+
```
|
|
365
|
+
Found F auto-fixable issues in the isolated worktree.
|
|
366
|
+
|
|
367
|
+
Apply these fixes to your working tree? (y/N):
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
If user says `y` or `yes`:
|
|
371
|
+
```bash
|
|
372
|
+
git -C "$WORKTREE_PATH" diff HEAD | git apply --index
|
|
373
|
+
```
|
|
374
|
+
Print: `✅ Fixes applied to working tree. Review with: git diff`
|
|
375
|
+
|
|
376
|
+
If user says `n` or anything else:
|
|
377
|
+
Print:
|
|
378
|
+
```
|
|
379
|
+
ℹ️ Fixes NOT applied. To apply manually:
|
|
380
|
+
git -C <worktree_path> diff HEAD | git apply --index
|
|
381
|
+
|
|
382
|
+
Or inspect the worktree directly:
|
|
383
|
+
cd <worktree_path>
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### 3B.8 — Cleanup worktree
|
|
387
|
+
|
|
388
|
+
```bash
|
|
389
|
+
git worktree remove "$WORKTREE_PATH" --force
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
Print: `🧹 Worktree cleaned up.`
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
## SEVERITY CLASSIFICATION GUIDE
|
|
397
|
+
|
|
398
|
+
Use these rules when Claude is assessing code (Claude-only mode or supplementing linters):
|
|
399
|
+
|
|
400
|
+
| Severity | Criteria |
|
|
401
|
+
|----------|----------|
|
|
402
|
+
| CRITICAL | Data loss risk, security vulnerability, goroutine leak, unhandled error on I/O path, nil dereference risk, race condition |
|
|
403
|
+
| WARNING | Missing context propagation, Java migration smell that affects maintainability, incorrect error wrapping, missing defer for cleanup |
|
|
404
|
+
| INFO | Naming conventions, struct layout, minor style, documentation gaps, test coverage suggestions |
|
|
405
|
+
|
|
406
|
+
---
|
|
407
|
+
|
|
408
|
+
## GO STANDARDS REFERENCE (Garuda Airlines — Java→Go Migration)
|
|
409
|
+
|
|
410
|
+
Apply these project-specific rules on top of standard Go idioms:
|
|
411
|
+
|
|
412
|
+
1. **Module path**: All internal imports use `github.com/zokypesch/go-ga-lib/...`
|
|
413
|
+
2. **Error wrapping**: Always use `fmt.Errorf("operation: %w", err)` — never `errors.New()` on a wrapped error
|
|
414
|
+
3. **HTTP handlers**: Must accept `context.Context`; use `r.Context()` from the request
|
|
415
|
+
4. **Database**: All DB calls must use context-aware variants (`QueryContext`, `ExecContext`, etc.)
|
|
416
|
+
5. **Logging**: Use structured logging (slog or zerolog) — no `fmt.Println` in production paths
|
|
417
|
+
6. **Java patterns to eliminate**:
|
|
418
|
+
- No `getter`/`setter` methods — use direct field access or functional options
|
|
419
|
+
- No `*Exception` type names — use `*Error` or descriptive names
|
|
420
|
+
- No `Abstract*` prefixes — use interfaces
|
|
421
|
+
- No `*Manager`, `*Factory`, `*Helper` as primary type names
|
|
422
|
+
- No checked-exception-style error chaining through empty interfaces
|
|
423
|
+
7. **Concurrency**: Every `go func()` must be tracked (WaitGroup, errgroup, or channel receive)
|
|
424
|
+
8. **Tests**: Table-driven tests preferred; test files must be in same package (not `_test` external unless testing exported API)
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# go-reviewer-mcp
|
|
2
|
+
|
|
3
|
+
A thin MCP (Model Context Protocol) shim server that runs external Go analysis binaries
|
|
4
|
+
(`golangci-lint`, `gopls`, `semgrep`) and returns structured findings to Claude.
|
|
5
|
+
|
|
6
|
+
## What This Server Does
|
|
7
|
+
|
|
8
|
+
Claude cannot directly execute shell commands during a review session. This MCP server
|
|
9
|
+
bridges that gap: it exposes three tools over the MCP JSON-RPC protocol (stdio transport),
|
|
10
|
+
each of which shells out to an external binary, parses its output, and returns a normalized
|
|
11
|
+
`[]Finding` array that Claude can reason over.
|
|
12
|
+
|
|
13
|
+
**Graceful degradation is a first-class concern.** If a binary is not on PATH, the tool
|
|
14
|
+
returns `{"skipped": true, "reason": "binary not found"}` instead of an error. Claude
|
|
15
|
+
interprets this response and silently falls back to its own analysis. The server never
|
|
16
|
+
crashes due to a missing binary.
|
|
17
|
+
|
|
18
|
+
## Architecture
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
Claude (go-review command)
|
|
22
|
+
│ JSON-RPC over stdio
|
|
23
|
+
▼
|
|
24
|
+
go-reviewer-mcp (this server)
|
|
25
|
+
│
|
|
26
|
+
├── run_golangci_lint → golangci-lint (subprocess)
|
|
27
|
+
├── run_gopls_check → gopls (subprocess)
|
|
28
|
+
└── run_semgrep → semgrep (subprocess)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Prerequisites
|
|
32
|
+
|
|
33
|
+
The server itself requires only Go 1.23+. External binaries are optional:
|
|
34
|
+
|
|
35
|
+
| Tool | Install command | Notes |
|
|
36
|
+
|------|----------------|-------|
|
|
37
|
+
| `golangci-lint` | `go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest` | Comprehensive meta-linter |
|
|
38
|
+
| `gopls` | `go install golang.org/x/tools/gopls@latest` | Type-aware language server |
|
|
39
|
+
| `semgrep` | `pip install semgrep` or `brew install semgrep` | Pattern-based scanner |
|
|
40
|
+
|
|
41
|
+
Missing binaries are silently skipped — install only what you need.
|
|
42
|
+
|
|
43
|
+
## Build
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
cd mcp-servers/go-reviewer-mcp
|
|
47
|
+
go build -o go-reviewer-mcp ./...
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
On Windows:
|
|
51
|
+
```powershell
|
|
52
|
+
go build -o go-reviewer-mcp.exe ./...
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Register in ~/.claude.json
|
|
56
|
+
|
|
57
|
+
Add the server to your Claude configuration file (`~/.claude.json` on macOS/Linux,
|
|
58
|
+
`%USERPROFILE%\.claude.json` on Windows):
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
{
|
|
62
|
+
"mcpServers": {
|
|
63
|
+
"go-reviewer": {
|
|
64
|
+
"command": "/absolute/path/to/go-reviewer-mcp",
|
|
65
|
+
"args": [],
|
|
66
|
+
"env": {}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
On Windows, use forward slashes or escaped backslashes:
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"mcpServers": {
|
|
76
|
+
"go-reviewer": {
|
|
77
|
+
"command": "C:/Users/yourname/.claude/mcp/go-reviewer-mcp.exe",
|
|
78
|
+
"args": [],
|
|
79
|
+
"env": {}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Recommended install location
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# macOS / Linux
|
|
89
|
+
mkdir -p ~/.claude/mcp
|
|
90
|
+
cp go-reviewer-mcp ~/.claude/mcp/go-reviewer-mcp
|
|
91
|
+
chmod +x ~/.claude/mcp/go-reviewer-mcp
|
|
92
|
+
|
|
93
|
+
# Windows (PowerShell)
|
|
94
|
+
New-Item -ItemType Directory -Force "$env:USERPROFILE\.claude\mcp"
|
|
95
|
+
Copy-Item go-reviewer-mcp.exe "$env:USERPROFILE\.claude\mcp\go-reviewer-mcp.exe"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Available MCP Tools
|
|
99
|
+
|
|
100
|
+
### `run_golangci_lint`
|
|
101
|
+
|
|
102
|
+
Runs `golangci-lint run --out-format json` on the given path.
|
|
103
|
+
|
|
104
|
+
**Input:**
|
|
105
|
+
```json
|
|
106
|
+
{ "path": "/absolute/path/to/go/package/or/file" }
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Output (success):**
|
|
110
|
+
```json
|
|
111
|
+
{
|
|
112
|
+
"skipped": false,
|
|
113
|
+
"findings": [
|
|
114
|
+
{
|
|
115
|
+
"File": "internal/service/booking.go",
|
|
116
|
+
"Line": 87,
|
|
117
|
+
"Rule": "errcheck",
|
|
118
|
+
"Severity": "CRITICAL",
|
|
119
|
+
"Message": "Error return value of `db.QueryRowContext` is not checked"
|
|
120
|
+
}
|
|
121
|
+
]
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Output (binary missing):**
|
|
126
|
+
```json
|
|
127
|
+
{ "skipped": true, "reason": "binary not found: golangci-lint" }
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
### `run_gopls_check`
|
|
133
|
+
|
|
134
|
+
Runs `gopls check` on the given path for type-aware diagnostics.
|
|
135
|
+
|
|
136
|
+
**Input:**
|
|
137
|
+
```json
|
|
138
|
+
{ "path": "/absolute/path/to/go/file/or/directory" }
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**Output (success):**
|
|
142
|
+
```json
|
|
143
|
+
{
|
|
144
|
+
"skipped": false,
|
|
145
|
+
"findings": [
|
|
146
|
+
{
|
|
147
|
+
"File": "internal/handler/flight.go",
|
|
148
|
+
"Line": 34,
|
|
149
|
+
"Rule": "gopls/unused-variable",
|
|
150
|
+
"Severity": "WARNING",
|
|
151
|
+
"Message": "result 'resp' is not used"
|
|
152
|
+
}
|
|
153
|
+
]
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
### `run_semgrep`
|
|
160
|
+
|
|
161
|
+
Runs `semgrep --config <rules> --json` on the given path.
|
|
162
|
+
|
|
163
|
+
**Input:**
|
|
164
|
+
```json
|
|
165
|
+
{
|
|
166
|
+
"path": "/absolute/path/to/scan",
|
|
167
|
+
"rules": "p/golang"
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Default `rules` value is `"p/golang"` if omitted.
|
|
172
|
+
|
|
173
|
+
**Output (success):**
|
|
174
|
+
```json
|
|
175
|
+
{
|
|
176
|
+
"skipped": false,
|
|
177
|
+
"findings": [
|
|
178
|
+
{
|
|
179
|
+
"File": "internal/util/crypto.go",
|
|
180
|
+
"Line": 12,
|
|
181
|
+
"Rule": "go.lang.security.audit.crypto.use_of_weak_crypto.use-of-md5",
|
|
182
|
+
"Severity": "WARNING",
|
|
183
|
+
"Message": "Use of weak cryptographic primitive MD5"
|
|
184
|
+
}
|
|
185
|
+
]
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Graceful Degradation
|
|
190
|
+
|
|
191
|
+
If a binary is not found on PATH, each tool returns:
|
|
192
|
+
```json
|
|
193
|
+
{ "skipped": true, "reason": "binary not found: <tool-name>" }
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
The server:
|
|
197
|
+
- Never panics or exits non-zero due to a missing binary
|
|
198
|
+
- Returns a valid JSON-RPC response in all cases
|
|
199
|
+
- Logs warnings to stderr (not stdout, which is reserved for JSON-RPC)
|
|
200
|
+
- Continues serving other tool calls after any single failure
|
|
201
|
+
|
|
202
|
+
## Severity Mapping
|
|
203
|
+
|
|
204
|
+
| Source tool | Source severity | Mapped to |
|
|
205
|
+
|-------------|----------------|-----------|
|
|
206
|
+
| golangci-lint | `error` | `CRITICAL` |
|
|
207
|
+
| golangci-lint | `warning` | `WARNING` |
|
|
208
|
+
| golangci-lint | `info` / other | `INFO` |
|
|
209
|
+
| gopls | diagnostic | `WARNING` |
|
|
210
|
+
| semgrep | `ERROR` | `CRITICAL` |
|
|
211
|
+
| semgrep | `WARNING` | `WARNING` |
|
|
212
|
+
| semgrep | `INFO` | `INFO` |
|
|
213
|
+
|
|
214
|
+
## Troubleshooting
|
|
215
|
+
|
|
216
|
+
**Server not starting:** Check that the binary is executable and the path in `~/.claude.json` is absolute.
|
|
217
|
+
|
|
218
|
+
**All tools skipped:** Run `which golangci-lint` (or `where golangci-lint` on Windows) to verify binaries are on PATH. The server inherits the PATH from Claude's process, which may differ from your shell's PATH. Set `env.PATH` in the MCP server config if needed:
|
|
219
|
+
```json
|
|
220
|
+
{
|
|
221
|
+
"mcpServers": {
|
|
222
|
+
"go-reviewer": {
|
|
223
|
+
"command": "...",
|
|
224
|
+
"env": {
|
|
225
|
+
"PATH": "/usr/local/go/bin:/home/yourname/go/bin:/usr/local/bin:/usr/bin:/bin"
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
**golangci-lint times out:** For large codebases, increase the timeout:
|
|
233
|
+
```json
|
|
234
|
+
{ "args": ["--timeout-seconds", "120"] }
|
|
235
|
+
```
|
|
236
|
+
(The server passes extra args to the binary — not yet implemented; file an issue.)
|