@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,820 @@
1
+ /**
2
+ * MCP tool definitions and handlers for cross-session analytics and digest delivery.
3
+ *
4
+ * Tools: nr_observe_get_session_history, nr_observe_get_weekly_summary,
5
+ * nr_observe_get_trends, nr_observe_get_collaboration_profile,
6
+ * nr_observe_get_claudemd_impact, nr_observe_get_cost_per_outcome,
7
+ * nr_observe_get_recommendations, nr_observe_get_platform_comparison,
8
+ * nr_observe_get_team_summary, nr_observe_subscribe_digest,
9
+ * nr_observe_unsubscribe_digest, nr_observe_send_digest
10
+ *
11
+ * Tool defs and handlers are exported for integration into the main
12
+ * registerTools() in session-stats.ts.
13
+ */
14
+ import { readFileSync, writeFileSync } from 'node:fs';
15
+ import { formatSlackDigest } from '../digest/digest-formatter.js';
16
+ import { sendSlackDigest } from '../digest/digest-sender.js';
17
+ import { getIsoWeekId } from '../storage/weekly-summary.js';
18
+ import { PersonalCoach } from '../metrics/personal-coach.js';
19
+ function getNerdgraphUrl(collectorHost) {
20
+ if (collectorHost === 'eu')
21
+ return 'https://api.eu.newrelic.com/graphql';
22
+ return 'https://api.newrelic.com/graphql';
23
+ }
24
+ // ---------------------------------------------------------------------------
25
+ // Tool definitions
26
+ // ---------------------------------------------------------------------------
27
+ export const SESSION_HISTORY_TOOL = {
28
+ name: 'nr_observe_get_session_history',
29
+ description: 'Get a list of past sessions with summary metrics (efficiency, cost, tool calls, outcome).',
30
+ inputSchema: {
31
+ type: 'object',
32
+ properties: {
33
+ since: {
34
+ type: 'string',
35
+ description: 'ISO date string to filter sessions from (e.g., "2026-04-01")',
36
+ },
37
+ developer: {
38
+ type: 'string',
39
+ description: 'Filter by developer name',
40
+ },
41
+ limit: {
42
+ type: 'number',
43
+ description: 'Maximum number of sessions to return (default: 20)',
44
+ },
45
+ },
46
+ },
47
+ annotations: { readOnlyHint: true },
48
+ };
49
+ export const WEEKLY_SUMMARY_TOOL = {
50
+ name: 'nr_observe_get_weekly_summary',
51
+ description: 'Get a weekly summary report with per-developer breakdown, cost, efficiency, and anti-pattern counts.',
52
+ inputSchema: {
53
+ type: 'object',
54
+ properties: {
55
+ week: {
56
+ type: 'string',
57
+ description: 'ISO week (e.g., "2026-W16") or "latest" for the most recent summary',
58
+ },
59
+ },
60
+ },
61
+ annotations: { readOnlyHint: true },
62
+ };
63
+ export const TRENDS_TOOL = {
64
+ name: 'nr_observe_get_trends',
65
+ description: 'Get trend data for a metric over time: weekly efficiency, cost, task success rate, or tool call counts.',
66
+ inputSchema: {
67
+ type: 'object',
68
+ properties: {
69
+ metric: {
70
+ type: 'string',
71
+ description: 'Metric to trend: "efficiency", "cost", "task_success", or "tool_calls" (default: "efficiency")',
72
+ },
73
+ developer: {
74
+ type: 'string',
75
+ description: 'Filter by developer name',
76
+ },
77
+ weeks: {
78
+ type: 'number',
79
+ description: 'Number of weeks to include (default: 8)',
80
+ },
81
+ },
82
+ },
83
+ annotations: { readOnlyHint: true },
84
+ };
85
+ export const COLLABORATION_PROFILE_TOOL = {
86
+ name: 'nr_observe_get_collaboration_profile',
87
+ description: "Get a developer's collaboration profile: specificity, autonomy, correction rate, task complexity, and classification.",
88
+ inputSchema: {
89
+ type: 'object',
90
+ properties: {
91
+ developer: {
92
+ type: 'string',
93
+ description: 'Developer name (default: current developer)',
94
+ },
95
+ },
96
+ },
97
+ annotations: { readOnlyHint: true },
98
+ };
99
+ export const CLAUDEMD_IMPACT_TOOL = {
100
+ name: 'nr_observe_get_claudemd_impact',
101
+ description: 'Get the impact report for the most recent CLAUDE.md change: before/after comparison with deltas and verdict.',
102
+ inputSchema: {
103
+ type: 'object',
104
+ properties: {},
105
+ },
106
+ annotations: { readOnlyHint: true },
107
+ };
108
+ export const COST_PER_OUTCOME_TOOL = {
109
+ name: 'nr_observe_get_cost_per_outcome',
110
+ description: 'Get cost breakdown by outcome type (bug fix, feature, refactor, etc.) with waste ratio and ROI estimate.',
111
+ inputSchema: {
112
+ type: 'object',
113
+ properties: {
114
+ since: {
115
+ type: 'string',
116
+ description: 'ISO date string to filter from (e.g., "2026-04-01")',
117
+ },
118
+ },
119
+ },
120
+ annotations: { readOnlyHint: true },
121
+ };
122
+ export const RECOMMENDATIONS_TOOL = {
123
+ name: 'nr_observe_get_recommendations',
124
+ description: 'Get personalized optimization recommendations covering cost, efficiency, prompt engineering, CLAUDE.md impact, and model selection.',
125
+ inputSchema: {
126
+ type: 'object',
127
+ properties: {
128
+ developer: {
129
+ type: 'string',
130
+ description: 'Developer name (default: current developer)',
131
+ },
132
+ topN: {
133
+ type: 'number',
134
+ description: 'Maximum number of recommendations to return',
135
+ },
136
+ },
137
+ },
138
+ annotations: { readOnlyHint: true },
139
+ };
140
+ export const PLATFORM_COMPARISON_TOOL = {
141
+ name: 'nr_observe_get_platform_comparison',
142
+ description: 'Compare AI coding assistant platforms side-by-side on a given metric: efficiency, cost, task_success, tool_calls, or error_rate.',
143
+ inputSchema: {
144
+ type: 'object',
145
+ properties: {
146
+ metric: {
147
+ type: 'string',
148
+ description: 'Metric to compare: "efficiency", "cost", "task_success", "tool_calls", or "error_rate" (default: "efficiency")',
149
+ },
150
+ weeks: {
151
+ type: 'number',
152
+ description: 'Number of weeks to include (default: 4)',
153
+ },
154
+ },
155
+ },
156
+ annotations: { readOnlyHint: true },
157
+ };
158
+ export const TEAM_SUMMARY_TOOL = {
159
+ name: 'nr_observe_get_team_summary',
160
+ description: 'Get aggregated AI coding cost and efficiency metrics for all developers in the configured team, queried via New Relic NRQL. Requires teamId to be set in config.',
161
+ inputSchema: {
162
+ type: 'object',
163
+ properties: {
164
+ since: {
165
+ type: 'string',
166
+ description: 'Time window (e.g. "7 days ago", "1 day ago"). Default: "7 days ago".',
167
+ },
168
+ },
169
+ },
170
+ annotations: { readOnlyHint: true },
171
+ };
172
+ export const SUBSCRIBE_DIGEST_TOOL = {
173
+ name: 'nr_observe_subscribe_digest',
174
+ description: 'Register a Slack webhook URL to receive weekly AI coding cost and efficiency summaries.',
175
+ inputSchema: {
176
+ type: 'object',
177
+ properties: {
178
+ webhookUrl: {
179
+ type: 'string',
180
+ description: 'Slack incoming webhook URL (https://hooks.slack.com/...)',
181
+ },
182
+ },
183
+ required: ['webhookUrl'],
184
+ },
185
+ annotations: { readOnlyHint: false },
186
+ };
187
+ export const UNSUBSCRIBE_DIGEST_TOOL = {
188
+ name: 'nr_observe_unsubscribe_digest',
189
+ description: 'Remove the registered Slack webhook for weekly digests.',
190
+ inputSchema: { type: 'object', properties: {} },
191
+ annotations: { readOnlyHint: false },
192
+ };
193
+ export const SEND_DIGEST_TOOL = {
194
+ name: 'nr_observe_send_digest',
195
+ description: 'Generate the current weekly AI coding summary and POST it to the configured Slack webhook immediately.',
196
+ inputSchema: { type: 'object', properties: {} },
197
+ annotations: { readOnlyHint: false },
198
+ };
199
+ export const PERSONAL_INSIGHTS_TOOL = {
200
+ name: 'nr_observe_get_personal_insights',
201
+ description: "Returns a narrative coaching report comparing this week's personal AI coding metrics against your historical baseline. " +
202
+ 'Includes highlights, regressions, streaks, and a top recommendation. ' +
203
+ 'Requires at least 2 weeks of session history. ' +
204
+ 'Returns status: "insufficient_data" with a message when history is too sparse.',
205
+ inputSchema: {
206
+ type: 'object',
207
+ properties: {},
208
+ required: [],
209
+ },
210
+ annotations: { readOnlyHint: true },
211
+ };
212
+ // ---------------------------------------------------------------------------
213
+ // All tool definitions (for conditional registration)
214
+ // ---------------------------------------------------------------------------
215
+ export const CROSS_SESSION_TOOLS = [
216
+ SESSION_HISTORY_TOOL,
217
+ WEEKLY_SUMMARY_TOOL,
218
+ TRENDS_TOOL,
219
+ COLLABORATION_PROFILE_TOOL,
220
+ CLAUDEMD_IMPACT_TOOL,
221
+ COST_PER_OUTCOME_TOOL,
222
+ RECOMMENDATIONS_TOOL,
223
+ PLATFORM_COMPARISON_TOOL,
224
+ TEAM_SUMMARY_TOOL,
225
+ ];
226
+ // ---------------------------------------------------------------------------
227
+ // Utilities
228
+ // ---------------------------------------------------------------------------
229
+ export function toFiniteNumber(x, fallback = 0) {
230
+ const n = Number(x);
231
+ return Number.isFinite(n) ? n : fallback;
232
+ }
233
+ // ---------------------------------------------------------------------------
234
+ // Handlers
235
+ // ---------------------------------------------------------------------------
236
+ export function handleGetSessionHistory(sessionStore, args) {
237
+ const since = args.since ? new Date(args.since) : undefined;
238
+ if (since && isNaN(since.getTime())) {
239
+ return {
240
+ content: [{ type: 'text', text: JSON.stringify({ error: 'Invalid since date' }) }],
241
+ isError: true,
242
+ };
243
+ }
244
+ const developer = typeof args.developer === 'string' ? args.developer.slice(0, 256) : undefined;
245
+ const sessions = sessionStore.loadAllSessions({
246
+ since,
247
+ developer,
248
+ });
249
+ const limit = Math.max(1, Math.min(Math.floor(args.limit ?? 20), 500));
250
+ const limited = sessions.slice(-limit);
251
+ const result = limited.map((s) => ({
252
+ session_id: s.sessionId,
253
+ session_name: s.sessionName ?? null,
254
+ developer: s.developer,
255
+ start_time: new Date(s.startTime).toISOString(),
256
+ duration_ms: s.durationMs,
257
+ tool_calls: s.toolCallCount,
258
+ efficiency_score: s.efficiencyScore,
259
+ estimated_cost_usd: s.estimatedCostUsd,
260
+ task_count: s.taskCount,
261
+ outcome: s.outcome,
262
+ model: s.model,
263
+ }));
264
+ return {
265
+ content: [
266
+ {
267
+ type: 'text',
268
+ text: JSON.stringify({ sessions: result, count: result.length }, null, 2),
269
+ },
270
+ ],
271
+ };
272
+ }
273
+ export function handleGetWeeklySummary(weeklySummaryGenerator, args) {
274
+ if (!args.week || args.week === 'latest') {
275
+ const latest = weeklySummaryGenerator.getLatest();
276
+ if (!latest) {
277
+ // Generate current week
278
+ const currentWeek = getIsoWeekId(new Date());
279
+ const generated = weeklySummaryGenerator.generate(currentWeek);
280
+ return {
281
+ content: [
282
+ {
283
+ type: 'text',
284
+ text: JSON.stringify(generated, null, 2),
285
+ },
286
+ ],
287
+ };
288
+ }
289
+ return {
290
+ content: [
291
+ {
292
+ type: 'text',
293
+ text: JSON.stringify(latest, null, 2),
294
+ },
295
+ ],
296
+ };
297
+ }
298
+ // N-03: validate week format before it reaches file-path construction
299
+ if (!/^\d{4}-W\d{2}$/.test(args.week)) {
300
+ return {
301
+ content: [
302
+ {
303
+ type: 'text',
304
+ text: JSON.stringify({
305
+ error: 'Invalid week format. Use YYYY-Wnn (e.g. "2026-W16") or "latest".',
306
+ }),
307
+ },
308
+ ],
309
+ isError: true,
310
+ };
311
+ }
312
+ const summary = weeklySummaryGenerator.generate(args.week);
313
+ return {
314
+ content: [
315
+ {
316
+ type: 'text',
317
+ text: JSON.stringify(summary, null, 2),
318
+ },
319
+ ],
320
+ };
321
+ }
322
+ export function handleGetTrends(trendAnalyzer, args) {
323
+ const weeks = Math.max(1, args.weeks ?? 8);
324
+ const since = new Date(Date.now() - weeks * 7 * 86_400_000);
325
+ const developer = typeof args.developer === 'string' ? args.developer.slice(0, 256) : undefined;
326
+ const trends = trendAnalyzer.computeTrends({
327
+ since,
328
+ developer,
329
+ });
330
+ const metric = args.metric ?? 'efficiency';
331
+ let data;
332
+ switch (metric) {
333
+ case 'cost':
334
+ data = trends.weeklyCostTrend;
335
+ break;
336
+ case 'task_success':
337
+ data = trends.weeklyTaskSuccessTrend;
338
+ break;
339
+ case 'tool_calls':
340
+ data = trends.weeklyToolCallTrend;
341
+ break;
342
+ case 'efficiency':
343
+ default:
344
+ data = trends.weeklyEfficiencyTrend;
345
+ break;
346
+ }
347
+ return {
348
+ content: [
349
+ {
350
+ type: 'text',
351
+ text: JSON.stringify({ metric, weeks, data_points: data }, null, 2),
352
+ },
353
+ ],
354
+ };
355
+ }
356
+ export function handleGetCollaborationProfile(collaborationProfiler, args) {
357
+ const developer = typeof args.developer === 'string'
358
+ ? args.developer.trim().slice(0, 256) || 'unknown'
359
+ : 'unknown';
360
+ const profile = collaborationProfiler.computeProfile(developer);
361
+ const comparison = collaborationProfiler.compareToTeam(developer);
362
+ return {
363
+ content: [
364
+ {
365
+ type: 'text',
366
+ text: JSON.stringify({
367
+ developer: profile.developer,
368
+ classification: profile.classification,
369
+ dimensions: profile.dimensions,
370
+ session_count: profile.sessionCount,
371
+ team_comparison: comparison.deltas,
372
+ }, null, 2),
373
+ },
374
+ ],
375
+ };
376
+ }
377
+ export function handleGetClaudeMdImpact(claudeMdTracker) {
378
+ const changes = claudeMdTracker.getChanges();
379
+ if (changes.length === 0) {
380
+ return {
381
+ content: [
382
+ {
383
+ type: 'text',
384
+ text: JSON.stringify({ message: 'No CLAUDE.md changes detected' }, null, 2),
385
+ },
386
+ ],
387
+ };
388
+ }
389
+ const latestChange = changes[changes.length - 1];
390
+ const impact = claudeMdTracker.computeImpact(latestChange.timestamp);
391
+ return {
392
+ content: [
393
+ {
394
+ type: 'text',
395
+ text: JSON.stringify({
396
+ change: {
397
+ file: latestChange.filePath,
398
+ type: latestChange.changeType,
399
+ timestamp: new Date(latestChange.timestamp).toISOString(),
400
+ },
401
+ before: impact.beforeMetrics,
402
+ after: impact.afterMetrics,
403
+ deltas: impact.deltas,
404
+ context_tokens: impact.contextTokensForClaudeMd,
405
+ verdict: impact.verdict,
406
+ }, null, 2),
407
+ },
408
+ ],
409
+ };
410
+ }
411
+ export function handleGetCostPerOutcome(costPerOutcomeAnalyzer, taskDetector, args) {
412
+ let tasks = taskDetector.getCompletedTasks();
413
+ const current = taskDetector.getCurrentTask();
414
+ if (current) {
415
+ tasks = [...tasks, current];
416
+ }
417
+ if (args.since) {
418
+ const sinceMs = new Date(args.since).getTime();
419
+ if (isNaN(sinceMs)) {
420
+ return {
421
+ content: [
422
+ {
423
+ type: 'text',
424
+ text: JSON.stringify({ error: `Invalid since date: "${args.since}"` }),
425
+ },
426
+ ],
427
+ isError: true,
428
+ };
429
+ }
430
+ tasks = tasks.filter((t) => t.startTime >= sinceMs);
431
+ }
432
+ const attribution = costPerOutcomeAnalyzer.attributeCosts(tasks);
433
+ const roi = costPerOutcomeAnalyzer.estimateROI(attribution, 75); // default $75/hr
434
+ return {
435
+ content: [
436
+ {
437
+ type: 'text',
438
+ text: JSON.stringify({
439
+ outcome_distribution: attribution.outcomeDistribution,
440
+ waste_ratio: attribution.wasteRatio,
441
+ total_cost: attribution.totalCost,
442
+ total_tasks: attribution.totalTasks,
443
+ roi_estimate: roi,
444
+ }, null, 2),
445
+ },
446
+ ],
447
+ };
448
+ }
449
+ export function handleGetRecommendations(recommendationEngine, args) {
450
+ const developer = typeof args.developer === 'string'
451
+ ? args.developer.trim().slice(0, 256) || 'unknown'
452
+ : 'unknown';
453
+ const recs = recommendationEngine.generateAllRecommendations(developer, {
454
+ topN: args.topN,
455
+ });
456
+ return {
457
+ content: [
458
+ {
459
+ type: 'text',
460
+ text: JSON.stringify({ recommendations: recs, count: recs.length }, null, 2),
461
+ },
462
+ ],
463
+ };
464
+ }
465
+ export function handleGetPlatformComparison(sessionStore, args) {
466
+ const weeks = args.weeks ?? 4;
467
+ const since = new Date(Date.now() - weeks * 7 * 86_400_000);
468
+ const metric = args.metric ?? 'efficiency';
469
+ const sessions = sessionStore.loadAllSessions({ since });
470
+ // Group sessions by platform (uses 'claude-code' as default)
471
+ const byPlatform = new Map();
472
+ for (const s of sessions) {
473
+ const rawPlatform = s.platform;
474
+ const platform = typeof rawPlatform === 'string' ? rawPlatform : 'claude-code';
475
+ const list = byPlatform.get(platform) ?? [];
476
+ list.push(s);
477
+ byPlatform.set(platform, list);
478
+ }
479
+ const comparison = {};
480
+ for (const [platform, platformSessions] of byPlatform) {
481
+ const count = platformSessions.length;
482
+ if (count === 0)
483
+ continue;
484
+ let value;
485
+ switch (metric) {
486
+ case 'cost': {
487
+ const total = platformSessions.reduce((sum, s) => sum + (s.estimatedCostUsd ?? 0), 0);
488
+ value = Math.round((total / count) * 100) / 100;
489
+ break;
490
+ }
491
+ case 'task_success': {
492
+ const total = platformSessions.reduce((sum, s) => sum + (s.taskSuccessRate ?? 0), 0);
493
+ value = Math.round((total / count) * 100) / 100;
494
+ break;
495
+ }
496
+ case 'tool_calls': {
497
+ const total = platformSessions.reduce((sum, s) => sum + (s.toolCallCount ?? 0), 0);
498
+ value = Math.round(total / count);
499
+ break;
500
+ }
501
+ case 'error_rate': {
502
+ let weightedErrors = 0;
503
+ let totalTc = 0;
504
+ for (const s of platformSessions) {
505
+ const tc = s.toolCallCount ?? 0;
506
+ const errorRate = 1 - (s.toolSuccessRate ?? 1);
507
+ weightedErrors += tc * errorRate;
508
+ totalTc += tc;
509
+ }
510
+ value = totalTc > 0 ? Math.round((weightedErrors / totalTc) * 100) / 100 : 0;
511
+ break;
512
+ }
513
+ case 'efficiency':
514
+ default: {
515
+ const total = platformSessions.reduce((sum, s) => sum + (s.efficiencyScore ?? 0), 0);
516
+ value = Math.round((total / count) * 100) / 100;
517
+ break;
518
+ }
519
+ }
520
+ comparison[platform] = {
521
+ session_count: count,
522
+ average: value,
523
+ };
524
+ }
525
+ return {
526
+ content: [
527
+ {
528
+ type: 'text',
529
+ text: JSON.stringify({ metric, weeks, platforms: comparison }, null, 2),
530
+ },
531
+ ],
532
+ };
533
+ }
534
+ export async function handleGetTeamSummary(options) {
535
+ if (!options.teamId) {
536
+ return {
537
+ content: [
538
+ {
539
+ type: 'text',
540
+ text: JSON.stringify({
541
+ error: 'teamId is not configured. Set NEW_RELIC_AI_TEAM_ID or teamId in config.',
542
+ }),
543
+ },
544
+ ],
545
+ isError: true,
546
+ };
547
+ }
548
+ if (!options.nrApiKey) {
549
+ return {
550
+ content: [
551
+ {
552
+ type: 'text',
553
+ text: JSON.stringify({
554
+ error: 'NEW_RELIC_API_KEY (User key) is required for team summary queries.',
555
+ }),
556
+ },
557
+ ],
558
+ isError: true,
559
+ };
560
+ }
561
+ // Validate `since` against a strict allowlist: "<N> <unit>(s) ago"
562
+ const rawSince = options.since ?? '7 days ago';
563
+ if (!/^\d+\s+(?:minute|hour|day|week)s?\s+ago$/i.test(rawSince)) {
564
+ return {
565
+ content: [
566
+ {
567
+ type: 'text',
568
+ text: JSON.stringify({
569
+ error: 'Invalid since value. Use a relative time like "7 days ago", "24 hours ago", or "1 week ago".',
570
+ }),
571
+ },
572
+ ],
573
+ isError: true,
574
+ };
575
+ }
576
+ const since = rawSince;
577
+ if (!/^[a-zA-Z0-9_-]+$/.test(options.teamId)) {
578
+ return {
579
+ content: [
580
+ {
581
+ type: 'text',
582
+ text: JSON.stringify({
583
+ error: 'Invalid teamId format. Allowed characters: a-z, A-Z, 0-9, underscore, hyphen.',
584
+ }),
585
+ },
586
+ ],
587
+ isError: true,
588
+ };
589
+ }
590
+ const safeTeamId = options.teamId;
591
+ const accountId = Number(options.accountId);
592
+ if (!Number.isFinite(accountId) || accountId <= 0) {
593
+ return {
594
+ content: [
595
+ {
596
+ type: 'text',
597
+ text: JSON.stringify({
598
+ error: `Invalid accountId: "${options.accountId}" is not a valid number`,
599
+ }),
600
+ },
601
+ ],
602
+ isError: true,
603
+ };
604
+ }
605
+ const nerdgraphQuery = `query($accountId: Int!, $nrql: Nrql!) {
606
+ actor { account(id: $accountId) { nrql(query: $nrql) { results } } }
607
+ }`;
608
+ const nerdgraphUrl = getNerdgraphUrl(options.collectorHost ?? null);
609
+ async function runNrql(nrql) {
610
+ const resp = await fetch(nerdgraphUrl, {
611
+ method: 'POST',
612
+ headers: { 'Content-Type': 'application/json', 'API-Key': options.nrApiKey },
613
+ body: JSON.stringify({ query: nerdgraphQuery, variables: { accountId, nrql } }),
614
+ });
615
+ if (!resp.ok) {
616
+ throw new Error(`NerdGraph request failed: HTTP ${resp.status} ${resp.statusText}`);
617
+ }
618
+ const json = (await resp.json());
619
+ if (json.errors && Array.isArray(json.errors) && json.errors.length > 0) {
620
+ const msg = json.errors
621
+ .map((e) => String(e.message ?? e))
622
+ .join('; ');
623
+ throw new Error(`NerdGraph errors: ${msg}`);
624
+ }
625
+ if (!json.data?.actor?.account?.nrql?.results) {
626
+ throw new Error('NerdGraph query returned no data (unexpected response structure)');
627
+ }
628
+ return json.data.actor.account.nrql.results;
629
+ }
630
+ let costRows;
631
+ let effRows;
632
+ let antiPatternRows;
633
+ try {
634
+ [costRows, effRows, antiPatternRows] = await Promise.all([
635
+ runNrql(`SELECT sum(ai.estimated_cost_usd) AS totalCost
636
+ FROM AiCodingTask WHERE team_id = '${safeTeamId}'
637
+ SINCE ${since} FACET developer LIMIT 50`),
638
+ runNrql(`SELECT average(ai.efficiency.score) AS avgScore
639
+ FROM Metric WHERE team_id = '${safeTeamId}'
640
+ SINCE ${since} FACET developer LIMIT 50`),
641
+ runNrql(`SELECT count(*) AS antiPatterns
642
+ FROM AiAntiPattern WHERE team_id = '${safeTeamId}'
643
+ SINCE ${since} FACET developer LIMIT 50`),
644
+ ]);
645
+ }
646
+ catch (err) {
647
+ return {
648
+ content: [
649
+ {
650
+ type: 'text',
651
+ text: JSON.stringify({
652
+ error: `Failed to query New Relic: ${err instanceof Error ? err.message : String(err)}`,
653
+ }),
654
+ },
655
+ ],
656
+ isError: true,
657
+ };
658
+ }
659
+ // Use Object.create(null) to prevent prototype-pollution if a developer name
660
+ // is "__proto__", "constructor", or "toString".
661
+ const byDev = Object.create(null);
662
+ for (const row of costRows) {
663
+ const dev = ((row.developer && String(row.developer).trim()) || 'unknown');
664
+ if (!byDev[dev])
665
+ byDev[dev] = { costUsd: 0, efficiencyScore: null, antiPatterns: 0 };
666
+ byDev[dev].costUsd = toFiniteNumber(row.totalCost);
667
+ }
668
+ for (const row of effRows) {
669
+ const dev = ((row.developer && String(row.developer).trim()) || 'unknown');
670
+ if (!byDev[dev])
671
+ byDev[dev] = { costUsd: 0, efficiencyScore: null, antiPatterns: 0 };
672
+ const score = toFiniteNumber(row.avgScore, Number.NaN);
673
+ byDev[dev].efficiencyScore = Number.isFinite(score) ? score : null;
674
+ }
675
+ for (const row of antiPatternRows) {
676
+ const dev = ((row.developer && String(row.developer).trim()) || 'unknown');
677
+ if (!byDev[dev])
678
+ byDev[dev] = { costUsd: 0, efficiencyScore: null, antiPatterns: 0 };
679
+ byDev[dev].antiPatterns = toFiniteNumber(row.antiPatterns);
680
+ }
681
+ const result = {
682
+ teamId: options.teamId,
683
+ since,
684
+ developers: Object.entries(byDev).map(([developer, stats]) => ({ developer, ...stats })),
685
+ totals: {
686
+ costUsd: Object.values(byDev).reduce((s, d) => s + d.costUsd, 0),
687
+ developerCount: Object.keys(byDev).length,
688
+ },
689
+ };
690
+ return { content: [{ type: 'text', text: JSON.stringify(result) }] };
691
+ }
692
+ export function handleSubscribeDigest(webhookUrl, configFilePath) {
693
+ if (!webhookUrl.startsWith('https://hooks.slack.com/')) {
694
+ return {
695
+ content: [
696
+ {
697
+ type: 'text',
698
+ text: JSON.stringify({
699
+ error: 'webhookUrl must be a Slack incoming webhook URL (https://hooks.slack.com/...)',
700
+ }),
701
+ },
702
+ ],
703
+ isError: true,
704
+ };
705
+ }
706
+ try {
707
+ let existing = {};
708
+ try {
709
+ existing = JSON.parse(readFileSync(configFilePath, 'utf-8'));
710
+ }
711
+ catch {
712
+ /* no existing config */
713
+ }
714
+ existing.digestWebhookUrl = webhookUrl;
715
+ writeFileSync(configFilePath, JSON.stringify(existing, null, 2), { mode: 0o600 });
716
+ return {
717
+ content: [
718
+ {
719
+ type: 'text',
720
+ text: JSON.stringify({
721
+ ok: true,
722
+ message: 'Webhook registered. Digest will be sent on the configured schedule.',
723
+ }),
724
+ },
725
+ ],
726
+ };
727
+ }
728
+ catch (err) {
729
+ return {
730
+ content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }],
731
+ isError: true,
732
+ };
733
+ }
734
+ }
735
+ export function handleUnsubscribeDigest(configFilePath) {
736
+ try {
737
+ let existing = {};
738
+ try {
739
+ existing = JSON.parse(readFileSync(configFilePath, 'utf-8'));
740
+ }
741
+ catch {
742
+ /* no existing config */
743
+ }
744
+ delete existing.digestWebhookUrl;
745
+ writeFileSync(configFilePath, JSON.stringify(existing, null, 2), { mode: 0o600 });
746
+ return {
747
+ content: [{ type: 'text', text: JSON.stringify({ ok: true, message: 'Webhook removed.' }) }],
748
+ };
749
+ }
750
+ catch (err) {
751
+ return {
752
+ content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }],
753
+ isError: true,
754
+ };
755
+ }
756
+ }
757
+ export async function handleSendDigest(weeklySummaryGenerator, configFilePath) {
758
+ // Read webhook URL from config file at call time (not in-memory config, which won't
759
+ // reflect updates made via nr_observe_subscribe_digest without a server restart).
760
+ let webhookUrl;
761
+ try {
762
+ const raw = JSON.parse(readFileSync(configFilePath, 'utf-8'));
763
+ if (typeof raw.digestWebhookUrl === 'string') {
764
+ webhookUrl = raw.digestWebhookUrl;
765
+ }
766
+ }
767
+ catch {
768
+ /* config file may not exist yet */
769
+ }
770
+ if (!webhookUrl) {
771
+ return {
772
+ content: [
773
+ {
774
+ type: 'text',
775
+ text: JSON.stringify({
776
+ error: 'No webhook URL configured. Call nr_observe_subscribe_digest first.',
777
+ }),
778
+ },
779
+ ],
780
+ };
781
+ }
782
+ const currentWeek = getIsoWeekId(new Date());
783
+ const summary = weeklySummaryGenerator.generate(currentWeek);
784
+ const payload = formatSlackDigest(summary);
785
+ try {
786
+ await sendSlackDigest(webhookUrl, payload);
787
+ return {
788
+ content: [
789
+ {
790
+ type: 'text',
791
+ text: JSON.stringify({
792
+ ok: true,
793
+ week: currentWeek,
794
+ message: 'Digest sent successfully.',
795
+ }),
796
+ },
797
+ ],
798
+ };
799
+ }
800
+ catch (err) {
801
+ return {
802
+ content: [
803
+ {
804
+ type: 'text',
805
+ text: JSON.stringify({
806
+ error: `Failed to send digest: ${err instanceof Error ? err.message : String(err)}`,
807
+ }),
808
+ },
809
+ ],
810
+ };
811
+ }
812
+ }
813
+ export function handleGetPersonalInsights(summaryGenerator, developer) {
814
+ const coach = new PersonalCoach(summaryGenerator, developer);
815
+ const result = coach.generate();
816
+ return {
817
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
818
+ };
819
+ }
820
+ //# sourceMappingURL=cross-session-tools.js.map