@dotsetlabs/bellwether 0.10.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.
- package/CHANGELOG.md +291 -0
- package/LICENSE +21 -0
- package/README.md +739 -0
- package/dist/auth/credentials.d.ts +64 -0
- package/dist/auth/credentials.js +218 -0
- package/dist/auth/index.d.ts +6 -0
- package/dist/auth/index.js +6 -0
- package/dist/auth/keychain.d.ts +64 -0
- package/dist/auth/keychain.js +268 -0
- package/dist/baseline/ab-testing.d.ts +80 -0
- package/dist/baseline/ab-testing.js +236 -0
- package/dist/baseline/ai-compatibility-scorer.d.ts +95 -0
- package/dist/baseline/ai-compatibility-scorer.js +606 -0
- package/dist/baseline/calibration.d.ts +77 -0
- package/dist/baseline/calibration.js +136 -0
- package/dist/baseline/category-matching.d.ts +85 -0
- package/dist/baseline/category-matching.js +289 -0
- package/dist/baseline/change-impact-analyzer.d.ts +98 -0
- package/dist/baseline/change-impact-analyzer.js +592 -0
- package/dist/baseline/comparator.d.ts +64 -0
- package/dist/baseline/comparator.js +916 -0
- package/dist/baseline/confidence.d.ts +55 -0
- package/dist/baseline/confidence.js +122 -0
- package/dist/baseline/converter.d.ts +61 -0
- package/dist/baseline/converter.js +585 -0
- package/dist/baseline/dependency-analyzer.d.ts +89 -0
- package/dist/baseline/dependency-analyzer.js +567 -0
- package/dist/baseline/deprecation-tracker.d.ts +133 -0
- package/dist/baseline/deprecation-tracker.js +322 -0
- package/dist/baseline/diff.d.ts +55 -0
- package/dist/baseline/diff.js +1584 -0
- package/dist/baseline/documentation-scorer.d.ts +205 -0
- package/dist/baseline/documentation-scorer.js +466 -0
- package/dist/baseline/embeddings.d.ts +118 -0
- package/dist/baseline/embeddings.js +251 -0
- package/dist/baseline/error-analyzer.d.ts +198 -0
- package/dist/baseline/error-analyzer.js +721 -0
- package/dist/baseline/evaluation/evaluator.d.ts +42 -0
- package/dist/baseline/evaluation/evaluator.js +323 -0
- package/dist/baseline/evaluation/expanded-dataset.d.ts +45 -0
- package/dist/baseline/evaluation/expanded-dataset.js +1164 -0
- package/dist/baseline/evaluation/golden-dataset.d.ts +58 -0
- package/dist/baseline/evaluation/golden-dataset.js +717 -0
- package/dist/baseline/evaluation/index.d.ts +15 -0
- package/dist/baseline/evaluation/index.js +15 -0
- package/dist/baseline/evaluation/types.d.ts +186 -0
- package/dist/baseline/evaluation/types.js +8 -0
- package/dist/baseline/external-dependency-detector.d.ts +181 -0
- package/dist/baseline/external-dependency-detector.js +524 -0
- package/dist/baseline/golden-output.d.ts +162 -0
- package/dist/baseline/golden-output.js +636 -0
- package/dist/baseline/health-scorer.d.ts +174 -0
- package/dist/baseline/health-scorer.js +451 -0
- package/dist/baseline/incremental-checker.d.ts +97 -0
- package/dist/baseline/incremental-checker.js +174 -0
- package/dist/baseline/index.d.ts +31 -0
- package/dist/baseline/index.js +42 -0
- package/dist/baseline/migration-generator.d.ts +137 -0
- package/dist/baseline/migration-generator.js +554 -0
- package/dist/baseline/migrations.d.ts +60 -0
- package/dist/baseline/migrations.js +197 -0
- package/dist/baseline/performance-tracker.d.ts +214 -0
- package/dist/baseline/performance-tracker.js +577 -0
- package/dist/baseline/pr-comment-generator.d.ts +117 -0
- package/dist/baseline/pr-comment-generator.js +546 -0
- package/dist/baseline/response-fingerprint.d.ts +127 -0
- package/dist/baseline/response-fingerprint.js +728 -0
- package/dist/baseline/response-schema-tracker.d.ts +129 -0
- package/dist/baseline/response-schema-tracker.js +420 -0
- package/dist/baseline/risk-scorer.d.ts +54 -0
- package/dist/baseline/risk-scorer.js +434 -0
- package/dist/baseline/saver.d.ts +89 -0
- package/dist/baseline/saver.js +554 -0
- package/dist/baseline/scenario-generator.d.ts +151 -0
- package/dist/baseline/scenario-generator.js +905 -0
- package/dist/baseline/schema-compare.d.ts +86 -0
- package/dist/baseline/schema-compare.js +557 -0
- package/dist/baseline/schema-evolution.d.ts +189 -0
- package/dist/baseline/schema-evolution.js +467 -0
- package/dist/baseline/semantic.d.ts +203 -0
- package/dist/baseline/semantic.js +908 -0
- package/dist/baseline/synonyms.d.ts +60 -0
- package/dist/baseline/synonyms.js +386 -0
- package/dist/baseline/telemetry.d.ts +165 -0
- package/dist/baseline/telemetry.js +294 -0
- package/dist/baseline/test-pruner.d.ts +120 -0
- package/dist/baseline/test-pruner.js +387 -0
- package/dist/baseline/types.d.ts +449 -0
- package/dist/baseline/types.js +5 -0
- package/dist/baseline/version.d.ts +138 -0
- package/dist/baseline/version.js +206 -0
- package/dist/cache/index.d.ts +5 -0
- package/dist/cache/index.js +5 -0
- package/dist/cache/response-cache.d.ts +151 -0
- package/dist/cache/response-cache.js +287 -0
- package/dist/ci/index.d.ts +60 -0
- package/dist/ci/index.js +342 -0
- package/dist/cli/commands/auth.d.ts +12 -0
- package/dist/cli/commands/auth.js +352 -0
- package/dist/cli/commands/badge.d.ts +3 -0
- package/dist/cli/commands/badge.js +74 -0
- package/dist/cli/commands/baseline-accept.d.ts +15 -0
- package/dist/cli/commands/baseline-accept.js +178 -0
- package/dist/cli/commands/baseline-migrate.d.ts +12 -0
- package/dist/cli/commands/baseline-migrate.js +164 -0
- package/dist/cli/commands/baseline.d.ts +14 -0
- package/dist/cli/commands/baseline.js +449 -0
- package/dist/cli/commands/beta.d.ts +10 -0
- package/dist/cli/commands/beta.js +231 -0
- package/dist/cli/commands/check.d.ts +11 -0
- package/dist/cli/commands/check.js +820 -0
- package/dist/cli/commands/cloud/badge.d.ts +3 -0
- package/dist/cli/commands/cloud/badge.js +74 -0
- package/dist/cli/commands/cloud/diff.d.ts +6 -0
- package/dist/cli/commands/cloud/diff.js +79 -0
- package/dist/cli/commands/cloud/history.d.ts +6 -0
- package/dist/cli/commands/cloud/history.js +102 -0
- package/dist/cli/commands/cloud/link.d.ts +9 -0
- package/dist/cli/commands/cloud/link.js +119 -0
- package/dist/cli/commands/cloud/login.d.ts +7 -0
- package/dist/cli/commands/cloud/login.js +499 -0
- package/dist/cli/commands/cloud/projects.d.ts +6 -0
- package/dist/cli/commands/cloud/projects.js +44 -0
- package/dist/cli/commands/cloud/shared.d.ts +7 -0
- package/dist/cli/commands/cloud/shared.js +42 -0
- package/dist/cli/commands/cloud/teams.d.ts +8 -0
- package/dist/cli/commands/cloud/teams.js +169 -0
- package/dist/cli/commands/cloud/upload.d.ts +8 -0
- package/dist/cli/commands/cloud/upload.js +181 -0
- package/dist/cli/commands/contract.d.ts +11 -0
- package/dist/cli/commands/contract.js +280 -0
- package/dist/cli/commands/discover.d.ts +3 -0
- package/dist/cli/commands/discover.js +82 -0
- package/dist/cli/commands/eval.d.ts +9 -0
- package/dist/cli/commands/eval.js +187 -0
- package/dist/cli/commands/explore.d.ts +11 -0
- package/dist/cli/commands/explore.js +437 -0
- package/dist/cli/commands/feedback.d.ts +9 -0
- package/dist/cli/commands/feedback.js +174 -0
- package/dist/cli/commands/golden.d.ts +12 -0
- package/dist/cli/commands/golden.js +407 -0
- package/dist/cli/commands/history.d.ts +10 -0
- package/dist/cli/commands/history.js +202 -0
- package/dist/cli/commands/init.d.ts +9 -0
- package/dist/cli/commands/init.js +219 -0
- package/dist/cli/commands/interview.d.ts +3 -0
- package/dist/cli/commands/interview.js +903 -0
- package/dist/cli/commands/link.d.ts +10 -0
- package/dist/cli/commands/link.js +169 -0
- package/dist/cli/commands/login.d.ts +7 -0
- package/dist/cli/commands/login.js +499 -0
- package/dist/cli/commands/preset.d.ts +33 -0
- package/dist/cli/commands/preset.js +297 -0
- package/dist/cli/commands/profile.d.ts +33 -0
- package/dist/cli/commands/profile.js +286 -0
- package/dist/cli/commands/registry.d.ts +11 -0
- package/dist/cli/commands/registry.js +146 -0
- package/dist/cli/commands/shared.d.ts +79 -0
- package/dist/cli/commands/shared.js +196 -0
- package/dist/cli/commands/teams.d.ts +8 -0
- package/dist/cli/commands/teams.js +169 -0
- package/dist/cli/commands/test.d.ts +9 -0
- package/dist/cli/commands/test.js +500 -0
- package/dist/cli/commands/upload.d.ts +8 -0
- package/dist/cli/commands/upload.js +223 -0
- package/dist/cli/commands/validate-config.d.ts +6 -0
- package/dist/cli/commands/validate-config.js +35 -0
- package/dist/cli/commands/verify.d.ts +11 -0
- package/dist/cli/commands/verify.js +283 -0
- package/dist/cli/commands/watch.d.ts +12 -0
- package/dist/cli/commands/watch.js +253 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.js +178 -0
- package/dist/cli/interactive.d.ts +47 -0
- package/dist/cli/interactive.js +216 -0
- package/dist/cli/output/terminal-reporter.d.ts +19 -0
- package/dist/cli/output/terminal-reporter.js +104 -0
- package/dist/cli/output.d.ts +226 -0
- package/dist/cli/output.js +438 -0
- package/dist/cli/utils/env.d.ts +5 -0
- package/dist/cli/utils/env.js +14 -0
- package/dist/cli/utils/progress.d.ts +59 -0
- package/dist/cli/utils/progress.js +206 -0
- package/dist/cli/utils/server-context.d.ts +10 -0
- package/dist/cli/utils/server-context.js +36 -0
- package/dist/cloud/auth.d.ts +144 -0
- package/dist/cloud/auth.js +374 -0
- package/dist/cloud/client.d.ts +24 -0
- package/dist/cloud/client.js +65 -0
- package/dist/cloud/http-client.d.ts +38 -0
- package/dist/cloud/http-client.js +215 -0
- package/dist/cloud/index.d.ts +23 -0
- package/dist/cloud/index.js +25 -0
- package/dist/cloud/mock-client.d.ts +107 -0
- package/dist/cloud/mock-client.js +545 -0
- package/dist/cloud/types.d.ts +515 -0
- package/dist/cloud/types.js +15 -0
- package/dist/config/defaults.d.ts +160 -0
- package/dist/config/defaults.js +169 -0
- package/dist/config/loader.d.ts +24 -0
- package/dist/config/loader.js +122 -0
- package/dist/config/template.d.ts +42 -0
- package/dist/config/template.js +647 -0
- package/dist/config/validator.d.ts +2112 -0
- package/dist/config/validator.js +658 -0
- package/dist/constants/cloud.d.ts +107 -0
- package/dist/constants/cloud.js +110 -0
- package/dist/constants/core.d.ts +521 -0
- package/dist/constants/core.js +556 -0
- package/dist/constants/testing.d.ts +1283 -0
- package/dist/constants/testing.js +1568 -0
- package/dist/constants.d.ts +10 -0
- package/dist/constants.js +10 -0
- package/dist/contract/index.d.ts +6 -0
- package/dist/contract/index.js +5 -0
- package/dist/contract/validator.d.ts +177 -0
- package/dist/contract/validator.js +574 -0
- package/dist/cost/index.d.ts +6 -0
- package/dist/cost/index.js +5 -0
- package/dist/cost/tracker.d.ts +134 -0
- package/dist/cost/tracker.js +313 -0
- package/dist/discovery/discovery.d.ts +16 -0
- package/dist/discovery/discovery.js +173 -0
- package/dist/discovery/types.d.ts +51 -0
- package/dist/discovery/types.js +2 -0
- package/dist/docs/agents.d.ts +3 -0
- package/dist/docs/agents.js +995 -0
- package/dist/docs/contract.d.ts +51 -0
- package/dist/docs/contract.js +1681 -0
- package/dist/docs/generator.d.ts +4 -0
- package/dist/docs/generator.js +4 -0
- package/dist/docs/html-reporter.d.ts +9 -0
- package/dist/docs/html-reporter.js +757 -0
- package/dist/docs/index.d.ts +10 -0
- package/dist/docs/index.js +11 -0
- package/dist/docs/junit-reporter.d.ts +18 -0
- package/dist/docs/junit-reporter.js +210 -0
- package/dist/docs/report.d.ts +14 -0
- package/dist/docs/report.js +44 -0
- package/dist/docs/sarif-reporter.d.ts +19 -0
- package/dist/docs/sarif-reporter.js +335 -0
- package/dist/docs/shared.d.ts +35 -0
- package/dist/docs/shared.js +162 -0
- package/dist/docs/templates.d.ts +12 -0
- package/dist/docs/templates.js +76 -0
- package/dist/errors/index.d.ts +6 -0
- package/dist/errors/index.js +6 -0
- package/dist/errors/retry.d.ts +92 -0
- package/dist/errors/retry.js +323 -0
- package/dist/errors/types.d.ts +321 -0
- package/dist/errors/types.js +584 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +32 -0
- package/dist/interview/dependency-resolver.d.ts +11 -0
- package/dist/interview/dependency-resolver.js +32 -0
- package/dist/interview/interviewer.d.ts +232 -0
- package/dist/interview/interviewer.js +1939 -0
- package/dist/interview/mock-response-generator.d.ts +7 -0
- package/dist/interview/mock-response-generator.js +102 -0
- package/dist/interview/orchestrator.d.ts +237 -0
- package/dist/interview/orchestrator.js +1296 -0
- package/dist/interview/rate-limiter.d.ts +15 -0
- package/dist/interview/rate-limiter.js +55 -0
- package/dist/interview/response-validator.d.ts +10 -0
- package/dist/interview/response-validator.js +132 -0
- package/dist/interview/schema-inferrer.d.ts +8 -0
- package/dist/interview/schema-inferrer.js +71 -0
- package/dist/interview/schema-test-generator.d.ts +71 -0
- package/dist/interview/schema-test-generator.js +834 -0
- package/dist/interview/smart-value-generator.d.ts +155 -0
- package/dist/interview/smart-value-generator.js +554 -0
- package/dist/interview/stateful-test-runner.d.ts +19 -0
- package/dist/interview/stateful-test-runner.js +106 -0
- package/dist/interview/types.d.ts +561 -0
- package/dist/interview/types.js +2 -0
- package/dist/llm/anthropic.d.ts +41 -0
- package/dist/llm/anthropic.js +355 -0
- package/dist/llm/client.d.ts +123 -0
- package/dist/llm/client.js +42 -0
- package/dist/llm/factory.d.ts +38 -0
- package/dist/llm/factory.js +145 -0
- package/dist/llm/fallback.d.ts +140 -0
- package/dist/llm/fallback.js +379 -0
- package/dist/llm/index.d.ts +18 -0
- package/dist/llm/index.js +15 -0
- package/dist/llm/ollama.d.ts +37 -0
- package/dist/llm/ollama.js +330 -0
- package/dist/llm/openai.d.ts +25 -0
- package/dist/llm/openai.js +320 -0
- package/dist/llm/token-budget.d.ts +161 -0
- package/dist/llm/token-budget.js +395 -0
- package/dist/logging/logger.d.ts +70 -0
- package/dist/logging/logger.js +130 -0
- package/dist/metrics/collector.d.ts +106 -0
- package/dist/metrics/collector.js +547 -0
- package/dist/metrics/index.d.ts +7 -0
- package/dist/metrics/index.js +7 -0
- package/dist/metrics/prometheus.d.ts +20 -0
- package/dist/metrics/prometheus.js +241 -0
- package/dist/metrics/types.d.ts +209 -0
- package/dist/metrics/types.js +5 -0
- package/dist/persona/builtins.d.ts +54 -0
- package/dist/persona/builtins.js +219 -0
- package/dist/persona/index.d.ts +8 -0
- package/dist/persona/index.js +8 -0
- package/dist/persona/loader.d.ts +30 -0
- package/dist/persona/loader.js +190 -0
- package/dist/persona/types.d.ts +144 -0
- package/dist/persona/types.js +5 -0
- package/dist/persona/validation.d.ts +94 -0
- package/dist/persona/validation.js +332 -0
- package/dist/prompts/index.d.ts +5 -0
- package/dist/prompts/index.js +5 -0
- package/dist/prompts/templates.d.ts +180 -0
- package/dist/prompts/templates.js +431 -0
- package/dist/registry/client.d.ts +49 -0
- package/dist/registry/client.js +191 -0
- package/dist/registry/index.d.ts +7 -0
- package/dist/registry/index.js +6 -0
- package/dist/registry/types.d.ts +140 -0
- package/dist/registry/types.js +6 -0
- package/dist/scenarios/evaluator.d.ts +43 -0
- package/dist/scenarios/evaluator.js +206 -0
- package/dist/scenarios/index.d.ts +10 -0
- package/dist/scenarios/index.js +9 -0
- package/dist/scenarios/loader.d.ts +20 -0
- package/dist/scenarios/loader.js +285 -0
- package/dist/scenarios/types.d.ts +153 -0
- package/dist/scenarios/types.js +8 -0
- package/dist/security/index.d.ts +17 -0
- package/dist/security/index.js +18 -0
- package/dist/security/payloads.d.ts +61 -0
- package/dist/security/payloads.js +268 -0
- package/dist/security/security-tester.d.ts +42 -0
- package/dist/security/security-tester.js +582 -0
- package/dist/security/types.d.ts +166 -0
- package/dist/security/types.js +8 -0
- package/dist/transport/base-transport.d.ts +59 -0
- package/dist/transport/base-transport.js +38 -0
- package/dist/transport/http-transport.d.ts +67 -0
- package/dist/transport/http-transport.js +238 -0
- package/dist/transport/mcp-client.d.ts +141 -0
- package/dist/transport/mcp-client.js +496 -0
- package/dist/transport/sse-transport.d.ts +88 -0
- package/dist/transport/sse-transport.js +316 -0
- package/dist/transport/stdio-transport.d.ts +43 -0
- package/dist/transport/stdio-transport.js +238 -0
- package/dist/transport/types.d.ts +125 -0
- package/dist/transport/types.js +16 -0
- package/dist/utils/concurrency.d.ts +123 -0
- package/dist/utils/concurrency.js +213 -0
- package/dist/utils/formatters.d.ts +16 -0
- package/dist/utils/formatters.js +37 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/jsonpath.d.ts +87 -0
- package/dist/utils/jsonpath.js +326 -0
- package/dist/utils/markdown.d.ts +113 -0
- package/dist/utils/markdown.js +265 -0
- package/dist/utils/network.d.ts +14 -0
- package/dist/utils/network.js +17 -0
- package/dist/utils/sanitize.d.ts +92 -0
- package/dist/utils/sanitize.js +191 -0
- package/dist/utils/semantic.d.ts +194 -0
- package/dist/utils/semantic.js +1051 -0
- package/dist/utils/smart-truncate.d.ts +94 -0
- package/dist/utils/smart-truncate.js +361 -0
- package/dist/utils/timeout.d.ts +153 -0
- package/dist/utils/timeout.js +205 -0
- package/dist/utils/yaml-parser.d.ts +58 -0
- package/dist/utils/yaml-parser.js +86 -0
- package/dist/validation/index.d.ts +32 -0
- package/dist/validation/index.js +32 -0
- package/dist/validation/semantic-test-generator.d.ts +50 -0
- package/dist/validation/semantic-test-generator.js +176 -0
- package/dist/validation/semantic-types.d.ts +66 -0
- package/dist/validation/semantic-types.js +94 -0
- package/dist/validation/semantic-validator.d.ts +38 -0
- package/dist/validation/semantic-validator.js +340 -0
- package/dist/verification/index.d.ts +6 -0
- package/dist/verification/index.js +5 -0
- package/dist/verification/types.d.ts +133 -0
- package/dist/verification/types.js +5 -0
- package/dist/verification/verifier.d.ts +30 -0
- package/dist/verification/verifier.js +309 -0
- package/dist/version.d.ts +19 -0
- package/dist/version.js +48 -0
- package/dist/workflow/auto-generator.d.ts +27 -0
- package/dist/workflow/auto-generator.js +513 -0
- package/dist/workflow/discovery.d.ts +40 -0
- package/dist/workflow/discovery.js +195 -0
- package/dist/workflow/executor.d.ts +82 -0
- package/dist/workflow/executor.js +611 -0
- package/dist/workflow/index.d.ts +10 -0
- package/dist/workflow/index.js +10 -0
- package/dist/workflow/loader.d.ts +24 -0
- package/dist/workflow/loader.js +194 -0
- package/dist/workflow/state-tracker.d.ts +98 -0
- package/dist/workflow/state-tracker.js +424 -0
- package/dist/workflow/types.d.ts +337 -0
- package/dist/workflow/types.js +5 -0
- package/package.json +94 -0
- package/schemas/bellwether-check.schema.json +651 -0
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telemetry and Decision Logging for Drift Detection
|
|
3
|
+
*
|
|
4
|
+
* Records comparison decisions for post-hoc analysis and algorithm improvement.
|
|
5
|
+
* Decisions are logged locally and can be exported for feedback or A/B testing.
|
|
6
|
+
*/
|
|
7
|
+
import { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
8
|
+
import { join } from 'path';
|
|
9
|
+
import { homedir } from 'os';
|
|
10
|
+
import { randomUUID } from 'crypto';
|
|
11
|
+
/**
|
|
12
|
+
* Get the telemetry directory path.
|
|
13
|
+
*/
|
|
14
|
+
function getTelemetryDir() {
|
|
15
|
+
return join(homedir(), '.bellwether', 'telemetry');
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Ensure telemetry directory exists.
|
|
19
|
+
*/
|
|
20
|
+
function ensureTelemetryDir() {
|
|
21
|
+
const dir = getTelemetryDir();
|
|
22
|
+
if (!existsSync(dir)) {
|
|
23
|
+
mkdirSync(dir, { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Decision logger for recording and analyzing comparison decisions.
|
|
28
|
+
*/
|
|
29
|
+
export class DecisionLogger {
|
|
30
|
+
decisions = [];
|
|
31
|
+
logPath;
|
|
32
|
+
enabled;
|
|
33
|
+
constructor(options = {}) {
|
|
34
|
+
this.enabled = options.enabled ?? true;
|
|
35
|
+
ensureTelemetryDir();
|
|
36
|
+
this.logPath = options.logPath ?? join(getTelemetryDir(), 'comparison-log.jsonl');
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Log a comparison decision.
|
|
40
|
+
*/
|
|
41
|
+
log(decision) {
|
|
42
|
+
const fullDecision = {
|
|
43
|
+
...decision,
|
|
44
|
+
id: randomUUID(),
|
|
45
|
+
timestamp: new Date(),
|
|
46
|
+
bellwetherVersion: getVersion(),
|
|
47
|
+
};
|
|
48
|
+
this.decisions.push(fullDecision);
|
|
49
|
+
if (this.enabled) {
|
|
50
|
+
try {
|
|
51
|
+
appendFileSync(this.logPath, JSON.stringify(fullDecision) + '\n');
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// Silently fail if we can't write to log file
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return fullDecision.id;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Get all logged decisions from this session.
|
|
61
|
+
*/
|
|
62
|
+
getSessionDecisions() {
|
|
63
|
+
return [...this.decisions];
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Load all decisions from the log file.
|
|
67
|
+
*/
|
|
68
|
+
loadAllDecisions() {
|
|
69
|
+
if (!existsSync(this.logPath)) {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
const content = readFileSync(this.logPath, 'utf-8');
|
|
74
|
+
const lines = content.trim().split('\n').filter(Boolean);
|
|
75
|
+
return lines.map(line => {
|
|
76
|
+
const decision = JSON.parse(line);
|
|
77
|
+
decision.timestamp = new Date(decision.timestamp);
|
|
78
|
+
return decision;
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Get a specific decision by ID.
|
|
87
|
+
*/
|
|
88
|
+
getDecision(id) {
|
|
89
|
+
// First check session decisions
|
|
90
|
+
const sessionDecision = this.decisions.find(d => d.id === id);
|
|
91
|
+
if (sessionDecision)
|
|
92
|
+
return sessionDecision;
|
|
93
|
+
// Then check log file
|
|
94
|
+
const allDecisions = this.loadAllDecisions();
|
|
95
|
+
return allDecisions.find(d => d.id === id);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Export decisions to a JSON file.
|
|
99
|
+
*/
|
|
100
|
+
exportToFile(filePath) {
|
|
101
|
+
const decisions = this.loadAllDecisions();
|
|
102
|
+
writeFileSync(filePath, JSON.stringify(decisions, null, 2));
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get statistics about logged decisions.
|
|
106
|
+
*/
|
|
107
|
+
getStatistics() {
|
|
108
|
+
const decisions = this.loadAllDecisions();
|
|
109
|
+
if (decisions.length === 0) {
|
|
110
|
+
return {
|
|
111
|
+
totalDecisions: 0,
|
|
112
|
+
byType: {},
|
|
113
|
+
averageConfidence: 0,
|
|
114
|
+
matchRate: 0,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
const byType = {};
|
|
118
|
+
let totalConfidence = 0;
|
|
119
|
+
let matchCount = 0;
|
|
120
|
+
for (const decision of decisions) {
|
|
121
|
+
byType[decision.type] = (byType[decision.type] || 0) + 1;
|
|
122
|
+
totalConfidence += decision.rawConfidence;
|
|
123
|
+
if (decision.matchDecision)
|
|
124
|
+
matchCount++;
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
totalDecisions: decisions.length,
|
|
128
|
+
byType,
|
|
129
|
+
averageConfidence: Math.round(totalConfidence / decisions.length),
|
|
130
|
+
matchRate: Math.round((matchCount / decisions.length) * 100),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Clear all logged decisions.
|
|
135
|
+
*/
|
|
136
|
+
clear() {
|
|
137
|
+
this.decisions = [];
|
|
138
|
+
if (existsSync(this.logPath)) {
|
|
139
|
+
writeFileSync(this.logPath, '');
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Feedback manager for recording and analyzing user feedback.
|
|
145
|
+
*/
|
|
146
|
+
export class FeedbackManager {
|
|
147
|
+
feedbackPath;
|
|
148
|
+
constructor(options = {}) {
|
|
149
|
+
ensureTelemetryDir();
|
|
150
|
+
this.feedbackPath = options.feedbackPath ?? join(getTelemetryDir(), 'feedback.jsonl');
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Submit feedback on a comparison decision.
|
|
154
|
+
*/
|
|
155
|
+
submit(feedback) {
|
|
156
|
+
const fullFeedback = {
|
|
157
|
+
...feedback,
|
|
158
|
+
timestamp: new Date(),
|
|
159
|
+
};
|
|
160
|
+
try {
|
|
161
|
+
appendFileSync(this.feedbackPath, JSON.stringify(fullFeedback) + '\n');
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
// Silently fail if we can't write
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Load all feedback reports.
|
|
169
|
+
*/
|
|
170
|
+
loadAll() {
|
|
171
|
+
if (!existsSync(this.feedbackPath)) {
|
|
172
|
+
return [];
|
|
173
|
+
}
|
|
174
|
+
try {
|
|
175
|
+
const content = readFileSync(this.feedbackPath, 'utf-8');
|
|
176
|
+
const lines = content.trim().split('\n').filter(Boolean);
|
|
177
|
+
return lines.map(line => {
|
|
178
|
+
const report = JSON.parse(line);
|
|
179
|
+
report.timestamp = new Date(report.timestamp);
|
|
180
|
+
return report;
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
return [];
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Analyze all feedback to identify patterns.
|
|
189
|
+
*/
|
|
190
|
+
analyze() {
|
|
191
|
+
const reports = this.loadAll();
|
|
192
|
+
if (reports.length === 0) {
|
|
193
|
+
return {
|
|
194
|
+
totalReports: 0,
|
|
195
|
+
falsePositiveRate: 0,
|
|
196
|
+
falseNegativeRate: 0,
|
|
197
|
+
confidenceIssueRate: 0,
|
|
198
|
+
commonPatterns: [],
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
const fpCount = reports.filter(r => r.feedbackType === 'false_positive').length;
|
|
202
|
+
const fnCount = reports.filter(r => r.feedbackType === 'false_negative').length;
|
|
203
|
+
const confCount = reports.filter(r => r.feedbackType === 'confidence_wrong').length;
|
|
204
|
+
// Extract common patterns from user comments
|
|
205
|
+
const patternCounts = new Map();
|
|
206
|
+
for (const report of reports) {
|
|
207
|
+
if (report.userComment) {
|
|
208
|
+
// Simple keyword extraction
|
|
209
|
+
const keywords = report.userComment.toLowerCase()
|
|
210
|
+
.split(/\s+/)
|
|
211
|
+
.filter(word => word.length > 4);
|
|
212
|
+
for (const keyword of keywords) {
|
|
213
|
+
const existing = patternCounts.get(keyword);
|
|
214
|
+
if (existing) {
|
|
215
|
+
existing.count++;
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
patternCounts.set(keyword, { count: 1, feedbackType: report.feedbackType });
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
const commonPatterns = Array.from(patternCounts.entries())
|
|
224
|
+
.filter(([, data]) => data.count >= 2)
|
|
225
|
+
.sort((a, b) => b[1].count - a[1].count)
|
|
226
|
+
.slice(0, 10)
|
|
227
|
+
.map(([pattern, data]) => ({
|
|
228
|
+
pattern,
|
|
229
|
+
count: data.count,
|
|
230
|
+
feedbackType: data.feedbackType,
|
|
231
|
+
}));
|
|
232
|
+
return {
|
|
233
|
+
totalReports: reports.length,
|
|
234
|
+
falsePositiveRate: Math.round((fpCount / reports.length) * 100),
|
|
235
|
+
falseNegativeRate: Math.round((fnCount / reports.length) * 100),
|
|
236
|
+
confidenceIssueRate: Math.round((confCount / reports.length) * 100),
|
|
237
|
+
commonPatterns,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Clear all feedback.
|
|
242
|
+
*/
|
|
243
|
+
clear() {
|
|
244
|
+
if (existsSync(this.feedbackPath)) {
|
|
245
|
+
writeFileSync(this.feedbackPath, '');
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Get the package version.
|
|
251
|
+
*/
|
|
252
|
+
function getVersion() {
|
|
253
|
+
try {
|
|
254
|
+
// Try to read from package.json
|
|
255
|
+
const packageJsonPath = join(__dirname, '..', '..', 'package.json');
|
|
256
|
+
if (existsSync(packageJsonPath)) {
|
|
257
|
+
const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
258
|
+
return pkg.version || '0.0.0';
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
catch {
|
|
262
|
+
// Ignore errors
|
|
263
|
+
}
|
|
264
|
+
return '0.0.0';
|
|
265
|
+
}
|
|
266
|
+
// Singleton instances for global access
|
|
267
|
+
let globalDecisionLogger = null;
|
|
268
|
+
let globalFeedbackManager = null;
|
|
269
|
+
/**
|
|
270
|
+
* Get the global decision logger instance.
|
|
271
|
+
*/
|
|
272
|
+
export function getDecisionLogger(options) {
|
|
273
|
+
if (!globalDecisionLogger) {
|
|
274
|
+
globalDecisionLogger = new DecisionLogger(options);
|
|
275
|
+
}
|
|
276
|
+
return globalDecisionLogger;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Get the global feedback manager instance.
|
|
280
|
+
*/
|
|
281
|
+
export function getFeedbackManager() {
|
|
282
|
+
if (!globalFeedbackManager) {
|
|
283
|
+
globalFeedbackManager = new FeedbackManager();
|
|
284
|
+
}
|
|
285
|
+
return globalFeedbackManager;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Reset global instances (for testing).
|
|
289
|
+
*/
|
|
290
|
+
export function resetTelemetry() {
|
|
291
|
+
globalDecisionLogger = null;
|
|
292
|
+
globalFeedbackManager = null;
|
|
293
|
+
}
|
|
294
|
+
//# sourceMappingURL=telemetry.js.map
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Intelligent Test Pruning.
|
|
3
|
+
*
|
|
4
|
+
* Determines which test categories to run or skip based on tool characteristics
|
|
5
|
+
* and testing history. Reduces test time while maintaining coverage where it matters.
|
|
6
|
+
*/
|
|
7
|
+
import type { MCPTool } from '../transport/types.js';
|
|
8
|
+
import type { ToolFingerprint, ErrorPattern } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Test category type.
|
|
11
|
+
*/
|
|
12
|
+
export type TestCategory = 'happy_path' | 'boundary' | 'enum' | 'optional_combinations' | 'error_handling' | 'security' | 'semantic';
|
|
13
|
+
/**
|
|
14
|
+
* Decision about a test category.
|
|
15
|
+
*/
|
|
16
|
+
export interface TestCategoryDecision {
|
|
17
|
+
/** The test category */
|
|
18
|
+
category: TestCategory;
|
|
19
|
+
/** Whether to run this category */
|
|
20
|
+
shouldRun: boolean;
|
|
21
|
+
/** Reason for the decision */
|
|
22
|
+
reason: string;
|
|
23
|
+
/** Priority if running (higher = more important) */
|
|
24
|
+
priority: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Complete pruning decision for a tool.
|
|
28
|
+
*/
|
|
29
|
+
export interface ToolPruningDecision {
|
|
30
|
+
/** Tool name */
|
|
31
|
+
toolName: string;
|
|
32
|
+
/** Overall tool priority (0-100) */
|
|
33
|
+
priority: number;
|
|
34
|
+
/** Decisions for each category */
|
|
35
|
+
categories: TestCategoryDecision[];
|
|
36
|
+
/** Categories that will run */
|
|
37
|
+
categoriesToRun: TestCategory[];
|
|
38
|
+
/** Categories that will skip */
|
|
39
|
+
categoriesToSkip: TestCategory[];
|
|
40
|
+
/** Estimated test reduction percentage */
|
|
41
|
+
reductionPercent: number;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Tool characteristics for pruning decisions.
|
|
45
|
+
*/
|
|
46
|
+
export interface ToolCharacteristics {
|
|
47
|
+
/** Number of parameters */
|
|
48
|
+
parameterCount: number;
|
|
49
|
+
/** Number of required parameters */
|
|
50
|
+
requiredParamCount: number;
|
|
51
|
+
/** Whether tool has numeric parameters */
|
|
52
|
+
hasNumericParams: boolean;
|
|
53
|
+
/** Whether tool has enum parameters */
|
|
54
|
+
hasEnumParams: boolean;
|
|
55
|
+
/** Whether tool has optional parameters */
|
|
56
|
+
hasOptionalParams: boolean;
|
|
57
|
+
/** Whether tool has string parameters (for security testing) */
|
|
58
|
+
hasStringParams: boolean;
|
|
59
|
+
/** Maximum nesting depth in schema */
|
|
60
|
+
maxNestingDepth: number;
|
|
61
|
+
/** Whether tool has external dependencies */
|
|
62
|
+
hasExternalDependency: boolean;
|
|
63
|
+
/** Error rate from previous testing (0-1) */
|
|
64
|
+
errorRate: number;
|
|
65
|
+
/** Hours since last test (null if never tested) */
|
|
66
|
+
hoursSinceLastTest: number | null;
|
|
67
|
+
/** Consecutive successful runs */
|
|
68
|
+
consecutiveSuccesses: number;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Input for making pruning decisions.
|
|
72
|
+
*/
|
|
73
|
+
export interface PruningInput {
|
|
74
|
+
/** Tool definition */
|
|
75
|
+
tool: MCPTool;
|
|
76
|
+
/** Previous baseline fingerprint (if available) */
|
|
77
|
+
fingerprint?: ToolFingerprint;
|
|
78
|
+
/** Error patterns from baseline */
|
|
79
|
+
errorPatterns?: ErrorPattern[];
|
|
80
|
+
/** All test categories that could run */
|
|
81
|
+
availableCategories: TestCategory[];
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Calculate pruning decisions for a set of tools.
|
|
85
|
+
*/
|
|
86
|
+
export declare function calculatePruningDecisions(inputs: PruningInput[]): ToolPruningDecision[];
|
|
87
|
+
/**
|
|
88
|
+
* Calculate pruning decision for a single tool.
|
|
89
|
+
*/
|
|
90
|
+
export declare function calculateToolPruning(input: PruningInput): ToolPruningDecision;
|
|
91
|
+
/**
|
|
92
|
+
* Prioritize tools for testing order.
|
|
93
|
+
*/
|
|
94
|
+
export declare function prioritizeTools(decisions: ToolPruningDecision[]): ToolPruningDecision[];
|
|
95
|
+
/**
|
|
96
|
+
* Generate summary of pruning decisions.
|
|
97
|
+
*/
|
|
98
|
+
export interface PruningSummary {
|
|
99
|
+
/** Total tools analyzed */
|
|
100
|
+
totalTools: number;
|
|
101
|
+
/** Total categories that would run without pruning */
|
|
102
|
+
totalCategoriesWithoutPruning: number;
|
|
103
|
+
/** Total categories that will run with pruning */
|
|
104
|
+
totalCategoriesWithPruning: number;
|
|
105
|
+
/** Overall reduction percentage */
|
|
106
|
+
overallReduction: number;
|
|
107
|
+
/** Tools with highest priority */
|
|
108
|
+
highPriorityTools: string[];
|
|
109
|
+
/** Tools with most categories skipped */
|
|
110
|
+
mostPrunedTools: string[];
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Generate pruning summary.
|
|
114
|
+
*/
|
|
115
|
+
export declare function generatePruningSummary(decisions: ToolPruningDecision[]): PruningSummary;
|
|
116
|
+
/**
|
|
117
|
+
* Generate markdown report for pruning decisions.
|
|
118
|
+
*/
|
|
119
|
+
export declare function generatePruningMarkdown(decisions: ToolPruningDecision[], summary: PruningSummary): string;
|
|
120
|
+
//# sourceMappingURL=test-pruner.d.ts.map
|