@newrelic/preflight 0.0.1-pre.1 → 1.0.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 (578) hide show
  1. package/LICENSE +183 -0
  2. package/README.md +498 -0
  3. package/dist/alerts/alert-log.d.ts +24 -0
  4. package/dist/alerts/alert-log.d.ts.map +1 -0
  5. package/dist/alerts/alert-log.js +159 -0
  6. package/dist/alerts/alert-log.js.map +1 -0
  7. package/dist/alerts/alert-snapshot-collector.d.ts +168 -0
  8. package/dist/alerts/alert-snapshot-collector.d.ts.map +1 -0
  9. package/dist/alerts/alert-snapshot-collector.js +243 -0
  10. package/dist/alerts/alert-snapshot-collector.js.map +1 -0
  11. package/dist/alerts/local-alert-engine.d.ts +86 -0
  12. package/dist/alerts/local-alert-engine.d.ts.map +1 -0
  13. package/dist/alerts/local-alert-engine.js +466 -0
  14. package/dist/alerts/local-alert-engine.js.map +1 -0
  15. package/dist/alerts/local-alert-rule.d.ts +439 -0
  16. package/dist/alerts/local-alert-rule.d.ts.map +1 -0
  17. package/dist/alerts/local-alert-rule.js +139 -0
  18. package/dist/alerts/local-alert-rule.js.map +1 -0
  19. package/dist/alerts/os-notifier.d.ts +39 -0
  20. package/dist/alerts/os-notifier.d.ts.map +1 -0
  21. package/dist/alerts/os-notifier.js +170 -0
  22. package/dist/alerts/os-notifier.js.map +1 -0
  23. package/dist/alerts/types.d.ts +35 -0
  24. package/dist/alerts/types.d.ts.map +1 -0
  25. package/dist/alerts/types.js +8 -0
  26. package/dist/alerts/types.js.map +1 -0
  27. package/dist/config.d.ts +169 -0
  28. package/dist/config.d.ts.map +1 -0
  29. package/dist/config.js +860 -0
  30. package/dist/config.js.map +1 -0
  31. package/dist/dashboard/dashboard-server.d.ts +38 -0
  32. package/dist/dashboard/dashboard-server.d.ts.map +1 -0
  33. package/dist/dashboard/dashboard-server.js +207 -0
  34. package/dist/dashboard/dashboard-server.js.map +1 -0
  35. package/dist/dashboard/index.d.ts +3 -0
  36. package/dist/dashboard/index.d.ts.map +1 -0
  37. package/dist/dashboard/index.js +2 -0
  38. package/dist/dashboard/index.js.map +1 -0
  39. package/dist/dashboard/live-event-bus.d.ts +99 -0
  40. package/dist/dashboard/live-event-bus.d.ts.map +1 -0
  41. package/dist/dashboard/live-event-bus.js +56 -0
  42. package/dist/dashboard/live-event-bus.js.map +1 -0
  43. package/dist/dashboard/routes/api-handler.d.ts +122 -0
  44. package/dist/dashboard/routes/api-handler.d.ts.map +1 -0
  45. package/dist/dashboard/routes/api-handler.js +1414 -0
  46. package/dist/dashboard/routes/api-handler.js.map +1 -0
  47. package/dist/dashboard/routes/replay-analyzer.d.ts +15 -0
  48. package/dist/dashboard/routes/replay-analyzer.d.ts.map +1 -0
  49. package/dist/dashboard/routes/replay-analyzer.js +227 -0
  50. package/dist/dashboard/routes/replay-analyzer.js.map +1 -0
  51. package/dist/dashboard/routes/sse-handler.d.ts +4 -0
  52. package/dist/dashboard/routes/sse-handler.d.ts.map +1 -0
  53. package/dist/dashboard/routes/sse-handler.js +122 -0
  54. package/dist/dashboard/routes/sse-handler.js.map +1 -0
  55. package/dist/dashboard/routes/static-handler.d.ts +3 -0
  56. package/dist/dashboard/routes/static-handler.d.ts.map +1 -0
  57. package/dist/dashboard/routes/static-handler.js +103 -0
  58. package/dist/dashboard/routes/static-handler.js.map +1 -0
  59. package/dist/data/alerts/conditions/01-daily-cost-spike.json +16 -0
  60. package/dist/data/alerts/conditions/02-low-efficiency-score.json +16 -0
  61. package/dist/data/alerts/conditions/03-stuck-loop-rate.json +16 -0
  62. package/dist/data/alerts/conditions/04-anti-pattern-rate.json +16 -0
  63. package/dist/data/alerts/conditions/05-session-cost-budget.json +16 -0
  64. package/dist/data/alerts/conditions-personal/01-personal-daily-cost.json +16 -0
  65. package/dist/data/alerts/conditions-personal/02-personal-session-cost.json +16 -0
  66. package/dist/data/alerts/conditions-personal/03-personal-low-efficiency.json +16 -0
  67. package/dist/data/alerts/conditions-personal/04-personal-anti-pattern-rate.json +16 -0
  68. package/dist/data/alerts/conditions-personal/05-personal-stuck-loop.json +16 -0
  69. package/dist/data/alerts/policy.json +4 -0
  70. package/dist/data/dashboards/ai-coding-assistant-manager-view.json +103 -0
  71. package/dist/data/dashboards/ai-coding-assistant-overview.json +239 -0
  72. package/dist/data/dashboards/ai-coding-assistant-personal.json +442 -0
  73. package/dist/data/dashboards/ai-coding-assistant-platform-comparison.json +320 -0
  74. package/dist/data/dashboards/ai-coding-assistant-security.json +275 -0
  75. package/dist/data/dashboards/ai-coding-assistant-session-detail.json +296 -0
  76. package/dist/data/dashboards/ai-coding-assistant-team-view.json +345 -0
  77. package/dist/deploy/data-paths.d.ts +22 -0
  78. package/dist/deploy/data-paths.d.ts.map +1 -0
  79. package/dist/deploy/data-paths.js +69 -0
  80. package/dist/deploy/data-paths.js.map +1 -0
  81. package/dist/deploy/deploy-alerts.d.ts +58 -0
  82. package/dist/deploy/deploy-alerts.d.ts.map +1 -0
  83. package/dist/deploy/deploy-alerts.js +371 -0
  84. package/dist/deploy/deploy-alerts.js.map +1 -0
  85. package/dist/deploy/deploy-dashboards.d.ts +92 -0
  86. package/dist/deploy/deploy-dashboards.d.ts.map +1 -0
  87. package/dist/deploy/deploy-dashboards.js +282 -0
  88. package/dist/deploy/deploy-dashboards.js.map +1 -0
  89. package/dist/digest/digest-formatter.d.ts +3 -0
  90. package/dist/digest/digest-formatter.d.ts.map +1 -0
  91. package/dist/digest/digest-formatter.js +37 -0
  92. package/dist/digest/digest-formatter.js.map +1 -0
  93. package/dist/digest/digest-sender.d.ts +2 -0
  94. package/dist/digest/digest-sender.d.ts.map +1 -0
  95. package/dist/digest/digest-sender.js +29 -0
  96. package/dist/digest/digest-sender.js.map +1 -0
  97. package/dist/hooks/bash-classifier.d.ts +26 -0
  98. package/dist/hooks/bash-classifier.d.ts.map +1 -0
  99. package/dist/hooks/bash-classifier.js +409 -0
  100. package/dist/hooks/bash-classifier.js.map +1 -0
  101. package/dist/hooks/collector-script.d.ts +47 -0
  102. package/dist/hooks/collector-script.d.ts.map +1 -0
  103. package/dist/hooks/collector-script.js +662 -0
  104. package/dist/hooks/collector-script.js.map +1 -0
  105. package/dist/hooks/event-processor.d.ts +65 -0
  106. package/dist/hooks/event-processor.d.ts.map +1 -0
  107. package/dist/hooks/event-processor.js +342 -0
  108. package/dist/hooks/event-processor.js.map +1 -0
  109. package/dist/hooks/index.d.ts +7 -0
  110. package/dist/hooks/index.d.ts.map +1 -0
  111. package/dist/hooks/index.js +5 -0
  112. package/dist/hooks/index.js.map +1 -0
  113. package/dist/hooks/session-resolver.d.ts +66 -0
  114. package/dist/hooks/session-resolver.d.ts.map +1 -0
  115. package/dist/hooks/session-resolver.js +196 -0
  116. package/dist/hooks/session-resolver.js.map +1 -0
  117. package/dist/hooks/tool-parsers.d.ts +19 -0
  118. package/dist/hooks/tool-parsers.d.ts.map +1 -0
  119. package/dist/hooks/tool-parsers.js +260 -0
  120. package/dist/hooks/tool-parsers.js.map +1 -0
  121. package/dist/index.d.ts +107 -0
  122. package/dist/index.d.ts.map +1 -0
  123. package/dist/index.js +1505 -0
  124. package/dist/index.js.map +1 -0
  125. package/dist/install/cli.d.ts +11 -0
  126. package/dist/install/cli.d.ts.map +1 -0
  127. package/dist/install/cli.js +365 -0
  128. package/dist/install/cli.js.map +1 -0
  129. package/dist/install/index.d.ts +4 -0
  130. package/dist/install/index.d.ts.map +1 -0
  131. package/dist/install/index.js +3 -0
  132. package/dist/install/index.js.map +1 -0
  133. package/dist/install/install-helper.d.ts +35 -0
  134. package/dist/install/install-helper.d.ts.map +1 -0
  135. package/dist/install/install-helper.js +227 -0
  136. package/dist/install/install-helper.js.map +1 -0
  137. package/dist/install/key-validator.d.ts +19 -0
  138. package/dist/install/key-validator.d.ts.map +1 -0
  139. package/dist/install/key-validator.js +122 -0
  140. package/dist/install/key-validator.js.map +1 -0
  141. package/dist/install/migrate.d.ts +12 -0
  142. package/dist/install/migrate.d.ts.map +1 -0
  143. package/dist/install/migrate.js +115 -0
  144. package/dist/install/migrate.js.map +1 -0
  145. package/dist/install/schedule.d.ts +11 -0
  146. package/dist/install/schedule.d.ts.map +1 -0
  147. package/dist/install/schedule.js +114 -0
  148. package/dist/install/schedule.js.map +1 -0
  149. package/dist/install/setup-wizard.d.ts +40 -0
  150. package/dist/install/setup-wizard.d.ts.map +1 -0
  151. package/dist/install/setup-wizard.js +489 -0
  152. package/dist/install/setup-wizard.js.map +1 -0
  153. package/dist/lib/date.d.ts +54 -0
  154. package/dist/lib/date.d.ts.map +1 -0
  155. package/dist/lib/date.js +85 -0
  156. package/dist/lib/date.js.map +1 -0
  157. package/dist/metrics/anti-patterns.d.ts +62 -0
  158. package/dist/metrics/anti-patterns.d.ts.map +1 -0
  159. package/dist/metrics/anti-patterns.js +301 -0
  160. package/dist/metrics/anti-patterns.js.map +1 -0
  161. package/dist/metrics/api-failure-tracker.d.ts +82 -0
  162. package/dist/metrics/api-failure-tracker.d.ts.map +1 -0
  163. package/dist/metrics/api-failure-tracker.js +202 -0
  164. package/dist/metrics/api-failure-tracker.js.map +1 -0
  165. package/dist/metrics/budget-tracker.d.ts +60 -0
  166. package/dist/metrics/budget-tracker.d.ts.map +1 -0
  167. package/dist/metrics/budget-tracker.js +130 -0
  168. package/dist/metrics/budget-tracker.js.map +1 -0
  169. package/dist/metrics/claudemd-tracker.d.ts +108 -0
  170. package/dist/metrics/claudemd-tracker.d.ts.map +1 -0
  171. package/dist/metrics/claudemd-tracker.js +337 -0
  172. package/dist/metrics/claudemd-tracker.js.map +1 -0
  173. package/dist/metrics/collaboration-profile.d.ts +65 -0
  174. package/dist/metrics/collaboration-profile.d.ts.map +1 -0
  175. package/dist/metrics/collaboration-profile.js +231 -0
  176. package/dist/metrics/collaboration-profile.js.map +1 -0
  177. package/dist/metrics/context-composition-tracker.d.ts +74 -0
  178. package/dist/metrics/context-composition-tracker.d.ts.map +1 -0
  179. package/dist/metrics/context-composition-tracker.js +202 -0
  180. package/dist/metrics/context-composition-tracker.js.map +1 -0
  181. package/dist/metrics/context-tracker.d.ts +78 -0
  182. package/dist/metrics/context-tracker.d.ts.map +1 -0
  183. package/dist/metrics/context-tracker.js +222 -0
  184. package/dist/metrics/context-tracker.js.map +1 -0
  185. package/dist/metrics/context-window-tracker.d.ts +18 -0
  186. package/dist/metrics/context-window-tracker.d.ts.map +1 -0
  187. package/dist/metrics/context-window-tracker.js +35 -0
  188. package/dist/metrics/context-window-tracker.js.map +1 -0
  189. package/dist/metrics/cost-forecast.d.ts +36 -0
  190. package/dist/metrics/cost-forecast.d.ts.map +1 -0
  191. package/dist/metrics/cost-forecast.js +91 -0
  192. package/dist/metrics/cost-forecast.js.map +1 -0
  193. package/dist/metrics/cost-per-outcome.d.ts +102 -0
  194. package/dist/metrics/cost-per-outcome.d.ts.map +1 -0
  195. package/dist/metrics/cost-per-outcome.js +266 -0
  196. package/dist/metrics/cost-per-outcome.js.map +1 -0
  197. package/dist/metrics/cost-tracker.d.ts +78 -0
  198. package/dist/metrics/cost-tracker.d.ts.map +1 -0
  199. package/dist/metrics/cost-tracker.js +169 -0
  200. package/dist/metrics/cost-tracker.js.map +1 -0
  201. package/dist/metrics/decision-tracker.d.ts +49 -0
  202. package/dist/metrics/decision-tracker.d.ts.map +1 -0
  203. package/dist/metrics/decision-tracker.js +161 -0
  204. package/dist/metrics/decision-tracker.js.map +1 -0
  205. package/dist/metrics/efficiency-score.d.ts +80 -0
  206. package/dist/metrics/efficiency-score.d.ts.map +1 -0
  207. package/dist/metrics/efficiency-score.js +219 -0
  208. package/dist/metrics/efficiency-score.js.map +1 -0
  209. package/dist/metrics/git-efficiency-tracker.d.ts +165 -0
  210. package/dist/metrics/git-efficiency-tracker.d.ts.map +1 -0
  211. package/dist/metrics/git-efficiency-tracker.js +1056 -0
  212. package/dist/metrics/git-efficiency-tracker.js.map +1 -0
  213. package/dist/metrics/index.d.ts +26 -0
  214. package/dist/metrics/index.d.ts.map +1 -0
  215. package/dist/metrics/index.js +14 -0
  216. package/dist/metrics/index.js.map +1 -0
  217. package/dist/metrics/instruction-drift-tracker.d.ts +69 -0
  218. package/dist/metrics/instruction-drift-tracker.d.ts.map +1 -0
  219. package/dist/metrics/instruction-drift-tracker.js +213 -0
  220. package/dist/metrics/instruction-drift-tracker.js.map +1 -0
  221. package/dist/metrics/latency-decomposition.d.ts +50 -0
  222. package/dist/metrics/latency-decomposition.d.ts.map +1 -0
  223. package/dist/metrics/latency-decomposition.js +112 -0
  224. package/dist/metrics/latency-decomposition.js.map +1 -0
  225. package/dist/metrics/latency-tracker.d.ts +33 -0
  226. package/dist/metrics/latency-tracker.d.ts.map +1 -0
  227. package/dist/metrics/latency-tracker.js +93 -0
  228. package/dist/metrics/latency-tracker.js.map +1 -0
  229. package/dist/metrics/live-session-registry.d.ts +29 -0
  230. package/dist/metrics/live-session-registry.d.ts.map +1 -0
  231. package/dist/metrics/live-session-registry.js +103 -0
  232. package/dist/metrics/live-session-registry.js.map +1 -0
  233. package/dist/metrics/model-usage-tracker.d.ts +21 -0
  234. package/dist/metrics/model-usage-tracker.d.ts.map +1 -0
  235. package/dist/metrics/model-usage-tracker.js +53 -0
  236. package/dist/metrics/model-usage-tracker.js.map +1 -0
  237. package/dist/metrics/percentile.d.ts +5 -0
  238. package/dist/metrics/percentile.d.ts.map +1 -0
  239. package/dist/metrics/percentile.js +10 -0
  240. package/dist/metrics/percentile.js.map +1 -0
  241. package/dist/metrics/personal-coach.d.ts +47 -0
  242. package/dist/metrics/personal-coach.d.ts.map +1 -0
  243. package/dist/metrics/personal-coach.js +241 -0
  244. package/dist/metrics/personal-coach.js.map +1 -0
  245. package/dist/metrics/prompt-feedback.d.ts +75 -0
  246. package/dist/metrics/prompt-feedback.d.ts.map +1 -0
  247. package/dist/metrics/prompt-feedback.js +286 -0
  248. package/dist/metrics/prompt-feedback.js.map +1 -0
  249. package/dist/metrics/proxy-metrics.d.ts +54 -0
  250. package/dist/metrics/proxy-metrics.d.ts.map +1 -0
  251. package/dist/metrics/proxy-metrics.js +228 -0
  252. package/dist/metrics/proxy-metrics.js.map +1 -0
  253. package/dist/metrics/quality-proxy-tracker.d.ts +51 -0
  254. package/dist/metrics/quality-proxy-tracker.d.ts.map +1 -0
  255. package/dist/metrics/quality-proxy-tracker.js +162 -0
  256. package/dist/metrics/quality-proxy-tracker.js.map +1 -0
  257. package/dist/metrics/recommendation-engine.d.ts +72 -0
  258. package/dist/metrics/recommendation-engine.d.ts.map +1 -0
  259. package/dist/metrics/recommendation-engine.js +207 -0
  260. package/dist/metrics/recommendation-engine.js.map +1 -0
  261. package/dist/metrics/retry-detector.d.ts +43 -0
  262. package/dist/metrics/retry-detector.d.ts.map +1 -0
  263. package/dist/metrics/retry-detector.js +179 -0
  264. package/dist/metrics/retry-detector.js.map +1 -0
  265. package/dist/metrics/session-tracker.d.ts +75 -0
  266. package/dist/metrics/session-tracker.d.ts.map +1 -0
  267. package/dist/metrics/session-tracker.js +249 -0
  268. package/dist/metrics/session-tracker.js.map +1 -0
  269. package/dist/metrics/task-completion-tracker.d.ts +15 -0
  270. package/dist/metrics/task-completion-tracker.d.ts.map +1 -0
  271. package/dist/metrics/task-completion-tracker.js +27 -0
  272. package/dist/metrics/task-completion-tracker.js.map +1 -0
  273. package/dist/metrics/task-detector.d.ts +84 -0
  274. package/dist/metrics/task-detector.d.ts.map +1 -0
  275. package/dist/metrics/task-detector.js +302 -0
  276. package/dist/metrics/task-detector.js.map +1 -0
  277. package/dist/metrics/tool-selection-scorer.d.ts +39 -0
  278. package/dist/metrics/tool-selection-scorer.d.ts.map +1 -0
  279. package/dist/metrics/tool-selection-scorer.js +193 -0
  280. package/dist/metrics/tool-selection-scorer.js.map +1 -0
  281. package/dist/metrics/trend-analyzer.d.ts +92 -0
  282. package/dist/metrics/trend-analyzer.d.ts.map +1 -0
  283. package/dist/metrics/trend-analyzer.js +293 -0
  284. package/dist/metrics/trend-analyzer.js.map +1 -0
  285. package/dist/metrics/turn-cost-attributor.d.ts +41 -0
  286. package/dist/metrics/turn-cost-attributor.d.ts.map +1 -0
  287. package/dist/metrics/turn-cost-attributor.js +118 -0
  288. package/dist/metrics/turn-cost-attributor.js.map +1 -0
  289. package/dist/metrics/turn-tracker.d.ts +49 -0
  290. package/dist/metrics/turn-tracker.d.ts.map +1 -0
  291. package/dist/metrics/turn-tracker.js +192 -0
  292. package/dist/metrics/turn-tracker.js.map +1 -0
  293. package/dist/platforms/amazon-q-adapter.d.ts +10 -0
  294. package/dist/platforms/amazon-q-adapter.d.ts.map +1 -0
  295. package/dist/platforms/amazon-q-adapter.js +75 -0
  296. package/dist/platforms/amazon-q-adapter.js.map +1 -0
  297. package/dist/platforms/claude-code-adapter.d.ts +10 -0
  298. package/dist/platforms/claude-code-adapter.d.ts.map +1 -0
  299. package/dist/platforms/claude-code-adapter.js +48 -0
  300. package/dist/platforms/claude-code-adapter.js.map +1 -0
  301. package/dist/platforms/continue-adapter.d.ts +10 -0
  302. package/dist/platforms/continue-adapter.d.ts.map +1 -0
  303. package/dist/platforms/continue-adapter.js +73 -0
  304. package/dist/platforms/continue-adapter.js.map +1 -0
  305. package/dist/platforms/copilot-adapter.d.ts +37 -0
  306. package/dist/platforms/copilot-adapter.d.ts.map +1 -0
  307. package/dist/platforms/copilot-adapter.js +66 -0
  308. package/dist/platforms/copilot-adapter.js.map +1 -0
  309. package/dist/platforms/cursor-adapter.d.ts +10 -0
  310. package/dist/platforms/cursor-adapter.d.ts.map +1 -0
  311. package/dist/platforms/cursor-adapter.js +60 -0
  312. package/dist/platforms/cursor-adapter.js.map +1 -0
  313. package/dist/platforms/generic-mcp-adapter.d.ts +113 -0
  314. package/dist/platforms/generic-mcp-adapter.d.ts.map +1 -0
  315. package/dist/platforms/generic-mcp-adapter.js +139 -0
  316. package/dist/platforms/generic-mcp-adapter.js.map +1 -0
  317. package/dist/platforms/index.d.ts +15 -0
  318. package/dist/platforms/index.d.ts.map +1 -0
  319. package/dist/platforms/index.js +12 -0
  320. package/dist/platforms/index.js.map +1 -0
  321. package/dist/platforms/platform-registry.d.ts +11 -0
  322. package/dist/platforms/platform-registry.d.ts.map +1 -0
  323. package/dist/platforms/platform-registry.js +54 -0
  324. package/dist/platforms/platform-registry.js.map +1 -0
  325. package/dist/platforms/types.d.ts +36 -0
  326. package/dist/platforms/types.d.ts.map +1 -0
  327. package/dist/platforms/types.js +2 -0
  328. package/dist/platforms/types.js.map +1 -0
  329. package/dist/platforms/windsurf-adapter.d.ts +10 -0
  330. package/dist/platforms/windsurf-adapter.d.ts.map +1 -0
  331. package/dist/platforms/windsurf-adapter.js +63 -0
  332. package/dist/platforms/windsurf-adapter.js.map +1 -0
  333. package/dist/platforms/zed-adapter.d.ts +10 -0
  334. package/dist/platforms/zed-adapter.d.ts.map +1 -0
  335. package/dist/platforms/zed-adapter.js +72 -0
  336. package/dist/platforms/zed-adapter.js.map +1 -0
  337. package/dist/proxy/index.d.ts +7 -0
  338. package/dist/proxy/index.d.ts.map +1 -0
  339. package/dist/proxy/index.js +5 -0
  340. package/dist/proxy/index.js.map +1 -0
  341. package/dist/proxy/otlp-receiver.d.ts +28 -0
  342. package/dist/proxy/otlp-receiver.d.ts.map +1 -0
  343. package/dist/proxy/otlp-receiver.js +319 -0
  344. package/dist/proxy/otlp-receiver.js.map +1 -0
  345. package/dist/proxy/proxy-manager.d.ts +47 -0
  346. package/dist/proxy/proxy-manager.d.ts.map +1 -0
  347. package/dist/proxy/proxy-manager.js +338 -0
  348. package/dist/proxy/proxy-manager.js.map +1 -0
  349. package/dist/proxy/types.d.ts +72 -0
  350. package/dist/proxy/types.d.ts.map +1 -0
  351. package/dist/proxy/types.js +33 -0
  352. package/dist/proxy/types.js.map +1 -0
  353. package/dist/proxy/upstream-http.d.ts +26 -0
  354. package/dist/proxy/upstream-http.d.ts.map +1 -0
  355. package/dist/proxy/upstream-http.js +209 -0
  356. package/dist/proxy/upstream-http.js.map +1 -0
  357. package/dist/proxy/upstream-stdio.d.ts +25 -0
  358. package/dist/proxy/upstream-stdio.d.ts.map +1 -0
  359. package/dist/proxy/upstream-stdio.js +256 -0
  360. package/dist/proxy/upstream-stdio.js.map +1 -0
  361. package/dist/security/audit-trail.d.ts +74 -0
  362. package/dist/security/audit-trail.d.ts.map +1 -0
  363. package/dist/security/audit-trail.js +338 -0
  364. package/dist/security/audit-trail.js.map +1 -0
  365. package/dist/security/index.d.ts +5 -0
  366. package/dist/security/index.d.ts.map +1 -0
  367. package/dist/security/index.js +4 -0
  368. package/dist/security/index.js.map +1 -0
  369. package/dist/security/ssrf.d.ts +2 -0
  370. package/dist/security/ssrf.d.ts.map +1 -0
  371. package/dist/security/ssrf.js +126 -0
  372. package/dist/security/ssrf.js.map +1 -0
  373. package/dist/server.d.ts +14 -0
  374. package/dist/server.d.ts.map +1 -0
  375. package/dist/server.js +117 -0
  376. package/dist/server.js.map +1 -0
  377. package/dist/shared/__test-utils__/log-output.d.ts +49 -0
  378. package/dist/shared/__test-utils__/log-output.d.ts.map +1 -0
  379. package/dist/shared/__test-utils__/log-output.js +38 -0
  380. package/dist/shared/__test-utils__/log-output.js.map +1 -0
  381. package/dist/shared/config.d.ts +56 -0
  382. package/dist/shared/config.d.ts.map +1 -0
  383. package/dist/shared/config.js +290 -0
  384. package/dist/shared/config.js.map +1 -0
  385. package/dist/shared/errors.d.ts +139 -0
  386. package/dist/shared/errors.d.ts.map +1 -0
  387. package/dist/shared/errors.js +406 -0
  388. package/dist/shared/errors.js.map +1 -0
  389. package/dist/shared/events/factory.d.ts +143 -0
  390. package/dist/shared/events/factory.d.ts.map +1 -0
  391. package/dist/shared/events/factory.js +351 -0
  392. package/dist/shared/events/factory.js.map +1 -0
  393. package/dist/shared/events/index.d.ts +6 -0
  394. package/dist/shared/events/index.d.ts.map +1 -0
  395. package/dist/shared/events/index.js +3 -0
  396. package/dist/shared/events/index.js.map +1 -0
  397. package/dist/shared/events/serialize.d.ts +87 -0
  398. package/dist/shared/events/serialize.d.ts.map +1 -0
  399. package/dist/shared/events/serialize.js +510 -0
  400. package/dist/shared/events/serialize.js.map +1 -0
  401. package/dist/shared/events/types.d.ts +139 -0
  402. package/dist/shared/events/types.d.ts.map +1 -0
  403. package/dist/shared/events/types.js +2 -0
  404. package/dist/shared/events/types.js.map +1 -0
  405. package/dist/shared/harvest/event-buffer.d.ts +59 -0
  406. package/dist/shared/harvest/event-buffer.d.ts.map +1 -0
  407. package/dist/shared/harvest/event-buffer.js +100 -0
  408. package/dist/shared/harvest/event-buffer.js.map +1 -0
  409. package/dist/shared/harvest/harvest-scheduler.d.ts +200 -0
  410. package/dist/shared/harvest/harvest-scheduler.d.ts.map +1 -0
  411. package/dist/shared/harvest/harvest-scheduler.js +647 -0
  412. package/dist/shared/harvest/harvest-scheduler.js.map +1 -0
  413. package/dist/shared/harvest/index.d.ts +7 -0
  414. package/dist/shared/harvest/index.d.ts.map +1 -0
  415. package/dist/shared/harvest/index.js +4 -0
  416. package/dist/shared/harvest/index.js.map +1 -0
  417. package/dist/shared/harvest/metric-aggregator.d.ts +115 -0
  418. package/dist/shared/harvest/metric-aggregator.d.ts.map +1 -0
  419. package/dist/shared/harvest/metric-aggregator.js +247 -0
  420. package/dist/shared/harvest/metric-aggregator.js.map +1 -0
  421. package/dist/shared/index.d.ts +22 -0
  422. package/dist/shared/index.d.ts.map +1 -0
  423. package/dist/shared/index.js +13 -0
  424. package/dist/shared/index.js.map +1 -0
  425. package/dist/shared/logger.d.ts +57 -0
  426. package/dist/shared/logger.d.ts.map +1 -0
  427. package/dist/shared/logger.js +166 -0
  428. package/dist/shared/logger.js.map +1 -0
  429. package/dist/shared/pricing-data.d.ts +4 -0
  430. package/dist/shared/pricing-data.d.ts.map +1 -0
  431. package/dist/shared/pricing-data.js +473 -0
  432. package/dist/shared/pricing-data.js.map +1 -0
  433. package/dist/shared/pricing.d.ts +148 -0
  434. package/dist/shared/pricing.d.ts.map +1 -0
  435. package/dist/shared/pricing.js +528 -0
  436. package/dist/shared/pricing.js.map +1 -0
  437. package/dist/shared/redact.d.ts +33 -0
  438. package/dist/shared/redact.d.ts.map +1 -0
  439. package/dist/shared/redact.js +110 -0
  440. package/dist/shared/redact.js.map +1 -0
  441. package/dist/shared/timing.d.ts +96 -0
  442. package/dist/shared/timing.d.ts.map +1 -0
  443. package/dist/shared/timing.js +173 -0
  444. package/dist/shared/timing.js.map +1 -0
  445. package/dist/shared/tokens.d.ts +145 -0
  446. package/dist/shared/tokens.d.ts.map +1 -0
  447. package/dist/shared/tokens.js +492 -0
  448. package/dist/shared/tokens.js.map +1 -0
  449. package/dist/shared/transport/events-api.d.ts +14 -0
  450. package/dist/shared/transport/events-api.d.ts.map +1 -0
  451. package/dist/shared/transport/events-api.js +29 -0
  452. package/dist/shared/transport/events-api.js.map +1 -0
  453. package/dist/shared/transport/http-client.d.ts +49 -0
  454. package/dist/shared/transport/http-client.d.ts.map +1 -0
  455. package/dist/shared/transport/http-client.js +381 -0
  456. package/dist/shared/transport/http-client.js.map +1 -0
  457. package/dist/shared/transport/index.d.ts +10 -0
  458. package/dist/shared/transport/index.d.ts.map +1 -0
  459. package/dist/shared/transport/index.js +6 -0
  460. package/dist/shared/transport/index.js.map +1 -0
  461. package/dist/shared/transport/logs-api.d.ts +29 -0
  462. package/dist/shared/transport/logs-api.d.ts.map +1 -0
  463. package/dist/shared/transport/logs-api.js +40 -0
  464. package/dist/shared/transport/logs-api.js.map +1 -0
  465. package/dist/shared/transport/metric-api.d.ts +9 -0
  466. package/dist/shared/transport/metric-api.d.ts.map +1 -0
  467. package/dist/shared/transport/metric-api.js +39 -0
  468. package/dist/shared/transport/metric-api.js.map +1 -0
  469. package/dist/shared/transport/otlp-event-bridge.d.ts +22 -0
  470. package/dist/shared/transport/otlp-event-bridge.d.ts.map +1 -0
  471. package/dist/shared/transport/otlp-event-bridge.js +50 -0
  472. package/dist/shared/transport/otlp-event-bridge.js.map +1 -0
  473. package/dist/shared/transport/otlp-shared.d.ts +14 -0
  474. package/dist/shared/transport/otlp-shared.d.ts.map +1 -0
  475. package/dist/shared/transport/otlp-shared.js +49 -0
  476. package/dist/shared/transport/otlp-shared.js.map +1 -0
  477. package/dist/shared/transport/otlp-transport.d.ts +58 -0
  478. package/dist/shared/transport/otlp-transport.d.ts.map +1 -0
  479. package/dist/shared/transport/otlp-transport.js +236 -0
  480. package/dist/shared/transport/otlp-transport.js.map +1 -0
  481. package/dist/shared/transport/types.d.ts +129 -0
  482. package/dist/shared/transport/types.d.ts.map +1 -0
  483. package/dist/shared/transport/types.js +2 -0
  484. package/dist/shared/transport/types.js.map +1 -0
  485. package/dist/shared/version.d.ts +2 -0
  486. package/dist/shared/version.d.ts.map +1 -0
  487. package/dist/shared/version.js +2 -0
  488. package/dist/shared/version.js.map +1 -0
  489. package/dist/storage/index.d.ts +7 -0
  490. package/dist/storage/index.d.ts.map +1 -0
  491. package/dist/storage/index.js +4 -0
  492. package/dist/storage/index.js.map +1 -0
  493. package/dist/storage/local-store.d.ts +153 -0
  494. package/dist/storage/local-store.d.ts.map +1 -0
  495. package/dist/storage/local-store.js +719 -0
  496. package/dist/storage/local-store.js.map +1 -0
  497. package/dist/storage/retention.d.ts +2 -0
  498. package/dist/storage/retention.d.ts.map +1 -0
  499. package/dist/storage/retention.js +53 -0
  500. package/dist/storage/retention.js.map +1 -0
  501. package/dist/storage/session-store.d.ts +97 -0
  502. package/dist/storage/session-store.d.ts.map +1 -0
  503. package/dist/storage/session-store.js +391 -0
  504. package/dist/storage/session-store.js.map +1 -0
  505. package/dist/storage/types.d.ts +64 -0
  506. package/dist/storage/types.d.ts.map +1 -0
  507. package/dist/storage/types.js +2 -0
  508. package/dist/storage/types.js.map +1 -0
  509. package/dist/storage/weekly-summary.d.ts +61 -0
  510. package/dist/storage/weekly-summary.d.ts.map +1 -0
  511. package/dist/storage/weekly-summary.js +243 -0
  512. package/dist/storage/weekly-summary.js.map +1 -0
  513. package/dist/tools/analytics-tools.d.ts +101 -0
  514. package/dist/tools/analytics-tools.d.ts.map +1 -0
  515. package/dist/tools/analytics-tools.js +71 -0
  516. package/dist/tools/analytics-tools.js.map +1 -0
  517. package/dist/tools/cost-tools.d.ts +121 -0
  518. package/dist/tools/cost-tools.d.ts.map +1 -0
  519. package/dist/tools/cost-tools.js +174 -0
  520. package/dist/tools/cost-tools.js.map +1 -0
  521. package/dist/tools/cross-session-tools.d.ts +376 -0
  522. package/dist/tools/cross-session-tools.d.ts.map +1 -0
  523. package/dist/tools/cross-session-tools.js +820 -0
  524. package/dist/tools/cross-session-tools.js.map +1 -0
  525. package/dist/tools/extended-analytics-tools.d.ts +164 -0
  526. package/dist/tools/extended-analytics-tools.d.ts.map +1 -0
  527. package/dist/tools/extended-analytics-tools.js +121 -0
  528. package/dist/tools/extended-analytics-tools.js.map +1 -0
  529. package/dist/tools/index.d.ts +7 -0
  530. package/dist/tools/index.d.ts.map +1 -0
  531. package/dist/tools/index.js +4 -0
  532. package/dist/tools/index.js.map +1 -0
  533. package/dist/tools/session-stats.d.ts +162 -0
  534. package/dist/tools/session-stats.d.ts.map +1 -0
  535. package/dist/tools/session-stats.js +1054 -0
  536. package/dist/tools/session-stats.js.map +1 -0
  537. package/dist/tools/workflow-tools.d.ts +126 -0
  538. package/dist/tools/workflow-tools.d.ts.map +1 -0
  539. package/dist/tools/workflow-tools.js +274 -0
  540. package/dist/tools/workflow-tools.js.map +1 -0
  541. package/dist/tracing/mcp-tracer.d.ts +4 -0
  542. package/dist/tracing/mcp-tracer.d.ts.map +1 -0
  543. package/dist/tracing/mcp-tracer.js +14 -0
  544. package/dist/tracing/mcp-tracer.js.map +1 -0
  545. package/dist/tracing/session-span.d.ts +14 -0
  546. package/dist/tracing/session-span.d.ts.map +1 -0
  547. package/dist/tracing/session-span.js +53 -0
  548. package/dist/tracing/session-span.js.map +1 -0
  549. package/dist/tracing/task-span-tracker.d.ts +11 -0
  550. package/dist/tracing/task-span-tracker.d.ts.map +1 -0
  551. package/dist/tracing/task-span-tracker.js +59 -0
  552. package/dist/tracing/task-span-tracker.js.map +1 -0
  553. package/dist/tracing/tool-call-span.d.ts +4 -0
  554. package/dist/tracing/tool-call-span.d.ts.map +1 -0
  555. package/dist/tracing/tool-call-span.js +60 -0
  556. package/dist/tracing/tool-call-span.js.map +1 -0
  557. package/dist/transport/index.d.ts +3 -0
  558. package/dist/transport/index.d.ts.map +1 -0
  559. package/dist/transport/index.js +2 -0
  560. package/dist/transport/index.js.map +1 -0
  561. package/dist/transport/log-ingest.d.ts +42 -0
  562. package/dist/transport/log-ingest.d.ts.map +1 -0
  563. package/dist/transport/log-ingest.js +151 -0
  564. package/dist/transport/log-ingest.js.map +1 -0
  565. package/dist/transport/nr-ingest.d.ts +171 -0
  566. package/dist/transport/nr-ingest.d.ts.map +1 -0
  567. package/dist/transport/nr-ingest.js +659 -0
  568. package/dist/transport/nr-ingest.js.map +1 -0
  569. package/dist/types.d.ts +45 -0
  570. package/dist/types.d.ts.map +1 -0
  571. package/dist/types.js +2 -0
  572. package/dist/types.js.map +1 -0
  573. package/dist/web/assets/index-BrL281N-.css +2 -0
  574. package/dist/web/assets/index-CcaYZzXm.js +42 -0
  575. package/dist/web/favicon.svg +15 -0
  576. package/dist/web/index.html +15 -0
  577. package/examples/local-alert-rules.json +106 -0
  578. package/package.json +125 -1
