ghcopilot-hub 1.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 (109) hide show
  1. package/README.md +176 -0
  2. package/hub/agents/README.md +243 -0
  3. package/hub/agents/archiver.agent.md +231 -0
  4. package/hub/agents/explore.agent.md +49 -0
  5. package/hub/agents/implementador.agent.md +176 -0
  6. package/hub/agents/librarian.agent.md +34 -0
  7. package/hub/agents/momus.agent.md +130 -0
  8. package/hub/agents/oracle.agent.md +52 -0
  9. package/hub/agents/plan-guardian.agent.md +109 -0
  10. package/hub/agents/planificador.agent.md +295 -0
  11. package/hub/agents/test-sentinel.agent.md +106 -0
  12. package/hub/base/.github/copilot-instructions.md +10 -0
  13. package/hub/base/.github/instructions/ghcopilot-hub.instructions.md +6 -0
  14. package/hub/base/.github/prompts/ghcopilot-hub-maintenance.prompt.md +8 -0
  15. package/hub/base/.vscode/settings.json +1 -0
  16. package/hub/packs/base-web.json +4 -0
  17. package/hub/packs/nextjs-ssr.json +4 -0
  18. package/hub/packs/node-api.json +4 -0
  19. package/hub/packs/spa-tanstack.json +4 -0
  20. package/hub/skills/architecture-testing/SKILL.md +108 -0
  21. package/hub/skills/architecture-testing/references/archunitts.md +46 -0
  22. package/hub/skills/ghcopilot-hub-consumer/SKILL.md +115 -0
  23. package/hub/skills/ghcopilot-hub-consumer/references/workflow.md +39 -0
  24. package/hub/skills/mermaid-expert/SKILL.md +152 -0
  25. package/hub/skills/mermaid-expert/assets/examples/c4_model.md +121 -0
  26. package/hub/skills/mermaid-expert/assets/examples/flowchart.md +123 -0
  27. package/hub/skills/mermaid-expert/assets/examples/img/base_minimal.png +0 -0
  28. package/hub/skills/mermaid-expert/assets/examples/img/corporate.png +0 -0
  29. package/hub/skills/mermaid-expert/assets/examples/img/dark.png +0 -0
  30. package/hub/skills/mermaid-expert/assets/examples/img/dark_neo.png +0 -0
  31. package/hub/skills/mermaid-expert/assets/examples/img/default_neo.png +0 -0
  32. package/hub/skills/mermaid-expert/assets/examples/img/forest_corp.png +0 -0
  33. package/hub/skills/mermaid-expert/assets/examples/img/handdrawn.png +0 -0
  34. package/hub/skills/mermaid-expert/assets/examples/img/neo.png +0 -0
  35. package/hub/skills/mermaid-expert/assets/examples/img/neutral_sketch.png +0 -0
  36. package/hub/skills/mermaid-expert/assets/examples/img/retro.png +0 -0
  37. package/hub/skills/mermaid-expert/assets/examples/sequence.md +116 -0
  38. package/hub/skills/mermaid-expert/assets/examples/styles_and_looks.md +102 -0
  39. package/hub/skills/mermaid-expert/assets/examples/technical.md +130 -0
  40. package/hub/skills/mermaid-expert/assets/examples.md +57 -0
  41. package/hub/skills/mermaid-expert/references/cheatsheet.md +88 -0
  42. package/hub/skills/mermaid-expert/references/validation.md +66 -0
  43. package/hub/skills/react/SKILL.md +235 -0
  44. package/hub/skills/react/references/common-mistakes.md +518 -0
  45. package/hub/skills/react/references/composition-patterns.md +526 -0
  46. package/hub/skills/react/references/effects-patterns.md +396 -0
  47. package/hub/skills/react/references/react-compiler.md +268 -0
  48. package/hub/skills/react-hook-form/SKILL.md +291 -0
  49. package/hub/skills/react-hook-form/references/field-arrays.md +98 -0
  50. package/hub/skills/react-hook-form/references/integration.md +102 -0
  51. package/hub/skills/react-hook-form/references/performance.md +96 -0
  52. package/hub/skills/skill-creator/SKILL.md +152 -0
  53. package/hub/skills/skill-creator/assets/SKILL-TEMPLATE.md +84 -0
  54. package/hub/skills/skill-judge/README.md +261 -0
  55. package/hub/skills/skill-judge/SKILL.md +806 -0
  56. package/hub/skills/tailwind/SKILL.md +200 -0
  57. package/hub/skills/tanstack/SKILL.md +284 -0
  58. package/hub/skills/tanstack/references/loader-adapter-examples.md +79 -0
  59. package/hub/skills/tanstack/references/query-options-examples.md +115 -0
  60. package/hub/skills/tanstack/references/resilience-patterns.md +110 -0
  61. package/hub/skills/tanstack/references/suspense-consumption-examples.md +82 -0
  62. package/hub/skills/tanstack-query/SKILL.md +241 -0
  63. package/hub/skills/tanstack-query/references/advanced-hooks.md +126 -0
  64. package/hub/skills/tanstack-query/references/best-practices.md +241 -0
  65. package/hub/skills/tanstack-query/references/cache-strategies.md +474 -0
  66. package/hub/skills/tanstack-query/references/common-patterns.md +239 -0
  67. package/hub/skills/tanstack-query/references/migration-v5.md +93 -0
  68. package/hub/skills/tanstack-query/references/resilience-and-mutations.md +63 -0
  69. package/hub/skills/tanstack-query/references/testing.md +116 -0
  70. package/hub/skills/tanstack-query/references/top-errors.md +148 -0
  71. package/hub/skills/tanstack-query/references/typescript.md +176 -0
  72. package/hub/skills/tanstack-router/SKILL.md +145 -0
  73. package/hub/skills/tanstack-router/references/code-splitting.md +31 -0
  74. package/hub/skills/tanstack-router/references/errors-and-boundaries.md +44 -0
  75. package/hub/skills/tanstack-router/references/loaders-and-preload.md +51 -0
  76. package/hub/skills/tanstack-router/references/navigation.md +24 -0
  77. package/hub/skills/tanstack-router/references/private-routes.md +169 -0
  78. package/hub/skills/tanstack-router/references/router-context.md +35 -0
  79. package/hub/skills/tanstack-router/references/search-params.md +29 -0
  80. package/hub/skills/tanstack-router/references/typescript.md +24 -0
  81. package/hub/skills/testing/SKILL.md +187 -0
  82. package/hub/skills/testing/references/assertions.md +64 -0
  83. package/hub/skills/testing/references/async-testing.md +66 -0
  84. package/hub/skills/testing/references/e2e-strategy.md +69 -0
  85. package/hub/skills/testing/references/layer-matrix.md +67 -0
  86. package/hub/skills/testing/references/performance.md +49 -0
  87. package/hub/skills/testing/references/tooling-map.md +81 -0
  88. package/hub/skills/testing/references/zustand-mocking.md +84 -0
  89. package/hub/skills/typescript/SKILL.md +232 -0
  90. package/hub/skills/typescript/references/perf-additional-concerns.md +248 -0
  91. package/hub/skills/typescript/references/perf-execution-cache-locality.md +178 -0
  92. package/hub/skills/typescript/references/reduce-branching.md +147 -0
  93. package/hub/skills/typescript/references/reduce-looping.md +203 -0
  94. package/hub/skills/typescript/references/style-and-types.md +171 -0
  95. package/hub/skills/typescript/references/type-vs-interface.md +27 -0
  96. package/hub/skills/zod/SKILL.md +219 -0
  97. package/hub/skills/zustand/SKILL.md +273 -0
  98. package/package.json +59 -0
  99. package/tooling/cli/src/bin.js +11 -0
  100. package/tooling/cli/src/cli.js +409 -0
  101. package/tooling/cli/src/lib/catalog-loader.js +191 -0
  102. package/tooling/cli/src/lib/constants.js +39 -0
  103. package/tooling/cli/src/lib/errors.js +8 -0
  104. package/tooling/cli/src/lib/frontmatter.js +41 -0
  105. package/tooling/cli/src/lib/fs-utils.js +77 -0
  106. package/tooling/cli/src/lib/managed-header.js +74 -0
  107. package/tooling/cli/src/lib/manifest.js +105 -0
  108. package/tooling/cli/src/lib/resolver.js +53 -0
  109. package/tooling/cli/src/lib/sync-engine.js +262 -0
