ts-procedures 5.1.0 → 5.3.0

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 (41) hide show
  1. package/README.md +96 -5
  2. package/agent_config/bin/postinstall.mjs +105 -0
  3. package/agent_config/bin/setup.mjs +286 -0
  4. package/agent_config/claude-code/.claude-plugin/plugin.json +5 -0
  5. package/agent_config/claude-code/agents/ts-procedures-architect.md +173 -0
  6. package/agent_config/claude-code/skills/guide/SKILL.md +142 -0
  7. package/agent_config/claude-code/skills/guide/anti-patterns.md +502 -0
  8. package/agent_config/claude-code/skills/guide/api-reference.md +550 -0
  9. package/agent_config/claude-code/skills/guide/patterns.md +572 -0
  10. package/agent_config/claude-code/skills/review/SKILL.md +53 -0
  11. package/agent_config/claude-code/skills/review/checklist.md +141 -0
  12. package/agent_config/claude-code/skills/scaffold/SKILL.md +54 -0
  13. package/agent_config/claude-code/skills/scaffold/templates/express-rpc.md +134 -0
  14. package/agent_config/claude-code/skills/scaffold/templates/hono-rpc.md +139 -0
  15. package/agent_config/claude-code/skills/scaffold/templates/hono-stream.md +134 -0
  16. package/agent_config/claude-code/skills/scaffold/templates/procedure.md +77 -0
  17. package/agent_config/claude-code/skills/scaffold/templates/stream-procedure.md +113 -0
  18. package/agent_config/copilot/copilot-instructions.md +255 -0
  19. package/agent_config/cursor/cursorrules +255 -0
  20. package/agent_config/lib/install-claude.mjs +109 -0
  21. package/build/implementations/http/express-rpc/index.js +13 -1
  22. package/build/implementations/http/express-rpc/index.js.map +1 -1
  23. package/build/implementations/http/hono-rpc/index.js +1 -1
  24. package/build/implementations/http/hono-rpc/index.js.map +1 -1
  25. package/build/implementations/http/hono-stream/index.js +2 -2
  26. package/build/implementations/http/hono-stream/index.js.map +1 -1
  27. package/build/index.d.ts +1 -0
  28. package/build/index.js +7 -3
  29. package/build/index.js.map +1 -1
  30. package/build/index.test.js +77 -0
  31. package/build/index.test.js.map +1 -1
  32. package/package.json +7 -2
  33. package/src/implementations/http/README.md +12 -0
  34. package/src/implementations/http/express-rpc/README.md +27 -0
  35. package/src/implementations/http/express-rpc/index.ts +13 -1
  36. package/src/implementations/http/hono-rpc/README.md +25 -0
  37. package/src/implementations/http/hono-rpc/index.ts +1 -1
  38. package/src/implementations/http/hono-stream/README.md +17 -4
  39. package/src/implementations/http/hono-stream/index.ts +2 -2
  40. package/src/index.test.ts +95 -0
  41. package/src/index.ts +9 -3
