@ironbee-ai/cli 0.3.0 → 0.4.1

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 (116) hide show
  1. package/CHANGELOG.md +19 -8
  2. package/README.md +163 -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/commands/ironbee-verify.md +127 -0
  35. package/dist/clients/claude/hooks/clear-verdict.js +1 -1
  36. package/dist/clients/claude/hooks/clear-verdict.js.map +1 -1
  37. package/dist/clients/claude/hooks/require-verification.d.ts +15 -0
  38. package/dist/clients/claude/hooks/require-verification.d.ts.map +1 -0
  39. package/dist/clients/claude/hooks/require-verification.js +63 -0
  40. package/dist/clients/claude/hooks/require-verification.js.map +1 -0
  41. package/dist/clients/claude/hooks/session-start.d.ts.map +1 -1
  42. package/dist/clients/claude/hooks/session-start.js +7 -0
  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.js +1 -1
  49. package/dist/clients/claude/hooks/verify-gate.js.map +1 -1
  50. package/dist/clients/claude/index.d.ts +2 -0
  51. package/dist/clients/claude/index.d.ts.map +1 -1
  52. package/dist/clients/claude/index.js +51 -19
  53. package/dist/clients/claude/index.js.map +1 -1
  54. package/dist/clients/claude/rule.md +10 -7
  55. package/dist/clients/claude/skill.md +13 -8
  56. package/dist/clients/claude/skills/ironbee-analyze.md +39 -0
  57. package/dist/clients/cursor/commands/ironbee-analyze/SKILL.md +48 -0
  58. package/dist/clients/cursor/commands/ironbee-verify/SKILL.md +133 -0
  59. package/dist/clients/cursor/hooks/clear-verdict.js +1 -1
  60. package/dist/clients/cursor/hooks/clear-verdict.js.map +1 -1
  61. package/dist/clients/cursor/hooks/require-verification.d.ts +15 -0
  62. package/dist/clients/cursor/hooks/require-verification.d.ts.map +1 -0
  63. package/dist/clients/cursor/hooks/require-verification.js +65 -0
  64. package/dist/clients/cursor/hooks/require-verification.js.map +1 -0
  65. package/dist/clients/cursor/hooks/session-start.d.ts.map +1 -1
  66. package/dist/clients/cursor/hooks/session-start.js +3 -0
  67. package/dist/clients/cursor/hooks/session-start.js.map +1 -1
  68. package/dist/clients/cursor/hooks/track-action.d.ts.map +1 -1
  69. package/dist/clients/cursor/hooks/track-action.js +62 -12
  70. package/dist/clients/cursor/hooks/track-action.js.map +1 -1
  71. package/dist/clients/cursor/hooks/verify-gate.js +1 -1
  72. package/dist/clients/cursor/hooks/verify-gate.js.map +1 -1
  73. package/dist/clients/cursor/index.d.ts +2 -0
  74. package/dist/clients/cursor/index.d.ts.map +1 -1
  75. package/dist/clients/cursor/index.js +41 -16
  76. package/dist/clients/cursor/index.js.map +1 -1
  77. package/dist/clients/cursor/rule.md +10 -7
  78. package/dist/clients/cursor/skill.md +13 -8
  79. package/dist/commands/analyze.d.ts +3 -0
  80. package/dist/commands/analyze.d.ts.map +1 -0
  81. package/dist/commands/analyze.js +298 -0
  82. package/dist/commands/analyze.js.map +1 -0
  83. package/dist/commands/hook.d.ts.map +1 -1
  84. package/dist/commands/hook.js +79 -0
  85. package/dist/commands/hook.js.map +1 -1
  86. package/dist/hooks/core/actions.d.ts +19 -0
  87. package/dist/hooks/core/actions.d.ts.map +1 -1
  88. package/dist/hooks/core/actions.js +5 -0
  89. package/dist/hooks/core/actions.js.map +1 -1
  90. package/dist/hooks/core/clear-verdict.d.ts +1 -1
  91. package/dist/hooks/core/clear-verdict.d.ts.map +1 -1
  92. package/dist/hooks/core/clear-verdict.js +13 -9
  93. package/dist/hooks/core/clear-verdict.js.map +1 -1
  94. package/dist/hooks/core/session-state.d.ts +47 -0
  95. package/dist/hooks/core/session-state.d.ts.map +1 -0
  96. package/dist/hooks/core/session-state.js +192 -0
  97. package/dist/hooks/core/session-state.js.map +1 -0
  98. package/dist/hooks/core/submit-verdict.d.ts +1 -0
  99. package/dist/hooks/core/submit-verdict.d.ts.map +1 -1
  100. package/dist/hooks/core/submit-verdict.js +35 -27
  101. package/dist/hooks/core/submit-verdict.js.map +1 -1
  102. package/dist/hooks/core/verification-lifecycle.d.ts +30 -0
  103. package/dist/hooks/core/verification-lifecycle.d.ts.map +1 -0
  104. package/dist/hooks/core/verification-lifecycle.js +75 -0
  105. package/dist/hooks/core/verification-lifecycle.js.map +1 -0
  106. package/dist/hooks/core/verify-gate.d.ts +1 -1
  107. package/dist/hooks/core/verify-gate.d.ts.map +1 -1
  108. package/dist/hooks/core/verify-gate.js +13 -20
  109. package/dist/hooks/core/verify-gate.js.map +1 -1
  110. package/dist/index.js +3 -0
  111. package/dist/index.js.map +1 -1
  112. package/dist/lib/config.d.ts +18 -0
  113. package/dist/lib/config.d.ts.map +1 -1
  114. package/dist/lib/config.js +59 -0
  115. package/dist/lib/config.js.map +1 -1
  116. package/package.json +4 -3