@@ -0,0 +1,178 @@
1
+ # Predictable Execution and Cache Locality
2
+
3
+ ## Load Scope & Quick Navigation
4
+
5
+ Load this file for data-layout and access-pattern optimization (sequential access, struct-of-arrays, branch predictability).
6
+
7
+ Do NOT load this file for basic TS syntax, naming conventions, or type-system-only concerns.
8
+
9
+ Quick navigation:
10
+
11
+ - Access pattern choice → [Sequential vs Random Access](#sequential-vs-random-access)
12
+ - Data layout choice → [Struct-of-Arrays vs Array-of-Structs](#struct-of-arrays-vs-array-of-structs)
13
+
14
+ ## Issues
15
+
16
+ - Poor data structure layout for access pattern
17
+ - Random access patterns that could be sequential
18
+ - Struct-of-arrays vs array-of-structs mismatches
19
+ - Scattered memory access in tight loops
20
+ - Unpredictable control flow
21
+
22
+ ## Optimizations
23
+
24
+ - Sequential memory access patterns
25
+ - Group related data together
26
+ - Use flat arrays instead of nested structures
27
+ - Consider columnar layout for analytics workloads
28
+ - Write code with clear, predictable execution paths
29
+
30
+ ## Examples
31
+
32
+ ### Sequential vs Random Access
33
+
34
+ **❌ Incorrect: random access pattern**
35
+
36
+ ```ts
37
+ const users = new Map();
38
+ users.set("id1", { name: "Alice", age: 30 });
39
+ users.set("id2", { name: "Bob", age: 25 });
40
+
41
+ // Random access through Map
42
+ for (const id of shuffledIds) {
43
+ process(users.get(id));
44
+ }
45
+ ```
46
+
47
+ **✅ Correct: sequential access**
48
+
49
+ ```ts
50
+ const users = [
51
+ { id: "id1", name: "Alice", age: 30 },
52
+ { id: "id2", name: "Bob", age: 25 },
53
+ ];
54
+
55
+ // Sequential memory access
56
+ for (let i = 0; i < users.length; i++) {
57
+ process(users[i]);
58
+ }
59
+ ```
60
+
61
+ ### Struct-of-Arrays vs Array-of-Structs
62
+
63
+ **❌ Incorrect: array-of-structs for columnar access**
64
+
65
+ ```ts
66
+ const particles = [
67
+ { x: 1, y: 2, vx: 0.1, vy: 0.2 },
68
+ { x: 3, y: 4, vx: 0.3, vy: 0.4 },
69
+ // ... thousands more
70
+ ];
71
+
72
+ // Need only x coordinates - poor cache usage
73
+ for (let i = 0; i < particles.length; i++) {
74
+ updateX(particles[i].x);
75
+ }
76
+ ```
77
+
78
+ **✅ Correct: struct-of-arrays for columnar workload**
79
+
80
+ ```ts
81
+ const particles = {
82
+ x: [1, 3 /* ... */],
83
+ y: [2, 4 /* ... */],
84
+ vx: [0.1, 0.3 /* ... */],
85
+ vy: [0.2, 0.4 /* ... */],
86
+ };
87
+
88
+ // Sequential access to contiguous memory
89
+ for (let i = 0; i < particles.x.length; i++) {
90
+ updateX(particles.x[i]);
91
+ }
92
+ ```
93
+
94
+ ### Flat Arrays vs Nested Structures
95
+
96
+ **❌ Incorrect: nested object access**
97
+
98
+ ```ts
99
+ const grid = {
100
+ rows: [{ cells: [{ value: 1 }, { value: 2 }] }, { cells: [{ value: 3 }, { value: 4 }] }],
101
+ };
102
+
103
+ for (const row of grid.rows) {
104
+ for (const cell of row.cells) {
105
+ process(cell.value);
106
+ }
107
+ }
108
+ ```
109
+
110
+ **✅ Correct: flat array**
111
+
112
+ ```ts
113
+ const values = [1, 2, 3, 4];
114
+ const width = 2;
115
+
116
+ for (let i = 0; i < values.length; i++) {
117
+ process(values[i]);
118
+ }
119
+ ```
120
+
121
+ ### Group Related Data
122
+
123
+ **❌ Incorrect: scattered data access**
124
+
125
+ ```ts
126
+ const ids = [1, 2, 3];
127
+ const names = ["Alice", "Bob", "Charlie"];
128
+ const ages = [30, 25, 35];
129
+
130
+ for (let i = 0; i < ids.length; i++) {
131
+ processUser(ids[i], names[i], ages[i]);
132
+ }
133
+ ```
134
+
135
+ **✅ Correct: grouped data**
136
+
137
+ ```ts
138
+ const users = [
139
+ { id: 1, name: "Alice", age: 30 },
140
+ { id: 2, name: "Bob", age: 25 },
141
+ { id: 3, name: "Charlie", age: 35 },
142
+ ];
143
+
144
+ for (let i = 0; i < users.length; i++) {
145
+ const user = users[i];
146
+ processUser(user.id, user.name, user.age);
147
+ }
148
+ ```
149
+
150
+ ### Predictable Control Flow
151
+
152
+ **❌ Incorrect: unpredictable branches**
153
+
154
+ ```ts
155
+ function process(items) {
156
+ for (const item of items) {
157
+ if (Math.random() > 0.5) {
158
+ handleA(item);
159
+ } else {
160
+ handleB(item);
161
+ }
162
+ }
163
+ }
164
+ ```
165
+
166
+ **✅ Correct: predictable branches**
167
+
168
+ ```ts
169
+ function process(items) {
170
+ for (const item of items) {
171
+ if (item.type === "A") {
172
+ handleA(item);
173
+ } else {
174
+ handleB(item);
175
+ }
176
+ }
177
+ }
178
+ ```
@@ -0,0 +1,147 @@
1
+ # Reduce Branching
2
+
3
+ ## Load Scope & Quick Navigation
4
+
5
+ Load this file when conditionals/switches are deeply nested or repeated and control flow dominates complexity.
6
+
7
+ Do NOT load this file when the primary issue is array pass count or cache-locality/data-layout concerns.
8
+
9
+ Quick navigation:
10
+
11
+ - Replace conditional chains → [Switch to Lookup Table](#switch-to-lookup-table)
12
+ - Flatten deep nesting → [Nested Conditionals to Early Returns](#nested-conditionals-to-early-returns)
13
+
14
+ ## Issues
15
+
16
+ - Excessive nested conditionals (>3 levels)
17
+ - Switch statements that could be lookup tables
18
+ - Repeated condition checks in same scope
19
+ - Polymorphic branching on hot paths
20
+ - Type guards that could be avoided
21
+
22
+ ## Optimizations
23
+
24
+ - Convert switch/if-chains to object/Map lookups
25
+ - Hoist invariant conditions
26
+ - Use early returns to reduce nesting
27
+ - Replace runtime type checks with compile-time guarantees
28
+
29
+ ## Examples
30
+
31
+ ### Switch to Lookup Table
32
+
33
+ **❌ Incorrect: conditional checks**
34
+
35
+ ```ts
36
+ if (thing === "ONE") {
37
+ /*...*/
38
+ }
39
+
40
+ if (thing === "TWO") {
41
+ /*...*/
42
+ }
43
+
44
+ if (thing === "THREE") {
45
+ /*...*/
46
+ }
47
+ ```
48
+
49
+ **✅ Correct: lookup table**
50
+
51
+ ```ts
52
+ const lookup = {
53
+ ONE: {
54
+ /*...*/
55
+ },
56
+ TWO: {
57
+ /*...*/
58
+ },
59
+ THREE: {
60
+ /*...*/
61
+ },
62
+ };
63
+
64
+ const action = lookup[thing];
65
+ ```
66
+
67
+ ### Nested Conditionals to Early Returns
68
+
69
+ **❌ Incorrect: excessive nesting**
70
+
71
+ ```ts
72
+ function process(data) {
73
+ if (data) {
74
+ if (data.isValid) {
75
+ if (data.user) {
76
+ if (data.user.hasPermission) {
77
+ return doWork(data);
78
+ }
79
+ }
80
+ }
81
+ }
82
+ return null;
83
+ }
84
+ ```
85
+
86
+ **✅ Correct: early returns**
87
+
88
+ ```ts
89
+ function process(data) {
90
+ if (!data) return null;
91
+ if (!data.isValid) return null;
92
+ if (!data.user) return null;
93
+ if (!data.user.hasPermission) return null;
94
+
95
+ return doWork(data);
96
+ }
97
+ ```
98
+
99
+ ### Hoist Invariant Conditions
100
+
101
+ **❌ Incorrect: repeated checks**
102
+
103
+ ```ts
104
+ for (const item of items) {
105
+ if (config.enableFeature && item.active) {
106
+ process(item);
107
+ }
108
+ }
109
+ ```
110
+
111
+ **✅ Correct: hoist invariant**
112
+
113
+ ```ts
114
+ if (config.enableFeature) {
115
+ for (const item of items) {
116
+ if (item.active) {
117
+ process(item);
118
+ }
119
+ }
120
+ }
121
+ ```
122
+
123
+ ### Runtime Type Checks to Compile-Time
124
+
125
+ **❌ Incorrect: runtime branching**
126
+
127
+ ```ts
128
+ function format(value: string | number) {
129
+ if (typeof value === "string") {
130
+ return value.toUpperCase();
131
+ } else {
132
+ return value.toFixed(2);
133
+ }
134
+ }
135
+ ```
136
+
137
+ **✅ Correct: separate functions**
138
+
139
+ ```ts
140
+ function formatString(value: string): string {
141
+ return value.toUpperCase();
142
+ }
143
+
144
+ function formatNumber(value: number): string {
145
+ return value.toFixed(2);
146
+ }
147
+ ```
@@ -0,0 +1,203 @@
1
+ # Reduce Looping
2
+
3
+ ## Load Scope & Quick Navigation
4
+
5
+ Load this file when performance issues come from extra collection passes, repeated lookups, or nested iterations.
6
+
7
+ Do NOT load this file for branching structure redesign or type-modeling decisions.
8
+
9
+ Quick navigation:
10
+
11
+ - Collapse chained passes → [Chained Methods to Single Reduce](#chained-methods-to-single-reduce)
12
+ - Replace repeated O(n) checks → [Linear Search to O(1) Lookup](#linear-search-to-o1-lookup)
13
+ - Remove nested loop-side filtering → [Array Methods in Loops](#array-methods-in-loops)
14
+
15
+ ## Issues
16
+
17
+ - Multiple passes over same array (`.map().filter().reduce()`)
18
+ - Unnecessary array creation (spreading, slicing)
19
+ - Array methods in loops
20
+ - Linear searches that could use Sets/Maps
21
+ - Incorrect collection type for access pattern
22
+
23
+ ## Optimizations
24
+
25
+ - Combine multiple array operations into single pass
26
+ - Use index-based loops for performance-critical paths
27
+ - Replace O(n) lookups with O(1) using Set/Map
28
+ - Use typed arrays for numeric data
29
+ - Reuse arrays when function owns them (local scope, not returned/exposed)
30
+
31
+ ## Examples
32
+
33
+ ### Chained Methods to Single Reduce
34
+
35
+ **❌ Incorrect: two iterations**
36
+
37
+ ```ts
38
+ const result = arr.filter(predicate).map(mapper);
39
+ ```
40
+
41
+ **✅ Correct: single iteration**
42
+
43
+ ```ts
44
+ const result = arr.reduce((acc, curr) => (predicate(curr) ? [...acc, mapper(curr)] : acc), []);
45
+ ```
46
+
47
+ ### Linear Search to O(1) Lookup
48
+
49
+ **❌ Incorrect: O(n)**
50
+
51
+ ```ts
52
+ const keys = Object.keys(someObj);
53
+ if (keys.includes(id)) {
54
+ /**/
55
+ }
56
+ ```
57
+
58
+ **✅ Correct: O(1)**
59
+
60
+ ```ts
61
+ const keys = new Set(Object.keys(someObj));
62
+ if (keys.has(id)) {
63
+ /**/
64
+ }
65
+ ```
66
+
67
+ ### Array Methods in Loops
68
+
69
+ **❌ Incorrect: nested iterations**
70
+
71
+ ```ts
72
+ for (const user of users) {
73
+ const active = items.filter((item) => item.userId === user.id);
74
+ process(active);
75
+ }
76
+ ```
77
+
78
+ **✅ Correct: build lookup once**
79
+
80
+ ```ts
81
+ const itemsByUser = new Map();
82
+ for (const item of items) {
83
+ if (!itemsByUser.has(item.userId)) {
84
+ itemsByUser.set(item.userId, []);
85
+ }
86
+ itemsByUser.get(item.userId).push(item);
87
+ }
88
+
89
+ for (const user of users) {
90
+ const active = itemsByUser.get(user.id) || [];
91
+ process(active);
92
+ }
93
+ ```
94
+
95
+ ### Build Index Maps for Repeated Lookups
96
+
97
+ **❌ Incorrect: (O(n) per lookup)**
98
+
99
+ ```ts
100
+ function processOrders(orders: Order[], users: User[]) {
101
+ return orders.map((order) => ({
102
+ ...order,
103
+ user: users.find((u) => u.id === order.userId),
104
+ }));
105
+ }
106
+ ```
107
+
108
+ **✅ Correct: (O(1) per lookup)**
109
+
110
+ ```ts
111
+ function processOrders(orders: Order[], users: User[]) {
112
+ const userById = new Map(users.map((u) => [u.id, u]));
113
+
114
+ return orders.map((order) => ({
115
+ ...order,
116
+ user: userById.get(order.userId),
117
+ }));
118
+ }
119
+ ```
120
+
121
+ ### Combine Multiple Array Iterations
122
+
123
+ > Multiple .filter() or .map() calls iterate the array multiple times. Combine into one loop.
124
+
125
+ **❌ Incorrect: 3 iterations**`
126
+
127
+ ```ts
128
+ const admins = users.filter((u) => u.isAdmin);
129
+ const testers = users.filter((u) => u.isTester);
130
+ const inactive = users.filter((u) => !u.isActive);
131
+ ```
132
+
133
+ **✅ Correct: 1 iteration**
134
+
135
+ ```ts
136
+ const admins: User[] = [];
137
+ const testers: User[] = [];
138
+ const inactive: User[] = [];
139
+
140
+ for (const user of users) {
141
+ if (user.isAdmin) admins.push(user);
142
+ if (user.isTester) testers.push(user);
143
+ if (!user.isActive) inactive.push(user);
144
+ }
145
+ ```
146
+
147
+ ### Unnecessary Array Creation
148
+
149
+ **❌ Incorrect: creates intermediate arrays**
150
+
151
+ ```ts
152
+ const result = [...arr].slice(0, 10).map(transform);
153
+ ```
154
+
155
+ **✅ Correct: process directly**
156
+
157
+ ```ts
158
+ const result = [];
159
+ const len = Math.min(arr.length, 10);
160
+ for (let i = 0; i < len; i++) {
161
+ result.push(transform(arr[i]));
162
+ }
163
+ ```
164
+
165
+ ### Index-Based Loops for Hot Paths
166
+
167
+ **❌ Incorrect: slower iteration**
168
+
169
+ ```ts
170
+ for (const item of largeArray) {
171
+ // performance-critical operation
172
+ processPixel(item);
173
+ }
174
+ ```
175
+
176
+ **✅ Correct: index-based**
177
+
178
+ ```ts
179
+ const len = largeArray.length;
180
+ for (let i = 0; i < len; i++) {
181
+ processPixel(largeArray[i]);
182
+ }
183
+ ```
184
+
185
+ ### Typed Arrays for Numeric Data
186
+
187
+ **❌ Incorrect: generic array**
188
+
189
+ ```ts
190
+ const pixels = new Array(width * height);
191
+ for (let i = 0; i < pixels.length; i++) {
192
+ pixels[i] = Math.random() * 255;
193
+ }
194
+ ```
195
+
196
+ **✅ Correct: typed array**
197
+
198
+ ```ts
199
+ const pixels = new Uint8Array(width * height);
200
+ for (let i = 0; i < pixels.length; i++) {
201
+ pixels[i] = Math.random() * 255;
202
+ }
203
+ ```
@@ -0,0 +1,171 @@
1
+ # TypeScript Style & Typing Notes
2
+
3
+ ## Load Scope & Quick Navigation
4
+
5
+ Load this file for naming conventions, `satisfies` vs `as const`, baseline utility types, type guards, and `import type` usage.
6
+
7
+ Do NOT load this file for branch/loop performance diagnostics when dedicated perf references are required.
8
+
9
+ Quick navigation:
10
+
11
+ - Naming/casing guidance → [Naming Conventions (Casing)](#naming-conventions-casing)
12
+ - `as const` vs `satisfies` tradeoffs → [as const vs satisfies](#as-const-vs-satisfies)
13
+ - Utility types cheat sheet → [Utility Types](#utility-types)
14
+ - Type guards baseline → [Type Guards](#type-guards)
15
+ - Type-only imports → [Import Types](#import-types)
16
+
17
+ ## Naming Conventions (Casing)
18
+
19
+ Use a single, consistent casing strategy by context. Avoid mixing styles in the same scope unless required by external systems.
20
+
21
+ ### Recommended Usage
22
+
23
+ - **camelCase**: variables, functions, methods, local state, parameters.
24
+ - **PascalCase**: types, interfaces, classes, React components.
25
+ - **kebab-case**: URLs, route segments, file names for static assets.
26
+ - **snake_case**: avoid in TS/JS; only for external APIs or database schemas.
27
+
28
+ ### Examples
29
+
30
+ ```ts
31
+ // camelCase
32
+ const userId = "123";
33
+ function getUserById(id: string) {}
34
+
35
+ // PascalCase
36
+ type UserId = string;
37
+ interface UserProfile {}
38
+ class UserService {}
39
+
40
+ // kebab-case (URLs)
41
+ // /user-profile/123
42
+
43
+ // snake_case (external APIs / DB fields)
44
+ interface UserApiResponse {
45
+ user_id: string;
46
+ created_at: string;
47
+ }
48
+ ```
49
+
50
+ ### Interop Guidance
51
+
52
+ When consuming snake_case data from APIs, map to camelCase at the boundary (infrastructure layer) so the rest of the app remains consistent.
53
+
54
+ ---
55
+
56
+ ## `as const` vs `satisfies`
57
+
58
+ ### Summary
59
+
60
+ - **`as const`**: narrows literals and makes values deeply readonly.
61
+ - **`satisfies`**: validates the shape while preserving the most specific inferred type.
62
+ - **Combine both** when you need immutability **and** validation.
63
+
64
+ ### Practical Differences
65
+
66
+ ```ts
67
+ interface Theme {
68
+ colors: Record<string, string>;
69
+ spacing: Record<string, number>;
70
+ }
71
+
72
+ // ✅ Validate shape + keep exact keys
73
+ const theme = {
74
+ colors: { primary: "#3b82f6", secondary: "#10b981" },
75
+ spacing: { sm: 8, md: 16, lg: 24 },
76
+ } satisfies Theme;
77
+
78
+ // ✅ Immutable + validated
79
+ const themeConst = {
80
+ colors: { primary: "#3b82f6", secondary: "#10b981" },
81
+ spacing: { sm: 8, md: 16, lg: 24 },
82
+ } as const satisfies Theme;
83
+
84
+ // ⚠️ `as const` only (no validation)
85
+ const themeOnlyConst = {
86
+ colors: { primary_typo: "#3b82f6" },
87
+ spacing: { sm: 8 },
88
+ } as const;
89
+ ```
90
+
91
+ ### Common Pitfall
92
+
93
+ Avoid `const x: Type = ...` for config objects because the type annotation widens literals and erases exact keys. Prefer `satisfies` so typos are caught at compile time while keeping precise inference.
94
+
95
+ ---
96
+
97
+ ## Avoid TypeScript `enum`
98
+
99
+ ### Why
100
+
101
+ - Adds runtime artifacts and non-idiomatic JS behavior.
102
+ - Creates tight coupling to enum members instead of values.
103
+ - Reduces flexibility when interoperating with plain strings.
104
+
105
+ ### Preferred Alternatives
106
+
107
+ #### 1) Const object + derived union (recommended)
108
+
109
+ ```ts
110
+ const ROLE = {
111
+ ADMIN: "ADMIN",
112
+ USER: "USER",
113
+ GUEST: "GUEST",
114
+ } as const;
115
+
116
+ type Role = (typeof ROLE)[keyof typeof ROLE];
117
+
118
+ function setRole(role: Role) {}
119
+
120
+ setRole(ROLE.ADMIN);
121
+ setRole("ADMIN");
122
+ ```
123
+
124
+ #### 2) Literal union (small sets)
125
+
126
+ ```ts
127
+ type Size = "sm" | "md" | "lg";
128
+ ```
129
+
130
+ ### Avoid
131
+
132
+ ```ts
133
+ enum RoleEnum {
134
+ ADMIN = "ADMIN",
135
+ USER = "USER",
136
+ GUEST = "GUEST",
137
+ }
138
+ ```
139
+
140
+ ---
141
+
142
+ ## Utility Types
143
+
144
+ ```ts
145
+ Pick<User, "id" | "name">; // Select fields
146
+ Omit<User, "id">; // Exclude fields
147
+ Partial<User>; // All optional
148
+ Required<User>; // All required
149
+ Readonly<User>; // All readonly
150
+ Record<string, User>; // Object type
151
+ Extract<Union, "a" | "b">; // Extract from union
152
+ Exclude<Union, "a">; // Exclude from union
153
+ NonNullable<T | null>; // Remove null/undefined
154
+ ReturnType<typeof fn>; // Function return type
155
+ Parameters<typeof fn>; // Function params tuple
156
+ ```
157
+
158
+ ## Type Guards
159
+
160
+ ```ts
161
+ function isUser(value: unknown): value is User {
162
+ return typeof value === "object" && value !== null && "id" in value && "name" in value;
163
+ }
164
+ ```
165
+
166
+ ## Import Types
167
+
168
+ ```ts
169
+ import type { User } from "./types";
170
+ import { type Config, createUser } from "./utils";
171
+ ```
@@ -0,0 +1,27 @@
1
+ # Type vs. Interface
2
+
3
+ ## Load Scope & Quick Navigation
4
+
5
+ Load this file when deciding modeling strategy for aliases/unions/intersections versus class/declaration-merging contracts.
6
+
7
+ Do NOT load this file for runtime performance tuning.
8
+
9
+ Prefer `type` over `interface` for type aliases, unions, intersections, branded types, and functional patterns. Use `interface` only when you absolutely need:
10
+
11
+ - Declaration merging (intentional extensibility)
12
+ - Class implementation contracts (`implements`)
13
+ - Legacy API compatibility
14
+
15
+ **❌ Incorrect: interface not preferred for use case**
16
+
17
+ ```ts
18
+ interface AvatarProps {
19
+ avatar: string;
20
+ }
21
+ ```
22
+
23
+ **✅ Correct: type preferred for use case**
24
+
25
+ ```ts
26
+ type AvatarProps = { avatar: string };
27
+ ```