tribunal-kit 2.4.6 → 3.0.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 (142) hide show
  1. package/.agent/agents/accessibility-reviewer.md +220 -134
  2. package/.agent/agents/ai-code-reviewer.md +233 -129
  3. package/.agent/agents/backend-specialist.md +238 -178
  4. package/.agent/agents/code-archaeologist.md +181 -119
  5. package/.agent/agents/database-architect.md +207 -164
  6. package/.agent/agents/debugger.md +218 -151
  7. package/.agent/agents/dependency-reviewer.md +136 -55
  8. package/.agent/agents/devops-engineer.md +238 -175
  9. package/.agent/agents/documentation-writer.md +221 -137
  10. package/.agent/agents/explorer-agent.md +180 -142
  11. package/.agent/agents/frontend-reviewer.md +194 -80
  12. package/.agent/agents/frontend-specialist.md +237 -188
  13. package/.agent/agents/game-developer.md +52 -184
  14. package/.agent/agents/logic-reviewer.md +149 -78
  15. package/.agent/agents/mobile-developer.md +223 -152
  16. package/.agent/agents/mobile-reviewer.md +195 -79
  17. package/.agent/agents/orchestrator.md +211 -170
  18. package/.agent/agents/penetration-tester.md +174 -131
  19. package/.agent/agents/performance-optimizer.md +203 -139
  20. package/.agent/agents/performance-reviewer.md +211 -108
  21. package/.agent/agents/product-manager.md +162 -108
  22. package/.agent/agents/project-planner.md +162 -142
  23. package/.agent/agents/qa-automation-engineer.md +242 -138
  24. package/.agent/agents/security-auditor.md +194 -170
  25. package/.agent/agents/seo-specialist.md +213 -132
  26. package/.agent/agents/sql-reviewer.md +194 -73
  27. package/.agent/agents/supervisor-agent.md +203 -156
  28. package/.agent/agents/test-coverage-reviewer.md +193 -81
  29. package/.agent/agents/type-safety-reviewer.md +208 -65
  30. package/.agent/scripts/__pycache__/auto_preview.cpython-311.pyc +0 -0
  31. package/.agent/scripts/__pycache__/bundle_analyzer.cpython-311.pyc +0 -0
  32. package/.agent/scripts/__pycache__/checklist.cpython-311.pyc +0 -0
  33. package/.agent/scripts/__pycache__/dependency_analyzer.cpython-311.pyc +0 -0
  34. package/.agent/scripts/__pycache__/security_scan.cpython-311.pyc +0 -0
  35. package/.agent/scripts/__pycache__/session_manager.cpython-311.pyc +0 -0
  36. package/.agent/scripts/__pycache__/skill_integrator.cpython-311.pyc +0 -0
  37. package/.agent/scripts/__pycache__/swarm_dispatcher.cpython-311.pyc +0 -0
  38. package/.agent/scripts/__pycache__/test_runner.cpython-311.pyc +0 -0
  39. package/.agent/scripts/__pycache__/verify_all.cpython-311.pyc +0 -0
  40. package/.agent/skills/agent-organizer/SKILL.md +126 -132
  41. package/.agent/skills/ai-prompt-injection-defense/SKILL.md +155 -66
  42. package/.agent/skills/api-patterns/SKILL.md +289 -257
  43. package/.agent/skills/api-security-auditor/SKILL.md +172 -70
  44. package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +1 -1
  45. package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +1 -1
  46. package/.agent/skills/appflow-wireframe/SKILL.md +107 -100
  47. package/.agent/skills/architecture/SKILL.md +331 -200
  48. package/.agent/skills/authentication-best-practices/SKILL.md +168 -67
  49. package/.agent/skills/bash-linux/SKILL.md +154 -215
  50. package/.agent/skills/brainstorming/SKILL.md +104 -210
  51. package/.agent/skills/building-native-ui/SKILL.md +169 -70
  52. package/.agent/skills/clean-code/SKILL.md +360 -206
  53. package/.agent/skills/config-validator/SKILL.md +141 -165
  54. package/.agent/skills/csharp-developer/SKILL.md +528 -107
  55. package/.agent/skills/database-design/SKILL.md +455 -275
  56. package/.agent/skills/deployment-procedures/SKILL.md +145 -188
  57. package/.agent/skills/devops-engineer/SKILL.md +332 -134
  58. package/.agent/skills/devops-incident-responder/SKILL.md +113 -98
  59. package/.agent/skills/edge-computing/SKILL.md +157 -213
  60. package/.agent/skills/extract-design-system/SKILL.md +129 -69
  61. package/.agent/skills/framer-motion-expert/SKILL.md +939 -0
  62. package/.agent/skills/game-design-expert/SKILL.md +105 -0
  63. package/.agent/skills/game-engineering-expert/SKILL.md +122 -0
  64. package/.agent/skills/geo-fundamentals/SKILL.md +124 -215
  65. package/.agent/skills/github-operations/SKILL.md +314 -354
  66. package/.agent/skills/gsap-expert/SKILL.md +901 -0
  67. package/.agent/skills/i18n-localization/SKILL.md +138 -216
  68. package/.agent/skills/intelligent-routing/SKILL.md +127 -139
  69. package/.agent/skills/llm-engineering/SKILL.md +357 -258
  70. package/.agent/skills/local-first/SKILL.md +154 -203
  71. package/.agent/skills/mcp-builder/SKILL.md +118 -224
  72. package/.agent/skills/nextjs-react-expert/SKILL.md +783 -203
  73. package/.agent/skills/nodejs-best-practices/SKILL.md +559 -280
  74. package/.agent/skills/observability/SKILL.md +330 -285
  75. package/.agent/skills/parallel-agents/SKILL.md +122 -181
  76. package/.agent/skills/performance-profiling/SKILL.md +254 -197
  77. package/.agent/skills/plan-writing/SKILL.md +118 -188
  78. package/.agent/skills/platform-engineer/SKILL.md +123 -135
  79. package/.agent/skills/playwright-best-practices/SKILL.md +157 -76
  80. package/.agent/skills/powershell-windows/SKILL.md +146 -230
  81. package/.agent/skills/python-pro/SKILL.md +879 -114
  82. package/.agent/skills/react-specialist/SKILL.md +931 -108
  83. package/.agent/skills/realtime-patterns/SKILL.md +304 -296
  84. package/.agent/skills/rust-pro/SKILL.md +701 -240
  85. package/.agent/skills/seo-fundamentals/SKILL.md +154 -181
  86. package/.agent/skills/server-management/SKILL.md +190 -212
  87. package/.agent/skills/shadcn-ui-expert/SKILL.md +201 -68
  88. package/.agent/skills/sql-pro/SKILL.md +633 -104
  89. package/.agent/skills/swiftui-expert/SKILL.md +171 -70
  90. package/.agent/skills/systematic-debugging/SKILL.md +118 -186
  91. package/.agent/skills/tailwind-patterns/SKILL.md +576 -232
  92. package/.agent/skills/tdd-workflow/SKILL.md +137 -209
  93. package/.agent/skills/testing-patterns/SKILL.md +573 -205
  94. package/.agent/skills/vue-expert/SKILL.md +964 -119
  95. package/.agent/skills/vulnerability-scanner/SKILL.md +269 -316
  96. package/.agent/skills/web-accessibility-auditor/SKILL.md +188 -71
  97. package/.agent/skills/webapp-testing/SKILL.md +145 -236
  98. package/.agent/workflows/api-tester.md +151 -279
  99. package/.agent/workflows/audit.md +138 -168
  100. package/.agent/workflows/brainstorm.md +110 -146
  101. package/.agent/workflows/changelog.md +112 -144
  102. package/.agent/workflows/create.md +124 -139
  103. package/.agent/workflows/debug.md +189 -196
  104. package/.agent/workflows/deploy.md +189 -153
  105. package/.agent/workflows/enhance.md +151 -139
  106. package/.agent/workflows/fix.md +135 -143
  107. package/.agent/workflows/generate.md +157 -164
  108. package/.agent/workflows/migrate.md +160 -163
  109. package/.agent/workflows/orchestrate.md +168 -151
  110. package/.agent/workflows/performance-benchmarker.md +123 -305
  111. package/.agent/workflows/plan.md +173 -151
  112. package/.agent/workflows/preview.md +80 -137
  113. package/.agent/workflows/refactor.md +183 -153
  114. package/.agent/workflows/review-ai.md +129 -140
  115. package/.agent/workflows/review.md +116 -155
  116. package/.agent/workflows/session.md +94 -154
  117. package/.agent/workflows/status.md +79 -125
  118. package/.agent/workflows/strengthen-skills.md +139 -99
  119. package/.agent/workflows/swarm.md +179 -194
  120. package/.agent/workflows/test.md +211 -166
  121. package/.agent/workflows/tribunal-backend.md +113 -111
  122. package/.agent/workflows/tribunal-database.md +115 -132
  123. package/.agent/workflows/tribunal-frontend.md +118 -115
  124. package/.agent/workflows/tribunal-full.md +133 -136
  125. package/.agent/workflows/tribunal-mobile.md +119 -123
  126. package/.agent/workflows/tribunal-performance.md +133 -152
  127. package/.agent/workflows/ui-ux-pro-max.md +143 -171
  128. package/README.md +11 -15
  129. package/package.json +1 -1
  130. package/.agent/skills/dotnet-core-expert/SKILL.md +0 -103
  131. package/.agent/skills/framer-motion-animations/SKILL.md +0 -74
  132. package/.agent/skills/game-development/2d-games/SKILL.md +0 -119
  133. package/.agent/skills/game-development/3d-games/SKILL.md +0 -135
  134. package/.agent/skills/game-development/SKILL.md +0 -236
  135. package/.agent/skills/game-development/game-art/SKILL.md +0 -185
  136. package/.agent/skills/game-development/game-audio/SKILL.md +0 -190
  137. package/.agent/skills/game-development/game-design/SKILL.md +0 -129
  138. package/.agent/skills/game-development/mobile-games/SKILL.md +0 -108
  139. package/.agent/skills/game-development/multiplayer/SKILL.md +0 -132
  140. package/.agent/skills/game-development/pc-games/SKILL.md +0 -144
  141. package/.agent/skills/game-development/vr-ar/SKILL.md +0 -123
  142. package/.agent/skills/game-development/web-games/SKILL.md +0 -150