package/CHANGELOG.md CHANGED
@@ -1,34 +1,45 @@
1
1
  # Changelog
2
2
 
3
- ## 0.3.0 (2026-03-17)
3
+ ## 0.4.1 (2026-03-25)
4
+
5
+ ### Features
6
+
7
+ * **verify-command:** add parametric modes and improve verification quality ([b274813](https://github.com/ironbee-ai/ironbee-cli/commit/b2748139d0dc17f9ffcf5e211a6c1b95b0ec9d33))
8
+
9
+ ## [0.4.0](https://github.com/ironbee-ai/ironbee-cli/compare/v0.3.0...v0.4.0) (2026-03-22)
10
+
11
+ ### Features
12
+
13
+ * **verification:** add verification lifecycle with start/end boundaries, trace IDs, tool input metadata injection, and bdt_ tool name prefix ([a5df3e8](https://github.com/ironbee-ai/ironbee-cli/commit/a5df3e8))
14
+ * **lifecycle:** add fix start/stop tracking with phase state and session reconciliation ([b10f878](https://github.com/ironbee-ai/ironbee-cli/commit/b10f878))
15
+ * **analyze:** add session analytics with time, quality, code changes, fix effectiveness, scoring, cross-session analysis, and /ironbee-analyze command ([61fe0c8](https://github.com/ironbee-ai/ironbee-cli/commit/61fe0c8))
4
16
 
5
17
  All notable changes to this project will be documented in this file.
6
18
 
7
- ## [0.2.1](https://github.com/ironbee-ai/ironbee-cli/compare/v0.2.0...v0.2.1) (2026-03-16)
19
+ ## [0.3.0](https://github.com/ironbee-ai/ironbee-cli/compare/v0.2.1...v0.3.0) (2026-03-17)
8
20
 
21
+ ### Features
22
+
23
+ * **telemetry:** add telemetry support ([#3](https://github.com/ironbee-ai/ironbee-cli/issues/3)) ([e39398b](https://github.com/ironbee-ai/ironbee-cli/commit/e39398b))
24
+
25
+ ## [0.2.1](https://github.com/ironbee-ai/ironbee-cli/compare/v0.2.0...v0.2.1) (2026-03-16)
9
26
 
10
27
  ### Refactors
11
28
 
12
29
  * **banner:** update banner for the terminals without color support ([3865968](https://github.com/ironbee-ai/ironbee-cli/commit/3865968))
13
30
 
14
-
15
31
  ## [0.2.0](https://github.com/ironbee-ai/ironbee-cli/compare/v0.1.1...v0.2.0) (2026-03-16)
16
32
 
17
-
18
33
  ### Features
19
34
 
20
35
  * **cursor:** initial impl ([#2](https://github.com/ironbee-ai/ironbee-cli/issues/2)) ([872a91e](https://github.com/ironbee-ai/ironbee-cli/commit/872a91e))
21
36
 
22
-
23
37
  ### Bug Fixes
24
38
 
25
- * **build:** fix banner.txt path resolution for npm global install ([1830699](https://github.com/ironbee-ai/ironbee-cli/commit/1830699))
26
39
  * **readme:** fix license and CI badges ([42ea61c](https://github.com/ironbee-ai/ironbee-cli/commit/42ea61c))
27
40
 
28
-
29
41
  ## [0.1.1](https://github.com/ironbee-ai/ironbee-cli/compare/v0.1.0...v0.1.1) (2026-03-14)
30
42
 
31
-
32
43
  ### Features
33
44
 
34
45
  * **claude:** initial impl ([#1](https://github.com/ironbee-ai/ironbee-cli/issues/1)) ([960c59d](https://github.com/ironbee-ai/ironbee-cli/commit/960c59d))
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  </h1>
5
5
 
6
6
  <p align="center">
7
- <strong>The CLI for <a href="https://ironbee.ai">IronBee</a> — The Verification Layer for Agentic Development</strong>
7
+ <strong>The CLI for <a href="https://ironbee.ai">IronBee</a> — Verification and Intelligence Layer for Agentic Development</strong>
8
8
  </p>
9
9
 
10
10
  <p align="center">
@@ -19,6 +19,8 @@
19
19
 
20
20
  No more "it should work" — every change is tested.
21
21
 
22
+ IronBee also tracks every verification cycle — coding time, fix time, pass/fail rates, problematic files — and provides session and project-level analytics for LLM-powered semantic insights.
23
+
22
24
  Powered by [browser-devtools-mcp](https://browser-devtools.com) — the agent navigates pages, clicks buttons, fills forms, takes screenshots, checks console errors, and writes a structured verdict.
23
25
 
24
26
  ## Supported Clients
@@ -72,8 +74,23 @@ ironbee install [project-dir] [--client <name>] Set up hooks and config
72
74
  ironbee uninstall [project-dir] [--client <name>] Remove hooks and config
73
75
  ironbee status [project-dir] Show verdict status for active sessions
74
76
  ironbee verify [session-id] Dry-run verdict validation
77
+ ironbee analyze [session-id] Analyze session metrics (or all sessions)
75
78
  ```
76
79
 
80
+ ### Agent Commands (slash commands)
81
+
82
+ IronBee installs slash commands that the agent can use inside Claude Code or Cursor:
83
+
84
+ | Command | Description |
85
+ |---------|-------------|
86
+ | `/ironbee-verify` | Verify changes — focused on affected areas (default) |
87
+ | `/ironbee-verify full` | Full verification — complete visual + functional + accessibility checklists |
88
+ | `/ironbee-verify visual` | Visual-only — contrast, layout, spacing, fonts, images, theming |
89
+ | `/ironbee-verify functional` | Functional-only — clicks, forms, navigation, data flow, error handling |
90
+ | `/ironbee-analyze` | Run session analytics and provide LLM-powered semantic insights |
91
+
92
+ `/ironbee-verify` guides the agent through a systematic verification process. The default mode focuses on what changed, while `full` runs every checklist item. Use `visual` or `functional` to narrow the scope when you know what type of testing is needed.
93
+
77
94
  ## Configuration
78
95
 
79
96
  IronBee loads config from two locations (project overrides global):
@@ -103,6 +120,51 @@ By default, IronBee requires verification for common code file extensions: `.ts`
103
120
 
104
121
  Non-code files like `README.md`, `package.json`, or `.gitignore` do not trigger verification.
105
122
 
123
+ ### Browser DevTools MCP config
124
+
125
+ By default, IronBee configures `browser-devtools-mcp` via npx. To customize the MCP server (e.g., use a local server or HTTP transport), add a `browserDevTools` key to your config:
126
+
127
+ ```json
128
+ {
129
+ "browserDevTools": {
130
+ "mcp": {
131
+ "url": "http://localhost:4000/mcp"
132
+ }
133
+ }
134
+ }
135
+ ```
136
+
137
+ Or with a custom stdio command:
138
+
139
+ ```json
140
+ {
141
+ "browserDevTools": {
142
+ "mcp": {
143
+ "command": "node",
144
+ "args": ["./my-server.js"],
145
+ "env": { "MY_VAR": "value" }
146
+ }
147
+ }
148
+ }
149
+ ```
150
+
151
+ You can also pass extra env vars to the default npx server without replacing it:
152
+
153
+ ```json
154
+ {
155
+ "browserDevTools": {
156
+ "env": { "BROWSER_HEADLESS_ENABLE": "true", "OTEL_ENABLE": "true" }
157
+ }
158
+ }
159
+ ```
160
+
161
+ | Key | Description |
162
+ |-----|-------------|
163
+ | `browserDevTools.mcp` | Full MCP server config — used as-is when provided. Supports `command`+`args` (stdio) or `url` (HTTP) |
164
+ | `browserDevTools.env` | Extra env vars merged into the default config. Only used when `mcp` is not provided |
165
+
166
+ > **Note:** IronBee always sets `TOOL_NAME_PREFIX=bdt_` and `TOOL_INPUT_METADATA_ENABLE=true` — these cannot be overridden.
167
+
106
168
  ## Verification Flow
107
169
 
108
170
  When the agent tries to complete a task, IronBee runs these checks:
@@ -166,13 +228,111 @@ Each AI session gets its own directory under `.ironbee/sessions/<session-id>/`:
166
228
  ```
167
229
  .ironbee/sessions/<session-id>/
168
230
  actions.jsonl # Event log (file edits, tool calls, verification markers)
169
- verdict.json # Written by agent after verification
170
- retries # Retry counter
231
+ verdict.json # Current verdict (cleared on code edit)
232
+ state.json # Session state (retries, active verification, trace ID, active fix, phase)
171
233
  session.log # Debug log
172
234
  ```
173
235
 
174
236
  This means parallel sessions (e.g., multiple Claude Code instances) don't interfere with each other.
175
237
 
238
+ ## Analytics
239
+
240
+ `ironbee analyze` provides metrics about verification sessions — how time is spent, how effective verifications are, and how confident we can be in the agent's code.
241
+
242
+ ### Usage
243
+
244
+ ```bash
245
+ ironbee analyze <session-id> # single session analysis
246
+ ironbee analyze # all sessions (project-level)
247
+ ironbee analyze --json # JSON output
248
+ ironbee analyze --detailed # include verdict details (checks, issues, fixes)
249
+ ironbee analyze --json --detailed # JSON with verdict text for LLM semantic analysis
250
+ ironbee analyze <session-id> --json --detailed # single session JSON with verdict details
251
+ ```
252
+
253
+ The `--detailed` flag includes raw verdict text (checks, issues, fixes) in the output. This is designed for LLM-powered semantic analysis — use `/ironbee-analyze` in Claude Code or Cursor to have the agent interpret these details automatically.
254
+
255
+ ### Session Analysis
256
+
257
+ #### Phase Distribution
258
+
259
+ Each session is divided into three phases:
260
+
261
+ | Phase | What it measures |
262
+ |-------|-----------------|
263
+ | **Coding** | Time from session start to first verification, and between fix end and next verification start |
264
+ | **Verification** | Time between `verification_start` and `verification_end` — browser testing |
265
+ | **Fixing** | Time between `fix_start` and `fix_end` — fixing failed verifications |
266
+
267
+ #### Cycles
268
+
269
+ | Metric | Meaning |
270
+ |--------|---------|
271
+ | Verifications | Number of verification cycles in the session |
272
+ | Fixes | Number of fix cycles (each fail verdict starts a fix) |
273
+ | Avg verify | Average duration of a verification cycle |
274
+ | Avg fix | Average duration of a fix cycle |
275
+ | First verify | Time from session start to first verification |
276
+
277
+ #### Verification Quality
278
+
279
+ | Metric | Meaning |
280
+ |--------|---------|
281
+ | First-pass rate | Percentage of verification chains where the first verdict was pass |
282
+ | Verdicts | Total verdict count (pass + fail) |
283
+ | Avg retries | Average number of fail verdicts before pass per chain |
284
+ | Avg console errs | Average `console_errors` across all verdicts |
285
+ | Avg network fails | Average `network_failures` across all verdicts |
286
+ | Avg pages tested | Average number of pages tested per verdict |
287
+ | Avg checks | Average number of checks performed per verdict |
288
+
289
+ #### Code Changes
290
+
291
+ | Metric | Meaning |
292
+ |--------|---------|
293
+ | Total edits | Total file edit operations in the session |
294
+ | Unique files | Number of distinct files edited |
295
+ | Avg per verify | Average file edits before each verification |
296
+ | Avg per fix | Average file edits during each fix cycle |
297
+ | Hot Files | Top 5 most frequently edited files |
298
+ | Problematic Files | Top 5 files with most edits during fix cycles |
299
+ | Edit Churn | Files edited in 2+ separate fix cycles (root cause may not be resolved) |
300
+
301
+ #### Fix Effectiveness
302
+
303
+ | Metric | Meaning |
304
+ |--------|---------|
305
+ | Success rate | Percentage of fixes followed by a pass verdict |
306
+ | Re-fail rate | Percentage of fixes followed by another fail verdict |
307
+ | Fix/verify | Ratio of fix cycles to verification cycles (0 = no fixes needed) |
308
+
309
+ #### Scoring
310
+
311
+ Three scores summarize the session:
312
+
313
+ | Score | Formula | What it measures |
314
+ |-------|---------|-----------------|
315
+ | **Efficiency** | `coding_time / (coding_time + fix_time) × 100` | How much productive time vs fix overhead. High = minimal wasted time on fixes |
316
+ | **Quality** | `(pass_pct + pages_pct + checks_pct + clean_pct) / 4` | How thorough and clean the verification was. Components: pass rate, page coverage (3+ = 100%), check depth (5+ = 100%), error cleanliness (0 errors = 100%) |
317
+ | **Confidence** | `pass_count / total_verdicts × 100` | How likely the agent's code works. Based on verdict pass rate |
318
+
319
+ ### Project Analysis
320
+
321
+ When run without a session ID, `ironbee analyze` aggregates metrics across all sessions:
322
+
323
+ | Metric | Meaning |
324
+ |--------|---------|
325
+ | Session History | Each session's summary — duration, cycles, outcome, score |
326
+ | Avg duration | Average session duration across all sessions |
327
+ | Avg verifies | Average verification cycles per session |
328
+ | Avg fixes | Average fix cycles per session |
329
+ | First-pass rate | Percentage of sessions where the first verdict was pass |
330
+ | Fix success rate | Percentage of all fixes (across sessions) that succeeded |
331
+ | Abandon rate | Percentage of sessions with interrupted verification/fix cycles |
332
+ | Avg efficiency | Average efficiency score across all sessions |
333
+ | Avg confidence | Average confidence score across all sessions |
334
+ | Problematic Files | Top 5 files with most fix edits across all sessions |
335
+
176
336
  ## Telemetry
177
337
 
178
338
  IronBee collects anonymous usage data to help improve the product. No source code, file contents, or personally identifiable information is ever sent.
@@ -0,0 +1,22 @@
1
+ /**
2
+ * IronBee — Code Change Analysis
3
+ *
4
+ * Reads actions.jsonl and calculates code change metrics.
5
+ * Pure logic — no process.exit, no stdin, no side effects.
6
+ */
7
+ export interface FileStats {
8
+ filePath: string;
9
+ editCount: number;
10
+ fixEditCount: number;
11
+ }
12
+ export interface CodeChangeAnalysis {
13
+ totalFileEdits: number;
14
+ uniqueFilesEdited: number;
15
+ filesEditedPerVerification: number;
16
+ filesChangedPerFix: number;
17
+ hotFiles: FileStats[];
18
+ problematicFiles: FileStats[];
19
+ editChurnFiles: string[];
20
+ }
21
+ export declare function analyzeCodeChanges(actionsFile: string): CodeChangeAnalysis | null;
22
+ //# sourceMappingURL=code-changes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-changes.d.ts","sourceRoot":"","sources":["../../src/analysis/code-changes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,WAAW,SAAS;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,0BAA0B,EAAE,MAAM,CAAC;IACnC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,SAAS,EAAE,CAAC;IACtB,gBAAgB,EAAE,SAAS,EAAE,CAAC;IAC9B,cAAc,EAAE,MAAM,EAAE,CAAC;CAC5B;AAuBD,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CAqIjF"}
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ /**
3
+ * IronBee — Code Change Analysis
4
+ *
5
+ * Reads actions.jsonl and calculates code change metrics.
6
+ * Pure logic — no process.exit, no stdin, no side effects.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.analyzeCodeChanges = analyzeCodeChanges;
10
+ const fs_1 = require("fs");
11
+ function parseEntries(actionsFile) {
12
+ if (!(0, fs_1.existsSync)(actionsFile)) {
13
+ return [];
14
+ }
15
+ const content = (0, fs_1.readFileSync)(actionsFile, "utf-8");
16
+ const lines = content.trim().split("\n").filter((l) => l.length > 0);
17
+ const entries = [];
18
+ for (const line of lines) {
19
+ try {
20
+ const entry = JSON.parse(line);
21
+ entries.push(entry);
22
+ }
23
+ catch {
24
+ // skip malformed lines
25
+ }
26
+ }
27
+ return entries;
28
+ }
29
+ function analyzeCodeChanges(actionsFile) {
30
+ const entries = parseEntries(actionsFile);
31
+ // Collect all file_edit entries
32
+ const fileEdits = entries.filter((e) => e.type === "file_edit");
33
+ if (fileEdits.length === 0) {
34
+ return null;
35
+ }
36
+ const totalFileEdits = fileEdits.length;
37
+ // Unique files
38
+ const uniqueFiles = new Set();
39
+ for (const edit of fileEdits) {
40
+ const filePath = edit.file_path;
41
+ if (typeof filePath === "string") {
42
+ uniqueFiles.add(filePath);
43
+ }
44
+ }
45
+ const uniqueFilesEdited = uniqueFiles.size;
46
+ // Track phases and count edits per phase type
47
+ let inFixPhase = false;
48
+ let currentFixId = null;
49
+ let codingEditCount = 0;
50
+ let fixEditCount = 0;
51
+ let verificationCount = 0;
52
+ let fixCount = 0;
53
+ // Per-file stats
54
+ const fileEditCounts = new Map();
55
+ const fileFixEditCounts = new Map();
56
+ // Track which fix cycles each file appears in (for churn detection)
57
+ const fileFixCycles = new Map();
58
+ for (const entry of entries) {
59
+ if (entry.type === "fix_start") {
60
+ inFixPhase = true;
61
+ currentFixId = entry.fix_id;
62
+ fixCount++;
63
+ continue;
64
+ }
65
+ if (entry.type === "fix_end") {
66
+ inFixPhase = false;
67
+ currentFixId = null;
68
+ continue;
69
+ }
70
+ if (entry.type === "verification_start") {
71
+ inFixPhase = false;
72
+ currentFixId = null;
73
+ verificationCount++;
74
+ continue;
75
+ }
76
+ if (entry.type === "file_edit") {
77
+ const filePath = entry.file_path;
78
+ if (inFixPhase) {
79
+ fixEditCount++;
80
+ if (typeof filePath === "string") {
81
+ const currentCount = fileFixEditCounts.get(filePath) ?? 0;
82
+ fileFixEditCounts.set(filePath, currentCount + 1);
83
+ if (typeof currentFixId === "string") {
84
+ let cycles = fileFixCycles.get(filePath);
85
+ if (cycles === undefined) {
86
+ cycles = new Set();
87
+ fileFixCycles.set(filePath, cycles);
88
+ }
89
+ cycles.add(currentFixId);
90
+ }
91
+ }
92
+ }
93
+ else {
94
+ codingEditCount++;
95
+ }
96
+ if (typeof filePath === "string") {
97
+ const currentCount = fileEditCounts.get(filePath) ?? 0;
98
+ fileEditCounts.set(filePath, currentCount + 1);
99
+ }
100
+ }
101
+ }
102
+ // filesEditedPerVerification: coding edits / verification count
103
+ const filesEditedPerVerification = verificationCount > 0
104
+ ? Math.round((codingEditCount / verificationCount) * 10) / 10
105
+ : 0;
106
+ // filesChangedPerFix: fix edits / fix count
107
+ const filesChangedPerFix = fixCount > 0
108
+ ? Math.round((fixEditCount / fixCount) * 10) / 10
109
+ : 0;
110
+ // hotFiles: top 5 by total edit count
111
+ const allFileStats = [];
112
+ for (const [filePath, editCount] of fileEditCounts) {
113
+ const fixEdits = fileFixEditCounts.get(filePath) ?? 0;
114
+ allFileStats.push({ filePath, editCount, fixEditCount: fixEdits });
115
+ }
116
+ const hotFiles = [...allFileStats]
117
+ .sort((a, b) => b.editCount - a.editCount)
118
+ .slice(0, 5);
119
+ // problematicFiles: top 5 by fix edit count, only those with fixEditCount > 0
120
+ const problematicFiles = [...allFileStats]
121
+ .filter((f) => f.fixEditCount > 0)
122
+ .sort((a, b) => b.fixEditCount - a.fixEditCount)
123
+ .slice(0, 5);
124
+ // editChurnFiles: files edited in 2+ different fix cycles
125
+ const editChurnFiles = [];
126
+ for (const [filePath, cycles] of fileFixCycles) {
127
+ if (cycles.size >= 2) {
128
+ editChurnFiles.push(filePath);
129
+ }
130
+ }
131
+ return {
132
+ totalFileEdits,
133
+ uniqueFilesEdited,
134
+ filesEditedPerVerification,
135
+ filesChangedPerFix,
136
+ hotFiles,
137
+ problematicFiles,
138
+ editChurnFiles,
139
+ };
140
+ }
141
+ //# sourceMappingURL=code-changes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-changes.js","sourceRoot":"","sources":["../../src/analysis/code-changes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * IronBee — Cross-Session Analysis
3
+ *
4
+ * Scans all sessions in .ironbee/sessions/ and produces aggregate metrics.
5
+ * Pure logic — no process.exit, no stdin, no side effects.
6
+ */
7
+ export interface SessionSummary {
8
+ sessionId: string;
9
+ timestamp: string;
10
+ duration: number;
11
+ verificationCycles: number;
12
+ fixCycles: number;
13
+ firstPassSuccess: boolean;
14
+ lastVerdictStatus: string | null;
15
+ agentEfficiencyScore: number;
16
+ }
17
+ export interface CrossSessionAnalysis {
18
+ totalSessions: number;
19
+ sessionSummaries: SessionSummary[];
20
+ aggregateFirstPassRate: number;
21
+ aggregateFixSuccessRate: number;
22
+ averageSessionDuration: number;
23
+ averageVerificationCycles: number;
24
+ averageFixCycles: number;
25
+ averageEfficiencyScore: number;
26
+ averageCodeConfidence: number;
27
+ mostProblematicFiles: Array<{
28
+ filePath: string;
29
+ fixEditCount: number;
30
+ }>;
31
+ abandonRate: number;
32
+ }
33
+ export declare function analyzeCrossSessions(sessionsDir: string): CrossSessionAnalysis | null;
34
+ //# sourceMappingURL=cross-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cross-session.d.ts","sourceRoot":"","sources":["../../src/analysis/cross-session.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH,MAAM,WAAW,cAAc;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,oBAAoB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,oBAAoB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,cAAc,EAAE,CAAC;IACnC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,uBAAuB,EAAE,MAAM,CAAC;IAChC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,yBAAyB,EAAE,MAAM,CAAC;IAClC,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,oBAAoB,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxE,WAAW,EAAE,MAAM,CAAC;CACvB;AAiFD,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI,CA2KrF"}