ga-plugins-cli 0.1.0 → 0.1.1

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.
Files changed (55) hide show
  1. package/dist/config-patcher.d.ts +20 -50
  2. package/dist/config-patcher.d.ts.map +1 -1
  3. package/dist/config-patcher.js +138 -102
  4. package/dist/config-patcher.js.map +1 -1
  5. package/dist/index.js +41 -5
  6. package/dist/index.js.map +1 -1
  7. package/dist/installer.d.ts +0 -18
  8. package/dist/installer.d.ts.map +1 -1
  9. package/dist/installer.js +19 -39
  10. package/dist/installer.js.map +1 -1
  11. package/dist/types.d.ts +10 -6
  12. package/dist/types.d.ts.map +1 -1
  13. package/dist/uninstaller.d.ts +0 -23
  14. package/dist/uninstaller.d.ts.map +1 -1
  15. package/dist/uninstaller.js +22 -68
  16. package/dist/uninstaller.js.map +1 -1
  17. package/package.json +3 -2
  18. package/plugins/go-reviewer/.claude-plugin/plugin.json +12 -0
  19. package/plugins/go-reviewer/commands/go-review.md +424 -0
  20. package/plugins/go-reviewer/mcp-servers/go-reviewer-mcp/README.md +236 -0
  21. package/plugins/go-reviewer/mcp-servers/go-reviewer-mcp/main.go +678 -0
  22. package/plugins/go-scaffolder/.claude-plugin/plugin.json +12 -0
  23. package/plugins/go-scaffolder/commands/scaffold-service.md +802 -0
  24. package/plugins/go-scaffolder/reference-service/.env.example +27 -0
  25. package/plugins/go-scaffolder/reference-service/Dockerfile +55 -0
  26. package/plugins/go-scaffolder/reference-service/REFERENCE-SERVICE-NOTICE.md +104 -0
  27. package/plugins/go-scaffolder/reference-service/cmd/server/main.go +266 -0
  28. package/plugins/go-scaffolder/reference-service/config/config.go +67 -0
  29. package/plugins/go-scaffolder/reference-service/go.mod +17 -0
  30. package/plugins/go-scaffolder/reference-service/internal/domain/booking.go +118 -0
  31. package/plugins/go-scaffolder/reference-service/internal/handler/booking.go +242 -0
  32. package/plugins/go-scaffolder/reference-service/internal/handler/booking_test.go +451 -0
  33. package/plugins/go-scaffolder/reference-service/internal/repository/booking_postgres.go +124 -0
  34. package/plugins/go-scaffolder/reference-service/internal/usecase/booking.go +181 -0
  35. package/plugins/go-standards/.claude-plugin/plugin.json +22 -0
  36. package/plugins/go-standards/commands/go-standards-check.md +232 -0
  37. package/plugins/go-standards/skills/concurrency.md +336 -0
  38. package/plugins/go-standards/skills/config.md +267 -0
  39. package/plugins/go-standards/skills/error-handling.md +286 -0
  40. package/plugins/go-standards/skills/http-chi.md +390 -0
  41. package/plugins/go-standards/skills/logging-observability.md +340 -0
  42. package/plugins/go-standards/skills/naming-and-style.md +315 -0
  43. package/plugins/go-standards/skills/project-layout.md +313 -0
  44. package/plugins/go-standards/skills/testing.md +366 -0
  45. package/plugins/java2go-porter/.claude-plugin/plugin.json +21 -0
  46. package/plugins/java2go-porter/agents/analyzer.md +232 -0
  47. package/plugins/java2go-porter/agents/reviewer.md +241 -0
  48. package/plugins/java2go-porter/agents/test-pairer.md +365 -0
  49. package/plugins/java2go-porter/agents/translator.md +419 -0
  50. package/plugins/java2go-porter/commands/port-java-service.md +149 -0
  51. package/plugins/java2go-porter/skills/idiom-mapping.md +75 -0
  52. package/plugins/migration-safety/.claude-plugin/plugin.json +20 -0
  53. package/plugins/migration-safety/commands/gen-characterization-test.md +452 -0
  54. package/plugins/migration-safety/commands/strangler-plan.md +356 -0
  55. package/plugins/migration-safety/skills/strangler-fig.md +382 -0
