nairon-bench 0.3.11 → 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 +681 -30
- 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")) {
|
|
@@ -10985,11 +10985,10 @@ function analyzePlanning2(agents, git, projectDir, analysis, projectContext) {
|
|
|
10985
10985
|
strengths.push("Has planning skill installed");
|
|
10986
10986
|
} else {
|
|
10987
10987
|
recommendations.push({
|
|
10988
|
-
title: "
|
|
10989
|
-
description: "
|
|
10988
|
+
title: "Add AGENTS.md for planning guidance",
|
|
10989
|
+
description: "Create an AGENTS.md file with project-specific planning instructions",
|
|
10990
10990
|
impact: "medium",
|
|
10991
|
-
type: "
|
|
10992
|
-
installCommand: "npx skills add obra/superpowers/writing-plans"
|
|
10991
|
+
type: "config"
|
|
10993
10992
|
});
|
|
10994
10993
|
}
|
|
10995
10994
|
if (agents && agents.sessions.length > 0) {
|
|
@@ -11282,11 +11281,11 @@ function analyzeReview2(agents, git, tests, projectDir, analysis, projectContext
|
|
|
11282
11281
|
strengths.push("TDD workflow skill installed");
|
|
11283
11282
|
} else {
|
|
11284
11283
|
recommendations.push({
|
|
11285
|
-
title: "
|
|
11286
|
-
description: "
|
|
11287
|
-
impact: "
|
|
11288
|
-
type: "
|
|
11289
|
-
installCommand: "
|
|
11284
|
+
title: "Add testing framework",
|
|
11285
|
+
description: "Install Vitest or Jest for test-driven development",
|
|
11286
|
+
impact: "high",
|
|
11287
|
+
type: "library",
|
|
11288
|
+
installCommand: "bun add -D vitest"
|
|
11290
11289
|
});
|
|
11291
11290
|
}
|
|
11292
11291
|
const hasLinting = existsSync6(join6(projectDir, ".eslintrc.js")) || existsSync6(join6(projectDir, ".eslintrc.json")) || existsSync6(join6(projectDir, "eslint.config.js")) || existsSync6(join6(projectDir, "biome.json"));
|
|
@@ -11860,19 +11859,11 @@ Describe your project structure here.
|
|
|
11860
11859
|
selected: true
|
|
11861
11860
|
},
|
|
11862
11861
|
{
|
|
11863
|
-
id: "
|
|
11864
|
-
name: "
|
|
11865
|
-
type: "
|
|
11866
|
-
description: "
|
|
11867
|
-
installCommand: "
|
|
11868
|
-
selected: true
|
|
11869
|
-
},
|
|
11870
|
-
{
|
|
11871
|
-
id: "debugging-skill",
|
|
11872
|
-
name: "Debugging Skill",
|
|
11873
|
-
type: "skill",
|
|
11874
|
-
description: "Systematic debugging approach",
|
|
11875
|
-
installCommand: "npx skills add obra/superpowers/systematic-debugging",
|
|
11862
|
+
id: "vitest",
|
|
11863
|
+
name: "Vitest",
|
|
11864
|
+
type: "library",
|
|
11865
|
+
description: "Fast unit testing framework",
|
|
11866
|
+
installCommand: "bun add -D vitest",
|
|
11876
11867
|
selected: true
|
|
11877
11868
|
}
|
|
11878
11869
|
]
|
|
@@ -21370,12 +21361,651 @@ import { existsSync as existsSync12 } from "node:fs";
|
|
|
21370
21361
|
import { homedir as homedir9 } from "node:os";
|
|
21371
21362
|
import { join as join12 } from "node:path";
|
|
21372
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
|
|
21373
21956
|
var doctorCommand = defineCommand2({
|
|
21374
21957
|
meta: {
|
|
21375
21958
|
name: "doctor",
|
|
21376
21959
|
description: "Check tool detection, data sources, and connectivity health"
|
|
21377
21960
|
},
|
|
21378
|
-
|
|
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
|
+
}
|
|
21379
22009
|
console.log();
|
|
21380
22010
|
console.log(colors2.bold(colors2.primary(" NaironAI Doctor")));
|
|
21381
22011
|
console.log(colors2.dim(` Checking system health...
|
|
@@ -22013,6 +22643,25 @@ var BOLD = "\x1B[1m";
|
|
|
22013
22643
|
var RESET = "\x1B[0m";
|
|
22014
22644
|
var MAGENTA = "\x1B[35m";
|
|
22015
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
|
+
},
|
|
22655
|
+
{
|
|
22656
|
+
version: "0.3.12",
|
|
22657
|
+
date: "2026-02-14",
|
|
22658
|
+
title: "Fixed Skill Recommendations",
|
|
22659
|
+
highlights: [
|
|
22660
|
+
"Removed non-existent skill recommendations",
|
|
22661
|
+
"Replaced with real, installable tools (Vitest, etc.)",
|
|
22662
|
+
"Skills installation now foolproof"
|
|
22663
|
+
]
|
|
22664
|
+
},
|
|
22016
22665
|
{
|
|
22017
22666
|
version: "0.3.11",
|
|
22018
22667
|
date: "2026-02-14",
|
|
@@ -22402,7 +23051,7 @@ function showFullChangelog() {
|
|
|
22402
23051
|
// package.json
|
|
22403
23052
|
var package_default = {
|
|
22404
23053
|
name: "nairon-bench",
|
|
22405
|
-
version: "0.3.
|
|
23054
|
+
version: "0.3.13",
|
|
22406
23055
|
description: "AI workflow benchmarking CLI",
|
|
22407
23056
|
type: "module",
|
|
22408
23057
|
bin: {
|
|
@@ -22434,8 +23083,9 @@ var package_default = {
|
|
|
22434
23083
|
"build:linux-arm64": "bun build --compile --target=bun-linux-arm64 --outfile=dist/nb-linux-arm64 src/index.ts",
|
|
22435
23084
|
"build:windows-x64": "bun build --compile --target=bun-windows-x64 --outfile=dist/nb-windows-x64.exe src/index.ts",
|
|
22436
23085
|
typecheck: "tsc --noEmit",
|
|
22437
|
-
test: "
|
|
22438
|
-
"test:e2e": "
|
|
23086
|
+
test: "vitest run",
|
|
23087
|
+
"test:e2e": "vitest run tests/e2e/",
|
|
23088
|
+
"test:watch": "vitest",
|
|
22439
23089
|
clean: "rm -rf dist",
|
|
22440
23090
|
prepublishOnly: "bun run build"
|
|
22441
23091
|
},
|
|
@@ -24926,7 +25576,7 @@ function formatBytes(bytes) {
|
|
|
24926
25576
|
// package.json
|
|
24927
25577
|
var package_default2 = {
|
|
24928
25578
|
name: "nairon-bench",
|
|
24929
|
-
version: "0.3.
|
|
25579
|
+
version: "0.3.13",
|
|
24930
25580
|
description: "AI workflow benchmarking CLI",
|
|
24931
25581
|
type: "module",
|
|
24932
25582
|
bin: {
|
|
@@ -24958,8 +25608,9 @@ var package_default2 = {
|
|
|
24958
25608
|
"build:linux-arm64": "bun build --compile --target=bun-linux-arm64 --outfile=dist/nb-linux-arm64 src/index.ts",
|
|
24959
25609
|
"build:windows-x64": "bun build --compile --target=bun-windows-x64 --outfile=dist/nb-windows-x64.exe src/index.ts",
|
|
24960
25610
|
typecheck: "tsc --noEmit",
|
|
24961
|
-
test: "
|
|
24962
|
-
"test:e2e": "
|
|
25611
|
+
test: "vitest run",
|
|
25612
|
+
"test:e2e": "vitest run tests/e2e/",
|
|
25613
|
+
"test:watch": "vitest",
|
|
24963
25614
|
clean: "rm -rf dist",
|
|
24964
25615
|
prepublishOnly: "bun run build"
|
|
24965
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
|
},
|