mycontext-cli 2.0.28 → 2.0.30
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/README.md +106 -14
- package/dist/cli.js +89 -99
- package/dist/cli.js.map +1 -1
- package/dist/commands/generate-components.d.ts +10 -0
- package/dist/commands/generate-components.d.ts.map +1 -1
- package/dist/commands/generate-components.js +300 -3
- package/dist/commands/generate-components.js.map +1 -1
- package/dist/commands/generate-context-files.d.ts +9 -0
- package/dist/commands/generate-context-files.d.ts.map +1 -1
- package/dist/commands/generate-context-files.js +57 -0
- package/dist/commands/generate-context-files.js.map +1 -1
- package/dist/commands/generate.d.ts +5 -0
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +75 -1
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/init.d.ts +9 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +223 -68
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/preview-components.d.ts +12 -0
- package/dist/commands/preview-components.d.ts.map +1 -0
- package/dist/commands/preview-components.js +122 -0
- package/dist/commands/preview-components.js.map +1 -0
- package/dist/commands/refine-component.d.ts +43 -0
- package/dist/commands/refine-component.d.ts.map +1 -0
- package/dist/commands/refine-component.js +313 -0
- package/dist/commands/refine-component.js.map +1 -0
- package/dist/commands/review-context.d.ts +47 -0
- package/dist/commands/review-context.d.ts.map +1 -0
- package/dist/commands/review-context.js +335 -0
- package/dist/commands/review-context.js.map +1 -0
- package/dist/package.json +11 -2
- package/dist/services/ContextValidator.d.ts +99 -0
- package/dist/services/ContextValidator.d.ts.map +1 -0
- package/dist/services/ContextValidator.js +433 -0
- package/dist/services/ContextValidator.js.map +1 -0
- package/dist/services/MutationLogger.d.ts +54 -0
- package/dist/services/MutationLogger.d.ts.map +1 -0
- package/dist/services/MutationLogger.js +164 -0
- package/dist/services/MutationLogger.js.map +1 -0
- package/dist/services/RegressionRunner.d.ts +49 -0
- package/dist/services/RegressionRunner.d.ts.map +1 -0
- package/dist/services/RegressionRunner.js +285 -0
- package/dist/services/RegressionRunner.js.map +1 -0
- package/dist/services/TriggerLogger.d.ts +101 -0
- package/dist/services/TriggerLogger.d.ts.map +1 -0
- package/dist/services/TriggerLogger.js +263 -0
- package/dist/services/TriggerLogger.js.map +1 -0
- package/dist/templates/instantdb/db.template.ts +14 -0
- package/dist/templates/instantdb/home-client.template.tsx +127 -0
- package/dist/templates/instantdb/page.template.tsx +5 -0
- package/dist/templates/instantdb/perms.template.ts +9 -0
- package/dist/templates/instantdb/schema.template.ts +28 -0
- package/dist/templates/playbooks/instantdb-integration.md +851 -0
- package/dist/templates/playbooks/mpesa-integration.md +652 -0
- package/dist/templates/pm-integration-config.json +20 -0
- package/dist/templates/ui-spec-examples.md +318 -0
- package/dist/templates/ui-spec-templates.json +244 -0
- package/dist/utils/envExampleGenerator.d.ts.map +1 -1
- package/dist/utils/envExampleGenerator.js +9 -3
- package/dist/utils/envExampleGenerator.js.map +1 -1
- package/dist/utils/hybridAIClient.d.ts.map +1 -1
- package/dist/utils/hybridAIClient.js +21 -0
- package/dist/utils/hybridAIClient.js.map +1 -1
- package/dist/utils/openRouterClient.d.ts +10 -0
- package/dist/utils/openRouterClient.d.ts.map +1 -0
- package/dist/utils/openRouterClient.js +61 -0
- package/dist/utils/openRouterClient.js.map +1 -0
- package/package.json +11 -2
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Context Validator Service
|
|
4
|
+
*
|
|
5
|
+
* Detects gaps in context files and tracks auto-generated features
|
|
6
|
+
* to ensure user approval before proceeding with generation.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.ContextValidator = void 0;
|
|
10
|
+
class ContextValidator {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.gaps = [];
|
|
13
|
+
this.autoGeneratedFeatures = [];
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Validate context files for completeness and detect gaps
|
|
17
|
+
*/
|
|
18
|
+
async validateContext(contextFiles) {
|
|
19
|
+
this.gaps = [];
|
|
20
|
+
this.autoGeneratedFeatures = [];
|
|
21
|
+
// Analyze PRD for gaps
|
|
22
|
+
if (contextFiles.prd) {
|
|
23
|
+
this.analyzePRDGaps(contextFiles.prd);
|
|
24
|
+
}
|
|
25
|
+
// Analyze description for gaps
|
|
26
|
+
if (contextFiles.description) {
|
|
27
|
+
this.analyzeDescriptionGaps(contextFiles.description);
|
|
28
|
+
}
|
|
29
|
+
// Analyze tech stack for gaps
|
|
30
|
+
if (contextFiles.techStack) {
|
|
31
|
+
this.analyzeTechStackGaps(contextFiles.techStack);
|
|
32
|
+
}
|
|
33
|
+
// Deduplicate gaps by ID
|
|
34
|
+
this.gaps = this.deduplicateGaps(this.gaps);
|
|
35
|
+
// Deduplicate features by ID
|
|
36
|
+
this.autoGeneratedFeatures = this.deduplicateFeatures(this.autoGeneratedFeatures);
|
|
37
|
+
const hasCriticalGaps = this.gaps.some((gap) => gap.category === "critical");
|
|
38
|
+
const canProceed = !hasCriticalGaps;
|
|
39
|
+
return {
|
|
40
|
+
gaps: this.gaps,
|
|
41
|
+
autoGeneratedFeatures: this.autoGeneratedFeatures,
|
|
42
|
+
hasCriticalGaps,
|
|
43
|
+
canProceed,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Deduplicate gaps by ID
|
|
48
|
+
*/
|
|
49
|
+
deduplicateGaps(gaps) {
|
|
50
|
+
const seen = new Set();
|
|
51
|
+
return gaps.filter((gap) => {
|
|
52
|
+
if (seen.has(gap.id))
|
|
53
|
+
return false;
|
|
54
|
+
seen.add(gap.id);
|
|
55
|
+
return true;
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Deduplicate features by ID
|
|
60
|
+
*/
|
|
61
|
+
deduplicateFeatures(features) {
|
|
62
|
+
const seen = new Set();
|
|
63
|
+
return features.filter((feature) => {
|
|
64
|
+
if (seen.has(feature.id))
|
|
65
|
+
return false;
|
|
66
|
+
seen.add(feature.id);
|
|
67
|
+
return true;
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Analyze PRD for missing critical information
|
|
72
|
+
*/
|
|
73
|
+
analyzePRDGaps(prd) {
|
|
74
|
+
const prdLower = prd.toLowerCase();
|
|
75
|
+
// Check for game-related gaps
|
|
76
|
+
if (this.containsGameKeywords(prdLower)) {
|
|
77
|
+
this.checkGameGaps(prdLower, "prd");
|
|
78
|
+
}
|
|
79
|
+
// Check for user authentication gaps
|
|
80
|
+
if (this.mentionsUsers(prdLower) && !this.mentionsAuth(prdLower)) {
|
|
81
|
+
this.gaps.push({
|
|
82
|
+
id: "auth-method",
|
|
83
|
+
category: "critical",
|
|
84
|
+
question: "How should users authenticate?",
|
|
85
|
+
context: "prd",
|
|
86
|
+
suggestedAnswers: [
|
|
87
|
+
"Email/password",
|
|
88
|
+
"Social login (Google, GitHub)",
|
|
89
|
+
"Magic link",
|
|
90
|
+
"No authentication needed",
|
|
91
|
+
],
|
|
92
|
+
reasoning: "PRD mentions users but no authentication method specified",
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
// Check for database gaps
|
|
96
|
+
if (this.mentionsDataPersistence(prdLower) &&
|
|
97
|
+
!this.mentionsDatabase(prdLower)) {
|
|
98
|
+
this.gaps.push({
|
|
99
|
+
id: "database-choice",
|
|
100
|
+
category: "critical",
|
|
101
|
+
question: "What database should be used?",
|
|
102
|
+
context: "prd",
|
|
103
|
+
suggestedAnswers: [
|
|
104
|
+
"InstantDB (recommended)",
|
|
105
|
+
"PostgreSQL",
|
|
106
|
+
"MongoDB",
|
|
107
|
+
"SQLite",
|
|
108
|
+
"No database needed",
|
|
109
|
+
],
|
|
110
|
+
reasoning: "PRD mentions data persistence but no database specified",
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
// Check for payment gaps
|
|
114
|
+
if (this.mentionsPayments(prdLower)) {
|
|
115
|
+
this.gaps.push({
|
|
116
|
+
id: "payment-method",
|
|
117
|
+
category: "critical",
|
|
118
|
+
question: "What payment method should be integrated?",
|
|
119
|
+
context: "prd",
|
|
120
|
+
suggestedAnswers: [
|
|
121
|
+
"Stripe",
|
|
122
|
+
"PayPal",
|
|
123
|
+
"Apple Pay",
|
|
124
|
+
"Google Pay",
|
|
125
|
+
"Other",
|
|
126
|
+
],
|
|
127
|
+
reasoning: "PRD mentions payments but no payment method specified",
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Analyze initial description for gaps
|
|
133
|
+
*/
|
|
134
|
+
analyzeDescriptionGaps(description) {
|
|
135
|
+
const descLower = description.toLowerCase();
|
|
136
|
+
// Check for vague game descriptions
|
|
137
|
+
if (this.isVagueGameDescription(descLower)) {
|
|
138
|
+
this.checkGameGaps(descLower, "description");
|
|
139
|
+
}
|
|
140
|
+
// Check for vague app descriptions
|
|
141
|
+
if (this.isVagueAppDescription(descLower)) {
|
|
142
|
+
this.gaps.push({
|
|
143
|
+
id: "app-purpose",
|
|
144
|
+
category: "critical",
|
|
145
|
+
question: "What is the main purpose of this app?",
|
|
146
|
+
context: "description",
|
|
147
|
+
suggestedAnswers: [
|
|
148
|
+
"Productivity tool",
|
|
149
|
+
"Social platform",
|
|
150
|
+
"E-commerce store",
|
|
151
|
+
"Educational platform",
|
|
152
|
+
"Entertainment app",
|
|
153
|
+
"Other",
|
|
154
|
+
],
|
|
155
|
+
reasoning: "Description is too vague to determine app purpose",
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
// Check for missing target audience
|
|
159
|
+
if (this.mentionsUsers(descLower) &&
|
|
160
|
+
!this.mentionsTargetAudience(descLower)) {
|
|
161
|
+
this.gaps.push({
|
|
162
|
+
id: "target-audience",
|
|
163
|
+
category: "important",
|
|
164
|
+
question: "Who is the target audience?",
|
|
165
|
+
context: "description",
|
|
166
|
+
suggestedAnswers: [
|
|
167
|
+
"General public",
|
|
168
|
+
"Business professionals",
|
|
169
|
+
"Students",
|
|
170
|
+
"Developers",
|
|
171
|
+
"Specific industry",
|
|
172
|
+
"Other",
|
|
173
|
+
],
|
|
174
|
+
reasoning: "App mentions users but target audience is unclear",
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Analyze tech stack for gaps
|
|
180
|
+
*/
|
|
181
|
+
analyzeTechStackGaps(techStack) {
|
|
182
|
+
const techLower = techStack.toLowerCase();
|
|
183
|
+
// Check for missing deployment strategy
|
|
184
|
+
if (!this.mentionsDeployment(techLower)) {
|
|
185
|
+
this.gaps.push({
|
|
186
|
+
id: "deployment-strategy",
|
|
187
|
+
category: "important",
|
|
188
|
+
question: "How should the app be deployed?",
|
|
189
|
+
context: "tech-stack",
|
|
190
|
+
suggestedAnswers: [
|
|
191
|
+
"Vercel (recommended for Next.js)",
|
|
192
|
+
"Netlify",
|
|
193
|
+
"AWS",
|
|
194
|
+
"Railway",
|
|
195
|
+
"Self-hosted",
|
|
196
|
+
"Other",
|
|
197
|
+
],
|
|
198
|
+
reasoning: "Tech stack specified but no deployment strategy mentioned",
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
// Check for missing environment configuration
|
|
202
|
+
if (!this.mentionsEnvironmentConfig(techLower)) {
|
|
203
|
+
this.gaps.push({
|
|
204
|
+
id: "environment-config",
|
|
205
|
+
category: "optional",
|
|
206
|
+
question: "What environment variables are needed?",
|
|
207
|
+
context: "tech-stack",
|
|
208
|
+
reasoning: "Consider adding environment configuration for API keys and secrets",
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Check for game-specific gaps
|
|
214
|
+
*/
|
|
215
|
+
checkGameGaps(text, context) {
|
|
216
|
+
// Game type gap
|
|
217
|
+
this.gaps.push({
|
|
218
|
+
id: "game-type",
|
|
219
|
+
category: "critical",
|
|
220
|
+
question: "What type of game is this?",
|
|
221
|
+
context: context,
|
|
222
|
+
suggestedAnswers: [
|
|
223
|
+
"Turn-based (Tic-tac-toe, Chess)",
|
|
224
|
+
"Real-time (Racing, Shooting)",
|
|
225
|
+
"Puzzle (Matching, Strategy)",
|
|
226
|
+
"Card game",
|
|
227
|
+
"Board game",
|
|
228
|
+
"Other",
|
|
229
|
+
],
|
|
230
|
+
reasoning: "Game mentioned but type not specified",
|
|
231
|
+
});
|
|
232
|
+
// Game rules gap
|
|
233
|
+
this.gaps.push({
|
|
234
|
+
id: "game-rules",
|
|
235
|
+
category: "critical",
|
|
236
|
+
question: "What are the core game rules?",
|
|
237
|
+
context: context,
|
|
238
|
+
reasoning: "Game rules need to be defined for proper implementation",
|
|
239
|
+
});
|
|
240
|
+
// Multiplayer gap
|
|
241
|
+
if (this.mentionsMultiplayer(text)) {
|
|
242
|
+
this.autoGeneratedFeatures.push({
|
|
243
|
+
id: "realtime-multiplayer",
|
|
244
|
+
feature: "Real-time multiplayer with Socket.io",
|
|
245
|
+
reasoning: "User mentioned playing against each other",
|
|
246
|
+
confidence: "medium",
|
|
247
|
+
contextSource: "description",
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Helper methods for text analysis
|
|
253
|
+
*/
|
|
254
|
+
containsGameKeywords(text) {
|
|
255
|
+
const gameKeywords = [
|
|
256
|
+
"game",
|
|
257
|
+
"play",
|
|
258
|
+
"player",
|
|
259
|
+
"score",
|
|
260
|
+
"win",
|
|
261
|
+
"lose",
|
|
262
|
+
"match",
|
|
263
|
+
"tournament",
|
|
264
|
+
];
|
|
265
|
+
return gameKeywords.some((keyword) => text.includes(keyword));
|
|
266
|
+
}
|
|
267
|
+
mentionsUsers(text) {
|
|
268
|
+
const userKeywords = [
|
|
269
|
+
"user",
|
|
270
|
+
"users",
|
|
271
|
+
"player",
|
|
272
|
+
"players",
|
|
273
|
+
"member",
|
|
274
|
+
"members",
|
|
275
|
+
"account",
|
|
276
|
+
"accounts",
|
|
277
|
+
];
|
|
278
|
+
return userKeywords.some((keyword) => text.includes(keyword));
|
|
279
|
+
}
|
|
280
|
+
mentionsAuth(text) {
|
|
281
|
+
const authKeywords = [
|
|
282
|
+
"login",
|
|
283
|
+
"signin",
|
|
284
|
+
"signup",
|
|
285
|
+
"register",
|
|
286
|
+
"authentication",
|
|
287
|
+
"auth",
|
|
288
|
+
"password",
|
|
289
|
+
"oauth",
|
|
290
|
+
];
|
|
291
|
+
return authKeywords.some((keyword) => text.includes(keyword));
|
|
292
|
+
}
|
|
293
|
+
mentionsDataPersistence(text) {
|
|
294
|
+
const dataKeywords = [
|
|
295
|
+
"save",
|
|
296
|
+
"store",
|
|
297
|
+
"data",
|
|
298
|
+
"database",
|
|
299
|
+
"persist",
|
|
300
|
+
"memory",
|
|
301
|
+
"history",
|
|
302
|
+
"record",
|
|
303
|
+
];
|
|
304
|
+
return dataKeywords.some((keyword) => text.includes(keyword));
|
|
305
|
+
}
|
|
306
|
+
mentionsDatabase(text) {
|
|
307
|
+
const dbKeywords = [
|
|
308
|
+
"database",
|
|
309
|
+
"db",
|
|
310
|
+
"postgres",
|
|
311
|
+
"mysql",
|
|
312
|
+
"mongodb",
|
|
313
|
+
"sqlite",
|
|
314
|
+
"instantdb",
|
|
315
|
+
"supabase",
|
|
316
|
+
];
|
|
317
|
+
return dbKeywords.some((keyword) => text.includes(keyword));
|
|
318
|
+
}
|
|
319
|
+
mentionsPayments(text) {
|
|
320
|
+
const paymentKeywords = [
|
|
321
|
+
"payment",
|
|
322
|
+
"pay",
|
|
323
|
+
"buy",
|
|
324
|
+
"purchase",
|
|
325
|
+
"subscription",
|
|
326
|
+
"billing",
|
|
327
|
+
"stripe",
|
|
328
|
+
"paypal",
|
|
329
|
+
];
|
|
330
|
+
return paymentKeywords.some((keyword) => text.includes(keyword));
|
|
331
|
+
}
|
|
332
|
+
isVagueGameDescription(text) {
|
|
333
|
+
const vaguePatterns = [
|
|
334
|
+
"fun game",
|
|
335
|
+
"simple game",
|
|
336
|
+
"game where",
|
|
337
|
+
"play against",
|
|
338
|
+
"multiplayer game",
|
|
339
|
+
];
|
|
340
|
+
return vaguePatterns.some((pattern) => text.includes(pattern));
|
|
341
|
+
}
|
|
342
|
+
isVagueAppDescription(text) {
|
|
343
|
+
const vaguePatterns = [
|
|
344
|
+
"simple app",
|
|
345
|
+
"basic app",
|
|
346
|
+
"useful app",
|
|
347
|
+
"helpful app",
|
|
348
|
+
"cool app",
|
|
349
|
+
];
|
|
350
|
+
return vaguePatterns.some((pattern) => text.includes(pattern));
|
|
351
|
+
}
|
|
352
|
+
mentionsTargetAudience(text) {
|
|
353
|
+
const audienceKeywords = [
|
|
354
|
+
"for",
|
|
355
|
+
"target",
|
|
356
|
+
"audience",
|
|
357
|
+
"users",
|
|
358
|
+
"people",
|
|
359
|
+
"business",
|
|
360
|
+
"students",
|
|
361
|
+
"developers",
|
|
362
|
+
];
|
|
363
|
+
return audienceKeywords.some((keyword) => text.includes(keyword));
|
|
364
|
+
}
|
|
365
|
+
mentionsMultiplayer(text) {
|
|
366
|
+
const multiplayerKeywords = [
|
|
367
|
+
"against each other",
|
|
368
|
+
"multiplayer",
|
|
369
|
+
"together",
|
|
370
|
+
"compete",
|
|
371
|
+
"versus",
|
|
372
|
+
"vs",
|
|
373
|
+
];
|
|
374
|
+
return multiplayerKeywords.some((keyword) => text.includes(keyword));
|
|
375
|
+
}
|
|
376
|
+
mentionsDeployment(text) {
|
|
377
|
+
const deploymentKeywords = [
|
|
378
|
+
"deploy",
|
|
379
|
+
"hosting",
|
|
380
|
+
"vercel",
|
|
381
|
+
"netlify",
|
|
382
|
+
"aws",
|
|
383
|
+
"railway",
|
|
384
|
+
"production",
|
|
385
|
+
];
|
|
386
|
+
return deploymentKeywords.some((keyword) => text.includes(keyword));
|
|
387
|
+
}
|
|
388
|
+
mentionsEnvironmentConfig(text) {
|
|
389
|
+
const envKeywords = [
|
|
390
|
+
"environment",
|
|
391
|
+
"env",
|
|
392
|
+
"config",
|
|
393
|
+
"variables",
|
|
394
|
+
"secrets",
|
|
395
|
+
"api key",
|
|
396
|
+
];
|
|
397
|
+
return envKeywords.some((keyword) => text.includes(keyword));
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Get gaps by category
|
|
401
|
+
*/
|
|
402
|
+
getGapsByCategory(category) {
|
|
403
|
+
return this.gaps.filter((gap) => gap.category === category);
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Get auto-generated features by confidence
|
|
407
|
+
*/
|
|
408
|
+
getFeaturesByConfidence(confidence) {
|
|
409
|
+
return this.autoGeneratedFeatures.filter((feature) => feature.confidence === confidence);
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Add auto-generated feature
|
|
413
|
+
*/
|
|
414
|
+
addAutoGeneratedFeature(feature) {
|
|
415
|
+
const id = this.generateFeatureId(feature.feature);
|
|
416
|
+
this.autoGeneratedFeatures.push({
|
|
417
|
+
id,
|
|
418
|
+
...feature,
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Generate unique ID for feature
|
|
423
|
+
*/
|
|
424
|
+
generateFeatureId(feature) {
|
|
425
|
+
return feature
|
|
426
|
+
.toLowerCase()
|
|
427
|
+
.replace(/[^a-z0-9\s]/g, "")
|
|
428
|
+
.replace(/\s+/g, "-")
|
|
429
|
+
.substring(0, 50);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
exports.ContextValidator = ContextValidator;
|
|
433
|
+
//# sourceMappingURL=ContextValidator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContextValidator.js","sourceRoot":"","sources":["../../src/services/ContextValidator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export interface ComponentMutation {
|
|
2
|
+
id: string;
|
|
3
|
+
componentPath: string;
|
|
4
|
+
timestamp: string;
|
|
5
|
+
actor: "human" | "ai" | "system";
|
|
6
|
+
before: string;
|
|
7
|
+
after: string;
|
|
8
|
+
diff: string;
|
|
9
|
+
patch: string;
|
|
10
|
+
chainOfThought?: string;
|
|
11
|
+
confidence?: number;
|
|
12
|
+
riskFlags: string[];
|
|
13
|
+
tests: {
|
|
14
|
+
unit: string[];
|
|
15
|
+
lint: string[];
|
|
16
|
+
typecheck: string[];
|
|
17
|
+
results: {
|
|
18
|
+
unit: {
|
|
19
|
+
passed: number;
|
|
20
|
+
failed: number;
|
|
21
|
+
details: string[];
|
|
22
|
+
};
|
|
23
|
+
lint: {
|
|
24
|
+
passed: boolean;
|
|
25
|
+
details: string[];
|
|
26
|
+
};
|
|
27
|
+
typecheck: {
|
|
28
|
+
passed: boolean;
|
|
29
|
+
details: string[];
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
status: "proposed" | "applied" | "rejected";
|
|
34
|
+
appliedAt?: string;
|
|
35
|
+
rejectedAt?: string;
|
|
36
|
+
rejectionReason?: string;
|
|
37
|
+
}
|
|
38
|
+
export declare class MutationLogger {
|
|
39
|
+
private mutationsDir;
|
|
40
|
+
constructor(contextDir: string);
|
|
41
|
+
private ensureMutationsDir;
|
|
42
|
+
private getComponentMutationsDir;
|
|
43
|
+
private generateMutationId;
|
|
44
|
+
logMutation(mutation: Omit<ComponentMutation, "id" | "timestamp">): Promise<string>;
|
|
45
|
+
getMutationHistory(componentPath: string): Promise<ComponentMutation[]>;
|
|
46
|
+
getLastApprovedVersion(componentPath: string): Promise<ComponentMutation | null>;
|
|
47
|
+
getLastProposedVersion(componentPath: string): Promise<ComponentMutation | null>;
|
|
48
|
+
updateMutationStatus(mutationId: string, status: "applied" | "rejected", reason?: string): Promise<void>;
|
|
49
|
+
private getAllMutations;
|
|
50
|
+
createMutationFromRefinement(componentPath: string, before: string, after: string, chainOfThought: string, confidence: number, riskFlags?: string[]): Promise<string>;
|
|
51
|
+
getMutationById(mutationId: string): Promise<ComponentMutation | null>;
|
|
52
|
+
deleteMutation(mutationId: string): Promise<void>;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=MutationLogger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MutationLogger.d.ts","sourceRoot":"","sources":["../../src/services/MutationLogger.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,GAAG,IAAI,GAAG,QAAQ,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,SAAS,EAAE,MAAM,EAAE,CAAC;QACpB,OAAO,EAAE;YACP,IAAI,EAAE;gBAAE,MAAM,EAAE,MAAM,CAAC;gBAAC,MAAM,EAAE,MAAM,CAAC;gBAAC,OAAO,EAAE,MAAM,EAAE,CAAA;aAAE,CAAC;YAC5D,IAAI,EAAE;gBAAE,MAAM,EAAE,OAAO,CAAC;gBAAC,OAAO,EAAE,MAAM,EAAE,CAAA;aAAE,CAAC;YAC7C,SAAS,EAAE;gBAAE,MAAM,EAAE,OAAO,CAAC;gBAAC,OAAO,EAAE,MAAM,EAAE,CAAA;aAAE,CAAC;SACnD,CAAC;KACH,CAAC;IACF,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,UAAU,CAAC;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,YAAY,CAAS;gBAEjB,UAAU,EAAE,MAAM;IAK9B,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,wBAAwB;IAQhC,OAAO,CAAC,kBAAkB;IAMpB,WAAW,CACf,QAAQ,EAAE,IAAI,CAAC,iBAAiB,EAAE,IAAI,GAAG,WAAW,CAAC,GACpD,OAAO,CAAC,MAAM,CAAC;IAmBZ,kBAAkB,CACtB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,iBAAiB,EAAE,CAAC;IA6BzB,sBAAsB,CAC1B,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAc9B,sBAAsB,CAC1B,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAc9B,oBAAoB,CACxB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,SAAS,GAAG,UAAU,EAC9B,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC;YA2BF,eAAe;IAmBvB,4BAA4B,CAChC,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,SAAS,GAAE,MAAM,EAAO,GACvB,OAAO,CAAC,MAAM,CAAC;IA6BZ,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAKtE,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAgBxD"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.MutationLogger = void 0;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const diff_1 = require("diff");
|
|
10
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
11
|
+
class MutationLogger {
|
|
12
|
+
constructor(contextDir) {
|
|
13
|
+
this.mutationsDir = path_1.default.join(contextDir, ".mycontext", "mutations");
|
|
14
|
+
this.ensureMutationsDir();
|
|
15
|
+
}
|
|
16
|
+
ensureMutationsDir() {
|
|
17
|
+
if (!fs_1.default.existsSync(this.mutationsDir)) {
|
|
18
|
+
fs_1.default.mkdirSync(this.mutationsDir, { recursive: true });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
getComponentMutationsDir(componentName) {
|
|
22
|
+
const componentDir = path_1.default.join(this.mutationsDir, componentName);
|
|
23
|
+
if (!fs_1.default.existsSync(componentDir)) {
|
|
24
|
+
fs_1.default.mkdirSync(componentDir, { recursive: true });
|
|
25
|
+
}
|
|
26
|
+
return componentDir;
|
|
27
|
+
}
|
|
28
|
+
generateMutationId() {
|
|
29
|
+
const timestamp = Date.now();
|
|
30
|
+
const random = Math.random().toString(36).substring(2, 8);
|
|
31
|
+
return `mutation-${timestamp}-${random}`;
|
|
32
|
+
}
|
|
33
|
+
async logMutation(mutation) {
|
|
34
|
+
const id = this.generateMutationId();
|
|
35
|
+
const timestamp = new Date().toISOString();
|
|
36
|
+
const fullMutation = {
|
|
37
|
+
...mutation,
|
|
38
|
+
id,
|
|
39
|
+
timestamp,
|
|
40
|
+
};
|
|
41
|
+
const componentDir = this.getComponentMutationsDir(mutation.componentPath);
|
|
42
|
+
const mutationFile = path_1.default.join(componentDir, `${id}.json`);
|
|
43
|
+
fs_1.default.writeFileSync(mutationFile, JSON.stringify(fullMutation, null, 2));
|
|
44
|
+
console.log(chalk_1.default.green(`✅ Mutation logged: ${id}`));
|
|
45
|
+
return id;
|
|
46
|
+
}
|
|
47
|
+
async getMutationHistory(componentPath) {
|
|
48
|
+
const componentDir = this.getComponentMutationsDir(componentPath);
|
|
49
|
+
if (!fs_1.default.existsSync(componentDir)) {
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
const files = fs_1.default
|
|
53
|
+
.readdirSync(componentDir)
|
|
54
|
+
.filter((file) => file.endsWith(".json"))
|
|
55
|
+
.sort();
|
|
56
|
+
const mutations = [];
|
|
57
|
+
for (const file of files) {
|
|
58
|
+
try {
|
|
59
|
+
const content = fs_1.default.readFileSync(path_1.default.join(componentDir, file), "utf8");
|
|
60
|
+
const mutation = JSON.parse(content);
|
|
61
|
+
mutations.push(mutation);
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
console.warn(chalk_1.default.yellow(`⚠️ Failed to parse mutation file: ${file}`));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return mutations;
|
|
68
|
+
}
|
|
69
|
+
async getLastApprovedVersion(componentPath) {
|
|
70
|
+
const mutations = await this.getMutationHistory(componentPath);
|
|
71
|
+
// Find the most recent applied mutation
|
|
72
|
+
const appliedMutations = mutations
|
|
73
|
+
.filter((m) => m.status === "applied")
|
|
74
|
+
.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
|
|
75
|
+
return appliedMutations[0] || null;
|
|
76
|
+
}
|
|
77
|
+
async getLastProposedVersion(componentPath) {
|
|
78
|
+
const mutations = await this.getMutationHistory(componentPath);
|
|
79
|
+
// Find the most recent proposed mutation
|
|
80
|
+
const proposedMutations = mutations
|
|
81
|
+
.filter((m) => m.status === "proposed")
|
|
82
|
+
.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
|
|
83
|
+
return proposedMutations[0] || null;
|
|
84
|
+
}
|
|
85
|
+
async updateMutationStatus(mutationId, status, reason) {
|
|
86
|
+
const mutations = await this.getAllMutations();
|
|
87
|
+
const mutation = mutations.find((m) => m.id === mutationId);
|
|
88
|
+
if (!mutation) {
|
|
89
|
+
throw new Error(`Mutation ${mutationId} not found`);
|
|
90
|
+
}
|
|
91
|
+
mutation.status = status;
|
|
92
|
+
if (status === "applied") {
|
|
93
|
+
mutation.appliedAt = new Date().toISOString();
|
|
94
|
+
}
|
|
95
|
+
else if (status === "rejected") {
|
|
96
|
+
mutation.rejectedAt = new Date().toISOString();
|
|
97
|
+
mutation.rejectionReason = reason;
|
|
98
|
+
}
|
|
99
|
+
const componentDir = this.getComponentMutationsDir(mutation.componentPath);
|
|
100
|
+
const mutationFile = path_1.default.join(componentDir, `${mutationId}.json`);
|
|
101
|
+
fs_1.default.writeFileSync(mutationFile, JSON.stringify(mutation, null, 2));
|
|
102
|
+
console.log(chalk_1.default.green(`✅ Mutation ${mutationId} status updated to: ${status}`));
|
|
103
|
+
}
|
|
104
|
+
async getAllMutations() {
|
|
105
|
+
if (!fs_1.default.existsSync(this.mutationsDir)) {
|
|
106
|
+
return [];
|
|
107
|
+
}
|
|
108
|
+
const allMutations = [];
|
|
109
|
+
const componentDirs = fs_1.default.readdirSync(this.mutationsDir);
|
|
110
|
+
for (const componentDir of componentDirs) {
|
|
111
|
+
const componentPath = path_1.default.join(this.mutationsDir, componentDir);
|
|
112
|
+
if (fs_1.default.statSync(componentPath).isDirectory()) {
|
|
113
|
+
const mutations = await this.getMutationHistory(componentDir);
|
|
114
|
+
allMutations.push(...mutations);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return allMutations;
|
|
118
|
+
}
|
|
119
|
+
async createMutationFromRefinement(componentPath, before, after, chainOfThought, confidence, riskFlags = []) {
|
|
120
|
+
const diff = (0, diff_1.createPatch)(componentPath, before, after);
|
|
121
|
+
const mutation = {
|
|
122
|
+
componentPath,
|
|
123
|
+
actor: "ai",
|
|
124
|
+
before,
|
|
125
|
+
after,
|
|
126
|
+
diff,
|
|
127
|
+
patch: diff,
|
|
128
|
+
chainOfThought,
|
|
129
|
+
confidence,
|
|
130
|
+
riskFlags,
|
|
131
|
+
tests: {
|
|
132
|
+
unit: [],
|
|
133
|
+
lint: [],
|
|
134
|
+
typecheck: [],
|
|
135
|
+
results: {
|
|
136
|
+
unit: { passed: 0, failed: 0, details: [] },
|
|
137
|
+
lint: { passed: false, details: [] },
|
|
138
|
+
typecheck: { passed: false, details: [] },
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
status: "proposed",
|
|
142
|
+
};
|
|
143
|
+
return await this.logMutation(mutation);
|
|
144
|
+
}
|
|
145
|
+
async getMutationById(mutationId) {
|
|
146
|
+
const mutations = await this.getAllMutations();
|
|
147
|
+
return mutations.find((m) => m.id === mutationId) || null;
|
|
148
|
+
}
|
|
149
|
+
async deleteMutation(mutationId) {
|
|
150
|
+
const mutations = await this.getAllMutations();
|
|
151
|
+
const mutation = mutations.find((m) => m.id === mutationId);
|
|
152
|
+
if (!mutation) {
|
|
153
|
+
throw new Error(`Mutation ${mutationId} not found`);
|
|
154
|
+
}
|
|
155
|
+
const componentDir = this.getComponentMutationsDir(mutation.componentPath);
|
|
156
|
+
const mutationFile = path_1.default.join(componentDir, `${mutationId}.json`);
|
|
157
|
+
if (fs_1.default.existsSync(mutationFile)) {
|
|
158
|
+
fs_1.default.unlinkSync(mutationFile);
|
|
159
|
+
console.log(chalk_1.default.green(`✅ Mutation ${mutationId} deleted`));
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
exports.MutationLogger = MutationLogger;
|
|
164
|
+
//# sourceMappingURL=MutationLogger.js.map
|