@@ -1,280 +1,559 @@
1
- ---
2
- name: nodejs-best-practices
3
- description: Node.js development principles and decision-making. Framework selection, async patterns, security, and architecture. Teaches thinking, not copying.
4
- allowed-tools: Read, Write, Edit, Glob, Grep
5
- version: 1.0.0
6
- last-updated: 2026-03-12
7
- applies-to-model: gemini-2.5-pro, claude-3-7-sonnet
8
- ---
9
-
10
- # Node.js Development Principles
11
-
12
- > Node.js is not a problem unpredictable async behavior is.
13
- > Understand the event loop and half of Node.js "gotchas" disappear.
14
-
15
- ---
16
-
17
- ## Framework Selection
18
-
19
- | Context | Recommended | Why |
20
- |---|---|---|
21
- | REST API, standard patterns | Express + TypeScript | Mature, flexible, most hiring knowledge |
22
- | REST API, speed + TypeScript-first | Fastify | 2x Express throughput, built-in validation |
23
- | Full-stack React | Next.js API routes | Colocated API and UI, serverless-friendly |
24
- | REST + tRPC | Next.js + tRPC | Type-safe end-to-end with no code generation |
25
- | RPC across services | gRPC | Binary protocol, contract-first |
26
- | Edge function / Cloudflare Worker | Hono | Tiny, Web Platform API-native, zero cold start |
27
- | Scripts / tooling / bun-native | Bun | Built-in bundler, test runner, near-Node compat |
28
-
29
- **Questions to ask before choosing:**
30
-
31
- - Is this public-facing or internal?
32
- - Do we control the deployment environment (server vs. serverless vs. edge)?
33
- - Is the team already familiar with a framework?
34
- - Does this need to compose with an existing TypeScript frontend?
35
-
36
- ---
37
-
38
- ## Modern Runtime Landscape (2025+)
39
-
40
- The Node.js monopoly is ending. Understand constraints before picking a runtime:
41
-
42
- | Runtime | `fs` | `crypto` | `child_process` | `process.env` | Deploy Target |
43
- |---|---|---|---|---|---|
44
- | **Node.js** | | ✅ | ✅ | ✅ | Server, serverless |
45
- | **Bun** | ✅ | ✅ | ✅ | ✅ | Server (Node-compatible) |
46
- | **Deno** | ✅ (explicit perm) | ✅ | ✅ (explicit perm) | ✅ | Server, Deno Deploy |
47
- | **Edge (Cloudflare Workers)** | ❌ | Web only | ❌ | via `env` binding | Edge (global) |
48
-
49
- ```ts
50
- // ❌ Portability anti-pattern — works in Node, breaks at edge
51
- import { createHash } from 'crypto'; // Node crypto — not available at edge
52
- import fs from 'fs'; // No filesystem at edge
53
-
54
- // ✅ Web Platform APIs — work everywhere (Node ≥18, Bun, Deno, Edge)
55
- const hash = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(input));
56
- const response = await fetch('https://api.example.com/data');
57
- ```
58
-
59
- ### When to Consider Bun
60
-
61
- ```ts
62
- // Bun is Node-compatible but: starts faster, ships a bundler + test runner built-in
63
- // Use Bun when: scripts, tooling, new greenfield backends, or test-heavy projects
64
-
65
- // package.json — identical, works in both
66
- // bun install → 10x faster than npm install
67
- // bun test → built-in Vitest-compatible runner
68
- // bun run → direct TypeScript execution, no transpile step
69
-
70
- // Gotcha: some native Node addons (e.g. bcrypt, canvas) need Bun alternatives
71
- // Use: @node-rs/bcrypt instead of bcrypt (N-API native, works in both)
72
- ```
73
-
74
- ---
75
-
76
- ## Async Patterns
77
-
78
- ### Always: Handle rejection
79
-
80
- Every Promise needs a rejection handler. Unhandled rejections crash Node.js processes in modern versions.
81
-
82
- ```ts
83
- // ❌ Unhandled rejection
84
- fetchData().then(process);
85
-
86
- // ✅ Handled
87
- fetchData().then(process).catch(handleError);
88
-
89
- // ✅ Or with async/await
90
- try {
91
- const data = await fetchData();
92
- process(data);
93
- } catch (err) {
94
- handleError(err);
95
- }
96
- ```
97
-
98
- ### Avoid: Blocking the event loop
99
-
100
- The event loop is single-threaded. Anything synchronous that takes more than a few ms blocks all other requests.
101
-
102
- ```ts
103
- // ❌ Blocks event loop for large files
104
- const data = fs.readFileSync('huge.csv');
105
-
106
- // Non-blocking
107
- const data = await fs.promises.readFile('huge.csv');
108
-
109
- // CPU-intensive work on main thread
110
- const result = computeHuge(dataset);
111
-
112
- // ✅ Offload to worker thread
113
- const { Worker } = require('worker_threads');
114
- ```
115
-
116
- ### Concurrency vs. Parallelism
117
-
118
- ```ts
119
- // Sequential — each awaits the previous (use when order matters or requests are dependent)
120
- for (const id of ids) {
121
- await processItem(id);
122
- }
123
-
124
- // Concurrent all start immediately, await all completions (use for independent operations)
125
- await Promise.all(ids.map(id => processItem(id)));
126
-
127
- // Concurrent with limit — avoid overwhelming downstream services
128
- import pLimit from 'p-limit';
129
- const limit = pLimit(5); // max 5 concurrent
130
- await Promise.all(ids.map(id => limit(() => processItem(id))));
131
- ```
132
-
133
- ---
134
-
135
- ## Error Handling Architecture
136
-
137
- Structure errors so they carry meaning, not just messages:
138
-
139
- ```ts
140
- // Base application error
141
- class AppError extends Error {
142
- constructor(
143
- message: string,
144
- public code: string,
145
- public statusCode: number,
146
- public isOperational = true
147
- ) {
148
- super(message);
149
- this.name = this.constructor.name;
150
- }
151
- }
152
-
153
- // Domain-specific errors
154
- class NotFoundError extends AppError {
155
- constructor(resource: string, id: string) {
156
- super(`${resource} ${id} not found`, 'NOT_FOUND', 404);
157
- }
158
- }
159
-
160
- class ValidationError extends AppError {
161
- constructor(message: string) {
162
- super(message, 'VALIDATION_FAILED', 400);
163
- }
164
- }
165
- ```
166
-
167
- **Global error handler:**
168
- ```ts
169
- app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
170
- if (err instanceof AppError && err.isOperational) {
171
- return res.status(err.statusCode).json({
172
- error: err.message,
173
- code: err.code,
174
- });
175
- }
176
- // Non-operational errors — log fully, don't expose details
177
- logger.error('Unexpected error', { err, url: req.url });
178
- res.status(500).json({ error: 'Internal server error' });
179
- });
180
- ```
181
-
182
- ---
183
-
184
- ## Security Baseline
185
-
186
- ```ts
187
- import helmet from 'helmet';
188
- import rateLimit from 'express-rate-limit';
189
-
190
- // Security headers
191
- app.use(helmet());
192
-
193
- // Rate limiting protect all routes
194
- app.use(rateLimit({
195
- windowMs: 15 * 60 * 1000, // 15 minutes
196
- max: 100, // requests per window
197
- standardHeaders: true,
198
- legacyHeaders: false,
199
- }));
200
-
201
- // Body size limit — prevent payload bombs
202
- app.use(express.json({ limit: '10kb' }));
203
-
204
- // Trust proxy correctly for rate limiting behind load balancer
205
- app.set('trust proxy', 1);
206
- ```
207
-
208
- **Never:**
209
- - Use `eval()` or `new Function()` with user input
210
- - Pass unvalidated user input to `exec()`, `spawn()`, or `child_process`
211
- - Log full request bodies (may contain credentials or PII)
212
-
213
- ---
214
-
215
- ## Project Structure
216
-
217
- ```
218
- src/
219
- routes/ HTTP route definitions (thin only parse and delegate)
220
- controllers/ Request handling, validation, response formatting
221
- services/ Business logic (no HTTP awareness)
222
- repositories/ Database access (no business logic)
223
- middleware/ Auth, rate limit, logging
224
- lib/ Shared utilities (date, crypto, validation)
225
- types/ TypeScript interfaces and type exports
226
- config/ Environment config with validation
227
- ```
228
-
229
- **Dependency direction:** routes → controllers → services → repositories
230
- **Never:** repositories calling services, or services knowing about HTTP
231
-
232
- ---
233
-
234
- ## Output Format
235
-
236
- When this skill produces or reviews code, structure your output as follows:
237
-
238
- ```
239
- ━━━ Nodejs Best Practices Report ━━━━━━━━━━━━━━━━━━━━━━━━
240
- Skill: Nodejs Best Practices
241
- Language: [detected language / framework]
242
- Scope: [N files · N functions]
243
- ─────────────────────────────────────────────────
244
- Passed: [checks that passed, or "All clean"]
245
- ⚠️ Warnings: [non-blocking issues, or "None"]
246
- Blocked: [blocking issues requiring fix, or "None"]
247
- ─────────────────────────────────────────────────
248
- VBC status: PENDING → VERIFIED
249
- Evidence: [test output / lint pass / compile success]
250
- ```
251
-
252
- **VBC (Verification-Before-Completion) is mandatory.**
253
- Do not mark status as VERIFIED until concrete terminal evidence is provided.
254
-
255
-
256
- ---
257
-
258
- ## 🏛️ Tribunal Integration (Anti-Hallucination)
259
-
260
- **Slash command: `/tribunal-backend`**
261
- **Active reviewers: `logic` · `security` · `dependency` · `type-safety`**
262
-
263
- ### ❌ Forbidden AI Tropes in Node.js
264
-
265
- 1. **Blindly mixing `require` and `import`** — pick ESM or CommonJS and stick to it strictly based on `package.json`.
266
- 2. **"Catch-all and ignore" error handling** — e.g., `catch (e) { console.log(e); }` without throwing or returning an error response.
267
- 3. **Assuming Express** if the project is Next.js, Fastify, or NestJS, do not hallucinate Express code.
268
- 4. **Unparameterized queries** — never interpolate strings into SQL.
269
- 5. **No `any` types** unless an external library leaves no choice, type all request bodies and responses.
270
-
271
- ### Pre-Flight Self-Audit
272
-
273
- Review these questions before generating Node.js code:
274
- ```
275
- Did I use the correct module system (CJS vs ESM) for this context?
276
- ✅ Is every Promise rejection properly handled?
277
- Did I block the event loop with synchronous FS or Crypto operations?
278
- Are all inputs validated before business logic runs?
279
- Is this code safe from memory leaks (e.g., unbounded arrays/maps)?
280
- ```
1
+ ---
2
+ name: nodejs-best-practices
3
+ description: Node.js 22+ production mastery. ES Modules, async patterns, Express/Fastify/Hono, middleware architecture, error handling, streaming, worker threads, environment config, security hardening, process management, and deployment patterns. Use when building Node.js servers, APIs, CLI tools, or any server-side JavaScript.
4
+ allowed-tools: Read, Write, Edit, Glob, Grep
5
+ version: 2.0.0
6
+ last-updated: 2026-04-01
7
+ applies-to-model: gemini-2.5-pro, claude-3-7-sonnet
8
+ ---
9
+
10
+ # Node.js Best Practices — Node 22+ Production Mastery
11
+
12
+ > Node.js is not "JavaScript on the server." It is an event-driven, non-blocking I/O runtime.
13
+ > Every callback without error handling is a memory leak waiting to happen.
14
+ > Every unhandled promise rejection is a crashed process in production.
15
+
16
+ ---
17
+
18
+ ## ES Modules (Mandatory)
19
+
20
+ ```json
21
+ // package.json ALWAYS set type to module
22
+ {
23
+ "type": "module",
24
+ "engines": { "node": ">=22" }
25
+ }
26
+ ```
27
+
28
+ ```typescript
29
+ // ESM imports (modern Node.js)
30
+ import { readFile, writeFile } from "node:fs/promises";
31
+ import { join, resolve } from "node:path";
32
+ import { createServer } from "node:http";
33
+ import { EventEmitter } from "node:events";
34
+
35
+ // ❌ HALLUCINATION TRAP: Use node: protocol prefix for built-in modules
36
+ // ❌ import fs from "fs"; ← ambiguous (could be npm package)
37
+ // ✅ import fs from "node:fs"; ← explicitly a Node.js built-in
38
+
39
+ // ❌ HALLUCINATION TRAP: Do NOT use require() in ESM projects
40
+ // const fs = require("fs"); ← CommonJS (legacy)
41
+ // ✅ import fs from "node:fs/promises"; ← ESM
42
+
43
+ // Dynamic imports (for conditional loading)
44
+ const module = await import("./heavy-module.js");
45
+ ```
46
+
47
+ ---
48
+
49
+ ## Framework Selection
50
+
51
+ ```
52
+ ┌────────────────────────────────────────────────────────────┐
53
+ │ When to Use What │
54
+ ├────────────────────────────────────────────────────────────┤
55
+ Express │ Legacy projects, extensive middleware ecosystem│
56
+ Fastify │ Performance-critical APIs, schema validation │
57
+ │ Hono │ Edge/serverless, multi-runtime (Node/Deno/Bun)│
58
+ │ tRPC │ Full-stack TypeScript (Next.js + React Query) │
59
+ Raw http │ Learning, minimal proxies, health checks │
60
+ └────────────────────────────────────────────────────────────┘
61
+ ```
62
+
63
+ ### Fastify (Recommended)
64
+
65
+ ```typescript
66
+ import Fastify from "fastify";
67
+ import { z } from "zod";
68
+
69
+ const app = Fastify({
70
+ logger: {
71
+ level: process.env.LOG_LEVEL ?? "info",
72
+ transport: process.env.NODE_ENV === "development"
73
+ ? { target: "pino-pretty" }
74
+ : undefined,
75
+ },
76
+ });
77
+
78
+ // Schema validation with Zod → Fastify schema
79
+ const CreateUserSchema = z.object({
80
+ name: z.string().min(2).max(100),
81
+ email: z.string().email(),
82
+ role: z.enum(["admin", "user"]).default("user"),
83
+ });
84
+
85
+ type CreateUserBody = z.infer<typeof CreateUserSchema>;
86
+
87
+ app.post<{ Body: CreateUserBody }>("/users", {
88
+ schema: {
89
+ body: {
90
+ type: "object",
91
+ required: ["name", "email"],
92
+ properties: {
93
+ name: { type: "string", minLength: 2 },
94
+ email: { type: "string", format: "email" },
95
+ role: { type: "string", enum: ["admin", "user"] },
96
+ },
97
+ },
98
+ },
99
+ }, async (request, reply) => {
100
+ const validated = CreateUserSchema.parse(request.body);
101
+ const user = await createUser(validated);
102
+ return reply.status(201).send(user);
103
+ });
104
+
105
+ // Graceful shutdown
106
+ const start = async () => {
107
+ try {
108
+ await app.listen({ port: 3000, host: "0.0.0.0" });
109
+ } catch (err) {
110
+ app.log.error(err);
111
+ process.exit(1);
112
+ }
113
+ };
114
+
115
+ start();
116
+ ```
117
+
118
+ ### Hono (Edge-First)
119
+
120
+ ```typescript
121
+ import { Hono } from "hono";
122
+ import { cors } from "hono/cors";
123
+ import { logger } from "hono/logger";
124
+ import { zValidator } from "@hono/zod-validator";
125
+ import { z } from "zod";
126
+
127
+ const app = new Hono();
128
+
129
+ app.use("*", logger());
130
+ app.use("*", cors({ origin: "https://myapp.com" }));
131
+
132
+ const createUserSchema = z.object({
133
+ name: z.string().min(2),
134
+ email: z.string().email(),
135
+ });
136
+
137
+ app.post("/users", zValidator("json", createUserSchema), async (c) => {
138
+ const body = c.req.valid("json");
139
+ const user = await createUser(body);
140
+ return c.json(user, 201);
141
+ });
142
+
143
+ app.get("/health", (c) => c.json({ status: "ok" }));
144
+
145
+ export default app; // works in Node, Deno, Bun, Cloudflare Workers
146
+ ```
147
+
148
+ ---
149
+
150
+ ## Error Handling
151
+
152
+ ### Global Error Handlers
153
+
154
+ ```typescript
155
+ // MANDATORY: Handle unhandled rejections and exceptions
156
+ process.on("unhandledRejection", (reason, promise) => {
157
+ console.error("Unhandled Rejection at:", promise, "reason:", reason);
158
+ // Log to error tracking service (Sentry, etc.)
159
+ // Gracefully shutdown
160
+ process.exit(1);
161
+ });
162
+
163
+ process.on("uncaughtException", (error) => {
164
+ console.error("Uncaught Exception:", error);
165
+ // Log to error tracking service
166
+ process.exit(1); // MUST exit — state is corrupted
167
+ });
168
+
169
+ // HALLUCINATION TRAP: After uncaughtException, the process MUST exit
170
+ // The process is in an undefined state — continuing is dangerous
171
+ // ❌ process.on("uncaughtException", (err) => { console.log(err); }); // continues running
172
+ // ✅ process.on("uncaughtException", (err) => { log(err); process.exit(1); });
173
+ ```
174
+
175
+ ### Application Error Classes
176
+
177
+ ```typescript
178
+ export class AppError extends Error {
179
+ constructor(
180
+ message: string,
181
+ public statusCode: number = 500,
182
+ public code: string = "INTERNAL_ERROR",
183
+ public isOperational: boolean = true,
184
+ ) {
185
+ super(message);
186
+ this.name = "AppError";
187
+ Error.captureStackTrace(this, this.constructor);
188
+ }
189
+ }
190
+
191
+ export class NotFoundError extends AppError {
192
+ constructor(resource: string, id: string) {
193
+ super(`${resource} '${id}' not found`, 404, "NOT_FOUND");
194
+ }
195
+ }
196
+
197
+ export class ValidationError extends AppError {
198
+ constructor(message: string, public errors: Record<string, string[]> = {}) {
199
+ super(message, 400, "VALIDATION_ERROR");
200
+ }
201
+ }
202
+
203
+ export class UnauthorizedError extends AppError {
204
+ constructor(message = "Authentication required") {
205
+ super(message, 401, "UNAUTHORIZED");
206
+ }
207
+ }
208
+
209
+ // Express error middleware
210
+ app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
211
+ if (err instanceof AppError && err.isOperational) {
212
+ res.status(err.statusCode).json({
213
+ error: { code: err.code, message: err.message },
214
+ });
215
+ } else {
216
+ // Programmer error — log and return generic message
217
+ console.error("Unexpected error:", err);
218
+ res.status(500).json({
219
+ error: { code: "INTERNAL_ERROR", message: "Something went wrong" },
220
+ });
221
+ }
222
+ });
223
+ ```
224
+
225
+ ---
226
+
227
+ ## Async Patterns
228
+
229
+ ### Parallel vs Sequential
230
+
231
+ ```typescript
232
+ // ❌ SEQUENTIAL: Each await blocks the next
233
+ const users = await getUsers(); // 200ms
234
+ const posts = await getPosts(); // 200ms
235
+ const stats = await getStats(); // 200ms
236
+ // Total: 600ms
237
+
238
+ // ✅ PARALLEL: All start simultaneously
239
+ const [users, posts, stats] = await Promise.all([
240
+ getUsers(), // 200ms
241
+ getPosts(), // 200ms (concurrent)
242
+ getStats(), // 200ms (concurrent)
243
+ ]);
244
+ // Total: ~200ms
245
+
246
+ // Promise.allSettled when some can fail
247
+ const results = await Promise.allSettled([
248
+ fetchCriticalData(),
249
+ fetchOptionalData(),
250
+ fetchAnalytics(),
251
+ ]);
252
+
253
+ for (const result of results) {
254
+ if (result.status === "fulfilled") {
255
+ process(result.value);
256
+ } else {
257
+ console.error("Failed:", result.reason);
258
+ }
259
+ }
260
+ ```
261
+
262
+ ### Retry Pattern
263
+
264
+ ```typescript
265
+ async function withRetry<T>(
266
+ fn: () => Promise<T>,
267
+ options: { maxRetries?: number; baseDelay?: number; maxDelay?: number } = {},
268
+ ): Promise<T> {
269
+ const { maxRetries = 3, baseDelay = 1000, maxDelay = 10000 } = options;
270
+
271
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
272
+ try {
273
+ return await fn();
274
+ } catch (error) {
275
+ if (attempt === maxRetries) throw error;
276
+
277
+ const delay = Math.min(baseDelay * 2 ** attempt, maxDelay);
278
+ const jitter = delay * (0.5 + Math.random() * 0.5);
279
+ console.warn(`Attempt ${attempt + 1} failed, retrying in ${jitter}ms`);
280
+ await new Promise((resolve) => setTimeout(resolve, jitter));
281
+ }
282
+ }
283
+ throw new Error("Unreachable");
284
+ }
285
+
286
+ // Usage:
287
+ const data = await withRetry(() => fetch("https://api.flaky.com/data"), {
288
+ maxRetries: 3,
289
+ baseDelay: 500,
290
+ });
291
+ ```
292
+
293
+ ### AbortController (Timeouts & Cancellation)
294
+
295
+ ```typescript
296
+ async function fetchWithTimeout(url: string, timeoutMs = 5000): Promise<Response> {
297
+ const controller = new AbortController();
298
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
299
+
300
+ try {
301
+ const response = await fetch(url, { signal: controller.signal });
302
+ return response;
303
+ } catch (error) {
304
+ if (error instanceof DOMException && error.name === "AbortError") {
305
+ throw new Error(`Request to ${url} timed out after ${timeoutMs}ms`);
306
+ }
307
+ throw error;
308
+ } finally {
309
+ clearTimeout(timeoutId);
310
+ }
311
+ }
312
+ ```
313
+
314
+ ---
315
+
316
+ ## Streaming
317
+
318
+ ```typescript
319
+ import { Readable, Transform, pipeline } from "node:stream/promises";
320
+ import { createReadStream, createWriteStream } from "node:fs";
321
+ import { createGzip } from "node:zlib";
322
+
323
+ // Stream large file processing (no memory issues)
324
+ async function processLargeCSV(inputPath: string, outputPath: string) {
325
+ const transform = new Transform({
326
+ transform(chunk, encoding, callback) {
327
+ const processed = chunk.toString().toUpperCase();
328
+ callback(null, processed);
329
+ },
330
+ });
331
+
332
+ await pipeline(
333
+ createReadStream(inputPath),
334
+ transform,
335
+ createGzip(),
336
+ createWriteStream(outputPath),
337
+ );
338
+ }
339
+
340
+ // Streaming HTTP response
341
+ app.get("/export", async (req, res) => {
342
+ res.setHeader("Content-Type", "text/csv");
343
+ res.setHeader("Content-Disposition", "attachment; filename=export.csv");
344
+
345
+ const cursor = db.collection("users").find().stream();
346
+ cursor.on("data", (user) => {
347
+ res.write(`${user.id},${user.name},${user.email}\n`);
348
+ });
349
+ cursor.on("end", () => res.end());
350
+ cursor.on("error", (err) => {
351
+ console.error(err);
352
+ res.status(500).end();
353
+ });
354
+ });
355
+
356
+ // ❌ HALLUCINATION TRAP: Use stream/promises (not callbacks)
357
+ // ❌ const { pipeline } = require("stream"); ← callback-based
358
+ // ✅ import { pipeline } from "node:stream/promises"; ← async/await
359
+ ```
360
+
361
+ ---
362
+
363
+ ## Environment & Config
364
+
365
+ ```typescript
366
+ // config.ts — centralized, validated configuration
367
+ import { z } from "zod";
368
+
369
+ const envSchema = z.object({
370
+ NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
371
+ PORT: z.coerce.number().default(3000),
372
+ DATABASE_URL: z.string().url(),
373
+ REDIS_URL: z.string().url().optional(),
374
+ JWT_SECRET: z.string().min(32),
375
+ CORS_ORIGIN: z.string().default("http://localhost:5173"),
376
+ LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("info"),
377
+ });
378
+
379
+ export const config = envSchema.parse(process.env);
380
+
381
+ // ❌ HALLUCINATION TRAP: Validate env vars at startup — fail FAST
382
+ // ❌ process.env.DATABASE_URL! ← crashes at runtime, not startup
383
+ // ✅ Validate with Zod on app init — crash immediately with clear error
384
+
385
+ // ❌ HALLUCINATION TRAP: Never hardcode secrets
386
+ // ❌ const JWT_SECRET = "my-secret-key"; ← in source code
387
+ // ✅ const JWT_SECRET = process.env.JWT_SECRET; ← from environment
388
+ ```
389
+
390
+ ---
391
+
392
+ ## Security Hardening
393
+
394
+ ```typescript
395
+ import helmet from "helmet";
396
+ import rateLimit from "express-rate-limit";
397
+
398
+ // Security headers
399
+ app.use(helmet());
400
+
401
+ // Rate limiting
402
+ app.use("/api/", rateLimit({
403
+ windowMs: 15 * 60 * 1000, // 15 minutes
404
+ max: 100, // 100 requests per window
405
+ standardHeaders: true,
406
+ legacyHeaders: false,
407
+ message: { error: "Too many requests, try again later" },
408
+ }));
409
+
410
+ // Auth rate limiting (stricter)
411
+ app.use("/api/auth/", rateLimit({
412
+ windowMs: 15 * 60 * 1000,
413
+ max: 5, // only 5 login attempts per 15 min
414
+ }));
415
+
416
+ // Input validation (ALWAYS validate)
417
+ app.post("/api/users", async (req, res, next) => {
418
+ try {
419
+ const data = CreateUserSchema.parse(req.body); // Zod validates
420
+ const user = await createUser(data);
421
+ res.status(201).json(user);
422
+ } catch (error) {
423
+ next(error);
424
+ }
425
+ });
426
+
427
+ // SQL injection prevention (covered by parameterized queries)
428
+ // ❌ db.query(`SELECT * FROM users WHERE id = ${req.params.id}`);
429
+ // ✅ db.query("SELECT * FROM users WHERE id = $1", [req.params.id]);
430
+
431
+ // Path traversal prevention
432
+ import { resolve, normalize } from "node:path";
433
+
434
+ function safePath(userInput: string, baseDir: string): string {
435
+ const resolved = resolve(baseDir, normalize(userInput));
436
+ if (!resolved.startsWith(baseDir)) {
437
+ throw new Error("Path traversal detected");
438
+ }
439
+ return resolved;
440
+ }
441
+ ```
442
+
443
+ ---
444
+
445
+ ## Process Management
446
+
447
+ ### Graceful Shutdown
448
+
449
+ ```typescript
450
+ async function gracefulShutdown(signal: string) {
451
+ console.log(`\n${signal} received — shutting down gracefully`);
452
+
453
+ // Stop accepting new connections
454
+ server.close();
455
+
456
+ // Close database connections
457
+ await db.end();
458
+
459
+ // Close Redis
460
+ await redis.quit();
461
+
462
+ // Allow in-flight requests 10s to complete
463
+ setTimeout(() => {
464
+ console.error("Forceful shutdown after timeout");
465
+ process.exit(1);
466
+ }, 10000);
467
+
468
+ process.exit(0);
469
+ }
470
+
471
+ process.on("SIGTERM", () => gracefulShutdown("SIGTERM"));
472
+ process.on("SIGINT", () => gracefulShutdown("SIGINT"));
473
+ ```
474
+
475
+ ### Worker Threads (CPU-Bound)
476
+
477
+ ```typescript
478
+ import { Worker, isMainThread, parentPort, workerData } from "node:worker_threads";
479
+
480
+ if (isMainThread) {
481
+ // Main thread — offload CPU work
482
+ function runWorker(data: unknown): Promise<unknown> {
483
+ return new Promise((resolve, reject) => {
484
+ const worker = new Worker(new URL(import.meta.url), { workerData: data });
485
+ worker.on("message", resolve);
486
+ worker.on("error", reject);
487
+ });
488
+ }
489
+
490
+ const result = await runWorker({ input: largeDataSet });
491
+ } else {
492
+ // Worker thread — CPU-intensive work
493
+ const result = heavyComputation(workerData.input);
494
+ parentPort?.postMessage(result);
495
+ }
496
+
497
+ // ❌ HALLUCINATION TRAP: Worker threads are for CPU-bound tasks
498
+ // For I/O-bound tasks (network, file), use async/await — NOT workers
499
+ // Workers have overhead (serialization, memory) — don't overuse
500
+ ```
501
+
502
+ ---
503
+
504
+ ## Output Format
505
+
506
+ ```
507
+ ━━━ Node.js Report ━━━━━━━━━━━━━━━━━━━━━━━━
508
+ Skill: Node.js Best Practices
509
+ Node Ver: 22+
510
+ Scope: [N files · N endpoints]
511
+ ─────────────────────────────────────────────────
512
+ ✅ Passed: [checks that passed, or "All clean"]
513
+ ⚠️ Warnings: [non-blocking issues, or "None"]
514
+ ❌ Blocked: [blocking issues requiring fix, or "None"]
515
+ ─────────────────────────────────────────────────
516
+ VBC status: PENDING → VERIFIED
517
+ Evidence: [test output / server start / build success]
518
+ ```
519
+
520
+ ---
521
+
522
+ ## 🤖 LLM-Specific Traps
523
+
524
+ 1. **`require()` in ESM:** Never use `require()` in `"type": "module"` projects. Use `import`.
525
+ 2. **Missing `node:` Prefix:** Always use `node:fs`, `node:path`, `node:http`, etc. Bare imports are ambiguous.
526
+ 3. **Callback-Based APIs:** Use `node:fs/promises`, `node:stream/promises`. Callback APIs are legacy.
527
+ 4. **Continuing After `uncaughtException`:** Process MUST exit after uncaughtException. State is corrupted.
528
+ 5. **`process.env` Without Validation:** Environment variables are `string | undefined`. Always validate at startup with Zod.
529
+ 6. **Hardcoded Secrets:** JWT secrets, API keys, and DB URLs must come from environment, never source code.
530
+ 7. **`express()` Without `helmet()`:** Every Express app needs security headers. `helmet()` is non-negotiable.
531
+ 8. **SQL String Interpolation:** Never use template literals for SQL. Use parameterized queries.
532
+ 9. **Worker Threads for I/O:** Workers are for CPU-bound work. I/O-bound work uses async/await natively.
533
+ 10. **Missing Graceful Shutdown:** Servers MUST handle SIGTERM/SIGINT for clean container/PaaS shutdown.
534
+
535
+ ---
536
+
537
+ ## 🏛️ Tribunal Integration
538
+
539
+ **Slash command: `/tribunal-backend`**
540
+
541
+ ### ✅ Pre-Flight Self-Audit
542
+
543
+ ```
544
+ ✅ Did I use ESM imports with node: prefix?
545
+ ✅ Did I validate all environment variables at startup?
546
+ ✅ Are secrets in environment variables (not hardcoded)?
547
+ ✅ Did I handle unhandledRejection and uncaughtException?
548
+ ✅ Did I implement graceful shutdown (SIGTERM/SIGINT)?
549
+ ✅ Did I use parameterized queries (not string interpolation)?
550
+ ✅ Did I add rate limiting and security headers?
551
+ ✅ Did I validate all request input with Zod?
552
+ ✅ Are async errors properly caught and propagated?
553
+ ✅ Did I use streams for large data (not loading all into memory)?
554
+ ```
555
+
556
+ ### 🛑 VBC Protocol
557
+
558
+ - ❌ **Forbidden:** Assuming a server "works" because it starts without errors.
559
+ - ✅ **Required:** Provide test output, health check response, or build success evidence.