codebakers 4.1.0 → 4.3.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.
- package/dist/index.js +240 -9
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2177,6 +2177,24 @@ var INTENT_PATTERNS = [
|
|
|
2177
2177
|
weight: 8
|
|
2178
2178
|
},
|
|
2179
2179
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
2180
|
+
// WEBSITE REVIEW - Audit a website URL
|
|
2181
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
2182
|
+
{
|
|
2183
|
+
intent: "website-review",
|
|
2184
|
+
patterns: [
|
|
2185
|
+
/\b(review|audit|check|analyze|scan)\b.*\b(website|site|url|page|webpage)\b/i,
|
|
2186
|
+
/\b(website|site|url|page)\b.*\b(review|audit|check|issues|seo|accessibility)\b/i,
|
|
2187
|
+
/\bseo\s*(audit|check|review|analysis)\b/i,
|
|
2188
|
+
/\baccessibility\s*(audit|check|review)\b/i,
|
|
2189
|
+
/\bcheck\s*(this\s*)?(url|site|website)\b/i,
|
|
2190
|
+
/\bwhat('s| is)\s*wrong\s*with\s*(this\s*)?(website|site|url)\b/i,
|
|
2191
|
+
/\breview\s+(https?:\/\/|www\.)/i,
|
|
2192
|
+
/\baudit\s+(https?:\/\/|www\.)/i
|
|
2193
|
+
],
|
|
2194
|
+
keywords: ["review website", "audit website", "check site", "seo audit", "accessibility check", "website issues", "scan url"],
|
|
2195
|
+
weight: 9
|
|
2196
|
+
},
|
|
2197
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
2180
2198
|
// PATTERNS - Pattern rules
|
|
2181
2199
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
2182
2200
|
{
|
|
@@ -5259,6 +5277,161 @@ Respond with ONLY valid JSON:
|
|
|
5259
5277
|
};
|
|
5260
5278
|
}
|
|
5261
5279
|
}
|
|
5280
|
+
// ============================================================================
|
|
5281
|
+
// WEBSITE REVIEW/AUDIT
|
|
5282
|
+
// ============================================================================
|
|
5283
|
+
async reviewWebsite(url) {
|
|
5284
|
+
const html = await this.fetchURL(url);
|
|
5285
|
+
if (!html) {
|
|
5286
|
+
return {
|
|
5287
|
+
url,
|
|
5288
|
+
score: 0,
|
|
5289
|
+
issues: [{ category: "error", severity: "error", message: "Unable to fetch URL" }],
|
|
5290
|
+
suggestions: [],
|
|
5291
|
+
seoAnalysis: null,
|
|
5292
|
+
accessibilityAnalysis: null,
|
|
5293
|
+
performanceHints: []
|
|
5294
|
+
};
|
|
5295
|
+
}
|
|
5296
|
+
const prompt = `Review this website HTML for issues, best practices, SEO, and accessibility.
|
|
5297
|
+
|
|
5298
|
+
URL: ${url}
|
|
5299
|
+
|
|
5300
|
+
HTML:
|
|
5301
|
+
${html.slice(0, 4e4)}
|
|
5302
|
+
|
|
5303
|
+
Analyze and respond with ONLY valid JSON:
|
|
5304
|
+
{
|
|
5305
|
+
"score": 85,
|
|
5306
|
+
"issues": [
|
|
5307
|
+
{"category": "seo", "severity": "warning", "message": "Missing meta description", "fix": "Add <meta name='description'>"},
|
|
5308
|
+
{"category": "accessibility", "severity": "error", "message": "Images missing alt text", "fix": "Add alt attributes to all images"},
|
|
5309
|
+
{"category": "performance", "severity": "warning", "message": "Large inline styles", "fix": "Move to external CSS"},
|
|
5310
|
+
{"category": "security", "severity": "error", "message": "Mixed content (http in https)", "fix": "Use https for all resources"},
|
|
5311
|
+
{"category": "html", "severity": "warning", "message": "Invalid HTML structure", "fix": "Fix nesting issues"}
|
|
5312
|
+
],
|
|
5313
|
+
"suggestions": [
|
|
5314
|
+
"Add Open Graph tags for social sharing",
|
|
5315
|
+
"Implement lazy loading for images",
|
|
5316
|
+
"Add structured data markup"
|
|
5317
|
+
],
|
|
5318
|
+
"seoAnalysis": {
|
|
5319
|
+
"title": "Page title here",
|
|
5320
|
+
"titleLength": 55,
|
|
5321
|
+
"hasMetaDescription": true,
|
|
5322
|
+
"metaDescriptionLength": 150,
|
|
5323
|
+
"hasCanonical": false,
|
|
5324
|
+
"hasOpenGraph": false,
|
|
5325
|
+
"headingStructure": "H1 > H2 > H3 (good)",
|
|
5326
|
+
"keywordDensity": "moderate"
|
|
5327
|
+
},
|
|
5328
|
+
"accessibilityAnalysis": {
|
|
5329
|
+
"hasSkipLink": false,
|
|
5330
|
+
"imagesWithAlt": 8,
|
|
5331
|
+
"imagesWithoutAlt": 3,
|
|
5332
|
+
"formLabels": "all labeled",
|
|
5333
|
+
"colorContrast": "needs review",
|
|
5334
|
+
"keyboardNavigation": "partial"
|
|
5335
|
+
},
|
|
5336
|
+
"performanceHints": [
|
|
5337
|
+
"Compress images",
|
|
5338
|
+
"Minify CSS/JS",
|
|
5339
|
+
"Enable caching headers"
|
|
5340
|
+
]
|
|
5341
|
+
}`;
|
|
5342
|
+
const response = await this.anthropic.messages.create({
|
|
5343
|
+
model: "claude-sonnet-4-20250514",
|
|
5344
|
+
max_tokens: 4096,
|
|
5345
|
+
messages: [{ role: "user", content: prompt }]
|
|
5346
|
+
});
|
|
5347
|
+
const content = response.content[0]?.type === "text" ? response.content[0].text : "";
|
|
5348
|
+
try {
|
|
5349
|
+
const jsonStr = content.replace(/```json\n?|\n?```/g, "").trim();
|
|
5350
|
+
return { url, ...JSON.parse(jsonStr) };
|
|
5351
|
+
} catch {
|
|
5352
|
+
return {
|
|
5353
|
+
url,
|
|
5354
|
+
score: 0,
|
|
5355
|
+
issues: [{ category: "error", severity: "error", message: "Unable to analyze website" }],
|
|
5356
|
+
suggestions: [],
|
|
5357
|
+
seoAnalysis: null,
|
|
5358
|
+
accessibilityAnalysis: null,
|
|
5359
|
+
performanceHints: []
|
|
5360
|
+
};
|
|
5361
|
+
}
|
|
5362
|
+
}
|
|
5363
|
+
formatWebsiteReview(review) {
|
|
5364
|
+
let output = "\n";
|
|
5365
|
+
output += colors.muted(" \u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E\n");
|
|
5366
|
+
output += colors.muted(" \u2502") + colors.white(" \u{1F310} Website Review ") + colors.muted("\u2502\n");
|
|
5367
|
+
output += colors.muted(" \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F\n\n");
|
|
5368
|
+
output += colors.muted(` URL: ${review.url}
|
|
5369
|
+
|
|
5370
|
+
`);
|
|
5371
|
+
const scoreColor = review.score >= 80 ? colors.success : review.score >= 60 ? colors.warning : colors.error;
|
|
5372
|
+
output += colors.white(" Score: ") + scoreColor(`${review.score}/100
|
|
5373
|
+
|
|
5374
|
+
`);
|
|
5375
|
+
if (review.issues && review.issues.length > 0) {
|
|
5376
|
+
output += colors.white(" Issues Found:\n");
|
|
5377
|
+
const categories = ["error", "security", "accessibility", "seo", "performance", "html"];
|
|
5378
|
+
for (const cat of categories) {
|
|
5379
|
+
const catIssues = review.issues.filter((i) => i.category === cat || i.severity === cat);
|
|
5380
|
+
if (catIssues.length > 0) {
|
|
5381
|
+
for (const issue of catIssues.slice(0, 3)) {
|
|
5382
|
+
const icon = issue.severity === "error" ? colors.error("\u2717") : colors.warning("\u26A0");
|
|
5383
|
+
output += ` ${icon} ${colors.muted(`[${issue.category}]`)} ${issue.message}
|
|
5384
|
+
`;
|
|
5385
|
+
if (issue.fix) {
|
|
5386
|
+
output += colors.dim(` \u2192 ${issue.fix}
|
|
5387
|
+
`);
|
|
5388
|
+
}
|
|
5389
|
+
}
|
|
5390
|
+
}
|
|
5391
|
+
}
|
|
5392
|
+
output += "\n";
|
|
5393
|
+
}
|
|
5394
|
+
if (review.seoAnalysis) {
|
|
5395
|
+
output += colors.white(" SEO:\n");
|
|
5396
|
+
const seo = review.seoAnalysis;
|
|
5397
|
+
output += colors.muted(` Title: ${seo.title || "Missing"} (${seo.titleLength || 0} chars)
|
|
5398
|
+
`);
|
|
5399
|
+
output += colors.muted(` Meta Description: ${seo.hasMetaDescription ? "\u2713" : "\u2717"}
|
|
5400
|
+
`);
|
|
5401
|
+
output += colors.muted(` Open Graph: ${seo.hasOpenGraph ? "\u2713" : "\u2717"}
|
|
5402
|
+
`);
|
|
5403
|
+
output += colors.muted(` Headings: ${seo.headingStructure || "Unknown"}
|
|
5404
|
+
|
|
5405
|
+
`);
|
|
5406
|
+
}
|
|
5407
|
+
if (review.accessibilityAnalysis) {
|
|
5408
|
+
output += colors.white(" Accessibility:\n");
|
|
5409
|
+
const a11y = review.accessibilityAnalysis;
|
|
5410
|
+
output += colors.muted(` Images with alt: ${a11y.imagesWithAlt || 0}/${(a11y.imagesWithAlt || 0) + (a11y.imagesWithoutAlt || 0)}
|
|
5411
|
+
`);
|
|
5412
|
+
output += colors.muted(` Skip link: ${a11y.hasSkipLink ? "\u2713" : "\u2717"}
|
|
5413
|
+
`);
|
|
5414
|
+
output += colors.muted(` Form labels: ${a11y.formLabels || "Unknown"}
|
|
5415
|
+
|
|
5416
|
+
`);
|
|
5417
|
+
}
|
|
5418
|
+
if (review.suggestions && review.suggestions.length > 0) {
|
|
5419
|
+
output += colors.white(" Suggestions:\n");
|
|
5420
|
+
for (const suggestion of review.suggestions.slice(0, 5)) {
|
|
5421
|
+
output += colors.dim(` \u2022 ${suggestion}
|
|
5422
|
+
`);
|
|
5423
|
+
}
|
|
5424
|
+
output += "\n";
|
|
5425
|
+
}
|
|
5426
|
+
if (review.performanceHints && review.performanceHints.length > 0) {
|
|
5427
|
+
output += colors.white(" Performance Tips:\n");
|
|
5428
|
+
for (const hint of review.performanceHints.slice(0, 3)) {
|
|
5429
|
+
output += colors.dim(` \u2022 ${hint}
|
|
5430
|
+
`);
|
|
5431
|
+
}
|
|
5432
|
+
}
|
|
5433
|
+
return output;
|
|
5434
|
+
}
|
|
5262
5435
|
async buildFromURL(url, specificSection) {
|
|
5263
5436
|
const html = await this.fetchURL(url);
|
|
5264
5437
|
if (!html) {
|
|
@@ -9804,7 +9977,32 @@ var VercelService = class {
|
|
|
9804
9977
|
};
|
|
9805
9978
|
|
|
9806
9979
|
// src/index.ts
|
|
9807
|
-
|
|
9980
|
+
import * as readline from "readline";
|
|
9981
|
+
var VERSION = "4.3.0";
|
|
9982
|
+
async function showChatInput() {
|
|
9983
|
+
return new Promise((resolve) => {
|
|
9984
|
+
const width = Math.min(process.stdout.columns || 80, 70);
|
|
9985
|
+
const innerWidth = width - 4;
|
|
9986
|
+
console.log("");
|
|
9987
|
+
console.log(colors.primary(` \u256D${"\u2500".repeat(innerWidth)}\u256E`));
|
|
9988
|
+
const rl = readline.createInterface({
|
|
9989
|
+
input: process.stdin,
|
|
9990
|
+
output: process.stdout,
|
|
9991
|
+
terminal: true
|
|
9992
|
+
});
|
|
9993
|
+
rl.on("SIGINT", () => {
|
|
9994
|
+
rl.close();
|
|
9995
|
+
console.log(colors.primary(` \u2570${"\u2500".repeat(innerWidth)}\u256F`));
|
|
9996
|
+
resolve(null);
|
|
9997
|
+
});
|
|
9998
|
+
process.stdout.write(colors.primary(" \u2502 ") + colors.dim("\u203A "));
|
|
9999
|
+
rl.question("", (answer) => {
|
|
10000
|
+
rl.close();
|
|
10001
|
+
console.log(colors.primary(` \u2570${"\u2500".repeat(innerWidth)}\u256F`));
|
|
10002
|
+
resolve(answer);
|
|
10003
|
+
});
|
|
10004
|
+
});
|
|
10005
|
+
}
|
|
9808
10006
|
async function main() {
|
|
9809
10007
|
const config = new Config();
|
|
9810
10008
|
const args = process.argv.slice(2);
|
|
@@ -9878,17 +10076,11 @@ async function main() {
|
|
|
9878
10076
|
console.log(colors.dim(" Just tell me what you want to build or do."));
|
|
9879
10077
|
console.log(colors.dim(" Type /help to see examples."));
|
|
9880
10078
|
console.log("");
|
|
9881
|
-
const terminalHeight = process.stdout.rows || 24;
|
|
9882
|
-
const paddingLines = Math.max(0, terminalHeight - 14);
|
|
9883
|
-
console.log("\n".repeat(paddingLines));
|
|
9884
10079
|
let lastAction;
|
|
9885
10080
|
let running = true;
|
|
9886
10081
|
while (running) {
|
|
9887
|
-
const input = await
|
|
9888
|
-
|
|
9889
|
-
placeholder: 'e.g. "Add a login page" or "Check my code"'
|
|
9890
|
-
});
|
|
9891
|
-
if (p7.isCancel(input)) {
|
|
10082
|
+
const input = await showChatInput();
|
|
10083
|
+
if (input === null) {
|
|
9892
10084
|
running = false;
|
|
9893
10085
|
console.log("");
|
|
9894
10086
|
console.log(colors.muted(" Goodbye! \u{1F44B}"));
|
|
@@ -10038,6 +10230,9 @@ async function main() {
|
|
|
10038
10230
|
case "audit":
|
|
10039
10231
|
await handleAudit(result.params?.args, ctx);
|
|
10040
10232
|
break;
|
|
10233
|
+
case "website-review":
|
|
10234
|
+
await handleWebsiteReview(cmd, ctx);
|
|
10235
|
+
break;
|
|
10041
10236
|
case "patterns":
|
|
10042
10237
|
await handlePatterns(result.params?.args, ctx);
|
|
10043
10238
|
break;
|
|
@@ -10943,6 +11138,42 @@ async function handleAudit(args, ctx) {
|
|
|
10943
11138
|
}
|
|
10944
11139
|
}
|
|
10945
11140
|
}
|
|
11141
|
+
async function handleWebsiteReview(input, ctx) {
|
|
11142
|
+
const { config } = ctx;
|
|
11143
|
+
const urlMatch = input.match(/(https?:\/\/[^\s]+)|(www\.[^\s]+)/i);
|
|
11144
|
+
let url = urlMatch ? urlMatch[0] : "";
|
|
11145
|
+
if (!url) {
|
|
11146
|
+
const urlInput = await p7.text({
|
|
11147
|
+
message: "Website URL to review:",
|
|
11148
|
+
placeholder: "https://example.com"
|
|
11149
|
+
});
|
|
11150
|
+
if (p7.isCancel(urlInput) || !urlInput) {
|
|
11151
|
+
console.log(colors.muted(" Cancelled"));
|
|
11152
|
+
return;
|
|
11153
|
+
}
|
|
11154
|
+
url = urlInput;
|
|
11155
|
+
}
|
|
11156
|
+
if (!url.startsWith("http")) {
|
|
11157
|
+
url = "https://" + url;
|
|
11158
|
+
}
|
|
11159
|
+
console.log("");
|
|
11160
|
+
const spinner = ora3(`Reviewing ${url}...`).start();
|
|
11161
|
+
try {
|
|
11162
|
+
const visualHandler = new VisualInputHandler(config);
|
|
11163
|
+
const review = await visualHandler.reviewWebsite(url);
|
|
11164
|
+
spinner.stop();
|
|
11165
|
+
console.log(visualHandler.formatWebsiteReview(review));
|
|
11166
|
+
console.log("");
|
|
11167
|
+
console.log(colors.muted(" What you can do:"));
|
|
11168
|
+
console.log(colors.dim(' "Build a better version of this"'));
|
|
11169
|
+
console.log(colors.dim(' "Fix the accessibility issues"'));
|
|
11170
|
+
console.log(colors.dim(' "Create an SEO-optimized version"'));
|
|
11171
|
+
console.log("");
|
|
11172
|
+
} catch (error) {
|
|
11173
|
+
spinner.stop();
|
|
11174
|
+
showError(error instanceof Error ? error.message : "Failed to review website");
|
|
11175
|
+
}
|
|
11176
|
+
}
|
|
10946
11177
|
async function handlePatterns(args, ctx) {
|
|
10947
11178
|
const { config } = ctx;
|
|
10948
11179
|
const auditor = new CodebaseAuditor(config);
|
package/package.json
CHANGED