@vpxa/aikit 0.1.308 → 0.1.309
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.
- package/package.json +1 -1
- package/packages/cli/dist/index.js +3 -3
- package/packages/cli/dist/{init-CyjUXjQw.js → init-VP9ig7OK.js} +1 -1
- package/packages/cli/dist/{templates-BQ1J4HzY.js → templates-WsJg6Pkc.js} +5 -5
- package/packages/server/dist/bin.js +1 -1
- package/packages/server/dist/index.js +1 -1
- package/packages/server/dist/repair-json-B6Q_HRoP.js +3 -0
- package/packages/server/dist/repair-json-D4mft_HA.js +4 -0
- package/packages/server/dist/{server-D6sJEw0I.js → server-DZKWh8ZG.js} +162 -164
- package/packages/server/dist/{server-BSvqfFcK.js → server-RV1UYywi.js} +162 -164
- package/packages/server/dist/{server-http-B1ixOw2x.js → server-http-DeWcQphZ.js} +1 -1
- package/packages/server/dist/{server-http-BurquBLf.js → server-http-Dk16rq4T.js} +1 -1
- package/packages/server/dist/server-stdio-Bx_Aa99F.js +1 -0
- package/packages/server/dist/server-stdio-CebgeeBc.js +2 -0
- package/scaffold/INSTRUCTIONS.md +273 -0
- package/scaffold/dist/adapters/copilot.mjs +2 -9
- package/scaffold/dist/adapters/hermes-agent.mjs +2 -2
- package/scaffold/dist/adapters/hermes.mjs +8 -4
- package/scaffold/dist/adapters/intellij.mjs +7 -3
- package/scaffold/dist/adapters/skills.mjs +3 -1
- package/scaffold/dist/adapters/zed.mjs +6 -2
- package/scaffold/dist/definitions/agents.mjs +2 -2
- package/scaffold/dist/definitions/bodies.mjs +95 -366
- package/scaffold/dist/definitions/protocols.mjs +117 -556
- package/scaffold/dist/definitions/skills/adr-skill.mjs +41 -197
- package/scaffold/dist/definitions/skills/aikit.mjs +52 -205
- package/scaffold/dist/definitions/skills/brainstorming.mjs +74 -112
- package/scaffold/dist/definitions/skills/browser-use.mjs +128 -184
- package/scaffold/dist/definitions/skills/c4-architecture.mjs +45 -106
- package/scaffold/dist/definitions/skills/docs.mjs +70 -214
- package/scaffold/dist/definitions/skills/frontend-design.mjs +96 -193
- package/scaffold/dist/definitions/skills/lesson-learned.mjs +57 -184
- package/scaffold/dist/definitions/skills/multi-agents-development.mjs +98 -408
- package/scaffold/dist/definitions/skills/present.mjs +193 -1
- package/scaffold/dist/definitions/skills/react.mjs +68 -111
- package/scaffold/dist/definitions/skills/repo-access.mjs +24 -169
- package/scaffold/dist/definitions/skills/requirements-clarity.mjs +45 -94
- package/scaffold/dist/definitions/skills/typescript.mjs +162 -230
- package/packages/server/dist/server-stdio-CBmXDMpq.js +0 -1
- package/packages/server/dist/server-stdio-z3_zG1HF.js +0 -2
|
@@ -12,125 +12,85 @@ metadata:
|
|
|
12
12
|
|
|
13
13
|
# TypeScript
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Use for TypeScript implementation/review, public APIs, type safety, compiler config, async/runtime boundaries, and type-check performance.
|
|
16
16
|
|
|
17
17
|
## Mindset
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
Types are executable contracts. Prefer designs where invalid states cannot be expressed, but keep types readable and fast enough for humans and compiler.
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
## Core Rules
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
- Avoid any in exported signatures; use unknown, generics, unions, and narrowing.
|
|
24
|
+
- Avoid as to silence errors; use guards/assertion fns or fix upstream types. Test mocks may use contained as unknown as T.
|
|
25
|
+
- Avoid non-null ! without runtime guard.
|
|
26
|
+
- Prefer undefined for optional/missing and null for explicit empty; follow repo convention.
|
|
27
|
+
- Prefer as const objects or literal unions over new enum usage.
|
|
28
|
+
- Export readonly/public types when mutation is not part of contract.
|
|
29
|
+
- Keep runtime validation at trust boundaries; TypeScript does not validate external data.
|
|
24
30
|
|
|
25
|
-
|
|
26
|
-
- Writing or reviewing TypeScript code
|
|
27
|
-
- Configuring \`tsconfig.json\` or compiler options
|
|
28
|
-
- Designing type-safe APIs, libraries, or utilities
|
|
29
|
-
- Optimizing type-check performance or build times
|
|
31
|
+
## Compiler Config
|
|
30
32
|
|
|
31
|
-
|
|
33
|
+
Baseline for app/library code:
|
|
34
|
+
- strict, noUncheckedIndexedAccess, exactOptionalPropertyTypes, noFallthroughCasesInSwitch.
|
|
35
|
+
- isolatedModules and verbatimModuleSyntax for modern bundlers.
|
|
36
|
+
- incremental for local speed; composite/declaration/declarationMap for referenced packages.
|
|
37
|
+
- skipLibCheck acceptable for apps; be stricter for published libs when feasible.
|
|
32
38
|
|
|
33
|
-
|
|
34
|
-
- **NEVER use \`any\` in exported signatures** — it infects every consumer. Use \`unknown\` + narrowing, generics, or explicit union types. \`any\` in implementation internals is tolerable if contained.
|
|
35
|
-
- **NEVER use \`!\` (non-null assertion) without a runtime guard** — it's a lie to the compiler. If you're sure it's not null, prove it with an \`if\` check or \`?? throw\`.
|
|
36
|
-
- **NEVER mix null and undefined semantics** — pick one convention per codebase. Prefer \`undefined\` for "not set" (matches optional properties), \`null\` for "explicitly empty" (matches DOM/JSON).
|
|
37
|
-
- **NEVER export mutable state as a shared type** — use \`readonly\` modifier, \`Readonly<T>\`, or \`ReadonlyArray<T>\`. Mutable shared state causes action-at-a-distance bugs that types cannot catch.
|
|
38
|
-
- **NEVER use \`enum\` in new code** — use \`as const\` objects or string literal unions. Enums have runtime cost, tree-shaking issues, and numeric enums allow unsafe access.
|
|
39
|
-
- **NEVER ignore generic constraints** — if a function works on "any array", type it as \`T extends readonly unknown[]\`, not \`T[]\`. Constraints document intent and catch misuse at call sites.
|
|
39
|
+
## Type Design
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
Use:
|
|
42
|
+
- Discriminated unions for variants/state machines.
|
|
43
|
+
- Exhaustive never checks in switches.
|
|
44
|
+
- Branded types for semantically different IDs/strings.
|
|
45
|
+
- Result<T, E> or explicit error unions when callers must handle failure.
|
|
46
|
+
- interface extends for object extension; type for unions/mapped/conditional types.
|
|
47
|
+
- satisfies to check object shape while preserving literal types.
|
|
42
48
|
|
|
43
|
-
|
|
49
|
+
Avoid:
|
|
50
|
+
- Deep recursive conditional types in hot paths.
|
|
51
|
+
- Giant inferred return types on exported fns.
|
|
52
|
+
- Generic APIs without constraints.
|
|
53
|
+
- Ambient globals unless truly platform-level.
|
|
44
54
|
|
|
45
|
-
|
|
46
|
-
\`\`\`tsx
|
|
47
|
-
// BAD — O(n²) type checking with deep conditionals
|
|
48
|
-
type DeepResolve<T> = T extends Promise<infer U> ? DeepResolve<U> : T extends Array<infer V> ? DeepResolve<V>[] : T;
|
|
55
|
+
## Performance
|
|
49
56
|
|
|
50
|
-
|
|
51
|
-
type Status = "idle" | "loading" | "success" | "error";
|
|
52
|
-
type Result = SuccessResult | ErrorResult | PendingResult;
|
|
53
|
-
\`\`\`
|
|
57
|
+
Slow typechecking signs: deep conditional recursion, huge unions, circular references, inferred public return types, mapped types over broad keys.
|
|
54
58
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
+
Fix order:
|
|
60
|
+
1. Annotate public/complex returns.
|
|
61
|
+
2. Flatten unions and split types.
|
|
62
|
+
3. Replace intersections of object shapes with interfaces.
|
|
63
|
+
4. Limit recursion depth or move complexity to runtime validation.
|
|
64
|
+
5. Use project references for package boundaries.
|
|
59
65
|
|
|
60
|
-
|
|
61
|
-
interface Extended extends BaseType {
|
|
62
|
-
extra: string;
|
|
63
|
-
more: number;
|
|
64
|
-
}
|
|
65
|
-
\`\`\`
|
|
66
|
+
## Async + Runtime Boundaries
|
|
66
67
|
|
|
67
|
-
|
|
68
|
-
-
|
|
69
|
-
-
|
|
70
|
-
-
|
|
71
|
-
-
|
|
72
|
-
- **Avoid generic defaults that trigger deep inference** — provide explicit type arguments at call sites
|
|
73
|
-
- **Break circular type references** — extract shared shapes into separate interfaces
|
|
68
|
+
- Model loading/error/empty states explicitly.
|
|
69
|
+
- Parse external input with schema/guard before trusting it.
|
|
70
|
+
- Preserve causes when wrapping errors.
|
|
71
|
+
- Type async cancellation/timeouts explicitly when API supports them.
|
|
72
|
+
- Keep JSON-compatible types separate from rich runtime objects.
|
|
74
73
|
|
|
75
|
-
##
|
|
74
|
+
## Module Hygiene
|
|
76
75
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
"strict": true, // Enables ALL strict checks
|
|
82
|
-
"noUncheckedIndexedAccess": true, // arr[0] is T | undefined
|
|
83
|
-
"exactOptionalProperties": true, // undefined ≠ missing
|
|
84
|
-
"noFallthroughCasesInSwitch": true,
|
|
85
|
-
"forceConsistentCasingInFileNames": true,
|
|
86
|
-
"isolatedModules": true, // Required for most bundlers
|
|
87
|
-
"verbatimModuleSyntax": true // Explicit import/export type
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
\`\`\`
|
|
76
|
+
- Use import type / export type for type-only edges.
|
|
77
|
+
- Avoid barrel files that create cycles or hide heavy imports.
|
|
78
|
+
- Keep public API types stable; changing exported shapes is a contract change.
|
|
79
|
+
- Match repo path alias/import convention; do not invent one.
|
|
91
80
|
|
|
92
|
-
|
|
93
|
-
\`\`\`jsonc
|
|
94
|
-
{
|
|
95
|
-
"compilerOptions": {
|
|
96
|
-
"incremental": true, // Cache type-check results
|
|
97
|
-
"tsBuildInfoFile": ".tsbuildinfo",
|
|
98
|
-
"skipLibCheck": true // Skip .d.ts checking (safe for apps)
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
\`\`\`
|
|
81
|
+
## Validation Before Done
|
|
102
82
|
|
|
103
|
-
|
|
104
|
-
\`\`\`jsonc
|
|
105
|
-
// tsconfig.json (root)
|
|
106
|
-
{
|
|
107
|
-
"references": [
|
|
108
|
-
{ "path": "packages/core" },
|
|
109
|
-
{ "path": "packages/server" },
|
|
110
|
-
{ "path": "packages/cli" }
|
|
111
|
-
]
|
|
112
|
-
}
|
|
83
|
+
Run check({}) or tsc --noEmit equivalent, plus relevant tests. For type-only changes, add compile-time assertions or tests where repo patterns support them.
|
|
113
84
|
|
|
114
|
-
|
|
115
|
-
{
|
|
116
|
-
"compilerOptions": {
|
|
117
|
-
"composite": true,
|
|
118
|
-
"declaration": true,
|
|
119
|
-
"declarationMap": true
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
\`\`\`
|
|
85
|
+
## References
|
|
123
86
|
|
|
124
|
-
|
|
125
|
-
-
|
|
126
|
-
-
|
|
127
|
-
-
|
|
128
|
-
- **\`--stableTypeOrdering\`**: Deterministic declaration output for reproducible builds
|
|
129
|
-
- **\`isolatedDeclarations\`**: Generate \`.d.ts\` without type-checking — enables parallel builds
|
|
87
|
+
Load on demand:
|
|
88
|
+
- references/advanced-types.md — Conditional types, mapped types, template literal types, utility patterns with code examples.
|
|
89
|
+
- references/patterns-and-perf.md — Type system performance rules, compiler config details, never rules, async/runtime module patterns.
|
|
90
|
+
`},{file:`references/advanced-types.md`,content:`# Advanced Types
|
|
130
91
|
|
|
131
|
-
##
|
|
92
|
+
## Constrained Generics
|
|
132
93
|
|
|
133
|
-
### Constrained Generics
|
|
134
94
|
\`\`\`tsx
|
|
135
95
|
// Constrain to ensure property exists
|
|
136
96
|
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
|
|
@@ -143,7 +103,8 @@ function merge<T extends Record<string, unknown>>(target: T, source: Partial<T>)
|
|
|
143
103
|
}
|
|
144
104
|
\`\`\`
|
|
145
105
|
|
|
146
|
-
|
|
106
|
+
## Conditional Types
|
|
107
|
+
|
|
147
108
|
\`\`\`tsx
|
|
148
109
|
// Extract return type from async function
|
|
149
110
|
type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;
|
|
@@ -155,7 +116,8 @@ type NonNullableDeep<T> = T extends null | undefined ? never : T extends object
|
|
|
155
116
|
type Parameters<T> = T extends (...args: infer P) => unknown ? P : never;
|
|
156
117
|
\`\`\`
|
|
157
118
|
|
|
158
|
-
|
|
119
|
+
## Mapped Types
|
|
120
|
+
|
|
159
121
|
\`\`\`tsx
|
|
160
122
|
// Make all properties optional recursively
|
|
161
123
|
type DeepPartial<T> = { [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P] };
|
|
@@ -167,7 +129,8 @@ type Mutable<T> = { -readonly [P in keyof T]: T[P] };
|
|
|
167
129
|
type Getters<T> = { [K in keyof T as \`get\${Capitalize<string & K>}\`]: () => T[K] };
|
|
168
130
|
\`\`\`
|
|
169
131
|
|
|
170
|
-
|
|
132
|
+
## Template Literal Types
|
|
133
|
+
|
|
171
134
|
\`\`\`tsx
|
|
172
135
|
// Event name typing
|
|
173
136
|
type EventName<T extends string> = \`on\${Capitalize<T>}\`;
|
|
@@ -183,7 +146,8 @@ type ExtractParams<T extends string> =
|
|
|
183
146
|
type Params = ExtractParams<"/users/:id/posts/:postId">; // "id" | "postId"
|
|
184
147
|
\`\`\`
|
|
185
148
|
|
|
186
|
-
|
|
149
|
+
## Utility Type Patterns
|
|
150
|
+
|
|
187
151
|
\`\`\`tsx
|
|
188
152
|
// Deep readonly
|
|
189
153
|
type DeepReadonly<T> = { readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P] };
|
|
@@ -199,9 +163,8 @@ type Paths<T, D extends number = 3> = [D] extends [never]
|
|
|
199
163
|
: never;
|
|
200
164
|
\`\`\`
|
|
201
165
|
|
|
202
|
-
##
|
|
166
|
+
## Branded Types
|
|
203
167
|
|
|
204
|
-
### Branded Types
|
|
205
168
|
\`\`\`tsx
|
|
206
169
|
// Prevent mixing IDs of different entities
|
|
207
170
|
type UserId = string & { readonly __brand: "UserId" };
|
|
@@ -214,7 +177,8 @@ function getUser(id: UserId) { /* ... */ }
|
|
|
214
177
|
getUser(createOrderId("123")); // TS Error! OrderId is not UserId
|
|
215
178
|
\`\`\`
|
|
216
179
|
|
|
217
|
-
|
|
180
|
+
## Discriminated Unions with Exhaustive Matching
|
|
181
|
+
|
|
218
182
|
\`\`\`tsx
|
|
219
183
|
type Shape =
|
|
220
184
|
| { kind: "circle"; radius: number }
|
|
@@ -234,7 +198,8 @@ function area(shape: Shape): number {
|
|
|
234
198
|
}
|
|
235
199
|
\`\`\`
|
|
236
200
|
|
|
237
|
-
|
|
201
|
+
## Result Pattern
|
|
202
|
+
|
|
238
203
|
\`\`\`tsx
|
|
239
204
|
type Result<T, E = Error> = { ok: true; value: T } | { ok: false; error: E };
|
|
240
205
|
|
|
@@ -258,165 +223,132 @@ if (!result.ok) {
|
|
|
258
223
|
}
|
|
259
224
|
const config = result.value; // Type-narrowed to Config
|
|
260
225
|
\`\`\`
|
|
226
|
+
`},{file:`references/patterns-and-perf.md`,content:`# TypeScript Patterns and Performance
|
|
261
227
|
|
|
262
|
-
##
|
|
263
|
-
|
|
264
|
-
### Parallel Execution
|
|
265
|
-
\`\`\`tsx
|
|
266
|
-
// Promise.all — fail-fast on first rejection
|
|
267
|
-
const [users, posts] = await Promise.all([getUsers(), getPosts()]);
|
|
268
|
-
|
|
269
|
-
// Promise.allSettled — get all results regardless of failures
|
|
270
|
-
const results = await Promise.allSettled([getUsers(), getPosts(), getComments()]);
|
|
271
|
-
for (const r of results) {
|
|
272
|
-
if (r.status === "fulfilled") process(r.value);
|
|
273
|
-
else logError(r.reason);
|
|
274
|
-
}
|
|
275
|
-
\`\`\`
|
|
228
|
+
## Type System Performance
|
|
276
229
|
|
|
277
|
-
|
|
278
|
-
\`\`\`tsx
|
|
279
|
-
async function fetchWithTimeout(url: string, timeoutMs: number): Promise<Response> {
|
|
280
|
-
const controller = new AbortController();
|
|
281
|
-
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
282
|
-
try {
|
|
283
|
-
return await fetch(url, { signal: controller.signal });
|
|
284
|
-
} finally {
|
|
285
|
-
clearTimeout(timeout);
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
\`\`\`
|
|
230
|
+
Prefer flat unions over deep conditional types. Deep conditionals are O(n^2) in the checker.
|
|
289
231
|
|
|
290
|
-
### Async Iterators
|
|
291
232
|
\`\`\`tsx
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
while (true) {
|
|
295
|
-
const items = await fetcher(page++);
|
|
296
|
-
if (items.length === 0) break;
|
|
297
|
-
yield* items;
|
|
298
|
-
}
|
|
299
|
-
}
|
|
233
|
+
// BAD — deep conditional
|
|
234
|
+
type DeepResolve<T> = T extends Promise<infer U> ? DeepResolve<U> : T extends Array<infer V> ? DeepResolve<V>[] : T;
|
|
300
235
|
|
|
301
|
-
//
|
|
302
|
-
|
|
303
|
-
processUser(user);
|
|
304
|
-
}
|
|
236
|
+
// GOOD — flat unions check in O(n)
|
|
237
|
+
type Status = "idle" | "loading" | "success" | "error";
|
|
305
238
|
\`\`\`
|
|
306
239
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
### Barrel File Performance
|
|
310
|
-
\`\`\`tsx
|
|
311
|
-
// BAD — barrel files cause entire module tree to load
|
|
312
|
-
// index.ts
|
|
313
|
-
export * from "./userService";
|
|
314
|
-
export * from "./orderService";
|
|
315
|
-
export * from "./paymentService";
|
|
316
|
-
|
|
317
|
-
// GOOD — direct imports skip barrel overhead
|
|
318
|
-
import { UserService } from "./services/userService";
|
|
319
|
-
\`\`\`
|
|
240
|
+
Prefer interface extends over intersection types for object shapes:
|
|
320
241
|
|
|
321
|
-
### Type-Only Imports
|
|
322
242
|
\`\`\`tsx
|
|
323
|
-
//
|
|
324
|
-
|
|
325
|
-
import { UserService } from "./userService";
|
|
326
|
-
// With verbatimModuleSyntax, this is enforced
|
|
327
|
-
\`\`\`
|
|
243
|
+
// BAD — intersection types are expensive to compute
|
|
244
|
+
type Extended = BaseType & { extra: string } & { more: number };
|
|
328
245
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
// Don't export internal implementation details
|
|
246
|
+
// GOOD — interface extends is cached by the compiler
|
|
247
|
+
interface Extended extends BaseType {
|
|
248
|
+
extra: string;
|
|
249
|
+
more: number;
|
|
250
|
+
}
|
|
335
251
|
\`\`\`
|
|
336
252
|
|
|
337
|
-
|
|
253
|
+
### Performance Rules
|
|
254
|
+
- Avoid recursive conditional types deeper than 3 levels — use iterative mapped types instead.
|
|
255
|
+
- Minimize computed types in hot paths (function parameters, return types used in many places).
|
|
256
|
+
- Use \`interface\` for object shapes, \`type\` for unions, intersections, and mapped types.
|
|
257
|
+
- Annotate complex return types explicitly — do not force the compiler to infer through 5 layers.
|
|
258
|
+
- Break circular type references by extracting shared shapes into separate interfaces.
|
|
338
259
|
|
|
339
|
-
|
|
340
|
-
\`\`\`tsx
|
|
341
|
-
class WeakCache<K extends object, V> {
|
|
342
|
-
private cache = new Map<K, WeakRef<V & object>>();
|
|
343
|
-
private registry = new FinalizationRegistry<K>(key => this.cache.delete(key));
|
|
260
|
+
## Compiler Configuration (Detailed)
|
|
344
261
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
262
|
+
### Strict Mode
|
|
263
|
+
\`\`\`jsonc
|
|
264
|
+
{
|
|
265
|
+
"compilerOptions": {
|
|
266
|
+
"strict": true,
|
|
267
|
+
"noUncheckedIndexedAccess": true, // arr[0] is T | undefined
|
|
268
|
+
"exactOptionalPropertyTypes": true, // undefined ≠ missing
|
|
269
|
+
"noFallthroughCasesInSwitch": true,
|
|
270
|
+
"forceConsistentCasingInFileNames": true,
|
|
271
|
+
"isolatedModules": true,
|
|
272
|
+
"verbatimModuleSyntax": true
|
|
348
273
|
}
|
|
274
|
+
}
|
|
275
|
+
\`\`\`
|
|
349
276
|
|
|
350
|
-
|
|
351
|
-
|
|
277
|
+
### Build Performance
|
|
278
|
+
\`\`\`jsonc
|
|
279
|
+
{
|
|
280
|
+
"compilerOptions": {
|
|
281
|
+
"incremental": true,
|
|
282
|
+
"tsBuildInfoFile": ".tsbuildinfo",
|
|
283
|
+
"skipLibCheck": true
|
|
352
284
|
}
|
|
353
285
|
}
|
|
354
286
|
\`\`\`
|
|
355
287
|
|
|
356
|
-
###
|
|
357
|
-
\`\`\`
|
|
358
|
-
//
|
|
359
|
-
|
|
360
|
-
const activeIds = new Set<string>(); // O(1) has/add/delete
|
|
288
|
+
### Project References (monorepos)
|
|
289
|
+
\`\`\`jsonc
|
|
290
|
+
// tsconfig.json (root)
|
|
291
|
+
{ "references": [{ "path": "packages/core" }, { "path": "packages/server" }] }
|
|
361
292
|
|
|
362
|
-
//
|
|
363
|
-
|
|
293
|
+
// packages/core/tsconfig.json
|
|
294
|
+
{ "compilerOptions": { "composite": true, "declaration": true, "declarationMap": true } }
|
|
364
295
|
\`\`\`
|
|
365
296
|
|
|
366
|
-
###
|
|
367
|
-
-
|
|
368
|
-
-
|
|
369
|
-
-
|
|
370
|
-
- Avoid \`eval()\`, \`new Function()\`, and dynamic \`require()\` — security + performance issues
|
|
297
|
+
### TypeScript 6.0+ Features
|
|
298
|
+
- \`#/\` subpath imports: \`import { utils } from "#/lib/utils"\` — configured in \`package.json\` \`"imports"\` field.
|
|
299
|
+
- \`--noCheck\`: Skip type-checking in CI when pre-checked for faster builds.
|
|
300
|
+
- \`isolatedDeclarations\`: Generate .d.ts without type-checking for parallel builds.
|
|
371
301
|
|
|
372
|
-
##
|
|
302
|
+
## Never Rules
|
|
373
303
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
304
|
+
- NEVER use \`as\` to silence type errors — use type guards or fix upstream types. Only \`as unknown as T\` in tests.
|
|
305
|
+
- NEVER use \`any\` in exported signatures — it infects every consumer. Use \`unknown\` + narrowing.
|
|
306
|
+
- NEVER use \`!\` (non-null assertion) without a runtime guard.
|
|
307
|
+
- NEVER mix null and undefined semantics — pick one convention per codebase.
|
|
308
|
+
- NEVER export mutable state as a shared type — use \`readonly\` or \`Readonly<T>\`.
|
|
309
|
+
- NEVER use \`enum\` in new code — use \`as const\` objects or string literal unions.
|
|
310
|
+
- NEVER ignore generic constraints — type parameters should document intent.
|
|
380
311
|
|
|
381
|
-
|
|
382
|
-
\`\`\`tsx
|
|
383
|
-
// Object spread for shallow updates
|
|
384
|
-
const updated = { ...user, name: "New Name" };
|
|
312
|
+
## Async Patterns
|
|
385
313
|
|
|
386
|
-
|
|
387
|
-
|
|
314
|
+
\`\`\`tsx
|
|
315
|
+
// Parallel execution — fail-fast
|
|
316
|
+
const [users, posts] = await Promise.all([getUsers(), getPosts()]);
|
|
388
317
|
|
|
389
|
-
//
|
|
390
|
-
const
|
|
391
|
-
const removed = items.filter(i => i.id !== targetId);
|
|
392
|
-
const updated = items.map(i => i.id === targetId ? { ...i, ...changes } : i);
|
|
393
|
-
\`\`\`
|
|
318
|
+
// All results regardless of failures
|
|
319
|
+
const results = await Promise.allSettled([getUsers(), getPosts()]);
|
|
394
320
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
321
|
+
// AbortController for timeout
|
|
322
|
+
async function fetchWithTimeout(url: string, timeoutMs: number): Promise<Response> {
|
|
323
|
+
const controller = new AbortController();
|
|
324
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
325
|
+
try { return await fetch(url, { signal: controller.signal }); }
|
|
326
|
+
finally { clearTimeout(timeout); }
|
|
399
327
|
}
|
|
400
328
|
|
|
401
|
-
//
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
329
|
+
// Async iterator for pagination
|
|
330
|
+
async function* paginate<T>(fetcher: (page: number) => Promise<T[]>): AsyncGenerator<T> {
|
|
331
|
+
let page = 0;
|
|
332
|
+
while (true) {
|
|
333
|
+
const items = await fetcher(page++);
|
|
334
|
+
if (items.length === 0) break;
|
|
335
|
+
yield* items;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
409
338
|
\`\`\`
|
|
410
339
|
|
|
411
|
-
##
|
|
340
|
+
## Module Organization
|
|
341
|
+
|
|
342
|
+
- Direct imports over barrel files — barrels cause entire module trees to load.
|
|
343
|
+
- Always use \`import type\` for types.
|
|
344
|
+
- Re-export public API surface explicitly; do not export internal implementation details.
|
|
345
|
+
- Use named exports, not default exports.
|
|
412
346
|
|
|
413
|
-
|
|
347
|
+
## Memory and Runtime
|
|
414
348
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
6. **Error handling?** → Result pattern for expected errors. throw for unexpected/programmer errors.
|
|
421
|
-
7. **Async?** → Promise.all for parallel. AbortController for timeouts. AsyncGenerator for streams.
|
|
349
|
+
- Use \`structuredClone()\` over \`JSON.parse(JSON.stringify())\` for deep cloning.
|
|
350
|
+
- Use \`Object.freeze()\` for truly immutable constants.
|
|
351
|
+
- Use Map/Set for frequent lookups instead of plain objects.
|
|
352
|
+
- Minimize \`Reflect.metadata\` and decorator reflection — adds runtime overhead.
|
|
353
|
+
- Avoid \`eval()\`, \`new Function()\`, and dynamic \`require()\`.
|
|
422
354
|
`}];export{e as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{n as e}from"./workspace-bootstrap-BPWA6BVf.js";import{n as t,t as n}from"./startup-maintenance-D0Uhpi3k.js";import{createLogger as r,serializeError as i,setDetailedErrorLoggingEnabled as a}from"../../core/dist/index.js";const o=r(`server`);async function s(r){let[{loadConfig:s,reconfigureForWorkspace:c,resolveIndexMode:l},{createLazyServer:u},{checkForUpdates:d,autoUpgradeScaffold:f},{RootsListChangedNotificationSchema:p}]=await Promise.all([import(`./config-B-wvmMyo.js`),import(`./server-D6sJEw0I.js`),import(`./version-check-CggUKvv8.js`),import(`@modelcontextprotocol/sdk/types.js`)]),m=s();a(m.logging?.errorDetails===!0),m.configError&&o.warn(`Config load failure`,{error:m.configError}),o.info(`Config loaded`,{sourceCount:m.sources.length,storePath:m.store.path}),f(),setInterval(d,1440*60*1e3).unref();let h=l(m),g=u(m,h),{server:_,startInit:v,ready:y,runInitialIndex:b}=g,{StdioServerTransport:x}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),S=new x;await _.connect(S),o.debug(`MCP server started`,{transport:`stdio`}),await e({config:m,indexMode:h,log:o,rootsChangedNotificationSchema:p,reconfigureForWorkspace:c,runInitialIndex:b,server:_,startInit:v,version:r});let C=null,w=null,T=!1,E=async e=>{T||(T=!0,o.info(`Shutdown signal received`,{signal:e}),C&&=(clearTimeout(C),null),w?.stop(),await import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),await S.close().catch(()=>void 0),await _.close().catch(()=>void 0),g.aikit&&await Promise.all([g.aikit.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),g.aikit.graphStore.close().catch(()=>{}),g.aikit.closeStateStore?.().catch(()=>{})??Promise.resolve(),g.aikit.store.close().catch(()=>{})]),process.exit(0))},D=()=>{C&&clearTimeout(C),C=setTimeout(async()=>{o.info(`Auto-shutdown: no activity for 30 minutes — releasing resources`);try{let e=g.aikit;e&&(e.embedder.shutdown?.().catch(()=>{}),e.store.releaseMemory?.(),e.graphStore.releaseMemory?.())}catch(e){o.warn(`Resource release failed during shutdown`,i(e))}},18e5),C.unref&&C.unref()};D(),process.stdin.on(`data`,()=>D()),process.stdin.on(`end`,()=>void E(`stdin-end`)),process.stdin.on(`close`,()=>void E(`stdin-close`)),process.stdin.on(`error`,()=>void E(`stdin-error`)),process.on(`SIGINT`,()=>void E(`SIGINT`)),process.on(`SIGTERM`,()=>void E(`SIGTERM`)),y.catch(e=>{o.error(`Initialization failed — server will continue with limited tools`,t(r,e))}),h===`smart`?y.then(async()=>{try{if(!g.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(g.aikit.indexer,m,g.aikit.store);w=t;let n=g.aikit.store;t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),g.setSmartScheduler(t),o.debug(`Smart index scheduler started (stdio mode)`)}catch(e){o.error(`Failed to start smart index scheduler`,t(r,e))}}).catch(e=>o.error(`AI Kit init failed for smart scheduler`,t(r,e))):o.warn(`Initial full indexing skipped; use aikit_reindex to index manually`,{indexMode:h}),n(y,()=>g.aikit?{curated:g.aikit.curated,stateStore:g.aikit.stateStore}:null,r)}export{s as startStdioMode};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import{r as e}from"./bin.js";import{n as t,t as n}from"./startup-maintenance-L9NUOBVy.js";import{createLogger as r,serializeError as i,setDetailedErrorLoggingEnabled as a}from"../../core/dist/index.js";const o=r(`server`);async function s(r){let[{loadConfig:s,reconfigureForWorkspace:c,resolveIndexMode:l},{createLazyServer:u},{checkForUpdates:d,autoUpgradeScaffold:f},{RootsListChangedNotificationSchema:p}]=await Promise.all([import(`./config-Bx85fwRX.js`),import(`./server-BSvqfFcK.js`),import(`./version-check-CdBHTxtt.js`),import(`@modelcontextprotocol/sdk/types.js`)]),m=s();a(m.logging?.errorDetails===!0),m.configError&&o.warn(`Config load failure`,{error:m.configError}),o.info(`Config loaded`,{sourceCount:m.sources.length,storePath:m.store.path}),f(),setInterval(d,1440*60*1e3).unref();let h=l(m),g=u(m,h),{server:_,startInit:v,ready:y,runInitialIndex:b}=g,{StdioServerTransport:x}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),S=new x;await _.connect(S),o.debug(`MCP server started`,{transport:`stdio`}),await e({config:m,indexMode:h,log:o,rootsChangedNotificationSchema:p,reconfigureForWorkspace:c,runInitialIndex:b,server:_,startInit:v,version:r});let C=null,w=null,T=!1,E=async e=>{T||(T=!0,o.info(`Shutdown signal received`,{signal:e}),C&&=(clearTimeout(C),null),w?.stop(),await import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),await S.close().catch(()=>void 0),await _.close().catch(()=>void 0),g.aikit&&await Promise.all([g.aikit.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),g.aikit.graphStore.close().catch(()=>{}),g.aikit.closeStateStore?.().catch(()=>{})??Promise.resolve(),g.aikit.store.close().catch(()=>{})]),process.exit(0))},D=()=>{C&&clearTimeout(C),C=setTimeout(async()=>{o.info(`Auto-shutdown: no activity for 30 minutes — releasing resources`);try{let e=g.aikit;e&&(e.embedder.shutdown?.().catch(()=>{}),e.store.releaseMemory?.(),e.graphStore.releaseMemory?.())}catch(e){o.warn(`Resource release failed during shutdown`,i(e))}},18e5),C.unref&&C.unref()};D(),process.stdin.on(`data`,()=>D()),process.stdin.on(`end`,()=>void E(`stdin-end`)),process.stdin.on(`close`,()=>void E(`stdin-close`)),process.stdin.on(`error`,()=>void E(`stdin-error`)),process.on(`SIGINT`,()=>void E(`SIGINT`)),process.on(`SIGTERM`,()=>void E(`SIGTERM`)),y.catch(e=>{o.error(`Initialization failed — server will continue with limited tools`,t(r,e))}),h===`smart`?y.then(async()=>{try{if(!g.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(g.aikit.indexer,m,g.aikit.store);w=t;let n=g.aikit.store;t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),g.setSmartScheduler(t),o.debug(`Smart index scheduler started (stdio mode)`)}catch(e){o.error(`Failed to start smart index scheduler`,t(r,e))}}).catch(e=>o.error(`AI Kit init failed for smart scheduler`,t(r,e))):o.warn(`Initial full indexing skipped; use aikit_reindex to index manually`,{indexMode:h}),n(y,()=>g.aikit?{curated:g.aikit.curated,stateStore:g.aikit.stateStore}:null,r)}export{s as startStdioMode};
|