nairon-bench 0.3.12 → 0.3.13
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 +658 -8
- package/package.json +4 -3
package/dist/index.js
CHANGED
|
@@ -10767,7 +10767,7 @@ function getTechStackSpecificRecommendations(projectContext) {
|
|
|
10767
10767
|
description: "Vercel's React and Next.js patterns for your stack",
|
|
10768
10768
|
impact: "medium",
|
|
10769
10769
|
type: "skill",
|
|
10770
|
-
installCommand: "npx skills add vercel/react-best-practices"
|
|
10770
|
+
installCommand: "npx skills add vercel-labs/agent-skills@vercel-react-best-practices --yes"
|
|
10771
10771
|
});
|
|
10772
10772
|
}
|
|
10773
10773
|
if (database2?.includes("convex")) {
|
|
@@ -21361,12 +21361,651 @@ import { existsSync as existsSync12 } from "node:fs";
|
|
|
21361
21361
|
import { homedir as homedir9 } from "node:os";
|
|
21362
21362
|
import { join as join12 } from "node:path";
|
|
21363
21363
|
init_client();
|
|
21364
|
+
|
|
21365
|
+
// src/lib/recommendations-db.ts
|
|
21366
|
+
var MCP_SERVERS = [
|
|
21367
|
+
{
|
|
21368
|
+
id: "context7",
|
|
21369
|
+
name: "Context7",
|
|
21370
|
+
type: "mcp",
|
|
21371
|
+
description: "Live documentation for any library - reduces API hallucinations by 40%+",
|
|
21372
|
+
installCommand: "claude mcp add context7 https://mcp.context7.com/mcp --transport http",
|
|
21373
|
+
phases: ["requirements", "implementation"],
|
|
21374
|
+
impact: "high",
|
|
21375
|
+
detectionKey: "context7",
|
|
21376
|
+
website: "https://context7.com",
|
|
21377
|
+
badge: "Essential",
|
|
21378
|
+
agents: {
|
|
21379
|
+
"claude-code": { installCommand: "claude mcp add context7 https://mcp.context7.com/mcp --transport http" },
|
|
21380
|
+
opencode: { installCommand: "Add to ~/.config/opencode/config.json mcpServers" }
|
|
21381
|
+
}
|
|
21382
|
+
},
|
|
21383
|
+
{
|
|
21384
|
+
id: "supermemory",
|
|
21385
|
+
name: "Supermemory",
|
|
21386
|
+
type: "mcp",
|
|
21387
|
+
description: "Persistent memory across sessions - never re-explain context",
|
|
21388
|
+
installCommand: "claude mcp add supermemory -- npx -y @supermemory/mcp@latest",
|
|
21389
|
+
phases: ["requirements", "implementation"],
|
|
21390
|
+
impact: "high",
|
|
21391
|
+
detectionKey: "supermemory",
|
|
21392
|
+
website: "https://supermemory.ai",
|
|
21393
|
+
badge: "Essential",
|
|
21394
|
+
agents: {
|
|
21395
|
+
"claude-code": { installCommand: "claude mcp add supermemory -- npx -y @supermemory/mcp@latest" }
|
|
21396
|
+
}
|
|
21397
|
+
},
|
|
21398
|
+
{
|
|
21399
|
+
id: "nia",
|
|
21400
|
+
name: "Nia",
|
|
21401
|
+
type: "mcp",
|
|
21402
|
+
description: "Index and search external codebases and documentation",
|
|
21403
|
+
installCommand: "pipx run --no-cache nia-mcp-server",
|
|
21404
|
+
phases: ["requirements"],
|
|
21405
|
+
impact: "medium",
|
|
21406
|
+
detectionKey: "nia",
|
|
21407
|
+
website: "https://trynia.ai"
|
|
21408
|
+
},
|
|
21409
|
+
{
|
|
21410
|
+
id: "greptile",
|
|
21411
|
+
name: "Greptile",
|
|
21412
|
+
type: "mcp",
|
|
21413
|
+
description: "AI-powered code review and PR analysis",
|
|
21414
|
+
installCommand: "claude mcp add greptile -- npx -y @greptile/mcp",
|
|
21415
|
+
phases: ["review"],
|
|
21416
|
+
impact: "high",
|
|
21417
|
+
detectionKey: "greptile",
|
|
21418
|
+
website: "https://www.greptile.com",
|
|
21419
|
+
badge: "Recommended"
|
|
21420
|
+
},
|
|
21421
|
+
{
|
|
21422
|
+
id: "agent-browser",
|
|
21423
|
+
name: "Agent Browser",
|
|
21424
|
+
type: "mcp",
|
|
21425
|
+
description: "Live end-to-end browser testing and automation",
|
|
21426
|
+
installCommand: "claude mcp add agent-browser -- npx -y agent-browser-mcp",
|
|
21427
|
+
phases: ["review"],
|
|
21428
|
+
impact: "high",
|
|
21429
|
+
detectionKey: "agent-browser",
|
|
21430
|
+
website: "https://agent-browser.dev",
|
|
21431
|
+
badge: "Recommended"
|
|
21432
|
+
},
|
|
21433
|
+
{
|
|
21434
|
+
id: "playwright-mcp",
|
|
21435
|
+
name: "Playwright MCP",
|
|
21436
|
+
type: "mcp",
|
|
21437
|
+
description: "Browser automation for E2E testing and web scraping",
|
|
21438
|
+
installCommand: "claude mcp add playwright -- npx -y @anthropic/playwright-mcp",
|
|
21439
|
+
phases: ["review"],
|
|
21440
|
+
impact: "medium",
|
|
21441
|
+
detectionKey: "playwright",
|
|
21442
|
+
website: "https://playwright.dev"
|
|
21443
|
+
},
|
|
21444
|
+
{
|
|
21445
|
+
id: "github-mcp",
|
|
21446
|
+
name: "GitHub MCP",
|
|
21447
|
+
type: "mcp",
|
|
21448
|
+
description: "GitHub integration for PRs, issues, and repo management",
|
|
21449
|
+
installCommand: "claude mcp add github -- npx -y @anthropic/github-mcp",
|
|
21450
|
+
phases: ["planning", "review"],
|
|
21451
|
+
impact: "medium",
|
|
21452
|
+
detectionKey: "github"
|
|
21453
|
+
}
|
|
21454
|
+
];
|
|
21455
|
+
var PLUGINS = [
|
|
21456
|
+
{
|
|
21457
|
+
id: "beads",
|
|
21458
|
+
name: "Beads",
|
|
21459
|
+
type: "plugin",
|
|
21460
|
+
description: "Lightweight issue tracking in git - survives context compaction",
|
|
21461
|
+
installCommand: "bun add -g beads && bd init",
|
|
21462
|
+
phases: ["planning"],
|
|
21463
|
+
impact: "high",
|
|
21464
|
+
detectionKey: "beads",
|
|
21465
|
+
website: "https://github.com/steveyegge/beads",
|
|
21466
|
+
badge: "Recommended"
|
|
21467
|
+
},
|
|
21468
|
+
{
|
|
21469
|
+
id: "linear",
|
|
21470
|
+
name: "Linear",
|
|
21471
|
+
type: "plugin",
|
|
21472
|
+
description: "Sync with Linear issues for team collaboration",
|
|
21473
|
+
phases: ["planning"],
|
|
21474
|
+
impact: "medium",
|
|
21475
|
+
website: "https://linear.app"
|
|
21476
|
+
},
|
|
21477
|
+
{
|
|
21478
|
+
id: "slack",
|
|
21479
|
+
name: "Slack",
|
|
21480
|
+
type: "plugin",
|
|
21481
|
+
description: "Team notifications and updates",
|
|
21482
|
+
phases: ["review"],
|
|
21483
|
+
impact: "low",
|
|
21484
|
+
website: "https://slack.com"
|
|
21485
|
+
}
|
|
21486
|
+
];
|
|
21487
|
+
var SKILLS = [
|
|
21488
|
+
{
|
|
21489
|
+
id: "tdd-skill",
|
|
21490
|
+
name: "Test-Driven Development",
|
|
21491
|
+
type: "skill",
|
|
21492
|
+
description: "Write tests first, then implement - reduces bugs by 40%",
|
|
21493
|
+
installCommand: "npx skills add obra/superpowers@test-driven-development --yes",
|
|
21494
|
+
phases: ["review"],
|
|
21495
|
+
impact: "high",
|
|
21496
|
+
website: "https://skills.sh"
|
|
21497
|
+
},
|
|
21498
|
+
{
|
|
21499
|
+
id: "debugging-skill",
|
|
21500
|
+
name: "Systematic Debugging",
|
|
21501
|
+
type: "skill",
|
|
21502
|
+
description: "Structured approach to finding and fixing bugs",
|
|
21503
|
+
installCommand: "npx skills add obra/superpowers@systematic-debugging --yes",
|
|
21504
|
+
phases: ["implementation", "review"],
|
|
21505
|
+
impact: "medium",
|
|
21506
|
+
website: "https://skills.sh"
|
|
21507
|
+
},
|
|
21508
|
+
{
|
|
21509
|
+
id: "planning-skill",
|
|
21510
|
+
name: "Writing Plans",
|
|
21511
|
+
type: "skill",
|
|
21512
|
+
description: "Structured planning before implementation",
|
|
21513
|
+
installCommand: "npx skills add obra/superpowers@writing-plans --yes",
|
|
21514
|
+
phases: ["planning"],
|
|
21515
|
+
impact: "medium",
|
|
21516
|
+
website: "https://skills.sh"
|
|
21517
|
+
},
|
|
21518
|
+
{
|
|
21519
|
+
id: "code-review-skill",
|
|
21520
|
+
name: "Code Review",
|
|
21521
|
+
type: "skill",
|
|
21522
|
+
description: "Thorough code review checklist and workflow",
|
|
21523
|
+
installCommand: "npx skills add obra/superpowers@requesting-code-review --yes",
|
|
21524
|
+
phases: ["review"],
|
|
21525
|
+
impact: "medium",
|
|
21526
|
+
website: "https://skills.sh"
|
|
21527
|
+
},
|
|
21528
|
+
{
|
|
21529
|
+
id: "react-skill",
|
|
21530
|
+
name: "React Best Practices",
|
|
21531
|
+
type: "skill",
|
|
21532
|
+
description: "Vercel's React and Next.js patterns",
|
|
21533
|
+
installCommand: "npx skills add vercel-labs/agent-skills@vercel-react-best-practices --yes",
|
|
21534
|
+
phases: ["implementation"],
|
|
21535
|
+
impact: "medium",
|
|
21536
|
+
website: "https://skills.sh"
|
|
21537
|
+
},
|
|
21538
|
+
{
|
|
21539
|
+
id: "remotion-skill",
|
|
21540
|
+
name: "Remotion",
|
|
21541
|
+
type: "skill",
|
|
21542
|
+
description: "Video creation with React",
|
|
21543
|
+
installCommand: "npx skills add remotion-dev/skills@remotion-best-practices --yes",
|
|
21544
|
+
phases: ["implementation"],
|
|
21545
|
+
impact: "low",
|
|
21546
|
+
website: "https://skills.sh"
|
|
21547
|
+
},
|
|
21548
|
+
{
|
|
21549
|
+
id: "frontend-design-skill",
|
|
21550
|
+
name: "Frontend Design",
|
|
21551
|
+
type: "skill",
|
|
21552
|
+
description: "Anthropic's frontend design patterns",
|
|
21553
|
+
installCommand: "npx skills add anthropics/skills@frontend-design --yes",
|
|
21554
|
+
phases: ["implementation"],
|
|
21555
|
+
impact: "medium",
|
|
21556
|
+
website: "https://skills.sh"
|
|
21557
|
+
},
|
|
21558
|
+
{
|
|
21559
|
+
id: "web-design-skill",
|
|
21560
|
+
name: "Web Design Guidelines",
|
|
21561
|
+
type: "skill",
|
|
21562
|
+
description: "Vercel's web design guidelines",
|
|
21563
|
+
installCommand: "npx skills add vercel-labs/agent-skills@web-design-guidelines --yes",
|
|
21564
|
+
phases: ["implementation"],
|
|
21565
|
+
impact: "medium",
|
|
21566
|
+
website: "https://skills.sh"
|
|
21567
|
+
}
|
|
21568
|
+
];
|
|
21569
|
+
var LIBRARIES = [
|
|
21570
|
+
{
|
|
21571
|
+
id: "vitest",
|
|
21572
|
+
name: "Vitest",
|
|
21573
|
+
type: "library",
|
|
21574
|
+
description: "Fast unit testing framework for TypeScript/JavaScript",
|
|
21575
|
+
installCommand: "bun add -D vitest",
|
|
21576
|
+
phases: ["review"],
|
|
21577
|
+
impact: "high",
|
|
21578
|
+
website: "https://vitest.dev"
|
|
21579
|
+
},
|
|
21580
|
+
{
|
|
21581
|
+
id: "playwright",
|
|
21582
|
+
name: "Playwright",
|
|
21583
|
+
type: "library",
|
|
21584
|
+
description: "E2E testing framework for web applications",
|
|
21585
|
+
installCommand: "bun add -D playwright @playwright/test",
|
|
21586
|
+
phases: ["review"],
|
|
21587
|
+
impact: "medium",
|
|
21588
|
+
website: "https://playwright.dev"
|
|
21589
|
+
},
|
|
21590
|
+
{
|
|
21591
|
+
id: "biome",
|
|
21592
|
+
name: "Biome",
|
|
21593
|
+
type: "library",
|
|
21594
|
+
description: "Fast linter and formatter (replaces ESLint + Prettier)",
|
|
21595
|
+
installCommand: "bun add -D @biomejs/biome && bunx biome init",
|
|
21596
|
+
phases: ["review"],
|
|
21597
|
+
impact: "medium",
|
|
21598
|
+
website: "https://biomejs.dev"
|
|
21599
|
+
}
|
|
21600
|
+
];
|
|
21601
|
+
var CONFIG_FILES = [
|
|
21602
|
+
{
|
|
21603
|
+
id: "claude-md",
|
|
21604
|
+
name: "CLAUDE.md",
|
|
21605
|
+
type: "config",
|
|
21606
|
+
description: "Project-specific instructions for AI - commands, conventions, architecture",
|
|
21607
|
+
configPath: "CLAUDE.md",
|
|
21608
|
+
configContent: `# Project Instructions
|
|
21609
|
+
|
|
21610
|
+
## Build & Test Commands
|
|
21611
|
+
\`\`\`bash
|
|
21612
|
+
bun test # Run tests
|
|
21613
|
+
bun run build # Build project
|
|
21614
|
+
bun run lint # Run linter
|
|
21615
|
+
\`\`\`
|
|
21616
|
+
|
|
21617
|
+
## Architecture
|
|
21618
|
+
Describe your project structure here.
|
|
21619
|
+
|
|
21620
|
+
## Conventions
|
|
21621
|
+
- Use TypeScript
|
|
21622
|
+
- Write tests for new features
|
|
21623
|
+
- Use conventional commits
|
|
21624
|
+
`,
|
|
21625
|
+
phases: ["requirements"],
|
|
21626
|
+
impact: "high"
|
|
21627
|
+
},
|
|
21628
|
+
{
|
|
21629
|
+
id: "agents-md",
|
|
21630
|
+
name: "AGENTS.md",
|
|
21631
|
+
type: "config",
|
|
21632
|
+
description: "Agent-specific instructions and workflows",
|
|
21633
|
+
configPath: "AGENTS.md",
|
|
21634
|
+
configContent: `# Agent Instructions
|
|
21635
|
+
|
|
21636
|
+
## Package Manager
|
|
21637
|
+
This project uses **bun** exclusively.
|
|
21638
|
+
|
|
21639
|
+
## Workflow
|
|
21640
|
+
1. Read existing code before making changes
|
|
21641
|
+
2. Write tests for new features
|
|
21642
|
+
3. Run \`bun test\` before committing
|
|
21643
|
+
`,
|
|
21644
|
+
phases: ["requirements", "planning"],
|
|
21645
|
+
impact: "medium"
|
|
21646
|
+
}
|
|
21647
|
+
];
|
|
21648
|
+
var WORKFLOW_TOOLS = [
|
|
21649
|
+
{
|
|
21650
|
+
id: "granola",
|
|
21651
|
+
name: "Granola",
|
|
21652
|
+
type: "tool",
|
|
21653
|
+
description: "AI meeting notes and requirements capture",
|
|
21654
|
+
phases: ["requirements"],
|
|
21655
|
+
impact: "medium",
|
|
21656
|
+
website: "https://www.granola.ai/"
|
|
21657
|
+
},
|
|
21658
|
+
{
|
|
21659
|
+
id: "repoprompt",
|
|
21660
|
+
name: "RepoPrompt",
|
|
21661
|
+
type: "tool",
|
|
21662
|
+
description: "Generate AI prompts from your codebase",
|
|
21663
|
+
phases: ["requirements"],
|
|
21664
|
+
impact: "medium",
|
|
21665
|
+
website: "https://repoprompt.com"
|
|
21666
|
+
},
|
|
21667
|
+
{
|
|
21668
|
+
id: "figma",
|
|
21669
|
+
name: "Figma / v0",
|
|
21670
|
+
type: "tool",
|
|
21671
|
+
description: "Design tools for UI/UX planning",
|
|
21672
|
+
phases: ["planning"],
|
|
21673
|
+
impact: "medium",
|
|
21674
|
+
website: "https://figma.com"
|
|
21675
|
+
}
|
|
21676
|
+
];
|
|
21677
|
+
var ALL_RECOMMENDATIONS = [
|
|
21678
|
+
...MCP_SERVERS,
|
|
21679
|
+
...PLUGINS,
|
|
21680
|
+
...SKILLS,
|
|
21681
|
+
...LIBRARIES,
|
|
21682
|
+
...CONFIG_FILES,
|
|
21683
|
+
...WORKFLOW_TOOLS
|
|
21684
|
+
];
|
|
21685
|
+
var INSTALLABLE_RECOMMENDATIONS = ALL_RECOMMENDATIONS.filter((r3) => r3.installCommand || r3.configPath);
|
|
21686
|
+
if (false) {}
|
|
21687
|
+
|
|
21688
|
+
// src/lib/verify-recommendations.ts
|
|
21689
|
+
function validateSkillFormat(command) {
|
|
21690
|
+
if (!command.match(/^(npx|bunx)\s+skills\s+add\s+/)) {
|
|
21691
|
+
return { valid: false, message: "Must start with 'npx skills add' or 'bunx skills add'" };
|
|
21692
|
+
}
|
|
21693
|
+
const match = command.match(/skills\s+add\s+([^\s]+)/);
|
|
21694
|
+
if (!match) {
|
|
21695
|
+
return { valid: false, message: "Could not extract skill path" };
|
|
21696
|
+
}
|
|
21697
|
+
const skillPath = match[1] ?? "";
|
|
21698
|
+
if (!skillPath.includes("@")) {
|
|
21699
|
+
return {
|
|
21700
|
+
valid: false,
|
|
21701
|
+
message: `Invalid format '${skillPath}'. Must use @ separator: owner/repo@skill-name`
|
|
21702
|
+
};
|
|
21703
|
+
}
|
|
21704
|
+
const skillMatch = skillPath.match(/^([^\/]+)\/([^@]+)@([^\/\s]+)$/);
|
|
21705
|
+
if (!skillMatch) {
|
|
21706
|
+
return {
|
|
21707
|
+
valid: false,
|
|
21708
|
+
message: `Invalid skill path '${skillPath}'. Expected: owner/repo@skill-name`
|
|
21709
|
+
};
|
|
21710
|
+
}
|
|
21711
|
+
if (!command.includes("--yes")) {
|
|
21712
|
+
return {
|
|
21713
|
+
valid: false,
|
|
21714
|
+
message: "Missing --yes flag for non-interactive installation"
|
|
21715
|
+
};
|
|
21716
|
+
}
|
|
21717
|
+
return { valid: true, message: "Valid skills.sh format" };
|
|
21718
|
+
}
|
|
21719
|
+
function validateMCPFormat(command) {
|
|
21720
|
+
if (command.startsWith("claude mcp add")) {
|
|
21721
|
+
if (command.includes("-- npx") || command.includes("--transport")) {
|
|
21722
|
+
return { valid: true, message: "Valid Claude MCP format" };
|
|
21723
|
+
}
|
|
21724
|
+
return { valid: false, message: "MCP command should have '-- npx' or '--transport' pattern" };
|
|
21725
|
+
}
|
|
21726
|
+
if (command.startsWith("pipx run")) {
|
|
21727
|
+
return { valid: true, message: "Valid pipx MCP format" };
|
|
21728
|
+
}
|
|
21729
|
+
if (command.includes("config") || command.includes("mcpServers")) {
|
|
21730
|
+
return { valid: true, message: "Manual configuration instruction" };
|
|
21731
|
+
}
|
|
21732
|
+
return { valid: false, message: "Unknown MCP install format" };
|
|
21733
|
+
}
|
|
21734
|
+
function validatePackageFormat(command) {
|
|
21735
|
+
if (command.match(/^bun\s+add\s+(-[dDgG]\s+)?[@\w\/-]+/)) {
|
|
21736
|
+
return { valid: true, message: "Valid bun add format" };
|
|
21737
|
+
}
|
|
21738
|
+
if (command.match(/^npm\s+(install|i)\s+(-[dDgG]\s+)?[@\w\/-]+/)) {
|
|
21739
|
+
return { valid: true, message: "Valid npm install format" };
|
|
21740
|
+
}
|
|
21741
|
+
if (command.match(/^(bunx|npx)\s+/)) {
|
|
21742
|
+
return { valid: true, message: "Valid bunx/npx format" };
|
|
21743
|
+
}
|
|
21744
|
+
return { valid: false, message: "Unknown package install format" };
|
|
21745
|
+
}
|
|
21746
|
+
async function checkNpmPackageExists(packageName) {
|
|
21747
|
+
try {
|
|
21748
|
+
const response = await fetch(`https://registry.npmjs.org/${packageName}`, {
|
|
21749
|
+
method: "HEAD",
|
|
21750
|
+
signal: AbortSignal.timeout(5000)
|
|
21751
|
+
});
|
|
21752
|
+
if (response.ok) {
|
|
21753
|
+
return { exists: true, message: "Package exists on npm" };
|
|
21754
|
+
}
|
|
21755
|
+
return { exists: false, message: `Package not found on npm (${response.status})` };
|
|
21756
|
+
} catch (error2) {
|
|
21757
|
+
return { exists: false, message: `Could not verify: ${error2 instanceof Error ? error2.message : String(error2)}` };
|
|
21758
|
+
}
|
|
21759
|
+
}
|
|
21760
|
+
async function checkGitHubRepoExists(owner, repo) {
|
|
21761
|
+
try {
|
|
21762
|
+
const response = await fetch(`https://api.github.com/repos/${owner}/${repo}`, {
|
|
21763
|
+
method: "HEAD",
|
|
21764
|
+
signal: AbortSignal.timeout(5000)
|
|
21765
|
+
});
|
|
21766
|
+
if (response.ok) {
|
|
21767
|
+
return { exists: true, message: "GitHub repo exists" };
|
|
21768
|
+
}
|
|
21769
|
+
if (response.status === 404) {
|
|
21770
|
+
return { exists: false, message: `GitHub repo ${owner}/${repo} not found` };
|
|
21771
|
+
}
|
|
21772
|
+
return { exists: false, message: `GitHub API error (${response.status})` };
|
|
21773
|
+
} catch (error2) {
|
|
21774
|
+
return { exists: false, message: `Could not verify: ${error2 instanceof Error ? error2.message : String(error2)}` };
|
|
21775
|
+
}
|
|
21776
|
+
}
|
|
21777
|
+
function verifyRecommendation(rec) {
|
|
21778
|
+
const base = {
|
|
21779
|
+
id: rec.id,
|
|
21780
|
+
name: rec.name,
|
|
21781
|
+
type: rec.type,
|
|
21782
|
+
installCommand: rec.installCommand
|
|
21783
|
+
};
|
|
21784
|
+
if (!rec.installCommand && !rec.configPath) {
|
|
21785
|
+
return { ...base, status: "skipped", message: "No install command (informational only)" };
|
|
21786
|
+
}
|
|
21787
|
+
if (rec.type === "config" && rec.configPath) {
|
|
21788
|
+
return { ...base, status: "valid", message: `Config file: ${rec.configPath}` };
|
|
21789
|
+
}
|
|
21790
|
+
if (!rec.installCommand) {
|
|
21791
|
+
return { ...base, status: "skipped", message: "No install command" };
|
|
21792
|
+
}
|
|
21793
|
+
switch (rec.type) {
|
|
21794
|
+
case "skill": {
|
|
21795
|
+
const result = validateSkillFormat(rec.installCommand);
|
|
21796
|
+
return {
|
|
21797
|
+
...base,
|
|
21798
|
+
status: result.valid ? "valid" : "invalid",
|
|
21799
|
+
message: result.message
|
|
21800
|
+
};
|
|
21801
|
+
}
|
|
21802
|
+
case "mcp": {
|
|
21803
|
+
const result = validateMCPFormat(rec.installCommand);
|
|
21804
|
+
return {
|
|
21805
|
+
...base,
|
|
21806
|
+
status: result.valid ? "valid" : "invalid",
|
|
21807
|
+
message: result.message
|
|
21808
|
+
};
|
|
21809
|
+
}
|
|
21810
|
+
case "library":
|
|
21811
|
+
case "plugin": {
|
|
21812
|
+
const result = validatePackageFormat(rec.installCommand);
|
|
21813
|
+
return {
|
|
21814
|
+
...base,
|
|
21815
|
+
status: result.valid ? "valid" : "invalid",
|
|
21816
|
+
message: result.message
|
|
21817
|
+
};
|
|
21818
|
+
}
|
|
21819
|
+
default:
|
|
21820
|
+
return { ...base, status: "warning", message: `Unknown type: ${rec.type}` };
|
|
21821
|
+
}
|
|
21822
|
+
}
|
|
21823
|
+
function verifyAllRecommendations() {
|
|
21824
|
+
const results = [];
|
|
21825
|
+
for (const rec of ALL_RECOMMENDATIONS) {
|
|
21826
|
+
results.push(verifyRecommendation(rec));
|
|
21827
|
+
}
|
|
21828
|
+
const valid = results.filter((r3) => r3.status === "valid").length;
|
|
21829
|
+
const invalid = results.filter((r3) => r3.status === "invalid").length;
|
|
21830
|
+
const warnings = results.filter((r3) => r3.status === "warning").length;
|
|
21831
|
+
const skipped = results.filter((r3) => r3.status === "skipped").length;
|
|
21832
|
+
return {
|
|
21833
|
+
total: results.length,
|
|
21834
|
+
valid,
|
|
21835
|
+
invalid,
|
|
21836
|
+
warnings,
|
|
21837
|
+
skipped,
|
|
21838
|
+
results
|
|
21839
|
+
};
|
|
21840
|
+
}
|
|
21841
|
+
async function verifyRecommendationsThorough() {
|
|
21842
|
+
const basicResults = verifyAllRecommendations();
|
|
21843
|
+
const enhancedResults = [];
|
|
21844
|
+
for (const result of basicResults.results) {
|
|
21845
|
+
if (result.status === "invalid" || result.status === "skipped") {
|
|
21846
|
+
enhancedResults.push(result);
|
|
21847
|
+
continue;
|
|
21848
|
+
}
|
|
21849
|
+
if (result.installCommand?.includes("skills add")) {
|
|
21850
|
+
const match = result.installCommand.match(/skills\s+add\s+([^\/]+)\/([^@]+)@/);
|
|
21851
|
+
if (match && match[1] && match[2]) {
|
|
21852
|
+
const owner = match[1];
|
|
21853
|
+
const repo = match[2];
|
|
21854
|
+
const check = await checkGitHubRepoExists(owner, repo);
|
|
21855
|
+
if (!check.exists) {
|
|
21856
|
+
enhancedResults.push({
|
|
21857
|
+
...result,
|
|
21858
|
+
status: "invalid",
|
|
21859
|
+
message: check.message
|
|
21860
|
+
});
|
|
21861
|
+
continue;
|
|
21862
|
+
}
|
|
21863
|
+
}
|
|
21864
|
+
}
|
|
21865
|
+
if (result.installCommand?.match(/npx\s+-y\s+@?[\w\/-]+/)) {
|
|
21866
|
+
const match = result.installCommand.match(/npx\s+-y\s+(@?[\w\/-]+)/);
|
|
21867
|
+
if (match && match[1]) {
|
|
21868
|
+
const packageName = match[1];
|
|
21869
|
+
const check = await checkNpmPackageExists(packageName);
|
|
21870
|
+
if (!check.exists) {
|
|
21871
|
+
enhancedResults.push({
|
|
21872
|
+
...result,
|
|
21873
|
+
status: "warning",
|
|
21874
|
+
message: check.message
|
|
21875
|
+
});
|
|
21876
|
+
continue;
|
|
21877
|
+
}
|
|
21878
|
+
}
|
|
21879
|
+
}
|
|
21880
|
+
enhancedResults.push(result);
|
|
21881
|
+
}
|
|
21882
|
+
const valid = enhancedResults.filter((r3) => r3.status === "valid").length;
|
|
21883
|
+
const invalid = enhancedResults.filter((r3) => r3.status === "invalid").length;
|
|
21884
|
+
const warnings = enhancedResults.filter((r3) => r3.status === "warning").length;
|
|
21885
|
+
const skipped = enhancedResults.filter((r3) => r3.status === "skipped").length;
|
|
21886
|
+
return {
|
|
21887
|
+
total: enhancedResults.length,
|
|
21888
|
+
valid,
|
|
21889
|
+
invalid,
|
|
21890
|
+
warnings,
|
|
21891
|
+
skipped,
|
|
21892
|
+
results: enhancedResults
|
|
21893
|
+
};
|
|
21894
|
+
}
|
|
21895
|
+
function printVerificationResults(summary, verbose = false) {
|
|
21896
|
+
console.log(`
|
|
21897
|
+
═══════════════════════════════════════════════════════════════`);
|
|
21898
|
+
console.log(" RECOMMENDATION VERIFICATION REPORT");
|
|
21899
|
+
console.log(`═══════════════════════════════════════════════════════════════
|
|
21900
|
+
`);
|
|
21901
|
+
const invalid = summary.results.filter((r3) => r3.status === "invalid");
|
|
21902
|
+
if (invalid.length > 0) {
|
|
21903
|
+
console.log(`❌ INVALID RECOMMENDATIONS:
|
|
21904
|
+
`);
|
|
21905
|
+
for (const r3 of invalid) {
|
|
21906
|
+
console.log(` ${r3.name} (${r3.type})`);
|
|
21907
|
+
console.log(` ID: ${r3.id}`);
|
|
21908
|
+
console.log(` Issue: ${r3.message}`);
|
|
21909
|
+
if (r3.installCommand) {
|
|
21910
|
+
console.log(` Command: ${r3.installCommand}`);
|
|
21911
|
+
}
|
|
21912
|
+
console.log();
|
|
21913
|
+
}
|
|
21914
|
+
}
|
|
21915
|
+
const warnings = summary.results.filter((r3) => r3.status === "warning");
|
|
21916
|
+
if (warnings.length > 0) {
|
|
21917
|
+
console.log(`⚠️ WARNINGS:
|
|
21918
|
+
`);
|
|
21919
|
+
for (const r3 of warnings) {
|
|
21920
|
+
console.log(` ${r3.name}: ${r3.message}`);
|
|
21921
|
+
}
|
|
21922
|
+
console.log();
|
|
21923
|
+
}
|
|
21924
|
+
if (verbose) {
|
|
21925
|
+
const valid = summary.results.filter((r3) => r3.status === "valid");
|
|
21926
|
+
if (valid.length > 0) {
|
|
21927
|
+
console.log(`✓ VALID RECOMMENDATIONS:
|
|
21928
|
+
`);
|
|
21929
|
+
for (const r3 of valid) {
|
|
21930
|
+
console.log(` ${r3.name} (${r3.type}): ${r3.message}`);
|
|
21931
|
+
}
|
|
21932
|
+
console.log();
|
|
21933
|
+
}
|
|
21934
|
+
}
|
|
21935
|
+
console.log("───────────────────────────────────────────────────────────────");
|
|
21936
|
+
console.log(` Total: ${summary.total}`);
|
|
21937
|
+
console.log(` ✓ Valid: ${summary.valid}`);
|
|
21938
|
+
console.log(` ❌ Invalid: ${summary.invalid}`);
|
|
21939
|
+
console.log(` ⚠️ Warnings: ${summary.warnings}`);
|
|
21940
|
+
console.log(` ○ Skipped: ${summary.skipped}`);
|
|
21941
|
+
console.log(`───────────────────────────────────────────────────────────────
|
|
21942
|
+
`);
|
|
21943
|
+
if (summary.invalid > 0) {
|
|
21944
|
+
console.log(`❌ VERIFICATION FAILED - Fix invalid recommendations before release!
|
|
21945
|
+
`);
|
|
21946
|
+
} else if (summary.warnings > 0) {
|
|
21947
|
+
console.log(`⚠️ VERIFICATION PASSED WITH WARNINGS
|
|
21948
|
+
`);
|
|
21949
|
+
} else {
|
|
21950
|
+
console.log(`✓ ALL RECOMMENDATIONS VERIFIED
|
|
21951
|
+
`);
|
|
21952
|
+
}
|
|
21953
|
+
}
|
|
21954
|
+
|
|
21955
|
+
// src/commands/doctor.ts
|
|
21364
21956
|
var doctorCommand = defineCommand2({
|
|
21365
21957
|
meta: {
|
|
21366
21958
|
name: "doctor",
|
|
21367
21959
|
description: "Check tool detection, data sources, and connectivity health"
|
|
21368
21960
|
},
|
|
21369
|
-
|
|
21961
|
+
args: {
|
|
21962
|
+
"verify-recommendations": {
|
|
21963
|
+
type: "boolean",
|
|
21964
|
+
description: "Verify all recommendations in the database are valid",
|
|
21965
|
+
alias: "verify",
|
|
21966
|
+
default: false
|
|
21967
|
+
},
|
|
21968
|
+
thorough: {
|
|
21969
|
+
type: "boolean",
|
|
21970
|
+
description: "Run thorough verification with network checks",
|
|
21971
|
+
alias: "t",
|
|
21972
|
+
default: false
|
|
21973
|
+
},
|
|
21974
|
+
verbose: {
|
|
21975
|
+
type: "boolean",
|
|
21976
|
+
description: "Show all results including valid recommendations",
|
|
21977
|
+
alias: "v",
|
|
21978
|
+
default: false
|
|
21979
|
+
}
|
|
21980
|
+
},
|
|
21981
|
+
async run({ args }) {
|
|
21982
|
+
if (args["verify-recommendations"]) {
|
|
21983
|
+
console.log();
|
|
21984
|
+
console.log(colors2.bold(colors2.primary(" NaironAI Recommendation Verifier")));
|
|
21985
|
+
console.log(colors2.dim(` Validating all recommendation install commands...
|
|
21986
|
+
`));
|
|
21987
|
+
const spinner2 = createSpinner("Verifying recommendations...");
|
|
21988
|
+
spinner2.start();
|
|
21989
|
+
let summary;
|
|
21990
|
+
if (args.thorough) {
|
|
21991
|
+
spinner2.text = "Verifying recommendations (thorough mode with network checks)...";
|
|
21992
|
+
summary = await verifyRecommendationsThorough();
|
|
21993
|
+
} else {
|
|
21994
|
+
summary = verifyAllRecommendations();
|
|
21995
|
+
}
|
|
21996
|
+
if (summary.invalid > 0) {
|
|
21997
|
+
spinner2.fail(`Found ${summary.invalid} invalid recommendation(s)`);
|
|
21998
|
+
} else if (summary.warnings > 0) {
|
|
21999
|
+
spinner2.warn(`Verification passed with ${summary.warnings} warning(s)`);
|
|
22000
|
+
} else {
|
|
22001
|
+
spinner2.succeed("All recommendations verified");
|
|
22002
|
+
}
|
|
22003
|
+
printVerificationResults(summary, args.verbose);
|
|
22004
|
+
if (summary.invalid > 0) {
|
|
22005
|
+
process.exit(1);
|
|
22006
|
+
}
|
|
22007
|
+
return;
|
|
22008
|
+
}
|
|
21370
22009
|
console.log();
|
|
21371
22010
|
console.log(colors2.bold(colors2.primary(" NaironAI Doctor")));
|
|
21372
22011
|
console.log(colors2.dim(` Checking system health...
|
|
@@ -22004,6 +22643,15 @@ var BOLD = "\x1B[1m";
|
|
|
22004
22643
|
var RESET = "\x1B[0m";
|
|
22005
22644
|
var MAGENTA = "\x1B[35m";
|
|
22006
22645
|
var CHANGELOG = [
|
|
22646
|
+
{
|
|
22647
|
+
version: "0.3.13",
|
|
22648
|
+
date: "2026-02-14",
|
|
22649
|
+
title: "Reliable Recommendations",
|
|
22650
|
+
highlights: [
|
|
22651
|
+
"Fixed skills.sh format - skills now install correctly",
|
|
22652
|
+
"New: nb doctor --verify-recommendations to validate install commands"
|
|
22653
|
+
]
|
|
22654
|
+
},
|
|
22007
22655
|
{
|
|
22008
22656
|
version: "0.3.12",
|
|
22009
22657
|
date: "2026-02-14",
|
|
@@ -22403,7 +23051,7 @@ function showFullChangelog() {
|
|
|
22403
23051
|
// package.json
|
|
22404
23052
|
var package_default = {
|
|
22405
23053
|
name: "nairon-bench",
|
|
22406
|
-
version: "0.3.
|
|
23054
|
+
version: "0.3.13",
|
|
22407
23055
|
description: "AI workflow benchmarking CLI",
|
|
22408
23056
|
type: "module",
|
|
22409
23057
|
bin: {
|
|
@@ -22435,8 +23083,9 @@ var package_default = {
|
|
|
22435
23083
|
"build:linux-arm64": "bun build --compile --target=bun-linux-arm64 --outfile=dist/nb-linux-arm64 src/index.ts",
|
|
22436
23084
|
"build:windows-x64": "bun build --compile --target=bun-windows-x64 --outfile=dist/nb-windows-x64.exe src/index.ts",
|
|
22437
23085
|
typecheck: "tsc --noEmit",
|
|
22438
|
-
test: "
|
|
22439
|
-
"test:e2e": "
|
|
23086
|
+
test: "vitest run",
|
|
23087
|
+
"test:e2e": "vitest run tests/e2e/",
|
|
23088
|
+
"test:watch": "vitest",
|
|
22440
23089
|
clean: "rm -rf dist",
|
|
22441
23090
|
prepublishOnly: "bun run build"
|
|
22442
23091
|
},
|
|
@@ -24927,7 +25576,7 @@ function formatBytes(bytes) {
|
|
|
24927
25576
|
// package.json
|
|
24928
25577
|
var package_default2 = {
|
|
24929
25578
|
name: "nairon-bench",
|
|
24930
|
-
version: "0.3.
|
|
25579
|
+
version: "0.3.13",
|
|
24931
25580
|
description: "AI workflow benchmarking CLI",
|
|
24932
25581
|
type: "module",
|
|
24933
25582
|
bin: {
|
|
@@ -24959,8 +25608,9 @@ var package_default2 = {
|
|
|
24959
25608
|
"build:linux-arm64": "bun build --compile --target=bun-linux-arm64 --outfile=dist/nb-linux-arm64 src/index.ts",
|
|
24960
25609
|
"build:windows-x64": "bun build --compile --target=bun-windows-x64 --outfile=dist/nb-windows-x64.exe src/index.ts",
|
|
24961
25610
|
typecheck: "tsc --noEmit",
|
|
24962
|
-
test: "
|
|
24963
|
-
"test:e2e": "
|
|
25611
|
+
test: "vitest run",
|
|
25612
|
+
"test:e2e": "vitest run tests/e2e/",
|
|
25613
|
+
"test:watch": "vitest",
|
|
24964
25614
|
clean: "rm -rf dist",
|
|
24965
25615
|
prepublishOnly: "bun run build"
|
|
24966
25616
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nairon-bench",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.13",
|
|
4
4
|
"description": "AI workflow benchmarking CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -32,8 +32,9 @@
|
|
|
32
32
|
"build:linux-arm64": "bun build --compile --target=bun-linux-arm64 --outfile=dist/nb-linux-arm64 src/index.ts",
|
|
33
33
|
"build:windows-x64": "bun build --compile --target=bun-windows-x64 --outfile=dist/nb-windows-x64.exe src/index.ts",
|
|
34
34
|
"typecheck": "tsc --noEmit",
|
|
35
|
-
"test": "
|
|
36
|
-
"test:e2e": "
|
|
35
|
+
"test": "vitest run",
|
|
36
|
+
"test:e2e": "vitest run tests/e2e/",
|
|
37
|
+
"test:watch": "vitest",
|
|
37
38
|
"clean": "rm -rf dist",
|
|
38
39
|
"prepublishOnly": "bun run build"
|
|
39
40
|
},
|