litclaude-ai 0.2.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.
Files changed (156) hide show
  1. package/CHANGELOG.md +155 -0
  2. package/LICENSE +21 -0
  3. package/README.md +369 -0
  4. package/README_ko-KR.md +374 -0
  5. package/RELEASE_CHECKLIST.md +165 -0
  6. package/bin/litclaude-ai.js +643 -0
  7. package/cover.png +0 -0
  8. package/docs/agents.md +67 -0
  9. package/docs/hooks.md +134 -0
  10. package/docs/lsp.md +40 -0
  11. package/docs/migration.md +209 -0
  12. package/docs/workflow-compatibility-audit.md +119 -0
  13. package/generate_cover.py +123 -0
  14. package/package.json +48 -0
  15. package/plugins/litclaude/.claude-plugin/plugin.json +25 -0
  16. package/plugins/litclaude/.lsp.json +13 -0
  17. package/plugins/litclaude/.mcp.json +9 -0
  18. package/plugins/litclaude/agents/boulder-executor.md +12 -0
  19. package/plugins/litclaude/agents/librarian-researcher.md +15 -0
  20. package/plugins/litclaude/agents/oracle-verifier.md +16 -0
  21. package/plugins/litclaude/agents/prometheus-planner.md +13 -0
  22. package/plugins/litclaude/agents/qa-runner.md +16 -0
  23. package/plugins/litclaude/agents/quality-reviewer.md +17 -0
  24. package/plugins/litclaude/bin/litclaude-hook.js +110 -0
  25. package/plugins/litclaude/bin/litclaude-hud.js +271 -0
  26. package/plugins/litclaude/bin/litclaude-lsp-doctor.js +15 -0
  27. package/plugins/litclaude/bin/litclaude-mcp.js +70 -0
  28. package/plugins/litclaude/commands/deep-interview.md +21 -0
  29. package/plugins/litclaude/commands/dynamic-workflow.md +36 -0
  30. package/plugins/litclaude/commands/lit-loop.md +40 -0
  31. package/plugins/litclaude/commands/lit-plan.md +35 -0
  32. package/plugins/litclaude/commands/litgoal.md +30 -0
  33. package/plugins/litclaude/commands/review-work.md +35 -0
  34. package/plugins/litclaude/commands/start-work.md +36 -0
  35. package/plugins/litclaude/hooks/hooks.json +54 -0
  36. package/plugins/litclaude/lib/context-pressure.mjs +25 -0
  37. package/plugins/litclaude/lib/hud-accent-palette.mjs +58 -0
  38. package/plugins/litclaude/lib/litgoal/cli.mjs +266 -0
  39. package/plugins/litclaude/lib/litgoal/ledger.mjs +16 -0
  40. package/plugins/litclaude/lib/litgoal/paths.mjs +7 -0
  41. package/plugins/litclaude/lib/litgoal/state.mjs +67 -0
  42. package/plugins/litclaude/lib/mutated-file-paths.mjs +63 -0
  43. package/plugins/litclaude/lib/start-work-continuation.mjs +99 -0
  44. package/plugins/litclaude/lib/workflow-check.mjs +83 -0
  45. package/plugins/litclaude/skills/ai-slop-remover/SKILL.md +142 -0
  46. package/plugins/litclaude/skills/comment-checker/SKILL.md +55 -0
  47. package/plugins/litclaude/skills/debugging/SKILL.md +70 -0
  48. package/plugins/litclaude/skills/debugging/references/methodology/00-setup.md +108 -0
  49. package/plugins/litclaude/skills/debugging/references/methodology/02-investigate.md +126 -0
  50. package/plugins/litclaude/skills/debugging/references/methodology/04-oracle-triple.md +106 -0
  51. package/plugins/litclaude/skills/debugging/references/methodology/05-escalate.md +69 -0
  52. package/plugins/litclaude/skills/debugging/references/methodology/06-fix.md +116 -0
  53. package/plugins/litclaude/skills/debugging/references/methodology/08-qa.md +94 -0
  54. package/plugins/litclaude/skills/debugging/references/methodology/09-cleanup.md +164 -0
  55. package/plugins/litclaude/skills/debugging/references/methodology/partial-runtime-evidence.md +228 -0
  56. package/plugins/litclaude/skills/debugging/references/runtimes/bundled-js-binary.md +415 -0
  57. package/plugins/litclaude/skills/debugging/references/runtimes/go.md +252 -0
  58. package/plugins/litclaude/skills/debugging/references/runtimes/native-binary.md +484 -0
  59. package/plugins/litclaude/skills/debugging/references/runtimes/node.md +260 -0
  60. package/plugins/litclaude/skills/debugging/references/runtimes/python.md +248 -0
  61. package/plugins/litclaude/skills/debugging/references/runtimes/rust.md +234 -0
  62. package/plugins/litclaude/skills/debugging/references/tools/ghidra.md +212 -0
  63. package/plugins/litclaude/skills/debugging/references/tools/playwright-cli.md +194 -0
  64. package/plugins/litclaude/skills/debugging/references/tools/pwndbg.md +263 -0
  65. package/plugins/litclaude/skills/debugging/references/tools/pwntools.md +265 -0
  66. package/plugins/litclaude/skills/deep-interview/SKILL.md +323 -0
  67. package/plugins/litclaude/skills/deep-interview/scripts/render_progress.py +193 -0
  68. package/plugins/litclaude/skills/frontend-ui-ux/SKILL.md +62 -0
  69. package/plugins/litclaude/skills/lit-loop/SKILL.md +144 -0
  70. package/plugins/litclaude/skills/lit-plan/SKILL.md +125 -0
  71. package/plugins/litclaude/skills/litgoal/SKILL.md +219 -0
  72. package/plugins/litclaude/skills/lsp/SKILL.md +63 -0
  73. package/plugins/litclaude/skills/programming/SKILL.md +106 -0
  74. package/plugins/litclaude/skills/programming/references/go/README.md +90 -0
  75. package/plugins/litclaude/skills/programming/references/go/backend-stack.md +641 -0
  76. package/plugins/litclaude/skills/programming/references/go/bootstrap.md +328 -0
  77. package/plugins/litclaude/skills/programming/references/go/bubbletea-v2.md +360 -0
  78. package/plugins/litclaude/skills/programming/references/go/cobra-stack.md +468 -0
  79. package/plugins/litclaude/skills/programming/references/go/concurrency.md +362 -0
  80. package/plugins/litclaude/skills/programming/references/go/data-modeling.md +329 -0
  81. package/plugins/litclaude/skills/programming/references/go/error-handling.md +359 -0
  82. package/plugins/litclaude/skills/programming/references/go/golangci-strict.md +236 -0
  83. package/plugins/litclaude/skills/programming/references/go/grpc-connect.md +375 -0
  84. package/plugins/litclaude/skills/programming/references/go/libraries.md +337 -0
  85. package/plugins/litclaude/skills/programming/references/go/one-liners.md +202 -0
  86. package/plugins/litclaude/skills/programming/references/go/sqlc-pgx.md +471 -0
  87. package/plugins/litclaude/skills/programming/references/go/testing.md +467 -0
  88. package/plugins/litclaude/skills/programming/references/go/type-patterns.md +298 -0
  89. package/plugins/litclaude/skills/programming/references/python/README.md +314 -0
  90. package/plugins/litclaude/skills/programming/references/python/async-anyio.md +442 -0
  91. package/plugins/litclaude/skills/programming/references/python/data-modeling.md +233 -0
  92. package/plugins/litclaude/skills/programming/references/python/data-processing.md +133 -0
  93. package/plugins/litclaude/skills/programming/references/python/error-handling.md +218 -0
  94. package/plugins/litclaude/skills/programming/references/python/fastapi-stack.md +316 -0
  95. package/plugins/litclaude/skills/programming/references/python/httpx2-optimization.md +360 -0
  96. package/plugins/litclaude/skills/programming/references/python/libraries.md +307 -0
  97. package/plugins/litclaude/skills/programming/references/python/one-liners.md +268 -0
  98. package/plugins/litclaude/skills/programming/references/python/orjson-stack.md +378 -0
  99. package/plugins/litclaude/skills/programming/references/python/pydantic-ai.md +285 -0
  100. package/plugins/litclaude/skills/programming/references/python/pyproject-strict.md +232 -0
  101. package/plugins/litclaude/skills/programming/references/python/textual-tui.md +201 -0
  102. package/plugins/litclaude/skills/programming/references/python/type-patterns.md +176 -0
  103. package/plugins/litclaude/skills/programming/references/rust/README.md +317 -0
  104. package/plugins/litclaude/skills/programming/references/rust/async-tokio.md +299 -0
  105. package/plugins/litclaude/skills/programming/references/rust/axum-stack.md +467 -0
  106. package/plugins/litclaude/skills/programming/references/rust/cargo-strict.md +317 -0
  107. package/plugins/litclaude/skills/programming/references/rust/clap-stack.md +409 -0
  108. package/plugins/litclaude/skills/programming/references/rust/concurrency.md +375 -0
  109. package/plugins/litclaude/skills/programming/references/rust/libraries.md +439 -0
  110. package/plugins/litclaude/skills/programming/references/rust/one-liners.md +291 -0
  111. package/plugins/litclaude/skills/programming/references/rust/proptest-insta.md +429 -0
  112. package/plugins/litclaude/skills/programming/references/rust/type-state.md +354 -0
  113. package/plugins/litclaude/skills/programming/references/rust/unsafe-discipline.md +250 -0
  114. package/plugins/litclaude/skills/programming/references/rust/zero-cost-safety.md +527 -0
  115. package/plugins/litclaude/skills/programming/references/rust-ub/README.md +289 -0
  116. package/plugins/litclaude/skills/programming/references/rust-ub/miri-sanitizers-loom.md +411 -0
  117. package/plugins/litclaude/skills/programming/references/rust-ub/ub-taxonomy.md +269 -0
  118. package/plugins/litclaude/skills/programming/references/typescript/README.md +195 -0
  119. package/plugins/litclaude/skills/programming/references/typescript/backend-hono.md +672 -0
  120. package/plugins/litclaude/skills/programming/references/typescript/bootstrap.md +199 -0
  121. package/plugins/litclaude/skills/programming/references/typescript/data-modeling.md +202 -0
  122. package/plugins/litclaude/skills/programming/references/typescript/error-handling.md +169 -0
  123. package/plugins/litclaude/skills/programming/references/typescript/tsconfig-strict.md +152 -0
  124. package/plugins/litclaude/skills/programming/references/typescript/type-patterns.md +196 -0
  125. package/plugins/litclaude/skills/programming/scripts/go/check-no-excuse-rules.sh +173 -0
  126. package/plugins/litclaude/skills/programming/scripts/go/new-project.py +138 -0
  127. package/plugins/litclaude/skills/programming/scripts/go/templates/.editorconfig +13 -0
  128. package/plugins/litclaude/skills/programming/scripts/go/templates/.golangci.yml +95 -0
  129. package/plugins/litclaude/skills/programming/scripts/go/templates/AGENTS.md.tmpl +24 -0
  130. package/plugins/litclaude/skills/programming/scripts/go/templates/README.md.tmpl +12 -0
  131. package/plugins/litclaude/skills/programming/scripts/go/templates/Taskfile.yml +40 -0
  132. package/plugins/litclaude/skills/programming/scripts/go/templates/ci.yml +37 -0
  133. package/plugins/litclaude/skills/programming/scripts/go/templates/config.go +24 -0
  134. package/plugins/litclaude/skills/programming/scripts/go/templates/gitignore +15 -0
  135. package/plugins/litclaude/skills/programming/scripts/go/templates/main.go.tmpl +22 -0
  136. package/plugins/litclaude/skills/programming/scripts/go/templates/run.go +15 -0
  137. package/plugins/litclaude/skills/programming/scripts/python/check-no-excuse-rules.py +687 -0
  138. package/plugins/litclaude/skills/programming/scripts/python/new-project.py +172 -0
  139. package/plugins/litclaude/skills/programming/scripts/python/new-script.py +116 -0
  140. package/plugins/litclaude/skills/programming/scripts/rust/check-no-excuse-rules.py +296 -0
  141. package/plugins/litclaude/skills/programming/scripts/rust/check-no-excuse-rules.sh +158 -0
  142. package/plugins/litclaude/skills/programming/scripts/rust/new-project.py +175 -0
  143. package/plugins/litclaude/skills/programming/scripts/typescript/check-no-excuse-rules.ts +282 -0
  144. package/plugins/litclaude/skills/programming/scripts/typescript/new-project.ts +177 -0
  145. package/plugins/litclaude/skills/refactor/SKILL.md +73 -0
  146. package/plugins/litclaude/skills/remove-ai-slops/SKILL.md +52 -0
  147. package/plugins/litclaude/skills/review-work/SKILL.md +331 -0
  148. package/plugins/litclaude/skills/rules/SKILL.md +66 -0
  149. package/plugins/litclaude/skills/start-work/SKILL.md +132 -0
  150. package/scripts/audit-plan-checkboxes.mjs +37 -0
  151. package/scripts/doctor.mjs +41 -0
  152. package/scripts/inspect-agent-tools.mjs +27 -0
  153. package/scripts/postinstall.mjs +50 -0
  154. package/scripts/qa-claude-plugin-smoke.sh +60 -0
  155. package/scripts/qa-portable-install.sh +136 -0
  156. package/scripts/validate-plugin.mjs +72 -0
