nairon-bench 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +238 -407
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -16067,159 +16067,52 @@ function filterAlreadyInstalled(optimizations, status) {
16067
16067
  return true;
16068
16068
  });
16069
16069
  }
16070
- var QUICK_INSTALL_PRESETS = {
16071
- essential: [
16072
- {
16073
- id: "context7",
16074
- name: "Context7 MCP",
16075
- type: "mcp",
16076
- description: "Up-to-date library documentation",
16077
- installCommand: "claude mcp add context7 https://mcp.context7.com/mcp --transport http",
16078
- selected: true
16079
- },
16080
- {
16081
- id: "supermemory",
16082
- name: "Supermemory MCP",
16083
- type: "mcp",
16084
- description: "Persistent memory across sessions",
16085
- installCommand: "claude mcp add supermemory -- npx -y @supermemory/mcp@latest",
16086
- selected: true
16087
- },
16088
- {
16089
- id: "beads",
16090
- name: "Beads Task Manager",
16091
- type: "mcp",
16092
- description: "Persistent task tracking",
16093
- installCommand: "bun add -g beads && bd init",
16094
- selected: true
16095
- }
16096
- ],
16097
- productivity: [
16098
- {
16099
- id: "claude-md",
16100
- name: "CLAUDE.md",
16101
- type: "config",
16102
- description: "Project context file",
16103
- configPath: "CLAUDE.md",
16104
- configContent: `# Project Instructions
16105
-
16106
- ## Build & Test Commands
16107
- \`\`\`bash
16108
- bun test # Run tests
16109
- bun run build # Build project
16110
- bun run lint # Run linter
16111
- \`\`\`
16112
-
16113
- ## Architecture
16114
- Describe your project structure here.
16115
-
16116
- ## Conventions
16117
- - Use TypeScript
16118
- - Write tests for new features
16119
- - Use conventional commits
16120
- `,
16121
- selected: true
16122
- },
16123
- {
16124
- id: "vitest",
16125
- name: "Vitest",
16126
- type: "library",
16127
- description: "Fast unit testing framework",
16128
- installCommand: "bun add -D vitest",
16129
- selected: true
16130
- }
16131
- ]
16132
- };
16133
16070
 
16134
16071
  // src/commands/scan.ts
