agentbrief 0.1.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 (137) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +141 -0
  3. package/briefs/code-reviewer/brief.yaml +8 -0
  4. package/briefs/code-reviewer/knowledge/review-standards.md +32 -0
  5. package/briefs/code-reviewer/personality.md +19 -0
  6. package/briefs/code-reviewer/skills/architecture-review/SKILL.md +76 -0
  7. package/briefs/code-reviewer/skills/review-process/SKILL.md +41 -0
  8. package/briefs/code-reviewer/skills/verification/SKILL.md +47 -0
  9. package/briefs/data-analyst/brief.yaml +8 -0
  10. package/briefs/data-analyst/knowledge/metrics-reference.md +43 -0
  11. package/briefs/data-analyst/personality.md +23 -0
  12. package/briefs/data-analyst/skills/metrics-framework/SKILL.md +90 -0
  13. package/briefs/data-analyst/skills/sql-query-builder/SKILL.md +115 -0
  14. package/briefs/devops-sre/brief.yaml +12 -0
  15. package/briefs/devops-sre/knowledge/runbook.md +69 -0
  16. package/briefs/devops-sre/personality.md +18 -0
  17. package/briefs/devops-sre/skills/ci-cd-github-actions/SKILL.md +114 -0
  18. package/briefs/devops-sre/skills/monitoring-observability/SKILL.md +394 -0
  19. package/briefs/devops-sre/skills/systematic-debugging/SKILL.md +46 -0
  20. package/briefs/devops-sre/skills/verification/SKILL.md +47 -0
  21. package/briefs/frontend-design/brief.yaml +8 -0
  22. package/briefs/frontend-design/knowledge/design-principles.md +43 -0
  23. package/briefs/frontend-design/personality.md +19 -0
  24. package/briefs/frontend-design/skills/design-review-checklist/SKILL.md +151 -0
  25. package/briefs/frontend-design/skills/web-design-guidelines/SKILL.md +39 -0
  26. package/briefs/fullstack-dev/brief.yaml +9 -0
  27. package/briefs/fullstack-dev/personality.md +18 -0
  28. package/briefs/growth-engineer/brief.yaml +8 -0
  29. package/briefs/growth-engineer/knowledge/growth-framework.md +83 -0
  30. package/briefs/growth-engineer/personality.md +19 -0
  31. package/briefs/growth-engineer/skills/analytics-setup/SKILL.md +109 -0
  32. package/briefs/growth-engineer/skills/brainstorming/SKILL.md +55 -0
  33. package/briefs/growth-engineer/skills/content-strategy/SKILL.md +93 -0
  34. package/briefs/growth-engineer/skills/seo-audit/SKILL.md +412 -0
  35. package/briefs/growth-engineer/skills/seo-audit/evals/evals.json +136 -0
  36. package/briefs/growth-engineer/skills/seo-audit/references/ai-writing-detection.md +200 -0
  37. package/briefs/nextjs-fullstack/brief.yaml +12 -0
  38. package/briefs/nextjs-fullstack/knowledge/conventions.md +57 -0
  39. package/briefs/nextjs-fullstack/personality.md +19 -0
  40. package/briefs/nextjs-fullstack/skills/next-best-practices/SKILL.md +153 -0
  41. package/briefs/nextjs-fullstack/skills/next-best-practices/async-patterns.md +87 -0
  42. package/briefs/nextjs-fullstack/skills/next-best-practices/bundling.md +180 -0
  43. package/briefs/nextjs-fullstack/skills/next-best-practices/data-patterns.md +297 -0
  44. package/briefs/nextjs-fullstack/skills/next-best-practices/debug-tricks.md +105 -0
  45. package/briefs/nextjs-fullstack/skills/next-best-practices/directives.md +73 -0
  46. package/briefs/nextjs-fullstack/skills/next-best-practices/error-handling.md +227 -0
  47. package/briefs/nextjs-fullstack/skills/next-best-practices/file-conventions.md +140 -0
  48. package/briefs/nextjs-fullstack/skills/next-best-practices/font.md +245 -0
  49. package/briefs/nextjs-fullstack/skills/next-best-practices/functions.md +108 -0
  50. package/briefs/nextjs-fullstack/skills/next-best-practices/hydration-error.md +91 -0
  51. package/briefs/nextjs-fullstack/skills/next-best-practices/image.md +173 -0
  52. package/briefs/nextjs-fullstack/skills/next-best-practices/metadata.md +301 -0
  53. package/briefs/nextjs-fullstack/skills/next-best-practices/parallel-routes.md +287 -0
  54. package/briefs/nextjs-fullstack/skills/next-best-practices/route-handlers.md +146 -0
  55. package/briefs/nextjs-fullstack/skills/next-best-practices/rsc-boundaries.md +159 -0
  56. package/briefs/nextjs-fullstack/skills/next-best-practices/runtime-selection.md +39 -0
  57. package/briefs/nextjs-fullstack/skills/next-best-practices/scripts.md +141 -0
  58. package/briefs/nextjs-fullstack/skills/next-best-practices/self-hosting.md +371 -0
  59. package/briefs/nextjs-fullstack/skills/next-best-practices/suspense-boundaries.md +67 -0
  60. package/briefs/nextjs-fullstack/skills/tdd/SKILL.md +53 -0
  61. package/briefs/product-manager/brief.yaml +8 -0
  62. package/briefs/product-manager/knowledge/pm-toolkit.md +51 -0
  63. package/briefs/product-manager/personality.md +19 -0
  64. package/briefs/product-manager/skills/brainstorming/SKILL.md +55 -0
  65. package/briefs/product-manager/skills/specification/SKILL.md +76 -0
  66. package/briefs/qa-engineer/brief.yaml +11 -0
  67. package/briefs/qa-engineer/knowledge/testing-patterns.md +54 -0
  68. package/briefs/qa-engineer/personality.md +24 -0
  69. package/briefs/qa-engineer/skills/qa-test-and-fix/SKILL.md +101 -0
  70. package/briefs/qa-engineer/skills/regression-testing/SKILL.md +95 -0
  71. package/briefs/security-auditor/brief.yaml +12 -0
  72. package/briefs/security-auditor/knowledge/code-patterns.md +49 -0
  73. package/briefs/security-auditor/knowledge/owasp-cheatsheet.md +75 -0
  74. package/briefs/security-auditor/personality.md +23 -0
  75. package/briefs/security-auditor/skills/security-review/SKILL.md +29 -0
  76. package/briefs/security-auditor/skills/systematic-debugging/SKILL.md +46 -0
  77. package/briefs/security-auditor/skills/verification/SKILL.md +47 -0
  78. package/briefs/startup-builder/brief.yaml +8 -0
  79. package/briefs/startup-builder/knowledge/startup-phases.md +64 -0
  80. package/briefs/startup-builder/personality.md +18 -0
  81. package/briefs/startup-builder/skills/ceo-review/SKILL.md +95 -0
  82. package/briefs/startup-builder/skills/launch-strategy/SKILL.md +353 -0
  83. package/briefs/startup-builder/skills/launch-strategy/evals/evals.json +91 -0
  84. package/briefs/startup-builder/skills/tdd/SKILL.md +53 -0
  85. package/briefs/startup-builder/skills/verification/SKILL.md +47 -0
  86. package/briefs/startup-kit/brief.yaml +9 -0
  87. package/briefs/startup-kit/personality.md +18 -0
  88. package/briefs/tech-writer/brief.yaml +8 -0
  89. package/briefs/tech-writer/knowledge/style-guide.md +54 -0
  90. package/briefs/tech-writer/personality.md +19 -0
  91. package/briefs/tech-writer/skills/api-documentation/SKILL.md +390 -0
  92. package/briefs/tech-writer/skills/plan-and-execute/SKILL.md +54 -0
  93. package/briefs/tech-writer/skills/release-notes/SKILL.md +77 -0
  94. package/briefs/typescript-strict/brief.yaml +8 -0
  95. package/briefs/typescript-strict/knowledge/type-patterns.md +117 -0
  96. package/briefs/typescript-strict/personality.md +23 -0
  97. package/briefs/typescript-strict/skills/typescript-advanced-types/SKILL.md +717 -0
  98. package/dist/brief.d.ts +13 -0
  99. package/dist/brief.d.ts.map +1 -0
  100. package/dist/brief.js +90 -0
  101. package/dist/brief.js.map +1 -0
  102. package/dist/cli.d.ts +3 -0
  103. package/dist/cli.d.ts.map +1 -0
  104. package/dist/cli.js +180 -0
  105. package/dist/cli.js.map +1 -0
  106. package/dist/compiler.d.ts +25 -0
  107. package/dist/compiler.d.ts.map +1 -0
  108. package/dist/compiler.js +253 -0
  109. package/dist/compiler.js.map +1 -0
  110. package/dist/index.d.ts +54 -0
  111. package/dist/index.d.ts.map +1 -0
  112. package/dist/index.js +255 -0
  113. package/dist/index.js.map +1 -0
  114. package/dist/injector.d.ts +17 -0
  115. package/dist/injector.d.ts.map +1 -0
  116. package/dist/injector.js +76 -0
  117. package/dist/injector.js.map +1 -0
  118. package/dist/lock.d.ts +8 -0
  119. package/dist/lock.d.ts.map +1 -0
  120. package/dist/lock.js +50 -0
  121. package/dist/lock.js.map +1 -0
  122. package/dist/resolver.d.ts +24 -0
  123. package/dist/resolver.d.ts.map +1 -0
  124. package/dist/resolver.js +135 -0
  125. package/dist/resolver.js.map +1 -0
  126. package/dist/types.d.ts +61 -0
  127. package/dist/types.d.ts.map +1 -0
  128. package/dist/types.js +15 -0
  129. package/dist/types.js.map +1 -0
  130. package/package.json +64 -0
  131. package/registry.yaml +91 -0
  132. package/templates/default/brief.yaml +7 -0
  133. package/templates/default/knowledge/.gitkeep +0 -0
  134. package/templates/default/personality.md +12 -0
  135. package/templates/security/brief.yaml +6 -0
  136. package/templates/security/knowledge/.gitkeep +0 -0
  137. package/templates/security/personality.md +20 -0