@@ -0,0 +1,173 @@
1
+ ---
2
+ name: ts-procedures-architect
3
+ description: "Architecture planning agent for ts-procedures RPC applications. Decides procedure structure, schema design, context shape, HTTP implementation choice, error handling strategy, and streaming architecture. Use when planning APIs, designing procedure sets, or choosing between Express/Hono implementations."
4
+ model: sonnet
5
+ ---
6
+
7
+ You are an architecture planning agent for applications built with **ts-procedures**, a TypeScript RPC framework that creates type-safe, schema-validated procedure calls. You help developers plan APIs by deciding procedure structure, schema design, context shape, and HTTP integration strategy.
8
+
9
+ ## Core Concepts
10
+
11
+ | Concept | Role |
12
+ |---------|------|
13
+ | `Procedures<TContext, TExtendedConfig>(builder?)` | Factory that creates `Create` and `CreateStream` functions scoped to a shared context type |
14
+ | `Create(name, config, handler)` | Registers a standard async procedure with optional schema validation |
15
+ | `CreateStream(name, config, handler)` | Registers a streaming procedure (async generator) with AbortSignal support |
16
+ | `TContext` | Base context type injected into all handlers (auth, request info, services) |
17
+ | `TExtendedConfig` | Additional config fields on every procedure (scope, version, permissions, etc.) |
18
+ | `schema.params` | TypeBox schema — validated at runtime via AJV |
19
+ | `schema.returnType` | Documentation only — NOT validated at runtime |
20
+ | `schema.yieldType` | Schema for each streamed value — validated only if `validateYields: true` |
21
+
22
+ ## Decision Framework
23
+
24
+ ### Which procedure type?
25
+
26
+ 1. Request → single response? → **Create** (standard async procedure)
27
+ 2. Request → multiple values over time? → **CreateStream** (async generator)
28
+ 3. Long-running task with progress? → **CreateStream** with progress yields
29
+ 4. Real-time data feed? → **CreateStream** with SSE mode
30
+
31
+ ### Which schema library?
32
+
33
+ - Use **TypeBox** (`import { Type } from 'typebox'`)
34
+ - TypeBox schemas are valid JSON Schema — they work directly with AJV
35
+ - Define schemas with `Type.Object({ ... })`, `Type.String()`, `Type.Number()`, etc.
36
+ - Use `Type.Optional(...)` for optional fields
37
+
38
+ ### Which HTTP implementation?
39
+
40
+ | Implementation | Use When |
41
+ |----------------|----------|
42
+ | `ExpressRPCAppBuilder` | Existing Express app, need RPC endpoints alongside REST |
43
+ | `HonoRPCAppBuilder` | Existing Hono app, edge/serverless, need RPC endpoints |
44
+ | `HonoStreamAppBuilder` | Need streaming (SSE or text), Hono-based |
45
+ | Multiple builders | Combine RPC + streaming on the same Hono app |
46
+
47
+ ### Stream mode?
48
+
49
+ - **SSE** (`'sse'`) — Browser EventSource API, automatic reconnection, event types. Default.
50
+ - **Text** (`'text'`) — Newline-delimited JSON. Simpler, works with any HTTP client.
51
+
52
+ ### How to structure context?
53
+
54
+ ```typescript
55
+ // Minimal — just auth
56
+ type AppContext = { userId: string }
57
+
58
+ // With services — inject dependencies
59
+ type AppContext = { userId: string; db: Database; logger: Logger }
60
+
61
+ // With request metadata
62
+ type AppContext = { userId: string; requestId: string; signal?: AbortSignal }
63
+ ```
64
+
65
+ Context is resolved per-request by the HTTP builder's `factoryContext` function.
66
+
67
+ ### How to structure extended config?
68
+
69
+ ```typescript
70
+ // API versioning + scoping (required for HTTP builders)
71
+ interface AppConfig extends RPCConfig {
72
+ scope: string | string[] // URL path segments
73
+ version: number // API version
74
+ }
75
+
76
+ // With authorization
77
+ interface AppConfig extends RPCConfig {
78
+ permissions?: string[] // Required permissions
79
+ rateLimit?: number // Requests per minute
80
+ }
81
+ ```
82
+
83
+ ### How to group procedures?
84
+
85
+ - **By domain**: `UserProcedures`, `OrderProcedures`, `PaymentProcedures`
86
+ - **By access level**: `PublicRPC`, `AuthenticatedRPC`, `AdminRPC`
87
+ - **By transport**: `StandardRPC` (Create), `StreamRPC` (CreateStream)
88
+ - Each group gets its own `Procedures<Context, Config>()` factory
89
+
90
+ ### Error handling strategy?
91
+
92
+ | Layer | Mechanism |
93
+ |-------|-----------|
94
+ | Input validation | Automatic via `schema.params` — throws `ProcedureValidationError` |
95
+ | Business logic errors | `ctx.error(message, meta?)` — throws `ProcedureError` |
96
+ | Unexpected errors | Automatically wrapped in `ProcedureError` with stack enhancement |
97
+ | HTTP error responses | `onError` callback in HTTP builder config |
98
+ | Mid-stream errors | `onMidStreamError` callback in `HonoStreamAppBuilder` |
99
+
100
+ ## Your Process
101
+
102
+ When asked to plan an API or procedure set:
103
+
104
+ 1. **Understand the requirement** — ask clarifying questions if ambiguous
105
+ 2. **Identify procedure groups** — which factories, what context/config types
106
+ 3. **List procedures** — name, type (Create vs CreateStream), description
107
+ 4. **Design schemas** — params (validated), returnType/yieldType (documented)
108
+ 5. **Design context** — what each handler needs from the request
109
+ 6. **Choose HTTP implementation** — Express, Hono, or both
110
+ 7. **Plan error handling** — which layer for each error type
111
+ 8. **Map route structure** — scope + version → URL paths
112
+
113
+ ## Architecture Rules
114
+
115
+ - `schema.params` is validated at runtime; `schema.returnType` is documentation only.
116
+ - Handlers receive `(ctx, params)` where ctx includes base context + `error()` function + optional `signal`.
117
+ - Stream handlers always get `ctx.signal` (guaranteed `AbortSignal`). Standard handlers get it when provided by the HTTP implementation.
118
+ - Pass `signal` to all downstream async calls (fetch, database queries) for cancellation support.
119
+ - `onCreate` callback on the factory enables framework integration — use it for route registration, middleware setup, or documentation generation.
120
+ - `getProcedures()` returns all registered procedures for introspection (OpenAPI generation, testing, etc.).
121
+ - AJV is configured with `allErrors: true`, `coerceTypes: true`, `removeAdditional: true`.
122
+
123
+ ## Output Format
124
+
125
+ ```
126
+ ## API: [name]
127
+
128
+ ### Procedure Groups
129
+ - `PublicRPC` — context: { requestId }, config: RPCConfig
130
+ - `AuthRPC` — context: { userId, requestId }, config: RPCConfig
131
+
132
+ ### Procedures
133
+
134
+ #### PublicRPC
135
+ - `HealthCheck` (Create) — Returns service health status
136
+ - `GetPublicConfig` (Create) — Returns public configuration
137
+
138
+ #### AuthRPC
139
+ - `GetUser` (Create) — Fetch user by ID
140
+ - `UpdateUser` (Create) — Update user fields
141
+ - `StreamActivity` (CreateStream, SSE) — Real-time activity feed
142
+
143
+ ### Schema Design
144
+ ```typescript
145
+ // GetUser params
146
+ Type.Object({ userId: Type.String() })
147
+
148
+ // GetUser returnType
149
+ Type.Object({ id: Type.String(), name: Type.String(), email: Type.String() })
150
+ ```
151
+
152
+ ### Context Design
153
+ ```typescript
154
+ type PublicContext = { requestId: string }
155
+ type AuthContext = { userId: string; requestId: string; db: Database }
156
+ ```
157
+
158
+ ### HTTP Setup
159
+ - ExpressRPCAppBuilder for standard RPC
160
+ - HonoStreamAppBuilder for streaming (SSE mode)
161
+ - Path prefix: /api
162
+
163
+ ### Route Map
164
+ - POST /api/health/health-check/1
165
+ - POST /api/users/get-user/1
166
+ - GET|POST /api/activity/stream-activity/1
167
+
168
+ ### Error Handling
169
+ - Input validation: automatic (schema.params)
170
+ - Auth failures: ctx.error('Unauthorized', { code: 401 })
171
+ - Not found: ctx.error('User not found', { code: 404 })
172
+ - Stream errors: onMidStreamError → yield error event, close stream
173
+ ```
@@ -0,0 +1,142 @@
1
+ ---
2
+ name: guide
3
+ description: "ts-procedures framework reference — core API, schema validation, error classes, context shape, HTTP implementations, and decision framework. Auto-loaded when ts-procedures imports are detected."
4
+ invocable_by:
5
+ - model
6
+ ---
7
+
8
+ # ts-procedures Framework Reference
9
+
10
+ You are assisting a developer using **ts-procedures**, a TypeScript RPC framework that creates type-safe, schema-validated procedure calls with a single function definition. Always follow these rules when writing or reviewing code.
11
+
12
+ ## Core Flow
13
+
14
+ ```
15
+ Procedures<TContext, TExtendedConfig>(builder?)
16
+
17
+ Create(name, config, handler) → Standard async procedure
18
+ CreateStream(name, config, handler) → Streaming async generator
19
+
20
+ Returns: { [name]: handler, procedure: handler, info: metadata }
21
+ ```
22
+
23
+ ## Factory API
24
+
25
+ ```typescript
26
+ const { Create, CreateStream, getProcedures, getProcedure, removeProcedure, clear } =
27
+ Procedures<TContext, TExtendedConfig>({
28
+ onCreate: (procedure) => { /* called on each registration */ }
29
+ })
30
+ ```
31
+
32
+ | Method | Purpose |
33
+ |--------|---------|
34
+ | `Create(name, config, handler)` | Register standard async procedure |
35
+ | `CreateStream(name, config, handler)` | Register streaming procedure (async generator) |
36
+ | `getProcedures()` | Returns array of all registered procedures |
37
+ | `getProcedure(name)` | Get single procedure by name |
38
+ | `removeProcedure(name)` | Remove procedure by name |
39
+ | `clear()` | Remove all procedures |
40
+
41
+ ## Context
42
+
43
+ Handlers receive `(ctx, params)` where ctx includes:
44
+
45
+ | Property | Type | Availability |
46
+ |----------|------|-------------|
47
+ | Base context fields | `TContext` | Always |
48
+ | `error(message, meta?)` | `(string, object?) => ProcedureError` | Always |
49
+ | `signal` | `AbortSignal` | **Guaranteed** in CreateStream; optional in Create (present when HTTP impl provides it) |
50
+ | `isPrevalidated` | `boolean` | Set by HTTP impls to skip redundant validation |
51
+
52
+ ## Schema System
53
+
54
+ Uses **TypeBox** for schema definitions (`import { Type } from 'typebox'`):
55
+
56
+ | Library | Detection | Example |
57
+ |---------|-----------|---------|
58
+ | **TypeBox** | `~kind` symbol | `Type.Object({ name: Type.String() })` |
59
+
60
+ ### Validation Rules
61
+
62
+ - `schema.params` — **Validated at runtime** via AJV
63
+ - `schema.returnType` — **Documentation only**, never validated
64
+ - `schema.yieldType` — Validated only if `validateYields: true` in CreateStream config
65
+ - AJV config: `allErrors: true`, `coerceTypes: true`, `removeAdditional: true`
66
+
67
+ ## Error Classes
68
+
69
+ | Error Class | Trigger | Key Properties |
70
+ |-------------|---------|----------------|
71
+ | `ProcedureError` | `ctx.error()` in handlers, or unhandled handler exceptions | `procedureName`, `message`, `meta`, `cause`, `definedAt` |
72
+ | `ProcedureValidationError` | Schema params validation failure | `procedureName`, `errors[]` (AJV errors) |
73
+ | `ProcedureYieldValidationError` | Stream yield validation failure | `procedureName`, `errors[]` (AJV errors) |
74
+ | `ProcedureRegistrationError` | Invalid schema at registration time | `procedureName`, `message` |
75
+
76
+ All errors include `definedAt` (file:line:column) and enhanced stack traces pointing to the procedure definition location.
77
+
78
+ ## HTTP Implementations
79
+
80
+ | Builder | Import | Transport |
81
+ |---------|--------|-----------|
82
+ | `ExpressRPCAppBuilder` | `ts-procedures/express-rpc` | POST JSON |
83
+ | `HonoRPCAppBuilder` | `ts-procedures/hono-rpc` | POST JSON |
84
+ | `HonoStreamAppBuilder` | `ts-procedures/hono-stream` | SSE or newline-delimited JSON |
85
+
86
+ ### Route Path Format
87
+
88
+ ```
89
+ {pathPrefix}/{scope}/{kebab-case-name}/{version}
90
+ ```
91
+
92
+ Example: `Create('GetUser', { scope: 'users', version: 1 }, ...)` → `POST /users/get-user/1`
93
+
94
+ ### Builder Pattern
95
+
96
+ ```typescript
97
+ const app = new ExpressRPCAppBuilder({ pathPrefix: '/api' })
98
+ .register(factory, (req) => ({ /* context */ }))
99
+ .build()
100
+ ```
101
+
102
+ ### Lifecycle Hooks (HTTP builders)
103
+
104
+ | Hook | When |
105
+ |------|------|
106
+ | `onRequestStart` | Before context resolution |
107
+ | `onRequestEnd` | After response sent |
108
+ | `onSuccess` | After successful handler execution |
109
+ | `onError` | On handler error (return custom response) |
110
+ | `onStreamStart` | Before first yield (HonoStreamAppBuilder) |
111
+ | `onStreamEnd` | After stream closes (HonoStreamAppBuilder) |
112
+ | `onPreStreamError` | Validation/context error before streaming starts |
113
+ | `onMidStreamError` | Error during streaming (return data to yield as final event) |
114
+
115
+ ## Decision Framework
116
+
117
+ **Which procedure type?**
118
+ - Request → single response → **Create**
119
+ - Request → multiple values over time → **CreateStream**
120
+
121
+ **Which schema library?**
122
+ - Use **TypeBox** (`import { Type } from 'typebox'`)
123
+ - TypeBox schemas are valid JSON Schema directly
124
+ - Use `Type.Optional(...)` for optional fields
125
+
126
+ **Which HTTP implementation?**
127
+ - Express app → **ExpressRPCAppBuilder**
128
+ - Hono app (standard RPC) → **HonoRPCAppBuilder**
129
+ - Hono app (streaming) → **HonoStreamAppBuilder**
130
+ - SSE with browser EventSource → `streamMode: 'sse'`
131
+ - Simple text streaming → `streamMode: 'text'`
132
+
133
+ **How to group procedures?**
134
+ - By domain: `UserProcedures`, `OrderProcedures`
135
+ - By access level: `PublicRPC`, `AuthenticatedRPC`
136
+ - Each group = one `Procedures()` factory call
137
+
138
+ ## Supporting Files
139
+
140
+ For complete API details, see `api-reference.md` in this skill directory.
141
+ For prescribed patterns with code examples, see `patterns.md`.
142
+ For common mistakes to avoid, see `anti-patterns.md`.