@girardmedia/bootspring 3.3.2 → 3.4.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 (171) hide show
  1. package/assets/agents/accessibility-auditor.md +39 -0
  2. package/assets/agents/api-designer.md +40 -0
  3. package/assets/agents/auth-implementer.md +64 -0
  4. package/assets/agents/bug-hunter.md +42 -0
  5. package/assets/agents/bundle-analyzer.md +40 -0
  6. package/assets/agents/cache-optimizer.md +55 -0
  7. package/assets/agents/changelog-writer.md +55 -0
  8. package/assets/agents/ci-cd-builder.md +40 -0
  9. package/assets/agents/code-explainer.md +39 -0
  10. package/assets/agents/code-reviewer.md +39 -0
  11. package/assets/agents/cost-optimizer.md +57 -0
  12. package/assets/agents/cron-scheduler.md +51 -0
  13. package/assets/agents/data-seeder.md +56 -0
  14. package/assets/agents/database-architect.md +40 -0
  15. package/assets/agents/dependency-updater.md +40 -0
  16. package/assets/agents/deploy-checker.md +40 -0
  17. package/assets/agents/docker-optimizer.md +40 -0
  18. package/assets/agents/documentation-writer.md +40 -0
  19. package/assets/agents/email-builder.md +55 -0
  20. package/assets/agents/env-setup.md +40 -0
  21. package/assets/agents/error-handler.md +40 -0
  22. package/assets/agents/eslint-fixer.md +46 -0
  23. package/assets/agents/feature-flagger.md +69 -0
  24. package/assets/agents/git-detective.md +39 -0
  25. package/assets/agents/graphql-builder.md +60 -0
  26. package/assets/agents/incident-responder.md +59 -0
  27. package/assets/agents/log-analyzer.md +39 -0
  28. package/assets/agents/migration-planner.md +41 -0
  29. package/assets/agents/monorepo-navigator.md +39 -0
  30. package/assets/agents/nextjs-expert.md +57 -0
  31. package/assets/agents/notification-builder.md +56 -0
  32. package/assets/agents/onboarding-guide.md +39 -0
  33. package/assets/agents/performance-profiler.md +40 -0
  34. package/assets/agents/prisma-expert.md +57 -0
  35. package/assets/agents/rate-limiter.md +58 -0
  36. package/assets/agents/react-expert.md +58 -0
  37. package/assets/agents/refactorer.md +42 -0
  38. package/assets/agents/regex-builder.md +46 -0
  39. package/assets/agents/release-manager.md +40 -0
  40. package/assets/agents/s3-manager.md +58 -0
  41. package/assets/agents/schema-validator.md +40 -0
  42. package/assets/agents/search-builder.md +62 -0
  43. package/assets/agents/security-auditor.md +39 -0
  44. package/assets/agents/sitemap-generator.md +53 -0
  45. package/assets/agents/stripe-integrator.md +59 -0
  46. package/assets/agents/tailwind-expert.md +55 -0
  47. package/assets/agents/tech-debt-tracker.md +39 -0
  48. package/assets/agents/test-writer.md +42 -0
  49. package/assets/agents/type-fixer.md +45 -0
  50. package/assets/agents/webhook-builder.md +54 -0
  51. package/assets/rules/cpp.md +53 -0
  52. package/assets/rules/css.md +52 -0
  53. package/assets/rules/go.md +50 -0
  54. package/assets/rules/html.md +52 -0
  55. package/assets/rules/java.md +51 -0
  56. package/assets/rules/kotlin.md +50 -0
  57. package/assets/rules/php.md +51 -0
  58. package/assets/rules/python.md +51 -0
  59. package/assets/rules/ruby.md +51 -0
  60. package/assets/rules/rust.md +49 -0
  61. package/assets/rules/shell.md +52 -0
  62. package/assets/rules/sql.md +49 -0
  63. package/assets/rules/swift.md +50 -0
  64. package/assets/rules/typescript.md +52 -0
  65. package/assets/rules/yaml-json.md +51 -0
  66. package/assets/skills/accessibility.md +210 -0
  67. package/assets/skills/agent-patterns.md +387 -0
  68. package/assets/skills/ai-integration.md +263 -0
  69. package/assets/skills/animation-patterns.md +224 -0
  70. package/assets/skills/api-design.md +218 -0
  71. package/assets/skills/api-gateway.md +341 -0
  72. package/assets/skills/api-versioning.md +226 -0
  73. package/assets/skills/astro-patterns.md +233 -0
  74. package/assets/skills/auth-patterns.md +248 -0
  75. package/assets/skills/aws-patterns.md +171 -0
  76. package/assets/skills/background-jobs.md +162 -0
  77. package/assets/skills/browser-extensions.md +309 -0
  78. package/assets/skills/caching-patterns.md +253 -0
  79. package/assets/skills/ci-cd.md +251 -0
  80. package/assets/skills/cli-development.md +296 -0
  81. package/assets/skills/code-review.md +185 -0
  82. package/assets/skills/cron-patterns.md +327 -0
  83. package/assets/skills/data-fetching.md +231 -0
  84. package/assets/skills/database-migrations.md +346 -0
  85. package/assets/skills/database-patterns.md +219 -0
  86. package/assets/skills/debugging.md +281 -0
  87. package/assets/skills/design-system.md +289 -0
  88. package/assets/skills/django-patterns.md +182 -0
  89. package/assets/skills/docker-patterns.md +235 -0
  90. package/assets/skills/e2e-testing.md +287 -0
  91. package/assets/skills/edge-computing.md +268 -0
  92. package/assets/skills/electron-patterns.md +266 -0
  93. package/assets/skills/email-templates.md +206 -0
  94. package/assets/skills/error-handling.md +265 -0
  95. package/assets/skills/event-driven.md +232 -0
  96. package/assets/skills/express-patterns.md +239 -0
  97. package/assets/skills/fastapi-patterns.md +198 -0
  98. package/assets/skills/feature-flags.md +212 -0
  99. package/assets/skills/figma-to-code.md +298 -0
  100. package/assets/skills/file-upload.md +228 -0
  101. package/assets/skills/forms-patterns.md +264 -0
  102. package/assets/skills/gcp-patterns.md +189 -0
  103. package/assets/skills/git-workflow.md +187 -0
  104. package/assets/skills/golang-patterns.md +185 -0
  105. package/assets/skills/graphql-patterns.md +244 -0
  106. package/assets/skills/i18n-patterns.md +172 -0
  107. package/assets/skills/image-processing.md +350 -0
  108. package/assets/skills/java-springboot.md +226 -0
  109. package/assets/skills/kotlin-patterns.md +207 -0
  110. package/assets/skills/kubernetes-patterns.md +326 -0
  111. package/assets/skills/laravel-patterns.md +261 -0
  112. package/assets/skills/llm-fine-tuning.md +335 -0
  113. package/assets/skills/load-testing.md +303 -0
  114. package/assets/skills/logging-observability.md +228 -0
  115. package/assets/skills/markdown-processing.md +318 -0
  116. package/assets/skills/mcp-server-patterns.md +292 -0
  117. package/assets/skills/microservices.md +272 -0
  118. package/assets/skills/migration-patterns.md +239 -0
  119. package/assets/skills/mongodb-patterns.md +189 -0
  120. package/assets/skills/monorepo-patterns.md +287 -0
  121. package/assets/skills/nextjs-app-router.md +237 -0
  122. package/assets/skills/notification-patterns.md +348 -0
  123. package/assets/skills/oauth-patterns.md +246 -0
  124. package/assets/skills/payment-integration.md +222 -0
  125. package/assets/skills/pdf-generation.md +307 -0
  126. package/assets/skills/performance-optimization.md +277 -0
  127. package/assets/skills/php-patterns.md +210 -0
  128. package/assets/skills/prisma-patterns.md +241 -0
  129. package/assets/skills/prompt-engineering.md +193 -0
  130. package/assets/skills/pwa-patterns.md +247 -0
  131. package/assets/skills/python-patterns.md +158 -0
  132. package/assets/skills/python-testing.md +172 -0
  133. package/assets/skills/queue-patterns.md +295 -0
  134. package/assets/skills/rag-patterns.md +159 -0
  135. package/assets/skills/rate-limiting.md +319 -0
  136. package/assets/skills/react-components.md +201 -0
  137. package/assets/skills/react-native-patterns.md +299 -0
  138. package/assets/skills/real-time-patterns.md +181 -0
  139. package/assets/skills/redis-patterns.md +188 -0
  140. package/assets/skills/refactoring.md +218 -0
  141. package/assets/skills/regex-patterns.md +191 -0
  142. package/assets/skills/remix-patterns.md +262 -0
  143. package/assets/skills/responsive-design.md +199 -0
  144. package/assets/skills/ruby-rails-patterns.md +178 -0
  145. package/assets/skills/rust-patterns.md +211 -0
  146. package/assets/skills/search-patterns.md +227 -0
  147. package/assets/skills/security-hardening.md +237 -0
  148. package/assets/skills/seo-patterns.md +179 -0
  149. package/assets/skills/serverless-patterns.md +223 -0
  150. package/assets/skills/sql-optimization.md +154 -0
  151. package/assets/skills/state-management.md +254 -0
  152. package/assets/skills/storybook-patterns.md +330 -0
  153. package/assets/skills/svelte-patterns.md +258 -0
  154. package/assets/skills/swift-patterns.md +227 -0
  155. package/assets/skills/tailwind-patterns.md +272 -0
  156. package/assets/skills/tdd-workflow.md +199 -0
  157. package/assets/skills/terraform-patterns.md +270 -0
  158. package/assets/skills/testing-react.md +240 -0
  159. package/assets/skills/testing-vitest.md +232 -0
  160. package/assets/skills/typescript-strict.md +159 -0
  161. package/assets/skills/video-processing.md +340 -0
  162. package/assets/skills/vue-patterns.md +247 -0
  163. package/assets/skills/web-workers.md +327 -0
  164. package/assets/skills/webhooks-patterns.md +283 -0
  165. package/assets/skills/websocket-patterns.md +306 -0
  166. package/dist/cli/index.js +941 -958
  167. package/dist/core/index.d.ts +341 -11
  168. package/dist/core.js +58 -95
  169. package/dist/mcp/index.d.ts +33 -1
  170. package/dist/mcp-server.js +177 -255
  171. package/package.json +4 -1
