@newrelic/preflight 0.0.1-pre.1 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +183 -0
- package/README.md +498 -0
- package/dist/alerts/alert-log.d.ts +24 -0
- package/dist/alerts/alert-log.d.ts.map +1 -0
- package/dist/alerts/alert-log.js +159 -0
- package/dist/alerts/alert-log.js.map +1 -0
- package/dist/alerts/alert-snapshot-collector.d.ts +168 -0
- package/dist/alerts/alert-snapshot-collector.d.ts.map +1 -0
- package/dist/alerts/alert-snapshot-collector.js +243 -0
- package/dist/alerts/alert-snapshot-collector.js.map +1 -0
- package/dist/alerts/local-alert-engine.d.ts +86 -0
- package/dist/alerts/local-alert-engine.d.ts.map +1 -0
- package/dist/alerts/local-alert-engine.js +466 -0
- package/dist/alerts/local-alert-engine.js.map +1 -0
- package/dist/alerts/local-alert-rule.d.ts +439 -0
- package/dist/alerts/local-alert-rule.d.ts.map +1 -0
- package/dist/alerts/local-alert-rule.js +139 -0
- package/dist/alerts/local-alert-rule.js.map +1 -0
- package/dist/alerts/os-notifier.d.ts +39 -0
- package/dist/alerts/os-notifier.d.ts.map +1 -0
- package/dist/alerts/os-notifier.js +170 -0
- package/dist/alerts/os-notifier.js.map +1 -0
- package/dist/alerts/types.d.ts +35 -0
- package/dist/alerts/types.d.ts.map +1 -0
- package/dist/alerts/types.js +8 -0
- package/dist/alerts/types.js.map +1 -0
- package/dist/config.d.ts +169 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +868 -0
- package/dist/config.js.map +1 -0
- package/dist/dashboard/dashboard-server.d.ts +38 -0
- package/dist/dashboard/dashboard-server.d.ts.map +1 -0
- package/dist/dashboard/dashboard-server.js +207 -0
- package/dist/dashboard/dashboard-server.js.map +1 -0
- package/dist/dashboard/index.d.ts +3 -0
- package/dist/dashboard/index.d.ts.map +1 -0
- package/dist/dashboard/index.js +2 -0
- package/dist/dashboard/index.js.map +1 -0
- package/dist/dashboard/live-event-bus.d.ts +99 -0
- package/dist/dashboard/live-event-bus.d.ts.map +1 -0
- package/dist/dashboard/live-event-bus.js +56 -0
- package/dist/dashboard/live-event-bus.js.map +1 -0
- package/dist/dashboard/routes/api-handler.d.ts +122 -0
- package/dist/dashboard/routes/api-handler.d.ts.map +1 -0
- package/dist/dashboard/routes/api-handler.js +1414 -0
- package/dist/dashboard/routes/api-handler.js.map +1 -0
- package/dist/dashboard/routes/replay-analyzer.d.ts +15 -0
- package/dist/dashboard/routes/replay-analyzer.d.ts.map +1 -0
- package/dist/dashboard/routes/replay-analyzer.js +227 -0
- package/dist/dashboard/routes/replay-analyzer.js.map +1 -0
- package/dist/dashboard/routes/sse-handler.d.ts +4 -0
- package/dist/dashboard/routes/sse-handler.d.ts.map +1 -0
- package/dist/dashboard/routes/sse-handler.js +122 -0
- package/dist/dashboard/routes/sse-handler.js.map +1 -0
- package/dist/dashboard/routes/static-handler.d.ts +3 -0
- package/dist/dashboard/routes/static-handler.d.ts.map +1 -0
- package/dist/dashboard/routes/static-handler.js +123 -0
- package/dist/dashboard/routes/static-handler.js.map +1 -0
- package/dist/data/alerts/conditions/01-daily-cost-spike.json +16 -0
- package/dist/data/alerts/conditions/02-low-efficiency-score.json +16 -0
- package/dist/data/alerts/conditions/03-stuck-loop-rate.json +16 -0
- package/dist/data/alerts/conditions/04-anti-pattern-rate.json +16 -0
- package/dist/data/alerts/conditions/05-session-cost-budget.json +16 -0
- package/dist/data/alerts/conditions-personal/01-personal-daily-cost.json +16 -0
- package/dist/data/alerts/conditions-personal/02-personal-session-cost.json +16 -0
- package/dist/data/alerts/conditions-personal/03-personal-low-efficiency.json +16 -0
- package/dist/data/alerts/conditions-personal/04-personal-anti-pattern-rate.json +16 -0
- package/dist/data/alerts/conditions-personal/05-personal-stuck-loop.json +16 -0
- package/dist/data/alerts/policy.json +4 -0
- package/dist/data/dashboards/ai-coding-assistant-manager-view.json +103 -0
- package/dist/data/dashboards/ai-coding-assistant-overview.json +239 -0
- package/dist/data/dashboards/ai-coding-assistant-personal.json +442 -0
- package/dist/data/dashboards/ai-coding-assistant-platform-comparison.json +320 -0
- package/dist/data/dashboards/ai-coding-assistant-security.json +275 -0
- package/dist/data/dashboards/ai-coding-assistant-session-detail.json +296 -0
- package/dist/data/dashboards/ai-coding-assistant-team-view.json +345 -0
- package/dist/deploy/data-paths.d.ts +22 -0
- package/dist/deploy/data-paths.d.ts.map +1 -0
- package/dist/deploy/data-paths.js +69 -0
- package/dist/deploy/data-paths.js.map +1 -0
- package/dist/deploy/deploy-alerts.d.ts +58 -0
- package/dist/deploy/deploy-alerts.d.ts.map +1 -0
- package/dist/deploy/deploy-alerts.js +371 -0
- package/dist/deploy/deploy-alerts.js.map +1 -0
- package/dist/deploy/deploy-dashboards.d.ts +92 -0
- package/dist/deploy/deploy-dashboards.d.ts.map +1 -0
- package/dist/deploy/deploy-dashboards.js +282 -0
- package/dist/deploy/deploy-dashboards.js.map +1 -0
- package/dist/digest/digest-formatter.d.ts +3 -0
- package/dist/digest/digest-formatter.d.ts.map +1 -0
- package/dist/digest/digest-formatter.js +37 -0
- package/dist/digest/digest-formatter.js.map +1 -0
- package/dist/digest/digest-sender.d.ts +2 -0
- package/dist/digest/digest-sender.d.ts.map +1 -0
- package/dist/digest/digest-sender.js +29 -0
- package/dist/digest/digest-sender.js.map +1 -0
- package/dist/hooks/bash-classifier.d.ts +26 -0
- package/dist/hooks/bash-classifier.d.ts.map +1 -0
- package/dist/hooks/bash-classifier.js +409 -0
- package/dist/hooks/bash-classifier.js.map +1 -0
- package/dist/hooks/collector-script.d.ts +47 -0
- package/dist/hooks/collector-script.d.ts.map +1 -0
- package/dist/hooks/collector-script.js +662 -0
- package/dist/hooks/collector-script.js.map +1 -0
- package/dist/hooks/event-processor.d.ts +65 -0
- package/dist/hooks/event-processor.d.ts.map +1 -0
- package/dist/hooks/event-processor.js +342 -0
- package/dist/hooks/event-processor.js.map +1 -0
- package/dist/hooks/index.d.ts +7 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +5 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/session-resolver.d.ts +66 -0
- package/dist/hooks/session-resolver.d.ts.map +1 -0
- package/dist/hooks/session-resolver.js +196 -0
- package/dist/hooks/session-resolver.js.map +1 -0
- package/dist/hooks/tool-parsers.d.ts +19 -0
- package/dist/hooks/tool-parsers.d.ts.map +1 -0
- package/dist/hooks/tool-parsers.js +260 -0
- package/dist/hooks/tool-parsers.js.map +1 -0
- package/dist/index.d.ts +107 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1505 -0
- package/dist/index.js.map +1 -0
- package/dist/install/cli.d.ts +11 -0
- package/dist/install/cli.d.ts.map +1 -0
- package/dist/install/cli.js +365 -0
- package/dist/install/cli.js.map +1 -0
- package/dist/install/index.d.ts +4 -0
- package/dist/install/index.d.ts.map +1 -0
- package/dist/install/index.js +3 -0
- package/dist/install/index.js.map +1 -0
- package/dist/install/install-helper.d.ts +35 -0
- package/dist/install/install-helper.d.ts.map +1 -0
- package/dist/install/install-helper.js +227 -0
- package/dist/install/install-helper.js.map +1 -0
- package/dist/install/key-validator.d.ts +19 -0
- package/dist/install/key-validator.d.ts.map +1 -0
- package/dist/install/key-validator.js +122 -0
- package/dist/install/key-validator.js.map +1 -0
- package/dist/install/migrate.d.ts +12 -0
- package/dist/install/migrate.d.ts.map +1 -0
- package/dist/install/migrate.js +115 -0
- package/dist/install/migrate.js.map +1 -0
- package/dist/install/schedule.d.ts +11 -0
- package/dist/install/schedule.d.ts.map +1 -0
- package/dist/install/schedule.js +114 -0
- package/dist/install/schedule.js.map +1 -0
- package/dist/install/setup-wizard.d.ts +40 -0
- package/dist/install/setup-wizard.d.ts.map +1 -0
- package/dist/install/setup-wizard.js +489 -0
- package/dist/install/setup-wizard.js.map +1 -0
- package/dist/lib/date.d.ts +54 -0
- package/dist/lib/date.d.ts.map +1 -0
- package/dist/lib/date.js +85 -0
- package/dist/lib/date.js.map +1 -0
- package/dist/metrics/anti-patterns.d.ts +62 -0
- package/dist/metrics/anti-patterns.d.ts.map +1 -0
- package/dist/metrics/anti-patterns.js +301 -0
- package/dist/metrics/anti-patterns.js.map +1 -0
- package/dist/metrics/api-failure-tracker.d.ts +82 -0
- package/dist/metrics/api-failure-tracker.d.ts.map +1 -0
- package/dist/metrics/api-failure-tracker.js +202 -0
- package/dist/metrics/api-failure-tracker.js.map +1 -0
- package/dist/metrics/budget-tracker.d.ts +60 -0
- package/dist/metrics/budget-tracker.d.ts.map +1 -0
- package/dist/metrics/budget-tracker.js +130 -0
- package/dist/metrics/budget-tracker.js.map +1 -0
- package/dist/metrics/claudemd-tracker.d.ts +108 -0
- package/dist/metrics/claudemd-tracker.d.ts.map +1 -0
- package/dist/metrics/claudemd-tracker.js +337 -0
- package/dist/metrics/claudemd-tracker.js.map +1 -0
- package/dist/metrics/collaboration-profile.d.ts +65 -0
- package/dist/metrics/collaboration-profile.d.ts.map +1 -0
- package/dist/metrics/collaboration-profile.js +231 -0
- package/dist/metrics/collaboration-profile.js.map +1 -0
- package/dist/metrics/context-composition-tracker.d.ts +74 -0
- package/dist/metrics/context-composition-tracker.d.ts.map +1 -0
- package/dist/metrics/context-composition-tracker.js +202 -0
- package/dist/metrics/context-composition-tracker.js.map +1 -0
- package/dist/metrics/context-tracker.d.ts +78 -0
- package/dist/metrics/context-tracker.d.ts.map +1 -0
- package/dist/metrics/context-tracker.js +222 -0
- package/dist/metrics/context-tracker.js.map +1 -0
- package/dist/metrics/context-window-tracker.d.ts +18 -0
- package/dist/metrics/context-window-tracker.d.ts.map +1 -0
- package/dist/metrics/context-window-tracker.js +35 -0
- package/dist/metrics/context-window-tracker.js.map +1 -0
- package/dist/metrics/cost-forecast.d.ts +36 -0
- package/dist/metrics/cost-forecast.d.ts.map +1 -0
- package/dist/metrics/cost-forecast.js +91 -0
- package/dist/metrics/cost-forecast.js.map +1 -0
- package/dist/metrics/cost-per-outcome.d.ts +102 -0
- package/dist/metrics/cost-per-outcome.d.ts.map +1 -0
- package/dist/metrics/cost-per-outcome.js +266 -0
- package/dist/metrics/cost-per-outcome.js.map +1 -0
- package/dist/metrics/cost-tracker.d.ts +78 -0
- package/dist/metrics/cost-tracker.d.ts.map +1 -0
- package/dist/metrics/cost-tracker.js +169 -0
- package/dist/metrics/cost-tracker.js.map +1 -0
- package/dist/metrics/decision-tracker.d.ts +49 -0
- package/dist/metrics/decision-tracker.d.ts.map +1 -0
- package/dist/metrics/decision-tracker.js +161 -0
- package/dist/metrics/decision-tracker.js.map +1 -0
- package/dist/metrics/efficiency-score.d.ts +80 -0
- package/dist/metrics/efficiency-score.d.ts.map +1 -0
- package/dist/metrics/efficiency-score.js +219 -0
- package/dist/metrics/efficiency-score.js.map +1 -0
- package/dist/metrics/git-efficiency-tracker.d.ts +165 -0
- package/dist/metrics/git-efficiency-tracker.d.ts.map +1 -0
- package/dist/metrics/git-efficiency-tracker.js +1056 -0
- package/dist/metrics/git-efficiency-tracker.js.map +1 -0
- package/dist/metrics/index.d.ts +26 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +14 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/instruction-drift-tracker.d.ts +69 -0
- package/dist/metrics/instruction-drift-tracker.d.ts.map +1 -0
- package/dist/metrics/instruction-drift-tracker.js +213 -0
- package/dist/metrics/instruction-drift-tracker.js.map +1 -0
- package/dist/metrics/latency-decomposition.d.ts +50 -0
- package/dist/metrics/latency-decomposition.d.ts.map +1 -0
- package/dist/metrics/latency-decomposition.js +112 -0
- package/dist/metrics/latency-decomposition.js.map +1 -0
- package/dist/metrics/latency-tracker.d.ts +33 -0
- package/dist/metrics/latency-tracker.d.ts.map +1 -0
- package/dist/metrics/latency-tracker.js +93 -0
- package/dist/metrics/latency-tracker.js.map +1 -0
- package/dist/metrics/live-session-registry.d.ts +29 -0
- package/dist/metrics/live-session-registry.d.ts.map +1 -0
- package/dist/metrics/live-session-registry.js +103 -0
- package/dist/metrics/live-session-registry.js.map +1 -0
- package/dist/metrics/model-usage-tracker.d.ts +21 -0
- package/dist/metrics/model-usage-tracker.d.ts.map +1 -0
- package/dist/metrics/model-usage-tracker.js +53 -0
- package/dist/metrics/model-usage-tracker.js.map +1 -0
- package/dist/metrics/percentile.d.ts +5 -0
- package/dist/metrics/percentile.d.ts.map +1 -0
- package/dist/metrics/percentile.js +10 -0
- package/dist/metrics/percentile.js.map +1 -0
- package/dist/metrics/personal-coach.d.ts +47 -0
- package/dist/metrics/personal-coach.d.ts.map +1 -0
- package/dist/metrics/personal-coach.js +241 -0
- package/dist/metrics/personal-coach.js.map +1 -0
- package/dist/metrics/prompt-feedback.d.ts +75 -0
- package/dist/metrics/prompt-feedback.d.ts.map +1 -0
- package/dist/metrics/prompt-feedback.js +286 -0
- package/dist/metrics/prompt-feedback.js.map +1 -0
- package/dist/metrics/proxy-metrics.d.ts +54 -0
- package/dist/metrics/proxy-metrics.d.ts.map +1 -0
- package/dist/metrics/proxy-metrics.js +228 -0
- package/dist/metrics/proxy-metrics.js.map +1 -0
- package/dist/metrics/quality-proxy-tracker.d.ts +51 -0
- package/dist/metrics/quality-proxy-tracker.d.ts.map +1 -0
- package/dist/metrics/quality-proxy-tracker.js +162 -0
- package/dist/metrics/quality-proxy-tracker.js.map +1 -0
- package/dist/metrics/recommendation-engine.d.ts +72 -0
- package/dist/metrics/recommendation-engine.d.ts.map +1 -0
- package/dist/metrics/recommendation-engine.js +207 -0
- package/dist/metrics/recommendation-engine.js.map +1 -0
- package/dist/metrics/retry-detector.d.ts +43 -0
- package/dist/metrics/retry-detector.d.ts.map +1 -0
- package/dist/metrics/retry-detector.js +179 -0
- package/dist/metrics/retry-detector.js.map +1 -0
- package/dist/metrics/session-tracker.d.ts +75 -0
- package/dist/metrics/session-tracker.d.ts.map +1 -0
- package/dist/metrics/session-tracker.js +249 -0
- package/dist/metrics/session-tracker.js.map +1 -0
- package/dist/metrics/task-completion-tracker.d.ts +15 -0
- package/dist/metrics/task-completion-tracker.d.ts.map +1 -0
- package/dist/metrics/task-completion-tracker.js +27 -0
- package/dist/metrics/task-completion-tracker.js.map +1 -0
- package/dist/metrics/task-detector.d.ts +84 -0
- package/dist/metrics/task-detector.d.ts.map +1 -0
- package/dist/metrics/task-detector.js +302 -0
- package/dist/metrics/task-detector.js.map +1 -0
- package/dist/metrics/tool-selection-scorer.d.ts +39 -0
- package/dist/metrics/tool-selection-scorer.d.ts.map +1 -0
- package/dist/metrics/tool-selection-scorer.js +193 -0
- package/dist/metrics/tool-selection-scorer.js.map +1 -0
- package/dist/metrics/trend-analyzer.d.ts +92 -0
- package/dist/metrics/trend-analyzer.d.ts.map +1 -0
- package/dist/metrics/trend-analyzer.js +293 -0
- package/dist/metrics/trend-analyzer.js.map +1 -0
- package/dist/metrics/turn-cost-attributor.d.ts +41 -0
- package/dist/metrics/turn-cost-attributor.d.ts.map +1 -0
- package/dist/metrics/turn-cost-attributor.js +118 -0
- package/dist/metrics/turn-cost-attributor.js.map +1 -0
- package/dist/metrics/turn-tracker.d.ts +49 -0
- package/dist/metrics/turn-tracker.d.ts.map +1 -0
- package/dist/metrics/turn-tracker.js +192 -0
- package/dist/metrics/turn-tracker.js.map +1 -0
- package/dist/platforms/amazon-q-adapter.d.ts +10 -0
- package/dist/platforms/amazon-q-adapter.d.ts.map +1 -0
- package/dist/platforms/amazon-q-adapter.js +75 -0
- package/dist/platforms/amazon-q-adapter.js.map +1 -0
- package/dist/platforms/claude-code-adapter.d.ts +10 -0
- package/dist/platforms/claude-code-adapter.d.ts.map +1 -0
- package/dist/platforms/claude-code-adapter.js +48 -0
- package/dist/platforms/claude-code-adapter.js.map +1 -0
- package/dist/platforms/continue-adapter.d.ts +10 -0
- package/dist/platforms/continue-adapter.d.ts.map +1 -0
- package/dist/platforms/continue-adapter.js +73 -0
- package/dist/platforms/continue-adapter.js.map +1 -0
- package/dist/platforms/copilot-adapter.d.ts +37 -0
- package/dist/platforms/copilot-adapter.d.ts.map +1 -0
- package/dist/platforms/copilot-adapter.js +66 -0
- package/dist/platforms/copilot-adapter.js.map +1 -0
- package/dist/platforms/cursor-adapter.d.ts +10 -0
- package/dist/platforms/cursor-adapter.d.ts.map +1 -0
- package/dist/platforms/cursor-adapter.js +60 -0
- package/dist/platforms/cursor-adapter.js.map +1 -0
- package/dist/platforms/generic-mcp-adapter.d.ts +113 -0
- package/dist/platforms/generic-mcp-adapter.d.ts.map +1 -0
- package/dist/platforms/generic-mcp-adapter.js +139 -0
- package/dist/platforms/generic-mcp-adapter.js.map +1 -0
- package/dist/platforms/index.d.ts +15 -0
- package/dist/platforms/index.d.ts.map +1 -0
- package/dist/platforms/index.js +12 -0
- package/dist/platforms/index.js.map +1 -0
- package/dist/platforms/platform-registry.d.ts +11 -0
- package/dist/platforms/platform-registry.d.ts.map +1 -0
- package/dist/platforms/platform-registry.js +54 -0
- package/dist/platforms/platform-registry.js.map +1 -0
- package/dist/platforms/types.d.ts +36 -0
- package/dist/platforms/types.d.ts.map +1 -0
- package/dist/platforms/types.js +2 -0
- package/dist/platforms/types.js.map +1 -0
- package/dist/platforms/windsurf-adapter.d.ts +10 -0
- package/dist/platforms/windsurf-adapter.d.ts.map +1 -0
- package/dist/platforms/windsurf-adapter.js +63 -0
- package/dist/platforms/windsurf-adapter.js.map +1 -0
- package/dist/platforms/zed-adapter.d.ts +10 -0
- package/dist/platforms/zed-adapter.d.ts.map +1 -0
- package/dist/platforms/zed-adapter.js +72 -0
- package/dist/platforms/zed-adapter.js.map +1 -0
- package/dist/proxy/index.d.ts +7 -0
- package/dist/proxy/index.d.ts.map +1 -0
- package/dist/proxy/index.js +5 -0
- package/dist/proxy/index.js.map +1 -0
- package/dist/proxy/otlp-receiver.d.ts +28 -0
- package/dist/proxy/otlp-receiver.d.ts.map +1 -0
- package/dist/proxy/otlp-receiver.js +319 -0
- package/dist/proxy/otlp-receiver.js.map +1 -0
- package/dist/proxy/proxy-manager.d.ts +47 -0
- package/dist/proxy/proxy-manager.d.ts.map +1 -0
- package/dist/proxy/proxy-manager.js +338 -0
- package/dist/proxy/proxy-manager.js.map +1 -0
- package/dist/proxy/types.d.ts +72 -0
- package/dist/proxy/types.d.ts.map +1 -0
- package/dist/proxy/types.js +33 -0
- package/dist/proxy/types.js.map +1 -0
- package/dist/proxy/upstream-http.d.ts +26 -0
- package/dist/proxy/upstream-http.d.ts.map +1 -0
- package/dist/proxy/upstream-http.js +209 -0
- package/dist/proxy/upstream-http.js.map +1 -0
- package/dist/proxy/upstream-stdio.d.ts +25 -0
- package/dist/proxy/upstream-stdio.d.ts.map +1 -0
- package/dist/proxy/upstream-stdio.js +256 -0
- package/dist/proxy/upstream-stdio.js.map +1 -0
- package/dist/security/audit-trail.d.ts +74 -0
- package/dist/security/audit-trail.d.ts.map +1 -0
- package/dist/security/audit-trail.js +338 -0
- package/dist/security/audit-trail.js.map +1 -0
- package/dist/security/index.d.ts +5 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +4 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/ssrf.d.ts +2 -0
- package/dist/security/ssrf.d.ts.map +1 -0
- package/dist/security/ssrf.js +126 -0
- package/dist/security/ssrf.js.map +1 -0
- package/dist/server.d.ts +14 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +117 -0
- package/dist/server.js.map +1 -0
- package/dist/shared/__test-utils__/log-output.d.ts +49 -0
- package/dist/shared/__test-utils__/log-output.d.ts.map +1 -0
- package/dist/shared/__test-utils__/log-output.js +38 -0
- package/dist/shared/__test-utils__/log-output.js.map +1 -0
- package/dist/shared/config.d.ts +56 -0
- package/dist/shared/config.d.ts.map +1 -0
- package/dist/shared/config.js +290 -0
- package/dist/shared/config.js.map +1 -0
- package/dist/shared/errors.d.ts +139 -0
- package/dist/shared/errors.d.ts.map +1 -0
- package/dist/shared/errors.js +406 -0
- package/dist/shared/errors.js.map +1 -0
- package/dist/shared/events/factory.d.ts +143 -0
- package/dist/shared/events/factory.d.ts.map +1 -0
- package/dist/shared/events/factory.js +351 -0
- package/dist/shared/events/factory.js.map +1 -0
- package/dist/shared/events/index.d.ts +6 -0
- package/dist/shared/events/index.d.ts.map +1 -0
- package/dist/shared/events/index.js +3 -0
- package/dist/shared/events/index.js.map +1 -0
- package/dist/shared/events/serialize.d.ts +87 -0
- package/dist/shared/events/serialize.d.ts.map +1 -0
- package/dist/shared/events/serialize.js +510 -0
- package/dist/shared/events/serialize.js.map +1 -0
- package/dist/shared/events/types.d.ts +139 -0
- package/dist/shared/events/types.d.ts.map +1 -0
- package/dist/shared/events/types.js +2 -0
- package/dist/shared/events/types.js.map +1 -0
- package/dist/shared/harvest/event-buffer.d.ts +59 -0
- package/dist/shared/harvest/event-buffer.d.ts.map +1 -0
- package/dist/shared/harvest/event-buffer.js +100 -0
- package/dist/shared/harvest/event-buffer.js.map +1 -0
- package/dist/shared/harvest/harvest-scheduler.d.ts +200 -0
- package/dist/shared/harvest/harvest-scheduler.d.ts.map +1 -0
- package/dist/shared/harvest/harvest-scheduler.js +647 -0
- package/dist/shared/harvest/harvest-scheduler.js.map +1 -0
- package/dist/shared/harvest/index.d.ts +7 -0
- package/dist/shared/harvest/index.d.ts.map +1 -0
- package/dist/shared/harvest/index.js +4 -0
- package/dist/shared/harvest/index.js.map +1 -0
- package/dist/shared/harvest/metric-aggregator.d.ts +115 -0
- package/dist/shared/harvest/metric-aggregator.d.ts.map +1 -0
- package/dist/shared/harvest/metric-aggregator.js +247 -0
- package/dist/shared/harvest/metric-aggregator.js.map +1 -0
- package/dist/shared/index.d.ts +22 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/dist/shared/index.js +13 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/shared/logger.d.ts +57 -0
- package/dist/shared/logger.d.ts.map +1 -0
- package/dist/shared/logger.js +166 -0
- package/dist/shared/logger.js.map +1 -0
- package/dist/shared/pricing-data.d.ts +4 -0
- package/dist/shared/pricing-data.d.ts.map +1 -0
- package/dist/shared/pricing-data.js +473 -0
- package/dist/shared/pricing-data.js.map +1 -0
- package/dist/shared/pricing.d.ts +148 -0
- package/dist/shared/pricing.d.ts.map +1 -0
- package/dist/shared/pricing.js +528 -0
- package/dist/shared/pricing.js.map +1 -0
- package/dist/shared/redact.d.ts +33 -0
- package/dist/shared/redact.d.ts.map +1 -0
- package/dist/shared/redact.js +110 -0
- package/dist/shared/redact.js.map +1 -0
- package/dist/shared/timing.d.ts +96 -0
- package/dist/shared/timing.d.ts.map +1 -0
- package/dist/shared/timing.js +173 -0
- package/dist/shared/timing.js.map +1 -0
- package/dist/shared/tokens.d.ts +145 -0
- package/dist/shared/tokens.d.ts.map +1 -0
- package/dist/shared/tokens.js +492 -0
- package/dist/shared/tokens.js.map +1 -0
- package/dist/shared/transport/events-api.d.ts +14 -0
- package/dist/shared/transport/events-api.d.ts.map +1 -0
- package/dist/shared/transport/events-api.js +29 -0
- package/dist/shared/transport/events-api.js.map +1 -0
- package/dist/shared/transport/http-client.d.ts +49 -0
- package/dist/shared/transport/http-client.d.ts.map +1 -0
- package/dist/shared/transport/http-client.js +381 -0
- package/dist/shared/transport/http-client.js.map +1 -0
- package/dist/shared/transport/index.d.ts +10 -0
- package/dist/shared/transport/index.d.ts.map +1 -0
- package/dist/shared/transport/index.js +6 -0
- package/dist/shared/transport/index.js.map +1 -0
- package/dist/shared/transport/logs-api.d.ts +29 -0
- package/dist/shared/transport/logs-api.d.ts.map +1 -0
- package/dist/shared/transport/logs-api.js +40 -0
- package/dist/shared/transport/logs-api.js.map +1 -0
- package/dist/shared/transport/metric-api.d.ts +9 -0
- package/dist/shared/transport/metric-api.d.ts.map +1 -0
- package/dist/shared/transport/metric-api.js +39 -0
- package/dist/shared/transport/metric-api.js.map +1 -0
- package/dist/shared/transport/otlp-event-bridge.d.ts +22 -0
- package/dist/shared/transport/otlp-event-bridge.d.ts.map +1 -0
- package/dist/shared/transport/otlp-event-bridge.js +50 -0
- package/dist/shared/transport/otlp-event-bridge.js.map +1 -0
- package/dist/shared/transport/otlp-shared.d.ts +14 -0
- package/dist/shared/transport/otlp-shared.d.ts.map +1 -0
- package/dist/shared/transport/otlp-shared.js +49 -0
- package/dist/shared/transport/otlp-shared.js.map +1 -0
- package/dist/shared/transport/otlp-transport.d.ts +58 -0
- package/dist/shared/transport/otlp-transport.d.ts.map +1 -0
- package/dist/shared/transport/otlp-transport.js +236 -0
- package/dist/shared/transport/otlp-transport.js.map +1 -0
- package/dist/shared/transport/types.d.ts +129 -0
- package/dist/shared/transport/types.d.ts.map +1 -0
- package/dist/shared/transport/types.js +2 -0
- package/dist/shared/transport/types.js.map +1 -0
- package/dist/shared/version.d.ts +2 -0
- package/dist/shared/version.d.ts.map +1 -0
- package/dist/shared/version.js +2 -0
- package/dist/shared/version.js.map +1 -0
- package/dist/storage/index.d.ts +7 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +4 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/local-store.d.ts +153 -0
- package/dist/storage/local-store.d.ts.map +1 -0
- package/dist/storage/local-store.js +719 -0
- package/dist/storage/local-store.js.map +1 -0
- package/dist/storage/retention.d.ts +2 -0
- package/dist/storage/retention.d.ts.map +1 -0
- package/dist/storage/retention.js +53 -0
- package/dist/storage/retention.js.map +1 -0
- package/dist/storage/session-store.d.ts +97 -0
- package/dist/storage/session-store.d.ts.map +1 -0
- package/dist/storage/session-store.js +391 -0
- package/dist/storage/session-store.js.map +1 -0
- package/dist/storage/types.d.ts +64 -0
- package/dist/storage/types.d.ts.map +1 -0
- package/dist/storage/types.js +2 -0
- package/dist/storage/types.js.map +1 -0
- package/dist/storage/weekly-summary.d.ts +61 -0
- package/dist/storage/weekly-summary.d.ts.map +1 -0
- package/dist/storage/weekly-summary.js +243 -0
- package/dist/storage/weekly-summary.js.map +1 -0
- package/dist/tools/analytics-tools.d.ts +101 -0
- package/dist/tools/analytics-tools.d.ts.map +1 -0
- package/dist/tools/analytics-tools.js +71 -0
- package/dist/tools/analytics-tools.js.map +1 -0
- package/dist/tools/cost-tools.d.ts +121 -0
- package/dist/tools/cost-tools.d.ts.map +1 -0
- package/dist/tools/cost-tools.js +174 -0
- package/dist/tools/cost-tools.js.map +1 -0
- package/dist/tools/cross-session-tools.d.ts +376 -0
- package/dist/tools/cross-session-tools.d.ts.map +1 -0
- package/dist/tools/cross-session-tools.js +820 -0
- package/dist/tools/cross-session-tools.js.map +1 -0
- package/dist/tools/extended-analytics-tools.d.ts +164 -0
- package/dist/tools/extended-analytics-tools.d.ts.map +1 -0
- package/dist/tools/extended-analytics-tools.js +121 -0
- package/dist/tools/extended-analytics-tools.js.map +1 -0
- package/dist/tools/index.d.ts +7 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +4 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/session-stats.d.ts +162 -0
- package/dist/tools/session-stats.d.ts.map +1 -0
- package/dist/tools/session-stats.js +1054 -0
- package/dist/tools/session-stats.js.map +1 -0
- package/dist/tools/workflow-tools.d.ts +126 -0
- package/dist/tools/workflow-tools.d.ts.map +1 -0
- package/dist/tools/workflow-tools.js +274 -0
- package/dist/tools/workflow-tools.js.map +1 -0
- package/dist/tracing/mcp-tracer.d.ts +4 -0
- package/dist/tracing/mcp-tracer.d.ts.map +1 -0
- package/dist/tracing/mcp-tracer.js +14 -0
- package/dist/tracing/mcp-tracer.js.map +1 -0
- package/dist/tracing/session-span.d.ts +14 -0
- package/dist/tracing/session-span.d.ts.map +1 -0
- package/dist/tracing/session-span.js +53 -0
- package/dist/tracing/session-span.js.map +1 -0
- package/dist/tracing/task-span-tracker.d.ts +11 -0
- package/dist/tracing/task-span-tracker.d.ts.map +1 -0
- package/dist/tracing/task-span-tracker.js +59 -0
- package/dist/tracing/task-span-tracker.js.map +1 -0
- package/dist/tracing/tool-call-span.d.ts +4 -0
- package/dist/tracing/tool-call-span.d.ts.map +1 -0
- package/dist/tracing/tool-call-span.js +60 -0
- package/dist/tracing/tool-call-span.js.map +1 -0
- package/dist/transport/index.d.ts +3 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/dist/transport/index.js +2 -0
- package/dist/transport/index.js.map +1 -0
- package/dist/transport/log-ingest.d.ts +42 -0
- package/dist/transport/log-ingest.d.ts.map +1 -0
- package/dist/transport/log-ingest.js +151 -0
- package/dist/transport/log-ingest.js.map +1 -0
- package/dist/transport/nr-ingest.d.ts +171 -0
- package/dist/transport/nr-ingest.d.ts.map +1 -0
- package/dist/transport/nr-ingest.js +659 -0
- package/dist/transport/nr-ingest.js.map +1 -0
- package/dist/types.d.ts +45 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/web/assets/index-BrL281N-.css +2 -0
- package/dist/web/assets/index-CcaYZzXm.js +42 -0
- package/dist/web/favicon.svg +15 -0
- package/dist/web/index.html +15 -0
- package/examples/local-alert-rules.json +106 -0
- package/package.json +129 -1
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
import { dirname } from 'node:path';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { createLogger } from '../shared/index.js';
|
|
5
|
+
// Runtime shape check for entries read back from disk. Hand-edited or
|
|
6
|
+
// corrupted log files won't poison the API consumer with wrong-typed
|
|
7
|
+
// fields. Mirrors the AlertEvent interface in live-event-bus.ts.
|
|
8
|
+
const AlertEventSchema = z.object({
|
|
9
|
+
id: z.string().min(1),
|
|
10
|
+
state: z.enum(['firing', 'cleared']),
|
|
11
|
+
severity: z.enum(['info', 'warning', 'critical']),
|
|
12
|
+
title: z.string(),
|
|
13
|
+
description: z.string(),
|
|
14
|
+
value: z.number(),
|
|
15
|
+
threshold: z.number(),
|
|
16
|
+
firedAt: z.number(),
|
|
17
|
+
});
|
|
18
|
+
const logger = createLogger('alert-log');
|
|
19
|
+
const DEFAULT_MAX_BYTES = 10 * 1024 * 1024;
|
|
20
|
+
/**
|
|
21
|
+
* Append-only JSONL log for alert events. One file with one rotation
|
|
22
|
+
* (`<path>.1`). All filesystem I/O is deferred to first append() so the
|
|
23
|
+
* constructor stays cheap and side-effect-free for testing.
|
|
24
|
+
*/
|
|
25
|
+
export class AlertLog {
|
|
26
|
+
path;
|
|
27
|
+
maxBytes;
|
|
28
|
+
initialized = false;
|
|
29
|
+
pending = Promise.resolve();
|
|
30
|
+
constructor(opts) {
|
|
31
|
+
this.path = opts.path;
|
|
32
|
+
this.maxBytes = opts.maxBytes ?? DEFAULT_MAX_BYTES;
|
|
33
|
+
}
|
|
34
|
+
async append(event) {
|
|
35
|
+
// Serialize writes so concurrent callers don't interleave lines.
|
|
36
|
+
this.pending = this.pending.then(async () => {
|
|
37
|
+
try {
|
|
38
|
+
await this.ensureInitialized();
|
|
39
|
+
// rotateIfNeeded() can rename log.jsonl → log.jsonl.1 and
|
|
40
|
+
// a process crash before the appendFile below would lose the
|
|
41
|
+
// current event (not in .1, not in the new file). Acceptable for
|
|
42
|
+
// Acceptable trade-off: (a) rotation is rare — tens of MB of alert
|
|
43
|
+
// history per device — so the crash window is small; (b) the
|
|
44
|
+
// alternative (write-temp + rename + append) doubles the I/O
|
|
45
|
+
// cost on every append. Revisit if audit-trail compliance ever
|
|
46
|
+
// demands stronger durability than "best-effort tail".
|
|
47
|
+
await this.rotateIfNeeded();
|
|
48
|
+
const line = JSON.stringify(event) + '\n';
|
|
49
|
+
await fs.appendFile(this.path, line, { mode: 0o600 });
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
logger.error('Failed to append alert log entry', { error: String(err) });
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
await this.pending;
|
|
56
|
+
}
|
|
57
|
+
async readRecent(limit) {
|
|
58
|
+
if (limit <= 0)
|
|
59
|
+
return [];
|
|
60
|
+
// Chain through pending AND reassign it so subsequent appends wait for
|
|
61
|
+
// this read to finish. Without the reassignment, an append queued after
|
|
62
|
+
// readRecent() can still race: both chain off the same resolved predecessor
|
|
63
|
+
// and run concurrently — the append's rotation can then be observed by
|
|
64
|
+
// doReadRecent mid-rename.
|
|
65
|
+
const result = this.pending.then(() => this.doReadRecent(limit));
|
|
66
|
+
this.pending = result.then(() => undefined, () => undefined);
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
async doReadRecent(limit) {
|
|
70
|
+
const readLines = async (filePath) => {
|
|
71
|
+
try {
|
|
72
|
+
const data = await fs.readFile(filePath, 'utf8');
|
|
73
|
+
return data.split('\n').filter((l) => l.length > 0);
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
const code = err.code;
|
|
77
|
+
if (code === 'ENOENT')
|
|
78
|
+
return [];
|
|
79
|
+
logger.error('Failed to read alert log', { path: filePath, error: String(err) });
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
// Read the rotation backup first (older entries), then the primary file
|
|
84
|
+
const [rotatedLines, primaryLines] = await Promise.all([
|
|
85
|
+
readLines(`${this.path}.1`),
|
|
86
|
+
readLines(this.path),
|
|
87
|
+
]);
|
|
88
|
+
const allLines = [...rotatedLines, ...primaryLines];
|
|
89
|
+
const slice = allLines.slice(-limit).reverse();
|
|
90
|
+
const out = [];
|
|
91
|
+
for (const line of slice) {
|
|
92
|
+
let parsed;
|
|
93
|
+
try {
|
|
94
|
+
parsed = JSON.parse(line);
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
logger.warn('Skipping malformed alert log line (invalid JSON)', {
|
|
98
|
+
error: String(err),
|
|
99
|
+
});
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
const result = AlertEventSchema.safeParse(parsed);
|
|
103
|
+
if (!result.success) {
|
|
104
|
+
logger.warn('Skipping alert log entry with unexpected shape', {
|
|
105
|
+
issue: result.error.issues[0]?.message ?? 'unknown',
|
|
106
|
+
});
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
out.push(result.data);
|
|
110
|
+
}
|
|
111
|
+
return out;
|
|
112
|
+
}
|
|
113
|
+
async rotateIfNeeded() {
|
|
114
|
+
try {
|
|
115
|
+
const stat = await fs.stat(this.path);
|
|
116
|
+
if (stat.size <= this.maxBytes)
|
|
117
|
+
return;
|
|
118
|
+
const rotated = `${this.path}.1`;
|
|
119
|
+
// Replace any existing .1 (only one rotation kept).
|
|
120
|
+
await fs.rename(this.path, rotated);
|
|
121
|
+
// rename preserves source perms, so a manually pre-created
|
|
122
|
+
// log with looser modes would carry that into .1. Force 0o600
|
|
123
|
+
// explicitly. Best-effort — Windows/NFS may not support chmod, and
|
|
124
|
+
// a perms failure shouldn't break rotation itself.
|
|
125
|
+
try {
|
|
126
|
+
await fs.chmod(rotated, 0o600);
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
/* ignore */
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
const code = err.code;
|
|
134
|
+
if (code === 'ENOENT')
|
|
135
|
+
return;
|
|
136
|
+
logger.warn('Alert log rotation failed', { error: String(err) });
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
async close() {
|
|
140
|
+
// Drain any in-flight writes.
|
|
141
|
+
await this.pending;
|
|
142
|
+
}
|
|
143
|
+
async ensureInitialized() {
|
|
144
|
+
if (this.initialized)
|
|
145
|
+
return;
|
|
146
|
+
const dir = dirname(this.path);
|
|
147
|
+
await fs.mkdir(dir, { recursive: true, mode: 0o700 });
|
|
148
|
+
// Best-effort: tighten perms on the directory if it already existed with
|
|
149
|
+
// looser perms. Failure here (e.g. on Windows or NFS) is not fatal.
|
|
150
|
+
try {
|
|
151
|
+
await fs.chmod(dir, 0o700);
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
/* ignore */
|
|
155
|
+
}
|
|
156
|
+
this.initialized = true;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=alert-log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alert-log.js","sourceRoot":"","sources":["../../src/alerts/alert-log.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Snapshot of the current observable state used by the engine to evaluate
|
|
3
|
+
* rules. Built by AlertSnapshotCollector on each evaluation tick.
|
|
4
|
+
*
|
|
5
|
+
* Window semantics:
|
|
6
|
+
* - `antiPatterns` is one entry per (type, windowMs) tuple. Engine matches
|
|
7
|
+
* by exact `windowMs`, so two rules with different windows over the same
|
|
8
|
+
* pattern type each get their own count entry.
|
|
9
|
+
* - `toolFailures` is one entry per (tool, windowMs) tuple, same matching
|
|
10
|
+
* rule.
|
|
11
|
+
*
|
|
12
|
+
* Cost is currently session-cumulative (not a rolling window). A true
|
|
13
|
+
* rolling-hour cost window is not yet implemented.
|
|
14
|
+
*/
|
|
15
|
+
export interface AlertSnapshot {
|
|
16
|
+
readonly timestamp: number;
|
|
17
|
+
readonly cost: {
|
|
18
|
+
sessionUsd: number;
|
|
19
|
+
todayUsd: number;
|
|
20
|
+
weekUsd: number;
|
|
21
|
+
};
|
|
22
|
+
readonly efficiency: {
|
|
23
|
+
score: number | null;
|
|
24
|
+
};
|
|
25
|
+
readonly antiPatterns: ReadonlyArray<{
|
|
26
|
+
type: string;
|
|
27
|
+
count: number;
|
|
28
|
+
windowMs: number;
|
|
29
|
+
}>;
|
|
30
|
+
readonly latency: ReadonlyArray<{
|
|
31
|
+
tool: string;
|
|
32
|
+
p50Ms: number;
|
|
33
|
+
p95Ms: number;
|
|
34
|
+
p99Ms: number;
|
|
35
|
+
}>;
|
|
36
|
+
readonly toolFailures: ReadonlyArray<{
|
|
37
|
+
tool: string;
|
|
38
|
+
failurePct: number;
|
|
39
|
+
windowMs: number;
|
|
40
|
+
}>;
|
|
41
|
+
readonly budgetThresholds?: ReadonlyArray<{
|
|
42
|
+
period: 'session' | 'daily' | 'weekly';
|
|
43
|
+
thresholdPct: 50 | 80 | 100;
|
|
44
|
+
spentUsd: number;
|
|
45
|
+
budgetUsd: number;
|
|
46
|
+
}>;
|
|
47
|
+
}
|
|
48
|
+
export interface AlertSnapshotCollectorDeps {
|
|
49
|
+
readonly costTracker?: {
|
|
50
|
+
getMetrics(): {
|
|
51
|
+
sessionTotalCostUsd?: number | null;
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Optional source for daily/weekly cumulative spend. When supplied, the
|
|
56
|
+
* snapshot's `cost.todayUsd` and `cost.weekUsd` reflect prior-session +
|
|
57
|
+
* current-session today/weekly totals (the same numbers fed to
|
|
58
|
+
* BudgetTracker.updateCost), enabling cost.window rules with `today`/
|
|
59
|
+
* `week` periods to fire. Without this, today/week fall back to 0 — the
|
|
60
|
+
* pre-fix behavior — so cost.window rules with non-session periods
|
|
61
|
+
* effectively become no-ops.
|
|
62
|
+
*/
|
|
63
|
+
readonly budgetTracker?: {
|
|
64
|
+
getStatus(): {
|
|
65
|
+
daily: {
|
|
66
|
+
spentUsd: number;
|
|
67
|
+
};
|
|
68
|
+
weekly: {
|
|
69
|
+
spentUsd: number;
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Thunk that returns the rolling cost forecast snapshot. Currently unused
|
|
75
|
+
* by the snapshot path (kept for symmetry with index.ts wiring); may be
|
|
76
|
+
* consumed in the future for true rolling-window cost.
|
|
77
|
+
*/
|
|
78
|
+
readonly costForecast?: () => unknown;
|
|
79
|
+
readonly efficiencyScorer?: {
|
|
80
|
+
/**
|
|
81
|
+
* Returns the current efficiency score in [0, 1], or `null` if there
|
|
82
|
+
* are no scored tasks yet. The collector adapts whatever the
|
|
83
|
+
* efficiency scorer exposes via this small interface so the tracker
|
|
84
|
+
* itself doesn't need a new public method.
|
|
85
|
+
*/
|
|
86
|
+
getCurrentScore(): number | null;
|
|
87
|
+
};
|
|
88
|
+
readonly antiPatternDetector?: {
|
|
89
|
+
getCurrentPatterns(): readonly {
|
|
90
|
+
type: string;
|
|
91
|
+
}[];
|
|
92
|
+
};
|
|
93
|
+
readonly latencyTracker?: {
|
|
94
|
+
getMetrics(): {
|
|
95
|
+
byTool: Readonly<Record<string, {
|
|
96
|
+
p50?: number;
|
|
97
|
+
p95?: number;
|
|
98
|
+
p99?: number;
|
|
99
|
+
} | null>>;
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
readonly sessionTracker?: {
|
|
103
|
+
getMetrics(): {
|
|
104
|
+
toolCalls?: ReadonlyArray<{
|
|
105
|
+
tool?: string;
|
|
106
|
+
toolName?: string;
|
|
107
|
+
success?: boolean;
|
|
108
|
+
}>;
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
readonly clock?: () => number;
|
|
112
|
+
}
|
|
113
|
+
export interface SnapshotWindowSpec {
|
|
114
|
+
readonly kind: 'antipattern' | 'tool-failure';
|
|
115
|
+
/**
|
|
116
|
+
* Free-form key for the window. For `antipattern`, the key is the
|
|
117
|
+
* pattern type (or `'*'` for "any type"). For `tool-failure`, the key is
|
|
118
|
+
* the tool name.
|
|
119
|
+
*/
|
|
120
|
+
readonly key: string;
|
|
121
|
+
readonly windowMs: number;
|
|
122
|
+
}
|
|
123
|
+
export declare class AlertSnapshotCollector {
|
|
124
|
+
private readonly deps;
|
|
125
|
+
private readonly clock;
|
|
126
|
+
private readonly toolCallEvents;
|
|
127
|
+
private readonly antiPatternEvents;
|
|
128
|
+
constructor(deps?: AlertSnapshotCollectorDeps);
|
|
129
|
+
/**
|
|
130
|
+
* Push a tool call observation onto the rolling buffer. Caller supplies
|
|
131
|
+
* the timestamp (typically `Date.now()` at the time the hook fired).
|
|
132
|
+
*/
|
|
133
|
+
recordToolCall(record: {
|
|
134
|
+
toolName: string;
|
|
135
|
+
success: boolean;
|
|
136
|
+
ts: number;
|
|
137
|
+
}): void;
|
|
138
|
+
/**
|
|
139
|
+
* Push an anti-pattern observation onto the rolling buffer.
|
|
140
|
+
*/
|
|
141
|
+
recordAntiPattern(observation: {
|
|
142
|
+
type: string;
|
|
143
|
+
ts: number;
|
|
144
|
+
}): void;
|
|
145
|
+
/**
|
|
146
|
+
* Build a snapshot. The longest window any rule can span is 30 minutes
|
|
147
|
+
* by default; older buffer entries are pruned during the call.
|
|
148
|
+
*
|
|
149
|
+
* Returns one entry per requested (type, windowMs) for anti-patterns and
|
|
150
|
+
* (tool, windowMs) for tool failures.
|
|
151
|
+
*/
|
|
152
|
+
snapshot(now: number, windows: ReadonlyArray<SnapshotWindowSpec>): AlertSnapshot;
|
|
153
|
+
private buildAntiPatternCounts;
|
|
154
|
+
private buildToolFailureCounts;
|
|
155
|
+
private readCost;
|
|
156
|
+
private readEfficiencyScore;
|
|
157
|
+
private readLatency;
|
|
158
|
+
private trimBuffer;
|
|
159
|
+
private pruneOlderThan;
|
|
160
|
+
/** @internal — for tests only. Returns the current buffer sizes. */
|
|
161
|
+
bufferSizes(): {
|
|
162
|
+
toolCalls: number;
|
|
163
|
+
antiPatterns: number;
|
|
164
|
+
};
|
|
165
|
+
/** @internal — for tests only. Returns the configured clock reading. */
|
|
166
|
+
now(): number;
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=alert-snapshot-collector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alert-snapshot-collector.d.ts","sourceRoot":"","sources":["../../src/alerts/alert-snapshot-collector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { createLogger } from '../shared/index.js';
|
|
2
|
+
const logger = createLogger('alert-snapshot-collector');
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Constants
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
const MAX_BUFFER_ENTRIES = 5000;
|
|
7
|
+
/**
|
|
8
|
+
* Default prune horizon (30 minutes). When `snapshot()` is called with no
|
|
9
|
+
* window specs, entries older than this are pruned so the buffers don't
|
|
10
|
+
* grow unbounded between evaluations.
|
|
11
|
+
*/
|
|
12
|
+
const DEFAULT_MAX_WINDOW_MS = 30 * 60 * 1000;
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// AlertSnapshotCollector
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
export class AlertSnapshotCollector {
|
|
17
|
+
deps;
|
|
18
|
+
clock;
|
|
19
|
+
// Both buffers are kept sorted by ts (callers typically push monotonically
|
|
20
|
+
// increasing timestamps). If a stale-timestamped entry sneaks in, the
|
|
21
|
+
// window queries below still work because we filter by `ts >= cutoff`.
|
|
22
|
+
toolCallEvents = [];
|
|
23
|
+
antiPatternEvents = [];
|
|
24
|
+
constructor(deps = {}) {
|
|
25
|
+
this.deps = deps;
|
|
26
|
+
this.clock = deps.clock ?? (() => Date.now());
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Push a tool call observation onto the rolling buffer. Caller supplies
|
|
30
|
+
* the timestamp (typically `Date.now()` at the time the hook fired).
|
|
31
|
+
*/
|
|
32
|
+
recordToolCall(record) {
|
|
33
|
+
this.toolCallEvents.push({
|
|
34
|
+
tool: record.toolName,
|
|
35
|
+
success: record.success,
|
|
36
|
+
ts: record.ts,
|
|
37
|
+
});
|
|
38
|
+
this.trimBuffer(this.toolCallEvents);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Push an anti-pattern observation onto the rolling buffer.
|
|
42
|
+
*/
|
|
43
|
+
recordAntiPattern(observation) {
|
|
44
|
+
this.antiPatternEvents.push({
|
|
45
|
+
type: observation.type,
|
|
46
|
+
ts: observation.ts,
|
|
47
|
+
});
|
|
48
|
+
this.trimBuffer(this.antiPatternEvents);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Build a snapshot. The longest window any rule can span is 30 minutes
|
|
52
|
+
* by default; older buffer entries are pruned during the call.
|
|
53
|
+
*
|
|
54
|
+
* Returns one entry per requested (type, windowMs) for anti-patterns and
|
|
55
|
+
* (tool, windowMs) for tool failures.
|
|
56
|
+
*/
|
|
57
|
+
snapshot(now, windows) {
|
|
58
|
+
// Determine the longest window so we know how far back to keep events.
|
|
59
|
+
let maxWindowMs = DEFAULT_MAX_WINDOW_MS;
|
|
60
|
+
for (const w of windows) {
|
|
61
|
+
if (w.windowMs > maxWindowMs)
|
|
62
|
+
maxWindowMs = w.windowMs;
|
|
63
|
+
}
|
|
64
|
+
const cutoff = now - maxWindowMs;
|
|
65
|
+
this.pruneOlderThan(this.toolCallEvents, cutoff);
|
|
66
|
+
this.pruneOlderThan(this.antiPatternEvents, cutoff);
|
|
67
|
+
const antiPatterns = this.buildAntiPatternCounts(windows, now);
|
|
68
|
+
const toolFailures = this.buildToolFailureCounts(windows, now);
|
|
69
|
+
return {
|
|
70
|
+
timestamp: now,
|
|
71
|
+
cost: this.readCost(),
|
|
72
|
+
efficiency: { score: this.readEfficiencyScore() },
|
|
73
|
+
antiPatterns,
|
|
74
|
+
latency: this.readLatency(),
|
|
75
|
+
toolFailures,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
// Internal — counts
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
buildAntiPatternCounts(windows, now) {
|
|
82
|
+
const out = [];
|
|
83
|
+
// Deduplicate (type, windowMs) so the same window spec twice doesn't
|
|
84
|
+
// produce two entries.
|
|
85
|
+
const seen = new Set();
|
|
86
|
+
for (const w of windows) {
|
|
87
|
+
if (w.kind !== 'antipattern')
|
|
88
|
+
continue;
|
|
89
|
+
const seenKey = `${w.key}:${w.windowMs}`;
|
|
90
|
+
if (seen.has(seenKey))
|
|
91
|
+
continue;
|
|
92
|
+
seen.add(seenKey);
|
|
93
|
+
const cutoff = now - w.windowMs;
|
|
94
|
+
let count = 0;
|
|
95
|
+
for (const ev of this.antiPatternEvents) {
|
|
96
|
+
if (ev.ts < cutoff)
|
|
97
|
+
continue;
|
|
98
|
+
if (w.key === '*' || ev.type === w.key)
|
|
99
|
+
count++;
|
|
100
|
+
}
|
|
101
|
+
out.push({ type: w.key, count, windowMs: w.windowMs });
|
|
102
|
+
}
|
|
103
|
+
return out;
|
|
104
|
+
}
|
|
105
|
+
buildToolFailureCounts(windows, now) {
|
|
106
|
+
const out = [];
|
|
107
|
+
const seen = new Set();
|
|
108
|
+
for (const w of windows) {
|
|
109
|
+
if (w.kind !== 'tool-failure')
|
|
110
|
+
continue;
|
|
111
|
+
const seenKey = `${w.key}:${w.windowMs}`;
|
|
112
|
+
if (seen.has(seenKey))
|
|
113
|
+
continue;
|
|
114
|
+
seen.add(seenKey);
|
|
115
|
+
const cutoff = now - w.windowMs;
|
|
116
|
+
let total = 0;
|
|
117
|
+
let failures = 0;
|
|
118
|
+
for (const ev of this.toolCallEvents) {
|
|
119
|
+
if (ev.ts < cutoff)
|
|
120
|
+
continue;
|
|
121
|
+
if (w.key !== '*' && ev.tool !== w.key)
|
|
122
|
+
continue;
|
|
123
|
+
total++;
|
|
124
|
+
if (!ev.success)
|
|
125
|
+
failures++;
|
|
126
|
+
}
|
|
127
|
+
// No samples → 0% (rather than NaN). Rules can compare; absence of
|
|
128
|
+
// calls is "everything's fine."
|
|
129
|
+
const failurePct = total === 0 ? 0 : (failures / total) * 100;
|
|
130
|
+
out.push({ tool: w.key, failurePct, windowMs: w.windowMs });
|
|
131
|
+
}
|
|
132
|
+
return out;
|
|
133
|
+
}
|
|
134
|
+
// ---------------------------------------------------------------------------
|
|
135
|
+
// Internal — tracker reads (defensive: missing deps yield neutral values)
|
|
136
|
+
// ---------------------------------------------------------------------------
|
|
137
|
+
readCost() {
|
|
138
|
+
try {
|
|
139
|
+
const m = this.deps.costTracker?.getMetrics();
|
|
140
|
+
const sessionUsd = m?.sessionTotalCostUsd ?? 0;
|
|
141
|
+
// Today/week fall through to BudgetTracker's accumulated daily/weekly
|
|
142
|
+
// spent — same numbers that feed budget alerts, computed in index.ts
|
|
143
|
+
// from costTracker.getCostForDay() + cross-midnight-aware prior session
|
|
144
|
+
// baseline. Falls back to 0 when no budgetTracker is wired (older
|
|
145
|
+
// configs / tests), matching the pre-fix placeholder behavior.
|
|
146
|
+
const status = this.deps.budgetTracker?.getStatus();
|
|
147
|
+
return {
|
|
148
|
+
sessionUsd: sessionUsd ?? 0,
|
|
149
|
+
todayUsd: status?.daily.spentUsd ?? 0,
|
|
150
|
+
weekUsd: status?.weekly.spentUsd ?? 0,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
logger.warn('costTracker.getMetrics() threw — defaulting to 0', {
|
|
155
|
+
error: String(err),
|
|
156
|
+
});
|
|
157
|
+
return { sessionUsd: 0, todayUsd: 0, weekUsd: 0 };
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
readEfficiencyScore() {
|
|
161
|
+
try {
|
|
162
|
+
const score = this.deps.efficiencyScorer?.getCurrentScore?.();
|
|
163
|
+
return typeof score === 'number' ? score : null;
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
logger.warn('efficiencyScorer.getCurrentScore() threw', {
|
|
167
|
+
error: String(err),
|
|
168
|
+
});
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
readLatency() {
|
|
173
|
+
try {
|
|
174
|
+
const metrics = this.deps.latencyTracker?.getMetrics();
|
|
175
|
+
if (!metrics)
|
|
176
|
+
return [];
|
|
177
|
+
const out = [];
|
|
178
|
+
for (const [tool, percentiles] of Object.entries(metrics.byTool)) {
|
|
179
|
+
if (!percentiles)
|
|
180
|
+
continue;
|
|
181
|
+
// Emit an entry when ANY of p50/p95/p99 is available. Missing
|
|
182
|
+
// percentiles surface as 0 to the rule comparator, which treats 0
|
|
183
|
+
// as below any positive threshold — so a `latency.percentile`
|
|
184
|
+
// rule asking for p99 still fires when the tracker has p99 data
|
|
185
|
+
// even if p95 happens to be missing. gating on p95
|
|
186
|
+
// alone caused p50/p99 rules to silently never fire when sample
|
|
187
|
+
// count was too low to compute all three.
|
|
188
|
+
const hasAny = typeof percentiles.p50 === 'number' ||
|
|
189
|
+
typeof percentiles.p95 === 'number' ||
|
|
190
|
+
typeof percentiles.p99 === 'number';
|
|
191
|
+
if (hasAny) {
|
|
192
|
+
out.push({
|
|
193
|
+
tool,
|
|
194
|
+
p50Ms: typeof percentiles.p50 === 'number' ? percentiles.p50 : 0,
|
|
195
|
+
p95Ms: typeof percentiles.p95 === 'number' ? percentiles.p95 : 0,
|
|
196
|
+
p99Ms: typeof percentiles.p99 === 'number' ? percentiles.p99 : 0,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return out;
|
|
201
|
+
}
|
|
202
|
+
catch (err) {
|
|
203
|
+
logger.warn('latencyTracker.getMetrics() threw', { error: String(err) });
|
|
204
|
+
return [];
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// ---------------------------------------------------------------------------
|
|
208
|
+
// Internal — buffer maintenance
|
|
209
|
+
// ---------------------------------------------------------------------------
|
|
210
|
+
trimBuffer(buf) {
|
|
211
|
+
// Hard cap so an idle process can't grow buffers without bound. Drop
|
|
212
|
+
// the oldest entries first.
|
|
213
|
+
if (buf.length > MAX_BUFFER_ENTRIES) {
|
|
214
|
+
buf.splice(0, buf.length - MAX_BUFFER_ENTRIES);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
pruneOlderThan(buf, cutoff) {
|
|
218
|
+
if (buf.length === 0)
|
|
219
|
+
return;
|
|
220
|
+
// Use filter to handle occasional out-of-order entries (late-arriving hook events).
|
|
221
|
+
// Linear scan from index 0 would stop at the first in-range entry and leave
|
|
222
|
+
// out-of-order stale entries further in the array.
|
|
223
|
+
const filtered = buf.filter((e) => e.ts >= cutoff);
|
|
224
|
+
if (filtered.length < buf.length) {
|
|
225
|
+
buf.splice(0, buf.length, ...filtered);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
// ---------------------------------------------------------------------------
|
|
229
|
+
// Test helpers
|
|
230
|
+
// ---------------------------------------------------------------------------
|
|
231
|
+
/** @internal — for tests only. Returns the current buffer sizes. */
|
|
232
|
+
bufferSizes() {
|
|
233
|
+
return {
|
|
234
|
+
toolCalls: this.toolCallEvents.length,
|
|
235
|
+
antiPatterns: this.antiPatternEvents.length,
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
/** @internal — for tests only. Returns the configured clock reading. */
|
|
239
|
+
now() {
|
|
240
|
+
return this.clock();
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=alert-snapshot-collector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alert-snapshot-collector.js","sourceRoot":"","sources":["../../src/alerts/alert-snapshot-collector.ts"],"names":[],"mappings":"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"}
|