@ironbee-ai/cli 0.2.1 → 0.4.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.
- package/CHANGELOG.md +31 -3
- package/README.md +118 -3
- package/dist/analysis/code-changes.d.ts +22 -0
- package/dist/analysis/code-changes.d.ts.map +1 -0
- package/dist/analysis/code-changes.js +141 -0
- package/dist/analysis/code-changes.js.map +1 -0
- package/dist/analysis/cross-session.d.ts +34 -0
- package/dist/analysis/cross-session.d.ts.map +1 -0
- package/dist/analysis/cross-session.js +230 -0
- package/dist/analysis/cross-session.js.map +1 -0
- package/dist/analysis/fix-effectiveness.d.ts +16 -0
- package/dist/analysis/fix-effectiveness.d.ts.map +1 -0
- package/dist/analysis/fix-effectiveness.js +99 -0
- package/dist/analysis/fix-effectiveness.js.map +1 -0
- package/dist/analysis/scoring.d.ts +15 -0
- package/dist/analysis/scoring.d.ts.map +1 -0
- package/dist/analysis/scoring.js +57 -0
- package/dist/analysis/scoring.js.map +1 -0
- package/dist/analysis/time-analysis.d.ts +22 -0
- package/dist/analysis/time-analysis.d.ts.map +1 -0
- package/dist/analysis/time-analysis.js +174 -0
- package/dist/analysis/time-analysis.js.map +1 -0
- package/dist/analysis/verdict-details.d.ts +23 -0
- package/dist/analysis/verdict-details.d.ts.map +1 -0
- package/dist/analysis/verdict-details.js +59 -0
- package/dist/analysis/verdict-details.js.map +1 -0
- package/dist/analysis/verification-quality.d.ts +19 -0
- package/dist/analysis/verification-quality.d.ts.map +1 -0
- package/dist/analysis/verification-quality.js +182 -0
- package/dist/analysis/verification-quality.js.map +1 -0
- package/dist/clients/base.d.ts +2 -0
- package/dist/clients/base.d.ts.map +1 -1
- package/dist/clients/claude/commands/ironbee-analyze.md +42 -0
- package/dist/clients/claude/hooks/clear-verdict.js +1 -1
- package/dist/clients/claude/hooks/clear-verdict.js.map +1 -1
- package/dist/clients/claude/hooks/require-verification.d.ts +15 -0
- package/dist/clients/claude/hooks/require-verification.d.ts.map +1 -0
- package/dist/clients/claude/hooks/require-verification.js +61 -0
- package/dist/clients/claude/hooks/require-verification.js.map +1 -0
- package/dist/clients/claude/hooks/session-start.d.ts +1 -1
- package/dist/clients/claude/hooks/session-start.d.ts.map +1 -1
- package/dist/clients/claude/hooks/session-start.js +10 -1
- package/dist/clients/claude/hooks/session-start.js.map +1 -1
- package/dist/clients/claude/hooks/track-action.d.ts +1 -1
- package/dist/clients/claude/hooks/track-action.d.ts.map +1 -1
- package/dist/clients/claude/hooks/track-action.js +58 -13
- package/dist/clients/claude/hooks/track-action.js.map +1 -1
- package/dist/clients/claude/hooks/verify-gate.d.ts +1 -1
- package/dist/clients/claude/hooks/verify-gate.d.ts.map +1 -1
- package/dist/clients/claude/hooks/verify-gate.js +3 -3
- package/dist/clients/claude/hooks/verify-gate.js.map +1 -1
- package/dist/clients/claude/index.d.ts +2 -0
- package/dist/clients/claude/index.d.ts.map +1 -1
- package/dist/clients/claude/index.js +43 -9
- package/dist/clients/claude/index.js.map +1 -1
- package/dist/clients/claude/rule.md +9 -7
- package/dist/clients/claude/skill.md +11 -8
- package/dist/clients/claude/skills/ironbee-analyze.md +39 -0
- package/dist/clients/cursor/commands/ironbee-analyze/SKILL.md +48 -0
- package/dist/clients/cursor/hooks/clear-verdict.js +1 -1
- package/dist/clients/cursor/hooks/clear-verdict.js.map +1 -1
- package/dist/clients/cursor/hooks/require-verification.d.ts +15 -0
- package/dist/clients/cursor/hooks/require-verification.d.ts.map +1 -0
- package/dist/clients/cursor/hooks/require-verification.js +63 -0
- package/dist/clients/cursor/hooks/require-verification.js.map +1 -0
- package/dist/clients/cursor/hooks/session-start.d.ts +1 -1
- package/dist/clients/cursor/hooks/session-start.d.ts.map +1 -1
- package/dist/clients/cursor/hooks/session-start.js +6 -1
- package/dist/clients/cursor/hooks/session-start.js.map +1 -1
- package/dist/clients/cursor/hooks/track-action.d.ts.map +1 -1
- package/dist/clients/cursor/hooks/track-action.js +62 -12
- package/dist/clients/cursor/hooks/track-action.js.map +1 -1
- package/dist/clients/cursor/hooks/verify-gate.d.ts +1 -1
- package/dist/clients/cursor/hooks/verify-gate.d.ts.map +1 -1
- package/dist/clients/cursor/hooks/verify-gate.js +3 -3
- package/dist/clients/cursor/hooks/verify-gate.js.map +1 -1
- package/dist/clients/cursor/index.d.ts +2 -0
- package/dist/clients/cursor/index.d.ts.map +1 -1
- package/dist/clients/cursor/index.js +31 -6
- package/dist/clients/cursor/index.js.map +1 -1
- package/dist/clients/cursor/rule.md +9 -7
- package/dist/clients/cursor/skill.md +11 -8
- package/dist/commands/analyze.d.ts +3 -0
- package/dist/commands/analyze.d.ts.map +1 -0
- package/dist/commands/analyze.js +298 -0
- package/dist/commands/analyze.js.map +1 -0
- package/dist/commands/hook.d.ts.map +1 -1
- package/dist/commands/hook.js +81 -2
- package/dist/commands/hook.js.map +1 -1
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/install.js +3 -1
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/uninstall.d.ts.map +1 -1
- package/dist/commands/uninstall.js +3 -1
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/hooks/core/actions.d.ts +19 -0
- package/dist/hooks/core/actions.d.ts.map +1 -1
- package/dist/hooks/core/actions.js +5 -0
- package/dist/hooks/core/actions.js.map +1 -1
- package/dist/hooks/core/clear-verdict.d.ts +1 -1
- package/dist/hooks/core/clear-verdict.d.ts.map +1 -1
- package/dist/hooks/core/clear-verdict.js +13 -9
- package/dist/hooks/core/clear-verdict.js.map +1 -1
- package/dist/hooks/core/session-state.d.ts +47 -0
- package/dist/hooks/core/session-state.d.ts.map +1 -0
- package/dist/hooks/core/session-state.js +192 -0
- package/dist/hooks/core/session-state.js.map +1 -0
- package/dist/hooks/core/submit-verdict.d.ts +2 -1
- package/dist/hooks/core/submit-verdict.d.ts.map +1 -1
- package/dist/hooks/core/submit-verdict.js +38 -28
- package/dist/hooks/core/submit-verdict.js.map +1 -1
- package/dist/hooks/core/verification-lifecycle.d.ts +30 -0
- package/dist/hooks/core/verification-lifecycle.d.ts.map +1 -0
- package/dist/hooks/core/verification-lifecycle.js +75 -0
- package/dist/hooks/core/verification-lifecycle.js.map +1 -0
- package/dist/hooks/core/verify-gate.d.ts +2 -2
- package/dist/hooks/core/verify-gate.d.ts.map +1 -1
- package/dist/hooks/core/verify-gate.js +28 -33
- package/dist/hooks/core/verify-gate.js.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/telemetry.d.ts +23 -0
- package/dist/lib/telemetry.d.ts.map +1 -0
- package/dist/lib/telemetry.js +265 -0
- package/dist/lib/telemetry.js.map +1 -0
- package/dist/scripts/postinstall.d.ts +7 -0
- package/dist/scripts/postinstall.d.ts.map +1 -0
- package/dist/scripts/postinstall.js +12 -0
- package/dist/scripts/postinstall.js.map +1 -0
- package/dist/scripts/preuninstall.d.ts +8 -0
- package/dist/scripts/preuninstall.d.ts.map +1 -0
- package/dist/scripts/preuninstall.js +13 -0
- package/dist/scripts/preuninstall.js.map +1 -0
- package/package.json +6 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify-gate.d.ts","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/verify-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAmBH,
|
|
1
|
+
{"version":3,"file":"verify-gate.d.ts","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/verify-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAmBH,wBAAsB,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkC3D"}
|
|
@@ -16,7 +16,7 @@ const verify_gate_1 = require("../../../hooks/core/verify-gate");
|
|
|
16
16
|
const config_1 = require("../../../lib/config");
|
|
17
17
|
const logger_1 = require("../../../lib/logger");
|
|
18
18
|
const stdin_1 = require("../../../lib/stdin");
|
|
19
|
-
function run(projectDir) {
|
|
19
|
+
async function run(projectDir) {
|
|
20
20
|
let input;
|
|
21
21
|
try {
|
|
22
22
|
input = JSON.parse((0, stdin_1.readStdin)());
|
|
@@ -29,11 +29,11 @@ function run(projectDir) {
|
|
|
29
29
|
const sessionId = input.conversation_id ?? "default";
|
|
30
30
|
(0, logger_1.setLogFile)(`${projectDir}/.ironbee/sessions/${sessionId}/session.log`);
|
|
31
31
|
const config = (0, config_1.loadConfig)(projectDir);
|
|
32
|
-
const result = (0, verify_gate_1.runVerifyGate)({
|
|
32
|
+
const result = await (0, verify_gate_1.runVerifyGate)({
|
|
33
33
|
sessionId,
|
|
34
|
+
sessionDir: `${projectDir}/.ironbee/sessions/${sessionId}`,
|
|
34
35
|
actionsFile: `${projectDir}/.ironbee/sessions/${sessionId}/actions.jsonl`,
|
|
35
36
|
verdictFile: `${projectDir}/.ironbee/sessions/${sessionId}/verdict.json`,
|
|
36
|
-
retryFile: `${projectDir}/.ironbee/sessions/${sessionId}/retries`,
|
|
37
37
|
maxRetries: (0, config_1.getMaxRetries)(config),
|
|
38
38
|
});
|
|
39
39
|
const output = {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify-gate.js","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/verify-gate.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;AAmBH,kBAkCC;AAnDD,iEAAkF;AAClF,gDAA+E;AAC/E,gDAAyD;AACzD,8CAA+C;
|
|
1
|
+
{"version":3,"file":"verify-gate.js","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/verify-gate.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;AAmBH,kBAkCC;AAnDD,iEAAkF;AAClF,gDAA+E;AAC/E,gDAAyD;AACzD,8CAA+C;AAcxC,KAAK,UAAU,GAAG,CAAC,UAAkB;IACxC,IAAI,KAA0B,CAAC;IAC/B,IAAI,CAAC;QACD,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,iBAAS,GAAE,CAAwB,CAAC;IAC3D,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QAClB,eAAM,CAAC,KAAK,CAAC,0BAA0B,CAAC,EAAE,CAAC,CAAC;QAC5C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;QACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,SAAS,GAAW,KAAK,CAAC,eAAe,IAAI,SAAS,CAAC;IAC7D,IAAA,mBAAU,EAAC,GAAG,UAAU,sBAAsB,SAAS,cAAc,CAAC,CAAC;IAEvE,MAAM,MAAM,GAAkB,IAAA,mBAAU,EAAC,UAAU,CAAC,CAAC;IAErD,MAAM,MAAM,GAAqB,MAAM,IAAA,2BAAa,EAAC;QACjD,SAAS;QACT,UAAU,EAAE,GAAG,UAAU,sBAAsB,SAAS,EAAE;QAC1D,WAAW,EAAE,GAAG,UAAU,sBAAsB,SAAS,gBAAgB;QACzE,WAAW,EAAE,GAAG,UAAU,sBAAsB,SAAS,eAAe;QACxE,UAAU,EAAE,IAAA,sBAAa,EAAC,MAAM,CAAC;KACpC,CAAC,CAAC;IAEH,MAAM,MAAM,GAAyB,EAAE,CAAC;IAExC,uEAAuE;IACvE,0EAA0E;IAC1E,qEAAqE;IACrE,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAC9C,MAAM,CAAC,gBAAgB,GAAG,MAAM,CAAC,OAAO,CAAC;IAC7C,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC"}
|
|
@@ -5,11 +5,13 @@ export declare class CursorClient implements IClient {
|
|
|
5
5
|
resolveProjectDir(): string;
|
|
6
6
|
install(projectDir: string): void;
|
|
7
7
|
uninstall(projectDir: string): void;
|
|
8
|
+
private cleanupArtifacts;
|
|
8
9
|
runVerifyGate(projectDir: string): void;
|
|
9
10
|
runClearVerdict(projectDir: string): void;
|
|
10
11
|
runTrackAction(projectDir: string): void;
|
|
11
12
|
runSessionStart(projectDir: string): void;
|
|
12
13
|
runRequireVerdict(projectDir: string): void;
|
|
14
|
+
runRequireVerification(projectDir: string): void;
|
|
13
15
|
private isIronBeeHook;
|
|
14
16
|
private mergeHooksConfig;
|
|
15
17
|
private removeIronBeeHooks;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/clients/cursor/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/clients/cursor/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAyClC,qBAAa,YAAa,YAAW,OAAO;IACxC,SAAgB,IAAI,EAAE,MAAM,CAAY;IAEjC,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAInC,iBAAiB,IAAI,MAAM;IAI3B,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IA2CjC,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAO1C,OAAO,CAAC,gBAAgB;IAoBjB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIvC,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIzC,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIxC,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIzC,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAI3C,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIvD,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,gBAAgB;IA4ExB,OAAO,CAAC,kBAAkB;IAuB1B,OAAO,CAAC,eAAe;IAgBvB,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,cAAc;CA2BzB"}
|
|
@@ -10,6 +10,7 @@ const clear_verdict_1 = require("./hooks/clear-verdict");
|
|
|
10
10
|
const track_action_1 = require("./hooks/track-action");
|
|
11
11
|
const session_start_1 = require("./hooks/session-start");
|
|
12
12
|
const require_verdict_1 = require("./hooks/require-verdict");
|
|
13
|
+
const require_verification_1 = require("./hooks/require-verification");
|
|
13
14
|
const MCP_SERVER_NAME = "browser-devtools";
|
|
14
15
|
const MCP_SERVER_PACKAGE = "browser-devtools-mcp";
|
|
15
16
|
const IRONBEE_HOOK_MARKER = "ironbee";
|
|
@@ -28,6 +29,8 @@ class CursorClient {
|
|
|
28
29
|
return process.env.CURSOR_PROJECT_DIR ?? process.env.IRONBEE_PROJECT_DIR ?? process.cwd();
|
|
29
30
|
}
|
|
30
31
|
install(projectDir) {
|
|
32
|
+
// Clean up old artifacts first (safe for re-install / upgrade)
|
|
33
|
+
this.cleanupArtifacts(projectDir);
|
|
31
34
|
const cursorDir = (0, path_1.join)(projectDir, ".cursor");
|
|
32
35
|
const rulesDir = (0, path_1.join)(cursorDir, "rules");
|
|
33
36
|
const skillsDir = (0, path_1.join)(cursorDir, "skills");
|
|
@@ -41,11 +44,17 @@ class CursorClient {
|
|
|
41
44
|
const rulePath = (0, path_1.join)(rulesDir, "ironbee-verification.mdc");
|
|
42
45
|
const ruleContent = (0, fs_1.readFileSync)((0, path_1.join)(__dirname, "rule.md"), "utf-8");
|
|
43
46
|
(0, fs_1.writeFileSync)(rulePath, ruleContent);
|
|
47
|
+
const analyzeSkillDir = (0, path_1.join)(skillsDir, "ironbee-analyze");
|
|
48
|
+
(0, fs_1.mkdirSync)(analyzeSkillDir, { recursive: true });
|
|
49
|
+
const analyzeSkillPath = (0, path_1.join)(analyzeSkillDir, "SKILL.md");
|
|
50
|
+
const analyzeContent = (0, fs_1.readFileSync)((0, path_1.join)(__dirname, "commands", "ironbee-analyze", "SKILL.md"), "utf-8");
|
|
51
|
+
(0, fs_1.writeFileSync)(analyzeSkillPath, analyzeContent);
|
|
44
52
|
const mcpPath = (0, path_1.join)(cursorDir, "mcp.json");
|
|
45
53
|
this.writeMcpConfig(mcpPath);
|
|
46
54
|
console.log(` ${output_1.pc.dim("→")} ${cursorColor("[cursor]")} hooks ${output_1.pc.dim("→")} ${output_1.pc.dim(hooksPath)}`);
|
|
47
55
|
console.log(` ${output_1.pc.dim("→")} ${cursorColor("[cursor]")} skill ${output_1.pc.dim("→")} ${output_1.pc.dim(skillPath)}`);
|
|
48
56
|
console.log(` ${output_1.pc.dim("→")} ${cursorColor("[cursor]")} rule ${output_1.pc.dim("→")} ${output_1.pc.dim(rulePath)}`);
|
|
57
|
+
console.log(` ${output_1.pc.dim("→")} ${cursorColor("[cursor]")} command ${output_1.pc.dim("→")} ${output_1.pc.dim(analyzeSkillPath)}`);
|
|
49
58
|
console.log(` ${output_1.pc.dim("→")} ${cursorColor("[cursor]")} mcp ${output_1.pc.dim("→")} ${output_1.pc.dim(mcpPath)}`);
|
|
50
59
|
console.log();
|
|
51
60
|
console.log(` ${output_1.pc.yellow("⚠")} ${output_1.pc.yellow("Cursor requires manual steps:")}`);
|
|
@@ -54,21 +63,26 @@ class CursorClient {
|
|
|
54
63
|
console.log(` ${output_1.pc.yellow("3.")} If the server shows as enabled but tools are unavailable, toggle it off and on`);
|
|
55
64
|
}
|
|
56
65
|
uninstall(projectDir) {
|
|
66
|
+
this.cleanupArtifacts(projectDir);
|
|
67
|
+
console.log(` ${output_1.pc.dim("→")} ${cursorColor("[cursor]")} removed hooks, skill, rule, command, and MCP`);
|
|
68
|
+
console.log();
|
|
69
|
+
console.log(` ${output_1.pc.yellow("⚠")} Restart Cursor to apply changes`);
|
|
70
|
+
}
|
|
71
|
+
cleanupArtifacts(projectDir) {
|
|
57
72
|
const cursorDir = (0, path_1.join)(projectDir, ".cursor");
|
|
58
|
-
// remove skill and
|
|
73
|
+
// remove skill, rule, and command files
|
|
59
74
|
const skillPath = (0, path_1.join)(cursorDir, "skills", "ironbee-verification.md");
|
|
60
75
|
const rulePath = (0, path_1.join)(cursorDir, "rules", "ironbee-verification.mdc");
|
|
76
|
+
const analyzeSkillPath = (0, path_1.join)(cursorDir, "skills", "ironbee-analyze", "SKILL.md");
|
|
61
77
|
this.removeFile(skillPath);
|
|
62
78
|
this.removeFile(rulePath);
|
|
79
|
+
this.removeFile(analyzeSkillPath);
|
|
63
80
|
// remove ironbee hooks from hooks.json
|
|
64
81
|
const hooksPath = (0, path_1.join)(cursorDir, "hooks.json");
|
|
65
82
|
this.removeIronBeeHooks(hooksPath);
|
|
66
83
|
// remove browser-devtools from mcp.json
|
|
67
84
|
const mcpPath = (0, path_1.join)(cursorDir, "mcp.json");
|
|
68
85
|
this.removeMcpServer(mcpPath);
|
|
69
|
-
console.log(` ${output_1.pc.dim("→")} ${cursorColor("[cursor]")} removed hooks, skill, rule, and MCP`);
|
|
70
|
-
console.log();
|
|
71
|
-
console.log(` ${output_1.pc.yellow("⚠")} Restart Cursor to apply changes`);
|
|
72
86
|
}
|
|
73
87
|
runVerifyGate(projectDir) {
|
|
74
88
|
(0, verify_gate_1.run)(projectDir);
|
|
@@ -85,6 +99,9 @@ class CursorClient {
|
|
|
85
99
|
runRequireVerdict(projectDir) {
|
|
86
100
|
(0, require_verdict_1.run)(projectDir);
|
|
87
101
|
}
|
|
102
|
+
runRequireVerification(projectDir) {
|
|
103
|
+
(0, require_verification_1.run)(projectDir);
|
|
104
|
+
}
|
|
88
105
|
isIronBeeHook(entry) {
|
|
89
106
|
return entry.command.includes(IRONBEE_HOOK_MARKER);
|
|
90
107
|
}
|
|
@@ -113,10 +130,16 @@ class CursorClient {
|
|
|
113
130
|
config.hooks.sessionStart.push({
|
|
114
131
|
command: `ironbee hook session-start --client cursor`,
|
|
115
132
|
});
|
|
116
|
-
// ── preToolUse — block
|
|
133
|
+
// ── preToolUse — block browser tools if no active verification ──
|
|
117
134
|
if (!config.hooks.preToolUse) {
|
|
118
135
|
config.hooks.preToolUse = [];
|
|
119
136
|
}
|
|
137
|
+
config.hooks.preToolUse.push({
|
|
138
|
+
command: `ironbee hook require-verification --client cursor`,
|
|
139
|
+
matcher: "MCP:bdt_.*",
|
|
140
|
+
failClosed: true,
|
|
141
|
+
});
|
|
142
|
+
// ── preToolUse — block edits if browser tools used without verdict ──
|
|
120
143
|
config.hooks.preToolUse.push({
|
|
121
144
|
command: `ironbee hook require-verdict --client cursor`,
|
|
122
145
|
matcher: "Write",
|
|
@@ -135,7 +158,7 @@ class CursorClient {
|
|
|
135
158
|
}
|
|
136
159
|
config.hooks.postToolUse.push({
|
|
137
160
|
command: `ironbee hook track-action --client cursor`,
|
|
138
|
-
matcher: "MCP
|
|
161
|
+
matcher: "MCP:bdt_.*",
|
|
139
162
|
});
|
|
140
163
|
// ── stop — verify-gate, forces re-verification via followup_message ──
|
|
141
164
|
if (!config.hooks.stop) {
|
|
@@ -204,6 +227,8 @@ class CursorClient {
|
|
|
204
227
|
args: ["-y", MCP_SERVER_PACKAGE],
|
|
205
228
|
env: {
|
|
206
229
|
BROWSER_DEVTOOLS_INSTALL_CHROMIUM: "true",
|
|
230
|
+
TOOL_NAME_PREFIX: "bdt_",
|
|
231
|
+
TOOL_INPUT_METADATA_ENABLE: "true",
|
|
207
232
|
},
|
|
208
233
|
};
|
|
209
234
|
(0, fs_1.writeFileSync)(mcpPath, JSON.stringify(config, null, 2));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/clients/cursor/index.ts"],"names":[],"mappings":";;;AAAA,2BAAoF;AACpF,+BAA4B;AAE5B,6CAA0C;AAC1C,6CAA8C;AAC9C,qDAA+D;AAC/D,yDAAmE;AACnE,uDAAiE;AACjE,yDAAmE;AACnE,6DAAuE;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/clients/cursor/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,15 +15,17 @@ If the application is already running, skip the start step. If the build fails,
|
|
|
15
15
|
|
|
16
16
|
Required verification steps:
|
|
17
17
|
1. Build and start the application if not already running
|
|
18
|
-
2.
|
|
19
|
-
3.
|
|
20
|
-
4.
|
|
21
|
-
5.
|
|
22
|
-
6. Check
|
|
23
|
-
7.
|
|
24
|
-
8.
|
|
18
|
+
2. **Start verification**: `echo '{"session_id":"<your-session-id>"}' | ironbee hook verification-start` — REQUIRED before browser tools
|
|
19
|
+
3. Navigate to affected page(s) with `mcp__browser-devtools__bdt_navigation_go-to`
|
|
20
|
+
4. **Functionally test** the changes — click, type, submit, navigate, interact with the UI to exercise the code paths you modified
|
|
21
|
+
5. Take a screenshot with `mcp__browser-devtools__bdt_content_take-screenshot` to capture the final state
|
|
22
|
+
6. Check accessibility with `mcp__browser-devtools__bdt_a11y_take-aria-snapshot`
|
|
23
|
+
7. Check console for errors with `mcp__browser-devtools__bdt_o11y_get-console-messages`
|
|
24
|
+
8. Stop the dev server when done
|
|
25
|
+
9. **IMMEDIATELY submit your verdict** — do NOT edit any code before submitting: `echo '<verdict-json>' | ironbee hook submit-verdict`
|
|
25
26
|
- Pass → submit pass verdict
|
|
26
27
|
- Fail → submit fail verdict with issues, THEN fix the code and re-verify
|
|
28
|
+
- Submitting a verdict automatically ends the verification cycle
|
|
27
29
|
|
|
28
30
|
Steps 2, 4, 5, and 6 are checked by the stop hook. Step 3 is expected — do not just take a screenshot and call it done.
|
|
29
31
|
|
|
@@ -28,19 +28,22 @@ If the application is already running, skip the start step. If the build fails,
|
|
|
28
28
|
## Flow
|
|
29
29
|
1. Implement your changes (write/edit code)
|
|
30
30
|
2. **Build and start** the application if not already running
|
|
31
|
-
3. **
|
|
32
|
-
-
|
|
31
|
+
3. **Start verification**: `echo '{"session_id":"<your-session-id>"}' | ironbee hook verification-start`
|
|
32
|
+
- This is REQUIRED before using any browser-devtools tools. Browser tools are blocked without it.
|
|
33
|
+
4. **Functionally test** your changes through the browser:
|
|
34
|
+
- **Navigate**: `mcp__browser-devtools__bdt_navigation_go-to` — go to the affected page(s)
|
|
33
35
|
- **Interact**: Use the browser agent to **actually test** what you changed — click buttons, fill forms, submit data, trigger workflows, navigate between pages. Do not just look at the page.
|
|
34
|
-
- **Screenshot**: `mcp__browser-
|
|
35
|
-
- **Accessibility**: `mcp__browser-
|
|
36
|
-
- **Console**: `mcp__browser-
|
|
36
|
+
- **Screenshot**: `mcp__browser-devtools__bdt_content_take-screenshot` — capture the final visual state
|
|
37
|
+
- **Accessibility**: `mcp__browser-devtools__bdt_a11y_take-aria-snapshot` — verify page structure
|
|
38
|
+
- **Console**: `mcp__browser-devtools__bdt_o11y_get-console-messages` — check for errors
|
|
37
39
|
Navigate, Screenshot, Accessibility, and Console tools are MANDATORY. Functional interaction is expected for every verification.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
5. **Stop** the dev server when verification is complete
|
|
41
|
+
6. **IMMEDIATELY submit your verdict** — do NOT edit any code before submitting: `echo '<verdict-json>' | ironbee hook submit-verdict`
|
|
40
42
|
- If everything works → submit pass verdict
|
|
41
43
|
- If something is broken → submit fail verdict with issues describing what failed
|
|
42
44
|
- **Never skip this step.** Every verification attempt must be recorded, pass or fail.
|
|
43
|
-
|
|
45
|
+
- Submitting a verdict automatically ends the verification cycle.
|
|
46
|
+
7. If you submitted a fail verdict → fix the code → rebuild → go back to step 2 → submit again → repeat until pass
|
|
44
47
|
|
|
45
48
|
## What good verification looks like
|
|
46
49
|
- Changed a form handler? → Start the app, fill the form, submit it, verify the response
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze.d.ts","sourceRoot":"","sources":["../../src/commands/analyze.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwSpC,eAAO,MAAM,cAAc,EAAE,OA2CvB,CAAC"}
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.analyzeCommand = void 0;
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const output_1 = require("../lib/output");
|
|
7
|
+
const time_analysis_1 = require("../analysis/time-analysis");
|
|
8
|
+
const verification_quality_1 = require("../analysis/verification-quality");
|
|
9
|
+
const code_changes_1 = require("../analysis/code-changes");
|
|
10
|
+
const fix_effectiveness_1 = require("../analysis/fix-effectiveness");
|
|
11
|
+
const scoring_1 = require("../analysis/scoring");
|
|
12
|
+
const cross_session_1 = require("../analysis/cross-session");
|
|
13
|
+
const verdict_details_1 = require("../analysis/verdict-details");
|
|
14
|
+
function formatDuration(ms) {
|
|
15
|
+
if (ms < 1000) {
|
|
16
|
+
return "0s";
|
|
17
|
+
}
|
|
18
|
+
const totalSeconds = Math.floor(ms / 1000);
|
|
19
|
+
const hours = Math.floor(totalSeconds / 3600);
|
|
20
|
+
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
|
21
|
+
const seconds = totalSeconds % 60;
|
|
22
|
+
if (hours > 0) {
|
|
23
|
+
return `${hours}h ${minutes}m`;
|
|
24
|
+
}
|
|
25
|
+
if (minutes > 0) {
|
|
26
|
+
return `${minutes}m ${seconds.toString().padStart(2, "0")}s`;
|
|
27
|
+
}
|
|
28
|
+
return `${seconds}s`;
|
|
29
|
+
}
|
|
30
|
+
function bar(percent, width = 20) {
|
|
31
|
+
const filled = Math.round(percent / 100 * width);
|
|
32
|
+
const empty = width - filled;
|
|
33
|
+
return `${"█".repeat(filled)}${"░".repeat(empty)}`;
|
|
34
|
+
}
|
|
35
|
+
function scoreColor(score, max = 100) {
|
|
36
|
+
const pct = max === 1 ? score * 100 : (score / max) * 100;
|
|
37
|
+
if (pct >= 80) {
|
|
38
|
+
return (s) => output_1.pc.bold(output_1.pc.green(s));
|
|
39
|
+
}
|
|
40
|
+
if (pct >= 50) {
|
|
41
|
+
return (s) => output_1.pc.yellow(s);
|
|
42
|
+
}
|
|
43
|
+
return (s) => output_1.pc.red(s);
|
|
44
|
+
}
|
|
45
|
+
function rateColor(rate) {
|
|
46
|
+
if (rate >= 80) {
|
|
47
|
+
return (s) => output_1.pc.green(s);
|
|
48
|
+
}
|
|
49
|
+
if (rate >= 50) {
|
|
50
|
+
return (s) => output_1.pc.yellow(s);
|
|
51
|
+
}
|
|
52
|
+
return (s) => output_1.pc.red(s);
|
|
53
|
+
}
|
|
54
|
+
function shortPath(filePath) {
|
|
55
|
+
const parts = filePath.split("/");
|
|
56
|
+
if (parts.length <= 3) {
|
|
57
|
+
return filePath;
|
|
58
|
+
}
|
|
59
|
+
return ".../" + parts.slice(-3).join("/");
|
|
60
|
+
}
|
|
61
|
+
function section(title, emoji) {
|
|
62
|
+
console.log();
|
|
63
|
+
console.log(` ${emoji} ${output_1.pc.bold(output_1.pc.underline(title))}`);
|
|
64
|
+
}
|
|
65
|
+
// ── Cross-Session Output ─────────────────────────────────
|
|
66
|
+
function printCrossSessionAnalysis(analysis, projectDir, opts) {
|
|
67
|
+
console.log();
|
|
68
|
+
console.log(` ${output_1.pc.bold("📊 Project Analysis")} ${output_1.pc.dim(`(${analysis.totalSessions} session${analysis.totalSessions !== 1 ? "s" : ""})`)}`);
|
|
69
|
+
// Session History
|
|
70
|
+
const displaySummaries = analysis.sessionSummaries.slice(0, 20);
|
|
71
|
+
if (displaySummaries.length > 0) {
|
|
72
|
+
section("Session History", "📋");
|
|
73
|
+
for (const s of displaySummaries) {
|
|
74
|
+
const dateStr = s.timestamp.slice(0, 10);
|
|
75
|
+
const durationStr = formatDuration(s.duration).padEnd(10);
|
|
76
|
+
const verifyStr = `${s.verificationCycles} verify`;
|
|
77
|
+
const fixStr = `${s.fixCycles} fix`;
|
|
78
|
+
const firstPassStr = s.lastVerdictStatus === "pass" ? output_1.pc.green("✓") : s.lastVerdictStatus === "fail" ? output_1.pc.red("✗") : output_1.pc.dim("—");
|
|
79
|
+
const scoreVal = s.agentEfficiencyScore;
|
|
80
|
+
const color = scoreColor(scoreVal);
|
|
81
|
+
const idShort = s.sessionId.length > 12 ? s.sessionId.slice(0, 12) : s.sessionId;
|
|
82
|
+
console.log(` ${firstPassStr} ${output_1.pc.cyan(idShort.padEnd(14))} ${output_1.pc.dim(dateStr)} ${durationStr} ${verifyStr.padEnd(10)} ${fixStr.padEnd(8)} ${color(`${scoreVal}pts`)}`);
|
|
83
|
+
}
|
|
84
|
+
if (analysis.sessionSummaries.length > 20) {
|
|
85
|
+
console.log(` ${output_1.pc.dim(`... and ${analysis.sessionSummaries.length - 20} more`)}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Aggregate Metrics
|
|
89
|
+
section("Aggregate Metrics", "📈");
|
|
90
|
+
console.log(` ${"Avg duration".padEnd(18)} ${output_1.pc.cyan(formatDuration(analysis.averageSessionDuration))}`);
|
|
91
|
+
console.log(` ${"Avg verifies".padEnd(18)} ${output_1.pc.cyan(String(analysis.averageVerificationCycles))}`);
|
|
92
|
+
console.log(` ${"Avg fixes".padEnd(18)} ${output_1.pc.cyan(String(analysis.averageFixCycles))}`);
|
|
93
|
+
console.log(` ${"First-pass".padEnd(18)} ${rateColor(analysis.aggregateFirstPassRate)(`${analysis.aggregateFirstPassRate}%`.padEnd(8))} ${output_1.pc.dim(bar(analysis.aggregateFirstPassRate))}`);
|
|
94
|
+
console.log(` ${"Fix success".padEnd(18)} ${rateColor(analysis.aggregateFixSuccessRate)(`${analysis.aggregateFixSuccessRate}%`.padEnd(8))} ${output_1.pc.dim(bar(analysis.aggregateFixSuccessRate))}`);
|
|
95
|
+
console.log(` ${"Abandon rate".padEnd(18)} ${output_1.pc.dim(`${analysis.abandonRate}%`)}`);
|
|
96
|
+
// Scores
|
|
97
|
+
section("Scores", "🏆");
|
|
98
|
+
console.log(` ${"Efficiency".padEnd(18)} ${scoreColor(analysis.averageEfficiencyScore)(`${analysis.averageEfficiencyScore}%`.padEnd(8))} ${output_1.pc.dim(bar(analysis.averageEfficiencyScore))}`);
|
|
99
|
+
console.log(` ${"Confidence".padEnd(18)} ${scoreColor(analysis.averageCodeConfidence)(`${analysis.averageCodeConfidence}%`.padEnd(8))} ${output_1.pc.dim(bar(analysis.averageCodeConfidence))}`);
|
|
100
|
+
// Most Problematic Files
|
|
101
|
+
if (analysis.mostProblematicFiles.length > 0) {
|
|
102
|
+
section("Problematic Files", "🔥");
|
|
103
|
+
for (const f of analysis.mostProblematicFiles) {
|
|
104
|
+
const label = shortPath(f.filePath);
|
|
105
|
+
console.log(` ${output_1.pc.red("●")} ${label.padEnd(40)} ${output_1.pc.dim(`${f.fixEditCount} fix edit${f.fixEditCount !== 1 ? "s" : ""}`)}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Verdict Details (--detailed)
|
|
109
|
+
if (opts.detailed) {
|
|
110
|
+
section("All Verdict Details", "📋");
|
|
111
|
+
for (const s of analysis.sessionSummaries) {
|
|
112
|
+
const actionsFile = (0, path_1.join)(projectDir, ".ironbee", "sessions", s.sessionId, "actions.jsonl");
|
|
113
|
+
const details = (0, verdict_details_1.extractVerdictDetails)(actionsFile);
|
|
114
|
+
if (details && details.verdicts.length > 0) {
|
|
115
|
+
const idShort = s.sessionId.length > 12 ? s.sessionId.slice(0, 12) : s.sessionId;
|
|
116
|
+
console.log();
|
|
117
|
+
console.log(` ${output_1.pc.bold(output_1.pc.cyan(idShort))} ${output_1.pc.dim(s.timestamp.slice(0, 10))}`);
|
|
118
|
+
for (let i = 0; i < details.verdicts.length; i++) {
|
|
119
|
+
const v = details.verdicts[i];
|
|
120
|
+
const statusIcon = v.status === "pass" ? output_1.pc.green("✓") : output_1.pc.red("✗");
|
|
121
|
+
console.log(` ${statusIcon} ${output_1.pc.bold(`#${i + 1}`)} ${v.status === "pass" ? output_1.pc.green(v.status) : output_1.pc.red(v.status)}`);
|
|
122
|
+
if (v.issues.length > 0) {
|
|
123
|
+
console.log(` ${"Issues".padEnd(8)} ${output_1.pc.red(v.issues.join(", "))}`);
|
|
124
|
+
}
|
|
125
|
+
if (v.fixes.length > 0) {
|
|
126
|
+
console.log(` ${"Fixes".padEnd(8)} ${output_1.pc.green(v.fixes.join(", "))}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
console.log();
|
|
133
|
+
}
|
|
134
|
+
// ── Single-Session Output ────────────────────────────────
|
|
135
|
+
function runSingleSessionAnalysis(sessionId, projectDir, opts) {
|
|
136
|
+
const actionsFile = (0, path_1.join)(projectDir, ".ironbee", "sessions", sessionId, "actions.jsonl");
|
|
137
|
+
const result = (0, time_analysis_1.analyzeTime)(actionsFile);
|
|
138
|
+
const qualityResult = (0, verification_quality_1.analyzeVerificationQuality)(actionsFile);
|
|
139
|
+
const codeChanges = (0, code_changes_1.analyzeCodeChanges)(actionsFile);
|
|
140
|
+
const fixEffectiveness = (0, fix_effectiveness_1.analyzeFixEffectiveness)(actionsFile);
|
|
141
|
+
const scoring = (0, scoring_1.calculateScoring)(result, qualityResult);
|
|
142
|
+
if (result === null && qualityResult === null && codeChanges === null && fixEffectiveness === null) {
|
|
143
|
+
output_1.log.warn("No analyzable session data found.");
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
if (opts.json) {
|
|
147
|
+
const output = { ...result, ...qualityResult, ...codeChanges, ...fixEffectiveness, ...scoring };
|
|
148
|
+
if (opts.detailed) {
|
|
149
|
+
const details = (0, verdict_details_1.extractVerdictDetails)(actionsFile);
|
|
150
|
+
if (details) {
|
|
151
|
+
output.verdicts = details.verdicts;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
console.log(JSON.stringify(output, null, 2));
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (result !== null) {
|
|
158
|
+
console.log();
|
|
159
|
+
console.log(` 📊 ${output_1.pc.bold("Session:")} ${output_1.pc.cyan(sessionId)}`);
|
|
160
|
+
console.log(` ${output_1.pc.bold("Duration:")} ${output_1.pc.cyan(formatDuration(result.sessionDuration))}`);
|
|
161
|
+
section("Phase Distribution", "⏱️");
|
|
162
|
+
const codingBar = bar(result.codingPercent);
|
|
163
|
+
const verifyBar = bar(result.verificationPercent);
|
|
164
|
+
const fixBar = bar(result.fixPercent);
|
|
165
|
+
console.log(` ${"Coding".padEnd(18)} ${output_1.pc.cyan(formatDuration(result.codingTime).padEnd(10))} ${output_1.pc.green(codingBar)} ${output_1.pc.dim(`${result.codingPercent}%`)}`);
|
|
166
|
+
console.log(` ${"Verification".padEnd(18)} ${output_1.pc.cyan(formatDuration(result.verificationTime).padEnd(10))} ${output_1.pc.blue(verifyBar)} ${output_1.pc.dim(`${result.verificationPercent}%`)}`);
|
|
167
|
+
console.log(` ${"Fixing".padEnd(18)} ${output_1.pc.cyan(formatDuration(result.fixTime).padEnd(10))} ${output_1.pc.yellow(fixBar)} ${output_1.pc.dim(`${result.fixPercent}%`)}`);
|
|
168
|
+
section("Cycles", "🔄");
|
|
169
|
+
console.log(` ${"Verifications".padEnd(18)} ${output_1.pc.cyan(String(result.verificationCycles))}`);
|
|
170
|
+
console.log(` ${"Fixes".padEnd(18)} ${output_1.pc.cyan(String(result.fixCycles))}`);
|
|
171
|
+
console.log(` ${"Avg verify".padEnd(18)} ${result.averageVerificationDuration !== null ? output_1.pc.cyan(formatDuration(result.averageVerificationDuration)) : output_1.pc.dim("n/a")}`);
|
|
172
|
+
console.log(` ${"Avg fix".padEnd(18)} ${result.averageFixDuration !== null ? output_1.pc.cyan(formatDuration(result.averageFixDuration)) : output_1.pc.dim("n/a")}`);
|
|
173
|
+
console.log(` ${"First verify".padEnd(18)} ${result.timeToFirstVerification !== null ? output_1.pc.cyan(formatDuration(result.timeToFirstVerification)) : output_1.pc.dim("n/a")}`);
|
|
174
|
+
}
|
|
175
|
+
if (qualityResult !== null) {
|
|
176
|
+
section("Verification Quality", "✅");
|
|
177
|
+
const passRate = `${qualityResult.firstPassSuccessRate}%`;
|
|
178
|
+
console.log(` ${"First-pass rate".padEnd(18)} ${rateColor(qualityResult.firstPassSuccessRate)(passRate.padEnd(8))} ${output_1.pc.dim(bar(qualityResult.firstPassSuccessRate))}`);
|
|
179
|
+
console.log(` ${"Verdicts".padEnd(18)} ${output_1.pc.cyan(String(qualityResult.totalVerifications).padEnd(8))} ${output_1.pc.dim(`(${output_1.pc.green(`${qualityResult.passCount} pass`)}, ${output_1.pc.red(`${qualityResult.failCount} fail`)})`)}`);
|
|
180
|
+
console.log(` ${"Avg retries".padEnd(18)} ${output_1.pc.cyan(String(qualityResult.averageRetries))}`);
|
|
181
|
+
console.log(` ${"Avg console errs".padEnd(18)} ${qualityResult.averageConsoleErrors > 0 ? output_1.pc.red(String(qualityResult.averageConsoleErrors)) : output_1.pc.green("0")}`);
|
|
182
|
+
console.log(` ${"Avg network fails".padEnd(18)} ${qualityResult.averageNetworkFailures > 0 ? output_1.pc.red(String(qualityResult.averageNetworkFailures)) : output_1.pc.green("0")}`);
|
|
183
|
+
console.log(` ${"Avg pages tested".padEnd(18)} ${output_1.pc.cyan(String(qualityResult.averagePagesTestedCount))}`);
|
|
184
|
+
console.log(` ${"Avg checks".padEnd(18)} ${output_1.pc.cyan(String(qualityResult.averageChecksCount))}`);
|
|
185
|
+
}
|
|
186
|
+
if (codeChanges !== null) {
|
|
187
|
+
section("Code Changes", "📝");
|
|
188
|
+
console.log(` ${"Total edits".padEnd(18)} ${output_1.pc.cyan(String(codeChanges.totalFileEdits))}`);
|
|
189
|
+
console.log(` ${"Unique files".padEnd(18)} ${output_1.pc.cyan(String(codeChanges.uniqueFilesEdited))}`);
|
|
190
|
+
console.log(` ${"Avg per verify".padEnd(18)} ${output_1.pc.cyan(String(codeChanges.filesEditedPerVerification))}`);
|
|
191
|
+
console.log(` ${"Avg per fix".padEnd(18)} ${output_1.pc.cyan(String(codeChanges.filesChangedPerFix))}`);
|
|
192
|
+
if (codeChanges.hotFiles.length > 0) {
|
|
193
|
+
console.log();
|
|
194
|
+
console.log(` ${output_1.pc.bold("🔥 Hot Files:")}`);
|
|
195
|
+
for (const f of codeChanges.hotFiles) {
|
|
196
|
+
const label = shortPath(f.filePath);
|
|
197
|
+
console.log(` ${output_1.pc.yellow("●")} ${label.padEnd(40)} ${output_1.pc.dim(`${f.editCount} edit${f.editCount !== 1 ? "s" : ""}`)}`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
if (codeChanges.problematicFiles.length > 0) {
|
|
201
|
+
console.log();
|
|
202
|
+
console.log(` ${output_1.pc.bold("⚠️ Problematic Files:")}`);
|
|
203
|
+
for (const f of codeChanges.problematicFiles) {
|
|
204
|
+
const label = shortPath(f.filePath);
|
|
205
|
+
console.log(` ${output_1.pc.red("●")} ${label.padEnd(40)} ${output_1.pc.dim(`${f.fixEditCount} fix edit${f.fixEditCount !== 1 ? "s" : ""}`)}`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
if (codeChanges.editChurnFiles.length > 0) {
|
|
209
|
+
console.log();
|
|
210
|
+
console.log(` ${output_1.pc.bold("🔁 Edit Churn")} ${output_1.pc.dim("(edited in 2+ fix cycles):")}`);
|
|
211
|
+
for (const filePath of codeChanges.editChurnFiles) {
|
|
212
|
+
console.log(` ${output_1.pc.red("●")} ${shortPath(filePath)}`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
if (fixEffectiveness !== null) {
|
|
217
|
+
section("Fix Effectiveness", "🔧");
|
|
218
|
+
console.log(` ${"Success rate".padEnd(18)} ${rateColor(fixEffectiveness.fixSuccessRate)(`${fixEffectiveness.fixSuccessRate}%`.padEnd(8))} ${output_1.pc.dim(bar(fixEffectiveness.fixSuccessRate))} ${output_1.pc.dim(`${fixEffectiveness.successfulFixes}/${fixEffectiveness.totalFixAttempts}`)}`);
|
|
219
|
+
const reFailStr = fixEffectiveness.reFailRate > 0 ? `${fixEffectiveness.reFailRate}%` : "0%";
|
|
220
|
+
const reFailColored = fixEffectiveness.reFailRate > 0 ? output_1.pc.red(reFailStr.padEnd(8)) : output_1.pc.green(reFailStr.padEnd(8));
|
|
221
|
+
console.log(` ${"Re-fail rate".padEnd(18)} ${reFailColored} ${output_1.pc.dim(bar(fixEffectiveness.reFailRate))} ${output_1.pc.dim(`${fixEffectiveness.failedFixes}/${fixEffectiveness.totalFixAttempts}`)}`);
|
|
222
|
+
console.log(` ${"Fix/verify".padEnd(18)} ${output_1.pc.cyan(String(fixEffectiveness.fixToVerifyRatio))}`);
|
|
223
|
+
}
|
|
224
|
+
if (scoring !== null) {
|
|
225
|
+
section("Scoring", "🏆");
|
|
226
|
+
console.log(` ${"Efficiency".padEnd(18)} ${scoreColor(scoring.agentEfficiencyScore)(`${scoring.agentEfficiencyScore}%`.padEnd(8))} ${output_1.pc.dim(bar(scoring.agentEfficiencyScore))}`);
|
|
227
|
+
console.log(` ${"Quality".padEnd(18)} ${scoreColor(scoring.verificationQualityScore)(`${scoring.verificationQualityScore}%`.padEnd(8))} ${output_1.pc.dim(bar(scoring.verificationQualityScore))}`);
|
|
228
|
+
console.log(` ${"Confidence".padEnd(18)} ${scoreColor(scoring.codeConfidenceScore)(`${scoring.codeConfidenceScore}%`.padEnd(8))} ${output_1.pc.dim(bar(scoring.codeConfidenceScore))}`);
|
|
229
|
+
}
|
|
230
|
+
if (opts.detailed) {
|
|
231
|
+
const details = (0, verdict_details_1.extractVerdictDetails)(actionsFile);
|
|
232
|
+
if (details) {
|
|
233
|
+
section("Verdict Details", "📋");
|
|
234
|
+
for (let i = 0; i < details.verdicts.length; i++) {
|
|
235
|
+
const v = details.verdicts[i];
|
|
236
|
+
const statusIcon = v.status === "pass" ? output_1.pc.green("✓") : output_1.pc.red("✗");
|
|
237
|
+
const dateStr = v.timestamp.slice(0, 19).replace("T", " ");
|
|
238
|
+
console.log(` ${statusIcon} ${output_1.pc.bold(`#${i + 1}`)} ${output_1.pc.dim(dateStr)} ${v.status === "pass" ? output_1.pc.green(v.status) : output_1.pc.red(v.status)}`);
|
|
239
|
+
if (v.pages_tested.length > 0) {
|
|
240
|
+
console.log(` ${"Pages".padEnd(10)} ${output_1.pc.cyan(v.pages_tested.join(", "))}`);
|
|
241
|
+
}
|
|
242
|
+
if (v.checks.length > 0) {
|
|
243
|
+
console.log(` ${"Checks".padEnd(10)} ${v.checks.join(", ")}`);
|
|
244
|
+
}
|
|
245
|
+
if (v.issues.length > 0) {
|
|
246
|
+
console.log(` ${"Issues".padEnd(10)} ${output_1.pc.red(v.issues.join(", "))}`);
|
|
247
|
+
}
|
|
248
|
+
if (v.fixes.length > 0) {
|
|
249
|
+
console.log(` ${"Fixes".padEnd(10)} ${output_1.pc.green(v.fixes.join(", "))}`);
|
|
250
|
+
}
|
|
251
|
+
if (v.console_errors > 0) {
|
|
252
|
+
console.log(` ${"Errors".padEnd(10)} ${output_1.pc.red(`${v.console_errors} console error${v.console_errors !== 1 ? "s" : ""}`)}`);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
console.log();
|
|
258
|
+
}
|
|
259
|
+
exports.analyzeCommand = new commander_1.Command("analyze")
|
|
260
|
+
.description("Analyze session metrics (single session or all sessions)")
|
|
261
|
+
.argument("[session-id]", "session ID to analyze (omit for cross-session analysis)")
|
|
262
|
+
.option("--project-dir <dir>", "project directory")
|
|
263
|
+
.option("--json", "output as JSON")
|
|
264
|
+
.option("--detailed", "include verdict details (checks, issues, fixes) for semantic analysis")
|
|
265
|
+
.option("--all", "analyze all sessions in the project")
|
|
266
|
+
.action((sessionId, opts) => {
|
|
267
|
+
const projectDir = (0, path_1.resolve)(opts.projectDir ?? ".");
|
|
268
|
+
// Cross-session mode: no session-id or --all flag
|
|
269
|
+
if (sessionId === undefined || opts.all === true) {
|
|
270
|
+
const sessionsDir = (0, path_1.join)(projectDir, ".ironbee", "sessions");
|
|
271
|
+
const crossResult = (0, cross_session_1.analyzeCrossSessions)(sessionsDir);
|
|
272
|
+
if (crossResult === null) {
|
|
273
|
+
output_1.log.warn("No sessions found to analyze.");
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
if (opts.json) {
|
|
277
|
+
const output = crossResult;
|
|
278
|
+
if (opts.detailed) {
|
|
279
|
+
const allVerdicts = [];
|
|
280
|
+
for (const s of crossResult.sessionSummaries) {
|
|
281
|
+
const actionsFile = (0, path_1.join)(projectDir, ".ironbee", "sessions", s.sessionId, "actions.jsonl");
|
|
282
|
+
const details = (0, verdict_details_1.extractVerdictDetails)(actionsFile);
|
|
283
|
+
if (details) {
|
|
284
|
+
allVerdicts.push({ sessionId: s.sessionId, verdicts: details.verdicts });
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
output.verdictDetails = allVerdicts;
|
|
288
|
+
}
|
|
289
|
+
console.log(JSON.stringify(output, null, 2));
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
printCrossSessionAnalysis(crossResult, projectDir, opts);
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
// Single-session mode
|
|
296
|
+
runSingleSessionAnalysis(sessionId, projectDir, opts);
|
|
297
|
+
});
|
|
298
|
+
//# sourceMappingURL=analyze.js.map
|