@@ -0,0 +1,232 @@
1
+ ---
2
+ name: testing-vitest
3
+ description: Vitest testing patterns including describe/it/expect, mocking with vi.*, snapshot testing, and coverage configuration.
4
+ ---
5
+
6
+ # Vitest Testing Patterns
7
+
8
+ ## When to Use
9
+ Use Vitest when writing unit and integration tests for TypeScript or JavaScript projects. Vitest is the preferred test runner for Vite-based projects and any modern TS codebase that benefits from native ESM support and fast HMR-driven test execution. Apply these patterns whenever you need to test pure functions, modules with dependencies, async code, or React components.
10
+
11
+ ## How It Works
12
+
13
+ ### Basic Test Structure
14
+
15
+ Every test file follows the describe/it/expect pattern:
16
+
17
+ ```typescript
18
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
19
+ import { calculateDiscount } from '../src/pricing';
20
+
21
+ describe('calculateDiscount', () => {
22
+ let basePrice: number;
23
+
24
+ beforeEach(() => {
25
+ basePrice = 100;
26
+ });
27
+
28
+ it('applies percentage discount correctly', () => {
29
+ const result = calculateDiscount(basePrice, { type: 'percent', value: 20 });
30
+ expect(result).toBe(80);
31
+ });
32
+
33
+ it('applies fixed discount correctly', () => {
34
+ const result = calculateDiscount(basePrice, { type: 'fixed', value: 15 });
35
+ expect(result).toBe(85);
36
+ });
37
+
38
+ it('never returns a negative price', () => {
39
+ const result = calculateDiscount(basePrice, { type: 'fixed', value: 200 });
40
+ expect(result).toBe(0);
41
+ });
42
+
43
+ it('throws on invalid discount type', () => {
44
+ expect(() => calculateDiscount(basePrice, { type: 'bogus' as any, value: 10 }))
45
+ .toThrow('Unknown discount type: bogus');
46
+ });
47
+ });
48
+ ```
49
+
50
+ ### Mocking with vi.*
51
+
52
+ Replace dependencies with controlled implementations:
53
+
54
+ ```typescript
55
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
56
+ import { fetchUserProfile } from '../src/user-service';
57
+
58
+ // Mock an entire module
59
+ vi.mock('../src/api-client', () => ({
60
+ apiClient: {
61
+ get: vi.fn(),
62
+ },
63
+ }));
64
+
65
+ import { apiClient } from '../src/api-client';
66
+
67
+ describe('fetchUserProfile', () => {
68
+ beforeEach(() => {
69
+ vi.clearAllMocks();
70
+ });
71
+
72
+ it('returns parsed user data', async () => {
73
+ vi.mocked(apiClient.get).mockResolvedValueOnce({
74
+ data: { id: '1', name: 'Alice', email: 'alice@example.com' },
75
+ });
76
+
77
+ const profile = await fetchUserProfile('1');
78
+
79
+ expect(apiClient.get).toHaveBeenCalledWith('/users/1');
80
+ expect(profile).toEqual({ id: '1', name: 'Alice', email: 'alice@example.com' });
81
+ });
82
+
83
+ it('throws on network error', async () => {
84
+ vi.mocked(apiClient.get).mockRejectedValueOnce(new Error('Network timeout'));
85
+
86
+ await expect(fetchUserProfile('1')).rejects.toThrow('Network timeout');
87
+ });
88
+ });
89
+ ```
90
+
91
+ ### Spying on Methods
92
+
93
+ ```typescript
94
+ import { describe, it, expect, vi } from 'vitest';
95
+
96
+ describe('Logger', () => {
97
+ it('tracks console.warn calls', () => {
98
+ const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
99
+
100
+ console.warn('deprecation notice');
101
+
102
+ expect(warnSpy).toHaveBeenCalledOnce();
103
+ expect(warnSpy).toHaveBeenCalledWith('deprecation notice');
104
+
105
+ warnSpy.mockRestore();
106
+ });
107
+ });
108
+ ```
109
+
110
+ ### Timer Mocking
111
+
112
+ ```typescript
113
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
114
+ import { debounce } from '../src/utils';
115
+
116
+ describe('debounce', () => {
117
+ beforeEach(() => {
118
+ vi.useFakeTimers();
119
+ });
120
+
121
+ afterEach(() => {
122
+ vi.useRealTimers();
123
+ });
124
+
125
+ it('delays execution by the specified ms', () => {
126
+ const fn = vi.fn();
127
+ const debounced = debounce(fn, 300);
128
+
129
+ debounced();
130
+ expect(fn).not.toHaveBeenCalled();
131
+
132
+ vi.advanceTimersByTime(299);
133
+ expect(fn).not.toHaveBeenCalled();
134
+
135
+ vi.advanceTimersByTime(1);
136
+ expect(fn).toHaveBeenCalledOnce();
137
+ });
138
+ });
139
+ ```
140
+
141
+ ### Snapshot Testing
142
+
143
+ ```typescript
144
+ import { describe, it, expect } from 'vitest';
145
+ import { generateConfig } from '../src/config-builder';
146
+
147
+ describe('generateConfig', () => {
148
+ it('matches snapshot for production env', () => {
149
+ const config = generateConfig({ env: 'production', region: 'us-east-1' });
150
+ expect(config).toMatchInlineSnapshot(`
151
+ {
152
+ "cache": true,
153
+ "debug": false,
154
+ "logLevel": "error",
155
+ "region": "us-east-1",
156
+ }
157
+ `);
158
+ });
159
+
160
+ it('matches file snapshot for full config', () => {
161
+ const config = generateConfig({ env: 'staging', region: 'eu-west-1' });
162
+ expect(config).toMatchSnapshot();
163
+ });
164
+ });
165
+ ```
166
+
167
+ ### Coverage Configuration
168
+
169
+ ```typescript
170
+ // vitest.config.ts
171
+ import { defineConfig } from 'vitest/config';
172
+
173
+ export default defineConfig({
174
+ test: {
175
+ globals: true,
176
+ environment: 'node',
177
+ include: ['**/*.test.ts', '**/*.spec.ts'],
178
+ coverage: {
179
+ provider: 'v8',
180
+ reporter: ['text', 'html', 'lcov'],
181
+ include: ['src/**/*.ts'],
182
+ exclude: ['src/**/*.d.ts', 'src/**/__tests__/**', 'src/**/index.ts'],
183
+ thresholds: {
184
+ branches: 80,
185
+ functions: 80,
186
+ lines: 80,
187
+ statements: 80,
188
+ },
189
+ },
190
+ },
191
+ });
192
+ ```
193
+
194
+ ### Parameterized Tests
195
+
196
+ ```typescript
197
+ import { describe, it, expect } from 'vitest';
198
+ import { slugify } from '../src/string-utils';
199
+
200
+ describe('slugify', () => {
201
+ it.each([
202
+ ['Hello World', 'hello-world'],
203
+ [' Leading spaces ', 'leading-spaces'],
204
+ ['Special Ch@r$!', 'special-chr'],
205
+ ['already-slugged', 'already-slugged'],
206
+ ['UPPERCASE', 'uppercase'],
207
+ ])('slugify(%j) => %j', (input, expected) => {
208
+ expect(slugify(input)).toBe(expected);
209
+ });
210
+ });
211
+ ```
212
+
213
+ ## Examples
214
+
215
+ | Pattern | Use Case |
216
+ |---------|----------|
217
+ | `vi.fn()` | Create a standalone mock function for callbacks |
218
+ | `vi.mock('module')` | Replace an entire module import |
219
+ | `vi.spyOn(obj, 'method')` | Watch calls without replacing implementation |
220
+ | `vi.useFakeTimers()` | Control setTimeout/setInterval/Date |
221
+ | `vi.mocked(fn)` | Get typed mock from an auto-mocked function |
222
+ | `toMatchInlineSnapshot()` | Pin output directly in the test file |
223
+ | `it.each([...])` | Run the same assertion with different inputs |
224
+
225
+ ## Checklist
226
+ - [ ] Every test file imports from `vitest`, not from `jest` or `@jest/globals`
227
+ - [ ] `vi.clearAllMocks()` is called in `beforeEach` when mocks are shared across tests
228
+ - [ ] Fake timers are restored in `afterEach` with `vi.useRealTimers()`
229
+ - [ ] Spies are restored with `mockRestore()` to prevent leakage between tests
230
+ - [ ] Coverage thresholds are set in `vitest.config.ts` and enforced in CI
231
+ - [ ] Async tests use `await expect(...).resolves` or `.rejects` instead of try/catch
232
+ - [ ] Snapshot files are committed and reviewed in PRs for unexpected changes
@@ -0,0 +1,159 @@
1
+ ---
2
+ name: typescript-strict
3
+ description: Enforce strict TypeScript patterns to catch bugs at compile time instead of runtime.
4
+ ---
5
+
6
+ # Strict TypeScript Patterns
7
+
8
+ ## When to Use
9
+
10
+ Apply these patterns whenever you write or review TypeScript code. Strict typing
11
+ eliminates entire categories of runtime errors — null reference crashes, missing
12
+ case handling, accidental type coercion, and silent data corruption. Use this
13
+ skill from day one of a project, not as a retrofit.
14
+
15
+ ## How It Works
16
+
17
+ ### 1. Ban `any` — Use `unknown` Instead
18
+
19
+ `any` disables the type checker. `unknown` forces you to narrow before use.
20
+
21
+ ```typescript
22
+ // Bad — silent runtime crash
23
+ function parse(input: any) {
24
+ return input.data.items; // no error, but blows up if input is null
25
+ }
26
+
27
+ // Good — compiler forces narrowing
28
+ function parse(input: unknown): Item[] {
29
+ if (typeof input === 'object' && input !== null && 'data' in input) {
30
+ const data = (input as { data: { items: Item[] } }).data;
31
+ return data.items;
32
+ }
33
+ throw new ParseError('Invalid input shape');
34
+ }
35
+ ```
36
+
37
+ Enable `"noImplicitAny": true` in tsconfig. Lint with `@typescript-eslint/no-explicit-any`.
38
+
39
+ ### 2. Discriminated Unions for State Modeling
40
+
41
+ Model mutually exclusive states with a literal discriminant field.
42
+
43
+ ```typescript
44
+ type AsyncState<T> =
45
+ | { status: 'idle' }
46
+ | { status: 'loading' }
47
+ | { status: 'success'; data: T }
48
+ | { status: 'error'; error: Error };
49
+
50
+ function render(state: AsyncState<User>) {
51
+ switch (state.status) {
52
+ case 'idle': return <Placeholder />;
53
+ case 'loading': return <Spinner />;
54
+ case 'success': return <Profile user={state.data} />; // data is narrowed
55
+ case 'error': return <Alert message={state.error.message} />;
56
+ }
57
+ }
58
+ ```
59
+
60
+ ### 3. Exhaustive Switch Checks
61
+
62
+ Use `never` to catch unhandled union members at compile time.
63
+
64
+ ```typescript
65
+ function assertNever(x: never): never {
66
+ throw new Error(`Unexpected value: ${JSON.stringify(x)}`);
67
+ }
68
+
69
+ function handleEvent(event: AppEvent) {
70
+ switch (event.type) {
71
+ case 'click': return onClick(event);
72
+ case 'keydown': return onKeydown(event);
73
+ default: return assertNever(event); // compile error if a case is missing
74
+ }
75
+ }
76
+ ```
77
+
78
+ ### 4. Branded Types for Domain Safety
79
+
80
+ Prevent mixing structurally identical but semantically different values.
81
+
82
+ ```typescript
83
+ type UserId = string & { readonly __brand: 'UserId' };
84
+ type OrderId = string & { readonly __brand: 'OrderId' };
85
+
86
+ function createUserId(raw: string): UserId { return raw as UserId; }
87
+ function createOrderId(raw: string): OrderId { return raw as OrderId; }
88
+
89
+ function getUser(id: UserId): Promise<User> { /* ... */ }
90
+
91
+ const orderId = createOrderId('abc-123');
92
+ getUser(orderId); // Compile error — OrderId is not assignable to UserId
93
+ ```
94
+
95
+ ### 5. Const Assertions and Readonly
96
+
97
+ Lock down object shapes and array contents.
98
+
99
+ ```typescript
100
+ const ROLES = ['admin', 'editor', 'viewer'] as const;
101
+ type Role = (typeof ROLES)[number]; // 'admin' | 'editor' | 'viewer'
102
+
103
+ interface Config {
104
+ readonly apiUrl: string;
105
+ readonly retries: number;
106
+ }
107
+ ```
108
+
109
+ ### 6. Template Literal Types for String Patterns
110
+
111
+ Constrain strings to known patterns without regex at runtime.
112
+
113
+ ```typescript
114
+ type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
115
+ type Route = `/${string}`;
116
+ type Endpoint = `${HttpMethod} ${Route}`;
117
+
118
+ const endpoint: Endpoint = 'GET /users'; // valid
119
+ const bad: Endpoint = 'FETCH /users'; // compile error
120
+ ```
121
+
122
+ ### 7. Strict tsconfig Settings
123
+
124
+ ```json
125
+ {
126
+ "compilerOptions": {
127
+ "strict": true,
128
+ "noUncheckedIndexedAccess": true,
129
+ "noImplicitReturns": true,
130
+ "noFallthroughCasesInSwitch": true,
131
+ "exactOptionalPropertyTypes": true,
132
+ "noPropertyAccessFromIndexSignature": true
133
+ }
134
+ }
135
+ ```
136
+
137
+ `noUncheckedIndexedAccess` is the most impactful — it makes `array[0]` return
138
+ `T | undefined` instead of `T`, catching out-of-bounds access.
139
+
140
+ ## Examples
141
+
142
+ | Pattern | Catches | Cost |
143
+ |---------|---------|------|
144
+ | Ban `any` | Type coercion bugs | Slightly more verbose parsers |
145
+ | Discriminated unions | Impossible state combinations | ~2 extra lines per type |
146
+ | Exhaustive checks | Unhandled cases after adding variants | One utility function |
147
+ | Branded types | ID mixups across domain boundaries | Factory function per type |
148
+ | `noUncheckedIndexedAccess` | Array/object out-of-bounds | More `?.` and null checks |
149
+
150
+ ## Checklist
151
+
152
+ - [ ] `"strict": true` is enabled in tsconfig with no per-file overrides
153
+ - [ ] `noUncheckedIndexedAccess` is enabled
154
+ - [ ] Zero `any` in application code (vendored types excluded)
155
+ - [ ] All union switches use exhaustive `assertNever` in the default branch
156
+ - [ ] Domain IDs use branded types, not raw strings
157
+ - [ ] Object configs use `as const` or `Readonly<>` where mutation is unintended
158
+ - [ ] ESLint rule `@typescript-eslint/no-explicit-any` is set to error
159
+ - [ ] CI fails on type errors — `tsc --noEmit` is in the pipeline