@@ -0,0 +1,452 @@
1
+ # Command: gen-characterization-test
2
+
3
+ Generate characterization test scaffolding that captures the behavioral contract of the OLD Java service, so that the new Go service can be validated against it. This command produces test scaffolding — a human must run the Java service to capture actual golden data.
4
+
5
+ ---
6
+
7
+ ## Step 1: Identify the Service
8
+
9
+ Ask the user:
10
+
11
+ > "What is the name or path of the Java service you want to characterize?
12
+ > (e.g., `services/booking-java-svc` or just `booking-svc`)"
13
+
14
+ Record as `<service-name>` and `<service-path>`.
15
+
16
+ If a path was given, check that the directory exists and contains Java source files. If not, inform the user and ask to clarify.
17
+
18
+ ---
19
+
20
+ ## Step 2: Choose the Test Format
21
+
22
+ Present the following options to the user:
23
+
24
+ > "Choose a characterization test format:
25
+ >
26
+ > **Option A — Golden JSON files** (recommended default)
27
+ > Simple. No extra tooling. Capture request/response pairs as JSON fixtures.
28
+ > Good for: small teams, early migration phase, services with stable contracts.
29
+ > Requires: manually running the Java service and saving HTTP responses as `.json` files.
30
+ >
31
+ > **Option B — Pact consumer-driven contracts**
32
+ > Stronger cross-team contracts. Versioned. Detectable breaking changes.
33
+ > Requires: a running Pact broker (e.g., PactFlow), Pact Go library.
34
+ > Good for: services consumed by multiple teams, long migration timelines.
35
+ >
36
+ > **Option C — HTTP recording (VCR-style)**
37
+ > Record real traffic against the Java service, replay against the Go service.
38
+ > Requires: HTTP recording library (e.g., `dnaeon/go-vcr`), Java service running during recording.
39
+ > Good for: services with complex request/response sequences.
40
+ >
41
+ > **NEEDS DECISION** — choose A, B, or C. If you proceed without choosing, Option A (golden JSON) will be used as the default."
42
+
43
+ If the user does not choose, default to Option A and note this in the generated output.
44
+
45
+ Record the choice as `<test-format>`.
46
+
47
+ ---
48
+
49
+ ## Step 3: Identify Endpoints to Cover
50
+
51
+ Ask the user:
52
+
53
+ > "Which endpoints should be covered by characterization tests?
54
+ > You can say 'all' to cover every endpoint, or list specific ones (e.g., `POST /api/v1/bookings`, `GET /api/v1/bookings/{id}`)."
55
+
56
+ If the user says "all" and a path was provided, scan the Java source for `@GetMapping`, `@PostMapping`, `@PutMapping`, `@DeleteMapping`, `@PatchMapping`, `@RequestMapping` annotations and list all found endpoints. Show the list to the user and confirm.
57
+
58
+ Record as `<endpoint-list>`.
59
+
60
+ ---
61
+
62
+ ## Step 4: Identify the Corresponding Go Service
63
+
64
+ Ask the user:
65
+
66
+ > "What is the path to the new Go service draft that these tests will validate against?
67
+ > (e.g., `flight-ops-svc/draft-booking-java-svc/` or the final merged service path)"
68
+
69
+ Record as `<go-service-path>`.
70
+
71
+ ---
72
+
73
+ ## Step 5: Generate Scaffolding Based on Format
74
+
75
+ ### Format A: Golden JSON Files
76
+
77
+ Create the following structure:
78
+
79
+ ```
80
+ <go-service-path>/
81
+ testdata/
82
+ golden/
83
+ README.md # instructions for capturing golden data
84
+ <endpoint-slug>/
85
+ <scenario-name>_request.json # HTTP request body fixture
86
+ <scenario-name>_response.json # PLACEHOLDER — must be filled by human
87
+ characterization_test.go # Go test loading fixtures and comparing responses
88
+ ```
89
+
90
+ #### testdata/golden/README.md
91
+
92
+ Write:
93
+
94
+ ```markdown
95
+ # Golden Data Capture Instructions
96
+
97
+ These JSON files capture the known-good behavior of the Java service: `<service-name>`.
98
+ They are used by `characterization_test.go` to verify the Go service produces equivalent responses.
99
+
100
+ ## How to Capture Golden Data
101
+
102
+ 1. Start the Java service locally or in a test environment:
103
+ ```
104
+ cd <service-path>
105
+ mvn spring-boot:run
106
+ # or: java -jar target/<service-name>.jar
107
+ ```
108
+ The service should be running on its default port (check application.properties).
109
+
110
+ 2. For each `*_request.json` file in this directory, send the request to the Java service:
111
+ ```
112
+ curl -s -X <METHOD> http://localhost:<PORT><PATH> \
113
+ -H "Content-Type: application/json" \
114
+ -d @<endpoint-slug>/<scenario>_request.json \
115
+ > <endpoint-slug>/<scenario>_response.json
116
+ ```
117
+
118
+ 3. Capture the HTTP status code separately:
119
+ ```
120
+ curl -s -o /dev/null -w "%{http_code}" -X <METHOD> http://localhost:<PORT><PATH> \
121
+ -H "Content-Type: application/json" \
122
+ -d @<endpoint-slug>/<scenario>_request.json
123
+ ```
124
+ Update the `expectedStatus` field in `characterization_test.go` for each scenario.
125
+
126
+ 4. Repeat for error scenarios (invalid input, not-found IDs, unauthorized requests).
127
+
128
+ 5. Once all `*_response.json` files are populated, remove the `t.Skip()` calls from `characterization_test.go`.
129
+
130
+ ## Important Notes
131
+
132
+ - Capture responses from the Java service BEFORE switching any traffic to Go.
133
+ - If the Java service uses a database, seed the same test data before each capture run.
134
+ - Store the DB seed script in `testdata/sql/seed.sql`.
135
+ - Do NOT commit real customer data as golden fixtures — use synthetic test data only.
136
+ ```
137
+
138
+ #### characterization_test.go
139
+
140
+ Write:
141
+
142
+ ```go
143
+ // AUTO-GENERATED CHARACTERIZATION TEST SCAFFOLDING
144
+ // Purpose: verify Go service <go-service-path> produces equivalent responses to Java <service-name>
145
+ // Format: Golden JSON (Option A)
146
+ //
147
+ // BEFORE RUNNING:
148
+ // 1. Read testdata/golden/README.md
149
+ // 2. Capture golden data from the running Java service
150
+ // 3. Remove t.Skip() calls for populated fixtures
151
+ //
152
+ // Run: go test -v ./... -run Characterization
153
+
154
+ package characterization_test
155
+
156
+ import (
157
+ "encoding/json"
158
+ "net/http"
159
+ "net/http/httptest"
160
+ "os"
161
+ "path/filepath"
162
+ "testing"
163
+
164
+ "github.com/go-chi/chi/v5"
165
+ "github.com/stretchr/testify/assert"
166
+ "github.com/stretchr/testify/require"
167
+ )
168
+
169
+ // goldenDir is the root of the golden fixture directory.
170
+ const goldenDir = "testdata/golden"
171
+
172
+ // CharacterizationScenario describes one request/response fixture pair.
173
+ type CharacterizationScenario struct {
174
+ Name string
175
+ Method string
176
+ Path string
177
+ RequestFile string // relative to goldenDir
178
+ ResponseFile string // relative to goldenDir — PLACEHOLDER until captured from Java
179
+ ExpectedStatus int // update after capturing from Java service
180
+ }
181
+
182
+ // scenarios lists every endpoint and scenario to characterize.
183
+ // TODO(human): populate ExpectedStatus for each scenario after running Java service.
184
+ // TODO(human): add additional scenarios (error cases, edge cases) as you discover them.
185
+ var scenarios = []CharacterizationScenario{
186
+ // Generated from endpoint list: <endpoint-list>
187
+ {
188
+ Name: "create booking - valid request",
189
+ Method: http.MethodPost,
190
+ Path: "/api/v1/bookings",
191
+ RequestFile: "create_booking/valid_request.json",
192
+ ResponseFile: "create_booking/valid_response.json",
193
+ ExpectedStatus: 201, // TODO(human): verify against actual Java response
194
+ },
195
+ {
196
+ Name: "create booking - invalid body",
197
+ Method: http.MethodPost,
198
+ Path: "/api/v1/bookings",
199
+ RequestFile: "create_booking/invalid_body_request.json",
200
+ ResponseFile: "create_booking/invalid_body_response.json",
201
+ ExpectedStatus: 400, // TODO(human): verify against actual Java response
202
+ },
203
+ // TODO(human): add one scenario per endpoint in <endpoint-list>
204
+ }
205
+
206
+ func TestCharacterization_GoldenJSON(t *testing.T) {
207
+ t.Skip("NEEDS GOLDEN DATA: read testdata/golden/README.md, run Java service, capture responses. Remove this Skip when all *_response.json files are populated.")
208
+
209
+ // TODO(human): initialize Go service router here
210
+ // Example:
211
+ // cfg, _ := config.Load()
212
+ // db, _ := database.New(cfg.DatabaseURL)
213
+ // ... wire dependencies ...
214
+ // r := chi.NewRouter()
215
+ // handler.NewBookingHandler(bookingUC).RegisterRoutes(r)
216
+ var r chi.Router // replace with your real router initialization
217
+ _ = r
218
+
219
+ server := httptest.NewServer(r)
220
+ defer server.Close()
221
+
222
+ for _, sc := range scenarios {
223
+ t.Run(sc.Name, func(t *testing.T) {
224
+ // Load request fixture
225
+ reqPath := filepath.Join(goldenDir, sc.RequestFile)
226
+ reqBody, err := os.ReadFile(reqPath)
227
+ require.NoError(t, err, "request fixture must exist: %s — create it if missing", reqPath)
228
+
229
+ // Send request to Go service
230
+ req, err := http.NewRequest(sc.Method, server.URL+sc.Path, bytesReader(reqBody))
231
+ require.NoError(t, err)
232
+ req.Header.Set("Content-Type", "application/json")
233
+
234
+ resp, err := http.DefaultClient.Do(req)
235
+ require.NoError(t, err)
236
+ defer resp.Body.Close()
237
+
238
+ // Check status code
239
+ assert.Equal(t, sc.ExpectedStatus, resp.StatusCode,
240
+ "HTTP status mismatch for %s %s", sc.Method, sc.Path)
241
+
242
+ // Load response fixture
243
+ respPath := filepath.Join(goldenDir, sc.ResponseFile)
244
+ goldenBody, err := os.ReadFile(respPath)
245
+ require.NoError(t, err,
246
+ "response fixture must exist: %s — capture from Java service first", respPath)
247
+
248
+ // Compare response bodies (JSON-normalized)
249
+ var golden, actual interface{}
250
+ require.NoError(t, json.Unmarshal(goldenBody, &golden))
251
+ require.NoError(t, json.NewDecoder(resp.Body).Decode(&actual))
252
+ assert.Equal(t, golden, actual,
253
+ "response body mismatch for %s %s — Go response differs from Java golden", sc.Method, sc.Path)
254
+ })
255
+ }
256
+ }
257
+
258
+ func bytesReader(b []byte) *bytes.Reader {
259
+ return bytes.NewReader(b)
260
+ }
261
+ ```
262
+
263
+ Also create placeholder request fixture files. For each endpoint, write a minimal `*_request.json` placeholder:
264
+
265
+ ```json
266
+ {
267
+ "_PLACEHOLDER": true,
268
+ "_instructions": "Replace this file with a real request body for the Java service endpoint.",
269
+ "_endpoint": "<METHOD> <PATH>"
270
+ }
271
+ ```
272
+
273
+ And a minimal `*_response.json` placeholder:
274
+
275
+ ```json
276
+ {
277
+ "_PLACEHOLDER": true,
278
+ "_instructions": "Run the Java service and capture the real response here. See testdata/golden/README.md.",
279
+ "_endpoint": "<METHOD> <PATH>"
280
+ }
281
+ ```
282
+
283
+ ---
284
+
285
+ ### Format B: Pact Consumer-Driven Contracts
286
+
287
+ Create:
288
+
289
+ ```
290
+ <go-service-path>/
291
+ contract/
292
+ pact/
293
+ <service-name>_pact_test.go # Pact consumer test skeleton
294
+ README.md # Pact setup instructions
295
+ ```
296
+
297
+ Write `<service-name>_pact_test.go`:
298
+
299
+ ```go
300
+ // AUTO-GENERATED PACT CONTRACT TEST SCAFFOLDING
301
+ // Format: Pact consumer-driven contracts (Option B)
302
+ //
303
+ // BEFORE RUNNING:
304
+ // 1. Install Pact Go: go get github.com/pact-foundation/pact-go/v2
305
+ // 2. Set up a Pact broker (PactFlow or self-hosted)
306
+ // 3. Set PACT_BROKER_URL, PACT_BROKER_TOKEN environment variables
307
+ // 4. Fill in interaction expectations below based on actual Java service behavior
308
+ //
309
+ // Run: go test -v ./contract/pact/...
310
+
311
+ package pact_test
312
+
313
+ import (
314
+ "fmt"
315
+ "testing"
316
+
317
+ "github.com/pact-foundation/pact-go/v2/consumer"
318
+ "github.com/pact-foundation/pact-go/v2/matchers"
319
+ "github.com/stretchr/testify/require"
320
+ )
321
+
322
+ func TestPact_<ServiceName>_CreateBooking(t *testing.T) {
323
+ t.Skip("NEEDS SETUP: configure Pact broker and fill in interaction expectations from Java service behavior")
324
+
325
+ mockProvider, err := consumer.NewV2Pact(consumer.MockHTTPProviderConfig{
326
+ Consumer: "go-<go-service-name>",
327
+ Provider: "java-<service-name>",
328
+ })
329
+ require.NoError(t, err)
330
+
331
+ // TODO(human): define interactions based on observed Java service behavior
332
+ err = mockProvider.
333
+ AddInteraction().
334
+ Given("a valid booking request").
335
+ UponReceiving("a POST /api/v1/bookings request").
336
+ WithRequest("POST", "/api/v1/bookings").
337
+ WithHeader("Content-Type", matchers.S("application/json")).
338
+ WithBody(matchers.MapMatcher{
339
+ "flightId": matchers.S("FL-001"),
340
+ "seatCount": matchers.Integer(2),
341
+ "passengerId": matchers.S("P-001"),
342
+ }).
343
+ WillRespondWith(201).
344
+ WithHeader("Content-Type", matchers.S("application/json")).
345
+ WithBody(matchers.MapMatcher{
346
+ "id": matchers.Regex("BK-[0-9]+", "BK-001"),
347
+ "status": matchers.S("PENDING"),
348
+ }).
349
+ ExecuteTest(t, func(config consumer.MockServerConfig) error {
350
+ // TODO(human): call your Go service client against config.Host:config.Port
351
+ return fmt.Errorf("implement me: call Go client against mock provider")
352
+ })
353
+
354
+ require.NoError(t, err)
355
+ }
356
+ ```
357
+
358
+ ---
359
+
360
+ ### Format C: HTTP Recording (VCR-Style)
361
+
362
+ Create:
363
+
364
+ ```
365
+ <go-service-path>/
366
+ testdata/
367
+ cassettes/ # VCR cassette files (recorded HTTP interactions)
368
+ <endpoint-slug>_<scenario>.yaml # PLACEHOLDER — recorded by running cassette capture
369
+ vcr_characterization_test.go # Test using go-vcr to replay cassettes
370
+ ```
371
+
372
+ Write `vcr_characterization_test.go`:
373
+
374
+ ```go
375
+ // AUTO-GENERATED VCR CHARACTERIZATION TEST SCAFFOLDING
376
+ // Format: HTTP recording / VCR-style (Option C)
377
+ //
378
+ // BEFORE RUNNING:
379
+ // 1. Install go-vcr: go get github.com/dnaeon/go-vcr/v3
380
+ // 2. Run the Java service locally
381
+ // 3. Set RECORD_MODE=true and run tests once to record cassettes
382
+ // 4. Commit the cassette YAML files
383
+ // 5. Run tests normally to replay cassettes against the Go service
384
+ //
385
+ // Run: go test -v ./... -run VCR
386
+
387
+ package characterization_test
388
+
389
+ import (
390
+ "net/http"
391
+ "testing"
392
+
393
+ "github.com/dnaeon/go-vcr/v3/cassette"
394
+ "github.com/dnaeon/go-vcr/v3/recorder"
395
+ "github.com/stretchr/testify/assert"
396
+ "github.com/stretchr/testify/require"
397
+ )
398
+
399
+ func TestVCR_<ServiceName>_Characterization(t *testing.T) {
400
+ t.Skip("NEEDS GOLDEN DATA: set JAVA_SERVICE_URL, run with RECORD_MODE=true against Java service first. See testdata/cassettes/ README.")
401
+
402
+ cassetteFile := "testdata/cassettes/create_booking_valid"
403
+
404
+ r, err := recorder.New(cassetteFile)
405
+ require.NoError(t, err)
406
+ defer r.Stop()
407
+
408
+ // TODO(human): point this at your Go service URL, not the Java service
409
+ // In record mode (cassette missing), it records against Java service
410
+ // In replay mode (cassette exists), it replays against Go service
411
+ client := &http.Client{Transport: r}
412
+ _ = client
413
+
414
+ // TODO(human): make HTTP requests using `client` and assert responses
415
+ assert.Fail(t, "implement VCR test body")
416
+ }
417
+ ```
418
+
419
+ ---
420
+
421
+ ## Step 6: Output Checklist
422
+
423
+ After generating scaffolding, print:
424
+
425
+ ```
426
+ ==========================================================================
427
+ CHARACTERIZATION TEST SCAFFOLDING GENERATED
428
+ Format: <test-format> (<A/B/C>)
429
+ Output: <go-service-path>/
430
+
431
+ WHAT YOU MUST DO NEXT TO CAPTURE GOLDEN DATA:
432
+
433
+ [ ] 1. Start the Java service: <service-name>
434
+ (see service README or run: mvn spring-boot:run in <service-path>)
435
+
436
+ [ ] 2. Set up test data in the database (if needed):
437
+ Run: psql -f testdata/sql/seed.sql <database-name>
438
+ (seed.sql must be written by the team — use synthetic data only, no real PII)
439
+
440
+ [ ] 3. For each endpoint in <endpoint-list>:
441
+ Send the requests and capture responses:
442
+ See testdata/golden/README.md for exact curl commands (Format A)
443
+ OR follow Pact setup in contract/pact/README.md (Format B)
444
+ OR run with RECORD_MODE=true (Format C)
445
+
446
+ [ ] 4. Remove t.Skip() calls as you populate each fixture
447
+
448
+ [ ] 5. Run the tests against the Go service: go test -v ./...
449
+
450
+ [ ] 6. All tests must pass before declaring the Go service ready for traffic
451
+ ==========================================================================
452
+ ```