nairon-bench 0.5.1 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +224 -65
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3661,10 +3661,10 @@ class ConvexHttpClient {
3661
3661
  }
3662
3662
  this.isProcessingQueue = true;
3663
3663
  while (this.mutationQueue.length > 0) {
3664
- const { mutation, args, resolve, reject } = this.mutationQueue.shift();
3664
+ const { mutation, args, resolve: resolve2, reject } = this.mutationQueue.shift();
3665
3665
  try {
3666
3666
  const result = await this.mutationInner(mutation, args);
3667
- resolve(result);
3667
+ resolve2(result);
3668
3668
  } catch (error) {
3669
3669
  reject(error);
3670
3670
  }
@@ -3672,8 +3672,8 @@ class ConvexHttpClient {
3672
3672
  this.isProcessingQueue = false;
3673
3673
  }
3674
3674
  enqueueMutation(mutation, args) {
3675
- return new Promise((resolve, reject) => {
3676
- this.mutationQueue.push({ mutation, args, resolve, reject });
3675
+ return new Promise((resolve2, reject) => {
3676
+ this.mutationQueue.push({ mutation, args, resolve: resolve2, reject });
3677
3677
  this.processMutationQueue();
3678
3678
  });
3679
3679
  }
@@ -8518,7 +8518,7 @@ async function collectGit(projectDir, since) {
8518
8518
  // src/collectors/agents.ts
8519
8519
  import { existsSync as existsSync2, readdirSync, readFileSync as readFileSync2 } from "node:fs";
8520
8520
  import { homedir as homedir2 } from "node:os";
8521
- import { join as join2, basename } from "node:path";
8521
+ import { join as join2, basename, resolve } from "node:path";
8522
8522
  // ../shared/src/constants.ts
8523
8523
  var PHASE_WEIGHTS = {
8524
8524
  requirements: 0.2,
@@ -8921,17 +8921,18 @@ function getCacheInfo() {
8921
8921
 
8922
8922
  // src/collectors/agents.ts
8923
8923
  var sessionCache = null;
8924
- async function collectAgentSessions(since, useCache = true) {
8924
+ async function collectAgentSessions(since, useCache = true, projectDir) {
8925
8925
  sessionCache = useCache ? new SessionCache : null;
8926
+ const targetProjectDir = projectDir ? resolve(projectDir) : process.cwd();
8926
8927
  const sessions = [];
8927
8928
  const claudeProjectsDir = join2(homedir2(), ".claude", "projects");
8928
8929
  if (existsSync2(claudeProjectsDir)) {
8929
- const claudeSessions = collectClaudeSessions(claudeProjectsDir, since);
8930
+ const claudeSessions = collectClaudeSessions(claudeProjectsDir, since, targetProjectDir);
8930
8931
  sessions.push(...claudeSessions);
8931
8932
  }
8932
8933
  const openCodeDir = join2(homedir2(), ".local", "share", "opencode");
8933
8934
  if (existsSync2(openCodeDir)) {
8934
- const openCodeSessions = collectOpenCodeSessions(openCodeDir, since);
8935
+ const openCodeSessions = collectOpenCodeSessions(openCodeDir, since, targetProjectDir);
8935
8936
  sessions.push(...openCodeSessions);
8936
8937
  }
8937
8938
  const cursorDirs = [
@@ -9011,11 +9012,29 @@ async function collectAgentSessions(since, useCache = true) {
9011
9012
  costByModel
9012
9013
  };
9013
9014
  }
9014
- function collectClaudeSessions(projectsDir, since) {
9015
+ function collectClaudeSessions(projectsDir, since, targetProjectDir) {
9015
9016
  const sessions = [];
9016
9017
  try {
9017
9018
  const projectDirs = readdirSync(projectsDir, { withFileTypes: true }).filter((d2) => d2.isDirectory()).map((d2) => join2(projectsDir, d2.name));
9019
+ let matchingProjectDir = null;
9018
9020
  for (const projectDir of projectDirs) {
9021
+ const projectMetaFile = join2(projectDir, ".project.json");
9022
+ if (existsSync2(projectMetaFile)) {
9023
+ try {
9024
+ const meta = JSON.parse(readFileSync2(projectMetaFile, "utf-8"));
9025
+ if (meta.directory) {
9026
+ const metaDir = resolve(meta.directory);
9027
+ const isMatch = metaDir === targetProjectDir || targetProjectDir.startsWith(metaDir + "/") || metaDir.startsWith(targetProjectDir + "/");
9028
+ if (isMatch) {
9029
+ matchingProjectDir = projectDir;
9030
+ break;
9031
+ }
9032
+ }
9033
+ } catch {}
9034
+ }
9035
+ }
9036
+ const dirsToScan = matchingProjectDir ? [matchingProjectDir] : projectDirs;
9037
+ for (const projectDir of dirsToScan) {
9019
9038
  const files = readdirSync(projectDir).filter((f3) => f3.endsWith(".jsonl")).map((f3) => join2(projectDir, f3));
9020
9039
  for (const file of files) {
9021
9040
  const session = parseClaudeSessionFile(file, since);
@@ -9289,7 +9308,7 @@ function similarity(a2, b2) {
9289
9308
  const union = new Set([...wordsA, ...wordsB]);
9290
9309
  return union.size > 0 ? intersection.size / union.size : 0;
9291
9310
  }
9292
- function collectOpenCodeSessions(baseDir, since) {
9311
+ function collectOpenCodeSessions(baseDir, since, targetProjectDir) {
9293
9312
  const sessions = [];
9294
9313
  const sessionStorageDir = join2(baseDir, "storage", "session");
9295
9314
  const messageStorageDir = join2(baseDir, "storage", "message");
@@ -9301,7 +9320,7 @@ function collectOpenCodeSessions(baseDir, since) {
9301
9320
  for (const projectDir of projectDirs) {
9302
9321
  const sessionFiles = readdirSync(projectDir).filter((f3) => f3.startsWith("ses_") && f3.endsWith(".json")).map((f3) => join2(projectDir, f3));
9303
9322
  for (const sessionFile of sessionFiles) {
9304
- const session = parseOpenCodeSession(sessionFile, messageStorageDir, partStorageDir, since);
9323
+ const session = parseOpenCodeSession(sessionFile, messageStorageDir, partStorageDir, since, targetProjectDir);
9305
9324
  if (session) {
9306
9325
  sessions.push(session);
9307
9326
  }
@@ -9310,7 +9329,7 @@ function collectOpenCodeSessions(baseDir, since) {
9310
9329
  } catch {}
9311
9330
  return sessions;
9312
9331
  }
9313
- function parseOpenCodeSession(sessionFile, messageStorageDir, partStorageDir, since) {
9332
+ function parseOpenCodeSession(sessionFile, messageStorageDir, partStorageDir, since, targetProjectDir) {
9314
9333
  try {
9315
9334
  const cached = sessionCache?.get(sessionFile);
9316
9335
  if (cached) {
@@ -9322,6 +9341,13 @@ function parseOpenCodeSession(sessionFile, messageStorageDir, partStorageDir, si
9322
9341
  }
9323
9342
  const sessionContent = readFileSync2(sessionFile, "utf-8");
9324
9343
  const session = JSON.parse(sessionContent);
9344
+ if (session.directory) {
9345
+ const sessionDir = resolve(session.directory);
9346
+ const isMatch = sessionDir === targetProjectDir || targetProjectDir.startsWith(sessionDir + "/") || sessionDir.startsWith(targetProjectDir + "/");
9347
+ if (!isMatch) {
9348
+ return null;
9349
+ }
9350
+ }
9325
9351
  const sessionStart = new Date(session.time.created);
9326
9352
  const sessionEnd = session.time.updated ? new Date(session.time.updated) : sessionStart;
9327
9353
  if (sessionEnd < since)
@@ -14763,7 +14789,7 @@ var icons = {
14763
14789
  brain: "\uD83E\uDDE0",
14764
14790
  target: "\uD83C\uDFAF"
14765
14791
  };
14766
- var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
14792
+ var sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
14767
14793
  function clearLine2() {
14768
14794
  readline.clearLine(process.stdout, 0);
14769
14795
  readline.cursorTo(process.stdout, 0);
@@ -15110,8 +15136,12 @@ function extractFrustrationPrompts(sessionPath, patterns) {
15110
15136
  }
15111
15137
  }
15112
15138
  } else if (sessionPath.endsWith(".json")) {
15113
- for (const _3 of patterns) {
15114
- prompts.push("");
15139
+ const sessionData = JSON.parse(content);
15140
+ const sessionId = sessionData.id;
15141
+ const userPrompts = extractOpenCodePrompts(sessionId);
15142
+ for (const pattern of patterns) {
15143
+ const frustrationMsg = findFrustrationMessage(userPrompts);
15144
+ prompts.push(frustrationMsg || userPrompts[0] || "");
15115
15145
  }
15116
15146
  }
15117
15147
  return prompts;
@@ -15119,6 +15149,45 @@ function extractFrustrationPrompts(sessionPath, patterns) {
15119
15149
  return [];
15120
15150
  }
15121
15151
  }
15152
+ function extractOpenCodePrompts(sessionId) {
15153
+ const home = homedir6();
15154
+ const messageDir = join7(home, ".local", "share", "opencode", "storage", "message", sessionId);
15155
+ const partBaseDir = join7(home, ".local", "share", "opencode", "storage", "part");
15156
+ if (!existsSync7(messageDir))
15157
+ return [];
15158
+ const prompts = [];
15159
+ try {
15160
+ const messageFiles = fsReaddirSync(messageDir).filter((f3) => f3.endsWith(".json")).sort();
15161
+ for (const msgFile of messageFiles) {
15162
+ try {
15163
+ const msgPath = join7(messageDir, msgFile);
15164
+ const msgData = JSON.parse(readFileSync7(msgPath, "utf-8"));
15165
+ if (msgData.role !== "user")
15166
+ continue;
15167
+ const messageId = msgData.id;
15168
+ const timestamp = msgData.time?.created;
15169
+ const partDir = join7(partBaseDir, messageId);
15170
+ if (!existsSync7(partDir))
15171
+ continue;
15172
+ const partFiles = fsReaddirSync(partDir).filter((f3) => f3.endsWith(".json"));
15173
+ let messageText = "";
15174
+ for (const partFile of partFiles) {
15175
+ try {
15176
+ const partData = JSON.parse(readFileSync7(join7(partDir, partFile), "utf-8"));
15177
+ if (partData.type === "text" && partData.text) {
15178
+ messageText += partData.text + " ";
15179
+ }
15180
+ } catch {}
15181
+ }
15182
+ if (messageText.trim()) {
15183
+ const timeStr = timestamp ? new Date(timestamp).toLocaleTimeString() : "";
15184
+ prompts.push(`[${timeStr}] ${messageText.trim()}`);
15185
+ }
15186
+ } catch {}
15187
+ }
15188
+ } catch {}
15189
+ return prompts;
15190
+ }
15122
15191
  function extractMessageText(msg) {
15123
15192
  if (typeof msg.content === "string")
15124
15193
  return msg.content;
@@ -15313,25 +15382,40 @@ function formatFrustrationSummary(summary) {
15313
15382
  }
15314
15383
  function formatFrustrationEvent(f3, index) {
15315
15384
  const lines = [];
15316
- lines.push(` ${colors2.warning(`${index}.`)} ${colors2.bold(f3.patternDescription)} ${colors2.dim(`(${f3.agent})`)}`);
15317
- lines.push(` ${colors2.dim("Session:")} ${f3.sessionId.slice(0, 12)}...`);
15318
- lines.push(` ${colors2.dim("Time wasted:")} ~${f3.estimatedTimeWastedMinutes} min`);
15319
- lines.push(` ${colors2.dim("Cause:")} ${formatCauseLabel(f3.rootCause.category)}`);
15385
+ lines.push(` ${colors2.error(`${index}.`)} ${formatCauseLabel(f3.rootCause.category)}`);
15386
+ lines.push(` ${colors2.dim("Session:")} ${f3.sessionId.slice(0, 16)}... ${colors2.dim(`(${f3.agent})`)}`);
15387
+ if (f3.timestamp) {
15388
+ const date = new Date(f3.timestamp);
15389
+ lines.push(` ${colors2.dim("When:")} ${date.toLocaleDateString()} ${date.toLocaleTimeString()}`);
15390
+ }
15391
+ lines.push(` ${colors2.dim("Time wasted:")} ${colors2.warning(`~${f3.estimatedTimeWastedMinutes} min`)}`);
15320
15392
  if (f3.exactPrompt && f3.exactPrompt.length > 0 && !f3.exactPrompt.startsWith("(Unable")) {
15321
15393
  lines.push("");
15322
- lines.push(` ${colors2.dim("┌" + "─".repeat(40))}`);
15323
- const promptLines = wrapText(f3.exactPrompt, 38);
15324
- for (const line of promptLines.slice(0, 4)) {
15325
- lines.push(` ${colors2.dim("")} ${line}`);
15394
+ lines.push(` ${colors2.bold("Your prompt:")}`);
15395
+ lines.push(` ${colors2.dim("┌" + "─".repeat(50))}`);
15396
+ let promptText = f3.exactPrompt;
15397
+ if (promptText.startsWith("[")) {
15398
+ const closeBracket = promptText.indexOf("]");
15399
+ if (closeBracket > 0 && closeBracket < 15) {
15400
+ promptText = promptText.slice(closeBracket + 2);
15401
+ }
15402
+ }
15403
+ const promptLines = wrapText(promptText, 48);
15404
+ for (const line of promptLines.slice(0, 6)) {
15405
+ lines.push(` ${colors2.dim("│")} ${colors2.primary(line)}`);
15326
15406
  }
15327
- if (promptLines.length > 4) {
15328
- lines.push(` ${colors2.dim("│")} ${colors2.dim("...")}`);
15407
+ if (promptLines.length > 6) {
15408
+ lines.push(` ${colors2.dim("│")} ${colors2.dim(`... (${promptLines.length - 6} more lines)`)}`);
15329
15409
  }
15330
- lines.push(` ${colors2.dim("└" + "─".repeat(40))}`);
15410
+ lines.push(` ${colors2.dim("└" + "─".repeat(50))}`);
15411
+ } else {
15412
+ lines.push("");
15413
+ lines.push(` ${colors2.dim("(Prompt not captured - " + f3.patternDescription + ")")}`);
15331
15414
  }
15332
15415
  lines.push("");
15333
- lines.push(` ${colors2.success("Fix:")} ${f3.recommendedFix.tool}`);
15334
- lines.push(` ${colors2.dim("$")} ${colors2.primary(f3.recommendedFix.installCommand)}`);
15416
+ lines.push(` ${colors2.success("Fix with:")} ${colors2.bold(f3.recommendedFix.tool)}`);
15417
+ lines.push(` ${colors2.dim(f3.recommendedFix.description)}`);
15418
+ lines.push(` ${colors2.dim("$")} ${colors2.primary(f3.recommendedFix.installCommand)}`);
15335
15419
  return lines;
15336
15420
  }
15337
15421
  function formatCauseLabel(cause) {
@@ -16086,22 +16170,62 @@ function markProjectScanned(projectDir) {
16086
16170
  }
16087
16171
  writeFileSync4(join9(projectDir, PROJECT_SCAN_MARKER), new Date().toISOString());
16088
16172
  }
16089
- function detectAgent() {
16173
+ var AGENT_CONFIGS = [
16174
+ {
16175
+ id: "claude-code",
16176
+ name: "Claude Code",
16177
+ paths: [".claude"]
16178
+ },
16179
+ {
16180
+ id: "opencode",
16181
+ name: "OpenCode",
16182
+ paths: [".config/opencode", ".local/share/opencode", ".opencode"]
16183
+ },
16184
+ {
16185
+ id: "cursor",
16186
+ name: "Cursor",
16187
+ paths: [".cursor"]
16188
+ },
16189
+ {
16190
+ id: "codex",
16191
+ name: "Codex CLI",
16192
+ paths: [".codex"]
16193
+ },
16194
+ {
16195
+ id: "copilot",
16196
+ name: "GitHub Copilot",
16197
+ paths: [".github-copilot"]
16198
+ },
16199
+ {
16200
+ id: "cody",
16201
+ name: "Sourcegraph Cody",
16202
+ paths: [".cody"]
16203
+ },
16204
+ {
16205
+ id: "aider",
16206
+ name: "Aider",
16207
+ paths: [".aider"]
16208
+ }
16209
+ ];
16210
+ function detectAllAgents() {
16090
16211
  const home = homedir8();
16091
- const claudeConfig = join9(home, ".claude");
16092
- const hasClaudeCode = existsSync9(claudeConfig);
16093
- const opencodeConfig = join9(home, ".config", "opencode");
16094
- const opencodeData = join9(home, ".local", "share", "opencode");
16095
- const hasOpenCode = existsSync9(opencodeConfig) || existsSync9(opencodeData);
16096
- const cursorConfig = join9(home, ".cursor");
16097
- const hasCursor = existsSync9(cursorConfig);
16098
- if (hasClaudeCode)
16099
- return "claude-code";
16100
- if (hasOpenCode)
16101
- return "opencode";
16102
- if (hasCursor)
16103
- return "cursor";
16104
- return "unknown";
16212
+ const cwd = process.cwd();
16213
+ const detected = [];
16214
+ for (const agent of AGENT_CONFIGS) {
16215
+ for (const relativePath of agent.paths) {
16216
+ const homePath = join9(home, relativePath);
16217
+ if (existsSync9(homePath)) {
16218
+ detected.push({ id: agent.id, name: agent.name, configPath: homePath });
16219
+ break;
16220
+ }
16221
+ const projectPath = join9(cwd, relativePath);
16222
+ if (existsSync9(projectPath)) {
16223
+ detected.push({ id: agent.id, name: agent.name, configPath: projectPath });
16224
+ break;
16225
+ }
16226
+ }
16227
+ }
16228
+ return detected;
16105
16229
  }
16106
16230
  function analyzeReadme(projectDir) {
16107
16231
  const readmePath = join9(projectDir, "README.md");
@@ -16336,7 +16460,7 @@ var scanCommand = defineCommand2({
16336
16460
  const timestamp = new Date().toLocaleTimeString();
16337
16461
  try {
16338
16462
  const git2 = await collectGit(projectDir, since);
16339
- const agents2 = await collectAgentSessions(since, useCache);
16463
+ const agents2 = await collectAgentSessions(since, useCache, projectDir);
16340
16464
  const tests2 = await collectTestResults(projectDir);
16341
16465
  const score2 = computeNaironScore(git2 ?? undefined, agents2 ?? undefined, tests2 ?? undefined);
16342
16466
  const delta = scanCount > 1 ? score2.overall - lastScore : 0;
@@ -16381,7 +16505,7 @@ var scanCommand = defineCommand2({
16381
16505
  }
16382
16506
  if (!silent)
16383
16507
  await thinkingStep("Scanning AI session logs...", 600);
16384
- const agents = await collectAgentSessions(since, useCache);
16508
+ const agents = await collectAgentSessions(since, useCache, projectDir);
16385
16509
  if (agents && !silent) {
16386
16510
  await revealDiscovery(icons.success, `Sessions: ${colors2.primary(agents.totalSessions.toString())} sessions loaded`, 200);
16387
16511
  }
@@ -16874,14 +16998,28 @@ async function showFirstScanWelcome(projectDir) {
16874
16998
  console.log(` ${colors2.primary("✨")} ${colors2.bold("First scan in this project!")}`);
16875
16999
  console.log(colors2.dim(" " + "═".repeat(50)));
16876
17000
  console.log();
16877
- const agent = detectAgent();
16878
- const agentNames = {
16879
- "claude-code": "Claude Code",
16880
- opencode: "OpenCode",
16881
- cursor: "Cursor",
16882
- unknown: "Unknown"
16883
- };
16884
- console.log(` ${icons.info} Detected agent: ${colors2.bold(agentNames[agent])}`);
17001
+ const detectedAgents = detectAllAgents();
17002
+ let selectedAgent = null;
17003
+ if (detectedAgents.length === 0) {
17004
+ console.log(` ${icons.info} No AI coding agents detected`);
17005
+ console.log(` ${colors2.dim(" Install Claude Code, Cursor, or OpenCode to get started")}`);
17006
+ } else if (detectedAgents.length === 1) {
17007
+ selectedAgent = detectedAgents[0];
17008
+ console.log(` ${icons.info} Detected agent: ${colors2.bold(selectedAgent.name)}`);
17009
+ } else {
17010
+ console.log(` ${icons.info} Found ${colors2.bold(detectedAgents.length.toString())} AI coding agents:`);
17011
+ console.log();
17012
+ const agentChoice = await consola.prompt("Which agent are you using for this project?", {
17013
+ type: "select",
17014
+ options: detectedAgents.map((a2) => ({
17015
+ value: a2.id,
17016
+ label: a2.name
17017
+ }))
17018
+ });
17019
+ selectedAgent = detectedAgents.find((a2) => a2.id === agentChoice) || detectedAgents[0];
17020
+ console.log();
17021
+ console.log(` ${icons.success} Selected: ${colors2.bold(selectedAgent.name)}`);
17022
+ }
16885
17023
  const context = analyzeReadme(projectDir);
16886
17024
  if (context) {
16887
17025
  console.log(` ${icons.info} Project: ${colors2.bold(context.name)}`);
@@ -21834,7 +21972,7 @@ function formatReportAsJSON(report) {
21834
21972
 
21835
21973
  // src/commands/report.ts
21836
21974
  import { writeFileSync as writeFileSync6 } from "node:fs";
21837
- import { resolve } from "node:path";
21975
+ import { resolve as resolve2 } from "node:path";
21838
21976
  var reportCommand = defineCommand2({
21839
21977
  meta: {
21840
21978
  name: "report",
@@ -22044,7 +22182,7 @@ async function runHackathonReport(args) {
22044
22182
  break;
22045
22183
  }
22046
22184
  if (args.output) {
22047
- const filepath = resolve(projectDir, args.output);
22185
+ const filepath = resolve2(projectDir, args.output);
22048
22186
  writeFileSync6(filepath, output);
22049
22187
  consola.success(`Report saved to ${filepath}`);
22050
22188
  }
@@ -22196,7 +22334,7 @@ async function runLeadershipReport(args) {
22196
22334
  const since = parseSince2(args.since || "7d");
22197
22335
  const periodLabel = args.since === "30d" ? "Last 30 days" : args.since === "48h" ? "Last 48 hours" : "Last 7 days";
22198
22336
  consola.start(`Generating leadership report (${periodLabel})...`);
22199
- const agents = await collectAgentSessions(since);
22337
+ const agents = await collectAgentSessions(since, true, projectDir);
22200
22338
  if (!agents || agents.sessions.length === 0) {
22201
22339
  consola.warn("No AI sessions found in the specified time range.");
22202
22340
  consola.info("Try running with --since 30d for a longer time range.");
@@ -22213,7 +22351,7 @@ async function runLeadershipReport(args) {
22213
22351
  `);
22214
22352
  }
22215
22353
  if (args.output) {
22216
- const filepath = resolve(projectDir, args.output);
22354
+ const filepath = resolve2(projectDir, args.output);
22217
22355
  writeFileSync6(filepath, output);
22218
22356
  consola.success(`Report saved to ${filepath}`);
22219
22357
  }
@@ -23218,10 +23356,10 @@ async function prompt2(question) {
23218
23356
  input: process.stdin,
23219
23357
  output: process.stdout
23220
23358
  });
23221
- return new Promise((resolve2) => {
23359
+ return new Promise((resolve3) => {
23222
23360
  rl.question(question, (answer) => {
23223
23361
  rl.close();
23224
- resolve2(answer.trim());
23362
+ resolve3(answer.trim());
23225
23363
  });
23226
23364
  });
23227
23365
  }
@@ -23666,6 +23804,27 @@ var BOLD = "\x1B[1m";
23666
23804
  var RESET = "\x1B[0m";
23667
23805
  var MAGENTA = "\x1B[35m";
23668
23806
  var CHANGELOG = [
23807
+ {
23808
+ version: "0.5.3",
23809
+ date: "2026-02-14",
23810
+ title: "Project-Scoped Analysis",
23811
+ highlights: [
23812
+ "CRITICAL FIX: Sessions now filtered to current project only",
23813
+ "No more mixing data from different projects in reports",
23814
+ "Improved frustration display with exact prompts and timestamps",
23815
+ "Better OpenCode prompt extraction for frustration analysis"
23816
+ ]
23817
+ },
23818
+ {
23819
+ version: "0.5.2",
23820
+ date: "2026-02-14",
23821
+ title: "Multi-Agent Detection",
23822
+ highlights: [
23823
+ "Detects ALL installed AI agents (Claude Code, Cursor, OpenCode, Codex, etc.)",
23824
+ "Choose which agent you're using if multiple are found",
23825
+ "Expanded agent support: Copilot, Cody, Aider"
23826
+ ]
23827
+ },
23669
23828
  {
23670
23829
  version: "0.5.1",
23671
23830
  date: "2026-02-14",
@@ -24127,7 +24286,7 @@ function showFullChangelog() {
24127
24286
  // package.json
24128
24287
  var package_default = {
24129
24288
  name: "nairon-bench",
24130
- version: "0.5.1",
24289
+ version: "0.5.3",
24131
24290
  description: "AI workflow benchmarking CLI",
24132
24291
  type: "module",
24133
24292
  bin: {
@@ -24316,7 +24475,7 @@ async function fetchGitHubUser(accessToken) {
24316
24475
  return await response.json();
24317
24476
  }
24318
24477
  function sleep2(ms) {
24319
- return new Promise((resolve2) => setTimeout(resolve2, ms));
24478
+ return new Promise((resolve3) => setTimeout(resolve3, ms));
24320
24479
  }
24321
24480
 
24322
24481
  // src/commands/init.ts
@@ -25105,7 +25264,7 @@ var safeJSON = (text) => {
25105
25264
  };
25106
25265
 
25107
25266
  // ../../node_modules/supermemory/internal/utils/sleep.mjs
25108
- var sleep3 = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
25267
+ var sleep3 = (ms) => new Promise((resolve3) => setTimeout(resolve3, ms));
25109
25268
 
25110
25269
  // ../../node_modules/supermemory/version.mjs
25111
25270
  var VERSION = "4.11.1";
@@ -25747,8 +25906,8 @@ var _APIPromise_client;
25747
25906
 
25748
25907
  class APIPromise extends Promise {
25749
25908
  constructor(client, responsePromise, parseResponse = defaultParseResponse) {
25750
- super((resolve2) => {
25751
- resolve2(null);
25909
+ super((resolve3) => {
25910
+ resolve3(null);
25752
25911
  });
25753
25912
  this.responsePromise = responsePromise;
25754
25913
  this.parseResponse = parseResponse;
@@ -26654,7 +26813,7 @@ function formatBytes(bytes) {
26654
26813
  // package.json
26655
26814
  var package_default2 = {
26656
26815
  name: "nairon-bench",
26657
- version: "0.5.1",
26816
+ version: "0.5.3",
26658
26817
  description: "AI workflow benchmarking CLI",
26659
26818
  type: "module",
26660
26819
  bin: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nairon-bench",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
4
4
  "description": "AI workflow benchmarking CLI",
5
5
  "type": "module",
6
6
  "bin": {