nairon-bench 0.0.28 → 0.0.30
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 +157 -8
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -14665,13 +14665,14 @@ init_client();
|
|
|
14665
14665
|
import { existsSync as existsSync7, readdirSync as readdirSync3, readFileSync as readFileSync6, statSync as statSync2 } from "node:fs";
|
|
14666
14666
|
import { homedir as homedir5 } from "node:os";
|
|
14667
14667
|
import { join as join7, basename as basename2 } from "node:path";
|
|
14668
|
-
async function collectReportData(projectDir, since, until = new Date) {
|
|
14668
|
+
async function collectReportData(projectDir, since, until = new Date, harness) {
|
|
14669
14669
|
const projectName = basename2(projectDir);
|
|
14670
|
-
const [commits,
|
|
14670
|
+
const [commits, allSessions, mcpConfigs] = await Promise.all([
|
|
14671
14671
|
collectGitCommits(projectDir, since, until),
|
|
14672
14672
|
collectAllSessions(since, until, projectDir),
|
|
14673
14673
|
collectMCPConfigs()
|
|
14674
14674
|
]);
|
|
14675
|
+
const sessions = harness && harness !== "all" ? allSessions.filter((s2) => s2.agent === harness) : allSessions;
|
|
14675
14676
|
const allPrompts = sessions.flatMap((s2) => s2.prompts);
|
|
14676
14677
|
const toolUsage = buildToolUsageMap(sessions);
|
|
14677
14678
|
const stats = calculateStats(sessions, allPrompts);
|
|
@@ -14893,7 +14894,128 @@ function parseClaudeTranscript(filePath, fileName) {
|
|
|
14893
14894
|
};
|
|
14894
14895
|
}
|
|
14895
14896
|
function collectOpenCodeSessions2(openCodeDir, since, until) {
|
|
14896
|
-
|
|
14897
|
+
const sessions = [];
|
|
14898
|
+
const sessionDir = join7(openCodeDir, "storage", "session");
|
|
14899
|
+
const messageDir = join7(openCodeDir, "storage", "message");
|
|
14900
|
+
const partDir = join7(openCodeDir, "storage", "part");
|
|
14901
|
+
if (!existsSync7(sessionDir))
|
|
14902
|
+
return sessions;
|
|
14903
|
+
try {
|
|
14904
|
+
const projectDirs = readdirSync3(sessionDir, { withFileTypes: true }).filter((d2) => d2.isDirectory()).map((d2) => join7(sessionDir, d2.name));
|
|
14905
|
+
for (const projectDir of projectDirs) {
|
|
14906
|
+
const sessionFiles = readdirSync3(projectDir).filter((f3) => f3.endsWith(".json"));
|
|
14907
|
+
for (const sessionFile of sessionFiles) {
|
|
14908
|
+
try {
|
|
14909
|
+
const sessionPath = join7(projectDir, sessionFile);
|
|
14910
|
+
const sessionData = JSON.parse(readFileSync6(sessionPath, "utf-8"));
|
|
14911
|
+
const createdAt = new Date(sessionData.time?.created || 0);
|
|
14912
|
+
const updatedAt = new Date(sessionData.time?.updated || sessionData.time?.created || 0);
|
|
14913
|
+
if (updatedAt < since || createdAt > until)
|
|
14914
|
+
continue;
|
|
14915
|
+
const sessionId = sessionData.id;
|
|
14916
|
+
const sessionMsgDir = join7(messageDir, sessionId);
|
|
14917
|
+
const prompts = [];
|
|
14918
|
+
const responses = [];
|
|
14919
|
+
const toolsUsed = new Set;
|
|
14920
|
+
const filesModified = new Set;
|
|
14921
|
+
let totalTokens = 0;
|
|
14922
|
+
let inputTokens = 0;
|
|
14923
|
+
let outputTokens = 0;
|
|
14924
|
+
let model = "unknown";
|
|
14925
|
+
let startTime = createdAt;
|
|
14926
|
+
let endTime = updatedAt;
|
|
14927
|
+
if (existsSync7(sessionMsgDir)) {
|
|
14928
|
+
const msgFiles = readdirSync3(sessionMsgDir).filter((f3) => f3.endsWith(".json")).sort();
|
|
14929
|
+
for (const msgFile of msgFiles) {
|
|
14930
|
+
try {
|
|
14931
|
+
const msgPath = join7(sessionMsgDir, msgFile);
|
|
14932
|
+
const msgData = JSON.parse(readFileSync6(msgPath, "utf-8"));
|
|
14933
|
+
const msgId = msgData.id;
|
|
14934
|
+
if (msgData.model?.modelID) {
|
|
14935
|
+
model = msgData.model.modelID;
|
|
14936
|
+
}
|
|
14937
|
+
const msgTime = new Date(msgData.time?.created || createdAt);
|
|
14938
|
+
if (msgTime < startTime)
|
|
14939
|
+
startTime = msgTime;
|
|
14940
|
+
if (msgTime > endTime)
|
|
14941
|
+
endTime = msgTime;
|
|
14942
|
+
const msgPartDir = join7(partDir, msgId);
|
|
14943
|
+
let messageText = "";
|
|
14944
|
+
if (existsSync7(msgPartDir)) {
|
|
14945
|
+
const partFiles = readdirSync3(msgPartDir).filter((f3) => f3.endsWith(".json")).sort();
|
|
14946
|
+
for (const partFile of partFiles) {
|
|
14947
|
+
try {
|
|
14948
|
+
const partPath = join7(msgPartDir, partFile);
|
|
14949
|
+
const partData = JSON.parse(readFileSync6(partPath, "utf-8"));
|
|
14950
|
+
if (partData.type === "text" && partData.text && !partData.synthetic) {
|
|
14951
|
+
messageText += partData.text + `
|
|
14952
|
+
`;
|
|
14953
|
+
}
|
|
14954
|
+
if (partData.type === "tool-invocation" || partData.type === "tool-result") {
|
|
14955
|
+
const toolName = partData.toolName || partData.name;
|
|
14956
|
+
if (toolName)
|
|
14957
|
+
toolsUsed.add(toolName);
|
|
14958
|
+
}
|
|
14959
|
+
} catch {}
|
|
14960
|
+
}
|
|
14961
|
+
}
|
|
14962
|
+
if (msgData.role === "user" && messageText.trim()) {
|
|
14963
|
+
const prompt2 = analyzePrompt(messageText, sessionId, prompts.length, msgTime);
|
|
14964
|
+
prompts.push(prompt2);
|
|
14965
|
+
}
|
|
14966
|
+
if (msgData.role === "assistant" && messageText.trim()) {
|
|
14967
|
+
const response = analyzeResponse(messageText, sessionId, responses.length, prompts[prompts.length - 1]?.id ?? "", msgTime);
|
|
14968
|
+
responses.push(response);
|
|
14969
|
+
if (messageText.includes("Write ") || messageText.includes("Created ")) {
|
|
14970
|
+
const fileMatches = messageText.match(/(?:Write|Created|Updated)\s+(\S+\.\w+)/g);
|
|
14971
|
+
if (fileMatches) {
|
|
14972
|
+
fileMatches.forEach((m2) => {
|
|
14973
|
+
const file = m2.split(/\s+/)[1];
|
|
14974
|
+
if (file)
|
|
14975
|
+
filesModified.add(file);
|
|
14976
|
+
});
|
|
14977
|
+
}
|
|
14978
|
+
}
|
|
14979
|
+
}
|
|
14980
|
+
if (msgData.usage) {
|
|
14981
|
+
totalTokens += msgData.usage.totalTokens || 0;
|
|
14982
|
+
inputTokens += msgData.usage.inputTokens || 0;
|
|
14983
|
+
outputTokens += msgData.usage.outputTokens || 0;
|
|
14984
|
+
}
|
|
14985
|
+
} catch {}
|
|
14986
|
+
}
|
|
14987
|
+
}
|
|
14988
|
+
if (prompts.length === 0)
|
|
14989
|
+
continue;
|
|
14990
|
+
const correctionCount = prompts.filter((p) => p.isCorrection).length;
|
|
14991
|
+
const frustrationCount = prompts.filter((p) => p.isFrustrated).length;
|
|
14992
|
+
if (sessionData.summary?.files) {
|
|
14993
|
+
filesModified.add(`${sessionData.summary.files} files changed`);
|
|
14994
|
+
}
|
|
14995
|
+
sessions.push({
|
|
14996
|
+
id: sessionId,
|
|
14997
|
+
agent: "opencode",
|
|
14998
|
+
model,
|
|
14999
|
+
startTime,
|
|
15000
|
+
endTime,
|
|
15001
|
+
durationMinutes: Math.round((endTime.getTime() - startTime.getTime()) / 60000),
|
|
15002
|
+
promptCount: prompts.length,
|
|
15003
|
+
totalTokens,
|
|
15004
|
+
inputTokens,
|
|
15005
|
+
outputTokens,
|
|
15006
|
+
prompts,
|
|
15007
|
+
responses,
|
|
15008
|
+
toolsUsed: Array.from(toolsUsed),
|
|
15009
|
+
filesModified: Array.from(filesModified),
|
|
15010
|
+
hadCompaction: false,
|
|
15011
|
+
correctionCount,
|
|
15012
|
+
frustrationCount
|
|
15013
|
+
});
|
|
15014
|
+
} catch {}
|
|
15015
|
+
}
|
|
15016
|
+
}
|
|
15017
|
+
} catch {}
|
|
15018
|
+
return sessions;
|
|
14897
15019
|
}
|
|
14898
15020
|
function analyzePrompt(text, sessionId, index, timestamp) {
|
|
14899
15021
|
const lower = text.toLowerCase();
|
|
@@ -18360,8 +18482,8 @@ function renderGitBlameMarkdown(analysis) {
|
|
|
18360
18482
|
}
|
|
18361
18483
|
|
|
18362
18484
|
// src/lib/hackathon-report.ts
|
|
18363
|
-
async function generateHackathonReport(projectDir, since, until = new Date) {
|
|
18364
|
-
const data = await collectReportData(projectDir, since, until);
|
|
18485
|
+
async function generateHackathonReport(projectDir, since, until = new Date, harness) {
|
|
18486
|
+
const data = await collectReportData(projectDir, since, until, harness);
|
|
18365
18487
|
const sdlcAnalysis = analyzeSDLC(data);
|
|
18366
18488
|
const promptAnalysis = analyzePrompts(data);
|
|
18367
18489
|
const effectivenessProfile = analyzeEffectiveness(data);
|
|
@@ -18873,6 +18995,10 @@ var reportCommand = defineCommand2({
|
|
|
18873
18995
|
description: "Generate hackathon submission report (last 48 hours)",
|
|
18874
18996
|
default: false
|
|
18875
18997
|
},
|
|
18998
|
+
harness: {
|
|
18999
|
+
type: "string",
|
|
19000
|
+
description: "AI harness to analyze: claude-code, opencode, cursor, or all"
|
|
19001
|
+
},
|
|
18876
19002
|
since: {
|
|
18877
19003
|
type: "string",
|
|
18878
19004
|
description: "Time range: 48h, 7d, 30d, or ISO date"
|
|
@@ -18933,6 +19059,16 @@ var reportCommand = defineCommand2({
|
|
|
18933
19059
|
month: "30d"
|
|
18934
19060
|
};
|
|
18935
19061
|
args.since = sinceMap[choice];
|
|
19062
|
+
const harness = await consola.prompt("Which AI harness did you use?", {
|
|
19063
|
+
type: "select",
|
|
19064
|
+
options: [
|
|
19065
|
+
{ value: "claude-code", label: "Claude Code" },
|
|
19066
|
+
{ value: "opencode", label: "OpenCode" },
|
|
19067
|
+
{ value: "cursor", label: "Cursor" },
|
|
19068
|
+
{ value: "all", label: "All (combine sessions from all harnesses)" }
|
|
19069
|
+
]
|
|
19070
|
+
});
|
|
19071
|
+
args.harness = harness;
|
|
18936
19072
|
const format2 = await consola.prompt("Output format?", {
|
|
18937
19073
|
type: "select",
|
|
18938
19074
|
options: [
|
|
@@ -18983,12 +19119,25 @@ var reportCommand = defineCommand2({
|
|
|
18983
19119
|
});
|
|
18984
19120
|
async function runHackathonReport(args) {
|
|
18985
19121
|
const projectDir = process.cwd();
|
|
19122
|
+
let harness = args.harness;
|
|
19123
|
+
if (!harness) {
|
|
19124
|
+
harness = await consola.prompt("Which AI harness did you use?", {
|
|
19125
|
+
type: "select",
|
|
19126
|
+
options: [
|
|
19127
|
+
{ value: "claude-code", label: "Claude Code" },
|
|
19128
|
+
{ value: "opencode", label: "OpenCode" },
|
|
19129
|
+
{ value: "cursor", label: "Cursor" },
|
|
19130
|
+
{ value: "all", label: "All (combine sessions from all harnesses)" }
|
|
19131
|
+
]
|
|
19132
|
+
});
|
|
19133
|
+
}
|
|
18986
19134
|
const since = parseSince2(args.since || (args.hackathon ? "48h" : "7d"));
|
|
18987
19135
|
const until = new Date;
|
|
18988
19136
|
const hoursAgo = Math.round((until.getTime() - since.getTime()) / (1000 * 60 * 60));
|
|
18989
|
-
|
|
19137
|
+
const harnessLabel = harness === "all" ? "all harnesses" : harness;
|
|
19138
|
+
consola.start(`Generating AI-nativeness report for ${harnessLabel} (last ${hoursAgo} hours)...`);
|
|
18990
19139
|
try {
|
|
18991
|
-
const report = await generateHackathonReport(projectDir, since, until);
|
|
19140
|
+
const report = await generateHackathonReport(projectDir, since, until, harness);
|
|
18992
19141
|
if (args.publish) {
|
|
18993
19142
|
await publishReport(report);
|
|
18994
19143
|
return;
|
|
@@ -22848,7 +22997,7 @@ var setupCommand = defineCommand2({
|
|
|
22848
22997
|
// package.json
|
|
22849
22998
|
var package_default = {
|
|
22850
22999
|
name: "nairon-bench",
|
|
22851
|
-
version: "0.0.
|
|
23000
|
+
version: "0.0.30",
|
|
22852
23001
|
description: "AI workflow benchmarking CLI",
|
|
22853
23002
|
type: "module",
|
|
22854
23003
|
bin: {
|