@@ -0,0 +1,717 @@
1
+ ---
2
+ name: typescript-advanced-types
3
+ description: Master TypeScript's advanced type system including generics, conditional types, mapped types, template literals, and utility types for building type-safe applications. Use when implementing complex type logic, creating reusable type utilities, or ensuring compile-time type safety in TypeScript projects.
4
+ ---
5
+
6
+ # TypeScript Advanced Types
7
+
8
+ Comprehensive guidance for mastering TypeScript's advanced type system including generics, conditional types, mapped types, template literal types, and utility types for building robust, type-safe applications.
9
+
10
+ ## When to Use This Skill
11
+
12
+ - Building type-safe libraries or frameworks
13
+ - Creating reusable generic components
14
+ - Implementing complex type inference logic
15
+ - Designing type-safe API clients
16
+ - Building form validation systems
17
+ - Creating strongly-typed configuration objects
18
+ - Implementing type-safe state management
19
+ - Migrating JavaScript codebases to TypeScript
20
+
21
+ ## Core Concepts
22
+
23
+ ### 1. Generics
24
+
25
+ **Purpose:** Create reusable, type-flexible components while maintaining type safety.
26
+
27
+ **Basic Generic Function:**
28
+
29
+ ```typescript
30
+ function identity<T>(value: T): T {
31
+ return value;
32
+ }
33
+
34
+ const num = identity<number>(42); // Type: number
35
+ const str = identity<string>("hello"); // Type: string
36
+ const auto = identity(true); // Type inferred: boolean
37
+ ```
38
+
39
+ **Generic Constraints:**
40
+
41
+ ```typescript
42
+ interface HasLength {
43
+ length: number;
44
+ }
45
+
46
+ function logLength<T extends HasLength>(item: T): T {
47
+ console.log(item.length);
48
+ return item;
49
+ }
50
+
51
+ logLength("hello"); // OK: string has length
52
+ logLength([1, 2, 3]); // OK: array has length
53
+ logLength({ length: 10 }); // OK: object has length
54
+ // logLength(42); // Error: number has no length
55
+ ```
56
+
57
+ **Multiple Type Parameters:**
58
+
59
+ ```typescript
60
+ function merge<T, U>(obj1: T, obj2: U): T & U {
61
+ return { ...obj1, ...obj2 };
62
+ }
63
+
64
+ const merged = merge({ name: "John" }, { age: 30 });
65
+ // Type: { name: string } & { age: number }
66
+ ```
67
+
68
+ ### 2. Conditional Types
69
+
70
+ **Purpose:** Create types that depend on conditions, enabling sophisticated type logic.
71
+
72
+ **Basic Conditional Type:**
73
+
74
+ ```typescript
75
+ type IsString<T> = T extends string ? true : false;
76
+
77
+ type A = IsString<string>; // true
78
+ type B = IsString<number>; // false
79
+ ```
80
+
81
+ **Extracting Return Types:**
82
+
83
+ ```typescript
84
+ type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
85
+
86
+ function getUser() {
87
+ return { id: 1, name: "John" };
88
+ }
89
+
90
+ type User = ReturnType<typeof getUser>;
91
+ // Type: { id: number; name: string; }
92
+ ```
93
+
94
+ **Distributive Conditional Types:**
95
+
96
+ ```typescript
97
+ type ToArray<T> = T extends any ? T[] : never;
98
+
99
+ type StrOrNumArray = ToArray<string | number>;
100
+ // Type: string[] | number[]
101
+ ```
102
+
103
+ **Nested Conditions:**
104
+
105
+ ```typescript
106
+ type TypeName<T> = T extends string
107
+ ? "string"
108
+ : T extends number
109
+ ? "number"
110
+ : T extends boolean
111
+ ? "boolean"
112
+ : T extends undefined
113
+ ? "undefined"
114
+ : T extends Function
115
+ ? "function"
116
+ : "object";
117
+
118
+ type T1 = TypeName<string>; // "string"
119
+ type T2 = TypeName<() => void>; // "function"
120
+ ```
121
+
122
+ ### 3. Mapped Types
123
+
124
+ **Purpose:** Transform existing types by iterating over their properties.
125
+
126
+ **Basic Mapped Type:**
127
+
128
+ ```typescript
129
+ type Readonly<T> = {
130
+ readonly [P in keyof T]: T[P];
131
+ };
132
+
133
+ interface User {
134
+ id: number;
135
+ name: string;
136
+ }
137
+
138
+ type ReadonlyUser = Readonly<User>;
139
+ // Type: { readonly id: number; readonly name: string; }
140
+ ```
141
+
142
+ **Optional Properties:**
143
+
144
+ ```typescript
145
+ type Partial<T> = {
146
+ [P in keyof T]?: T[P];
147
+ };
148
+
149
+ type PartialUser = Partial<User>;
150
+ // Type: { id?: number; name?: string; }
151
+ ```
152
+
153
+ **Key Remapping:**
154
+
155
+ ```typescript
156
+ type Getters<T> = {
157
+ [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
158
+ };
159
+
160
+ interface Person {
161
+ name: string;
162
+ age: number;
163
+ }
164
+
165
+ type PersonGetters = Getters<Person>;
166
+ // Type: { getName: () => string; getAge: () => number; }
167
+ ```
168
+
169
+ **Filtering Properties:**
170
+
171
+ ```typescript
172
+ type PickByType<T, U> = {
173
+ [K in keyof T as T[K] extends U ? K : never]: T[K];
174
+ };
175
+
176
+ interface Mixed {
177
+ id: number;
178
+ name: string;
179
+ age: number;
180
+ active: boolean;
181
+ }
182
+
183
+ type OnlyNumbers = PickByType<Mixed, number>;
184
+ // Type: { id: number; age: number; }
185
+ ```
186
+
187
+ ### 4. Template Literal Types
188
+
189
+ **Purpose:** Create string-based types with pattern matching and transformation.
190
+
191
+ **Basic Template Literal:**
192
+
193
+ ```typescript
194
+ type EventName = "click" | "focus" | "blur";
195
+ type EventHandler = `on${Capitalize<EventName>}`;
196
+ // Type: "onClick" | "onFocus" | "onBlur"
197
+ ```
198
+
199
+ **String Manipulation:**
200
+
201
+ ```typescript
202
+ type UppercaseGreeting = Uppercase<"hello">; // "HELLO"
203
+ type LowercaseGreeting = Lowercase<"HELLO">; // "hello"
204
+ type CapitalizedName = Capitalize<"john">; // "John"
205
+ type UncapitalizedName = Uncapitalize<"John">; // "john"
206
+ ```
207
+
208
+ **Path Building:**
209
+
210
+ ```typescript
211
+ type Path<T> = T extends object
212
+ ? {
213
+ [K in keyof T]: K extends string ? `${K}` | `${K}.${Path<T[K]>}` : never;
214
+ }[keyof T]
215
+ : never;
216
+
217
+ interface Config {
218
+ server: {
219
+ host: string;
220
+ port: number;
221
+ };
222
+ database: {
223
+ url: string;
224
+ };
225
+ }
226
+
227
+ type ConfigPath = Path<Config>;
228
+ // Type: "server" | "database" | "server.host" | "server.port" | "database.url"
229
+ ```
230
+
231
+ ### 5. Utility Types
232
+
233
+ **Built-in Utility Types:**
234
+
235
+ ```typescript
236
+ // Partial<T> - Make all properties optional
237
+ type PartialUser = Partial<User>;
238
+
239
+ // Required<T> - Make all properties required
240
+ type RequiredUser = Required<PartialUser>;
241
+
242
+ // Readonly<T> - Make all properties readonly
243
+ type ReadonlyUser = Readonly<User>;
244
+
245
+ // Pick<T, K> - Select specific properties
246
+ type UserName = Pick<User, "name" | "email">;
247
+
248
+ // Omit<T, K> - Remove specific properties
249
+ type UserWithoutPassword = Omit<User, "password">;
250
+
251
+ // Exclude<T, U> - Exclude types from union
252
+ type T1 = Exclude<"a" | "b" | "c", "a">; // "b" | "c"
253
+
254
+ // Extract<T, U> - Extract types from union
255
+ type T2 = Extract<"a" | "b" | "c", "a" | "b">; // "a" | "b"
256
+
257
+ // NonNullable<T> - Exclude null and undefined
258
+ type T3 = NonNullable<string | null | undefined>; // string
259
+
260
+ // Record<K, T> - Create object type with keys K and values T
261
+ type PageInfo = Record<"home" | "about", { title: string }>;
262
+ ```
263
+
264
+ ## Advanced Patterns
265
+
266
+ ### Pattern 1: Type-Safe Event Emitter
267
+
268
+ ```typescript
269
+ type EventMap = {
270
+ "user:created": { id: string; name: string };
271
+ "user:updated": { id: string };
272
+ "user:deleted": { id: string };
273
+ };
274
+
275
+ class TypedEventEmitter<T extends Record<string, any>> {
276
+ private listeners: {
277
+ [K in keyof T]?: Array<(data: T[K]) => void>;
278
+ } = {};
279
+
280
+ on<K extends keyof T>(event: K, callback: (data: T[K]) => void): void {
281
+ if (!this.listeners[event]) {
282
+ this.listeners[event] = [];
283
+ }
284
+ this.listeners[event]!.push(callback);
285
+ }
286
+
287
+ emit<K extends keyof T>(event: K, data: T[K]): void {
288
+ const callbacks = this.listeners[event];
289
+ if (callbacks) {
290
+ callbacks.forEach((callback) => callback(data));
291
+ }
292
+ }
293
+ }
294
+
295
+ const emitter = new TypedEventEmitter<EventMap>();
296
+
297
+ emitter.on("user:created", (data) => {
298
+ console.log(data.id, data.name); // Type-safe!
299
+ });
300
+
301
+ emitter.emit("user:created", { id: "1", name: "John" });
302
+ // emitter.emit("user:created", { id: "1" }); // Error: missing 'name'
303
+ ```
304
+
305
+ ### Pattern 2: Type-Safe API Client
306
+
307
+ ```typescript
308
+ type HTTPMethod = "GET" | "POST" | "PUT" | "DELETE";
309
+
310
+ type EndpointConfig = {
311
+ "/users": {
312
+ GET: { response: User[] };
313
+ POST: { body: { name: string; email: string }; response: User };
314
+ };
315
+ "/users/:id": {
316
+ GET: { params: { id: string }; response: User };
317
+ PUT: { params: { id: string }; body: Partial<User>; response: User };
318
+ DELETE: { params: { id: string }; response: void };
319
+ };
320
+ };
321
+
322
+ type ExtractParams<T> = T extends { params: infer P } ? P : never;
323
+ type ExtractBody<T> = T extends { body: infer B } ? B : never;
324
+ type ExtractResponse<T> = T extends { response: infer R } ? R : never;
325
+
326
+ class APIClient<Config extends Record<string, Record<HTTPMethod, any>>> {
327
+ async request<Path extends keyof Config, Method extends keyof Config[Path]>(
328
+ path: Path,
329
+ method: Method,
330
+ ...[options]: ExtractParams<Config[Path][Method]> extends never
331
+ ? ExtractBody<Config[Path][Method]> extends never
332
+ ? []
333
+ : [{ body: ExtractBody<Config[Path][Method]> }]
334
+ : [
335
+ {
336
+ params: ExtractParams<Config[Path][Method]>;
337
+ body?: ExtractBody<Config[Path][Method]>;
338
+ },
339
+ ]
340
+ ): Promise<ExtractResponse<Config[Path][Method]>> {
341
+ // Implementation here
342
+ return {} as any;
343
+ }
344
+ }
345
+
346
+ const api = new APIClient<EndpointConfig>();
347
+
348
+ // Type-safe API calls
349
+ const users = await api.request("/users", "GET");
350
+ // Type: User[]
351
+
352
+ const newUser = await api.request("/users", "POST", {
353
+ body: { name: "John", email: "john@example.com" },
354
+ });
355
+ // Type: User
356
+
357
+ const user = await api.request("/users/:id", "GET", {
358
+ params: { id: "123" },
359
+ });
360
+ // Type: User
361
+ ```
362
+
363
+ ### Pattern 3: Builder Pattern with Type Safety
364
+
365
+ ```typescript
366
+ type BuilderState<T> = {
367
+ [K in keyof T]: T[K] | undefined;
368
+ };
369
+
370
+ type RequiredKeys<T> = {
371
+ [K in keyof T]-?: {} extends Pick<T, K> ? never : K;
372
+ }[keyof T];
373
+
374
+ type OptionalKeys<T> = {
375
+ [K in keyof T]-?: {} extends Pick<T, K> ? K : never;
376
+ }[keyof T];
377
+
378
+ type IsComplete<T, S> =
379
+ RequiredKeys<T> extends keyof S
380
+ ? S[RequiredKeys<T>] extends undefined
381
+ ? false
382
+ : true
383
+ : false;
384
+
385
+ class Builder<T, S extends BuilderState<T> = {}> {
386
+ private state: S = {} as S;
387
+
388
+ set<K extends keyof T>(key: K, value: T[K]): Builder<T, S & Record<K, T[K]>> {
389
+ this.state[key] = value;
390
+ return this as any;
391
+ }
392
+
393
+ build(this: IsComplete<T, S> extends true ? this : never): T {
394
+ return this.state as T;
395
+ }
396
+ }
397
+
398
+ interface User {
399
+ id: string;
400
+ name: string;
401
+ email: string;
402
+ age?: number;
403
+ }
404
+
405
+ const builder = new Builder<User>();
406
+
407
+ const user = builder
408
+ .set("id", "1")
409
+ .set("name", "John")
410
+ .set("email", "john@example.com")
411
+ .build(); // OK: all required fields set
412
+
413
+ // const incomplete = builder
414
+ // .set("id", "1")
415
+ // .build(); // Error: missing required fields
416
+ ```
417
+
418
+ ### Pattern 4: Deep Readonly/Partial
419
+
420
+ ```typescript
421
+ type DeepReadonly<T> = {
422
+ readonly [P in keyof T]: T[P] extends object
423
+ ? T[P] extends Function
424
+ ? T[P]
425
+ : DeepReadonly<T[P]>
426
+ : T[P];
427
+ };
428
+
429
+ type DeepPartial<T> = {
430
+ [P in keyof T]?: T[P] extends object
431
+ ? T[P] extends Array<infer U>
432
+ ? Array<DeepPartial<U>>
433
+ : DeepPartial<T[P]>
434
+ : T[P];
435
+ };
436
+
437
+ interface Config {
438
+ server: {
439
+ host: string;
440
+ port: number;
441
+ ssl: {
442
+ enabled: boolean;
443
+ cert: string;
444
+ };
445
+ };
446
+ database: {
447
+ url: string;
448
+ pool: {
449
+ min: number;
450
+ max: number;
451
+ };
452
+ };
453
+ }
454
+
455
+ type ReadonlyConfig = DeepReadonly<Config>;
456
+ // All nested properties are readonly
457
+
458
+ type PartialConfig = DeepPartial<Config>;
459
+ // All nested properties are optional
460
+ ```
461
+
462
+ ### Pattern 5: Type-Safe Form Validation
463
+
464
+ ```typescript
465
+ type ValidationRule<T> = {
466
+ validate: (value: T) => boolean;
467
+ message: string;
468
+ };
469
+
470
+ type FieldValidation<T> = {
471
+ [K in keyof T]?: ValidationRule<T[K]>[];
472
+ };
473
+
474
+ type ValidationErrors<T> = {
475
+ [K in keyof T]?: string[];
476
+ };
477
+
478
+ class FormValidator<T extends Record<string, any>> {
479
+ constructor(private rules: FieldValidation<T>) {}
480
+
481
+ validate(data: T): ValidationErrors<T> | null {
482
+ const errors: ValidationErrors<T> = {};
483
+ let hasErrors = false;
484
+
485
+ for (const key in this.rules) {
486
+ const fieldRules = this.rules[key];
487
+ const value = data[key];
488
+
489
+ if (fieldRules) {
490
+ const fieldErrors: string[] = [];
491
+
492
+ for (const rule of fieldRules) {
493
+ if (!rule.validate(value)) {
494
+ fieldErrors.push(rule.message);
495
+ }
496
+ }
497
+
498
+ if (fieldErrors.length > 0) {
499
+ errors[key] = fieldErrors;
500
+ hasErrors = true;
501
+ }
502
+ }
503
+ }
504
+
505
+ return hasErrors ? errors : null;
506
+ }
507
+ }
508
+
509
+ interface LoginForm {
510
+ email: string;
511
+ password: string;
512
+ }
513
+
514
+ const validator = new FormValidator<LoginForm>({
515
+ email: [
516
+ {
517
+ validate: (v) => v.includes("@"),
518
+ message: "Email must contain @",
519
+ },
520
+ {
521
+ validate: (v) => v.length > 0,
522
+ message: "Email is required",
523
+ },
524
+ ],
525
+ password: [
526
+ {
527
+ validate: (v) => v.length >= 8,
528
+ message: "Password must be at least 8 characters",
529
+ },
530
+ ],
531
+ });
532
+
533
+ const errors = validator.validate({
534
+ email: "invalid",
535
+ password: "short",
536
+ });
537
+ // Type: { email?: string[]; password?: string[]; } | null
538
+ ```
539
+
540
+ ### Pattern 6: Discriminated Unions
541
+
542
+ ```typescript
543
+ type Success<T> = {
544
+ status: "success";
545
+ data: T;
546
+ };
547
+
548
+ type Error = {
549
+ status: "error";
550
+ error: string;
551
+ };
552
+
553
+ type Loading = {
554
+ status: "loading";
555
+ };
556
+
557
+ type AsyncState<T> = Success<T> | Error | Loading;
558
+
559
+ function handleState<T>(state: AsyncState<T>): void {
560
+ switch (state.status) {
561
+ case "success":
562
+ console.log(state.data); // Type: T
563
+ break;
564
+ case "error":
565
+ console.log(state.error); // Type: string
566
+ break;
567
+ case "loading":
568
+ console.log("Loading...");
569
+ break;
570
+ }
571
+ }
572
+
573
+ // Type-safe state machine
574
+ type State =
575
+ | { type: "idle" }
576
+ | { type: "fetching"; requestId: string }
577
+ | { type: "success"; data: any }
578
+ | { type: "error"; error: Error };
579
+
580
+ type Event =
581
+ | { type: "FETCH"; requestId: string }
582
+ | { type: "SUCCESS"; data: any }
583
+ | { type: "ERROR"; error: Error }
584
+ | { type: "RESET" };
585
+
586
+ function reducer(state: State, event: Event): State {
587
+ switch (state.type) {
588
+ case "idle":
589
+ return event.type === "FETCH"
590
+ ? { type: "fetching", requestId: event.requestId }
591
+ : state;
592
+ case "fetching":
593
+ if (event.type === "SUCCESS") {
594
+ return { type: "success", data: event.data };
595
+ }
596
+ if (event.type === "ERROR") {
597
+ return { type: "error", error: event.error };
598
+ }
599
+ return state;
600
+ case "success":
601
+ case "error":
602
+ return event.type === "RESET" ? { type: "idle" } : state;
603
+ }
604
+ }
605
+ ```
606
+
607
+ ## Type Inference Techniques
608
+
609
+ ### 1. Infer Keyword
610
+
611
+ ```typescript
612
+ // Extract array element type
613
+ type ElementType<T> = T extends (infer U)[] ? U : never;
614
+
615
+ type NumArray = number[];
616
+ type Num = ElementType<NumArray>; // number
617
+
618
+ // Extract promise type
619
+ type PromiseType<T> = T extends Promise<infer U> ? U : never;
620
+
621
+ type AsyncNum = PromiseType<Promise<number>>; // number
622
+
623
+ // Extract function parameters
624
+ type Parameters<T> = T extends (...args: infer P) => any ? P : never;
625
+
626
+ function foo(a: string, b: number) {}
627
+ type FooParams = Parameters<typeof foo>; // [string, number]
628
+ ```
629
+
630
+ ### 2. Type Guards
631
+
632
+ ```typescript
633
+ function isString(value: unknown): value is string {
634
+ return typeof value === "string";
635
+ }
636
+
637
+ function isArrayOf<T>(
638
+ value: unknown,
639
+ guard: (item: unknown) => item is T,
640
+ ): value is T[] {
641
+ return Array.isArray(value) && value.every(guard);
642
+ }
643
+
644
+ const data: unknown = ["a", "b", "c"];
645
+
646
+ if (isArrayOf(data, isString)) {
647
+ data.forEach((s) => s.toUpperCase()); // Type: string[]
648
+ }
649
+ ```
650
+
651
+ ### 3. Assertion Functions
652
+
653
+ ```typescript
654
+ function assertIsString(value: unknown): asserts value is string {
655
+ if (typeof value !== "string") {
656
+ throw new Error("Not a string");
657
+ }
658
+ }
659
+
660
+ function processValue(value: unknown) {
661
+ assertIsString(value);
662
+ // value is now typed as string
663
+ console.log(value.toUpperCase());
664
+ }
665
+ ```
666
+
667
+ ## Best Practices
668
+
669
+ 1. **Use `unknown` over `any`**: Enforce type checking
670
+ 2. **Prefer `interface` for object shapes**: Better error messages
671
+ 3. **Use `type` for unions and complex types**: More flexible
672
+ 4. **Leverage type inference**: Let TypeScript infer when possible
673
+ 5. **Create helper types**: Build reusable type utilities
674
+ 6. **Use const assertions**: Preserve literal types
675
+ 7. **Avoid type assertions**: Use type guards instead
676
+ 8. **Document complex types**: Add JSDoc comments
677
+ 9. **Use strict mode**: Enable all strict compiler options
678
+ 10. **Test your types**: Use type tests to verify type behavior
679
+
680
+ ## Type Testing
681
+
682
+ ```typescript
683
+ // Type assertion tests
684
+ type AssertEqual<T, U> = [T] extends [U]
685
+ ? [U] extends [T]
686
+ ? true
687
+ : false
688
+ : false;
689
+
690
+ type Test1 = AssertEqual<string, string>; // true
691
+ type Test2 = AssertEqual<string, number>; // false
692
+ type Test3 = AssertEqual<string | number, string>; // false
693
+
694
+ // Expect error helper
695
+ type ExpectError<T extends never> = T;
696
+
697
+ // Example usage
698
+ type ShouldError = ExpectError<AssertEqual<string, number>>;
699
+ ```
700
+
701
+ ## Common Pitfalls
702
+
703
+ 1. **Over-using `any`**: Defeats the purpose of TypeScript
704
+ 2. **Ignoring strict null checks**: Can lead to runtime errors
705
+ 3. **Too complex types**: Can slow down compilation
706
+ 4. **Not using discriminated unions**: Misses type narrowing opportunities
707
+ 5. **Forgetting readonly modifiers**: Allows unintended mutations
708
+ 6. **Circular type references**: Can cause compiler errors
709
+ 7. **Not handling edge cases**: Like empty arrays or null values
710
+
711
+ ## Performance Considerations
712
+
713
+ - Avoid deeply nested conditional types
714
+ - Use simple types when possible
715
+ - Cache complex type computations
716
+ - Limit recursion depth in recursive types
717
+ - Use build tools to skip type checking in production
@@ -0,0 +1,13 @@
1
+ import type { BriefSpec, SkillMeta } from "./types.js";
2
+ export declare function loadBrief(dir: string): Promise<BriefSpec>;
3
+ export declare function loadPersonality(dir: string, spec: BriefSpec): Promise<string>;
4
+ /**
5
+ * Scan skill directories and extract SKILL.md frontmatter.
6
+ *
7
+ * Each skill is a directory containing a SKILL.md file (+ optional scripts/, references/, assets/).
8
+ * Compatible with the skills.sh / Agent Skills ecosystem.
9
+ *
10
+ * Layout: skills/{skill-name}/SKILL.md
11
+ */
12
+ export declare function loadSkillMetas(dir: string, spec: BriefSpec): Promise<SkillMeta[]>;
13
+ //# sourceMappingURL=brief.d.ts.map