16135
16072
  var scanCommand = defineCommand2({
16136
16073
  meta: {
16137
16074
  name: "scan",
16138
- description: "Analyze local data sources (git, AI sessions, tests) and compute your NaironAI score"
16075
+ description: "Scan your AI workflow and get optimization recommendations (interactive)"
16139
16076
  },
16140
16077
  args: {
16141
- since: {
16142
- type: "string",
16143
- description: 'Time range: 6h, 24h, 7d, 30d, or "7 days"',
16144
- default: "7d"
16145
- },
16146
- project: {
16147
- type: "string",
16148
- description: "Project directory to scan (defaults to cwd)"
16149
- },
16150
- install: {
16151
- type: "boolean",
16152
- alias: "i",
16153
- description: "Install recommended optimizations (interactive)",
16154
- default: false
16155
- },
16156
- "install-all": {
16157
- type: "boolean",
16158
- description: "Install all recommended optimizations (non-interactive)",
16159
- default: false
16160
- },
16161
- "install-essentials": {
16162
- type: "boolean",
16163
- description: "Install essential tools: Context7, Supermemory, Beads",
16164
- default: false
16165
- },
16166
- offline: {
16167
- type: "boolean",
16168
- description: "Skip uploading results to Convex",
16169
- default: false
16170
- },
16171
- "no-report": {
16172
- type: "boolean",
16173
- description: "Skip generating markdown report",
16174
- default: false
16175
- },
16176
- "report-dir": {
16177
- type: "string",
16178
- description: "Directory for reports (defaults to .nairon/reports)",
16179
- default: ".nairon/reports"
16180
- },
16181
- brief: {
16182
- type: "boolean",
16183
- description: "Show brief output (skip detailed analysis)",
16184
- default: false
16185
- },
16186
16078
  json: {
16187
16079
  type: "boolean",
16188
- description: "Output results as JSON (for CI/scripts)",
16080
+ description: "Output as JSON (for CI/scripts)",
16189
16081
  default: false
16190
16082
  },
16191
16083
  quiet: {
16192
16084
  type: "boolean",
16193
16085
  alias: "q",
16194
- description: "Quiet mode - only output the score number",
16195
- default: false
16196
- },
16197
- "no-cache": {
16198
- type: "boolean",
16199
- description: "Disable session caching (slower but ensures fresh data)",
16200
- default: false
16201
- },
16202
- watch: {
16203
- type: "boolean",
16204
- alias: "w",
16205
- description: "Watch mode - re-scan on file changes",
16086
+ description: "Only output score number",
16206
16087
  default: false
16207
- },
16208
- "watch-interval": {
16209
- type: "string",
16210
- description: "Watch interval in seconds (default: 30)",
16211
- default: "30"
16212
16088
  }
16213
16089
  },
16214
16090
  async run({ args }) {
16215
- const projectDir = args.project ?? process.cwd();
16216
- const since = parseSince(args.since);
16091
+ const projectDir = process.cwd();
16217
16092
  const jsonOutput = args.json;
16218
16093
  const quietMode = args.quiet;
16219
- const useCache = !args["no-cache"];
16220
- const watchMode = args.watch;
16221
- const watchInterval = parseInt(args["watch-interval"] || "30", 10) * 1000;
16222
16094
  const silent = jsonOutput || quietMode;
16095
+ let since;
16096
+ if (silent) {
16097
+ since = parseSince("7d");
16098
+ } else {
16099
+ console.log();
16100
+ console.log(" \uD83D\uDD0D " + "\x1B[1mNaironAI Workflow Scanner\x1B[0m");
16101
+ console.log(" " + "\x1B[2m" + "─".repeat(35) + "\x1B[0m");
16102
+ console.log();
16103
+ const period = await consola.prompt("Time period to analyze?", {
16104
+ type: "select",
16105
+ options: [
16106
+ { value: "7d", label: "Last 7 days (recommended)" },
16107
+ { value: "24h", label: "Last 24 hours" },
16108
+ { value: "30d", label: "Last 30 days" }
16109
+ ]
16110
+ });
16111
+ since = parseSince(period);
16112
+ }
16113
+ const useCache = true;
16114
+ const watchMode = false;
16115
+ const watchInterval = 30000;
16223
16116
  if (watchMode) {
16224
16117
  console.log();
16225
16118
  console.log(colors2.bold(colors2.primary(" NaironAI Watch Mode")));
@@ -16352,19 +16245,17 @@ var scanCommand = defineCommand2({
16352
16245
  console.log(` Projected monthly: ${colors2.primary(`$${scanCost.projectedMonthlyCostUsd.toFixed(2)}`)}`);
16353
16246
  console.log(colors2.dim(" " + "═".repeat(45)));
16354
16247
  console.log();
16355
- if (!args["no-report"]) {
16356
- const reportDir = join9(projectDir, args["report-dir"]);
16357
- const reportPath = generateReport(reportDir, score, git, agents, tests, args.since, sdlcAnalysis, scanCost, analysis);
16358
- console.log(` ${icons.success} Report saved: ${colors2.dim(reportPath)}`);
16359
- }
16360
- if (agents && agents.sessions.length > 0 && !args.brief) {
16248
+ const reportDir = join9(projectDir, ".nairon/reports");
16249
+ const reportPath = generateReport(reportDir, score, git, agents, tests, "7d", sdlcAnalysis, scanCost, analysis);
16250
+ console.log(` ${icons.success} Report saved: ${colors2.dim(reportPath)}`);
16251
+ if (agents && agents.sessions.length > 0) {
16361
16252
  const effortBreakdown = analyzeEffort(agents.sessions, git);
16362
16253
  const effortLines = formatEffortBreakdown(effortBreakdown);
16363
16254
  for (const line of effortLines) {
16364
16255
  console.log(line);
16365
16256
  }
16366
16257
  }
16367
- if (agents && agents.sessions.length > 0 && !args.brief) {
16258
+ if (agents && agents.sessions.length > 0) {
16368
16259
  const frustrationSummary = detectFrustrations(agents.sessions);
16369
16260
  if (frustrationSummary.totalFrustrations > 0) {
16370
16261
  const frustrationLines = formatFrustrationSummary(frustrationSummary);
@@ -16373,68 +16264,71 @@ var scanCommand = defineCommand2({
16373
16264
  }
16374
16265
  }
16375
16266
  }
16376
- if (!args.brief) {
16377
- const installedStatus = checkInstalledStatus(projectDir);
16378
- const projectContext = loadProjectContext(projectDir);
16379
- if (projectContext) {
16380
- console.log(` ${colors2.dim("Using project context from onboarding for personalized recommendations")}`);
16381
- }
16382
- const sdlc = analyzeSDLC(agents, git, tests, projectDir, analysis, projectContext);
16383
- for (const phase of [sdlc.requirements, sdlc.planning, sdlc.implementation, sdlc.review]) {
16384
- phase.recommendations = phase.recommendations.filter((rec) => {
16385
- const id = rec.title.toLowerCase().replace(/\s+/g, "-");
16386
- if (id.includes("context7") && installedStatus.context7)
16387
- return false;
16388
- if (id.includes("supermemory") && installedStatus.supermemory)
16389
- return false;
16390
- if (id.includes("nia") && installedStatus.nia)
16391
- return false;
16392
- if (id.includes("beads") && installedStatus.beads)
16393
- return false;
16394
- return true;
16395
- });
16396
- for (const tool of phase.tools) {
16397
- if (tool.name.toLowerCase().includes("context7") && installedStatus.context7) {
16398
- tool.installed = true;
16399
- }
16400
- if (tool.name.toLowerCase().includes("supermemory") && installedStatus.supermemory) {
16401
- tool.installed = true;
16402
- }
16403
- if (tool.name.toLowerCase().includes("nia") && installedStatus.nia) {
16404
- tool.installed = true;
16405
- }
16267
+ const installedStatus = checkInstalledStatus(projectDir);
16268
+ const projectContext = loadProjectContext(projectDir);
16269
+ if (projectContext) {
16270
+ console.log(` ${colors2.dim("Using project context from onboarding for personalized recommendations")}`);
16271
+ }
16272
+ const sdlc = analyzeSDLC(agents, git, tests, projectDir, analysis, projectContext);
16273
+ for (const phase of [sdlc.requirements, sdlc.planning, sdlc.implementation, sdlc.review]) {
16274
+ phase.recommendations = phase.recommendations.filter((rec) => {
16275
+ const id = rec.title.toLowerCase().replace(/\s+/g, "-");
16276
+ if (id.includes("context7") && installedStatus.context7)
16277
+ return false;
16278
+ if (id.includes("supermemory") && installedStatus.supermemory)
16279
+ return false;
16280
+ if (id.includes("nia") && installedStatus.nia)
16281
+ return false;
16282
+ if (id.includes("beads") && installedStatus.beads)
16283
+ return false;
16284
+ return true;
16285
+ });
16286
+ for (const tool of phase.tools) {
16287
+ if (tool.name.toLowerCase().includes("context7") && installedStatus.context7) {
16288
+ tool.installed = true;
16289
+ }
16290
+ if (tool.name.toLowerCase().includes("supermemory") && installedStatus.supermemory) {
16291
+ tool.installed = true;
16292
+ }
16293
+ if (tool.name.toLowerCase().includes("nia") && installedStatus.nia) {
16294
+ tool.installed = true;
16406
16295
  }
16407
16296
  }
16408
- const totalRecs = [sdlc.requirements, sdlc.planning, sdlc.implementation, sdlc.review].reduce((a2, p) => a2 + p.recommendations.length, 0);
16409
- if (totalRecs > 0) {
16410
- sdlc.overall.summary = sdlc.overall.summary.replace(/\d+ optimizations available\./, `${totalRecs} optimizations available.`);
16411
- } else if (sdlc.overall.summary.includes("optimizations available")) {
16412
- sdlc.overall.summary = sdlc.overall.summary.replace(/\d+ optimizations available\./, "All recommended tools installed.");
16413
- }
16414
- const sdlcLines = formatSDLCForTerminal(sdlc);
16415
- for (const line of sdlcLines) {
16416
- console.log(line);
16417
- }
16418
- let allRecs = [];
16419
- for (const phase of [sdlc.requirements, sdlc.planning, sdlc.implementation, sdlc.review]) {
16420
- for (const rec of phase.recommendations) {
16421
- if (rec.installCommand) {
16422
- allRecs.push(phaseRecToInstallable(rec));
16423
- }
16297
+ }
16298
+ const totalRecs = [sdlc.requirements, sdlc.planning, sdlc.implementation, sdlc.review].reduce((a2, p) => a2 + p.recommendations.length, 0);
16299
+ if (totalRecs > 0) {
16300
+ sdlc.overall.summary = sdlc.overall.summary.replace(/\d+ optimizations available\./, `${totalRecs} optimizations available.`);
16301
+ } else if (sdlc.overall.summary.includes("optimizations available")) {
16302
+ sdlc.overall.summary = sdlc.overall.summary.replace(/\d+ optimizations available\./, "All recommended tools installed.");
16303
+ }
16304
+ const sdlcLines = formatSDLCForTerminal(sdlc);
16305
+ for (const line of sdlcLines) {
16306
+ console.log(line);
16307
+ }
16308
+ let allRecs = [];
16309
+ for (const phase of [sdlc.requirements, sdlc.planning, sdlc.implementation, sdlc.review]) {
16310
+ for (const rec of phase.recommendations) {
16311
+ if (rec.installCommand) {
16312
+ allRecs.push(phaseRecToInstallable(rec));
16424
16313
  }
16425
16314
  }
16426
- allRecs = filterAlreadyInstalled(allRecs, installedStatus);
16427
- if (args["install-essentials"]) {
16428
- console.log();
16429
- console.log(` ${colors2.bold(colors2.primary("Installing Essential Tools"))}`);
16430
- console.log(colors2.dim(" " + "─".repeat(40)));
16431
- console.log();
16432
- const essentials = filterAlreadyInstalled(QUICK_INSTALL_PRESETS.essential, installedStatus);
16433
- if (essentials.length === 0) {
16434
- console.log(` ${colors2.success("✓")} All essential tools already installed!`);
16315
+ }
16316
+ allRecs = filterAlreadyInstalled(allRecs, installedStatus);
16317
+ if (allRecs.length > 0) {
16318
+ console.log();
16319
+ const optionLabels = allRecs.map((rec) => `${rec.name} - ${rec.description}`);
16320
+ const selected = await consola.prompt(`${allRecs.length} optimizations available. Select to install (space to select, enter to confirm):`, {
16321
+ type: "multiselect",
16322
+ options: optionLabels,
16323
+ required: false
16324
+ });
16325
+ if (selected && typeof selected !== "symbol" && Array.isArray(selected) && selected.length > 0) {
16326
+ const toInstall = allRecs.filter((rec) => selected.some((s2) => s2.startsWith(rec.name))).map((r3) => ({ ...r3, selected: true }));
16327
+ if (toInstall.length > 0) {
16435
16328
  console.log();
16436
- } else {
16437
- const results = await installOptimizations(essentials.map((e2) => ({ ...e2, selected: true })), projectDir, {});
16329
+ console.log(` ${colors2.bold("Installing...")}${colors2.dim("")}`);
16330
+ console.log();
16331
+ const results = await installOptimizations(toInstall, projectDir, {});
16438
16332
  for (const result of results) {
16439
16333
  if (result.success) {
16440
16334
  console.log(` ${colors2.success("✓")} ${result.name}: ${result.message}`);
@@ -16444,82 +16338,15 @@ var scanCommand = defineCommand2({
16444
16338
  }
16445
16339
  console.log();
16446
16340
  }
16447
- } else if (args["install-all"] && allRecs.length > 0) {
16448
- console.log();
16449
- console.log(` ${colors2.bold(colors2.primary("Installing All Optimizations"))}`);
16450
- console.log(colors2.dim(" " + "─".repeat(40)));
16451
- console.log();
16452
- const results = await installOptimizations(allRecs.map((r3) => ({ ...r3, selected: true })), projectDir, {});
16453
- for (const result of results) {
16454
- if (result.success) {
16455
- console.log(` ${colors2.success("✓")} ${result.name}: ${result.message}`);
16456
- } else {
16457
- console.log(` ${colors2.error("✗")} ${result.name}: ${result.error || result.message}`);
16458
- }
16459
- }
16460
- console.log();
16461
- } else if (allRecs.length > 0 && !args["install-essentials"] && !args["install-all"]) {
16341
+ } else {
16342
+ console.log(` ${colors2.dim("Skipped.")}`);
16462
16343
  console.log();
16463
- const optionLabels = allRecs.map((rec) => `${rec.name} - ${rec.description}`);
16464
- const selected = await consola.prompt(`${allRecs.length} optimizations available. Select to install (space to select, enter to confirm):`, {
16465
- type: "multiselect",
16466
- options: optionLabels,
16467
- required: false
16468
- });
16469
- if (selected && typeof selected !== "symbol" && Array.isArray(selected) && selected.length > 0) {
16470
- const toInstall = allRecs.filter((rec) => selected.some((s2) => s2.startsWith(rec.name))).map((r3) => ({ ...r3, selected: true }));
16471
- if (toInstall.length > 0) {
16472
- console.log();
16473
- console.log(` ${colors2.bold("Installing...")}${colors2.dim("")}`);
16474
- console.log();
16475
- const results = await installOptimizations(toInstall, projectDir, {});
16476
- for (const result of results) {
16477
- if (result.success) {
16478
- console.log(` ${colors2.success("✓")} ${result.name}: ${result.message}`);
16479
- } else {
16480
- console.log(` ${colors2.error("✗")} ${result.name}: ${result.error || result.message}`);
16481
- }
16482
- }
16483
- console.log();
16484
- }
16485
- } else {
16486
- console.log(` ${colors2.dim("Skipped. Run")} ${colors2.primary("nb scan --install-essentials")} ${colors2.dim("anytime to quick-install.")}`);
16487
- console.log();
16488
- }
16489
16344
  }
16490
16345
  }
16491
16346
  }
16492
- if (args.offline) {
16493
- if (!silent) {
16494
- console.log(` ${icons.info} Offline mode - skipping cloud sync`);
16495
- console.log();
16496
- }
16497
- if (jsonOutput) {
16498
- const output = {
16499
- score: score.overall,
16500
- tier: score.tier,
16501
- baseScore: score.baseScore,
16502
- tokenEfficiency: score.tokenEfficiency,
16503
- phases: score.phases,
16504
- cost: scanCost,
16505
- git: git ? { commitCount: git.commitCount, authors: git.authors.length } : null,
16506
- agents: agents ? { sessions: agents.totalSessions, tokens: agents.totalTokens } : null,
16507
- tests: tests ? { total: tests.totalTests, passRate: tests.passRate } : null,
16508
- scannedAt: score.scannedAt
16509
- };
16510
- console.log(JSON.stringify(output, null, 2));
16511
- } else if (quietMode) {
16512
- console.log(score.overall);
16513
- }
16514
- return;
16515
- }
16516
16347
  const client = getClient();
16517
16348
  const clerkId = getClerkId();
16518
16349
  if (!client || !clerkId) {
16519
- if (!silent) {
16520
- console.log(` ${icons.info} Run ${colors2.primary("nb init")} to enable cloud sync`);
16521
- console.log();
16522
- }
16523
16350
  if (jsonOutput) {
16524
16351
  const output = {
16525
16352
  score: score.overall,
@@ -21744,145 +21571,146 @@ import { resolve } from "node:path";
21744
21571
  var reportCommand = defineCommand2({
21745
21572
  meta: {
21746
21573
  name: "report",
21747
- description: "Generate AI-nativeness reports for hackathon submissions or regular benchmarks"
21574
+ description: "Generate AI-nativeness reports (interactive)"
21748
21575
  },
21749
21576
  args: {
21750
- hackathon: {
21751
- type: "boolean",
21752
- description: "Generate hackathon submission report (last 48 hours)",
21753
- default: false
21754
- },
21755
- harness: {
21756
- type: "string",
21757
- description: "AI harness to analyze: claude-code, opencode, cursor, or all"
21758
- },
21759
- since: {
21760
- type: "string",
21761
- description: "Time range: 48h, 7d, 30d, or ISO date"
21762
- },
21763
- output: {
21764
- type: "string",
21765
- description: "Save report to file (e.g., report.md)"
21766
- },
21767
- publish: {
21768
- type: "boolean",
21769
- description: "Publish report and get a shareable public link",
21770
- default: false
21771
- },
21772
- phase: {
21773
- type: "string",
21774
- description: "Drill into a specific phase (requirements, planning, implementation, testing, review)"
21775
- },
21776
- weekly: {
21777
- type: "boolean",
21778
- description: "Show latest scheduled weekly improvement report",
21779
- default: false
21780
- },
21781
- history: {
21782
- type: "boolean",
21783
- description: "Show score trend over time",
21784
- default: false
21785
- },
21786
- limit: {
21787
- type: "string",
21788
- description: "Number of historical scans to show",
21789
- default: "10"
21790
- },
21791
- format: {
21792
- type: "string",
21793
- description: "Output format: terminal, md, json, or text (legacy)",
21794
- default: "terminal"
21795
- },
21796
- leadership: {
21577
+ json: {
21797
21578
  type: "boolean",
21798
- description: "Generate leadership report with effort breakdown and hidden work visibility",
21579
+ description: "Output as JSON (for CI/scripts)",
21799
21580
  default: false
21800
21581
  }
21801
21582
  },
21802
21583
  async run({ args }) {
21803
- if (args.leadership) {
21804
- await runLeadershipReport(args);
21805
- return;
21806
- }
21807
- if (args.hackathon || args.since) {
21808
- await runHackathonReport(args);
21584
+ if (args.json) {
21585
+ const projectDir = process.cwd();
21586
+ const since = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
21587
+ const report = await generateHackathonReport(projectDir, since, new Date, "all");
21588
+ console.log(formatReportAsJSON(report));
21809
21589
  return;
21810
21590
  }
21811
- if (!args.weekly && !args.history && !args.phase) {
21812
- const choice = await consola.prompt("What would you like to report on?", {
21813
- type: "select",
21814
- options: [
21815
- { value: "hackathon", label: "Hackathon (last 48 hours)" },
21816
- { value: "week", label: "Last week" },
21817
- { value: "month", label: "Last month" },
21818
- { value: "cloud", label: "Cloud benchmark (requires nb init)" }
21819
- ]
21820
- });
21821
- if (choice === "hackathon" || choice === "week" || choice === "month") {
21822
- const sinceMap = {
21823
- hackathon: "48h",
21824
- week: "7d",
21825
- month: "30d"
21826
- };
21827
- args.since = sinceMap[choice];
21828
- const harness = await consola.prompt("Which AI harness did you use?", {
21829
- type: "select",
21830
- options: [
21831
- { value: "claude-code", label: "Claude Code" },
21832
- { value: "opencode", label: "OpenCode" },
21833
- { value: "cursor", label: "Cursor" },
21834
- { value: "all", label: "All (combine sessions from all harnesses)" }
21835
- ]
21836
- });
21837
- args.harness = harness;
21838
- const format2 = await consola.prompt("Output format?", {
21839
- type: "select",
21840
- options: [
21841
- { value: "terminal", label: "Terminal (view now)" },
21842
- { value: "md", label: "Markdown (for submission)" },
21843
- { value: "publish", label: "Public link (shareable URL)" },
21844
- { value: "json", label: "JSON (programmatic)" }
21845
- ]
21846
- });
21847
- if (format2 === "publish") {
21848
- args.publish = true;
21849
- args.format = "terminal";
21850
- } else {
21851
- args.format = format2;
21852
- }
21853
- if (format2 === "md") {
21854
- const filename = await consola.prompt("Save to file?", {
21855
- type: "text",
21856
- default: "ai-nativeness-report.md",
21857
- placeholder: "report.md"
21858
- });
21859
- if (filename && typeof filename === "string") {
21860
- args.output = filename;
21861
- }
21862
- }
21863
- await runHackathonReport(args);
21864
- return;
21865
- }
21866
- args.format = "text";
21867
- }
21868
- const client = getClient();
21869
- const clerkId = getClerkId();
21870
- if (!client || !clerkId) {
21871
- consola.error("Not connected to Convex. Run `nb init` to set up your profile.");
21872
- consola.info("Use `nb report --hackathon` for local AI-nativeness report.");
21591
+ console.log();
21592
+ console.log(" \uD83D\uDCCA " + "\x1B[1mNaironAI Report Generator\x1B[0m");
21593
+ console.log(" " + "\x1B[2m" + "─".repeat(35) + "\x1B[0m");
21594
+ console.log();
21595
+ const reportType = await consola.prompt("What kind of report?", {
21596
+ type: "select",
21597
+ options: [
21598
+ { value: "ai-nativeness", label: "AI-Nativeness Report (recommended)" },
21599
+ { value: "leadership", label: "Leadership Report (effort visibility)" },
21600
+ { value: "cloud", label: "Cloud Benchmark (requires nb init)" }
21601
+ ]
21602
+ });
21603
+ if (reportType === "leadership") {
21604
+ await runLeadershipReportInteractive();
21873
21605
  return;
21874
21606
  }
21875
- if (args.weekly) {
21876
- await showWeeklyReport(client, clerkId, args.format);
21607
+ if (reportType === "cloud") {
21608
+ await runCloudReport();
21877
21609
  return;
21878
21610
  }
21879
- if (args.history) {
21880
- await showHistory(client, clerkId, parseInt(args.limit, 10), args.format);
21881
- return;
21611
+ const period = await consola.prompt("Time period?", {
21612
+ type: "select",
21613
+ options: [
21614
+ { value: "48h", label: "Last 48 hours (hackathon)" },
21615
+ { value: "7d", label: "Last 7 days" },
21616
+ { value: "30d", label: "Last 30 days" }
21617
+ ]
21618
+ });
21619
+ const harness = await consola.prompt("Which AI tool?", {
21620
+ type: "select",
21621
+ options: [
21622
+ { value: "all", label: "All tools (recommended)" },
21623
+ { value: "claude-code", label: "Claude Code" },
21624
+ { value: "opencode", label: "OpenCode" },
21625
+ { value: "cursor", label: "Cursor" }
21626
+ ]
21627
+ });
21628
+ const format2 = await consola.prompt("Output format?", {
21629
+ type: "select",
21630
+ options: [
21631
+ { value: "publish", label: "Public link (shareable URL)" },
21632
+ { value: "terminal", label: "Terminal (view now)" },
21633
+ { value: "md", label: "Markdown file" },
21634
+ { value: "json", label: "JSON" }
21635
+ ]
21636
+ });
21637
+ const reportArgs = {
21638
+ since: period,
21639
+ harness,
21640
+ format: format2 === "publish" ? "terminal" : format2,
21641
+ publish: format2 === "publish"
21642
+ };
21643
+ if (format2 === "md") {
21644
+ const filename = await consola.prompt("Save to file?", {
21645
+ type: "text",
21646
+ default: "ai-nativeness-report.md",
21647
+ placeholder: "report.md"
21648
+ });
21649
+ if (filename && typeof filename === "string") {
21650
+ reportArgs.output = filename;
21651
+ }
21882
21652
  }
21883
- await showLatestScan(client, clerkId, args.phase, args.format);
21653
+ await runHackathonReport(reportArgs);
21884
21654
  }
21885
21655
  });
21656
+ async function runLeadershipReportInteractive() {
21657
+ const period = await consola.prompt("Time period?", {
21658
+ type: "select",
21659
+ options: [
21660
+ { value: "7d", label: "Last 7 days" },
21661
+ { value: "30d", label: "Last 30 days" },
21662
+ { value: "48h", label: "Last 48 hours" }
21663
+ ]
21664
+ });
21665
+ const format2 = await consola.prompt("Output format?", {
21666
+ type: "select",
21667
+ options: [
21668
+ { value: "terminal", label: "Terminal (view now)" },
21669
+ { value: "md", label: "Markdown file" }
21670
+ ]
21671
+ });
21672
+ let output;
21673
+ if (format2 === "md") {
21674
+ const filename = await consola.prompt("Save to file?", {
21675
+ type: "text",
21676
+ default: "leadership-report.md"
21677
+ });
21678
+ if (filename && typeof filename === "string") {
21679
+ output = filename;
21680
+ }
21681
+ }
21682
+ await runLeadershipReport({
21683
+ since: period,
21684
+ format: format2,
21685
+ output
21686
+ });
21687
+ }
21688
+ async function runCloudReport() {
21689
+ const client = getClient();
21690
+ const clerkId = getClerkId();
21691
+ if (!client || !clerkId) {
21692
+ consola.error("Not connected to Convex. Run `nb init` to set up your profile.");
21693
+ consola.info("Try the AI-Nativeness Report instead - it works locally.");
21694
+ return;
21695
+ }
21696
+ const cloudOption = await consola.prompt("What would you like to see?", {
21697
+ type: "select",
21698
+ options: [
21699
+ { value: "latest", label: "Latest scan results" },
21700
+ { value: "history", label: "Score history (trend)" },
21701
+ { value: "weekly", label: "Weekly improvement report" }
21702
+ ]
21703
+ });
21704
+ if (cloudOption === "weekly") {
21705
+ await showWeeklyReport(client, clerkId, "text");
21706
+ return;
21707
+ }
21708
+ if (cloudOption === "history") {
21709
+ await showHistory(client, clerkId, 10, "text");
21710
+ return;
21711
+ }
21712
+ await showLatestScan(client, clerkId, undefined, "text");
21713
+ }
21886
21714
  async function runHackathonReport(args) {
21887
21715
  const projectDir = process.cwd();
21888
21716
  let harness = args.harness;
@@ -22880,25 +22708,17 @@ function printVerificationResults(summary, verbose = false) {
22880
22708
  var doctorCommand = defineCommand2({
22881
22709
  meta: {
22882
22710
  name: "doctor",
22883
- description: "Check tool detection, data sources, and connectivity health"
22711
+ description: "Check system health and diagnose issues"
22884
22712
  },
22885
22713
  args: {
22886
22714
  "verify-recommendations": {
22887
22715
  type: "boolean",
22888
- description: "Verify all recommendations in the database are valid",
22889
- alias: "verify",
22716
+ description: "",
22890
22717
  default: false
22891
22718
  },
22892
22719
  thorough: {
22893
22720
  type: "boolean",
22894
- description: "Run thorough verification with network checks",
22895
- alias: "t",
22896
- default: false
22897
- },
22898
- verbose: {
22899
- type: "boolean",
22900
- description: "Show all results including valid recommendations",
22901
- alias: "v",
22721
+ description: "",
22902
22722
  default: false
22903
22723
  }
22904
22724
  },
@@ -22924,16 +22744,16 @@ var doctorCommand = defineCommand2({
22924
22744
  } else {
22925
22745
  spinner2.succeed("All recommendations verified");
22926
22746
  }
22927
- printVerificationResults(summary, args.verbose);
22747
+ printVerificationResults(summary, true);
22928
22748
  if (summary.invalid > 0) {
22929
22749
  process.exit(1);
22930
22750
  }
22931
22751
  return;
22932
22752
  }
22933
22753
  console.log();
22934
- console.log(colors2.bold(colors2.primary(" NaironAI Doctor")));
22935
- console.log(colors2.dim(` Checking system health...
22936
- `));
22754
+ console.log(" \uD83E\uDE7A " + "\x1B[1mNaironAI Doctor\x1B[0m");
22755
+ console.log(" " + "\x1B[2m" + "─".repeat(35) + "\x1B[0m");
22756
+ console.log();
22937
22757
  const spinner = createSpinner("Running diagnostics...");
22938
22758
  spinner.start();
22939
22759
  const results = [];
@@ -23568,8 +23388,19 @@ var RESET = "\x1B[0m";
23568
23388
  var MAGENTA = "\x1B[35m";
23569
23389
  var CHANGELOG = [
23570
23390
  {
23571
- version: "0.4.0",
23391
+ version: "0.5.0",
23572
23392
  date: "2026-02-14",
23393
+ title: "Interactive-First CLI",
23394
+ highlights: [
23395
+ "No more flags to remember - commands guide you through options",
23396
+ "Just run nb scan or nb report and follow the prompts",
23397
+ "Public link is now the first option for report sharing",
23398
+ "CI/scripts still supported via --json flag"
23399
+ ]
23400
+ },
23401
+ {
23402
+ version: "0.4.0",
23403
+ date: "2026-02-13",
23573
23404
  title: "AI Work Visibility",
23574
23405
  highlights: [
23575
23406
  "New: Effort breakdown shows generation/review/correction/integration time",
@@ -23604,7 +23435,7 @@ var CHANGELOG = [
23604
23435
  title: "Reliable Recommendations",
23605
23436
  highlights: [
23606
23437
  "Fixed skills.sh format - skills now install correctly",
23607
- "New: nb doctor --verify-recommendations to validate install commands"
23438
+ "Improved recommendation validation before release"
23608
23439
  ]
23609
23440
  },
23610
23441
  {
@@ -24006,7 +23837,7 @@ function showFullChangelog() {
24006
23837
  // package.json
24007
23838
  var package_default = {
24008
23839
  name: "nairon-bench",
24009
- version: "0.4.0",
23840
+ version: "0.5.0",
24010
23841
  description: "AI workflow benchmarking CLI",
24011
23842
  type: "module",
24012
23843
  bin: {
@@ -26531,7 +26362,7 @@ function formatBytes(bytes) {
26531
26362
  // package.json
26532
26363
  var package_default2 = {
26533
26364
  name: "nairon-bench",
26534
- version: "0.4.0",
26365
+ version: "0.5.0",
26535
26366
  description: "AI workflow benchmarking CLI",
26536
26367
  type: "module",
26537
26368
  bin: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nairon-bench",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "AI workflow benchmarking CLI",
5
5
  "type": "module",
6
6
  "bin": {