@@ -0,0 +1,375 @@
1
+ # RPC — Connect-Go (default) + grpc-go (fallback) + protovalidate
2
+
3
+ `connectrpc/connect-go` is the default. It is wire-compatible with gRPC, also speaks Connect protocol + gRPC-Web from browsers, and uses ordinary `net/http` so middleware (logging, auth, tracing) composes the same way as REST. Reach for raw `grpc-go` only when you need a gRPC-specific feature Connect lacks.
4
+
5
+ ---
6
+
7
+ ## When Connect vs grpc-go
8
+
9
+ | Need | Use |
10
+ |---|---|
11
+ | Standard unary + server-streaming + client-streaming | **Connect** |
12
+ | Browser client without `grpc-web` proxy | **Connect** (native gRPC-Web support) |
13
+ | HTTP/1.1 fallback for hostile networks | **Connect** (gRPC requires HTTP/2 end-to-end) |
14
+ | Server reflection for `grpcurl` | grpc-go (Connect has reflection too, but ecosystem smaller) |
15
+ | Bidirectional streaming with frame-level control | grpc-go |
16
+ | Strict gRPC environment (Envoy with gRPC filters, Istio strict mode) | grpc-go |
17
+
18
+ **Default**: Connect. The default has been correct since 2024.
19
+
20
+ ---
21
+
22
+ ## Toolchain — Buf, not protoc
23
+
24
+ ```bash
25
+ go install github.com/bufbuild/buf/cmd/buf@latest
26
+ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
27
+ go install connectrpc.com/connect/cmd/protoc-gen-connect-go@latest
28
+ go install github.com/bufbuild/protovalidate/cmd/protoc-gen-go-vtproto@latest
29
+ ```
30
+
31
+ Buf replaces `protoc` for everything: linting, breaking-change detection, codegen, formatting. The `protoc` toolchain is dead-letter walking — every modern proto project uses Buf.
32
+
33
+ ---
34
+
35
+ ## Project layout
36
+
37
+ ```
38
+ proto/
39
+ buf.yaml
40
+ buf.gen.yaml
41
+ buf.lock
42
+ myservice/v1/
43
+ user.proto
44
+ auth.proto
45
+
46
+ gen/
47
+ myservice/v1/
48
+ user.pb.go # protoc-gen-go output
49
+ auth.pb.go
50
+ myservicev1connect/ # protoc-gen-connect-go output
51
+ user.connect.go
52
+ auth.connect.go
53
+ ```
54
+
55
+ **`gen/` is committed.** Generated code is part of the API contract; CI proves it is up-to-date.
56
+
57
+ ---
58
+
59
+ ## `buf.yaml`
60
+
61
+ ```yaml
62
+ version: v2
63
+ modules:
64
+ - path: proto
65
+ lint:
66
+ use:
67
+ - STANDARD
68
+ breaking:
69
+ use:
70
+ - FILE
71
+ ```
72
+
73
+ ## `buf.gen.yaml`
74
+
75
+ ```yaml
76
+ version: v2
77
+ managed:
78
+ enabled: true
79
+ override:
80
+ - file_option: go_package_prefix
81
+ value: github.com/your-org/myservice/gen
82
+ plugins:
83
+ - remote: buf.build/protocolbuffers/go
84
+ out: gen
85
+ opt:
86
+ - paths=source_relative
87
+ - remote: buf.build/connectrpc/go
88
+ out: gen
89
+ opt:
90
+ - paths=source_relative
91
+ - remote: buf.build/bufbuild/validate-go
92
+ out: gen
93
+ opt:
94
+ - paths=source_relative
95
+ ```
96
+
97
+ The `buf.build/...` plugin URIs use Buf's hosted remote registry — no local plugin installation needed.
98
+
99
+ ## Taskfile target
100
+
101
+ ```yaml
102
+ gen:proto:
103
+ cmds:
104
+ - buf lint
105
+ - buf format -w
106
+ - buf generate
107
+ sources:
108
+ - proto/**/*.proto
109
+ - buf.yaml
110
+ - buf.gen.yaml
111
+ ```
112
+
113
+ Run `task gen:proto` after editing any `.proto`. CI runs `buf generate` then `git diff --exit-code` to catch stale generated code.
114
+
115
+ ---
116
+
117
+ ## A `.proto` with validation
118
+
119
+ ```proto
120
+ syntax = "proto3";
121
+
122
+ package myservice.v1;
123
+
124
+ import "buf/validate/validate.proto";
125
+
126
+ option go_package = "github.com/your-org/myservice/gen/myservice/v1;myservicev1";
127
+
128
+ service UserService {
129
+ rpc CreateUser(CreateUserRequest) returns (CreateUserResponse);
130
+ rpc GetUser(GetUserRequest) returns (GetUserResponse);
131
+ rpc StreamEvents(StreamEventsRequest) returns (stream Event);
132
+ }
133
+
134
+ message CreateUserRequest {
135
+ string email = 1 [(buf.validate.field).string.email = true];
136
+ string username = 2 [
137
+ (buf.validate.field).string.min_len = 3,
138
+ (buf.validate.field).string.max_len = 32,
139
+ (buf.validate.field).string.pattern = "^[a-zA-Z0-9_]+$"
140
+ ];
141
+ int32 age = 3 [
142
+ (buf.validate.field).int32.gte = 13,
143
+ (buf.validate.field).int32.lte = 130
144
+ ];
145
+ }
146
+
147
+ message CreateUserResponse {
148
+ User user = 1;
149
+ }
150
+
151
+ message User {
152
+ string id = 1;
153
+ string email = 2;
154
+ string username = 3;
155
+ google.protobuf.Timestamp created_at = 4;
156
+ }
157
+ ```
158
+
159
+ `protovalidate` replaces the abandoned `protoc-gen-validate` — it is the official Buf-backed successor as of 2024, supported by Connect's interceptor pipeline.
160
+
161
+ ---
162
+
163
+ ## Server — Connect
164
+
165
+ ```go
166
+ package main
167
+
168
+ import (
169
+ "context"
170
+ "log/slog"
171
+ "net/http"
172
+
173
+ "connectrpc.com/connect"
174
+ "buf.build/go/protovalidate"
175
+ validateinterceptor "connectrpc.com/validate"
176
+ "golang.org/x/net/http2"
177
+ "golang.org/x/net/http2/h2c"
178
+
179
+ myservicev1 "github.com/your-org/myservice/gen/myservice/v1"
180
+ "github.com/your-org/myservice/gen/myservice/v1/myservicev1connect"
181
+ )
182
+
183
+ type UserServer struct {
184
+ svc *UserService
185
+ }
186
+
187
+ func (s *UserServer) CreateUser(
188
+ ctx context.Context,
189
+ req *connect.Request[myservicev1.CreateUserRequest],
190
+ ) (*connect.Response[myservicev1.CreateUserResponse], error) {
191
+
192
+ // protovalidate already ran via the interceptor below.
193
+ // req.Msg is guaranteed to satisfy the .proto constraints.
194
+
195
+ user, err := s.svc.Create(ctx, req.Msg.Email, req.Msg.Username, req.Msg.Age)
196
+ if err != nil {
197
+ return nil, mapError(err)
198
+ }
199
+ return connect.NewResponse(&myservicev1.CreateUserResponse{
200
+ User: userToProto(user),
201
+ }), nil
202
+ }
203
+
204
+ func main() {
205
+ validator, _ := protovalidate.New()
206
+ interceptors := connect.WithInterceptors(
207
+ loggingInterceptor(),
208
+ validateinterceptor.NewInterceptor(validator),
209
+ )
210
+
211
+ mux := http.NewServeMux()
212
+ mux.Handle(myservicev1connect.NewUserServiceHandler(
213
+ &UserServer{svc: newUserService()},
214
+ interceptors,
215
+ ))
216
+
217
+ // h2c lets the server speak HTTP/2 cleartext for gRPC clients.
218
+ srv := &http.Server{
219
+ Addr: ":8080",
220
+ Handler: h2c.NewHandler(mux, &http2.Server{}),
221
+ }
222
+ slog.Info("rpc server listening", slog.String("addr", srv.Addr))
223
+ if err := srv.ListenAndServe(); err != nil { slog.Error("rpc", slog.Any("err", err)) }
224
+ }
225
+ ```
226
+
227
+ The handler is **just an `http.Handler`** — mount it in the same `http.ServeMux` as your REST routes if you want one binary serving both.
228
+
229
+ ---
230
+
231
+ ## Error mapping — Connect codes
232
+
233
+ ```go
234
+ func mapError(err error) error {
235
+ if err == nil { return nil }
236
+
237
+ switch {
238
+ case errors.Is(err, domain.ErrInvalidEmail),
239
+ errors.Is(err, domain.ErrInvalidUsername):
240
+ return connect.NewError(connect.CodeInvalidArgument, err)
241
+ case errors.Is(err, ErrNotFound):
242
+ return connect.NewError(connect.CodeNotFound, err)
243
+ case errors.Is(err, ErrUnauthorized):
244
+ return connect.NewError(connect.CodeUnauthenticated, err)
245
+ case errors.Is(err, ErrConflict):
246
+ return connect.NewError(connect.CodeAlreadyExists, err)
247
+ default:
248
+ slog.Error("unmapped rpc error", slog.Any("err", err))
249
+ return connect.NewError(connect.CodeInternal, errors.New("internal"))
250
+ }
251
+ }
252
+ ```
253
+
254
+ Connect codes map 1:1 to gRPC codes. Clients see canonical error semantics.
255
+
256
+ ---
257
+
258
+ ## Logging interceptor
259
+
260
+ ```go
261
+ func loggingInterceptor() connect.UnaryInterceptorFunc {
262
+ return func(next connect.UnaryFunc) connect.UnaryFunc {
263
+ return func(ctx context.Context, req connect.AnyRequest) (connect.AnyResponse, error) {
264
+ start := time.Now()
265
+ res, err := next(ctx, req)
266
+ attrs := []slog.Attr{
267
+ slog.String("proc", req.Spec().Procedure),
268
+ slog.Duration("elapsed", time.Since(start)),
269
+ }
270
+ if err != nil {
271
+ attrs = append(attrs, slog.Any("err", err))
272
+ slog.LogAttrs(ctx, slog.LevelWarn, "rpc failed", attrs...)
273
+ } else {
274
+ slog.LogAttrs(ctx, slog.LevelInfo, "rpc ok", attrs...)
275
+ }
276
+ return res, err
277
+ }
278
+ }
279
+ }
280
+ ```
281
+
282
+ For streaming, implement the full `connect.Interceptor` (`WrapStreamingClient`, `WrapStreamingHandler`). Pattern is identical.
283
+
284
+ ---
285
+
286
+ ## Server streaming
287
+
288
+ ```go
289
+ func (s *UserServer) StreamEvents(
290
+ ctx context.Context,
291
+ req *connect.Request[myservicev1.StreamEventsRequest],
292
+ stream *connect.ServerStream[myservicev1.Event],
293
+ ) error {
294
+ events, errs := s.svc.Subscribe(ctx, req.Msg.UserId)
295
+ for {
296
+ select {
297
+ case <-ctx.Done():
298
+ return ctx.Err()
299
+ case e, ok := <-events:
300
+ if !ok { return nil }
301
+ if err := stream.Send(eventToProto(e)); err != nil {
302
+ return err
303
+ }
304
+ case err := <-errs:
305
+ return connect.NewError(connect.CodeInternal, err)
306
+ }
307
+ }
308
+ }
309
+ ```
310
+
311
+ Same shape as SSE in `backend-stack.md`. Connect handles HTTP/2 framing.
312
+
313
+ ---
314
+
315
+ ## Client
316
+
317
+ ```go
318
+ client := myservicev1connect.NewUserServiceClient(
319
+ http.DefaultClient,
320
+ "https://api.example.com",
321
+ // Use connect.WithGRPC() if the server is grpc-go and you want strict gRPC framing.
322
+ // Default is Connect protocol — works with Connect or gRPC servers transparently.
323
+ )
324
+
325
+ res, err := client.CreateUser(ctx, connect.NewRequest(&myservicev1.CreateUserRequest{
326
+ Email: "a@b.com",
327
+ Username: "alice",
328
+ Age: 30,
329
+ }))
330
+ if err != nil {
331
+ var connectErr *connect.Error
332
+ if errors.As(err, &connectErr) {
333
+ slog.Error("rpc failed",
334
+ slog.String("code", connectErr.Code().String()),
335
+ slog.String("msg", connectErr.Message()))
336
+ }
337
+ return err
338
+ }
339
+ slog.Info("created", slog.String("id", res.Msg.User.Id))
340
+ ```
341
+
342
+ ---
343
+
344
+ ## When you genuinely need raw grpc-go
345
+
346
+ ```go
347
+ import "google.golang.org/grpc"
348
+
349
+ lis, _ := net.Listen("tcp", ":8080")
350
+ srv := grpc.NewServer(
351
+ grpc.UnaryInterceptor(loggingUnaryInterceptor),
352
+ )
353
+ myservicev1.RegisterUserServiceServer(srv, &userServer{})
354
+ _ = srv.Serve(lis)
355
+ ```
356
+
357
+ The codegen is from `protoc-gen-go-grpc` (different binary from `protoc-gen-connect-go`). You can codegen **both** in the same `buf.gen.yaml` and switch by importing the right package. Most teams pick one.
358
+
359
+ ---
360
+
361
+ ## When NOT to use RPC at all
362
+
363
+ If your callers are all browsers, mobile apps, third-party developers, or the long tail of "things humans curl": **stay with REST + OpenAPI**. RPC's overhead is justified for service-to-service inside a single org. Outside that boundary, JSON over HTTP wins on debuggability.
364
+
365
+ `oapi-codegen/oapi-codegen/v2` generates Go server stubs and clients from OpenAPI 3 — the REST equivalent of what Connect does for proto. Same parse-don't-validate boundary discipline, different wire format.
366
+
367
+ ---
368
+
369
+ ## Sources
370
+
371
+ - Connect docs: https://connectrpc.com/docs/go/getting-started
372
+ - Buf: https://buf.build/docs
373
+ - protovalidate: https://github.com/bufbuild/protovalidate
374
+ - "Why we replaced protoc with buf" (Buf blog): https://buf.build/blog
375
+ - gRPC vs Connect comparison: https://connectrpc.com/docs/introduction