@@ -0,0 +1,337 @@
1
+ /**
2
+ * CLAUDE.md Change Impact Tracking — detects modifications to CLAUDE.md
3
+ * and `.claude/` configuration files, computes before/after metric deltas
4
+ * from stored sessions, estimates token context costs, and emits NR metrics.
5
+ *
6
+ * Change detection:
7
+ * - Within a session: Write/Edit tool calls targeting CLAUDE.md or .claude/
8
+ * - Between sessions: SHA-256 hash comparison of CLAUDE.md content
9
+ *
10
+ * Impact analysis:
11
+ * - Partitions sessions into before/after windows around a change timestamp
12
+ * - Compares efficiency, cost, correction rate, tool calls per task, and
13
+ * task success rate across the two windows
14
+ * - Generates a verdict string: "Positive impact", "Negative impact", or
15
+ * "Mixed impact" with the top changed metrics
16
+ */
17
+ import { createHash } from 'node:crypto';
18
+ import { readFileSync } from 'node:fs';
19
+ import { createLogger } from '../shared/index.js';
20
+ import { percentChange } from './trend-analyzer.js';
21
+ const logger = createLogger('claudemd-tracker');
22
+ // ---------------------------------------------------------------------------
23
+ // Constants
24
+ // ---------------------------------------------------------------------------
25
+ /** Rough heuristic: 1 char ≈ 0.25 tokens for English text. */
26
+ const TOKENS_PER_CHAR = 0.25;
27
+ /** Baseline input cost: Sonnet 4's $3 per million input tokens. */
28
+ const DEFAULT_INPUT_COST_PER_MTOK = 3;
29
+ /** Average turns per session — used for per-session cost estimation. */
30
+ const AVG_TURNS_PER_SESSION = 10;
31
+ /** Regex matching CLAUDE.md files and .claude/ directory contents. */
32
+ const CLAUDEMD_PATTERN = /(?:^|\/)CLAUDE\.md$|(?:^|\/)\.claude\//;
33
+ const MAX_CHANGES = 1_000;
34
+ // ---------------------------------------------------------------------------
35
+ // ClaudeMdTracker
36
+ // ---------------------------------------------------------------------------
37
+ export class ClaudeMdTracker {
38
+ sessionStore;
39
+ changes = [];
40
+ lastEmittedIndex = 0;
41
+ cachedImpact = null;
42
+ constructor(options) {
43
+ this.sessionStore = options.sessionStore;
44
+ }
45
+ /**
46
+ * Examine a tool call record and detect if it modifies a CLAUDE.md or
47
+ * `.claude/` file. Returns the change event if detected, null otherwise.
48
+ */
49
+ detectChange(toolCall) {
50
+ if (toolCall.toolName !== 'Write' && toolCall.toolName !== 'Edit') {
51
+ return null;
52
+ }
53
+ const rec = toolCall;
54
+ const filePath = typeof rec.filePath === 'string' ? rec.filePath : null;
55
+ if (!filePath || !CLAUDEMD_PATTERN.test(filePath)) {
56
+ return null;
57
+ }
58
+ let changeType;
59
+ let linesAdded = 0;
60
+ let linesRemoved = 0;
61
+ if (toolCall.toolName === 'Write') {
62
+ changeType = 'created';
63
+ linesAdded = typeof rec.lineCount === 'number' ? rec.lineCount : 0;
64
+ }
65
+ else {
66
+ // Edit tool
67
+ if (rec.isDelete === true) {
68
+ changeType = 'deleted';
69
+ }
70
+ else {
71
+ changeType = 'modified';
72
+ }
73
+ linesAdded = typeof rec.newLineCount === 'number' ? rec.newLineCount : 0;
74
+ linesRemoved = typeof rec.oldLineCount === 'number' ? rec.oldLineCount : 0;
75
+ }
76
+ const diffSummary = `${changeType} ${filePath}: +${linesAdded}/-${linesRemoved} lines`;
77
+ const change = {
78
+ timestamp: toolCall.timestamp,
79
+ sessionId: toolCall.sessionId ?? 'unknown',
80
+ filePath,
81
+ changeType,
82
+ diffSummary,
83
+ linesAdded,
84
+ linesRemoved,
85
+ };
86
+ this.appendChange(change);
87
+ this.cachedImpact = null;
88
+ logger.debug('CLAUDE.md change detected', { filePath, changeType });
89
+ return change;
90
+ }
91
+ /** Returns all detected changes in this tracker's lifetime. */
92
+ getChanges() {
93
+ return [...this.changes];
94
+ }
95
+ /**
96
+ * Compute SHA-256 hash of a file's content.
97
+ * Throws if the file does not exist.
98
+ */
99
+ static computeFileHash(filePath) {
100
+ const content = readFileSync(filePath, 'utf-8');
101
+ return createHash('sha256').update(content).digest('hex');
102
+ }
103
+ /**
104
+ * Detect whether CLAUDE.md changed between sessions by comparing hashes.
105
+ * Returns true if hashes differ. Returns false when previousHash is null
106
+ * (first session ever — no prior state to compare against, so no change).
107
+ */
108
+ static detectBetweenSessionChange(previousHash, currentHash) {
109
+ if (previousHash === null)
110
+ return false;
111
+ return previousHash !== currentHash;
112
+ }
113
+ /**
114
+ * Compare metrics in the N days before vs N days after a change timestamp.
115
+ * Returns a full impact report with deltas, context cost estimate, and verdict.
116
+ */
117
+ computeImpact(changeTimestamp, windowDays = 7) {
118
+ const windowMs = windowDays * 86_400_000;
119
+ const allSessions = this.sessionStore.loadAllSessions();
120
+ const beforeSessions = allSessions.filter((s) => s.startTime >= changeTimestamp - windowMs && s.startTime < changeTimestamp);
121
+ const afterSessions = allSessions.filter((s) => s.startTime >= changeTimestamp && s.startTime < changeTimestamp + windowMs);
122
+ const beforeMetrics = aggregateSessions(beforeSessions);
123
+ const afterMetrics = aggregateSessions(afterSessions);
124
+ const deltas = {
125
+ efficiencyScore: beforeMetrics.avgEfficiencyScore !== null && afterMetrics.avgEfficiencyScore !== null
126
+ ? computeDelta(beforeMetrics.avgEfficiencyScore, afterMetrics.avgEfficiencyScore, true)
127
+ : null,
128
+ cost: computeDelta(beforeMetrics.avgCostUsd, afterMetrics.avgCostUsd, false),
129
+ correctionRate: computeDelta(beforeMetrics.avgCorrectionRate, afterMetrics.avgCorrectionRate, false),
130
+ toolCallsPerTask: computeDelta(beforeMetrics.avgToolCallsPerTask, afterMetrics.avgToolCallsPerTask, false),
131
+ taskSuccessRate: beforeMetrics.avgTaskSuccessRate !== null && afterMetrics.avgTaskSuccessRate !== null
132
+ ? computeDelta(beforeMetrics.avgTaskSuccessRate, afterMetrics.avgTaskSuccessRate, true)
133
+ : null,
134
+ };
135
+ // Estimate context tokens from the actual file size
136
+ let contextTokensForClaudeMd = 0;
137
+ const latestChange = [...this.changes].reverse().find((c) => c.changeType !== 'deleted');
138
+ if (latestChange) {
139
+ try {
140
+ const cost = ClaudeMdTracker.estimateContextCost(latestChange.filePath);
141
+ contextTokensForClaudeMd = cost.estimatedTokens;
142
+ }
143
+ catch (err) {
144
+ if (err.code === 'ENOENT') {
145
+ contextTokensForClaudeMd = null;
146
+ }
147
+ else {
148
+ logger.warn('Failed to estimate CLAUDE.md context cost', { error: String(err) });
149
+ contextTokensForClaudeMd = 0;
150
+ }
151
+ }
152
+ }
153
+ // Generate verdict
154
+ const verdict = generateVerdict(deltas);
155
+ // Build change description
156
+ const lastChange = this.changes[this.changes.length - 1];
157
+ const changeDescription = lastChange?.diffSummary ?? 'Unknown change';
158
+ return {
159
+ changeDescription,
160
+ beforeMetrics,
161
+ afterMetrics,
162
+ deltas,
163
+ contextTokensForClaudeMd,
164
+ verdict,
165
+ };
166
+ }
167
+ appendChange(change) {
168
+ this.changes.push(change);
169
+ if (this.changes.length > MAX_CHANGES) {
170
+ const dropped = this.changes.length - MAX_CHANGES;
171
+ this.changes.splice(0, dropped);
172
+ this.lastEmittedIndex = Math.max(0, this.lastEmittedIndex - dropped);
173
+ }
174
+ }
175
+ getCachedImpact(timestamp) {
176
+ if (!this.cachedImpact || this.cachedImpact.timestamp !== timestamp) {
177
+ this.cachedImpact = { timestamp, report: this.computeImpact(timestamp) };
178
+ }
179
+ return this.cachedImpact.report;
180
+ }
181
+ /**
182
+ * Estimate the per-session and per-turn cost of loading a CLAUDE.md file
183
+ * into context. Reads the file and computes token estimate.
184
+ */
185
+ static estimateContextCost(claudeMdPath) {
186
+ const content = readFileSync(claudeMdPath, 'utf-8');
187
+ const charCount = content.length;
188
+ const estimatedTokens = Math.round(charCount * TOKENS_PER_CHAR);
189
+ const perTurnCostUsd = round((estimatedTokens / 1_000_000) * DEFAULT_INPUT_COST_PER_MTOK, 6);
190
+ const perSessionCostUsd = round(perTurnCostUsd * AVG_TURNS_PER_SESSION, 6);
191
+ return {
192
+ filePath: claudeMdPath,
193
+ charCount,
194
+ estimatedTokens,
195
+ perSessionCostUsd,
196
+ perTurnCostUsd,
197
+ };
198
+ }
199
+ /**
200
+ * Emit custom events and delta metrics for newly detected changes only.
201
+ * Impact report is cached and only recomputed when a new change arrives.
202
+ */
203
+ emitMetrics(aggregator) {
204
+ for (let i = this.lastEmittedIndex; i < this.changes.length; i++) {
205
+ const change = this.changes[i];
206
+ aggregator.record('ai.claudemd.change', 1, {
207
+ filePath: change.filePath,
208
+ changeType: change.changeType,
209
+ linesAdded: change.linesAdded,
210
+ linesRemoved: change.linesRemoved,
211
+ });
212
+ }
213
+ this.lastEmittedIndex = this.changes.length;
214
+ // Emit impact deltas for the latest change if we have one
215
+ if (this.changes.length > 0) {
216
+ const latest = this.changes[this.changes.length - 1];
217
+ const report = this.getCachedImpact(latest.timestamp);
218
+ if (report.deltas.efficiencyScore !== null) {
219
+ aggregator.record('ai.claudemd.post_change_efficiency_delta', report.deltas.efficiencyScore.value, { filePath: latest.filePath, changeType: latest.changeType });
220
+ }
221
+ aggregator.record('ai.claudemd.post_change_cost_delta', report.deltas.cost.value, {
222
+ filePath: latest.filePath,
223
+ changeType: latest.changeType,
224
+ });
225
+ }
226
+ logger.debug('CLAUDE.md change metrics emitted', { changeCount: this.changes.length });
227
+ }
228
+ reset() {
229
+ this.changes.length = 0;
230
+ this.lastEmittedIndex = 0;
231
+ this.cachedImpact = null;
232
+ }
233
+ }
234
+ // ---------------------------------------------------------------------------
235
+ // Session aggregation
236
+ // ---------------------------------------------------------------------------
237
+ function aggregateSessions(sessions) {
238
+ if (sessions.length === 0) {
239
+ return {
240
+ avgEfficiencyScore: null,
241
+ avgCostUsd: 0,
242
+ avgCorrectionRate: 0,
243
+ avgToolCallsPerTask: 0,
244
+ avgTaskSuccessRate: null,
245
+ sessionCount: 0,
246
+ };
247
+ }
248
+ let efficiencySum = 0;
249
+ let efficiencyCount = 0;
250
+ let totalCost = 0;
251
+ let totalCorrections = 0;
252
+ let totalUserMessages = 0;
253
+ let totalToolCalls = 0;
254
+ let totalTasks = 0;
255
+ let taskSuccessSum = 0;
256
+ for (const s of sessions) {
257
+ if (s.efficiencyScore !== null) {
258
+ efficiencySum += s.efficiencyScore;
259
+ efficiencyCount++;
260
+ }
261
+ totalCost += s.estimatedCostUsd ?? 0;
262
+ totalCorrections += s.userCorrections;
263
+ totalUserMessages += s.userMessages;
264
+ totalToolCalls += s.toolCallCount;
265
+ totalTasks += s.taskCount;
266
+ if (s.taskSuccessRate !== null) {
267
+ taskSuccessSum += s.taskSuccessRate * s.taskCount;
268
+ }
269
+ }
270
+ return {
271
+ avgEfficiencyScore: efficiencyCount > 0 ? round(efficiencySum / efficiencyCount, 3) : null,
272
+ avgCostUsd: round(totalCost / sessions.length, 4),
273
+ avgCorrectionRate: totalUserMessages > 0 ? round(totalCorrections / totalUserMessages, 3) : 0,
274
+ avgToolCallsPerTask: totalTasks > 0 ? round(totalToolCalls / totalTasks, 1) : 0,
275
+ avgTaskSuccessRate: totalTasks > 0 ? round(taskSuccessSum / totalTasks, 3) : null,
276
+ sessionCount: sessions.length,
277
+ };
278
+ }
279
+ // ---------------------------------------------------------------------------
280
+ // Delta computation
281
+ // ---------------------------------------------------------------------------
282
+ function computeDelta(beforeValue, afterValue, higherIsBetter) {
283
+ const value = round(afterValue - beforeValue, 4);
284
+ const pct = percentChange(beforeValue, afterValue);
285
+ const improved = higherIsBetter ? value > 0 : value < 0;
286
+ return { value, percentChange: pct, improved };
287
+ }
288
+ // ---------------------------------------------------------------------------
289
+ // Verdict generation
290
+ // ---------------------------------------------------------------------------
291
+ function generateVerdict(deltas) {
292
+ const entries = [
293
+ ...(deltas.efficiencyScore !== null
294
+ ? [{ name: 'efficiency', delta: deltas.efficiencyScore }]
295
+ : []),
296
+ { name: 'cost', delta: deltas.cost },
297
+ { name: 'corrections', delta: deltas.correctionRate },
298
+ { name: 'tool calls/task', delta: deltas.toolCallsPerTask },
299
+ ...(deltas.taskSuccessRate !== null
300
+ ? [{ name: 'task success', delta: deltas.taskSuccessRate }]
301
+ : []),
302
+ ];
303
+ const improved = entries.filter((e) => e.delta.improved);
304
+ const degraded = entries.filter((e) => !e.delta.improved && e.delta.value !== 0);
305
+ const formatMetric = (e) => {
306
+ if (e.delta.percentChange === null)
307
+ return `${e.name} ${e.delta.value > 0 ? '+' : ''}${e.delta.value}`;
308
+ const sign = e.delta.percentChange >= 0 ? '+' : '';
309
+ return `${e.name} ${sign}${e.delta.percentChange}%`;
310
+ };
311
+ // Sort by absolute percent change for most significant first (null treated as 0)
312
+ const sortByImpact = (a, b) => Math.abs(b.delta.percentChange ?? 0) - Math.abs(a.delta.percentChange ?? 0);
313
+ if (improved.length >= 3) {
314
+ const top = improved.sort(sortByImpact).slice(0, 2).map(formatMetric);
315
+ return `Positive impact: ${top.join(', ')}`;
316
+ }
317
+ if (degraded.length >= 3) {
318
+ const top = degraded.sort(sortByImpact).slice(0, 2).map(formatMetric);
319
+ return `Negative impact: ${top.join(', ')}`;
320
+ }
321
+ const parts = [];
322
+ if (improved.length > 0) {
323
+ parts.push(improved.sort(sortByImpact).slice(0, 1).map(formatMetric).join(''));
324
+ }
325
+ if (degraded.length > 0) {
326
+ parts.push(degraded.sort(sortByImpact).slice(0, 1).map(formatMetric).join(''));
327
+ }
328
+ return parts.length > 0 ? `Mixed impact: ${parts.join(', ')}` : 'No significant change';
329
+ }
330
+ // ---------------------------------------------------------------------------
331
+ // Helpers
332
+ // ---------------------------------------------------------------------------
333
+ function round(value, decimals) {
334
+ const factor = Math.pow(10, decimals);
335
+ return Math.round(value * factor) / factor;
336
+ }
337
+ //# sourceMappingURL=claudemd-tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claudemd-tracker.js","sourceRoot":"","sources":["../../src/metrics/claudemd-tracker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Developer Collaboration Profile — computes four profile dimensions from
3
+ * historical session data to characterize how a developer works with AI.
4
+ *
5
+ * Dimensions (each normalized to 0–1):
6
+ * 1. Specificity — how detailed are the developer's prompts?
7
+ * 2. Autonomy — how independently does the AI work?
8
+ * 3. Correction Rate — how rarely does the developer redirect the AI? (inverted)
9
+ * 4. Task Complexity — how complex are the tasks given to the AI?
10
+ *
11
+ * Classifications based on dimension thresholds:
12
+ * - "Power User": high specificity + high autonomy
13
+ * - "Delegator": low specificity + high autonomy
14
+ * - "Learning": low specificity + frequent corrections
15
+ * - "Collaborative": everything else
16
+ */
17
+ import type { MetricAggregator } from '../shared/index.js';
18
+ import type { SessionStore } from '../storage/session-store.js';
19
+ export interface ProfileDimensions {
20
+ readonly specificity: number;
21
+ readonly autonomy: number;
22
+ readonly correctionRate: number;
23
+ readonly taskComplexity: number;
24
+ }
25
+ export interface WeeklyProfile {
26
+ readonly week: string;
27
+ readonly dimensions: ProfileDimensions;
28
+ }
29
+ export interface DeveloperProfile {
30
+ readonly developer: string;
31
+ readonly dimensions: ProfileDimensions;
32
+ readonly weeklyProfiles: WeeklyProfile[];
33
+ readonly classification: string;
34
+ readonly sessionCount: number;
35
+ }
36
+ export interface TeamBaseline {
37
+ readonly dimensions: ProfileDimensions;
38
+ readonly developerCount: number;
39
+ readonly sessionCount: number;
40
+ }
41
+ export interface TeamComparison {
42
+ readonly developer: string;
43
+ readonly developerDimensions: ProfileDimensions;
44
+ readonly teamDimensions: ProfileDimensions;
45
+ readonly deltas: ProfileDimensions;
46
+ }
47
+ export declare class CollaborationProfiler {
48
+ private readonly sessionStore;
49
+ constructor(options: {
50
+ sessionStore: SessionStore;
51
+ });
52
+ computeProfile(developer: string, options?: {
53
+ since?: Date;
54
+ }): DeveloperProfile;
55
+ computeTeamBaseline(options?: {
56
+ since?: Date;
57
+ }): TeamBaseline;
58
+ compareToTeam(developer: string, options?: {
59
+ since?: Date;
60
+ }): TeamComparison;
61
+ emitMetrics(aggregator: MetricAggregator, options?: {
62
+ since?: Date;
63
+ }): void;
64
+ }
65
+ //# sourceMappingURL=collaboration-profile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collaboration-profile.d.ts","sourceRoot":"","sources":["../../src/metrics/collaboration-profile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAQhE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAC;CACxC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAC;IACvC,QAAQ,CAAC,cAAc,EAAE,aAAa,EAAE,CAAC;IACzC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAC;IACvC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,mBAAmB,EAAE,iBAAiB,CAAC;IAChD,QAAQ,CAAC,cAAc,EAAE,iBAAiB,CAAC;IAC3C,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;CACpC;AAMD,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;gBAEhC,OAAO,EAAE;QAAE,YAAY,EAAE,YAAY,CAAA;KAAE;IAInD,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,IAAI,CAAA;KAAE,GAAG,gBAAgB;IAmB/E,mBAAmB,CAAC,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,IAAI,CAAA;KAAE,GAAG,YAAY;IA8C7D,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,IAAI,CAAA;KAAE,GAAG,cAAc;IAuB5E,WAAW,CAAC,UAAU,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,IAAI,CAAA;KAAE,GAAG,IAAI;CAoB5E"}
@@ -0,0 +1,231 @@
1
+ /**
2
+ * Developer Collaboration Profile — computes four profile dimensions from
3
+ * historical session data to characterize how a developer works with AI.
4
+ *
5
+ * Dimensions (each normalized to 0–1):
6
+ * 1. Specificity — how detailed are the developer's prompts?
7
+ * 2. Autonomy — how independently does the AI work?
8
+ * 3. Correction Rate — how rarely does the developer redirect the AI? (inverted)
9
+ * 4. Task Complexity — how complex are the tasks given to the AI?
10
+ *
11
+ * Classifications based on dimension thresholds:
12
+ * - "Power User": high specificity + high autonomy
13
+ * - "Delegator": low specificity + high autonomy
14
+ * - "Learning": low specificity + frequent corrections
15
+ * - "Collaborative": everything else
16
+ */
17
+ import { getIsoWeekId } from '../storage/weekly-summary.js';
18
+ // ---------------------------------------------------------------------------
19
+ // CollaborationProfiler
20
+ // ---------------------------------------------------------------------------
21
+ export class CollaborationProfiler {
22
+ sessionStore;
23
+ constructor(options) {
24
+ this.sessionStore = options.sessionStore;
25
+ }
26
+ computeProfile(developer, options) {
27
+ const sessions = this.sessionStore.loadAllSessions({
28
+ since: options?.since,
29
+ developer,
30
+ });
31
+ const dimensions = computeDimensions(sessions);
32
+ const weeklyProfiles = computeWeeklyProfiles(sessions);
33
+ const classification = classify(dimensions);
34
+ return {
35
+ developer,
36
+ dimensions,
37
+ weeklyProfiles,
38
+ classification,
39
+ sessionCount: sessions.length,
40
+ };
41
+ }
42
+ computeTeamBaseline(options) {
43
+ const allSessions = this.sessionStore.loadAllSessions({ since: options?.since });
44
+ // Group by developer and compute per-developer dimensions
45
+ const byDeveloper = new Map();
46
+ for (const s of allSessions) {
47
+ const list = byDeveloper.get(s.developer) ?? [];
48
+ list.push(s);
49
+ byDeveloper.set(s.developer, list);
50
+ }
51
+ if (byDeveloper.size === 0) {
52
+ return {
53
+ dimensions: { specificity: 0, autonomy: 0, correctionRate: 0, taskComplexity: 0 },
54
+ developerCount: 0,
55
+ sessionCount: 0,
56
+ };
57
+ }
58
+ let totalSpecificity = 0;
59
+ let totalAutonomy = 0;
60
+ let totalCorrectionRate = 0;
61
+ let totalTaskComplexity = 0;
62
+ for (const [, devSessions] of byDeveloper) {
63
+ const dims = computeDimensions(devSessions);
64
+ totalSpecificity += dims.specificity;
65
+ totalAutonomy += dims.autonomy;
66
+ totalCorrectionRate += dims.correctionRate;
67
+ totalTaskComplexity += dims.taskComplexity;
68
+ }
69
+ const n = byDeveloper.size;
70
+ return {
71
+ dimensions: {
72
+ specificity: round(totalSpecificity / n, 3),
73
+ autonomy: round(totalAutonomy / n, 3),
74
+ correctionRate: round(totalCorrectionRate / n, 3),
75
+ taskComplexity: round(totalTaskComplexity / n, 3),
76
+ },
77
+ developerCount: n,
78
+ sessionCount: allSessions.length,
79
+ };
80
+ }
81
+ compareToTeam(developer, options) {
82
+ const profile = this.computeProfile(developer, options);
83
+ const baseline = this.computeTeamBaseline(options);
84
+ return {
85
+ developer,
86
+ developerDimensions: profile.dimensions,
87
+ teamDimensions: baseline.dimensions,
88
+ deltas: {
89
+ specificity: round(profile.dimensions.specificity - baseline.dimensions.specificity, 3),
90
+ autonomy: round(profile.dimensions.autonomy - baseline.dimensions.autonomy, 3),
91
+ correctionRate: round(profile.dimensions.correctionRate - baseline.dimensions.correctionRate, 3),
92
+ taskComplexity: round(profile.dimensions.taskComplexity - baseline.dimensions.taskComplexity, 3),
93
+ },
94
+ };
95
+ }
96
+ emitMetrics(aggregator, options) {
97
+ const allSessions = this.sessionStore.loadAllSessions({ since: options?.since });
98
+ const byDeveloper = new Map();
99
+ for (const s of allSessions) {
100
+ const list = byDeveloper.get(s.developer) ?? [];
101
+ list.push(s);
102
+ byDeveloper.set(s.developer, list);
103
+ }
104
+ for (const [developer, devSessions] of byDeveloper) {
105
+ const dims = computeDimensions(devSessions);
106
+ const attrs = { developer };
107
+ aggregator.record('ai.collaboration.specificity', dims.specificity, attrs);
108
+ aggregator.record('ai.collaboration.autonomy', dims.autonomy, attrs);
109
+ aggregator.record('ai.collaboration.correction_rate', dims.correctionRate, attrs);
110
+ aggregator.record('ai.collaboration.task_complexity', dims.taskComplexity, attrs);
111
+ }
112
+ }
113
+ }
114
+ // ---------------------------------------------------------------------------
115
+ // Dimension computation
116
+ // ---------------------------------------------------------------------------
117
+ function computeDimensions(sessions) {
118
+ if (sessions.length === 0) {
119
+ return { specificity: 0, autonomy: 0, correctionRate: 0, taskComplexity: 0 };
120
+ }
121
+ let totalToolCalls = 0;
122
+ let totalUserMessages = 0;
123
+ let totalAssistantMessages = 0;
124
+ let totalUserCorrections = 0;
125
+ let totalFiles = 0;
126
+ let totalTasks = 0;
127
+ let totalAgentSpawns = 0;
128
+ for (const s of sessions) {
129
+ totalToolCalls += s.toolCallCount;
130
+ totalUserMessages += s.userMessages;
131
+ totalAssistantMessages += s.assistantMessages;
132
+ totalUserCorrections += s.userCorrections;
133
+ totalFiles += s.filesRead.length + s.filesModified.length;
134
+ totalTasks += s.taskCount;
135
+ totalAgentSpawns += s.agentSpawns;
136
+ }
137
+ return {
138
+ specificity: computeSpecificity(totalToolCalls, totalUserMessages),
139
+ autonomy: computeAutonomy(totalToolCalls, totalAssistantMessages),
140
+ correctionRate: computeCorrectionRate(totalUserCorrections, totalUserMessages),
141
+ taskComplexity: computeTaskComplexity(totalFiles, totalToolCalls, totalAgentSpawns, totalTasks),
142
+ };
143
+ }
144
+ /**
145
+ * Specificity: ratio of tool calls to user messages, normalized so 10:1 = 1.0.
146
+ * When userMessages is 0, falls back to 0.5 (unknown).
147
+ */
148
+ function computeSpecificity(toolCalls, userMessages) {
149
+ if (userMessages === 0)
150
+ return 0.5;
151
+ const ratio = toolCalls / userMessages;
152
+ return clamp(round(ratio / 10, 3), 0, 1);
153
+ }
154
+ /**
155
+ * Autonomy: tool calls per assistant message, normalized so 5 tool calls/turn = 1.0.
156
+ * Measures how much multi-step work the AI does independently per turn.
157
+ * When assistantMessages is 0, falls back to 0.5 (neutral/unknown).
158
+ */
159
+ function computeAutonomy(toolCalls, assistantMessages) {
160
+ if (assistantMessages === 0)
161
+ return 0.5;
162
+ const ratio = toolCalls / assistantMessages;
163
+ return clamp(round(ratio / 5, 3), 0, 1);
164
+ }
165
+ /**
166
+ * Correction rate (inverted): 1 - (corrections / messages). 1.0 = no corrections.
167
+ * When userMessages is 0, falls back to 1.0 (no corrections observed).
168
+ */
169
+ function computeCorrectionRate(corrections, userMessages) {
170
+ if (userMessages === 0)
171
+ return 1;
172
+ return clamp(round(1 - corrections / userMessages, 3), 0, 1);
173
+ }
174
+ /**
175
+ * Task complexity: composite of avg files per task, avg tool calls per task,
176
+ * and avg agent spawns per task, each normalized against reasonable baselines.
177
+ */
178
+ function computeTaskComplexity(totalFiles, totalToolCalls, totalAgentSpawns, totalTasks) {
179
+ if (totalTasks === 0)
180
+ return 0;
181
+ const avgFiles = totalFiles / totalTasks;
182
+ const avgToolCalls = totalToolCalls / totalTasks;
183
+ const avgAgents = totalAgentSpawns / totalTasks;
184
+ // Normalize each component against reasonable baselines
185
+ const filesComponent = avgFiles / 20; // 20 files per task = max
186
+ const toolCallsComponent = avgToolCalls / 50; // 50 tool calls per task = max
187
+ const agentsComponent = avgAgents / 3; // 3 agents per task = max
188
+ const composite = (filesComponent + toolCallsComponent + agentsComponent) / 3;
189
+ return clamp(round(composite, 3), 0, 1);
190
+ }
191
+ // ---------------------------------------------------------------------------
192
+ // Classification
193
+ // ---------------------------------------------------------------------------
194
+ function classify(dimensions) {
195
+ const { specificity, autonomy, correctionRate } = dimensions;
196
+ if (specificity >= 0.6 && autonomy >= 0.6)
197
+ return 'Power User';
198
+ if (specificity < 0.6 && autonomy >= 0.6)
199
+ return 'Delegator';
200
+ if (specificity < 0.6 && autonomy < 0.6 && correctionRate < 0.6)
201
+ return 'Learning';
202
+ return 'Collaborative';
203
+ }
204
+ // ---------------------------------------------------------------------------
205
+ // Weekly profiles
206
+ // ---------------------------------------------------------------------------
207
+ function computeWeeklyProfiles(sessions) {
208
+ const byWeek = new Map();
209
+ for (const s of sessions) {
210
+ const week = getIsoWeekId(new Date(s.startTime));
211
+ const list = byWeek.get(week) ?? [];
212
+ list.push(s);
213
+ byWeek.set(week, list);
214
+ }
215
+ const profiles = [];
216
+ for (const [week, weekSessions] of byWeek) {
217
+ profiles.push({ week, dimensions: computeDimensions(weekSessions) });
218
+ }
219
+ return profiles.sort((a, b) => a.week.localeCompare(b.week));
220
+ }
221
+ // ---------------------------------------------------------------------------
222
+ // Helpers
223
+ // ---------------------------------------------------------------------------
224
+ function clamp(value, min, max) {
225
+ return Math.min(max, Math.max(min, value));
226
+ }
227
+ function round(value, decimals) {
228
+ const factor = Math.pow(10, decimals);
229
+ return Math.round(value * factor) / factor;
230
+ }
231
+ //# sourceMappingURL=collaboration-profile.js.map