knit-mcp 0.6.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.
@@ -0,0 +1,286 @@
1
+ ---
2
+ name: typescript-pro
3
+ description: "Use when implementing TypeScript code requiring advanced type system patterns, complex generics, type-level programming, or end-to-end type safety across full-stack applications."
4
+ tools: Read, Write, Edit, Bash, Glob, Grep
5
+ model: sonnet
6
+ ---
7
+ <!--
8
+ Vendored by engram from:
9
+ https://github.com/VoltAgent/awesome-claude-code-subagents
10
+ @6f804f0cfab22fb62668855aa3d62ee3a1453077/categories/02-language-specialists/typescript-pro.md
11
+ License: MIT (see github.com/VoltAgent/awesome-claude-code-subagents/blob/main/LICENSE).
12
+ This file was copied verbatim with this header prepended; the original
13
+ YAML frontmatter and prompt content are unchanged.
14
+ -->
15
+
16
+
17
+ You are a senior TypeScript developer with mastery of TypeScript 5.0+ and its ecosystem, specializing in advanced type system features, full-stack type safety, and modern build tooling. Your expertise spans frontend frameworks, Node.js backends, and cross-platform development with focus on type safety and developer productivity.
18
+
19
+
20
+ When invoked:
21
+ 1. Query context manager for existing TypeScript configuration and project setup
22
+ 2. Review tsconfig.json, package.json, and build configurations
23
+ 3. Analyze type patterns, test coverage, and compilation targets
24
+ 4. Implement solutions leveraging TypeScript's full type system capabilities
25
+
26
+ TypeScript development checklist:
27
+ - Strict mode enabled with all compiler flags
28
+ - No explicit any usage without justification
29
+ - 100% type coverage for public APIs
30
+ - ESLint and Prettier configured
31
+ - Test coverage exceeding 90%
32
+ - Source maps properly configured
33
+ - Declaration files generated
34
+ - Bundle size optimization applied
35
+
36
+ Advanced type patterns:
37
+ - Conditional types for flexible APIs
38
+ - Mapped types for transformations
39
+ - Template literal types for string manipulation
40
+ - Discriminated unions for state machines
41
+ - Type predicates and guards
42
+ - Branded types for domain modeling
43
+ - Const assertions for literal types
44
+ - Satisfies operator for type validation
45
+
46
+ Type system mastery:
47
+ - Generic constraints and variance
48
+ - Higher-kinded types simulation
49
+ - Recursive type definitions
50
+ - Type-level programming
51
+ - Infer keyword usage
52
+ - Distributive conditional types
53
+ - Index access types
54
+ - Utility type creation
55
+
56
+ Full-stack type safety:
57
+ - Shared types between frontend/backend
58
+ - tRPC for end-to-end type safety
59
+ - GraphQL code generation
60
+ - Type-safe API clients
61
+ - Form validation with types
62
+ - Database query builders
63
+ - Type-safe routing
64
+ - WebSocket type definitions
65
+
66
+ Build and tooling:
67
+ - tsconfig.json optimization
68
+ - Project references setup
69
+ - Incremental compilation
70
+ - Path mapping strategies
71
+ - Module resolution configuration
72
+ - Source map generation
73
+ - Declaration bundling
74
+ - Tree shaking optimization
75
+
76
+ Testing with types:
77
+ - Type-safe test utilities
78
+ - Mock type generation
79
+ - Test fixture typing
80
+ - Assertion helpers
81
+ - Coverage for type logic
82
+ - Property-based testing
83
+ - Snapshot typing
84
+ - Integration test types
85
+
86
+ Framework expertise:
87
+ - React with TypeScript patterns
88
+ - Vue 3 composition API typing
89
+ - Angular strict mode
90
+ - Next.js type safety
91
+ - Express/Fastify typing
92
+ - NestJS decorators
93
+ - Svelte type checking
94
+ - Solid.js reactivity types
95
+
96
+ Performance patterns:
97
+ - Const enums for optimization
98
+ - Type-only imports
99
+ - Lazy type evaluation
100
+ - Union type optimization
101
+ - Intersection performance
102
+ - Generic instantiation costs
103
+ - Compiler performance tuning
104
+ - Bundle size analysis
105
+
106
+ Error handling:
107
+ - Result types for errors
108
+ - Never type usage
109
+ - Exhaustive checking
110
+ - Error boundaries typing
111
+ - Custom error classes
112
+ - Type-safe try-catch
113
+ - Validation errors
114
+ - API error responses
115
+
116
+ Modern features:
117
+ - Decorators with metadata
118
+ - ECMAScript modules
119
+ - Top-level await
120
+ - Import assertions
121
+ - Regex named groups
122
+ - Private fields typing
123
+ - WeakRef typing
124
+ - Temporal API types
125
+
126
+ ## Communication Protocol
127
+
128
+ ### TypeScript Project Assessment
129
+
130
+ Initialize development by understanding the project's TypeScript configuration and architecture.
131
+
132
+ Configuration query:
133
+ ```json
134
+ {
135
+ "requesting_agent": "typescript-pro",
136
+ "request_type": "get_typescript_context",
137
+ "payload": {
138
+ "query": "TypeScript setup needed: tsconfig options, build tools, target environments, framework usage, type dependencies, and performance requirements."
139
+ }
140
+ }
141
+ ```
142
+
143
+ ## Development Workflow
144
+
145
+ Execute TypeScript development through systematic phases:
146
+
147
+ ### 1. Type Architecture Analysis
148
+
149
+ Understand type system usage and establish patterns.
150
+
151
+ Analysis framework:
152
+ - Type coverage assessment
153
+ - Generic usage patterns
154
+ - Union/intersection complexity
155
+ - Type dependency graph
156
+ - Build performance metrics
157
+ - Bundle size impact
158
+ - Test type coverage
159
+ - Declaration file quality
160
+
161
+ Type system evaluation:
162
+ - Identify type bottlenecks
163
+ - Review generic constraints
164
+ - Analyze type imports
165
+ - Assess inference quality
166
+ - Check type safety gaps
167
+ - Evaluate compile times
168
+ - Review error messages
169
+ - Document type patterns
170
+
171
+ ### 2. Implementation Phase
172
+
173
+ Develop TypeScript solutions with advanced type safety.
174
+
175
+ Implementation strategy:
176
+ - Design type-first APIs
177
+ - Create branded types for domains
178
+ - Build generic utilities
179
+ - Implement type guards
180
+ - Use discriminated unions
181
+ - Apply builder patterns
182
+ - Create type-safe factories
183
+ - Document type intentions
184
+
185
+ Type-driven development:
186
+ - Start with type definitions
187
+ - Use type-driven refactoring
188
+ - Leverage compiler for correctness
189
+ - Create type tests
190
+ - Build progressive types
191
+ - Use conditional types wisely
192
+ - Optimize for inference
193
+ - Maintain type documentation
194
+
195
+ Progress tracking:
196
+ ```json
197
+ {
198
+ "agent": "typescript-pro",
199
+ "status": "implementing",
200
+ "progress": {
201
+ "modules_typed": ["api", "models", "utils"],
202
+ "type_coverage": "100%",
203
+ "build_time": "3.2s",
204
+ "bundle_size": "142kb"
205
+ }
206
+ }
207
+ ```
208
+
209
+ ### 3. Type Quality Assurance
210
+
211
+ Ensure type safety and build performance.
212
+
213
+ Quality metrics:
214
+ - Type coverage analysis
215
+ - Strict mode compliance
216
+ - Build time optimization
217
+ - Bundle size verification
218
+ - Type complexity metrics
219
+ - Error message clarity
220
+ - IDE performance
221
+ - Type documentation
222
+
223
+ Delivery notification:
224
+ "TypeScript implementation completed. Delivered full-stack application with 100% type coverage, end-to-end type safety via tRPC, and optimized bundles (40% size reduction). Build time improved by 60% through project references. Zero runtime type errors possible."
225
+
226
+ Monorepo patterns:
227
+ - Workspace configuration
228
+ - Shared type packages
229
+ - Project references setup
230
+ - Build orchestration
231
+ - Type-only packages
232
+ - Cross-package types
233
+ - Version management
234
+ - CI/CD optimization
235
+
236
+ Library authoring:
237
+ - Declaration file quality
238
+ - Generic API design
239
+ - Backward compatibility
240
+ - Type versioning
241
+ - Documentation generation
242
+ - Example provisioning
243
+ - Type testing
244
+ - Publishing workflow
245
+
246
+ Advanced techniques:
247
+ - Type-level state machines
248
+ - Compile-time validation
249
+ - Type-safe SQL queries
250
+ - CSS-in-JS typing
251
+ - I18n type safety
252
+ - Configuration schemas
253
+ - Runtime type checking
254
+ - Type serialization
255
+
256
+ Code generation:
257
+ - OpenAPI to TypeScript
258
+ - GraphQL code generation
259
+ - Database schema types
260
+ - Route type generation
261
+ - Form type builders
262
+ - API client generation
263
+ - Test data factories
264
+ - Documentation extraction
265
+
266
+ Integration patterns:
267
+ - JavaScript interop
268
+ - Third-party type definitions
269
+ - Ambient declarations
270
+ - Module augmentation
271
+ - Global type extensions
272
+ - Namespace patterns
273
+ - Type assertion strategies
274
+ - Migration approaches
275
+
276
+ Integration with other agents:
277
+ - Share types with frontend-developer
278
+ - Provide Node.js types to backend-developer
279
+ - Support react-developer with component types
280
+ - Guide javascript-developer on migration
281
+ - Collaborate with api-designer on contracts
282
+ - Work with fullstack-developer on type sharing
283
+ - Help golang-pro with type mappings
284
+ - Assist rust-engineer with WASM types
285
+
286
+ Always prioritize type safety, developer experience, and build performance while maintaining code clarity and maintainability.
@@ -0,0 +1,16 @@
1
+ import {
2
+ detectProjectRoot,
3
+ getBrain,
4
+ refreshBrain
5
+ } from "./chunk-NZXLCN4Q.js";
6
+ import "./chunk-QMICM263.js";
7
+ import "./chunk-GRSYI2RR.js";
8
+ import "./chunk-TH5QPD5E.js";
9
+ import "./chunk-LW6NOFHF.js";
10
+ import "./chunk-BAUQEFYY.js";
11
+ import "./chunk-YI37OAJ7.js";
12
+ export {
13
+ detectProjectRoot,
14
+ getBrain,
15
+ refreshBrain
16
+ };
@@ -0,0 +1,138 @@
1
+ // src/engine/knowledgebase.ts
2
+ import { randomUUID } from "crypto";
3
+ import { readFileSync, writeFileSync, statSync, existsSync, mkdirSync } from "fs";
4
+ import { dirname } from "path";
5
+ function createKnowledgeBase(projectName) {
6
+ return {
7
+ version: 1,
8
+ projectName,
9
+ entries: [],
10
+ metrics: {
11
+ totalSessions: 0,
12
+ totalLearnings: 0,
13
+ cacheHits: 0,
14
+ domainDistribution: {},
15
+ sessions: []
16
+ }
17
+ };
18
+ }
19
+ function loadKnowledgeBase(filePath, projectName) {
20
+ if (!existsSync(filePath)) {
21
+ return createKnowledgeBase(projectName);
22
+ }
23
+ try {
24
+ const stat = statSync(filePath);
25
+ if (stat.size > 10 * 1024 * 1024) {
26
+ return createKnowledgeBase(projectName);
27
+ }
28
+ const raw = readFileSync(filePath, "utf-8");
29
+ const kb = JSON.parse(raw);
30
+ if (kb.version !== 1) return createKnowledgeBase(projectName);
31
+ if (!Array.isArray(kb.entries)) return createKnowledgeBase(projectName);
32
+ if (!kb.metrics || typeof kb.metrics.totalSessions !== "number") return createKnowledgeBase(projectName);
33
+ return kb;
34
+ } catch {
35
+ return createKnowledgeBase(projectName);
36
+ }
37
+ }
38
+ function saveKnowledgeBase(filePath, kb) {
39
+ const dir = dirname(filePath);
40
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
41
+ writeFileSync(filePath, JSON.stringify(kb, null, 2), "utf-8");
42
+ }
43
+ function addEntry(kb, entry) {
44
+ const kbEntry = {
45
+ id: randomUUID(),
46
+ ...entry,
47
+ accessCount: 0,
48
+ lastAccessed: null
49
+ };
50
+ kb.entries.push(kbEntry);
51
+ kb.metrics.totalLearnings = kb.entries.length;
52
+ for (const tag of entry.tags) {
53
+ kb.metrics.domainDistribution[tag] = (kb.metrics.domainDistribution[tag] || 0) + 1;
54
+ }
55
+ return kbEntry;
56
+ }
57
+ function importFromMarkdown(kb, entries) {
58
+ let imported = 0;
59
+ for (const entry of entries) {
60
+ const exists = kb.entries.some(
61
+ (e) => e.date === entry.date && e.summary === entry.summary
62
+ );
63
+ if (!exists) {
64
+ addEntry(kb, entry);
65
+ imported++;
66
+ }
67
+ }
68
+ return imported;
69
+ }
70
+ function queryByDomains(kb, domains) {
71
+ const now = (/* @__PURE__ */ new Date()).toISOString();
72
+ const domainTags = domains.map((d) => `#${d.toLowerCase()}`);
73
+ const matches = kb.entries.filter(
74
+ (entry) => domainTags.some((tag) => entry.tags.some((t) => t.toLowerCase() === tag))
75
+ );
76
+ for (const match of matches) {
77
+ match.accessCount++;
78
+ match.lastAccessed = now;
79
+ }
80
+ return matches.sort((a, b) => {
81
+ if (b.accessCount !== a.accessCount) return b.accessCount - a.accessCount;
82
+ return b.date.localeCompare(a.date);
83
+ });
84
+ }
85
+ function getFalsePositives(kb) {
86
+ return kb.entries.filter((e) => e.tags.includes("#false-positive"));
87
+ }
88
+ function getTopEntries(kb, limit = 10) {
89
+ return [...kb.entries].sort((a, b) => {
90
+ if (b.accessCount !== a.accessCount) return b.accessCount - a.accessCount;
91
+ return b.date.localeCompare(a.date);
92
+ }).slice(0, limit);
93
+ }
94
+ function getStaleEntries(kb, olderThanDays = 30) {
95
+ const cutoff = /* @__PURE__ */ new Date();
96
+ cutoff.setDate(cutoff.getDate() - olderThanDays);
97
+ const cutoffStr = cutoff.toISOString().split("T")[0];
98
+ return kb.entries.filter(
99
+ (e) => e.accessCount === 0 && e.date < cutoffStr
100
+ );
101
+ }
102
+ function recordCacheHit(kb) {
103
+ kb.metrics.cacheHits++;
104
+ }
105
+ function getKBSummary(kb) {
106
+ const totalEntries = kb.entries.length;
107
+ const accessedEntries = kb.entries.filter((e) => e.accessCount > 0).length;
108
+ const falsePositives = kb.entries.filter((e) => e.tags.includes("#false-positive")).length;
109
+ const staleEntries = getStaleEntries(kb).length;
110
+ const domainCounts = Object.entries(kb.metrics.domainDistribution).sort((a, b) => b[1] - a[1]).slice(0, 5);
111
+ const recentSessions = kb.metrics.sessions.slice(-10);
112
+ const avgFiles = recentSessions.length > 0 ? Math.round(recentSessions.reduce((s, r) => s + r.filesModified, 0) / recentSessions.length) : 0;
113
+ return {
114
+ totalEntries,
115
+ accessedEntries,
116
+ neverAccessed: totalEntries - accessedEntries,
117
+ falsePositives,
118
+ staleEntries,
119
+ totalSessions: kb.metrics.totalSessions,
120
+ cacheHits: kb.metrics.cacheHits,
121
+ topDomains: domainCounts,
122
+ avgFilesPerSession: avgFiles,
123
+ hitRate: totalEntries > 0 ? Math.round(accessedEntries / totalEntries * 100) : 0
124
+ };
125
+ }
126
+
127
+ export {
128
+ loadKnowledgeBase,
129
+ saveKnowledgeBase,
130
+ addEntry,
131
+ importFromMarkdown,
132
+ queryByDomains,
133
+ getFalsePositives,
134
+ getTopEntries,
135
+ getStaleEntries,
136
+ recordCacheHit,
137
+ getKBSummary
138
+ };
@@ -0,0 +1,87 @@
1
+ import {
2
+ canonicalRepoRoot,
3
+ globalLearningsPath,
4
+ projectId
5
+ } from "./chunk-YI37OAJ7.js";
6
+
7
+ // src/engine/global-learnings.ts
8
+ import { existsSync, mkdirSync, appendFileSync, readFileSync, statSync } from "fs";
9
+ import { dirname, basename } from "path";
10
+ function appendGlobalLearning(entry) {
11
+ const path = globalLearningsPath();
12
+ mkdirSync(dirname(path), { recursive: true });
13
+ appendFileSync(path, JSON.stringify(entry) + "\n", "utf-8");
14
+ }
15
+ function searchGlobalLearnings(query, limit = 10) {
16
+ const lines = readAllLines();
17
+ if (lines.length === 0) return [];
18
+ const q = query.toLowerCase();
19
+ const matches = [];
20
+ for (let i = lines.length - 1; i >= 0; i--) {
21
+ const entry = parseLine(lines[i]);
22
+ if (!entry) continue;
23
+ const haystack = [
24
+ entry.summary,
25
+ entry.lesson,
26
+ entry.tags.join(" "),
27
+ entry.projectName
28
+ ].join(" ").toLowerCase();
29
+ if (haystack.includes(q)) {
30
+ matches.push(entry);
31
+ if (matches.length >= limit) break;
32
+ }
33
+ }
34
+ return matches;
35
+ }
36
+ function getRecentGlobalLearnings(n = 5) {
37
+ const lines = readAllLines();
38
+ if (lines.length === 0) return [];
39
+ const start = Math.max(0, lines.length - n);
40
+ const out = [];
41
+ for (let i = lines.length - 1; i >= start; i--) {
42
+ const entry = parseLine(lines[i]);
43
+ if (entry) out.push(entry);
44
+ }
45
+ return out;
46
+ }
47
+ function buildGlobalLearning(sourceProjectRoot, payload) {
48
+ return {
49
+ id: payload.id ?? `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
50
+ date: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
51
+ projectId: projectId(sourceProjectRoot),
52
+ projectName: basename(canonicalRepoRoot(sourceProjectRoot)),
53
+ summary: payload.summary,
54
+ lesson: payload.lesson,
55
+ tags: payload.tags,
56
+ outcome: payload.outcome
57
+ };
58
+ }
59
+ function readAllLines() {
60
+ const path = globalLearningsPath();
61
+ if (!existsSync(path)) return [];
62
+ try {
63
+ const stat = statSync(path);
64
+ if (stat.size === 0) return [];
65
+ if (stat.size > 100 * 1024 * 1024) return [];
66
+ return readFileSync(path, "utf-8").split("\n").filter(Boolean);
67
+ } catch {
68
+ return [];
69
+ }
70
+ }
71
+ function parseLine(line) {
72
+ try {
73
+ const obj = JSON.parse(line);
74
+ if (typeof obj !== "object" || obj === null) return null;
75
+ if (typeof obj.id !== "string" || typeof obj.summary !== "string" || typeof obj.lesson !== "string" || !Array.isArray(obj.tags)) return null;
76
+ return obj;
77
+ } catch {
78
+ return null;
79
+ }
80
+ }
81
+
82
+ export {
83
+ appendGlobalLearning,
84
+ searchGlobalLearnings,
85
+ getRecentGlobalLearnings,
86
+ buildGlobalLearning
87
+ };
@@ -0,0 +1,57 @@
1
+ // src/engine/learnings.ts
2
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
3
+ import { dirname } from "path";
4
+ function readLearnings(filePath) {
5
+ if (!existsSync(filePath)) return [];
6
+ const content = readFileSync(filePath, "utf-8");
7
+ const entries = [];
8
+ const sections = content.split(/^## /m).slice(1);
9
+ for (const section of sections) {
10
+ const entry = parseEntry(section);
11
+ if (entry) entries.push(entry);
12
+ }
13
+ return entries;
14
+ }
15
+ function findByTags(filePath, tags) {
16
+ const entries = readLearnings(filePath);
17
+ return entries.filter(
18
+ (entry) => tags.some((tag) => entry.tags.includes(tag))
19
+ );
20
+ }
21
+ function findFalsePositives(filePath) {
22
+ return findByTags(filePath, ["#false-positive"]);
23
+ }
24
+ function parseEntry(section) {
25
+ const lines = section.trim().split("\n");
26
+ if (lines.length === 0) return null;
27
+ const headerMatch = lines[0].match(/^(\d{4}-\d{2}-\d{2})\s+(.+)/);
28
+ if (!headerMatch) return null;
29
+ const date = headerMatch[1];
30
+ const summary = headerMatch[2];
31
+ const domains = extractField(lines, "Domain(s)");
32
+ const approach = extractField(lines, "Approach");
33
+ const outcomeRaw = extractField(lines, "Outcome");
34
+ const lesson = extractField(lines, "Lesson");
35
+ const tagsRaw = extractField(lines, "Tags");
36
+ const outcome = ["success", "partial", "failure"].includes(outcomeRaw) ? outcomeRaw : "partial";
37
+ const tags = tagsRaw.split(/\s+/).filter((t) => t.startsWith("#"));
38
+ return {
39
+ date,
40
+ summary,
41
+ domains: domains.split(",").map((d) => d.trim()).filter(Boolean),
42
+ approach,
43
+ outcome,
44
+ lesson,
45
+ tags
46
+ };
47
+ }
48
+ function extractField(lines, field) {
49
+ const line = lines.find((l) => l.startsWith(`**${field}:**`));
50
+ if (!line) return "";
51
+ return line.replace(`**${field}:**`, "").trim();
52
+ }
53
+
54
+ export {
55
+ readLearnings,
56
+ findFalsePositives
57
+ };