thevoidforge 21.0.11 → 21.0.13

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 (108) hide show
  1. package/dist/.claude/commands/ai.md +69 -0
  2. package/dist/.claude/commands/architect.md +121 -0
  3. package/dist/.claude/commands/assemble.md +201 -0
  4. package/dist/.claude/commands/assess.md +75 -0
  5. package/dist/.claude/commands/blueprint.md +135 -0
  6. package/dist/.claude/commands/build.md +116 -0
  7. package/dist/.claude/commands/campaign.md +201 -0
  8. package/dist/.claude/commands/cultivation.md +166 -0
  9. package/dist/.claude/commands/current.md +128 -0
  10. package/dist/.claude/commands/dangerroom.md +74 -0
  11. package/dist/.claude/commands/debrief.md +178 -0
  12. package/dist/.claude/commands/deploy.md +99 -0
  13. package/dist/.claude/commands/devops.md +143 -0
  14. package/dist/.claude/commands/gauntlet.md +140 -0
  15. package/dist/.claude/commands/git.md +104 -0
  16. package/dist/.claude/commands/grow.md +146 -0
  17. package/dist/.claude/commands/imagine.md +126 -0
  18. package/dist/.claude/commands/portfolio.md +50 -0
  19. package/dist/.claude/commands/prd.md +113 -0
  20. package/dist/.claude/commands/qa.md +107 -0
  21. package/dist/.claude/commands/review.md +151 -0
  22. package/dist/.claude/commands/security.md +100 -0
  23. package/dist/.claude/commands/test.md +96 -0
  24. package/dist/.claude/commands/thumper.md +116 -0
  25. package/dist/.claude/commands/treasury.md +100 -0
  26. package/dist/.claude/commands/ux.md +118 -0
  27. package/dist/.claude/commands/vault.md +189 -0
  28. package/dist/.claude/commands/void.md +108 -0
  29. package/dist/CHANGELOG.md +1918 -0
  30. package/dist/CLAUDE.md +250 -0
  31. package/dist/HOLOCRON.md +856 -0
  32. package/dist/VERSION.md +123 -0
  33. package/dist/docs/NAMING_REGISTRY.md +478 -0
  34. package/dist/docs/methods/AI_INTELLIGENCE.md +276 -0
  35. package/dist/docs/methods/ASSEMBLER.md +142 -0
  36. package/dist/docs/methods/BACKEND_ENGINEER.md +165 -0
  37. package/dist/docs/methods/BUILD_JOURNAL.md +185 -0
  38. package/dist/docs/methods/BUILD_PROTOCOL.md +426 -0
  39. package/dist/docs/methods/CAMPAIGN.md +568 -0
  40. package/dist/docs/methods/CONTEXT_MANAGEMENT.md +189 -0
  41. package/dist/docs/methods/DEEP_CURRENT.md +184 -0
  42. package/dist/docs/methods/DEVOPS_ENGINEER.md +295 -0
  43. package/dist/docs/methods/FIELD_MEDIC.md +261 -0
  44. package/dist/docs/methods/FORGE_ARTIST.md +108 -0
  45. package/dist/docs/methods/FORGE_KEEPER.md +268 -0
  46. package/dist/docs/methods/GAUNTLET.md +344 -0
  47. package/dist/docs/methods/GROWTH_STRATEGIST.md +466 -0
  48. package/dist/docs/methods/HEARTBEAT.md +168 -0
  49. package/dist/docs/methods/MCP_INTEGRATION.md +139 -0
  50. package/dist/docs/methods/MUSTER.md +148 -0
  51. package/dist/docs/methods/PRD_GENERATOR.md +186 -0
  52. package/dist/docs/methods/PRODUCT_DESIGN_FRONTEND.md +250 -0
  53. package/dist/docs/methods/QA_ENGINEER.md +337 -0
  54. package/dist/docs/methods/RELEASE_MANAGER.md +145 -0
  55. package/dist/docs/methods/SECURITY_AUDITOR.md +320 -0
  56. package/dist/docs/methods/SUB_AGENTS.md +335 -0
  57. package/dist/docs/methods/SYSTEMS_ARCHITECT.md +171 -0
  58. package/dist/docs/methods/TESTING.md +359 -0
  59. package/dist/docs/methods/THUMPER.md +175 -0
  60. package/dist/docs/methods/TIME_VAULT.md +120 -0
  61. package/dist/docs/methods/TREASURY.md +184 -0
  62. package/dist/docs/methods/TROUBLESHOOTING.md +265 -0
  63. package/dist/docs/patterns/README.md +52 -0
  64. package/dist/docs/patterns/ad-billing-adapter.ts +537 -0
  65. package/dist/docs/patterns/ad-platform-adapter.ts +421 -0
  66. package/dist/docs/patterns/ai-classifier.ts +195 -0
  67. package/dist/docs/patterns/ai-eval.ts +272 -0
  68. package/dist/docs/patterns/ai-orchestrator.ts +341 -0
  69. package/dist/docs/patterns/ai-router.ts +194 -0
  70. package/dist/docs/patterns/ai-tool-schema.ts +237 -0
  71. package/dist/docs/patterns/api-route.ts +241 -0
  72. package/dist/docs/patterns/backtest-engine.ts +499 -0
  73. package/dist/docs/patterns/browser-review.ts +292 -0
  74. package/dist/docs/patterns/combobox.tsx +300 -0
  75. package/dist/docs/patterns/component.tsx +262 -0
  76. package/dist/docs/patterns/daemon-process.ts +338 -0
  77. package/dist/docs/patterns/data-pipeline.ts +297 -0
  78. package/dist/docs/patterns/database-migration.ts +466 -0
  79. package/dist/docs/patterns/e2e-test.ts +629 -0
  80. package/dist/docs/patterns/error-handling.ts +312 -0
  81. package/dist/docs/patterns/execution-safety.ts +601 -0
  82. package/dist/docs/patterns/financial-transaction.ts +342 -0
  83. package/dist/docs/patterns/funding-plan.ts +462 -0
  84. package/dist/docs/patterns/game-entity.ts +137 -0
  85. package/dist/docs/patterns/game-loop.ts +113 -0
  86. package/dist/docs/patterns/game-state.ts +143 -0
  87. package/dist/docs/patterns/job-queue.ts +225 -0
  88. package/dist/docs/patterns/kongo-integration.ts +164 -0
  89. package/dist/docs/patterns/middleware.ts +363 -0
  90. package/dist/docs/patterns/mobile-screen.tsx +139 -0
  91. package/dist/docs/patterns/mobile-service.ts +167 -0
  92. package/dist/docs/patterns/multi-tenant.ts +382 -0
  93. package/dist/docs/patterns/oauth-token-lifecycle.ts +223 -0
  94. package/dist/docs/patterns/outbound-rate-limiter.ts +260 -0
  95. package/dist/docs/patterns/prompt-template.ts +195 -0
  96. package/dist/docs/patterns/revenue-source-adapter.ts +311 -0
  97. package/dist/docs/patterns/service.ts +224 -0
  98. package/dist/docs/patterns/sse-endpoint.ts +118 -0
  99. package/dist/docs/patterns/stablecoin-adapter.ts +511 -0
  100. package/dist/docs/patterns/third-party-script.ts +68 -0
  101. package/dist/scripts/thumper/gom-jabbar.sh +241 -0
  102. package/dist/scripts/thumper/relay.sh +610 -0
  103. package/dist/scripts/thumper/scan.sh +359 -0
  104. package/dist/scripts/thumper/thumper.sh +190 -0
  105. package/dist/scripts/thumper/water-rings.sh +76 -0
  106. package/dist/wizard/ui/index.html +1 -1
  107. package/package.json +1 -1
  108. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -0,0 +1,312 @@
