@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,253 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Watch command - watch for file changes and auto-check.
|
|
3
|
+
*
|
|
4
|
+
* Uses bellwether.yaml for configuration.
|
|
5
|
+
* Only watch-specific options are available as flags.
|
|
6
|
+
*
|
|
7
|
+
* Note: Watch mode only runs schema validation (check mode).
|
|
8
|
+
* For LLM-powered exploration, use 'bellwether explore' directly.
|
|
9
|
+
*/
|
|
10
|
+
import { Command } from 'commander';
|
|
11
|
+
import { existsSync, readdirSync, statSync } from 'fs';
|
|
12
|
+
import { resolve, join } from 'path';
|
|
13
|
+
import { MCPClient } from '../../transport/mcp-client.js';
|
|
14
|
+
import { discover } from '../../discovery/discovery.js';
|
|
15
|
+
import { Interviewer } from '../../interview/interviewer.js';
|
|
16
|
+
import { loadConfig, ConfigNotFoundError } from '../../config/loader.js';
|
|
17
|
+
import { validateConfigForCheck } from '../../config/validator.js';
|
|
18
|
+
import { createBaseline, saveBaseline, loadBaseline, compareBaselines, formatDiffText, } from '../../baseline/index.js';
|
|
19
|
+
import { EXIT_CODES, CHECK_SAMPLING } from '../../constants.js';
|
|
20
|
+
import * as output from '../output.js';
|
|
21
|
+
export const watchCommand = new Command('watch')
|
|
22
|
+
.description('Watch for file changes and auto-check (uses bellwether.yaml)')
|
|
23
|
+
.argument('[server-command]', 'Server command (overrides config)')
|
|
24
|
+
.argument('[args...]', 'Server arguments')
|
|
25
|
+
.option('-c, --config <path>', 'Path to config file')
|
|
26
|
+
.action(async (serverCommandArg, serverArgs, options) => {
|
|
27
|
+
// Load configuration (required)
|
|
28
|
+
let config;
|
|
29
|
+
try {
|
|
30
|
+
config = loadConfig(options.config);
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
if (error instanceof ConfigNotFoundError) {
|
|
34
|
+
output.error(error.message);
|
|
35
|
+
process.exit(EXIT_CODES.ERROR);
|
|
36
|
+
}
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
// Determine server command (CLI arg overrides config)
|
|
40
|
+
const serverCommand = serverCommandArg || config.server.command;
|
|
41
|
+
const args = serverArgs.length > 0 ? serverArgs : config.server.args;
|
|
42
|
+
// Validate config for check mode (watch only does check, not explore)
|
|
43
|
+
try {
|
|
44
|
+
validateConfigForCheck(config, serverCommand);
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
output.error(error instanceof Error ? error.message : String(error));
|
|
48
|
+
process.exit(EXIT_CODES.ERROR);
|
|
49
|
+
}
|
|
50
|
+
// Get watch settings from config
|
|
51
|
+
const watchPath = resolve(config.watch.path);
|
|
52
|
+
const interval = config.watch.interval;
|
|
53
|
+
const extensions = config.watch.extensions;
|
|
54
|
+
const onDriftCommand = config.watch.onDrift;
|
|
55
|
+
const minSamplesForConfidence = CHECK_SAMPLING.SAMPLES_FOR_CONFIDENCE[config.check.sampling.targetConfidence];
|
|
56
|
+
const minSamples = Math.max(config.check.sampling.minSamples, minSamplesForConfidence);
|
|
57
|
+
// Baseline path for watch mode (use savePath or baseline default)
|
|
58
|
+
const baselinePathValue = config.baseline.savePath ?? config.baseline.path;
|
|
59
|
+
const baselinePath = baselinePathValue.startsWith('/')
|
|
60
|
+
? baselinePathValue
|
|
61
|
+
: resolve(join(config.output.dir, baselinePathValue));
|
|
62
|
+
// Extract settings from config
|
|
63
|
+
const timeout = config.server.timeout;
|
|
64
|
+
const verbose = config.logging.verbose;
|
|
65
|
+
output.info('Bellwether Watch Mode\n');
|
|
66
|
+
output.info(`Server: ${serverCommand} ${args.join(' ')}`);
|
|
67
|
+
output.info(`Mode: check (schema validation)`);
|
|
68
|
+
output.info(`Watching: ${watchPath}`);
|
|
69
|
+
output.info(`Baseline: ${baselinePath}`);
|
|
70
|
+
output.info(`Poll interval: ${interval}ms`);
|
|
71
|
+
output.info('');
|
|
72
|
+
output.info('Note: Watch mode runs schema validation only. Use "bellwether explore" for LLM analysis.');
|
|
73
|
+
output.info('');
|
|
74
|
+
// Track last baseline hash to detect changes
|
|
75
|
+
let lastBaselineHash = null;
|
|
76
|
+
if (existsSync(baselinePath)) {
|
|
77
|
+
const baseline = loadBaseline(baselinePath);
|
|
78
|
+
lastBaselineHash = baseline.integrityHash;
|
|
79
|
+
output.info(`Loaded existing baseline: ${lastBaselineHash.slice(0, 8)}`);
|
|
80
|
+
}
|
|
81
|
+
// Track watched file modification times
|
|
82
|
+
const fileModTimes = new Map();
|
|
83
|
+
async function runTest() {
|
|
84
|
+
const mcpClient = new MCPClient({ timeout });
|
|
85
|
+
try {
|
|
86
|
+
output.info('\n--- Running Test ---');
|
|
87
|
+
output.info(`[${new Date().toLocaleTimeString()}] Starting test...`);
|
|
88
|
+
await mcpClient.connect(serverCommand, args, config.server.env);
|
|
89
|
+
const discovery = await discover(mcpClient, serverCommand, args);
|
|
90
|
+
output.info(`Found ${discovery.tools.length} tools`);
|
|
91
|
+
if (discovery.tools.length === 0) {
|
|
92
|
+
output.info('No tools found. Skipping.');
|
|
93
|
+
await mcpClient.disconnect();
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const fullServerCommand = `${serverCommand} ${args.join(' ')}`.trim();
|
|
97
|
+
// Watch mode uses check (no LLM) for fast, deterministic drift detection
|
|
98
|
+
const interviewer = new Interviewer(null, {
|
|
99
|
+
maxQuestionsPerTool: minSamples,
|
|
100
|
+
timeout,
|
|
101
|
+
skipErrorTests: false,
|
|
102
|
+
model: 'check',
|
|
103
|
+
personas: [],
|
|
104
|
+
checkMode: true, // Required when passing null for LLM
|
|
105
|
+
parallelTools: config.check.parallel,
|
|
106
|
+
toolConcurrency: config.check.parallelWorkers,
|
|
107
|
+
serverCommand: fullServerCommand,
|
|
108
|
+
});
|
|
109
|
+
const progressCallback = (progress) => {
|
|
110
|
+
process.stdout.write(`\rChecking: ${progress.toolsCompleted + 1}/${progress.totalTools} tools`.padEnd(60));
|
|
111
|
+
};
|
|
112
|
+
const result = await interviewer.interview(mcpClient, discovery, progressCallback);
|
|
113
|
+
output.info('\n');
|
|
114
|
+
// Create and compare baseline
|
|
115
|
+
const newBaseline = createBaseline(result, fullServerCommand);
|
|
116
|
+
if (lastBaselineHash && existsSync(baselinePath)) {
|
|
117
|
+
const previousBaseline = loadBaseline(baselinePath);
|
|
118
|
+
const diff = compareBaselines(previousBaseline, newBaseline, {});
|
|
119
|
+
if (diff.severity !== 'none') {
|
|
120
|
+
output.info('\n--- Behavioral Drift Detected ---');
|
|
121
|
+
output.info(formatDiffText(diff));
|
|
122
|
+
// Run on-drift command if configured
|
|
123
|
+
if (onDriftCommand) {
|
|
124
|
+
output.info(`\nRunning: ${onDriftCommand}`);
|
|
125
|
+
const { spawnSync } = await import('child_process');
|
|
126
|
+
try {
|
|
127
|
+
// Parse command safely - split on spaces but respect quoted strings
|
|
128
|
+
const parts = onDriftCommand.match(/(?:[^\s"]+|"[^"]*")+/g);
|
|
129
|
+
if (!parts || parts.length === 0) {
|
|
130
|
+
throw new Error('Empty on-drift command');
|
|
131
|
+
}
|
|
132
|
+
const [cmd, ...rest] = parts;
|
|
133
|
+
const cmdArgs = rest.map((arg) => arg.replace(/^"|"$/g, ''));
|
|
134
|
+
// Use spawnSync without shell to prevent command injection
|
|
135
|
+
const cmdResult = spawnSync(cmd, cmdArgs, { stdio: 'inherit' });
|
|
136
|
+
if (cmdResult.error) {
|
|
137
|
+
throw cmdResult.error;
|
|
138
|
+
}
|
|
139
|
+
if (cmdResult.status !== 0) {
|
|
140
|
+
output.error(`On-drift command exited with code ${cmdResult.status}`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch (e) {
|
|
144
|
+
output.error('On-drift command failed: ' + (e instanceof Error ? e.message : String(e)));
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
output.info('No drift detected.');
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Save new baseline
|
|
153
|
+
saveBaseline(newBaseline, baselinePath);
|
|
154
|
+
lastBaselineHash = newBaseline.integrityHash;
|
|
155
|
+
output.info(`Baseline updated: ${newBaseline.integrityHash.slice(0, 8)}`);
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
output.error('Test failed: ' + (error instanceof Error ? error.message : String(error)));
|
|
159
|
+
}
|
|
160
|
+
finally {
|
|
161
|
+
await mcpClient.disconnect();
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
function checkForChanges() {
|
|
165
|
+
// Simple file watcher - check if any source files changed
|
|
166
|
+
let changed = false;
|
|
167
|
+
function walkDir(dir) {
|
|
168
|
+
try {
|
|
169
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
170
|
+
for (const entry of entries) {
|
|
171
|
+
const fullPath = join(dir, entry.name);
|
|
172
|
+
// Skip common directories
|
|
173
|
+
if (entry.isDirectory()) {
|
|
174
|
+
if (entry.name === 'node_modules' || entry.name === '.git' || entry.name === 'dist') {
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
walkDir(fullPath);
|
|
178
|
+
}
|
|
179
|
+
else if (entry.isFile()) {
|
|
180
|
+
if (extensions.some(ext => entry.name.endsWith(ext))) {
|
|
181
|
+
const stat = statSync(fullPath);
|
|
182
|
+
const modTime = stat.mtimeMs;
|
|
183
|
+
const lastMod = fileModTimes.get(fullPath);
|
|
184
|
+
if (lastMod === undefined) {
|
|
185
|
+
fileModTimes.set(fullPath, modTime);
|
|
186
|
+
}
|
|
187
|
+
else if (modTime > lastMod) {
|
|
188
|
+
fileModTimes.set(fullPath, modTime);
|
|
189
|
+
output.info(`\nFile changed: ${fullPath}`);
|
|
190
|
+
changed = true;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
if (verbose) {
|
|
198
|
+
output.error(`Warning: Error scanning ${dir}: ` + (error instanceof Error ? error.message : String(error)));
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
walkDir(watchPath);
|
|
203
|
+
return changed;
|
|
204
|
+
}
|
|
205
|
+
// Initial test run
|
|
206
|
+
await runTest();
|
|
207
|
+
output.info('\nWatching for changes... (Press Ctrl+C to exit)\n');
|
|
208
|
+
// Track current interval for proper cleanup
|
|
209
|
+
let currentInterval = null;
|
|
210
|
+
let isRunningInterview = false;
|
|
211
|
+
/**
|
|
212
|
+
* Poll for file changes and run test when changes detected.
|
|
213
|
+
*/
|
|
214
|
+
async function pollForChanges() {
|
|
215
|
+
if (isRunningInterview) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
try {
|
|
219
|
+
if (checkForChanges()) {
|
|
220
|
+
isRunningInterview = true;
|
|
221
|
+
await runTest();
|
|
222
|
+
output.info('\nWatching for changes... (Press Ctrl+C to exit)\n');
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
catch (error) {
|
|
226
|
+
output.error('Watch polling error: ' + (error instanceof Error ? error.message : String(error)));
|
|
227
|
+
}
|
|
228
|
+
finally {
|
|
229
|
+
isRunningInterview = false;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
// Start polling interval
|
|
233
|
+
currentInterval = setInterval(() => {
|
|
234
|
+
pollForChanges().catch((error) => {
|
|
235
|
+
output.error('Unexpected polling error: ' + (error instanceof Error ? error.message : String(error)));
|
|
236
|
+
});
|
|
237
|
+
}, interval);
|
|
238
|
+
// Handle exit
|
|
239
|
+
const cleanup = () => {
|
|
240
|
+
output.info('\n\nExiting watch mode.');
|
|
241
|
+
if (currentInterval) {
|
|
242
|
+
clearInterval(currentInterval);
|
|
243
|
+
currentInterval = null;
|
|
244
|
+
}
|
|
245
|
+
// Remove signal handlers to prevent accumulation
|
|
246
|
+
process.removeListener('SIGINT', cleanup);
|
|
247
|
+
process.removeListener('SIGTERM', cleanup);
|
|
248
|
+
process.exit(EXIT_CODES.CLEAN);
|
|
249
|
+
};
|
|
250
|
+
process.on('SIGINT', cleanup);
|
|
251
|
+
process.on('SIGTERM', cleanup);
|
|
252
|
+
});
|
|
253
|
+
//# sourceMappingURL=watch.js.map
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { config } from 'dotenv';
|
|
3
|
+
import { existsSync } from 'fs';
|
|
4
|
+
import { join } from 'path';
|
|
5
|
+
import { homedir } from 'os';
|
|
6
|
+
// Load global ~/.bellwether/.env first (if exists)
|
|
7
|
+
const globalEnvPath = join(homedir(), '.bellwether', '.env');
|
|
8
|
+
if (existsSync(globalEnvPath)) {
|
|
9
|
+
config({ path: globalEnvPath });
|
|
10
|
+
}
|
|
11
|
+
// Then load project .env (overrides global settings)
|
|
12
|
+
config();
|
|
13
|
+
// Load credentials from keychain if not already in env
|
|
14
|
+
// This is done async but we await it before parsing commands
|
|
15
|
+
async function loadKeychainCredentials() {
|
|
16
|
+
// Only load from keychain if env vars aren't already set
|
|
17
|
+
if (!process.env.OPENAI_API_KEY || !process.env.ANTHROPIC_API_KEY) {
|
|
18
|
+
try {
|
|
19
|
+
const { getKeychainService } = await import('../auth/keychain.js');
|
|
20
|
+
const keychain = getKeychainService();
|
|
21
|
+
// Load OpenAI key if not in env
|
|
22
|
+
if (!process.env.OPENAI_API_KEY) {
|
|
23
|
+
const key = await keychain.getApiKey('openai');
|
|
24
|
+
if (key) {
|
|
25
|
+
process.env.OPENAI_API_KEY = key;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
// Load Anthropic key if not in env
|
|
29
|
+
if (!process.env.ANTHROPIC_API_KEY) {
|
|
30
|
+
const key = await keychain.getApiKey('anthropic');
|
|
31
|
+
if (key) {
|
|
32
|
+
process.env.ANTHROPIC_API_KEY = key;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// Keychain not available - continue without it
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
import { Command } from 'commander';
|
|
42
|
+
import { checkCommand } from './commands/check.js';
|
|
43
|
+
import { exploreCommand } from './commands/explore.js';
|
|
44
|
+
import { discoverCommand } from './commands/discover.js';
|
|
45
|
+
import { watchCommand } from './commands/watch.js';
|
|
46
|
+
import { initCommand } from './commands/init.js';
|
|
47
|
+
import { authCommand } from './commands/auth.js';
|
|
48
|
+
import { baselineCommand } from './commands/baseline.js';
|
|
49
|
+
import { goldenCommand } from './commands/golden.js';
|
|
50
|
+
import { registryCommand } from './commands/registry.js';
|
|
51
|
+
import { verifyCommand } from './commands/verify.js';
|
|
52
|
+
import { contractCommand } from './commands/contract.js';
|
|
53
|
+
import { validateConfigCommand } from './commands/validate-config.js';
|
|
54
|
+
import { badgeCommand } from './commands/cloud/badge.js';
|
|
55
|
+
import { diffCommand } from './commands/cloud/diff.js';
|
|
56
|
+
import { historyCommand } from './commands/cloud/history.js';
|
|
57
|
+
import { linkCommand } from './commands/cloud/link.js';
|
|
58
|
+
import { loginCommand } from './commands/cloud/login.js';
|
|
59
|
+
import { projectsCommand } from './commands/cloud/projects.js';
|
|
60
|
+
import { teamsCommand } from './commands/cloud/teams.js';
|
|
61
|
+
import { uploadCommand } from './commands/cloud/upload.js';
|
|
62
|
+
import { configureLogger } from '../logging/logger.js';
|
|
63
|
+
import { VERSION } from '../version.js';
|
|
64
|
+
import { findConfigFile } from '../config/validator.js';
|
|
65
|
+
import { ConfigNotFoundError } from '../config/loader.js';
|
|
66
|
+
import { EXIT_CODES, PATHS } from '../constants.js';
|
|
67
|
+
const program = new Command();
|
|
68
|
+
// ASCII art banner for help
|
|
69
|
+
const banner = `
|
|
70
|
+
Bellwether - MCP Server Validation & Documentation
|
|
71
|
+
`;
|
|
72
|
+
// Extended help with examples
|
|
73
|
+
const examples = `
|
|
74
|
+
Examples:
|
|
75
|
+
|
|
76
|
+
Initialize configuration:
|
|
77
|
+
$ bellwether init # Create bellwether.yaml
|
|
78
|
+
$ bellwether init --preset ci # Optimized for CI/CD
|
|
79
|
+
$ bellwether init --preset local # Local LLM with Ollama
|
|
80
|
+
|
|
81
|
+
Check for drift (free, fast, deterministic):
|
|
82
|
+
$ bellwether check npx @mcp/my-server # Validate schemas
|
|
83
|
+
$ bellwether baseline save # Save baseline
|
|
84
|
+
$ bellwether baseline compare ./bellwether-baseline.json # Detect drift
|
|
85
|
+
|
|
86
|
+
Explore behavior (LLM-powered):
|
|
87
|
+
$ bellwether explore npx @mcp/my-server # Generate AGENTS.md documentation
|
|
88
|
+
|
|
89
|
+
Discover server capabilities:
|
|
90
|
+
$ bellwether discover npx @mcp/server-postgres
|
|
91
|
+
|
|
92
|
+
Search MCP Registry:
|
|
93
|
+
$ bellwether registry filesystem
|
|
94
|
+
|
|
95
|
+
Cloud workflow:
|
|
96
|
+
$ bellwether login # Authenticate with Bellwether Cloud
|
|
97
|
+
$ bellwether teams # List your teams
|
|
98
|
+
$ bellwether link my-project # Link to cloud project
|
|
99
|
+
$ bellwether upload # Upload baseline
|
|
100
|
+
$ bellwether history # View version history
|
|
101
|
+
|
|
102
|
+
Documentation: https://docs.bellwether.sh
|
|
103
|
+
`;
|
|
104
|
+
program
|
|
105
|
+
.name('bellwether')
|
|
106
|
+
.description(`${banner}
|
|
107
|
+
Check MCP servers for drift. Explore behavior. Generate documentation.
|
|
108
|
+
|
|
109
|
+
Commands:
|
|
110
|
+
check - Schema validation and drift detection (free, fast, deterministic)
|
|
111
|
+
explore - LLM-powered behavioral exploration and documentation
|
|
112
|
+
|
|
113
|
+
For more information on a specific command, use:
|
|
114
|
+
bellwether <command> --help`)
|
|
115
|
+
.version(VERSION)
|
|
116
|
+
.option('--log-level <level>', 'Log level: debug, info, warn, error, silent')
|
|
117
|
+
.option('--log-file <path>', 'Write logs to file instead of stderr')
|
|
118
|
+
.hook('preAction', (thisCommand, actionCommand) => {
|
|
119
|
+
const activeCommand = actionCommand ?? thisCommand;
|
|
120
|
+
const commandName = activeCommand.name();
|
|
121
|
+
const opts = activeCommand.opts();
|
|
122
|
+
if (commandName !== 'init' && commandName !== 'validate-config') {
|
|
123
|
+
const configPath = opts.config;
|
|
124
|
+
const found = findConfigFile(configPath);
|
|
125
|
+
if (!found) {
|
|
126
|
+
const searchedPaths = configPath
|
|
127
|
+
? [configPath]
|
|
128
|
+
: PATHS.CONFIG_FILENAMES.map((name) => join(process.cwd(), name));
|
|
129
|
+
console.error(new ConfigNotFoundError(searchedPaths).message);
|
|
130
|
+
process.exit(EXIT_CODES.ERROR);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (opts.logLevel || opts.logFile) {
|
|
134
|
+
process.env.BELLWETHER_LOG_OVERRIDE = '1';
|
|
135
|
+
configureLogger({
|
|
136
|
+
level: opts.logLevel,
|
|
137
|
+
file: opts.logFile,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
})
|
|
141
|
+
.addHelpText('after', examples);
|
|
142
|
+
// Add command groups for better organization
|
|
143
|
+
program.addHelpText('beforeAll', '\nCore Commands:');
|
|
144
|
+
// Core commands - check and explore
|
|
145
|
+
program.addCommand(checkCommand.description('Check MCP server schema and detect drift (free, fast, deterministic)'));
|
|
146
|
+
program.addCommand(exploreCommand.description('Explore MCP server behavior with LLM-powered testing'));
|
|
147
|
+
program.addCommand(watchCommand.description('Watch for MCP server changes and auto-check'));
|
|
148
|
+
program.addCommand(discoverCommand.description('Discover MCP server capabilities (tools, prompts, resources)'));
|
|
149
|
+
program.addCommand(initCommand.description('Create a new bellwether.yaml configuration file'));
|
|
150
|
+
program.addCommand(authCommand.description('Manage LLM provider API keys (keychain storage)'));
|
|
151
|
+
program.addCommand(baselineCommand.description('Manage baselines for drift detection (save, compare, show, diff)'));
|
|
152
|
+
program.addCommand(goldenCommand.description('Manage golden outputs for tool validation (save, compare, list, delete)'));
|
|
153
|
+
program.addCommand(registryCommand.description('Search the MCP Registry for servers'));
|
|
154
|
+
program.addCommand(verifyCommand.description('Generate verification report for Verified by Bellwether program'));
|
|
155
|
+
program.addCommand(contractCommand.description('Validate MCP servers against contract definitions (validate, generate, show)'));
|
|
156
|
+
program.addCommand(validateConfigCommand.description('Validate bellwether.yaml configuration (no tests)'));
|
|
157
|
+
// Cloud commands - sync with Bellwether Cloud
|
|
158
|
+
program.addCommand(loginCommand.description('Authenticate with Bellwether Cloud'));
|
|
159
|
+
program.addCommand(teamsCommand.description('Manage team selection for cloud operations'));
|
|
160
|
+
program.addCommand(linkCommand.description('Link local project to Bellwether Cloud project'));
|
|
161
|
+
program.addCommand(projectsCommand.description('List your Bellwether Cloud projects'));
|
|
162
|
+
program.addCommand(uploadCommand.description('Upload baseline to Bellwether Cloud'));
|
|
163
|
+
program.addCommand(historyCommand.description('View baseline version history'));
|
|
164
|
+
program.addCommand(diffCommand.description('Compare two baseline versions'));
|
|
165
|
+
program.addCommand(badgeCommand.description('Get embeddable verification badge for your project'));
|
|
166
|
+
// Custom help formatting
|
|
167
|
+
program.configureHelp({
|
|
168
|
+
sortSubcommands: false, // Keep our custom order
|
|
169
|
+
subcommandTerm: (cmd) => cmd.name() + ' ' + cmd.usage(),
|
|
170
|
+
});
|
|
171
|
+
// Load keychain credentials, then parse commands
|
|
172
|
+
loadKeychainCredentials().then(() => {
|
|
173
|
+
program.parse();
|
|
174
|
+
}).catch(() => {
|
|
175
|
+
// If keychain loading fails, still parse commands
|
|
176
|
+
program.parse();
|
|
177
|
+
});
|
|
178
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interactive mode utilities for CLI commands.
|
|
3
|
+
*
|
|
4
|
+
* Provides user prompts for server command, persona selection,
|
|
5
|
+
* output format, and test control.
|
|
6
|
+
*/
|
|
7
|
+
import type { BellwetherConfig } from '../config/loader.js';
|
|
8
|
+
/**
|
|
9
|
+
* Interactive configuration gathered from prompts.
|
|
10
|
+
*/
|
|
11
|
+
export interface InteractiveConfig {
|
|
12
|
+
serverCommand: string;
|
|
13
|
+
serverArgs: string[];
|
|
14
|
+
selectedPersonas: string[];
|
|
15
|
+
outputFormat: 'markdown' | 'json' | 'both';
|
|
16
|
+
outputDir: string;
|
|
17
|
+
saveBaseline: boolean;
|
|
18
|
+
baselinePath?: string;
|
|
19
|
+
compareBaseline?: string;
|
|
20
|
+
maxQuestions?: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Prompt user for interactive configuration.
|
|
24
|
+
*/
|
|
25
|
+
export declare function promptForConfig(existingConfig: BellwetherConfig, providedCommand?: string, providedArgs?: string[]): Promise<InteractiveConfig>;
|
|
26
|
+
/**
|
|
27
|
+
* Pause controller for mid-test pause/resume.
|
|
28
|
+
*/
|
|
29
|
+
export interface PauseController {
|
|
30
|
+
isPaused: boolean;
|
|
31
|
+
pause(): void;
|
|
32
|
+
resume(): void;
|
|
33
|
+
waitIfPaused(): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Create a pause controller for test control.
|
|
37
|
+
*/
|
|
38
|
+
export declare function createPauseController(): PauseController;
|
|
39
|
+
/**
|
|
40
|
+
* Setup keyboard listener for pause/resume during test.
|
|
41
|
+
*/
|
|
42
|
+
export declare function setupInteractiveKeyboard(controller: PauseController): () => void;
|
|
43
|
+
/**
|
|
44
|
+
* Display a summary of the interactive configuration.
|
|
45
|
+
*/
|
|
46
|
+
export declare function displayConfigSummary(config: InteractiveConfig): void;
|
|
47
|
+
//# sourceMappingURL=interactive.d.ts.map
|