@vibecheckai/cli 3.0.2 → 3.0.3
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 +9 -1
- package/bin/cli-hygiene.js +0 -241
- package/bin/guardrail.js +0 -834
- package/bin/runners/cli-utils.js +0 -1070
- package/bin/runners/context/ai-task-decomposer.js +0 -337
- package/bin/runners/context/analyzer.js +0 -462
- package/bin/runners/context/api-contracts.js +0 -427
- package/bin/runners/context/context-diff.js +0 -342
- package/bin/runners/context/context-pruner.js +0 -291
- package/bin/runners/context/dependency-graph.js +0 -414
- package/bin/runners/context/generators/claude.js +0 -107
- package/bin/runners/context/generators/codex.js +0 -108
- package/bin/runners/context/generators/copilot.js +0 -119
- package/bin/runners/context/generators/cursor.js +0 -514
- package/bin/runners/context/generators/mcp.js +0 -151
- package/bin/runners/context/generators/windsurf.js +0 -180
- package/bin/runners/context/git-context.js +0 -302
- package/bin/runners/context/index.js +0 -1042
- package/bin/runners/context/insights.js +0 -173
- package/bin/runners/context/mcp-server/generate-rules.js +0 -337
- package/bin/runners/context/mcp-server/index.js +0 -1176
- package/bin/runners/context/mcp-server/package.json +0 -24
- package/bin/runners/context/memory.js +0 -200
- package/bin/runners/context/monorepo.js +0 -215
- package/bin/runners/context/multi-repo-federation.js +0 -404
- package/bin/runners/context/patterns.js +0 -253
- package/bin/runners/context/proof-context.js +0 -972
- package/bin/runners/context/security-scanner.js +0 -303
- package/bin/runners/context/semantic-search.js +0 -350
- package/bin/runners/context/shared.js +0 -264
- package/bin/runners/context/team-conventions.js +0 -310
- package/bin/runners/lib/ai-bridge.js +0 -416
- package/bin/runners/lib/analysis-core.js +0 -271
- package/bin/runners/lib/analyzers.js +0 -541
- package/bin/runners/lib/audit-bridge.js +0 -391
- package/bin/runners/lib/auth-truth.js +0 -193
- package/bin/runners/lib/auth.js +0 -215
- package/bin/runners/lib/backup.js +0 -62
- package/bin/runners/lib/billing.js +0 -107
- package/bin/runners/lib/claims.js +0 -118
- package/bin/runners/lib/cli-ui.js +0 -540
- package/bin/runners/lib/compliance-bridge-new.js +0 -0
- package/bin/runners/lib/compliance-bridge.js +0 -165
- package/bin/runners/lib/contracts/auth-contract.js +0 -194
- package/bin/runners/lib/contracts/env-contract.js +0 -178
- package/bin/runners/lib/contracts/external-contract.js +0 -198
- package/bin/runners/lib/contracts/guard.js +0 -168
- package/bin/runners/lib/contracts/index.js +0 -89
- package/bin/runners/lib/contracts/plan-validator.js +0 -311
- package/bin/runners/lib/contracts/route-contract.js +0 -192
- package/bin/runners/lib/detect.js +0 -89
- package/bin/runners/lib/doctor/autofix.js +0 -254
- package/bin/runners/lib/doctor/index.js +0 -37
- package/bin/runners/lib/doctor/modules/dependencies.js +0 -325
- package/bin/runners/lib/doctor/modules/index.js +0 -46
- package/bin/runners/lib/doctor/modules/network.js +0 -250
- package/bin/runners/lib/doctor/modules/project.js +0 -312
- package/bin/runners/lib/doctor/modules/runtime.js +0 -224
- package/bin/runners/lib/doctor/modules/security.js +0 -348
- package/bin/runners/lib/doctor/modules/system.js +0 -213
- package/bin/runners/lib/doctor/modules/vibecheck.js +0 -394
- package/bin/runners/lib/doctor/reporter.js +0 -262
- package/bin/runners/lib/doctor/service.js +0 -262
- package/bin/runners/lib/doctor/types.js +0 -113
- package/bin/runners/lib/doctor/ui.js +0 -263
- package/bin/runners/lib/doctor-enhanced.js +0 -233
- package/bin/runners/lib/doctor-v2.js +0 -608
- package/bin/runners/lib/enforcement.js +0 -72
|
@@ -1,337 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AI Task Decomposer Module
|
|
3
|
-
* Analyzes user prompts and selects relevant context
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const { semanticSearch, loadSearchIndex } = require("./semantic-search");
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Task type patterns
|
|
10
|
-
*/
|
|
11
|
-
const TASK_PATTERNS = {
|
|
12
|
-
create: {
|
|
13
|
-
keywords: ["create", "add", "build", "make", "new", "implement", "write"],
|
|
14
|
-
contextTypes: ["components", "hooks", "types", "patterns"],
|
|
15
|
-
priority: ["components", "hooks", "types"],
|
|
16
|
-
},
|
|
17
|
-
fix: {
|
|
18
|
-
keywords: ["fix", "bug", "error", "issue", "problem", "broken"],
|
|
19
|
-
contextTypes: ["components", "utils", "error-handling", "logs"],
|
|
20
|
-
priority: ["error-handling", "components", "utils"],
|
|
21
|
-
},
|
|
22
|
-
refactor: {
|
|
23
|
-
keywords: ["refactor", "improve", "optimize", "clean", "reorganize"],
|
|
24
|
-
contextTypes: ["architecture", "patterns", "utils", "components"],
|
|
25
|
-
priority: ["architecture", "patterns", "components"],
|
|
26
|
-
},
|
|
27
|
-
test: {
|
|
28
|
-
keywords: ["test", "spec", "coverage", "unit", "integration"],
|
|
29
|
-
contextTypes: ["test-files", "components", "utils", "mocks"],
|
|
30
|
-
priority: ["test-files", "components", "utils"],
|
|
31
|
-
},
|
|
32
|
-
api: {
|
|
33
|
-
keywords: ["api", "endpoint", "route", "server", "backend"],
|
|
34
|
-
contextTypes: ["api-routes", "types", "validation", "models"],
|
|
35
|
-
priority: ["api-routes", "types", "validation"],
|
|
36
|
-
},
|
|
37
|
-
style: {
|
|
38
|
-
keywords: ["style", "css", "design", "ui", "theme", "layout"],
|
|
39
|
-
contextTypes: ["styles", "components", "themes"],
|
|
40
|
-
priority: ["styles", "components", "themes"],
|
|
41
|
-
},
|
|
42
|
-
config: {
|
|
43
|
-
keywords: ["config", "setup", "install", "deploy", "build"],
|
|
44
|
-
contextTypes: ["config-files", "package-json", "env-vars"],
|
|
45
|
-
priority: ["config-files", "package-json", "env-vars"],
|
|
46
|
-
},
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Extract task type from prompt
|
|
51
|
-
*/
|
|
52
|
-
function extractTaskType(prompt) {
|
|
53
|
-
const lower = prompt.toLowerCase();
|
|
54
|
-
let bestMatch = null;
|
|
55
|
-
let maxScore = 0;
|
|
56
|
-
|
|
57
|
-
for (const [type, pattern] of Object.entries(TASK_PATTERNS)) {
|
|
58
|
-
let score = 0;
|
|
59
|
-
for (const keyword of pattern.keywords) {
|
|
60
|
-
if (lower.includes(keyword)) {
|
|
61
|
-
score += 1;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
if (score > maxScore) {
|
|
65
|
-
maxScore = score;
|
|
66
|
-
bestMatch = type;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return bestMatch || "general";
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Extract entities from prompt
|
|
75
|
-
*/
|
|
76
|
-
function extractEntities(prompt) {
|
|
77
|
-
const entities = {
|
|
78
|
-
components: [],
|
|
79
|
-
files: [],
|
|
80
|
-
technologies: [],
|
|
81
|
-
features: [],
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
// Component names (PascalCase)
|
|
85
|
-
const componentMatches = prompt.match(/\b[A-Z][a-zA-Z0-9]*\b/g) || [];
|
|
86
|
-
entities.components = [...new Set(componentMatches)];
|
|
87
|
-
|
|
88
|
-
// File paths
|
|
89
|
-
const fileMatches = prompt.match(/[\w\-\/]+\.(ts|tsx|js|jsx|json|css|md)/g) || [];
|
|
90
|
-
entities.files = fileMatches;
|
|
91
|
-
|
|
92
|
-
// Technology keywords
|
|
93
|
-
const techKeywords = [
|
|
94
|
-
"react", "nextjs", "typescript", "prisma", "tailwind", "zustand",
|
|
95
|
-
"zod", "jest", "playwright", "express", "mongodb", "postgresql",
|
|
96
|
-
"graphql", "apollo", "redux", "webpack", "vite", "eslint"
|
|
97
|
-
];
|
|
98
|
-
|
|
99
|
-
for (const tech of techKeywords) {
|
|
100
|
-
if (prompt.toLowerCase().includes(tech)) {
|
|
101
|
-
entities.technologies.push(tech);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Feature keywords
|
|
106
|
-
const featureKeywords = [
|
|
107
|
-
"auth", "authentication", "login", "signup", "dashboard", "admin",
|
|
108
|
-
"profile", "settings", "search", "filter", "pagination", "modal",
|
|
109
|
-
"form", "input", "button", "navigation", "header", "footer"
|
|
110
|
-
];
|
|
111
|
-
|
|
112
|
-
for (const feature of featureKeywords) {
|
|
113
|
-
if (prompt.toLowerCase().includes(feature)) {
|
|
114
|
-
entities.features.push(feature);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return entities;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Build search query from entities
|
|
123
|
-
*/
|
|
124
|
-
function buildSearchQuery(entities, taskType) {
|
|
125
|
-
const terms = [];
|
|
126
|
-
|
|
127
|
-
// Add task-specific terms
|
|
128
|
-
if (taskType && TASK_PATTERNS[taskType]) {
|
|
129
|
-
terms.push(...TASK_PATTERNS[taskType].keywords.slice(0, 2));
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// Add entities
|
|
133
|
-
terms.push(...entities.components);
|
|
134
|
-
terms.push(...entities.features);
|
|
135
|
-
terms.push(...entities.technologies);
|
|
136
|
-
|
|
137
|
-
// Add file-specific terms
|
|
138
|
-
if (entities.files.length > 0) {
|
|
139
|
-
const file = entities.files[0];
|
|
140
|
-
const parts = file.split("/");
|
|
141
|
-
if (parts.length > 1) {
|
|
142
|
-
terms.push(parts[parts.length - 2]); // Directory
|
|
143
|
-
}
|
|
144
|
-
terms.push(path.basename(file, path.extname(file))); // Filename without ext
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return terms.join(" ");
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Select relevant context based on task
|
|
152
|
-
*/
|
|
153
|
-
function selectRelevantContext(searchResults, taskType, maxTokens = 4000) {
|
|
154
|
-
if (!searchResults || searchResults.length === 0) {
|
|
155
|
-
return { files: [], totalTokens: 0 };
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
const priorities = taskType && TASK_PATTERNS[taskType]
|
|
159
|
-
? TASK_PATTERNS[taskType].priority
|
|
160
|
-
: ["components", "hooks", "types", "utils"];
|
|
161
|
-
|
|
162
|
-
// Score files based on type and relevance
|
|
163
|
-
const scored = searchResults.map(result => {
|
|
164
|
-
let score = result.similarity;
|
|
165
|
-
|
|
166
|
-
// Boost based on file type priority
|
|
167
|
-
for (let i = 0; i < priorities.length; i++) {
|
|
168
|
-
if (result.file.includes(priorities[i]) ||
|
|
169
|
-
result.type === priorities[i].slice(0, -1)) {
|
|
170
|
-
score += (priorities.length - i) * 0.2;
|
|
171
|
-
break;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
return { ...result, score };
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
// Sort by combined score
|
|
179
|
-
scored.sort((a, b) => b.score - a.score);
|
|
180
|
-
|
|
181
|
-
// Select files within token limit
|
|
182
|
-
const selected = [];
|
|
183
|
-
let totalTokens = 0;
|
|
184
|
-
|
|
185
|
-
for (const file of scored) {
|
|
186
|
-
const estimatedTokens = file.text.length / 4;
|
|
187
|
-
if (totalTokens + estimatedTokens <= maxTokens) {
|
|
188
|
-
selected.push({
|
|
189
|
-
file: file.file,
|
|
190
|
-
content: file.text,
|
|
191
|
-
relevance: file.score,
|
|
192
|
-
tokens: Math.round(estimatedTokens),
|
|
193
|
-
});
|
|
194
|
-
totalTokens += estimatedTokens;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
return {
|
|
199
|
-
files: selected,
|
|
200
|
-
totalTokens: Math.round(totalTokens),
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Decompose task and generate context plan
|
|
206
|
-
*/
|
|
207
|
-
function decomposeTask(prompt, projectPath, options = {}) {
|
|
208
|
-
const { maxTokens = 4000, includeSemantic = true } = options;
|
|
209
|
-
|
|
210
|
-
// Extract task information
|
|
211
|
-
const taskType = extractTaskType(prompt);
|
|
212
|
-
const entities = extractEntities(prompt);
|
|
213
|
-
const searchQuery = buildSearchQuery(entities, taskType);
|
|
214
|
-
|
|
215
|
-
const plan = {
|
|
216
|
-
prompt,
|
|
217
|
-
taskType,
|
|
218
|
-
entities,
|
|
219
|
-
searchQuery,
|
|
220
|
-
context: {
|
|
221
|
-
files: [],
|
|
222
|
-
totalTokens: 0,
|
|
223
|
-
},
|
|
224
|
-
recommendations: [],
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
// Semantic search if available
|
|
228
|
-
if (includeSemantic) {
|
|
229
|
-
const searchIndex = loadSearchIndex(projectPath);
|
|
230
|
-
if (searchIndex) {
|
|
231
|
-
const searchResults = semanticSearch(searchIndex, searchQuery, 20);
|
|
232
|
-
plan.context = selectRelevantContext(searchResults, taskType, maxTokens);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
// Generate recommendations
|
|
237
|
-
plan.recommendations = generateRecommendations(plan);
|
|
238
|
-
|
|
239
|
-
return plan;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* Generate task-specific recommendations
|
|
244
|
-
*/
|
|
245
|
-
function generateRecommendations(plan) {
|
|
246
|
-
const recommendations = [];
|
|
247
|
-
const { taskType, entities } = plan;
|
|
248
|
-
|
|
249
|
-
// Task-specific recommendations
|
|
250
|
-
if (taskType === "create" && entities.components.length > 0) {
|
|
251
|
-
recommendations.push("Check if similar components already exist");
|
|
252
|
-
recommendations.push("Follow established component patterns");
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
if (taskType === "fix") {
|
|
256
|
-
recommendations.push("Look for error handling patterns");
|
|
257
|
-
recommendations.push("Check console logs and error boundaries");
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
if (taskType === "test") {
|
|
261
|
-
recommendations.push("Review existing test patterns");
|
|
262
|
-
recommendations.push("Use established mocking strategies");
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
if (taskType === "api") {
|
|
266
|
-
recommendations.push("Follow API response patterns");
|
|
267
|
-
recommendations.push("Include proper validation");
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
// Entity-specific recommendations
|
|
271
|
-
if (entities.technologies.includes("typescript")) {
|
|
272
|
-
recommendations.push("Define proper TypeScript types");
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
if (entities.technologies.includes("prisma")) {
|
|
276
|
-
recommendations.push("Check Prisma schema for models");
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
if (entities.technologies.includes("tailwind")) {
|
|
280
|
-
recommendations.push("Use Tailwind CSS classes");
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
return recommendations;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
/**
|
|
287
|
-
* Generate task decomposition report
|
|
288
|
-
*/
|
|
289
|
-
function generateDecompositionReport(plan) {
|
|
290
|
-
let report = `# Task Decomposition Report\n\n`;
|
|
291
|
-
report += `**Task Type:** ${plan.taskType}\n`;
|
|
292
|
-
report += `**Search Query:** "${plan.searchQuery}"\n\n`;
|
|
293
|
-
|
|
294
|
-
// Entities
|
|
295
|
-
report += `## Extracted Entities\n\n`;
|
|
296
|
-
if (plan.entities.components.length > 0) {
|
|
297
|
-
report += `- Components: ${plan.entities.components.join(", ")}\n`;
|
|
298
|
-
}
|
|
299
|
-
if (plan.entities.files.length > 0) {
|
|
300
|
-
report += `- Files: ${plan.entities.files.join(", ")}\n`;
|
|
301
|
-
}
|
|
302
|
-
if (plan.entities.technologies.length > 0) {
|
|
303
|
-
report += `- Technologies: ${plan.entities.technologies.join(", ")}\n`;
|
|
304
|
-
}
|
|
305
|
-
if (plan.entities.features.length > 0) {
|
|
306
|
-
report += `- Features: ${plan.entities.features.join(", ")}\n`;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
// Context
|
|
310
|
-
report += `\n## Selected Context (${plan.context.files.length} files)\n\n`;
|
|
311
|
-
report += `Total Tokens: ${plan.context.totalTokens}\n\n`;
|
|
312
|
-
|
|
313
|
-
for (const file of plan.context.files.slice(0, 10)) {
|
|
314
|
-
report += `### ${file.file}\n`;
|
|
315
|
-
report += `Relevance: ${(file.relevance * 100).toFixed(1)}%\n`;
|
|
316
|
-
report += `Tokens: ${file.tokens}\n\n`;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
// Recommendations
|
|
320
|
-
if (plan.recommendations.length > 0) {
|
|
321
|
-
report += `\n## Recommendations\n\n`;
|
|
322
|
-
for (const rec of plan.recommendations) {
|
|
323
|
-
report += `- ${rec}\n`;
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
return report;
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
module.exports = {
|
|
331
|
-
decomposeTask,
|
|
332
|
-
generateDecompositionReport,
|
|
333
|
-
extractTaskType,
|
|
334
|
-
extractEntities,
|
|
335
|
-
selectRelevantContext,
|
|
336
|
-
TASK_PATTERNS,
|
|
337
|
-
};
|