1
+ /**
2
+ * Pattern: Error Handling Strategy (Canonical Reference)
3
+ *
4
+ * This is the single source of truth for error handling across VoidForge.
5
+ * All other patterns (api-route.ts, service.ts, middleware.ts) reference this.
6
+ *
7
+ * Key principles:
8
+ * - Custom error types with codes, not raw Error throws
9
+ * - Catch at boundaries (route handlers), not in services
10
+ * - Never leak internals (stack traces, DB errors, file paths)
11
+ * - Structured error responses with consistent shape
12
+ * - Log errors with context (requestId, userId, action)
13
+ * - Different handling for operational vs programmer errors
14
+ *
15
+ * Agents: Barton (error handling), Kenobi (security — never leak), L (monitoring)
16
+ *
17
+ * Framework adaptations:
18
+ * Next.js: Global error handler in middleware or route wrapper
19
+ * Django: Custom exception handler in DRF, or middleware
20
+ * Rails: rescue_from in ApplicationController
21
+ * Express: Error-handling middleware (err, req, res, next)
22
+ *
23
+ * === Django Deep Dive (DRF) ===
24
+ *
25
+ * # app/exceptions.py — domain exceptions (same shape as TypeScript ApiError)
26
+ * class AppError(Exception):
27
+ * def __init__(self, message, status_code=500, code="INTERNAL_ERROR"):
28
+ * self.message = message
29
+ * self.status_code = status_code
30
+ * self.code = code
31
+ *
32
+ * class NotFoundError(AppError):
33
+ * def __init__(self, message="Not found"):
34
+ * super().__init__(message, 404, "NOT_FOUND")
35
+ *
36
+ * class ForbiddenError(AppError):
37
+ * def __init__(self, message="Forbidden"):
38
+ * super().__init__(message, 403, "FORBIDDEN")
39
+ *
40
+ * class ValidationError(AppError):
41
+ * def __init__(self, message="Validation failed"):
42
+ * super().__init__(message, 400, "VALIDATION_ERROR")
43
+ *
44
+ * # settings.py — register custom handler
45
+ * REST_FRAMEWORK = {
46
+ * 'EXCEPTION_HANDLER': 'app.exception_handler.custom_exception_handler'
47
+ * }
48
+ *
49
+ * # app/exception_handler.py
50
+ * def custom_exception_handler(exc, context):
51
+ * if isinstance(exc, AppError):
52
+ * return Response(
53
+ * {"success": False, "error": exc.message, "code": exc.code},
54
+ * status=exc.status_code
55
+ * )
56
+ * # Fall through to DRF default for validation errors, auth errors, etc.
57
+ * response = exception_handler(exc, context)
58
+ * if response: return response
59
+ * # Unhandled — log and return 500 (never leak internals)
60
+ * logger.error(f"Unhandled: {exc}", exc_info=True)
61
+ * return Response({"success": False, "error": "Internal error"}, status=500)
62
+ *
63
+ * === FastAPI Deep Dive ===
64
+ *
65
+ * # app/exceptions.py — same domain exceptions
66
+ * class AppError(Exception):
67
+ * def __init__(self, message: str, status_code: int = 500, code: str = "INTERNAL_ERROR"):
68
+ * self.message = message
69
+ * self.status_code = status_code
70
+ * self.code = code
71
+ *
72
+ * # app/main.py — register handler
73
+ * @app.exception_handler(AppError)
74
+ * async def app_error_handler(request, exc: AppError):
75
+ * return JSONResponse(
76
+ * status_code=exc.status_code,
77
+ * content={"success": False, "error": exc.message, "code": exc.code}
78
+ * )
79
+ *
80
+ * @app.exception_handler(Exception)
81
+ * async def unhandled_error_handler(request, exc):
82
+ * logger.error(f"Unhandled: {exc}", exc_info=True)
83
+ * return JSONResponse(
84
+ * status_code=500,
85
+ * content={"success": False, "error": "Internal error"}
86
+ * )
87
+ *
88
+ * # Pydantic validation errors are handled automatically by FastAPI (422)
89
+ * # Never leak stack traces — the unhandled handler catches everything
90
+ */
91
+
92
+ // ============================================================
93
+ // 1. ERROR TYPES — used across all services
94
+ // ============================================================
95
+
96
+ export class ApiError extends Error {
97
+ constructor(
98
+ public code: string,
99
+ message: string,
100
+ public status: number
101
+ ) {
102
+ super(message)
103
+ this.name = 'ApiError'
104
+ }
105
+ }
106
+
107
+ // Pre-built errors for common cases
108
+ export const Errors = {
109
+ unauthorized: () => new ApiError('UNAUTHORIZED', 'Authentication required', 401),
110
+ forbidden: () => new ApiError('FORBIDDEN', 'Insufficient permissions', 403),
111
+ notFound: (resource = 'Resource') => new ApiError('NOT_FOUND', `${resource} not found`, 404),
112
+ validation: (details: Record<string, string[]>) =>
113
+ Object.assign(new ApiError('VALIDATION_ERROR', 'Invalid input', 400), { details }),
114
+ conflict: (message: string) => new ApiError('CONFLICT', message, 409),
115
+ rateLimited: () => new ApiError('RATE_LIMITED', 'Too many requests', 429),
116
+ internal: () => new ApiError('INTERNAL_ERROR', 'Something went wrong', 500),
117
+ } as const
118
+
119
+ // ============================================================
120
+ // 2. ERROR RESPONSE SHAPE — consistent across all routes
121
+ // ============================================================
122
+
123
+ /*
124
+ Success:
125
+ {
126
+ "data": { ... }
127
+ }
128
+
129
+ Error:
130
+ {
131
+ "error": {
132
+ "code": "VALIDATION_ERROR", // Machine-readable
133
+ "message": "Invalid input", // Human-readable
134
+ "details": { ... } // Optional — field-level errors
135
+ }
136
+ }
137
+
138
+ Never include:
139
+ - Stack traces
140
+ - Internal file paths
141
+ - Database error messages
142
+ - SQL queries
143
+ - Environment variable names
144
+ */
145
+
146
+ // ============================================================
147
+ // 3. GLOBAL ERROR HANDLER — catches everything at the boundary
148
+ // ============================================================
149
+
150
+ import { NextResponse } from 'next/server'
151
+
152
+ export function handleApiError(error: unknown): NextResponse {
153
+ // Known operational errors — safe to expose
154
+ if (error instanceof ApiError) {
155
+ const body: Record<string, unknown> = {
156
+ error: {
157
+ code: error.code,
158
+ message: error.message,
159
+ },
160
+ }
161
+
162
+ // Include validation details if present
163
+ if ('details' in error) {
164
+ (body.error as Record<string, unknown>).details = (error as any).details
165
+ }
166
+
167
+ return NextResponse.json(body, { status: error.status })
168
+ }
169
+
170
+ // Unknown/programmer errors — log everything, expose nothing
171
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error'
172
+ const errorStack = error instanceof Error ? error.stack : undefined
173
+
174
+ // Structured log with full context (L — monitoring)
175
+ console.error(JSON.stringify({
176
+ event: 'unhandled_error',
177
+ message: errorMessage,
178
+ stack: errorStack,
179
+ timestamp: new Date().toISOString(),
180
+ // requestId and userId would be added by logging middleware
181
+ }))
182
+
183
+ // Generic response — never leak internals (Kenobi)
184
+ return NextResponse.json(
185
+ { error: { code: 'INTERNAL_ERROR', message: 'Something went wrong' } },
186
+ { status: 500 }
187
+ )
188
+ }
189
+
190
+ // ============================================================
191
+ // 4. USAGE IN SERVICES — throw typed errors
192
+ // ============================================================
193
+
194
+ /*
195
+ // In a service:
196
+ async function getProject(id: string, userId: string) {
197
+ const project = await db.project.findUnique({ where: { id } })
198
+
199
+ if (!project) {
200
+ throw Errors.notFound('Project') // 404 — clear, typed
201
+ }
202
+
203
+ if (project.ownerId !== userId) {
204
+ throw Errors.notFound('Project') // 404 (not 403) — don't reveal existence
205
+ }
206
+
207
+ return project
208
+ }
209
+
210
+ // In a route handler:
211
+ export async function GET(req: NextRequest) {
212
+ try {
213
+ const project = await getProject(id, userId)
214
+ return NextResponse.json({ data: project })
215
+ } catch (error) {
216
+ return handleApiError(error) // Single catch, handles everything
217
+ }
218
+ }
219
+ */
220
+
221
+ // ============================================================
222
+ // 5. OPERATIONAL vs PROGRAMMER ERRORS
223
+ // ============================================================
224
+
225
+ /*
226
+ OPERATIONAL (expected, handled):
227
+ - User not found → 404
228
+ - Invalid input → 400
229
+ - Unauthorized → 401
230
+ - Rate limited → 429
231
+ - External API down → 503 (with retry header)
232
+ → Throw ApiError. The handler returns the right status code.
233
+
234
+ PROGRAMMER (unexpected, bugs):
235
+ - TypeError, ReferenceError
236
+ - Unhandled promise rejection
237
+ - Database connection lost
238
+ - Out of memory
239
+ → Caught by handleApiError's fallback. Returns 500. Logged with full stack.
240
+ These indicate bugs — investigate and fix the root cause.
241
+ */
242
+
243
+ // ============================================================
244
+ // 6. FRAMEWORK ADAPTATIONS
245
+ // ============================================================
246
+
247
+ // --- Express error middleware ---
248
+ /*
249
+ // middleware/errorHandler.ts
250
+ import { Request, Response, NextFunction } from 'express'
251
+
252
+ export function errorHandler(err: unknown, req: Request, res: Response, next: NextFunction) {
253
+ if (err instanceof ApiError) {
254
+ return res.status(err.status).json({
255
+ error: { code: err.code, message: err.message }
256
+ })
257
+ }
258
+
259
+ console.error(JSON.stringify({
260
+ event: 'unhandled_error',
261
+ message: err instanceof Error ? err.message : 'Unknown',
262
+ path: req.path,
263
+ method: req.method,
264
+ }))
265
+
266
+ res.status(500).json({
267
+ error: { code: 'INTERNAL_ERROR', message: 'Something went wrong' }
268
+ })
269
+ }
270
+
271
+ // app.ts — register LAST
272
+ app.use(errorHandler)
273
+ */
274
+
275
+ // --- Django exception handler ---
276
+ /*
277
+ # utils/exceptions.py
278
+ from rest_framework.views import exception_handler
279
+ from rest_framework.response import Response
280
+
281
+ def custom_exception_handler(exc, context):
282
+ if isinstance(exc, ApiError):
283
+ return Response(
284
+ {'error': {'code': exc.code, 'message': str(exc)}},
285
+ status=exc.status_code
286
+ )
287
+
288
+ response = exception_handler(exc, context)
289
+ if response is None:
290
+ logger.error(f'Unhandled error: {exc}', exc_info=True)
291
+ return Response(
292
+ {'error': {'code': 'INTERNAL_ERROR', 'message': 'Something went wrong'}},
293
+ status=500
294
+ )
295
+ return response
296
+ */
297
+
298
+ // --- Rails rescue_from ---
299
+ /*
300
+ # app/controllers/application_controller.rb
301
+ class ApplicationController < ActionController::API
302
+ rescue_from ApiError do |e|
303
+ render json: { error: { code: e.code, message: e.message } }, status: e.status
304
+ end
305
+
306
+ rescue_from StandardError do |e|
307
+ Rails.logger.error("Unhandled error: #{e.message}\n#{e.backtrace.first(5).join("\n")}")
308
+ render json: { error: { code: 'INTERNAL_ERROR', message: 'Something went wrong' } },
309
+ status: :internal_server_error
310
+ end
311
+ end
312
+ */