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.
Files changed (2) hide show
  1. package/dist/index.js +240 -9
  2. 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
- var VERSION = "4.1.0";
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 p7.text({
9888
- message: colors.primary(">"),
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codebakers",
3
- "version": "4.1.0",
3
+ "version": "4.3.0",
4
4
  "description": "AI-powered product development CLI - Build faster with pattern enforcement, persistent memory, and parallel agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",