nairon-bench 0.5.0 → 0.5.2

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 CHANGED
@@ -4447,8 +4447,8 @@ function defineCommand2(def) {
4447
4447
 
4448
4448
  // src/commands/scan.ts
4449
4449
  init_dist();
4450
- import { existsSync as existsSync9, mkdirSync as mkdirSync4, writeFileSync as writeFileSync4, readFileSync as readFileSync9 } from "node:fs";
4451
- import { join as join9 } from "node:path";
4450
+ import { existsSync as existsSync10, mkdirSync as mkdirSync5, writeFileSync as writeFileSync5, readFileSync as readFileSync10 } from "node:fs";
4451
+ import { join as join10 } from "node:path";
4452
4452
 
4453
4453
  // ../../node_modules/simple-git/dist/esm/index.js
4454
4454
  var import_file_exists = __toESM(require_dist(), 1);
@@ -16068,6 +16068,251 @@ function filterAlreadyInstalled(optimizations, status) {
16068
16068
  });
16069
16069
  }
16070
16070
 
16071
+ // src/lib/first-run.ts
16072
+ init_dist();
16073
+ import { existsSync as existsSync9, readFileSync as readFileSync9, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4 } from "node:fs";
16074
+ import { homedir as homedir8 } from "node:os";
16075
+ import { join as join9 } from "node:path";
16076
+ import { spawnSync as spawnSync2 } from "node:child_process";
16077
+ var FIRST_RUN_FLAG = join9(homedir8(), ".nairon-bench", "first-run-complete");
16078
+ var PROJECT_SCAN_MARKER = ".nairon/first-scan-complete";
16079
+ function isFirstScanInProject(projectDir) {
16080
+ return !existsSync9(join9(projectDir, PROJECT_SCAN_MARKER));
16081
+ }
16082
+ function markProjectScanned(projectDir) {
16083
+ const naironDir = join9(projectDir, ".nairon");
16084
+ if (!existsSync9(naironDir)) {
16085
+ mkdirSync4(naironDir, { recursive: true });
16086
+ }
16087
+ writeFileSync4(join9(projectDir, PROJECT_SCAN_MARKER), new Date().toISOString());
16088
+ }
16089
+ var AGENT_CONFIGS = [
16090
+ {
16091
+ id: "claude-code",
16092
+ name: "Claude Code",
16093
+ paths: [".claude"]
16094
+ },
16095
+ {
16096
+ id: "opencode",
16097
+ name: "OpenCode",
16098
+ paths: [".config/opencode", ".local/share/opencode", ".opencode"]
16099
+ },
16100
+ {
16101
+ id: "cursor",
16102
+ name: "Cursor",
16103
+ paths: [".cursor"]
16104
+ },
16105
+ {
16106
+ id: "codex",
16107
+ name: "Codex CLI",
16108
+ paths: [".codex"]
16109
+ },
16110
+ {
16111
+ id: "copilot",
16112
+ name: "GitHub Copilot",
16113
+ paths: [".github-copilot"]
16114
+ },
16115
+ {
16116
+ id: "cody",
16117
+ name: "Sourcegraph Cody",
16118
+ paths: [".cody"]
16119
+ },
16120
+ {
16121
+ id: "aider",
16122
+ name: "Aider",
16123
+ paths: [".aider"]
16124
+ }
16125
+ ];
16126
+ function detectAllAgents() {
16127
+ const home = homedir8();
16128
+ const cwd = process.cwd();
16129
+ const detected = [];
16130
+ for (const agent of AGENT_CONFIGS) {
16131
+ for (const relativePath of agent.paths) {
16132
+ const homePath = join9(home, relativePath);
16133
+ if (existsSync9(homePath)) {
16134
+ detected.push({ id: agent.id, name: agent.name, configPath: homePath });
16135
+ break;
16136
+ }
16137
+ const projectPath = join9(cwd, relativePath);
16138
+ if (existsSync9(projectPath)) {
16139
+ detected.push({ id: agent.id, name: agent.name, configPath: projectPath });
16140
+ break;
16141
+ }
16142
+ }
16143
+ }
16144
+ return detected;
16145
+ }
16146
+ function analyzeReadme(projectDir) {
16147
+ const readmePath = join9(projectDir, "README.md");
16148
+ if (!existsSync9(readmePath)) {
16149
+ const alternatives = ["readme.md", "Readme.md", "README.MD", "README"];
16150
+ for (const alt of alternatives) {
16151
+ const altPath = join9(projectDir, alt);
16152
+ if (existsSync9(altPath)) {
16153
+ return parseReadme(readFileSync9(altPath, "utf-8"), projectDir);
16154
+ }
16155
+ }
16156
+ return null;
16157
+ }
16158
+ const content = readFileSync9(readmePath, "utf-8");
16159
+ return parseReadme(content, projectDir);
16160
+ }
16161
+ function parseReadme(content, projectDir) {
16162
+ let name = "Unknown Project";
16163
+ const pkgPath = join9(projectDir, "package.json");
16164
+ if (existsSync9(pkgPath)) {
16165
+ try {
16166
+ const pkg = JSON.parse(readFileSync9(pkgPath, "utf-8"));
16167
+ if (pkg.name && !pkg.name.startsWith("@") && pkg.name !== "root") {
16168
+ name = pkg.name;
16169
+ }
16170
+ } catch {}
16171
+ }
16172
+ if (name === "Unknown Project") {
16173
+ const headingMatch = content.match(/^#\s+([^<\n]+)$/m);
16174
+ if (headingMatch && headingMatch[1]) {
16175
+ const heading = headingMatch[1].trim();
16176
+ if (!heading.toLowerCase().includes("install") && !heading.toLowerCase().includes("getting started") && heading.length < 50) {
16177
+ name = heading;
16178
+ }
16179
+ }
16180
+ }
16181
+ let description = "";
16182
+ const descMatch = content.match(/^#[^#].*\n\n(.+?)(\n\n|$)/s);
16183
+ if (descMatch && descMatch[1]) {
16184
+ description = descMatch[1].replace(/\n/g, " ").trim().slice(0, 200);
16185
+ }
16186
+ const techStack = [];
16187
+ const techPatterns = {
16188
+ react: /\breact\b/i,
16189
+ "next.js": /\bnext\.?js\b/i,
16190
+ vue: /\bvue\b/i,
16191
+ svelte: /\bsvelte\b/i,
16192
+ typescript: /\btypescript\b/i,
16193
+ python: /\bpython\b/i,
16194
+ rust: /\brust\b/i,
16195
+ go: /\bgolang?\b/i,
16196
+ node: /\bnode\.?js\b/i,
16197
+ bun: /\bbun\b/i,
16198
+ deno: /\bdeno\b/i,
16199
+ tailwind: /\btailwind\b/i,
16200
+ prisma: /\bprisma\b/i,
16201
+ postgres: /\bpostgres\b/i,
16202
+ mongodb: /\bmongo\b/i,
16203
+ redis: /\bredis\b/i,
16204
+ docker: /\bdocker\b/i,
16205
+ kubernetes: /\bkubernetes\b|\bk8s\b/i,
16206
+ aws: /\baws\b/i,
16207
+ vercel: /\bvercel\b/i,
16208
+ cloudflare: /\bcloudflare\b/i,
16209
+ openai: /\bopenai\b/i,
16210
+ anthropic: /\banthropic\b|\bclaude\b/i,
16211
+ langchain: /\blangchain\b/i,
16212
+ convex: /\bconvex\b/i,
16213
+ supabase: /\bsupabase\b/i,
16214
+ firebase: /\bfirebase\b/i,
16215
+ stripe: /\bstripe\b/i,
16216
+ playwright: /\bplaywright\b/i,
16217
+ vitest: /\bvitest\b/i,
16218
+ jest: /\bjest\b/i,
16219
+ remotion: /\bremotion\b/i
16220
+ };
16221
+ for (const [tech, pattern] of Object.entries(techPatterns)) {
16222
+ if (pattern.test(content)) {
16223
+ techStack.push(tech);
16224
+ }
16225
+ }
16226
+ const keywords = [];
16227
+ const keywordPatterns = {
16228
+ api: /\bapi\b|\brest\b|\bgraphql\b/i,
16229
+ cli: /\bcli\b|\bcommand.?line\b/i,
16230
+ web: /\bweb\b|\bwebsite\b|\bfrontend\b/i,
16231
+ mobile: /\bmobile\b|\bios\b|\bandroid\b|\breact.?native\b/i,
16232
+ ai: /\bai\b|\bmachine.?learning\b|\bllm\b|\bgpt\b/i,
16233
+ video: /\bvideo\b|\bstreaming\b|\bmedia\b/i,
16234
+ ecommerce: /\becommerce\b|\bshop\b|\bstore\b|\bpayment\b/i,
16235
+ auth: /\bauth\b|\blogin\b|\bsession\b/i,
16236
+ testing: /\btest\b|\btesting\b|\btdd\b/i,
16237
+ devtools: /\bdevtool\b|\bdeveloper.?tool\b/i
16238
+ };
16239
+ for (const [keyword, pattern] of Object.entries(keywordPatterns)) {
16240
+ if (pattern.test(content)) {
16241
+ keywords.push(keyword);
16242
+ }
16243
+ }
16244
+ return { name, description, techStack, keywords };
16245
+ }
16246
+ function suggestSkills(context) {
16247
+ const suggestions = [];
16248
+ suggestions.push({
16249
+ name: "Find Skills",
16250
+ installCommand: "npx skills add vercel-labs/skills@find-skills --yes",
16251
+ reason: "Discover more skills for your workflow"
16252
+ });
16253
+ if (!context) {
16254
+ suggestions.push({
16255
+ name: "Writing Plans",
16256
+ installCommand: "npx skills add obra/superpowers@writing-plans --yes",
16257
+ reason: "Better planning before implementation"
16258
+ });
16259
+ return suggestions;
16260
+ }
16261
+ if (context.techStack.includes("react") || context.techStack.includes("next.js")) {
16262
+ suggestions.push({
16263
+ name: "React Best Practices",
16264
+ installCommand: "npx skills add vercel-labs/agent-skills@vercel-react-best-practices --yes",
16265
+ reason: `Detected React/Next.js in ${context.name}`
16266
+ });
16267
+ }
16268
+ if (context.techStack.includes("remotion")) {
16269
+ suggestions.push({
16270
+ name: "Remotion",
16271
+ installCommand: "npx skills add remotion-dev/skills@remotion-best-practices --yes",
16272
+ reason: "Detected Remotion video framework"
16273
+ });
16274
+ }
16275
+ if (context.keywords.includes("testing") || context.keywords.includes("tdd")) {
16276
+ suggestions.push({
16277
+ name: "Test-Driven Development",
16278
+ installCommand: "npx skills add obra/superpowers@test-driven-development --yes",
16279
+ reason: "Testing focus detected"
16280
+ });
16281
+ }
16282
+ if (context.keywords.includes("web")) {
16283
+ suggestions.push({
16284
+ name: "Web Design Guidelines",
16285
+ installCommand: "npx skills add vercel-labs/agent-skills@web-design-guidelines --yes",
16286
+ reason: "Web project detected"
16287
+ });
16288
+ }
16289
+ if (!suggestions.some((s2) => s2.name.includes("Plan"))) {
16290
+ suggestions.push({
16291
+ name: "Writing Plans",
16292
+ installCommand: "npx skills add obra/superpowers@writing-plans --yes",
16293
+ reason: "Helps structure work before coding"
16294
+ });
16295
+ }
16296
+ return suggestions.slice(0, 5);
16297
+ }
16298
+ function installSkill2(installCommand) {
16299
+ try {
16300
+ const result = spawnSync2("npx", installCommand.replace("npx ", "").split(" "), {
16301
+ stdio: "pipe",
16302
+ timeout: 60000,
16303
+ shell: true
16304
+ });
16305
+ if (result.status === 0) {
16306
+ return { success: true, message: "Installed successfully" };
16307
+ } else {
16308
+ const stderr = result.stderr?.toString() || "";
16309
+ return { success: false, message: stderr.slice(0, 100) || "Installation failed" };
16310
+ }
16311
+ } catch (error2) {
16312
+ return { success: false, message: error2 instanceof Error ? error2.message : "Unknown error" };
16313
+ }
16314
+ }
16315
+
16071
16316
  // src/commands/scan.ts
16072
16317
  var scanCommand = defineCommand2({
16073
16318
  meta: {
@@ -16109,6 +16354,10 @@ var scanCommand = defineCommand2({
16109
16354
  ]
16110
16355
  });
16111
16356
  since = parseSince(period);
16357
+ if (isFirstScanInProject(projectDir)) {
16358
+ await showFirstScanWelcome(projectDir);
16359
+ markProjectScanned(projectDir);
16360
+ }
16112
16361
  }
16113
16362
  const useCache = true;
16114
16363
  const watchMode = false;
@@ -16245,7 +16494,7 @@ var scanCommand = defineCommand2({
16245
16494
  console.log(` Projected monthly: ${colors2.primary(`$${scanCost.projectedMonthlyCostUsd.toFixed(2)}`)}`);
16246
16495
  console.log(colors2.dim(" " + "═".repeat(45)));
16247
16496
  console.log();
16248
- const reportDir = join9(projectDir, ".nairon/reports");
16497
+ const reportDir = join10(projectDir, ".nairon/reports");
16249
16498
  const reportPath = generateReport(reportDir, score, git, agents, tests, "7d", sdlcAnalysis, scanCost, analysis);
16250
16499
  console.log(` ${icons.success} Report saved: ${colors2.dim(reportPath)}`);
16251
16500
  if (agents && agents.sessions.length > 0) {
@@ -16461,12 +16710,12 @@ var scanCommand = defineCommand2({
16461
16710
  }
16462
16711
  });
16463
16712
  function loadProjectContext(projectDir) {
16464
- const contextPath = join9(projectDir, ".nairon", "context.json");
16465
- if (!existsSync9(contextPath)) {
16713
+ const contextPath = join10(projectDir, ".nairon", "context.json");
16714
+ if (!existsSync10(contextPath)) {
16466
16715
  return null;
16467
16716
  }
16468
16717
  try {
16469
- const raw = readFileSync9(contextPath, "utf-8");
16718
+ const raw = readFileSync10(contextPath, "utf-8");
16470
16719
  const data = JSON.parse(raw);
16471
16720
  const context = {
16472
16721
  painPoints: data.painPoints || [],
@@ -16519,12 +16768,12 @@ function parseSince(since) {
16519
16768
  return new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
16520
16769
  }
16521
16770
  function generateReport(reportDir, score, git, agents, tests, since, sdlcAnalysis, scanCost, analysis) {
16522
- if (!existsSync9(reportDir)) {
16523
- mkdirSync4(reportDir, { recursive: true });
16771
+ if (!existsSync10(reportDir)) {
16772
+ mkdirSync5(reportDir, { recursive: true });
16524
16773
  }
16525
16774
  const timestamp = new Date().toISOString().replace(/[:.]/g, "-").slice(0, 19);
16526
16775
  const filename = `scan-${timestamp}.md`;
16527
- const filepath = join9(reportDir, filename);
16776
+ const filepath = join10(reportDir, filename);
16528
16777
  const lines = [];
16529
16778
  lines.push(`# NaironAI Scan Report`);
16530
16779
  lines.push("");
@@ -16640,7 +16889,7 @@ function generateReport(reportDir, score, git, agents, tests, since, sdlcAnalysi
16640
16889
  lines.push("---");
16641
16890
  lines.push("");
16642
16891
  lines.push("*Generated by [nairon-bench](https://github.com/ObaidUr-Rahmaan/nairon-bench)*");
16643
- writeFileSync4(filepath, lines.join(`
16892
+ writeFileSync5(filepath, lines.join(`
16644
16893
  `));
16645
16894
  return filepath;
16646
16895
  }
@@ -16659,15 +16908,87 @@ function formatTokensPlain(tokens) {
16659
16908
  return `${Math.round(tokens / 1000)}K`;
16660
16909
  return tokens.toString();
16661
16910
  }
16911
+ async function showFirstScanWelcome(projectDir) {
16912
+ console.log();
16913
+ console.log(colors2.dim(" " + "═".repeat(50)));
16914
+ console.log(` ${colors2.primary("✨")} ${colors2.bold("First scan in this project!")}`);
16915
+ console.log(colors2.dim(" " + "═".repeat(50)));
16916
+ console.log();
16917
+ const detectedAgents = detectAllAgents();
16918
+ let selectedAgent = null;
16919
+ if (detectedAgents.length === 0) {
16920
+ console.log(` ${icons.info} No AI coding agents detected`);
16921
+ console.log(` ${colors2.dim(" Install Claude Code, Cursor, or OpenCode to get started")}`);
16922
+ } else if (detectedAgents.length === 1) {
16923
+ selectedAgent = detectedAgents[0];
16924
+ console.log(` ${icons.info} Detected agent: ${colors2.bold(selectedAgent.name)}`);
16925
+ } else {
16926
+ console.log(` ${icons.info} Found ${colors2.bold(detectedAgents.length.toString())} AI coding agents:`);
16927
+ console.log();
16928
+ const agentChoice = await consola.prompt("Which agent are you using for this project?", {
16929
+ type: "select",
16930
+ options: detectedAgents.map((a2) => ({
16931
+ value: a2.id,
16932
+ label: a2.name
16933
+ }))
16934
+ });
16935
+ selectedAgent = detectedAgents.find((a2) => a2.id === agentChoice) || detectedAgents[0];
16936
+ console.log();
16937
+ console.log(` ${icons.success} Selected: ${colors2.bold(selectedAgent.name)}`);
16938
+ }
16939
+ const context = analyzeReadme(projectDir);
16940
+ if (context) {
16941
+ console.log(` ${icons.info} Project: ${colors2.bold(context.name)}`);
16942
+ if (context.techStack.length > 0) {
16943
+ console.log(` ${colors2.dim(" Tech: " + context.techStack.slice(0, 4).join(", "))}`);
16944
+ }
16945
+ }
16946
+ console.log();
16947
+ const suggestions = suggestSkills(context);
16948
+ if (suggestions.length > 0) {
16949
+ console.log(` ${colors2.bold("Recommended skills for this project:")}`);
16950
+ console.log();
16951
+ for (let i3 = 0;i3 < Math.min(3, suggestions.length); i3++) {
16952
+ const s2 = suggestions[i3];
16953
+ console.log(` ${colors2.primary((i3 + 1).toString())}. ${colors2.bold(s2.name)}`);
16954
+ console.log(` ${colors2.dim(s2.reason)}`);
16955
+ }
16956
+ console.log();
16957
+ const installChoice = await consola.prompt("Install recommended skills?", {
16958
+ type: "select",
16959
+ options: [
16960
+ { value: "find-skills", label: "Just find-skills (discover more skills later)" },
16961
+ { value: "all", label: "All recommended skills" },
16962
+ { value: "skip", label: "Skip - continue to scan" }
16963
+ ]
16964
+ });
16965
+ if (installChoice === "find-skills" || installChoice === "all") {
16966
+ console.log();
16967
+ const toInstall = installChoice === "all" ? suggestions.slice(0, 3) : suggestions.slice(0, 1);
16968
+ for (const skill of toInstall) {
16969
+ process.stdout.write(` Installing ${skill.name}...`);
16970
+ const result = installSkill2(skill.installCommand);
16971
+ if (result.success) {
16972
+ console.log(` ${colors2.success("✓")}`);
16973
+ } else {
16974
+ console.log(` ${colors2.warning("⚠")} ${colors2.dim(`(${result.message.slice(0, 50)})`)}`);
16975
+ }
16976
+ }
16977
+ console.log();
16978
+ }
16979
+ }
16980
+ console.log(colors2.dim(" " + "═".repeat(50)));
16981
+ console.log();
16982
+ }
16662
16983
 
16663
16984
  // src/commands/report.ts
16664
16985
  init_dist();
16665
16986
  init_client();
16666
16987
 
16667
16988
  // src/collectors/report-data.ts
16668
- import { existsSync as existsSync10, readdirSync as readdirSync5, readFileSync as readFileSync10, statSync as statSync2 } from "node:fs";
16669
- import { homedir as homedir8 } from "node:os";
16670
- import { join as join10, basename as basename3 } from "node:path";
16989
+ import { existsSync as existsSync11, readdirSync as readdirSync5, readFileSync as readFileSync11, statSync as statSync2 } from "node:fs";
16990
+ import { homedir as homedir9 } from "node:os";
16991
+ import { join as join11, basename as basename3 } from "node:path";
16671
16992
  async function collectReportData(projectDir, since, until = new Date, harness) {
16672
16993
  const projectName = basename3(projectDir);
16673
16994
  const [commits, allSessions, mcpConfigs] = await Promise.all([
@@ -16750,12 +17071,12 @@ function detectAIAssistedCommit(message) {
16750
17071
  }
16751
17072
  async function collectAllSessions(since, until, projectDir) {
16752
17073
  const sessions = [];
16753
- const claudeDir = join10(homedir8(), ".claude");
16754
- if (existsSync10(claudeDir)) {
17074
+ const claudeDir = join11(homedir9(), ".claude");
17075
+ if (existsSync11(claudeDir)) {
16755
17076
  sessions.push(...collectClaudeCodeSessions(claudeDir, since, until, projectDir));
16756
17077
  }
16757
- const openCodeDir = join10(homedir8(), ".local", "share", "opencode");
16758
- if (existsSync10(openCodeDir)) {
17078
+ const openCodeDir = join11(homedir9(), ".local", "share", "opencode");
17079
+ if (existsSync11(openCodeDir)) {
16759
17080
  sessions.push(...collectOpenCodeSessions2(openCodeDir, since, until));
16760
17081
  }
16761
17082
  sessions.sort((a2, b2) => a2.startTime.getTime() - b2.startTime.getTime());
@@ -16763,15 +17084,15 @@ async function collectAllSessions(since, until, projectDir) {
16763
17084
  }
16764
17085
  function collectClaudeCodeSessions(claudeDir, since, until, projectDir) {
16765
17086
  const sessions = [];
16766
- const transcriptsDir = join10(claudeDir, "transcripts");
16767
- if (!existsSync10(transcriptsDir))
17087
+ const transcriptsDir = join11(claudeDir, "transcripts");
17088
+ if (!existsSync11(transcriptsDir))
16768
17089
  return sessions;
16769
17090
  const projectHash = projectDir ? hashPath(projectDir) : null;
16770
- const projectsDir = join10(claudeDir, "projects");
17091
+ const projectsDir = join11(claudeDir, "projects");
16771
17092
  try {
16772
17093
  const transcriptFiles = readdirSync5(transcriptsDir).filter((f3) => f3.endsWith(".jsonl"));
16773
17094
  for (const file of transcriptFiles) {
16774
- const filePath = join10(transcriptsDir, file);
17095
+ const filePath = join11(transcriptsDir, file);
16775
17096
  const stat = statSync2(filePath);
16776
17097
  if (stat.mtime < since || stat.mtime > until)
16777
17098
  continue;
@@ -16782,12 +17103,12 @@ function collectClaudeCodeSessions(claudeDir, since, until, projectDir) {
16782
17103
  }
16783
17104
  } catch {}
16784
17105
  }
16785
- if (projectHash && existsSync10(projectsDir)) {
16786
- const projectSessionDir = join10(projectsDir, projectHash);
16787
- if (existsSync10(projectSessionDir)) {
17106
+ if (projectHash && existsSync11(projectsDir)) {
17107
+ const projectSessionDir = join11(projectsDir, projectHash);
17108
+ if (existsSync11(projectSessionDir)) {
16788
17109
  const projectFiles = readdirSync5(projectSessionDir).filter((f3) => f3.endsWith(".jsonl"));
16789
17110
  for (const file of projectFiles) {
16790
- const filePath = join10(projectSessionDir, file);
17111
+ const filePath = join11(projectSessionDir, file);
16791
17112
  const stat = statSync2(filePath);
16792
17113
  if (stat.mtime < since || stat.mtime > until)
16793
17114
  continue;
@@ -16806,7 +17127,7 @@ function collectClaudeCodeSessions(claudeDir, since, until, projectDir) {
16806
17127
  return sessions;
16807
17128
  }
16808
17129
  function parseClaudeTranscript(filePath, fileName) {
16809
- const content = readFileSync10(filePath, "utf-8");
17130
+ const content = readFileSync11(filePath, "utf-8");
16810
17131
  const lines = content.trim().split(`
16811
17132
  `).filter((l2) => l2.trim());
16812
17133
  if (lines.length === 0)
@@ -16896,25 +17217,25 @@ function parseClaudeTranscript(filePath, fileName) {
16896
17217
  }
16897
17218
  function collectOpenCodeSessions2(openCodeDir, since, until) {
16898
17219
  const sessions = [];
16899
- const sessionDir = join10(openCodeDir, "storage", "session");
16900
- const messageDir = join10(openCodeDir, "storage", "message");
16901
- const partDir = join10(openCodeDir, "storage", "part");
16902
- if (!existsSync10(sessionDir))
17220
+ const sessionDir = join11(openCodeDir, "storage", "session");
17221
+ const messageDir = join11(openCodeDir, "storage", "message");
17222
+ const partDir = join11(openCodeDir, "storage", "part");
17223
+ if (!existsSync11(sessionDir))
16903
17224
  return sessions;
16904
17225
  try {
16905
- const projectDirs = readdirSync5(sessionDir, { withFileTypes: true }).filter((d2) => d2.isDirectory()).map((d2) => join10(sessionDir, d2.name));
17226
+ const projectDirs = readdirSync5(sessionDir, { withFileTypes: true }).filter((d2) => d2.isDirectory()).map((d2) => join11(sessionDir, d2.name));
16906
17227
  for (const projectDir of projectDirs) {
16907
17228
  const sessionFiles = readdirSync5(projectDir).filter((f3) => f3.endsWith(".json"));
16908
17229
  for (const sessionFile of sessionFiles) {
16909
17230
  try {
16910
- const sessionPath = join10(projectDir, sessionFile);
16911
- const sessionData = JSON.parse(readFileSync10(sessionPath, "utf-8"));
17231
+ const sessionPath = join11(projectDir, sessionFile);
17232
+ const sessionData = JSON.parse(readFileSync11(sessionPath, "utf-8"));
16912
17233
  const createdAt = new Date(sessionData.time?.created || 0);
16913
17234
  const updatedAt = new Date(sessionData.time?.updated || sessionData.time?.created || 0);
16914
17235
  if (updatedAt < since || createdAt > until)
16915
17236
  continue;
16916
17237
  const sessionId = sessionData.id;
16917
- const sessionMsgDir = join10(messageDir, sessionId);
17238
+ const sessionMsgDir = join11(messageDir, sessionId);
16918
17239
  const prompts = [];
16919
17240
  const responses = [];
16920
17241
  const toolsUsed = new Set;
@@ -16925,12 +17246,12 @@ function collectOpenCodeSessions2(openCodeDir, since, until) {
16925
17246
  let model = "unknown";
16926
17247
  let startTime = createdAt;
16927
17248
  let endTime = updatedAt;
16928
- if (existsSync10(sessionMsgDir)) {
17249
+ if (existsSync11(sessionMsgDir)) {
16929
17250
  const msgFiles = readdirSync5(sessionMsgDir).filter((f3) => f3.endsWith(".json")).sort();
16930
17251
  for (const msgFile of msgFiles) {
16931
17252
  try {
16932
- const msgPath = join10(sessionMsgDir, msgFile);
16933
- const msgData = JSON.parse(readFileSync10(msgPath, "utf-8"));
17253
+ const msgPath = join11(sessionMsgDir, msgFile);
17254
+ const msgData = JSON.parse(readFileSync11(msgPath, "utf-8"));
16934
17255
  const msgId = msgData.id;
16935
17256
  if (msgData.model?.modelID) {
16936
17257
  model = msgData.model.modelID;
@@ -16940,14 +17261,14 @@ function collectOpenCodeSessions2(openCodeDir, since, until) {
16940
17261
  startTime = msgTime;
16941
17262
  if (msgTime > endTime)
16942
17263
  endTime = msgTime;
16943
- const msgPartDir = join10(partDir, msgId);
17264
+ const msgPartDir = join11(partDir, msgId);
16944
17265
  let messageText = "";
16945
- if (existsSync10(msgPartDir)) {
17266
+ if (existsSync11(msgPartDir)) {
16946
17267
  const partFiles = readdirSync5(msgPartDir).filter((f3) => f3.endsWith(".json")).sort();
16947
17268
  for (const partFile of partFiles) {
16948
17269
  try {
16949
- const partPath = join10(msgPartDir, partFile);
16950
- const partData = JSON.parse(readFileSync10(partPath, "utf-8"));
17270
+ const partPath = join11(msgPartDir, partFile);
17271
+ const partData = JSON.parse(readFileSync11(partPath, "utf-8"));
16951
17272
  if (partData.type === "text" && partData.text && !partData.synthetic) {
16952
17273
  messageText += partData.text + `
16953
17274
  `;
@@ -17121,10 +17442,10 @@ function analyzeResponse(text, sessionId, index, promptId, timestamp) {
17121
17442
  }
17122
17443
  function collectMCPConfigs() {
17123
17444
  const configs = [];
17124
- const claudeConfig = join10(homedir8(), ".claude.json");
17125
- if (existsSync10(claudeConfig)) {
17445
+ const claudeConfig = join11(homedir9(), ".claude.json");
17446
+ if (existsSync11(claudeConfig)) {
17126
17447
  try {
17127
- const data = JSON.parse(readFileSync10(claudeConfig, "utf-8"));
17448
+ const data = JSON.parse(readFileSync11(claudeConfig, "utf-8"));
17128
17449
  const mcpServers = data.mcpServers || {};
17129
17450
  for (const [name, config] of Object.entries(mcpServers)) {
17130
17451
  configs.push({
@@ -17137,13 +17458,13 @@ function collectMCPConfigs() {
17137
17458
  } catch {}
17138
17459
  }
17139
17460
  const openCodeConfigs = [
17140
- join10(homedir8(), ".opencode.json"),
17141
- join10(homedir8(), ".config", "opencode", "opencode.json")
17461
+ join11(homedir9(), ".opencode.json"),
17462
+ join11(homedir9(), ".config", "opencode", "opencode.json")
17142
17463
  ];
17143
17464
  for (const configPath of openCodeConfigs) {
17144
- if (existsSync10(configPath)) {
17465
+ if (existsSync11(configPath)) {
17145
17466
  try {
17146
- const data = JSON.parse(readFileSync10(configPath, "utf-8"));
17467
+ const data = JSON.parse(readFileSync11(configPath, "utf-8"));
17147
17468
  const mcpServers = data.mcp || {};
17148
17469
  for (const [name, config] of Object.entries(mcpServers)) {
17149
17470
  if (!configs.find((c3) => c3.name === name)) {
@@ -17158,10 +17479,10 @@ function collectMCPConfigs() {
17158
17479
  } catch {}
17159
17480
  }
17160
17481
  }
17161
- const cursorConfig = join10(homedir8(), ".cursor", "mcp.json");
17162
- if (existsSync10(cursorConfig)) {
17482
+ const cursorConfig = join11(homedir9(), ".cursor", "mcp.json");
17483
+ if (existsSync11(cursorConfig)) {
17163
17484
  try {
17164
- const data = JSON.parse(readFileSync10(cursorConfig, "utf-8"));
17485
+ const data = JSON.parse(readFileSync11(cursorConfig, "utf-8"));
17165
17486
  const mcpServers = data.mcpServers || {};
17166
17487
  for (const [name, config] of Object.entries(mcpServers)) {
17167
17488
  if (!configs.find((c3) => c3.name === name)) {
@@ -19362,9 +19683,9 @@ function getSeverityEmoji(severity) {
19362
19683
  }
19363
19684
 
19364
19685
  // src/lib/tool-analyzer.ts
19365
- import { existsSync as existsSync11, readdirSync as readdirSync6 } from "node:fs";
19366
- import { homedir as homedir9 } from "node:os";
19367
- import { join as join11 } from "node:path";
19686
+ import { existsSync as existsSync12, readdirSync as readdirSync6 } from "node:fs";
19687
+ import { homedir as homedir10 } from "node:os";
19688
+ import { join as join12 } from "node:path";
19368
19689
  function analyzeToolUtilization(data) {
19369
19690
  const mcpServers = analyzeMCPServers(data);
19370
19691
  const mcpSummary = buildMCPSummary(mcpServers);
@@ -19514,24 +19835,24 @@ function categorizeTools(tools) {
19514
19835
  }
19515
19836
  function analyzeSkills() {
19516
19837
  const skills = [];
19517
- const home = homedir9();
19838
+ const home = homedir10();
19518
19839
  const skillsDirs = [
19519
- join11(home, ".claude", "skills"),
19520
- join11(home, ".agents", "skills"),
19521
- join11(home, ".config", "claude", "skills")
19840
+ join12(home, ".claude", "skills"),
19841
+ join12(home, ".agents", "skills"),
19842
+ join12(home, ".config", "claude", "skills")
19522
19843
  ];
19523
19844
  const projectSkillsDirs = [
19524
- join11(process.cwd(), ".claude", "skills"),
19525
- join11(process.cwd(), ".agents", "skills")
19845
+ join12(process.cwd(), ".claude", "skills"),
19846
+ join12(process.cwd(), ".agents", "skills")
19526
19847
  ];
19527
19848
  const openCodeSkillDirs = [
19528
- join11(home, ".config", "opencode", "skills"),
19529
- join11(home, ".local", "share", "opencode", "skills")
19849
+ join12(home, ".config", "opencode", "skills"),
19850
+ join12(home, ".local", "share", "opencode", "skills")
19530
19851
  ];
19531
19852
  const allSkillDirs = [...skillsDirs, ...projectSkillsDirs, ...openCodeSkillDirs];
19532
19853
  const seenSkills = new Set;
19533
19854
  for (const skillsDir of allSkillDirs) {
19534
- if (existsSync11(skillsDir)) {
19855
+ if (existsSync12(skillsDir)) {
19535
19856
  try {
19536
19857
  const entries = readdirSync6(skillsDir, { withFileTypes: true });
19537
19858
  for (const entry of entries) {
@@ -19542,7 +19863,7 @@ function analyzeSkills() {
19542
19863
  if (entry.isDirectory() || entry.isSymbolicLink() || entry.name.endsWith(".md")) {
19543
19864
  skills.push({
19544
19865
  name: skillName,
19545
- path: join11(skillsDir, entry.name),
19866
+ path: join12(skillsDir, entry.name),
19546
19867
  used: false,
19547
19868
  usageCount: 0
19548
19869
  });
@@ -19839,22 +20160,22 @@ function renderToolUtilizationMarkdown(analysis) {
19839
20160
  }
19840
20161
 
19841
20162
  // src/lib/coverage-parser.ts
19842
- import { existsSync as existsSync12, readFileSync as readFileSync12 } from "node:fs";
19843
- import { join as join12 } from "node:path";
20163
+ import { existsSync as existsSync13, readFileSync as readFileSync13 } from "node:fs";
20164
+ import { join as join13 } from "node:path";
19844
20165
  function parseCoverageReport(projectDir) {
19845
20166
  const coveragePaths = [
19846
- { path: join12(projectDir, "coverage", "lcov.info"), parser: parseLcov },
19847
- { path: join12(projectDir, "coverage", "coverage-summary.json"), parser: parseIstanbulSummary },
19848
- { path: join12(projectDir, "coverage", "coverage-final.json"), parser: parseIstanbulFinal },
19849
- { path: join12(projectDir, "coverage", "cobertura-coverage.xml"), parser: parseCobertura },
19850
- { path: join12(projectDir, "coverage", "clover.xml"), parser: parseClover },
19851
- { path: join12(projectDir, "lcov.info"), parser: parseLcov },
19852
- { path: join12(projectDir, ".nyc_output", "coverage-summary.json"), parser: parseIstanbulSummary }
20167
+ { path: join13(projectDir, "coverage", "lcov.info"), parser: parseLcov },
20168
+ { path: join13(projectDir, "coverage", "coverage-summary.json"), parser: parseIstanbulSummary },
20169
+ { path: join13(projectDir, "coverage", "coverage-final.json"), parser: parseIstanbulFinal },
20170
+ { path: join13(projectDir, "coverage", "cobertura-coverage.xml"), parser: parseCobertura },
20171
+ { path: join13(projectDir, "coverage", "clover.xml"), parser: parseClover },
20172
+ { path: join13(projectDir, "lcov.info"), parser: parseLcov },
20173
+ { path: join13(projectDir, ".nyc_output", "coverage-summary.json"), parser: parseIstanbulSummary }
19853
20174
  ];
19854
20175
  for (const { path, parser: parser4 } of coveragePaths) {
19855
- if (existsSync12(path)) {
20176
+ if (existsSync13(path)) {
19856
20177
  try {
19857
- const content = readFileSync12(path, "utf-8");
20178
+ const content = readFileSync13(path, "utf-8");
19858
20179
  return parser4(content, path);
19859
20180
  } catch {}
19860
20181
  }
@@ -21566,7 +21887,7 @@ function formatReportAsJSON(report) {
21566
21887
  }
21567
21888
 
21568
21889
  // src/commands/report.ts
21569
- import { writeFileSync as writeFileSync5 } from "node:fs";
21890
+ import { writeFileSync as writeFileSync6 } from "node:fs";
21570
21891
  import { resolve } from "node:path";
21571
21892
  var reportCommand = defineCommand2({
21572
21893
  meta: {
@@ -21778,7 +22099,7 @@ async function runHackathonReport(args) {
21778
22099
  }
21779
22100
  if (args.output) {
21780
22101
  const filepath = resolve(projectDir, args.output);
21781
- writeFileSync5(filepath, output);
22102
+ writeFileSync6(filepath, output);
21782
22103
  consola.success(`Report saved to ${filepath}`);
21783
22104
  }
21784
22105
  console.log(output);
@@ -21947,7 +22268,7 @@ async function runLeadershipReport(args) {
21947
22268
  }
21948
22269
  if (args.output) {
21949
22270
  const filepath = resolve(projectDir, args.output);
21950
- writeFileSync5(filepath, output);
22271
+ writeFileSync6(filepath, output);
21951
22272
  consola.success(`Report saved to ${filepath}`);
21952
22273
  }
21953
22274
  console.log(output);
@@ -22109,9 +22430,9 @@ function renderBar4(value, width) {
22109
22430
  }
22110
22431
 
22111
22432
  // src/commands/doctor.ts
22112
- import { existsSync as existsSync13 } from "node:fs";
22113
- import { homedir as homedir10 } from "node:os";
22114
- import { join as join13 } from "node:path";
22433
+ import { existsSync as existsSync14 } from "node:fs";
22434
+ import { homedir as homedir11 } from "node:os";
22435
+ import { join as join14 } from "node:path";
22115
22436
  init_client();
22116
22437
 
22117
22438
  // src/lib/recommendations-db.ts
@@ -22237,6 +22558,18 @@ var PLUGINS = [
22237
22558
  }
22238
22559
  ];
22239
22560
  var SKILLS = [
22561
+ {
22562
+ id: "find-skills",
22563
+ name: "Find Skills",
22564
+ type: "skill",
22565
+ description: "Discover and install skills from the open agent skills ecosystem - essential for any AI workflow",
22566
+ installCommand: "npx skills add vercel-labs/skills@find-skills --yes",
22567
+ phases: ["requirements", "planning", "implementation", "review"],
22568
+ impact: "high",
22569
+ detectionKey: "find-skills",
22570
+ website: "https://skills.sh/vercel-labs/skills/find-skills",
22571
+ badge: "Essential"
22572
+ },
22240
22573
  {
22241
22574
  id: "tdd-skill",
22242
22575
  name: "Test-Driven Development",
@@ -22760,16 +23093,16 @@ var doctorCommand = defineCommand2({
22760
23093
  results.push({ label: "OS", status: "info", value: `${process.platform} ${process.arch}` });
22761
23094
  results.push({ label: "Bun", status: "info", value: typeof Bun !== "undefined" ? Bun.version : "N/A" });
22762
23095
  results.push({ label: "Node", status: "info", value: process.version });
22763
- results.push({ label: "Home", status: "info", value: homedir10() });
22764
- const gitDir = join13(process.cwd(), ".git");
22765
- if (existsSync13(gitDir)) {
23096
+ results.push({ label: "Home", status: "info", value: homedir11() });
23097
+ const gitDir = join14(process.cwd(), ".git");
23098
+ if (existsSync14(gitDir)) {
22766
23099
  results.push({ label: "Git", status: "success", value: "Repository detected" });
22767
23100
  } else {
22768
23101
  results.push({ label: "Git", status: "warn", value: "No repository in current directory" });
22769
23102
  }
22770
23103
  for (const [agent, pathTemplate] of Object.entries(AGENT_LOG_PATHS)) {
22771
- const resolvedPath = pathTemplate.replace("~", homedir10());
22772
- if (existsSync13(resolvedPath)) {
23104
+ const resolvedPath = pathTemplate.replace("~", homedir11());
23105
+ if (existsSync14(resolvedPath)) {
22773
23106
  results.push({ label: agent, status: "success", value: `found at ${resolvedPath}` });
22774
23107
  }
22775
23108
  }
@@ -22823,10 +23156,10 @@ var doctorCommand = defineCommand2({
22823
23156
  });
22824
23157
 
22825
23158
  // src/commands/setup.ts
22826
- import { existsSync as existsSync14, readFileSync as readFileSync13, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, copyFileSync } from "node:fs";
22827
- import { join as join14, dirname as dirname2 } from "node:path";
22828
- import { homedir as homedir11, platform as platform2 } from "node:os";
22829
- import { execSync as execSync3 } from "node:child_process";
23159
+ import { existsSync as existsSync15, readFileSync as readFileSync14, writeFileSync as writeFileSync7, mkdirSync as mkdirSync6, copyFileSync } from "node:fs";
23160
+ import { join as join15, dirname as dirname2 } from "node:path";
23161
+ import { homedir as homedir12, platform as platform2 } from "node:os";
23162
+ import { execSync as execSync4 } from "node:child_process";
22830
23163
  import { createInterface } from "node:readline";
22831
23164
  var CONVEX_SITE_URL = "https://steady-bass-841.convex.site";
22832
23165
  async function fetchSetupData() {
@@ -22844,7 +23177,7 @@ var FALLBACK_HARNESSES = [
22844
23177
  id: "claude-code",
22845
23178
  name: "Claude Code",
22846
23179
  configPaths: [
22847
- join14(homedir11(), ".claude.json")
23180
+ join15(homedir12(), ".claude.json")
22848
23181
  ],
22849
23182
  mcpConfigKey: "mcpServers",
22850
23183
  detected: false
@@ -22853,8 +23186,8 @@ var FALLBACK_HARNESSES = [
22853
23186
  id: "opencode",
22854
23187
  name: "OpenCode",
22855
23188
  configPaths: [
22856
- join14(homedir11(), ".opencode.json"),
22857
- join14(homedir11(), ".config", "opencode", "opencode.json")
23189
+ join15(homedir12(), ".opencode.json"),
23190
+ join15(homedir12(), ".config", "opencode", "opencode.json")
22858
23191
  ],
22859
23192
  mcpConfigKey: "mcp",
22860
23193
  detected: false
@@ -22863,8 +23196,8 @@ var FALLBACK_HARNESSES = [
22863
23196
  id: "cursor",
22864
23197
  name: "Cursor",
22865
23198
  configPaths: [
22866
- join14(homedir11(), ".cursor", "mcp.json"),
22867
- join14(homedir11(), "Library", "Application Support", "Cursor", "User", "globalStorage", "mcp.json")
23199
+ join15(homedir12(), ".cursor", "mcp.json"),
23200
+ join15(homedir12(), "Library", "Application Support", "Cursor", "User", "globalStorage", "mcp.json")
22868
23201
  ],
22869
23202
  mcpConfigKey: "mcpServers",
22870
23203
  detected: false
@@ -22881,7 +23214,7 @@ function getConfigPathsForPlatform(harness) {
22881
23214
  } else {
22882
23215
  paths = pathMap.linux;
22883
23216
  }
22884
- return paths.map((p) => p.replace(/^~/, homedir11()).replace(/%USERPROFILE%/gi, homedir11()).replace(/%APPDATA%/gi, join14(homedir11(), "AppData", "Roaming")));
23217
+ return paths.map((p) => p.replace(/^~/, homedir12()).replace(/%USERPROFILE%/gi, homedir12()).replace(/%APPDATA%/gi, join15(homedir12(), "AppData", "Roaming")));
22885
23218
  }
22886
23219
  function convertAPIHarnessToConfig(harness) {
22887
23220
  return {
@@ -22896,7 +23229,7 @@ function detectHarnesses(harnesses) {
22896
23229
  const detected = [];
22897
23230
  for (const harness of harnesses) {
22898
23231
  for (const configPath of harness.configPaths) {
22899
- if (existsSync14(configPath)) {
23232
+ if (existsSync15(configPath)) {
22900
23233
  detected.push({
22901
23234
  ...harness,
22902
23235
  detected: true,
@@ -22909,19 +23242,19 @@ function detectHarnesses(harnesses) {
22909
23242
  return detected;
22910
23243
  }
22911
23244
  function backupConfig(configPath) {
22912
- const backupDir = join14(homedir11(), ".nairon", "backups");
22913
- if (!existsSync14(backupDir)) {
22914
- mkdirSync5(backupDir, { recursive: true });
23245
+ const backupDir = join15(homedir12(), ".nairon", "backups");
23246
+ if (!existsSync15(backupDir)) {
23247
+ mkdirSync6(backupDir, { recursive: true });
22915
23248
  }
22916
23249
  const timestamp = new Date().toISOString().replace(/[:.]/g, "-").slice(0, 19);
22917
23250
  const filename = configPath.replace(/[/\\]/g, "_").replace(/^_/, "");
22918
- const backupPath = join14(backupDir, `${timestamp}_${filename}`);
23251
+ const backupPath = join15(backupDir, `${timestamp}_${filename}`);
22919
23252
  copyFileSync(configPath, backupPath);
22920
23253
  return backupPath;
22921
23254
  }
22922
23255
  function readJsonConfig(configPath) {
22923
23256
  try {
22924
- const content = readFileSync13(configPath, "utf-8");
23257
+ const content = readFileSync14(configPath, "utf-8");
22925
23258
  return JSON.parse(content);
22926
23259
  } catch {
22927
23260
  return {};
@@ -22929,10 +23262,10 @@ function readJsonConfig(configPath) {
22929
23262
  }
22930
23263
  function writeJsonConfig(configPath, config) {
22931
23264
  const dir = dirname2(configPath);
22932
- if (!existsSync14(dir)) {
22933
- mkdirSync5(dir, { recursive: true });
23265
+ if (!existsSync15(dir)) {
23266
+ mkdirSync6(dir, { recursive: true });
22934
23267
  }
22935
- writeFileSync6(configPath, JSON.stringify(config, null, 2));
23268
+ writeFileSync7(configPath, JSON.stringify(config, null, 2));
22936
23269
  }
22937
23270
  async function prompt2(question) {
22938
23271
  const rl = createInterface({
@@ -22973,7 +23306,7 @@ function getInstalledMCPs(harnesses) {
22973
23306
  const installed = new Set;
22974
23307
  for (const harness of harnesses) {
22975
23308
  for (const configPath of harness.configPaths) {
22976
- if (!existsSync14(configPath))
23309
+ if (!existsSync15(configPath))
22977
23310
  continue;
22978
23311
  const config = readJsonConfig(configPath);
22979
23312
  const mcpServers = config[harness.mcpConfigKey];
@@ -22997,7 +23330,7 @@ async function installMCPServer(serverName, instruction, harness) {
22997
23330
  if (!harness.configPath || !instruction.mcpServerConfig)
22998
23331
  return false;
22999
23332
  try {
23000
- if (existsSync14(harness.configPath)) {
23333
+ if (existsSync15(harness.configPath)) {
23001
23334
  backupConfig(harness.configPath);
23002
23335
  }
23003
23336
  const config = readJsonConfig(harness.configPath);
@@ -23025,16 +23358,16 @@ async function installMCPServer(serverName, instruction, harness) {
23025
23358
  async function installBeads(projectDir) {
23026
23359
  try {
23027
23360
  try {
23028
- execSync3("bd --version", { stdio: "ignore" });
23361
+ execSync4("bd --version", { stdio: "ignore" });
23029
23362
  } catch {
23030
23363
  const spinner = createSpinner("Installing Beads globally...");
23031
23364
  spinner.start();
23032
23365
  try {
23033
- execSync3("bun add -g beads", { stdio: "ignore" });
23366
+ execSync4("bun add -g beads", { stdio: "ignore" });
23034
23367
  spinner.succeed("Beads installed globally");
23035
23368
  } catch {
23036
23369
  try {
23037
- execSync3("npm install -g beads", { stdio: "ignore" });
23370
+ execSync4("npm install -g beads", { stdio: "ignore" });
23038
23371
  spinner.succeed("Beads installed globally (via npm)");
23039
23372
  } catch {
23040
23373
  spinner.fail("Failed to install Beads globally");
@@ -23042,13 +23375,13 @@ async function installBeads(projectDir) {
23042
23375
  }
23043
23376
  }
23044
23377
  }
23045
- const beadsDir = join14(projectDir, ".beads");
23046
- if (!existsSync14(beadsDir)) {
23378
+ const beadsDir = join15(projectDir, ".beads");
23379
+ if (!existsSync15(beadsDir)) {
23047
23380
  const projectName = projectDir.split(/[/\\]/).pop() ?? "project";
23048
23381
  const initSpinner = createSpinner(`Initializing Beads in ${projectName}...`);
23049
23382
  initSpinner.start();
23050
23383
  try {
23051
- execSync3(`bd init ${projectName}`, { cwd: projectDir, stdio: "ignore" });
23384
+ execSync4(`bd init ${projectName}`, { cwd: projectDir, stdio: "ignore" });
23052
23385
  initSpinner.succeed(`Beads initialized in ${projectName}`);
23053
23386
  } catch {
23054
23387
  initSpinner.fail("Failed to initialize Beads in project");
@@ -23062,9 +23395,9 @@ async function installBeads(projectDir) {
23062
23395
  }
23063
23396
  }
23064
23397
  async function createClaudeRules(projectDir) {
23065
- const claudeMdPath = join14(projectDir, "CLAUDE.md");
23066
- const agentsMdPath = join14(projectDir, "AGENTS.md");
23067
- if (existsSync14(claudeMdPath) || existsSync14(agentsMdPath)) {
23398
+ const claudeMdPath = join15(projectDir, "CLAUDE.md");
23399
+ const agentsMdPath = join15(projectDir, "AGENTS.md");
23400
+ if (existsSync15(claudeMdPath) || existsSync15(agentsMdPath)) {
23068
23401
  console.log(` ${icons.info} CLAUDE.md or AGENTS.md already exists`);
23069
23402
  return true;
23070
23403
  }
@@ -23098,7 +23431,7 @@ bun run build
23098
23431
  Use conventional commits: feat:, fix:, docs:, refactor:, test:, chore:
23099
23432
  `;
23100
23433
  try {
23101
- writeFileSync6(claudeMdPath, content);
23434
+ writeFileSync7(claudeMdPath, content);
23102
23435
  return true;
23103
23436
  } catch {
23104
23437
  return false;
@@ -23378,7 +23711,7 @@ var setupCommand = defineCommand2({
23378
23711
  });
23379
23712
 
23380
23713
  // src/commands/upgrade.ts
23381
- import { execSync as execSync4 } from "node:child_process";
23714
+ import { execSync as execSync5 } from "node:child_process";
23382
23715
  var CYAN = "\x1B[36m";
23383
23716
  var GREEN = "\x1B[32m";
23384
23717
  var YELLOW = "\x1B[33m";
@@ -23387,6 +23720,27 @@ var BOLD = "\x1B[1m";
23387
23720
  var RESET = "\x1B[0m";
23388
23721
  var MAGENTA = "\x1B[35m";
23389
23722
  var CHANGELOG = [
23723
+ {
23724
+ version: "0.5.2",
23725
+ date: "2026-02-14",
23726
+ title: "Multi-Agent Detection",
23727
+ highlights: [
23728
+ "Detects ALL installed AI agents (Claude Code, Cursor, OpenCode, Codex, etc.)",
23729
+ "Choose which agent you're using if multiple are found",
23730
+ "Expanded agent support: Copilot, Cody, Aider"
23731
+ ]
23732
+ },
23733
+ {
23734
+ version: "0.5.1",
23735
+ date: "2026-02-14",
23736
+ title: "Smart Project Onboarding",
23737
+ highlights: [
23738
+ "First scan detects your project and suggests relevant skills",
23739
+ "Auto-installs find-skills to discover more tools later",
23740
+ "Analyzes README to recommend skills for your tech stack",
23741
+ "Detects your AI agent (Claude Code, OpenCode, Cursor)"
23742
+ ]
23743
+ },
23390
23744
  {
23391
23745
  version: "0.5.0",
23392
23746
  date: "2026-02-14",
@@ -23703,7 +24057,7 @@ var upgradeCommand = defineCommand2({
23703
24057
  console.log(`${DIM} Checking for updates...${RESET}`);
23704
24058
  let latestVersion;
23705
24059
  try {
23706
- latestVersion = execSync4("npm view nairon-bench version", { encoding: "utf-8" }).trim();
24060
+ latestVersion = execSync5("npm view nairon-bench version", { encoding: "utf-8" }).trim();
23707
24061
  } catch {
23708
24062
  console.log(` ${YELLOW}⚠${RESET} Could not check npm registry`);
23709
24063
  console.log(` ${DIM}Run 'bun add -g nairon-bench@latest' manually${RESET}`);
@@ -23730,7 +24084,7 @@ var upgradeCommand = defineCommand2({
23730
24084
  console.log(` ${CYAN}↓${RESET} Upgrading to ${GREEN}v${latestVersion}${RESET}...`);
23731
24085
  console.log();
23732
24086
  try {
23733
- execSync4("npm install -g nairon-bench@latest", {
24087
+ execSync5("npm install -g nairon-bench@latest", {
23734
24088
  stdio: "inherit",
23735
24089
  env: { ...process.env, npm_config_fund: "false" }
23736
24090
  });
@@ -23748,7 +24102,7 @@ var upgradeCommand = defineCommand2({
23748
24102
  });
23749
24103
  function getCurrentVersion() {
23750
24104
  try {
23751
- const output = execSync4("nb --version 2>/dev/null || nairon-bench --version 2>/dev/null", {
24105
+ const output = execSync5("nb --version 2>/dev/null || nairon-bench --version 2>/dev/null", {
23752
24106
  encoding: "utf-8",
23753
24107
  stdio: ["pipe", "pipe", "pipe"]
23754
24108
  });
@@ -23837,7 +24191,7 @@ function showFullChangelog() {
23837
24191
  // package.json
23838
24192
  var package_default = {
23839
24193
  name: "nairon-bench",
23840
- version: "0.5.0",
24194
+ version: "0.5.2",
23841
24195
  description: "AI workflow benchmarking CLI",
23842
24196
  type: "module",
23843
24197
  bin: {
@@ -23845,7 +24199,8 @@ var package_default = {
23845
24199
  nb: "./dist/index.js"
23846
24200
  },
23847
24201
  files: [
23848
- "dist"
24202
+ "dist",
24203
+ "postinstall.js"
23849
24204
  ],
23850
24205
  repository: {
23851
24206
  type: "git",
@@ -23873,7 +24228,8 @@ var package_default = {
23873
24228
  "test:e2e": "vitest run tests/e2e/",
23874
24229
  "test:watch": "vitest",
23875
24230
  clean: "rm -rf dist",
23876
- prepublishOnly: "bun run build"
24231
+ prepublishOnly: "bun run build",
24232
+ postinstall: "node postinstall.js || true"
23877
24233
  },
23878
24234
  dependencies: {
23879
24235
  "cli-boxes": "^4.0.1",
@@ -23896,9 +24252,9 @@ var versionCommand = defineCommand2({
23896
24252
 
23897
24253
  // src/commands/init.ts
23898
24254
  init_dist();
23899
- import { existsSync as existsSync15 } from "node:fs";
23900
- import { homedir as homedir12, platform as platform3, arch } from "node:os";
23901
- import { join as join15 } from "node:path";
24255
+ import { existsSync as existsSync16 } from "node:fs";
24256
+ import { homedir as homedir13, platform as platform3, arch } from "node:os";
24257
+ import { join as join16 } from "node:path";
23902
24258
  init_client();
23903
24259
 
23904
24260
  // src/lib/github-auth.ts
@@ -24068,8 +24424,8 @@ var initCommand = defineCommand2({
24068
24424
  consola.start("Step 2/6: Detecting AI agents...");
24069
24425
  const detectedAgents = [];
24070
24426
  for (const [agent, pathTemplate] of Object.entries(AGENT_LOG_PATHS)) {
24071
- const resolvedPath = pathTemplate.replace("~", homedir12());
24072
- if (existsSync15(resolvedPath)) {
24427
+ const resolvedPath = pathTemplate.replace("~", homedir13());
24428
+ if (existsSync16(resolvedPath)) {
24073
24429
  detectedAgents.push(agent);
24074
24430
  consola.success(` Found: ${agent}`);
24075
24431
  }
@@ -24172,7 +24528,7 @@ var initCommand = defineCommand2({
24172
24528
  { name: "playwright", configs: ["playwright.config.ts", "playwright.config.js"] }
24173
24529
  ];
24174
24530
  for (const fw of testFrameworks) {
24175
- if (fw.configs.some((c3) => existsSync15(join15(process.cwd(), c3)))) {
24531
+ if (fw.configs.some((c3) => existsSync16(join16(process.cwd(), c3)))) {
24176
24532
  toolStack.testing.push(fw.name);
24177
24533
  }
24178
24534
  }
@@ -24241,13 +24597,13 @@ var initCommand = defineCommand2({
24241
24597
  });
24242
24598
  function detectPackageManager() {
24243
24599
  const cwd = process.cwd();
24244
- if (existsSync15(join15(cwd, "bun.lock")) || existsSync15(join15(cwd, "bun.lockb")))
24600
+ if (existsSync16(join16(cwd, "bun.lock")) || existsSync16(join16(cwd, "bun.lockb")))
24245
24601
  return "bun";
24246
- if (existsSync15(join15(cwd, "pnpm-lock.yaml")))
24602
+ if (existsSync16(join16(cwd, "pnpm-lock.yaml")))
24247
24603
  return "pnpm";
24248
- if (existsSync15(join15(cwd, "yarn.lock")))
24604
+ if (existsSync16(join16(cwd, "yarn.lock")))
24249
24605
  return "yarn";
24250
- if (existsSync15(join15(cwd, "package-lock.json")))
24606
+ if (existsSync16(join16(cwd, "package-lock.json")))
24251
24607
  return "npm";
24252
24608
  return;
24253
24609
  }
@@ -24262,15 +24618,15 @@ var CLAUDE_CODE_SKILLS = [
24262
24618
  ];
24263
24619
  function detectEasyWins(detectedAgents) {
24264
24620
  const wins = [];
24265
- const home = homedir12();
24621
+ const home = homedir13();
24266
24622
  const hasClaudeCode = detectedAgents.some((a2) => a2.toLowerCase().includes("claude") || a2.toLowerCase().includes("opencode"));
24267
- const claudeConfigDir = join15(home, ".claude");
24268
- const hasClaudeConfig = existsSync15(claudeConfigDir);
24623
+ const claudeConfigDir = join16(home, ".claude");
24624
+ const hasClaudeConfig = existsSync16(claudeConfigDir);
24269
24625
  if (hasClaudeCode || hasClaudeConfig) {
24270
- const skillsDir = join15(home, ".claude", "skills");
24626
+ const skillsDir = join16(home, ".claude", "skills");
24271
24627
  for (const skill of CLAUDE_CODE_SKILLS) {
24272
- const skillPath = join15(skillsDir, skill.id);
24273
- const isInstalled = existsSync15(skillPath);
24628
+ const skillPath = join16(skillsDir, skill.id);
24629
+ const isInstalled = existsSync16(skillPath);
24274
24630
  if (!isInstalled) {
24275
24631
  wins.push({
24276
24632
  icon: skill.icon,
@@ -24286,12 +24642,12 @@ function detectEasyWins(detectedAgents) {
24286
24642
  // src/commands/onboard.ts
24287
24643
  init_dist();
24288
24644
  init_client();
24289
- import { existsSync as existsSync17, mkdirSync as mkdirSync6, readFileSync as readFileSync15, writeFileSync as writeFileSync7, readdirSync as readdirSync9 } from "node:fs";
24290
- import { join as join17 } from "node:path";
24645
+ import { existsSync as existsSync18, mkdirSync as mkdirSync7, readFileSync as readFileSync16, writeFileSync as writeFileSync8, readdirSync as readdirSync9 } from "node:fs";
24646
+ import { join as join18 } from "node:path";
24291
24647
 
24292
24648
  // src/lib/project-context-detector.ts
24293
- import { existsSync as existsSync16, readFileSync as readFileSync14, readdirSync as readdirSync8 } from "node:fs";
24294
- import { join as join16, basename as basename4 } from "node:path";
24649
+ import { existsSync as existsSync17, readFileSync as readFileSync15, readdirSync as readdirSync8 } from "node:fs";
24650
+ import { join as join17, basename as basename4 } from "node:path";
24295
24651
  function detectProjectContext(projectDir) {
24296
24652
  const projectName = basename4(projectDir);
24297
24653
  const projectId = generateProjectId(projectDir);
@@ -24327,11 +24683,11 @@ function detectTechStack(projectDir) {
24327
24683
  };
24328
24684
  }
24329
24685
  function readPackageJson(projectDir) {
24330
- const pkgPath = join16(projectDir, "package.json");
24331
- if (!existsSync16(pkgPath))
24686
+ const pkgPath = join17(projectDir, "package.json");
24687
+ if (!existsSync17(pkgPath))
24332
24688
  return {};
24333
24689
  try {
24334
- return JSON.parse(readFileSync14(pkgPath, "utf-8"));
24690
+ return JSON.parse(readFileSync15(pkgPath, "utf-8"));
24335
24691
  } catch {
24336
24692
  return {};
24337
24693
  }
@@ -24352,34 +24708,34 @@ function detectFramework(deps) {
24352
24708
  return null;
24353
24709
  }
24354
24710
  function detectMetaFramework(deps, projectDir) {
24355
- if (deps.next || existsSync16(join16(projectDir, "next.config.js")) || existsSync16(join16(projectDir, "next.config.mjs")))
24711
+ if (deps.next || existsSync17(join17(projectDir, "next.config.js")) || existsSync17(join17(projectDir, "next.config.mjs")))
24356
24712
  return "next";
24357
- if (deps.nuxt || existsSync16(join16(projectDir, "nuxt.config.ts")))
24713
+ if (deps.nuxt || existsSync17(join17(projectDir, "nuxt.config.ts")))
24358
24714
  return "nuxt";
24359
24715
  if (deps["@sveltejs/kit"])
24360
24716
  return "sveltekit";
24361
- if (deps.astro || existsSync16(join16(projectDir, "astro.config.mjs")))
24717
+ if (deps.astro || existsSync17(join17(projectDir, "astro.config.mjs")))
24362
24718
  return "astro";
24363
24719
  if (deps["@remix-run/react"])
24364
24720
  return "remix";
24365
24721
  if (deps.gatsby)
24366
24722
  return "gatsby";
24367
- if (deps.vite || existsSync16(join16(projectDir, "vite.config.ts")))
24723
+ if (deps.vite || existsSync17(join17(projectDir, "vite.config.ts")))
24368
24724
  return "vite";
24369
24725
  return null;
24370
24726
  }
24371
24727
  function detectRuntime(projectDir) {
24372
- if (existsSync16(join16(projectDir, "bun.lockb")) || existsSync16(join16(projectDir, "bun.lock")))
24728
+ if (existsSync17(join17(projectDir, "bun.lockb")) || existsSync17(join17(projectDir, "bun.lock")))
24373
24729
  return "bun";
24374
- if (existsSync16(join16(projectDir, "deno.json")) || existsSync16(join16(projectDir, "deno.lock")))
24730
+ if (existsSync17(join17(projectDir, "deno.json")) || existsSync17(join17(projectDir, "deno.lock")))
24375
24731
  return "deno";
24376
24732
  return "node";
24377
24733
  }
24378
24734
  function detectLanguage(projectDir) {
24379
- if (existsSync16(join16(projectDir, "tsconfig.json")))
24735
+ if (existsSync17(join17(projectDir, "tsconfig.json")))
24380
24736
  return "typescript";
24381
- const srcDir = join16(projectDir, "src");
24382
- if (existsSync16(srcDir)) {
24737
+ const srcDir = join17(projectDir, "src");
24738
+ if (existsSync17(srcDir)) {
24383
24739
  try {
24384
24740
  const files = readdirSync8(srcDir);
24385
24741
  if (files.some((f3) => f3.endsWith(".ts") || f3.endsWith(".tsx")))
@@ -24390,7 +24746,7 @@ function detectLanguage(projectDir) {
24390
24746
  }
24391
24747
  function detectStyling(deps, projectDir) {
24392
24748
  const tools = [];
24393
- if (deps.tailwindcss || existsSync16(join16(projectDir, "tailwind.config.js")) || existsSync16(join16(projectDir, "tailwind.config.ts")))
24749
+ if (deps.tailwindcss || existsSync17(join17(projectDir, "tailwind.config.js")) || existsSync17(join17(projectDir, "tailwind.config.ts")))
24394
24750
  tools.push("tailwind");
24395
24751
  if (deps["styled-components"])
24396
24752
  tools.push("styled-components");
@@ -24435,13 +24791,13 @@ function detectORM(deps) {
24435
24791
  }
24436
24792
  function detectTesting(deps, projectDir) {
24437
24793
  const tools = [];
24438
- if (deps.vitest || existsSync16(join16(projectDir, "vitest.config.ts")))
24794
+ if (deps.vitest || existsSync17(join17(projectDir, "vitest.config.ts")))
24439
24795
  tools.push("vitest");
24440
- if (deps.jest || existsSync16(join16(projectDir, "jest.config.js")))
24796
+ if (deps.jest || existsSync17(join17(projectDir, "jest.config.js")))
24441
24797
  tools.push("jest");
24442
- if (deps["@playwright/test"] || existsSync16(join16(projectDir, "playwright.config.ts")))
24798
+ if (deps["@playwright/test"] || existsSync17(join17(projectDir, "playwright.config.ts")))
24443
24799
  tools.push("playwright");
24444
- if (deps.cypress || existsSync16(join16(projectDir, "cypress.config.ts")))
24800
+ if (deps.cypress || existsSync17(join17(projectDir, "cypress.config.ts")))
24445
24801
  tools.push("cypress");
24446
24802
  if (deps["@testing-library/react"] || deps["@testing-library/vue"])
24447
24803
  tools.push("testing-library");
@@ -24473,7 +24829,7 @@ function detectBuildTools(deps, projectDir) {
24473
24829
  tools.push("esbuild");
24474
24830
  if (deps.webpack)
24475
24831
  tools.push("webpack");
24476
- if (deps.turbo || existsSync16(join16(projectDir, "turbo.json")))
24832
+ if (deps.turbo || existsSync17(join17(projectDir, "turbo.json")))
24477
24833
  tools.push("turborepo");
24478
24834
  if (deps.tsup)
24479
24835
  tools.push("tsup");
@@ -24483,17 +24839,17 @@ function detectBuildTools(deps, projectDir) {
24483
24839
  }
24484
24840
  function detectDeployment(projectDir) {
24485
24841
  const tools = [];
24486
- if (existsSync16(join16(projectDir, "vercel.json")) || existsSync16(join16(projectDir, ".vercel")))
24842
+ if (existsSync17(join17(projectDir, "vercel.json")) || existsSync17(join17(projectDir, ".vercel")))
24487
24843
  tools.push("vercel");
24488
- if (existsSync16(join16(projectDir, "netlify.toml")))
24844
+ if (existsSync17(join17(projectDir, "netlify.toml")))
24489
24845
  tools.push("netlify");
24490
- if (existsSync16(join16(projectDir, "fly.toml")))
24846
+ if (existsSync17(join17(projectDir, "fly.toml")))
24491
24847
  tools.push("fly");
24492
- if (existsSync16(join16(projectDir, "railway.json")))
24848
+ if (existsSync17(join17(projectDir, "railway.json")))
24493
24849
  tools.push("railway");
24494
- if (existsSync16(join16(projectDir, "Dockerfile")))
24850
+ if (existsSync17(join17(projectDir, "Dockerfile")))
24495
24851
  tools.push("docker");
24496
- if (existsSync16(join16(projectDir, ".github", "workflows")))
24852
+ if (existsSync17(join17(projectDir, ".github", "workflows")))
24497
24853
  tools.push("github-actions");
24498
24854
  return tools;
24499
24855
  }
@@ -24516,20 +24872,20 @@ function detectAIML(deps) {
24516
24872
  return tools;
24517
24873
  }
24518
24874
  function inferProjectType(projectDir, techStack) {
24519
- if (existsSync16(join16(projectDir, "packages")) || existsSync16(join16(projectDir, "apps"))) {
24875
+ if (existsSync17(join17(projectDir, "packages")) || existsSync17(join17(projectDir, "apps"))) {
24520
24876
  return "monorepo";
24521
24877
  }
24522
24878
  const pkg = readPackageJson(projectDir);
24523
- if (pkg.bin || existsSync16(join16(projectDir, "src", "cli.ts")) || existsSync16(join16(projectDir, "src", "index.ts"))) {
24879
+ if (pkg.bin || existsSync17(join17(projectDir, "src", "cli.ts")) || existsSync17(join17(projectDir, "src", "index.ts"))) {
24524
24880
  const hasBin = !!pkg.bin;
24525
- const hasCommands = existsSync16(join16(projectDir, "src", "commands"));
24881
+ const hasCommands = existsSync17(join17(projectDir, "src", "commands"));
24526
24882
  if (hasBin || hasCommands)
24527
24883
  return "cli";
24528
24884
  }
24529
24885
  if (!techStack.framework && !techStack.metaFramework && pkg.main) {
24530
24886
  return "library";
24531
24887
  }
24532
- if (existsSync16(join16(projectDir, "app.json")) || existsSync16(join16(projectDir, "expo"))) {
24888
+ if (existsSync17(join17(projectDir, "app.json")) || existsSync17(join17(projectDir, "expo"))) {
24533
24889
  return "mobile";
24534
24890
  }
24535
24891
  if (techStack.database.length > 0 && !techStack.framework) {
@@ -24546,10 +24902,10 @@ function extractDescription(projectDir) {
24546
24902
  return pkg.description;
24547
24903
  const readmePaths = ["README.md", "readme.md", "Readme.md"];
24548
24904
  for (const readme of readmePaths) {
24549
- const path = join16(projectDir, readme);
24550
- if (existsSync16(path)) {
24905
+ const path = join17(projectDir, readme);
24906
+ if (existsSync17(path)) {
24551
24907
  try {
24552
- const content = readFileSync14(path, "utf-8");
24908
+ const content = readFileSync15(path, "utf-8");
24553
24909
  const lines = content.split(`
24554
24910
  `);
24555
24911
  let foundTitle = false;
@@ -25967,9 +26323,9 @@ var onboardCommand = defineCommand2({
25967
26323
  },
25968
26324
  async run({ args }) {
25969
26325
  const projectPath = process.cwd();
25970
- const contextPath = join17(projectPath, ".nairon", "context.json");
25971
- if (existsSync17(contextPath) && !args.force) {
25972
- const existing = JSON.parse(readFileSync15(contextPath, "utf-8"));
26326
+ const contextPath = join18(projectPath, ".nairon", "context.json");
26327
+ if (existsSync18(contextPath) && !args.force) {
26328
+ const existing = JSON.parse(readFileSync16(contextPath, "utf-8"));
25973
26329
  consola.info("Project already onboarded. Use --force to re-run.");
25974
26330
  consola.info(`Business: ${existing.businessContext?.domain || existing.businessContext?.slice?.(0, 50) || "Not set"}...`);
25975
26331
  consola.info(`Stack: ${formatTechStackSummary(existing)}`);
@@ -26117,11 +26473,11 @@ var onboardCommand = defineCommand2({
26117
26473
  createdAt: new Date().toISOString(),
26118
26474
  updatedAt: new Date().toISOString()
26119
26475
  };
26120
- const naironDir = join17(projectPath, ".nairon");
26121
- if (!existsSync17(naironDir)) {
26122
- mkdirSync6(naironDir, { recursive: true });
26476
+ const naironDir = join18(projectPath, ".nairon");
26477
+ if (!existsSync18(naironDir)) {
26478
+ mkdirSync7(naironDir, { recursive: true });
26123
26479
  }
26124
- writeFileSync7(contextPath, JSON.stringify(fullContext, null, 2));
26480
+ writeFileSync8(contextPath, JSON.stringify(fullContext, null, 2));
26125
26481
  consola.success(`Saved to ${contextPath}`);
26126
26482
  if (isSupermemoryConfigured()) {
26127
26483
  consola.start("Storing in Supermemory...");
@@ -26209,51 +26565,51 @@ function formatTechStackSummary(context) {
26209
26565
  function detectInstalledTools(projectPath) {
26210
26566
  const tools = [];
26211
26567
  const home = process.env.HOME || "";
26212
- const userClaudeJson = join17(home, ".claude.json");
26213
- if (existsSync17(userClaudeJson)) {
26568
+ const userClaudeJson = join18(home, ".claude.json");
26569
+ if (existsSync18(userClaudeJson)) {
26214
26570
  try {
26215
- const config = JSON.parse(readFileSync15(userClaudeJson, "utf-8"));
26571
+ const config = JSON.parse(readFileSync16(userClaudeJson, "utf-8"));
26216
26572
  if (config.mcpServers) {
26217
26573
  tools.push(...Object.keys(config.mcpServers));
26218
26574
  }
26219
26575
  } catch {}
26220
26576
  }
26221
- const claudeDesktopConfig = join17(home, ".claude", "claude_desktop_config.json");
26222
- if (existsSync17(claudeDesktopConfig)) {
26577
+ const claudeDesktopConfig = join18(home, ".claude", "claude_desktop_config.json");
26578
+ if (existsSync18(claudeDesktopConfig)) {
26223
26579
  try {
26224
- const config = JSON.parse(readFileSync15(claudeDesktopConfig, "utf-8"));
26580
+ const config = JSON.parse(readFileSync16(claudeDesktopConfig, "utf-8"));
26225
26581
  if (config.mcpServers) {
26226
26582
  tools.push(...Object.keys(config.mcpServers));
26227
26583
  }
26228
26584
  } catch {}
26229
26585
  }
26230
- const projectMcpJson = join17(projectPath, ".mcp.json");
26231
- if (existsSync17(projectMcpJson)) {
26586
+ const projectMcpJson = join18(projectPath, ".mcp.json");
26587
+ if (existsSync18(projectMcpJson)) {
26232
26588
  try {
26233
- const config = JSON.parse(readFileSync15(projectMcpJson, "utf-8"));
26589
+ const config = JSON.parse(readFileSync16(projectMcpJson, "utf-8"));
26234
26590
  if (config.mcpServers) {
26235
26591
  tools.push(...Object.keys(config.mcpServers));
26236
26592
  }
26237
26593
  } catch {}
26238
26594
  }
26239
- const projectClaudeConfig = join17(projectPath, ".claude", "settings.json");
26240
- if (existsSync17(projectClaudeConfig)) {
26595
+ const projectClaudeConfig = join18(projectPath, ".claude", "settings.json");
26596
+ if (existsSync18(projectClaudeConfig)) {
26241
26597
  try {
26242
- const config = JSON.parse(readFileSync15(projectClaudeConfig, "utf-8"));
26598
+ const config = JSON.parse(readFileSync16(projectClaudeConfig, "utf-8"));
26243
26599
  if (config.mcpServers) {
26244
26600
  tools.push(...Object.keys(config.mcpServers));
26245
26601
  }
26246
26602
  } catch {}
26247
26603
  }
26248
- const skillsDir = join17(home, ".config", "opencode", "skills");
26249
- if (existsSync17(skillsDir)) {
26604
+ const skillsDir = join18(home, ".config", "opencode", "skills");
26605
+ if (existsSync18(skillsDir)) {
26250
26606
  try {
26251
26607
  const skills = readdirSync9(skillsDir);
26252
26608
  tools.push(...skills.filter((s2) => !s2.startsWith(".")));
26253
26609
  } catch {}
26254
26610
  }
26255
- const agentsSkillsDir = join17(home, ".agents", "skills");
26256
- if (existsSync17(agentsSkillsDir)) {
26611
+ const agentsSkillsDir = join18(home, ".agents", "skills");
26612
+ if (existsSync18(agentsSkillsDir)) {
26257
26613
  try {
26258
26614
  const skills = readdirSync9(agentsSkillsDir);
26259
26615
  tools.push(...skills.filter((s2) => !s2.startsWith(".")));
@@ -26263,11 +26619,11 @@ function detectInstalledTools(projectPath) {
26263
26619
  }
26264
26620
  function detectPrimaryAgent() {
26265
26621
  const home = process.env.HOME || "";
26266
- if (existsSync17(join17(home, ".claude")))
26622
+ if (existsSync18(join18(home, ".claude")))
26267
26623
  return "claude-code";
26268
- if (existsSync17(join17(home, ".cursor")))
26624
+ if (existsSync18(join18(home, ".cursor")))
26269
26625
  return "cursor";
26270
- if (existsSync17(join17(home, ".config", "opencode")))
26626
+ if (existsSync18(join18(home, ".config", "opencode")))
26271
26627
  return "opencode";
26272
26628
  return;
26273
26629
  }
@@ -26362,7 +26718,7 @@ function formatBytes(bytes) {
26362
26718
  // package.json
26363
26719
  var package_default2 = {
26364
26720
  name: "nairon-bench",
26365
- version: "0.5.0",
26721
+ version: "0.5.2",
26366
26722
  description: "AI workflow benchmarking CLI",
26367
26723
  type: "module",
26368
26724
  bin: {
@@ -26370,7 +26726,8 @@ var package_default2 = {
26370
26726
  nb: "./dist/index.js"
26371
26727
  },
26372
26728
  files: [
26373
- "dist"
26729
+ "dist",
26730
+ "postinstall.js"
26374
26731
  ],
26375
26732
  repository: {
26376
26733
  type: "git",
@@ -26398,7 +26755,8 @@ var package_default2 = {
26398
26755
  "test:e2e": "vitest run tests/e2e/",
26399
26756
  "test:watch": "vitest",
26400
26757
  clean: "rm -rf dist",
26401
- prepublishOnly: "bun run build"
26758
+ prepublishOnly: "bun run build",
26759
+ postinstall: "node postinstall.js || true"
26402
26760
  },
26403
26761
  dependencies: {
26404
26762
  "cli-boxes": "^4.0.1",
@@ -26463,7 +26821,7 @@ var hasVersion = args.includes("--version");
26463
26821
  if (!hasSubcommand && !hasHelp && !hasVersion && args.length === 0) {
26464
26822
  showBanner();
26465
26823
  } else {
26466
- const main = defineCommand({
26824
+ const cmd = defineCommand({
26467
26825
  meta: {
26468
26826
  name: "nairon-bench",
26469
26827
  version: VERSION2,
@@ -26481,5 +26839,5 @@ if (!hasSubcommand && !hasHelp && !hasVersion && args.length === 0) {
26481
26839
  cache: cacheCommand
26482
26840
  }
26483
26841
  });
26484
- runMain(main);
26842
+ runMain(cmd);
26485
26843
  }