@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.
Files changed (134) hide show
  1. package/CHANGELOG.md +31 -3
  2. package/README.md +118 -3
  3. package/dist/analysis/code-changes.d.ts +22 -0
  4. package/dist/analysis/code-changes.d.ts.map +1 -0
  5. package/dist/analysis/code-changes.js +141 -0
  6. package/dist/analysis/code-changes.js.map +1 -0
  7. package/dist/analysis/cross-session.d.ts +34 -0
  8. package/dist/analysis/cross-session.d.ts.map +1 -0
  9. package/dist/analysis/cross-session.js +230 -0
  10. package/dist/analysis/cross-session.js.map +1 -0
  11. package/dist/analysis/fix-effectiveness.d.ts +16 -0
  12. package/dist/analysis/fix-effectiveness.d.ts.map +1 -0
  13. package/dist/analysis/fix-effectiveness.js +99 -0
  14. package/dist/analysis/fix-effectiveness.js.map +1 -0
  15. package/dist/analysis/scoring.d.ts +15 -0
  16. package/dist/analysis/scoring.d.ts.map +1 -0
  17. package/dist/analysis/scoring.js +57 -0
  18. package/dist/analysis/scoring.js.map +1 -0
  19. package/dist/analysis/time-analysis.d.ts +22 -0
  20. package/dist/analysis/time-analysis.d.ts.map +1 -0
  21. package/dist/analysis/time-analysis.js +174 -0
  22. package/dist/analysis/time-analysis.js.map +1 -0
  23. package/dist/analysis/verdict-details.d.ts +23 -0
  24. package/dist/analysis/verdict-details.d.ts.map +1 -0
  25. package/dist/analysis/verdict-details.js +59 -0
  26. package/dist/analysis/verdict-details.js.map +1 -0
  27. package/dist/analysis/verification-quality.d.ts +19 -0
  28. package/dist/analysis/verification-quality.d.ts.map +1 -0
  29. package/dist/analysis/verification-quality.js +182 -0
  30. package/dist/analysis/verification-quality.js.map +1 -0
  31. package/dist/clients/base.d.ts +2 -0
  32. package/dist/clients/base.d.ts.map +1 -1
  33. package/dist/clients/claude/commands/ironbee-analyze.md +42 -0
  34. package/dist/clients/claude/hooks/clear-verdict.js +1 -1
  35. package/dist/clients/claude/hooks/clear-verdict.js.map +1 -1
  36. package/dist/clients/claude/hooks/require-verification.d.ts +15 -0
  37. package/dist/clients/claude/hooks/require-verification.d.ts.map +1 -0
  38. package/dist/clients/claude/hooks/require-verification.js +61 -0
  39. package/dist/clients/claude/hooks/require-verification.js.map +1 -0
  40. package/dist/clients/claude/hooks/session-start.d.ts +1 -1
  41. package/dist/clients/claude/hooks/session-start.d.ts.map +1 -1
  42. package/dist/clients/claude/hooks/session-start.js +10 -1
  43. package/dist/clients/claude/hooks/session-start.js.map +1 -1
  44. package/dist/clients/claude/hooks/track-action.d.ts +1 -1
  45. package/dist/clients/claude/hooks/track-action.d.ts.map +1 -1
  46. package/dist/clients/claude/hooks/track-action.js +58 -13
  47. package/dist/clients/claude/hooks/track-action.js.map +1 -1
  48. package/dist/clients/claude/hooks/verify-gate.d.ts +1 -1
  49. package/dist/clients/claude/hooks/verify-gate.d.ts.map +1 -1
  50. package/dist/clients/claude/hooks/verify-gate.js +3 -3
  51. package/dist/clients/claude/hooks/verify-gate.js.map +1 -1
  52. package/dist/clients/claude/index.d.ts +2 -0
  53. package/dist/clients/claude/index.d.ts.map +1 -1
  54. package/dist/clients/claude/index.js +43 -9
  55. package/dist/clients/claude/index.js.map +1 -1
  56. package/dist/clients/claude/rule.md +9 -7
  57. package/dist/clients/claude/skill.md +11 -8
  58. package/dist/clients/claude/skills/ironbee-analyze.md +39 -0
  59. package/dist/clients/cursor/commands/ironbee-analyze/SKILL.md +48 -0
  60. package/dist/clients/cursor/hooks/clear-verdict.js +1 -1
  61. package/dist/clients/cursor/hooks/clear-verdict.js.map +1 -1
  62. package/dist/clients/cursor/hooks/require-verification.d.ts +15 -0
  63. package/dist/clients/cursor/hooks/require-verification.d.ts.map +1 -0
  64. package/dist/clients/cursor/hooks/require-verification.js +63 -0
  65. package/dist/clients/cursor/hooks/require-verification.js.map +1 -0
  66. package/dist/clients/cursor/hooks/session-start.d.ts +1 -1
  67. package/dist/clients/cursor/hooks/session-start.d.ts.map +1 -1
  68. package/dist/clients/cursor/hooks/session-start.js +6 -1
  69. package/dist/clients/cursor/hooks/session-start.js.map +1 -1
  70. package/dist/clients/cursor/hooks/track-action.d.ts.map +1 -1
  71. package/dist/clients/cursor/hooks/track-action.js +62 -12
  72. package/dist/clients/cursor/hooks/track-action.js.map +1 -1
  73. package/dist/clients/cursor/hooks/verify-gate.d.ts +1 -1
  74. package/dist/clients/cursor/hooks/verify-gate.d.ts.map +1 -1
  75. package/dist/clients/cursor/hooks/verify-gate.js +3 -3
  76. package/dist/clients/cursor/hooks/verify-gate.js.map +1 -1
  77. package/dist/clients/cursor/index.d.ts +2 -0
  78. package/dist/clients/cursor/index.d.ts.map +1 -1
  79. package/dist/clients/cursor/index.js +31 -6
  80. package/dist/clients/cursor/index.js.map +1 -1
  81. package/dist/clients/cursor/rule.md +9 -7
  82. package/dist/clients/cursor/skill.md +11 -8
  83. package/dist/commands/analyze.d.ts +3 -0
  84. package/dist/commands/analyze.d.ts.map +1 -0
  85. package/dist/commands/analyze.js +298 -0
  86. package/dist/commands/analyze.js.map +1 -0
  87. package/dist/commands/hook.d.ts.map +1 -1
  88. package/dist/commands/hook.js +81 -2
  89. package/dist/commands/hook.js.map +1 -1
  90. package/dist/commands/install.d.ts.map +1 -1
  91. package/dist/commands/install.js +3 -1
  92. package/dist/commands/install.js.map +1 -1
  93. package/dist/commands/uninstall.d.ts.map +1 -1
  94. package/dist/commands/uninstall.js +3 -1
  95. package/dist/commands/uninstall.js.map +1 -1
  96. package/dist/hooks/core/actions.d.ts +19 -0
  97. package/dist/hooks/core/actions.d.ts.map +1 -1
  98. package/dist/hooks/core/actions.js +5 -0
  99. package/dist/hooks/core/actions.js.map +1 -1
  100. package/dist/hooks/core/clear-verdict.d.ts +1 -1
  101. package/dist/hooks/core/clear-verdict.d.ts.map +1 -1
  102. package/dist/hooks/core/clear-verdict.js +13 -9
  103. package/dist/hooks/core/clear-verdict.js.map +1 -1
  104. package/dist/hooks/core/session-state.d.ts +47 -0
  105. package/dist/hooks/core/session-state.d.ts.map +1 -0
  106. package/dist/hooks/core/session-state.js +192 -0
  107. package/dist/hooks/core/session-state.js.map +1 -0
  108. package/dist/hooks/core/submit-verdict.d.ts +2 -1
  109. package/dist/hooks/core/submit-verdict.d.ts.map +1 -1
  110. package/dist/hooks/core/submit-verdict.js +38 -28
  111. package/dist/hooks/core/submit-verdict.js.map +1 -1
  112. package/dist/hooks/core/verification-lifecycle.d.ts +30 -0
  113. package/dist/hooks/core/verification-lifecycle.d.ts.map +1 -0
  114. package/dist/hooks/core/verification-lifecycle.js +75 -0
  115. package/dist/hooks/core/verification-lifecycle.js.map +1 -0
  116. package/dist/hooks/core/verify-gate.d.ts +2 -2
  117. package/dist/hooks/core/verify-gate.d.ts.map +1 -1
  118. package/dist/hooks/core/verify-gate.js +28 -33
  119. package/dist/hooks/core/verify-gate.js.map +1 -1
  120. package/dist/index.js +3 -0
  121. package/dist/index.js.map +1 -1
  122. package/dist/lib/telemetry.d.ts +23 -0
  123. package/dist/lib/telemetry.d.ts.map +1 -0
  124. package/dist/lib/telemetry.js +265 -0
  125. package/dist/lib/telemetry.js.map +1 -0
  126. package/dist/scripts/postinstall.d.ts +7 -0
  127. package/dist/scripts/postinstall.d.ts.map +1 -0
  128. package/dist/scripts/postinstall.js +12 -0
  129. package/dist/scripts/postinstall.js.map +1 -0
  130. package/dist/scripts/preuninstall.d.ts +8 -0
  131. package/dist/scripts/preuninstall.d.ts.map +1 -0
  132. package/dist/scripts/preuninstall.js +13 -0
  133. package/dist/scripts/preuninstall.js.map +1 -0
  134. 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,wBAAgB,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAkC5C"}
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;AAc/C,SAAgB,GAAG,CAAC,UAAkB;IAClC,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,IAAA,2BAAa,EAAC;QAC3C,SAAS;QACT,WAAW,EAAE,GAAG,UAAU,sBAAsB,SAAS,gBAAgB;QACzE,WAAW,EAAE,GAAG,UAAU,sBAAsB,SAAS,eAAe;QACxE,SAAS,EAAE,GAAG,UAAU,sBAAsB,SAAS,UAAU;QACjE,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"}
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;AAwClC,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;IAiCjC,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAsBnC,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;IAIlD,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,gBAAgB;IAqExB,OAAO,CAAC,kBAAkB;IAuB1B,OAAO,CAAC,eAAe;IAgBvB,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,cAAc;CAyBzB"}
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 rule files
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 edits if browser tools used without verdict ──
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":"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"}
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. Navigate to affected page(s) with `mcp__browser-devtools__navigation_go-to`
19
- 3. **Functionally test** the changes — click, type, submit, navigate, interact with the UI to exercise the code paths you modified
20
- 4. Take a screenshot with `mcp__browser-devtools__content_take-screenshot` to capture the final state
21
- 5. Check accessibility with `mcp__browser-devtools__a11y_take-aria-snapshot`
22
- 6. Check console for errors with `mcp__browser-devtools__o11y_get-console-messages`
23
- 7. Stop the dev server when done
24
- 8. **IMMEDIATELY submit your verdict** do NOT edit any code before submitting: `echo '<verdict-json>' | ironbee hook submit-verdict`
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. **Functionally test** your changes through the browser:
32
- - **Navigate**: `mcp__browser-devtools__navigation_go-to` go to the affected page(s)
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-devtools__content_take-screenshot` — capture the final visual state
35
- - **Accessibility**: `mcp__browser-devtools__a11y_take-aria-snapshot` — verify page structure
36
- - **Console**: `mcp__browser-devtools__o11y_get-console-messages` — check for errors
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
- 4. **Stop** the dev server when verification is complete
39
- 5. **IMMEDIATELY submit your verdict** — do NOT edit any code before submitting: `echo '<verdict-json>' | ironbee hook submit-verdict`
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
- 6. If you submitted a fail verdict fix the code → rebuild → go back to step 2 → submit again → repeat until pass
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,3 @@
1
+ import { Command } from "commander";
2
+ export declare const analyzeCommand: Command;
3
+ //# sourceMappingURL=analyze.d.ts.map
@@ -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