@avi770/testteam 2.0.0 → 3.2.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 +188 -3
- package/README.md +111 -20
- package/bin/testteam.js +32 -4
- package/dist/agents/01-analyst.d.ts +2 -2
- package/dist/agents/01-analyst.js +1 -1
- package/dist/agents/02-seed-architect.d.ts +2 -2
- package/dist/agents/02-seed-architect.js +2 -2
- package/dist/agents/03-test-generator.d.ts +2 -2
- package/dist/agents/03-test-generator.js +2 -2
- package/dist/agents/04-unit-runner.d.ts +2 -2
- package/dist/agents/04-unit-runner.d.ts.map +1 -1
- package/dist/agents/04-unit-runner.js +12 -3
- package/dist/agents/04-unit-runner.js.map +1 -1
- package/dist/agents/05-browser-crawler.d.ts +2 -2
- package/dist/agents/05-browser-crawler.d.ts.map +1 -1
- package/dist/agents/05-browser-crawler.js +24 -12
- package/dist/agents/05-browser-crawler.js.map +1 -1
- package/dist/agents/06-api-exerciser.d.ts +2 -2
- package/dist/agents/06-api-exerciser.js +2 -2
- package/dist/agents/07-security-scout.d.ts +2 -2
- package/dist/agents/07-security-scout.js +2 -2
- package/dist/agents/08-a11y-guardian.d.ts +2 -2
- package/dist/agents/08-a11y-guardian.d.ts.map +1 -1
- package/dist/agents/08-a11y-guardian.js +9 -5
- package/dist/agents/08-a11y-guardian.js.map +1 -1
- package/dist/agents/09-healer.d.ts +2 -2
- package/dist/agents/09-healer.js +2 -2
- package/dist/agents/10-reporter.d.ts +2 -2
- package/dist/agents/10-reporter.d.ts.map +1 -1
- package/dist/agents/10-reporter.js +55 -27
- package/dist/agents/10-reporter.js.map +1 -1
- package/dist/agents/100-error-handling-auditor.d.ts +63 -0
- package/dist/agents/100-error-handling-auditor.d.ts.map +1 -0
- package/dist/agents/100-error-handling-auditor.js +334 -0
- package/dist/agents/100-error-handling-auditor.js.map +1 -0
- package/dist/agents/101-rate-limit-auditor.d.ts +72 -0
- package/dist/agents/101-rate-limit-auditor.d.ts.map +1 -0
- package/dist/agents/101-rate-limit-auditor.js +295 -0
- package/dist/agents/101-rate-limit-auditor.js.map +1 -0
- package/dist/agents/102-dockerfile-auditor.d.ts +62 -0
- package/dist/agents/102-dockerfile-auditor.d.ts.map +1 -0
- package/dist/agents/102-dockerfile-auditor.js +337 -0
- package/dist/agents/102-dockerfile-auditor.js.map +1 -0
- package/dist/agents/103-ci-workflow-auditor.d.ts +57 -0
- package/dist/agents/103-ci-workflow-auditor.d.ts.map +1 -0
- package/dist/agents/103-ci-workflow-auditor.js +247 -0
- package/dist/agents/103-ci-workflow-auditor.js.map +1 -0
- package/dist/agents/104-n-plus-one-detector.d.ts +57 -0
- package/dist/agents/104-n-plus-one-detector.d.ts.map +1 -0
- package/dist/agents/104-n-plus-one-detector.js +329 -0
- package/dist/agents/104-n-plus-one-detector.js.map +1 -0
- package/dist/agents/105-unbounded-query-auditor.d.ts +50 -0
- package/dist/agents/105-unbounded-query-auditor.d.ts.map +1 -0
- package/dist/agents/105-unbounded-query-auditor.js +284 -0
- package/dist/agents/105-unbounded-query-auditor.js.map +1 -0
- package/dist/agents/106-hardcoded-config-auditor.d.ts +54 -0
- package/dist/agents/106-hardcoded-config-auditor.d.ts.map +1 -0
- package/dist/agents/106-hardcoded-config-auditor.js +251 -0
- package/dist/agents/106-hardcoded-config-auditor.js.map +1 -0
- package/dist/agents/107-open-redirect-detector.d.ts +52 -0
- package/dist/agents/107-open-redirect-detector.d.ts.map +1 -0
- package/dist/agents/107-open-redirect-detector.js +263 -0
- package/dist/agents/107-open-redirect-detector.js.map +1 -0
- package/dist/agents/108-sql-injection-detector.d.ts +51 -0
- package/dist/agents/108-sql-injection-detector.d.ts.map +1 -0
- package/dist/agents/108-sql-injection-detector.js +323 -0
- package/dist/agents/108-sql-injection-detector.js.map +1 -0
- package/dist/agents/109-path-traversal-detector.d.ts +51 -0
- package/dist/agents/109-path-traversal-detector.d.ts.map +1 -0
- package/dist/agents/109-path-traversal-detector.js +244 -0
- package/dist/agents/109-path-traversal-detector.js.map +1 -0
- package/dist/agents/11-fixer.d.ts +4 -2
- package/dist/agents/11-fixer.d.ts.map +1 -1
- package/dist/agents/11-fixer.js +52 -11
- package/dist/agents/11-fixer.js.map +1 -1
- package/dist/agents/110-mass-assignment-detector.d.ts +52 -0
- package/dist/agents/110-mass-assignment-detector.d.ts.map +1 -0
- package/dist/agents/110-mass-assignment-detector.js +199 -0
- package/dist/agents/110-mass-assignment-detector.js.map +1 -0
- package/dist/agents/111-dynamic-eval-detector.d.ts +46 -0
- package/dist/agents/111-dynamic-eval-detector.d.ts.map +1 -0
- package/dist/agents/111-dynamic-eval-detector.js +233 -0
- package/dist/agents/111-dynamic-eval-detector.js.map +1 -0
- package/dist/agents/112-taint-tracker.d.ts +226 -0
- package/dist/agents/112-taint-tracker.d.ts.map +1 -0
- package/dist/agents/112-taint-tracker.js +1273 -0
- package/dist/agents/112-taint-tracker.js.map +1 -0
- package/dist/agents/113-response-contract-auditor.d.ts +92 -0
- package/dist/agents/113-response-contract-auditor.d.ts.map +1 -0
- package/dist/agents/113-response-contract-auditor.js +694 -0
- package/dist/agents/113-response-contract-auditor.js.map +1 -0
- package/dist/agents/114-static-a11y-auditor.d.ts +66 -0
- package/dist/agents/114-static-a11y-auditor.d.ts.map +1 -0
- package/dist/agents/114-static-a11y-auditor.js +377 -0
- package/dist/agents/114-static-a11y-auditor.js.map +1 -0
- package/dist/agents/115-multihop-taint-tracker.d.ts +84 -0
- package/dist/agents/115-multihop-taint-tracker.d.ts.map +1 -0
- package/dist/agents/115-multihop-taint-tracker.js +340 -0
- package/dist/agents/115-multihop-taint-tracker.js.map +1 -0
- package/dist/agents/116-runtime-contract-capture.d.ts +79 -0
- package/dist/agents/116-runtime-contract-capture.d.ts.map +1 -0
- package/dist/agents/116-runtime-contract-capture.js +274 -0
- package/dist/agents/116-runtime-contract-capture.js.map +1 -0
- package/dist/agents/117-aria-rule-engine.d.ts +52 -0
- package/dist/agents/117-aria-rule-engine.d.ts.map +1 -0
- package/dist/agents/117-aria-rule-engine.js +415 -0
- package/dist/agents/117-aria-rule-engine.js.map +1 -0
- package/dist/agents/118-insecure-crypto-auditor.d.ts +48 -0
- package/dist/agents/118-insecure-crypto-auditor.d.ts.map +1 -0
- package/dist/agents/118-insecure-crypto-auditor.js +232 -0
- package/dist/agents/118-insecure-crypto-auditor.js.map +1 -0
- package/dist/agents/119-secrets-scanner.d.ts +44 -0
- package/dist/agents/119-secrets-scanner.d.ts.map +1 -0
- package/dist/agents/119-secrets-scanner.js +242 -0
- package/dist/agents/119-secrets-scanner.js.map +1 -0
- package/dist/agents/12-ux-inspector.d.ts +2 -2
- package/dist/agents/12-ux-inspector.d.ts.map +1 -1
- package/dist/agents/12-ux-inspector.js +8 -4
- package/dist/agents/12-ux-inspector.js.map +1 -1
- package/dist/agents/120-async-safety-auditor.d.ts +48 -0
- package/dist/agents/120-async-safety-auditor.d.ts.map +1 -0
- package/dist/agents/120-async-safety-auditor.js +250 -0
- package/dist/agents/120-async-safety-auditor.js.map +1 -0
- package/dist/agents/13-performance-profiler.d.ts +2 -2
- package/dist/agents/13-performance-profiler.d.ts.map +1 -1
- package/dist/agents/13-performance-profiler.js +5 -4
- package/dist/agents/13-performance-profiler.js.map +1 -1
- package/dist/agents/14-data-integrity-auditor.d.ts +2 -2
- package/dist/agents/14-data-integrity-auditor.js +4 -4
- package/dist/agents/14-data-integrity-auditor.js.map +1 -1
- package/dist/agents/15-regression-sentinel.d.ts +6 -4
- package/dist/agents/15-regression-sentinel.d.ts.map +1 -1
- package/dist/agents/15-regression-sentinel.js +5 -4
- package/dist/agents/15-regression-sentinel.js.map +1 -1
- package/dist/agents/16-chaos-agent.d.ts +2 -2
- package/dist/agents/16-chaos-agent.d.ts.map +1 -1
- package/dist/agents/16-chaos-agent.js +11 -4
- package/dist/agents/16-chaos-agent.js.map +1 -1
- package/dist/agents/17-documentation-validator.d.ts +2 -2
- package/dist/agents/17-documentation-validator.d.ts.map +1 -1
- package/dist/agents/17-documentation-validator.js +5 -2
- package/dist/agents/17-documentation-validator.js.map +1 -1
- package/dist/agents/18-integration-watchdog.d.ts +2 -2
- package/dist/agents/18-integration-watchdog.d.ts.map +1 -1
- package/dist/agents/18-integration-watchdog.js +5 -2
- package/dist/agents/18-integration-watchdog.js.map +1 -1
- package/dist/agents/19-tenant-isolation-auditor.d.ts +2 -2
- package/dist/agents/19-tenant-isolation-auditor.js +4 -4
- package/dist/agents/19-tenant-isolation-auditor.js.map +1 -1
- package/dist/agents/20-workflow-completion-tester.d.ts +2 -2
- package/dist/agents/20-workflow-completion-tester.d.ts.map +1 -1
- package/dist/agents/20-workflow-completion-tester.js +10 -6
- package/dist/agents/20-workflow-completion-tester.js.map +1 -1
- package/dist/agents/21-state-session-tester.d.ts +2 -2
- package/dist/agents/21-state-session-tester.d.ts.map +1 -1
- package/dist/agents/21-state-session-tester.js +15 -5
- package/dist/agents/21-state-session-tester.js.map +1 -1
- package/dist/agents/22-email-notification-verifier.d.ts +2 -2
- package/dist/agents/22-email-notification-verifier.js +2 -2
- package/dist/agents/23-migration-tester.d.ts +2 -2
- package/dist/agents/23-migration-tester.js +1 -1
- package/dist/agents/24-signup-onboarding-tester.d.ts +2 -2
- package/dist/agents/24-signup-onboarding-tester.d.ts.map +1 -1
- package/dist/agents/24-signup-onboarding-tester.js +13 -10
- package/dist/agents/24-signup-onboarding-tester.js.map +1 -1
- package/dist/agents/25-crud-flow-tester.d.ts +2 -2
- package/dist/agents/25-crud-flow-tester.d.ts.map +1 -1
- package/dist/agents/25-crud-flow-tester.js +12 -6
- package/dist/agents/25-crud-flow-tester.js.map +1 -1
- package/dist/agents/26-form-validator.d.ts +2 -2
- package/dist/agents/26-form-validator.d.ts.map +1 -1
- package/dist/agents/26-form-validator.js +12 -6
- package/dist/agents/26-form-validator.js.map +1 -1
- package/dist/agents/27-search-filter-tester.d.ts +2 -2
- package/dist/agents/27-search-filter-tester.d.ts.map +1 -1
- package/dist/agents/27-search-filter-tester.js +12 -6
- package/dist/agents/27-search-filter-tester.js.map +1 -1
- package/dist/agents/28-navigation-routing-tester.d.ts +2 -2
- package/dist/agents/28-navigation-routing-tester.d.ts.map +1 -1
- package/dist/agents/28-navigation-routing-tester.js +12 -6
- package/dist/agents/28-navigation-routing-tester.js.map +1 -1
- package/dist/agents/29-responsive-interaction-tester.d.ts +2 -2
- package/dist/agents/29-responsive-interaction-tester.d.ts.map +1 -1
- package/dist/agents/29-responsive-interaction-tester.js +12 -6
- package/dist/agents/29-responsive-interaction-tester.js.map +1 -1
- package/dist/agents/30-multi-user-scenario-tester.d.ts +2 -2
- package/dist/agents/30-multi-user-scenario-tester.d.ts.map +1 -1
- package/dist/agents/30-multi-user-scenario-tester.js +20 -13
- package/dist/agents/30-multi-user-scenario-tester.js.map +1 -1
- package/dist/agents/31-load-tester.d.ts +2 -2
- package/dist/agents/31-load-tester.js +2 -2
- package/dist/agents/32-memory-leak-detector.d.ts +2 -2
- package/dist/agents/32-memory-leak-detector.d.ts.map +1 -1
- package/dist/agents/32-memory-leak-detector.js +5 -4
- package/dist/agents/32-memory-leak-detector.js.map +1 -1
- package/dist/agents/33-bundle-analyzer.d.ts +2 -2
- package/dist/agents/33-bundle-analyzer.js +1 -1
- package/dist/agents/34-xss-scanner.d.ts +2 -2
- package/dist/agents/34-xss-scanner.d.ts.map +1 -1
- package/dist/agents/34-xss-scanner.js +12 -6
- package/dist/agents/34-xss-scanner.js.map +1 -1
- package/dist/agents/35-csrf-tester.d.ts +2 -2
- package/dist/agents/35-csrf-tester.js +2 -2
- package/dist/agents/36-auth-fuzzer.d.ts +2 -2
- package/dist/agents/36-auth-fuzzer.js +2 -2
- package/dist/agents/37-dependency-scanner.d.ts +2 -2
- package/dist/agents/37-dependency-scanner.js +1 -1
- package/dist/agents/38-secrets-scanner.d.ts +2 -2
- package/dist/agents/38-secrets-scanner.d.ts.map +1 -1
- package/dist/agents/38-secrets-scanner.js +39 -4
- package/dist/agents/38-secrets-scanner.js.map +1 -1
- package/dist/agents/39-api-contract-tester.d.ts +2 -2
- package/dist/agents/39-api-contract-tester.js +2 -2
- package/dist/agents/40-rate-limit-tester.d.ts +2 -2
- package/dist/agents/40-rate-limit-tester.js +2 -2
- package/dist/agents/41-api-pagination-tester.d.ts +2 -2
- package/dist/agents/41-api-pagination-tester.js +2 -2
- package/dist/agents/42-graphql-tester.d.ts +2 -2
- package/dist/agents/42-graphql-tester.js +2 -2
- package/dist/agents/43-data-consistency-checker.d.ts +2 -2
- package/dist/agents/43-data-consistency-checker.js +3 -3
- package/dist/agents/44-backup-recovery-tester.d.ts +2 -2
- package/dist/agents/44-backup-recovery-tester.js +1 -1
- package/dist/agents/45-data-privacy-scanner.d.ts +2 -2
- package/dist/agents/45-data-privacy-scanner.js +3 -3
- package/dist/agents/46-seo-auditor.d.ts +2 -2
- package/dist/agents/46-seo-auditor.d.ts.map +1 -1
- package/dist/agents/46-seo-auditor.js +12 -6
- package/dist/agents/46-seo-auditor.js.map +1 -1
- package/dist/agents/47-social-preview-tester.d.ts +2 -2
- package/dist/agents/47-social-preview-tester.d.ts.map +1 -1
- package/dist/agents/47-social-preview-tester.js +12 -6
- package/dist/agents/47-social-preview-tester.js.map +1 -1
- package/dist/agents/48-lighthouse-auditor.d.ts +2 -2
- package/dist/agents/48-lighthouse-auditor.d.ts.map +1 -1
- package/dist/agents/48-lighthouse-auditor.js +5 -4
- package/dist/agents/48-lighthouse-auditor.js.map +1 -1
- package/dist/agents/49-i18n-tester.d.ts +2 -2
- package/dist/agents/49-i18n-tester.d.ts.map +1 -1
- package/dist/agents/49-i18n-tester.js +12 -6
- package/dist/agents/49-i18n-tester.js.map +1 -1
- package/dist/agents/50-timezone-tester.d.ts +2 -2
- package/dist/agents/50-timezone-tester.d.ts.map +1 -1
- package/dist/agents/50-timezone-tester.js +40 -33
- package/dist/agents/50-timezone-tester.js.map +1 -1
- package/dist/agents/51-error-recovery-tester.d.ts +2 -2
- package/dist/agents/51-error-recovery-tester.d.ts.map +1 -1
- package/dist/agents/51-error-recovery-tester.js +12 -7
- package/dist/agents/51-error-recovery-tester.js.map +1 -1
- package/dist/agents/52-offline-mode-tester.d.ts +2 -2
- package/dist/agents/52-offline-mode-tester.d.ts.map +1 -1
- package/dist/agents/52-offline-mode-tester.js +12 -7
- package/dist/agents/52-offline-mode-tester.js.map +1 -1
- package/dist/agents/53-graceful-degradation-tester.d.ts +2 -2
- package/dist/agents/53-graceful-degradation-tester.d.ts.map +1 -1
- package/dist/agents/53-graceful-degradation-tester.js +10 -3
- package/dist/agents/53-graceful-degradation-tester.js.map +1 -1
- package/dist/agents/54-websocket-tester.d.ts +2 -2
- package/dist/agents/54-websocket-tester.d.ts.map +1 -1
- package/dist/agents/54-websocket-tester.js +12 -6
- package/dist/agents/54-websocket-tester.js.map +1 -1
- package/dist/agents/55-realtime-sync-tester.d.ts +2 -2
- package/dist/agents/55-realtime-sync-tester.d.ts.map +1 -1
- package/dist/agents/55-realtime-sync-tester.js +101 -96
- package/dist/agents/55-realtime-sync-tester.js.map +1 -1
- package/dist/agents/56-file-upload-tester.d.ts +2 -2
- package/dist/agents/56-file-upload-tester.d.ts.map +1 -1
- package/dist/agents/56-file-upload-tester.js +17 -13
- package/dist/agents/56-file-upload-tester.js.map +1 -1
- package/dist/agents/57-export-tester.d.ts +2 -2
- package/dist/agents/57-export-tester.d.ts.map +1 -1
- package/dist/agents/57-export-tester.js +8 -4
- package/dist/agents/57-export-tester.js.map +1 -1
- package/dist/agents/58-payment-flow-tester.d.ts +2 -2
- package/dist/agents/58-payment-flow-tester.d.ts.map +1 -1
- package/dist/agents/58-payment-flow-tester.js +8 -4
- package/dist/agents/58-payment-flow-tester.js.map +1 -1
- package/dist/agents/59-ssl-tls-auditor.d.ts +2 -2
- package/dist/agents/59-ssl-tls-auditor.js +2 -2
- package/dist/agents/60-dns-cdn-tester.d.ts +2 -2
- package/dist/agents/60-dns-cdn-tester.js +2 -2
- package/dist/agents/61-docker-health-checker.d.ts +2 -2
- package/dist/agents/61-docker-health-checker.js +1 -1
- package/dist/agents/62-env-config-validator.d.ts +2 -2
- package/dist/agents/62-env-config-validator.js +1 -1
- package/dist/agents/63-log-quality-auditor.d.ts +2 -2
- package/dist/agents/63-log-quality-auditor.js +1 -1
- package/dist/agents/64-analytics-tracker-tester.d.ts +2 -2
- package/dist/agents/64-analytics-tracker-tester.d.ts.map +1 -1
- package/dist/agents/64-analytics-tracker-tester.js +8 -4
- package/dist/agents/64-analytics-tracker-tester.js.map +1 -1
- package/dist/agents/65-gdpr-compliance-tester.d.ts +2 -2
- package/dist/agents/65-gdpr-compliance-tester.d.ts.map +1 -1
- package/dist/agents/65-gdpr-compliance-tester.js +55 -40
- package/dist/agents/65-gdpr-compliance-tester.js.map +1 -1
- package/dist/agents/66-soc2-control-validator.d.ts +2 -2
- package/dist/agents/66-soc2-control-validator.d.ts.map +1 -1
- package/dist/agents/66-soc2-control-validator.js +29 -21
- package/dist/agents/66-soc2-control-validator.js.map +1 -1
- package/dist/agents/67-wcag-aaa-tester.d.ts +2 -2
- package/dist/agents/67-wcag-aaa-tester.d.ts.map +1 -1
- package/dist/agents/67-wcag-aaa-tester.js +12 -6
- package/dist/agents/67-wcag-aaa-tester.js.map +1 -1
- package/dist/agents/68-dead-code-detector.d.ts +2 -2
- package/dist/agents/68-dead-code-detector.d.ts.map +1 -1
- package/dist/agents/68-dead-code-detector.js +6 -3
- package/dist/agents/68-dead-code-detector.js.map +1 -1
- package/dist/agents/69-type-safety-auditor.d.ts +2 -2
- package/dist/agents/69-type-safety-auditor.js +1 -1
- package/dist/agents/70-complexity-analyzer.d.ts +2 -2
- package/dist/agents/70-complexity-analyzer.js +1 -1
- package/dist/agents/71-unit-testing-agent.d.ts +15 -0
- package/dist/agents/71-unit-testing-agent.d.ts.map +1 -0
- package/dist/agents/71-unit-testing-agent.js +220 -0
- package/dist/agents/71-unit-testing-agent.js.map +1 -0
- package/dist/agents/72-integration-testing-agent.d.ts +13 -0
- package/dist/agents/72-integration-testing-agent.d.ts.map +1 -0
- package/dist/agents/72-integration-testing-agent.js +243 -0
- package/dist/agents/72-integration-testing-agent.js.map +1 -0
- package/dist/agents/73-system-testing-agent.d.ts +11 -0
- package/dist/agents/73-system-testing-agent.d.ts.map +1 -0
- package/dist/agents/73-system-testing-agent.js +175 -0
- package/dist/agents/73-system-testing-agent.js.map +1 -0
- package/dist/agents/74-acceptance-testing-agent.d.ts +13 -0
- package/dist/agents/74-acceptance-testing-agent.d.ts.map +1 -0
- package/dist/agents/74-acceptance-testing-agent.js +254 -0
- package/dist/agents/74-acceptance-testing-agent.js.map +1 -0
- package/dist/agents/75-sanity-testing-agent.d.ts +15 -0
- package/dist/agents/75-sanity-testing-agent.d.ts.map +1 -0
- package/dist/agents/75-sanity-testing-agent.js +240 -0
- package/dist/agents/75-sanity-testing-agent.js.map +1 -0
- package/dist/agents/76-regression-testing-agent.d.ts +14 -0
- package/dist/agents/76-regression-testing-agent.d.ts.map +1 -0
- package/dist/agents/76-regression-testing-agent.js +230 -0
- package/dist/agents/76-regression-testing-agent.js.map +1 -0
- package/dist/agents/77-browser-load-testing-agent.d.ts +11 -0
- package/dist/agents/77-browser-load-testing-agent.d.ts.map +1 -0
- package/dist/agents/77-browser-load-testing-agent.js +128 -0
- package/dist/agents/77-browser-load-testing-agent.js.map +1 -0
- package/dist/agents/78-stress-testing-agent.d.ts +11 -0
- package/dist/agents/78-stress-testing-agent.d.ts.map +1 -0
- package/dist/agents/78-stress-testing-agent.js +146 -0
- package/dist/agents/78-stress-testing-agent.js.map +1 -0
- package/dist/agents/79-endurance-testing-agent.d.ts +12 -0
- package/dist/agents/79-endurance-testing-agent.d.ts.map +1 -0
- package/dist/agents/79-endurance-testing-agent.js +165 -0
- package/dist/agents/79-endurance-testing-agent.js.map +1 -0
- package/dist/agents/80-usability-testing-agent.d.ts +11 -0
- package/dist/agents/80-usability-testing-agent.d.ts.map +1 -0
- package/dist/agents/80-usability-testing-agent.js +196 -0
- package/dist/agents/80-usability-testing-agent.js.map +1 -0
- package/dist/agents/81-compatibility-testing-agent.d.ts +11 -0
- package/dist/agents/81-compatibility-testing-agent.d.ts.map +1 -0
- package/dist/agents/81-compatibility-testing-agent.js +224 -0
- package/dist/agents/81-compatibility-testing-agent.js.map +1 -0
- package/dist/agents/82-exploratory-testing-agent.d.ts +14 -0
- package/dist/agents/82-exploratory-testing-agent.d.ts.map +1 -0
- package/dist/agents/82-exploratory-testing-agent.js +345 -0
- package/dist/agents/82-exploratory-testing-agent.js.map +1 -0
- package/dist/agents/83-static-analysis-agent.d.ts +14 -0
- package/dist/agents/83-static-analysis-agent.d.ts.map +1 -0
- package/dist/agents/83-static-analysis-agent.js +261 -0
- package/dist/agents/83-static-analysis-agent.js.map +1 -0
- package/dist/agents/84-governance-testing-agent.d.ts +28 -0
- package/dist/agents/84-governance-testing-agent.d.ts.map +1 -0
- package/dist/agents/84-governance-testing-agent.js +591 -0
- package/dist/agents/84-governance-testing-agent.js.map +1 -0
- package/dist/agents/85-stagehand-agent.d.ts +22 -0
- package/dist/agents/85-stagehand-agent.d.ts.map +1 -0
- package/dist/agents/85-stagehand-agent.js +81 -0
- package/dist/agents/85-stagehand-agent.js.map +1 -0
- package/dist/agents/86-browser-use-agent.d.ts +31 -0
- package/dist/agents/86-browser-use-agent.d.ts.map +1 -0
- package/dist/agents/86-browser-use-agent.js +121 -0
- package/dist/agents/86-browser-use-agent.js.map +1 -0
- package/dist/agents/87-connection-mapper.d.ts +93 -0
- package/dist/agents/87-connection-mapper.d.ts.map +1 -0
- package/dist/agents/87-connection-mapper.js +658 -0
- package/dist/agents/87-connection-mapper.js.map +1 -0
- package/dist/agents/88-localhost-walkthrough.d.ts +272 -0
- package/dist/agents/88-localhost-walkthrough.d.ts.map +1 -0
- package/dist/agents/88-localhost-walkthrough.js +1203 -0
- package/dist/agents/88-localhost-walkthrough.js.map +1 -0
- package/dist/agents/89-repair-retest.d.ts +63 -0
- package/dist/agents/89-repair-retest.d.ts.map +1 -0
- package/dist/agents/89-repair-retest.js +227 -0
- package/dist/agents/89-repair-retest.js.map +1 -0
- package/dist/agents/90-response-shape-validator.d.ts +35 -0
- package/dist/agents/90-response-shape-validator.d.ts.map +1 -0
- package/dist/agents/90-response-shape-validator.js +156 -0
- package/dist/agents/90-response-shape-validator.js.map +1 -0
- package/dist/agents/91-boundary-fuzzer.d.ts +99 -0
- package/dist/agents/91-boundary-fuzzer.d.ts.map +1 -0
- package/dist/agents/91-boundary-fuzzer.js +0 -0
- package/dist/agents/91-boundary-fuzzer.js.map +1 -0
- package/dist/agents/92-repair-simulator.d.ts +89 -0
- package/dist/agents/92-repair-simulator.d.ts.map +1 -0
- package/dist/agents/92-repair-simulator.js +401 -0
- package/dist/agents/92-repair-simulator.js.map +1 -0
- package/dist/agents/93-env-var-auditor.d.ts +64 -0
- package/dist/agents/93-env-var-auditor.d.ts.map +1 -0
- package/dist/agents/93-env-var-auditor.js +435 -0
- package/dist/agents/93-env-var-auditor.js.map +1 -0
- package/dist/agents/94-schema-validator.d.ts +148 -0
- package/dist/agents/94-schema-validator.d.ts.map +1 -0
- package/dist/agents/94-schema-validator.js +567 -0
- package/dist/agents/94-schema-validator.js.map +1 -0
- package/dist/agents/95-contract-drift.d.ts +87 -0
- package/dist/agents/95-contract-drift.d.ts.map +1 -0
- package/dist/agents/95-contract-drift.js +335 -0
- package/dist/agents/95-contract-drift.js.map +1 -0
- package/dist/agents/96-cookie-security-auditor.d.ts +86 -0
- package/dist/agents/96-cookie-security-auditor.d.ts.map +1 -0
- package/dist/agents/96-cookie-security-auditor.js +339 -0
- package/dist/agents/96-cookie-security-auditor.js.map +1 -0
- package/dist/agents/97-healthcheck-validator.d.ts +62 -0
- package/dist/agents/97-healthcheck-validator.d.ts.map +1 -0
- package/dist/agents/97-healthcheck-validator.js +204 -0
- package/dist/agents/97-healthcheck-validator.js.map +1 -0
- package/dist/agents/98-cors-csp-auditor.d.ts +70 -0
- package/dist/agents/98-cors-csp-auditor.d.ts.map +1 -0
- package/dist/agents/98-cors-csp-auditor.js +308 -0
- package/dist/agents/98-cors-csp-auditor.js.map +1 -0
- package/dist/agents/99-logging-hygiene-auditor.d.ts +67 -0
- package/dist/agents/99-logging-hygiene-auditor.d.ts.map +1 -0
- package/dist/agents/99-logging-hygiene-auditor.js +325 -0
- package/dist/agents/99-logging-hygiene-auditor.js.map +1 -0
- package/dist/agents/base-agent.d.ts +75 -3
- package/dist/agents/base-agent.d.ts.map +1 -1
- package/dist/agents/base-agent.js +112 -1
- package/dist/agents/base-agent.js.map +1 -1
- package/dist/agents/browser-use-client.d.ts +68 -0
- package/dist/agents/browser-use-client.d.ts.map +1 -0
- package/dist/agents/browser-use-client.js +92 -0
- package/dist/agents/browser-use-client.js.map +1 -0
- package/dist/agents/lib/source-scan.d.ts +53 -0
- package/dist/agents/lib/source-scan.d.ts.map +1 -0
- package/dist/agents/lib/source-scan.js +279 -0
- package/dist/agents/lib/source-scan.js.map +1 -0
- package/dist/agents/registry.d.ts +27 -8
- package/dist/agents/registry.d.ts.map +1 -1
- package/dist/agents/registry.js +365 -151
- package/dist/agents/registry.js.map +1 -1
- package/dist/agents/stagehand-runner.d.ts +104 -0
- package/dist/agents/stagehand-runner.d.ts.map +1 -0
- package/dist/agents/stagehand-runner.js +153 -0
- package/dist/agents/stagehand-runner.js.map +1 -0
- package/dist/bridge/agent-registry.d.ts +21 -0
- package/dist/bridge/agent-registry.d.ts.map +1 -0
- package/dist/bridge/agent-registry.js +224 -0
- package/dist/bridge/agent-registry.js.map +1 -0
- package/dist/bridge/api-contract-reader.d.ts +55 -0
- package/dist/bridge/api-contract-reader.d.ts.map +1 -0
- package/dist/bridge/api-contract-reader.js +103 -0
- package/dist/bridge/api-contract-reader.js.map +1 -0
- package/dist/bridge/compliance-reader.d.ts +47 -0
- package/dist/bridge/compliance-reader.d.ts.map +1 -0
- package/dist/bridge/compliance-reader.js +91 -0
- package/dist/bridge/compliance-reader.js.map +1 -0
- package/dist/bridge/data-integrity-reader.d.ts +77 -0
- package/dist/bridge/data-integrity-reader.d.ts.map +1 -0
- package/dist/bridge/data-integrity-reader.js +110 -0
- package/dist/bridge/data-integrity-reader.js.map +1 -0
- package/dist/bridge/design-reader.d.ts +51 -0
- package/dist/bridge/design-reader.d.ts.map +1 -0
- package/dist/bridge/design-reader.js +105 -0
- package/dist/bridge/design-reader.js.map +1 -0
- package/dist/bridge/file-scanner.d.ts +21 -0
- package/dist/bridge/file-scanner.d.ts.map +1 -0
- package/dist/bridge/file-scanner.js +117 -0
- package/dist/bridge/file-scanner.js.map +1 -0
- package/dist/bridge/finding-normalize.d.ts +24 -0
- package/dist/bridge/finding-normalize.d.ts.map +1 -0
- package/dist/bridge/finding-normalize.js +46 -0
- package/dist/bridge/finding-normalize.js.map +1 -0
- package/dist/bridge/http-client.d.ts +44 -0
- package/dist/bridge/http-client.d.ts.map +1 -0
- package/dist/bridge/http-client.js +130 -0
- package/dist/bridge/http-client.js.map +1 -0
- package/dist/bridge/knowledge-reader.d.ts +10 -0
- package/dist/bridge/knowledge-reader.d.ts.map +1 -0
- package/dist/bridge/knowledge-reader.js +46 -0
- package/dist/bridge/knowledge-reader.js.map +1 -0
- package/dist/bridge/loop-engine-reader.d.ts +77 -0
- package/dist/bridge/loop-engine-reader.d.ts.map +1 -0
- package/dist/bridge/loop-engine-reader.js +73 -0
- package/dist/bridge/loop-engine-reader.js.map +1 -0
- package/dist/bridge/playwright-pool.d.ts +33 -0
- package/dist/bridge/playwright-pool.d.ts.map +1 -0
- package/dist/bridge/playwright-pool.js +89 -0
- package/dist/bridge/playwright-pool.js.map +1 -0
- package/dist/bridge/rate-limiter.d.ts +40 -0
- package/dist/bridge/rate-limiter.d.ts.map +1 -0
- package/dist/bridge/rate-limiter.js +33 -0
- package/dist/bridge/rate-limiter.js.map +1 -0
- package/dist/bridge/reliability-reader.d.ts +67 -0
- package/dist/bridge/reliability-reader.d.ts.map +1 -0
- package/dist/bridge/reliability-reader.js +146 -0
- package/dist/bridge/reliability-reader.js.map +1 -0
- package/dist/bridge/router.d.ts +26 -0
- package/dist/bridge/router.d.ts.map +1 -0
- package/dist/bridge/router.js +137 -0
- package/dist/bridge/router.js.map +1 -0
- package/dist/bridge/run-stream.d.ts +47 -0
- package/dist/bridge/run-stream.d.ts.map +1 -0
- package/dist/bridge/run-stream.js +67 -0
- package/dist/bridge/run-stream.js.map +1 -0
- package/dist/bridge/runs-reader.d.ts +41 -0
- package/dist/bridge/runs-reader.d.ts.map +1 -0
- package/dist/bridge/runs-reader.js +185 -0
- package/dist/bridge/runs-reader.js.map +1 -0
- package/dist/bridge/sentinel-reader.d.ts +55 -0
- package/dist/bridge/sentinel-reader.d.ts.map +1 -0
- package/dist/bridge/sentinel-reader.js +88 -0
- package/dist/bridge/sentinel-reader.js.map +1 -0
- package/dist/bridge/server.d.ts +83 -0
- package/dist/bridge/server.d.ts.map +1 -0
- package/dist/bridge/server.js +1103 -0
- package/dist/bridge/server.js.map +1 -0
- package/dist/bridge/shell-executor.d.ts +49 -0
- package/dist/bridge/shell-executor.d.ts.map +1 -0
- package/dist/bridge/shell-executor.js +181 -0
- package/dist/bridge/shell-executor.js.map +1 -0
- package/dist/bridge/tech-debt-reader.d.ts +57 -0
- package/dist/bridge/tech-debt-reader.d.ts.map +1 -0
- package/dist/bridge/tech-debt-reader.js +119 -0
- package/dist/bridge/tech-debt-reader.js.map +1 -0
- package/dist/bridge/types.d.ts +63 -0
- package/dist/bridge/types.d.ts.map +1 -0
- package/dist/bridge/types.js +7 -0
- package/dist/bridge/types.js.map +1 -0
- package/dist/clients/agent-mvp.d.ts +68 -0
- package/dist/clients/agent-mvp.d.ts.map +1 -0
- package/dist/clients/agent-mvp.js +102 -0
- package/dist/clients/agent-mvp.js.map +1 -0
- package/dist/clients/llm-council.d.ts +47 -0
- package/dist/clients/llm-council.d.ts.map +1 -0
- package/dist/clients/llm-council.js +52 -0
- package/dist/clients/llm-council.js.map +1 -0
- package/dist/clients/total-recall.d.ts +37 -0
- package/dist/clients/total-recall.d.ts.map +1 -0
- package/dist/clients/total-recall.js +239 -0
- package/dist/clients/total-recall.js.map +1 -0
- package/dist/core/agent-contract.d.ts +21 -0
- package/dist/core/agent-contract.d.ts.map +1 -0
- package/dist/core/agent-contract.js +18 -0
- package/dist/core/agent-contract.js.map +1 -0
- package/dist/core/api-contract/api-contract-validator.d.ts +178 -0
- package/dist/core/api-contract/api-contract-validator.d.ts.map +1 -0
- package/dist/core/api-contract/api-contract-validator.js +796 -0
- package/dist/core/api-contract/api-contract-validator.js.map +1 -0
- package/dist/core/api-contract/index.d.ts +16 -0
- package/dist/core/api-contract/index.d.ts.map +1 -0
- package/dist/core/api-contract/index.js +24 -0
- package/dist/core/api-contract/index.js.map +1 -0
- package/dist/core/api-contract/types.d.ts +235 -0
- package/dist/core/api-contract/types.d.ts.map +1 -0
- package/dist/core/api-contract/types.js +27 -0
- package/dist/core/api-contract/types.js.map +1 -0
- package/dist/core/blackboard/blackboard.d.ts +34 -0
- package/dist/core/blackboard/blackboard.d.ts.map +1 -0
- package/dist/core/blackboard/blackboard.js +133 -0
- package/dist/core/blackboard/blackboard.js.map +1 -0
- package/dist/core/blackboard/coordination.d.ts +27 -0
- package/dist/core/blackboard/coordination.d.ts.map +1 -0
- package/dist/core/blackboard/coordination.js +31 -0
- package/dist/core/blackboard/coordination.js.map +1 -0
- package/dist/core/blackboard/direct-channel.d.ts +26 -0
- package/dist/core/blackboard/direct-channel.d.ts.map +1 -0
- package/dist/core/blackboard/direct-channel.js +26 -0
- package/dist/core/blackboard/direct-channel.js.map +1 -0
- package/dist/core/blackboard/index.d.ts +10 -0
- package/dist/core/blackboard/index.d.ts.map +1 -0
- package/dist/core/blackboard/index.js +4 -0
- package/dist/core/blackboard/index.js.map +1 -0
- package/dist/core/blackboard/types.d.ts +36 -0
- package/dist/core/blackboard/types.d.ts.map +1 -0
- package/dist/core/blackboard/types.js +2 -0
- package/dist/core/blackboard/types.js.map +1 -0
- package/dist/core/canvas/schema.d.ts +81 -0
- package/dist/core/canvas/schema.d.ts.map +1 -0
- package/dist/core/canvas/schema.js +144 -0
- package/dist/core/canvas/schema.js.map +1 -0
- package/dist/core/canvas/store.d.ts +41 -0
- package/dist/core/canvas/store.d.ts.map +1 -0
- package/dist/core/canvas/store.js +121 -0
- package/dist/core/canvas/store.js.map +1 -0
- package/dist/core/ci-output.d.ts +1 -1
- package/dist/core/ci-output.d.ts.map +1 -1
- package/dist/core/ci-output.js +2 -0
- package/dist/core/ci-output.js.map +1 -1
- package/dist/core/cli.d.ts +15 -1
- package/dist/core/cli.d.ts.map +1 -1
- package/dist/core/cli.js +416 -35
- package/dist/core/cli.js.map +1 -1
- package/dist/core/compliance/auditor.d.ts +119 -0
- package/dist/core/compliance/auditor.d.ts.map +1 -0
- package/dist/core/compliance/auditor.js +577 -0
- package/dist/core/compliance/auditor.js.map +1 -0
- package/dist/core/compliance/index.d.ts +11 -0
- package/dist/core/compliance/index.d.ts.map +1 -0
- package/dist/core/compliance/index.js +10 -0
- package/dist/core/compliance/index.js.map +1 -0
- package/dist/core/compliance/types.d.ts +174 -0
- package/dist/core/compliance/types.d.ts.map +1 -0
- package/dist/core/compliance/types.js +12 -0
- package/dist/core/compliance/types.js.map +1 -0
- package/dist/core/conductor/conductor.d.ts +37 -0
- package/dist/core/conductor/conductor.d.ts.map +1 -0
- package/dist/core/conductor/conductor.js +96 -0
- package/dist/core/conductor/conductor.js.map +1 -0
- package/dist/core/conductor/index.d.ts +9 -0
- package/dist/core/conductor/index.d.ts.map +1 -0
- package/dist/core/conductor/index.js +3 -0
- package/dist/core/conductor/index.js.map +1 -0
- package/dist/core/conductor/model-router.d.ts +17 -0
- package/dist/core/conductor/model-router.d.ts.map +1 -0
- package/dist/core/conductor/model-router.js +29 -0
- package/dist/core/conductor/model-router.js.map +1 -0
- package/dist/core/conductor/types.d.ts +33 -0
- package/dist/core/conductor/types.d.ts.map +1 -0
- package/dist/core/conductor/types.js +2 -0
- package/dist/core/conductor/types.js.map +1 -0
- package/dist/core/config.d.ts +148 -1
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +53 -4
- package/dist/core/config.js.map +1 -1
- package/dist/core/data-integrity/data-integrity.d.ts +291 -0
- package/dist/core/data-integrity/data-integrity.d.ts.map +1 -0
- package/dist/core/data-integrity/data-integrity.js +892 -0
- package/dist/core/data-integrity/data-integrity.js.map +1 -0
- package/dist/core/data-integrity/index.d.ts +16 -0
- package/dist/core/data-integrity/index.d.ts.map +1 -0
- package/dist/core/data-integrity/index.js +17 -0
- package/dist/core/data-integrity/index.js.map +1 -0
- package/dist/core/data-integrity/types.d.ts +236 -0
- package/dist/core/data-integrity/types.d.ts.map +1 -0
- package/dist/core/data-integrity/types.js +14 -0
- package/dist/core/data-integrity/types.js.map +1 -0
- package/dist/core/disaster-recovery/index.d.ts +13 -0
- package/dist/core/disaster-recovery/index.d.ts.map +1 -0
- package/dist/core/disaster-recovery/index.js +3 -0
- package/dist/core/disaster-recovery/index.js.map +1 -0
- package/dist/core/disaster-recovery/simulator.d.ts +158 -0
- package/dist/core/disaster-recovery/simulator.d.ts.map +1 -0
- package/dist/core/disaster-recovery/simulator.js +553 -0
- package/dist/core/disaster-recovery/simulator.js.map +1 -0
- package/dist/core/disaster-recovery/types.d.ts +299 -0
- package/dist/core/disaster-recovery/types.d.ts.map +1 -0
- package/dist/core/disaster-recovery/types.js +33 -0
- package/dist/core/disaster-recovery/types.js.map +1 -0
- package/dist/core/escalation/heal-or-ask.d.ts +20 -0
- package/dist/core/escalation/heal-or-ask.d.ts.map +1 -0
- package/dist/core/escalation/heal-or-ask.js +19 -0
- package/dist/core/escalation/heal-or-ask.js.map +1 -0
- package/dist/core/escalation/index.d.ts +9 -0
- package/dist/core/escalation/index.d.ts.map +1 -0
- package/dist/core/escalation/index.js +3 -0
- package/dist/core/escalation/index.js.map +1 -0
- package/dist/core/escalation/pause-gate.d.ts +48 -0
- package/dist/core/escalation/pause-gate.d.ts.map +1 -0
- package/dist/core/escalation/pause-gate.js +96 -0
- package/dist/core/escalation/pause-gate.js.map +1 -0
- package/dist/core/escalation/types.d.ts +33 -0
- package/dist/core/escalation/types.d.ts.map +1 -0
- package/dist/core/escalation/types.js +9 -0
- package/dist/core/escalation/types.js.map +1 -0
- package/dist/core/evidence.d.ts +32 -1
- package/dist/core/evidence.d.ts.map +1 -1
- package/dist/core/evidence.js +99 -1
- package/dist/core/evidence.js.map +1 -1
- package/dist/core/feature-bdd/fix.d.ts +84 -0
- package/dist/core/feature-bdd/fix.d.ts.map +1 -0
- package/dist/core/feature-bdd/fix.js +121 -0
- package/dist/core/feature-bdd/fix.js.map +1 -0
- package/dist/core/feature-bdd/generate.d.ts +96 -0
- package/dist/core/feature-bdd/generate.d.ts.map +1 -0
- package/dist/core/feature-bdd/generate.js +228 -0
- package/dist/core/feature-bdd/generate.js.map +1 -0
- package/dist/core/feature-bdd/llm-provider.d.ts +92 -0
- package/dist/core/feature-bdd/llm-provider.d.ts.map +1 -0
- package/dist/core/feature-bdd/llm-provider.js +187 -0
- package/dist/core/feature-bdd/llm-provider.js.map +1 -0
- package/dist/core/feature-bdd/run.d.ts +56 -0
- package/dist/core/feature-bdd/run.d.ts.map +1 -0
- package/dist/core/feature-bdd/run.js +175 -0
- package/dist/core/feature-bdd/run.js.map +1 -0
- package/dist/core/feature-bdd/schema.d.ts +111 -0
- package/dist/core/feature-bdd/schema.d.ts.map +1 -0
- package/dist/core/feature-bdd/schema.js +272 -0
- package/dist/core/feature-bdd/schema.js.map +1 -0
- package/dist/core/feature-bdd/store.d.ts +145 -0
- package/dist/core/feature-bdd/store.d.ts.map +1 -0
- package/dist/core/feature-bdd/store.js +470 -0
- package/dist/core/feature-bdd/store.js.map +1 -0
- package/dist/core/finding-correlation.d.ts +55 -0
- package/dist/core/finding-correlation.d.ts.map +1 -0
- package/dist/core/finding-correlation.js +96 -0
- package/dist/core/finding-correlation.js.map +1 -0
- package/dist/core/fix-loop.d.ts +20 -1
- package/dist/core/fix-loop.d.ts.map +1 -1
- package/dist/core/fix-loop.js +34 -0
- package/dist/core/fix-loop.js.map +1 -1
- package/dist/core/governance/calibration.d.ts +31 -0
- package/dist/core/governance/calibration.d.ts.map +1 -0
- package/dist/core/governance/calibration.js +78 -0
- package/dist/core/governance/calibration.js.map +1 -0
- package/dist/core/governance/degradation.d.ts +35 -0
- package/dist/core/governance/degradation.d.ts.map +1 -0
- package/dist/core/governance/degradation.js +25 -0
- package/dist/core/governance/degradation.js.map +1 -0
- package/dist/core/governance/ethical-constraint.d.ts +55 -0
- package/dist/core/governance/ethical-constraint.d.ts.map +1 -0
- package/dist/core/governance/ethical-constraint.js +98 -0
- package/dist/core/governance/ethical-constraint.js.map +1 -0
- package/dist/core/governance/index.d.ts +9 -0
- package/dist/core/governance/index.d.ts.map +1 -0
- package/dist/core/governance/index.js +9 -0
- package/dist/core/governance/index.js.map +1 -0
- package/dist/core/harness/audit-log.d.ts +12 -0
- package/dist/core/harness/audit-log.d.ts.map +1 -0
- package/dist/core/harness/audit-log.js +62 -0
- package/dist/core/harness/audit-log.js.map +1 -0
- package/dist/core/harness/authorization.d.ts +24 -0
- package/dist/core/harness/authorization.d.ts.map +1 -0
- package/dist/core/harness/authorization.js +48 -0
- package/dist/core/harness/authorization.js.map +1 -0
- package/dist/core/harness/harness.d.ts +64 -0
- package/dist/core/harness/harness.d.ts.map +1 -0
- package/dist/core/harness/harness.js +188 -0
- package/dist/core/harness/harness.js.map +1 -0
- package/dist/core/harness/index.d.ts +10 -0
- package/dist/core/harness/index.d.ts.map +1 -0
- package/dist/core/harness/index.js +4 -0
- package/dist/core/harness/index.js.map +1 -0
- package/dist/core/harness/types.d.ts +88 -0
- package/dist/core/harness/types.d.ts.map +1 -0
- package/dist/core/harness/types.js +2 -0
- package/dist/core/harness/types.js.map +1 -0
- package/dist/core/health-check.d.ts +6 -0
- package/dist/core/health-check.d.ts.map +1 -1
- package/dist/core/health-check.js +14 -2
- package/dist/core/health-check.js.map +1 -1
- package/dist/core/init.d.ts.map +1 -1
- package/dist/core/init.js +58 -18
- package/dist/core/init.js.map +1 -1
- package/dist/core/knowledge/cached-map.d.ts +17 -0
- package/dist/core/knowledge/cached-map.d.ts.map +1 -0
- package/dist/core/knowledge/cached-map.js +23 -0
- package/dist/core/knowledge/cached-map.js.map +1 -0
- package/dist/core/knowledge/index.d.ts +10 -0
- package/dist/core/knowledge/index.d.ts.map +1 -0
- package/dist/core/knowledge/index.js +4 -0
- package/dist/core/knowledge/index.js.map +1 -0
- package/dist/core/knowledge/system-map.d.ts +50 -0
- package/dist/core/knowledge/system-map.d.ts.map +1 -0
- package/dist/core/knowledge/system-map.js +121 -0
- package/dist/core/knowledge/system-map.js.map +1 -0
- package/dist/core/knowledge/traversal.d.ts +12 -0
- package/dist/core/knowledge/traversal.d.ts.map +1 -0
- package/dist/core/knowledge/traversal.js +37 -0
- package/dist/core/knowledge/traversal.js.map +1 -0
- package/dist/core/knowledge/types.d.ts +41 -0
- package/dist/core/knowledge/types.d.ts.map +1 -0
- package/dist/core/knowledge/types.js +2 -0
- package/dist/core/knowledge/types.js.map +1 -0
- package/dist/core/license-gen.d.ts +1 -1
- package/dist/core/license-gen.d.ts.map +1 -1
- package/dist/core/license-gen.js +10 -5
- package/dist/core/license-gen.js.map +1 -1
- package/dist/core/license.d.ts +12 -2
- package/dist/core/license.d.ts.map +1 -1
- package/dist/core/license.js +104 -28
- package/dist/core/license.js.map +1 -1
- package/dist/core/loop-engine/circuit-breaker.d.ts +24 -0
- package/dist/core/loop-engine/circuit-breaker.d.ts.map +1 -0
- package/dist/core/loop-engine/circuit-breaker.js +48 -0
- package/dist/core/loop-engine/circuit-breaker.js.map +1 -0
- package/dist/core/loop-engine/demo.d.ts +35 -0
- package/dist/core/loop-engine/demo.d.ts.map +1 -0
- package/dist/core/loop-engine/demo.js +71 -0
- package/dist/core/loop-engine/demo.js.map +1 -0
- package/dist/core/loop-engine/event-store.d.ts +8 -0
- package/dist/core/loop-engine/event-store.d.ts.map +1 -0
- package/dist/core/loop-engine/event-store.js +9 -0
- package/dist/core/loop-engine/event-store.js.map +1 -0
- package/dist/core/loop-engine/index.d.ts +11 -0
- package/dist/core/loop-engine/index.d.ts.map +1 -0
- package/dist/core/loop-engine/index.js +11 -0
- package/dist/core/loop-engine/index.js.map +1 -0
- package/dist/core/loop-engine/kernel.d.ts +66 -0
- package/dist/core/loop-engine/kernel.d.ts.map +1 -0
- package/dist/core/loop-engine/kernel.js +196 -0
- package/dist/core/loop-engine/kernel.js.map +1 -0
- package/dist/core/loop-engine/tracing.d.ts +12 -0
- package/dist/core/loop-engine/tracing.d.ts.map +1 -0
- package/dist/core/loop-engine/tracing.js +15 -0
- package/dist/core/loop-engine/tracing.js.map +1 -0
- package/dist/core/loop-engine/types.d.ts +92 -0
- package/dist/core/loop-engine/types.d.ts.map +1 -0
- package/dist/core/loop-engine/types.js +21 -0
- package/dist/core/loop-engine/types.js.map +1 -0
- package/dist/core/messages.d.ts +1 -1
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +101 -1
- package/dist/core/messages.js.map +1 -1
- package/dist/core/orchestrator.d.ts +87 -7
- package/dist/core/orchestrator.d.ts.map +1 -1
- package/dist/core/orchestrator.js +399 -33
- package/dist/core/orchestrator.js.map +1 -1
- package/dist/core/phase-gate.d.ts +2 -2
- package/dist/core/quality-score/calculator.d.ts +125 -0
- package/dist/core/quality-score/calculator.d.ts.map +1 -0
- package/dist/core/quality-score/calculator.js +489 -0
- package/dist/core/quality-score/calculator.js.map +1 -0
- package/dist/core/quality-score/from-run.d.ts +27 -0
- package/dist/core/quality-score/from-run.d.ts.map +1 -0
- package/dist/core/quality-score/from-run.js +64 -0
- package/dist/core/quality-score/from-run.js.map +1 -0
- package/dist/core/quality-score/index.d.ts +9 -0
- package/dist/core/quality-score/index.d.ts.map +1 -0
- package/dist/core/quality-score/index.js +9 -0
- package/dist/core/quality-score/index.js.map +1 -0
- package/dist/core/quality-score/types.d.ts +225 -0
- package/dist/core/quality-score/types.d.ts.map +1 -0
- package/dist/core/quality-score/types.js +26 -0
- package/dist/core/quality-score/types.js.map +1 -0
- package/dist/core/report-html-script.d.ts +3 -0
- package/dist/core/report-html-script.d.ts.map +1 -0
- package/dist/core/report-html-script.js +47 -0
- package/dist/core/report-html-script.js.map +1 -0
- package/dist/core/report-html-styles.d.ts +3 -0
- package/dist/core/report-html-styles.d.ts.map +1 -0
- package/dist/core/report-html-styles.js +231 -0
- package/dist/core/report-html-styles.js.map +1 -0
- package/dist/core/report-html.d.ts +1 -1
- package/dist/core/report-html.d.ts.map +1 -1
- package/dist/core/report-html.js +5 -280
- package/dist/core/report-html.js.map +1 -1
- package/dist/core/report-upload.d.ts +8 -0
- package/dist/core/report-upload.d.ts.map +1 -1
- package/dist/core/report-upload.js +17 -4
- package/dist/core/report-upload.js.map +1 -1
- package/dist/core/run-counter.d.ts.map +1 -1
- package/dist/core/run-counter.js +25 -1
- package/dist/core/run-counter.js.map +1 -1
- package/dist/core/run-events/emitter.d.ts +112 -0
- package/dist/core/run-events/emitter.d.ts.map +1 -0
- package/dist/core/run-events/emitter.js +234 -0
- package/dist/core/run-events/emitter.js.map +1 -0
- package/dist/core/run-events/frame-sink.d.ts +24 -0
- package/dist/core/run-events/frame-sink.d.ts.map +1 -0
- package/dist/core/run-events/frame-sink.js +32 -0
- package/dist/core/run-events/frame-sink.js.map +1 -0
- package/dist/core/run-events/index.d.ts +7 -0
- package/dist/core/run-events/index.d.ts.map +1 -0
- package/dist/core/run-events/index.js +5 -0
- package/dist/core/run-events/index.js.map +1 -0
- package/dist/core/run-events/loop-event-sink.d.ts +56 -0
- package/dist/core/run-events/loop-event-sink.d.ts.map +1 -0
- package/dist/core/run-events/loop-event-sink.js +60 -0
- package/dist/core/run-events/loop-event-sink.js.map +1 -0
- package/dist/core/run-events/sse.d.ts +47 -0
- package/dist/core/run-events/sse.d.ts.map +1 -0
- package/dist/core/run-events/sse.js +64 -0
- package/dist/core/run-events/sse.js.map +1 -0
- package/dist/core/run-events/types.d.ts +147 -0
- package/dist/core/run-events/types.d.ts.map +1 -0
- package/dist/core/run-events/types.js +17 -0
- package/dist/core/run-events/types.js.map +1 -0
- package/dist/core/run-mode/capture.d.ts +37 -0
- package/dist/core/run-mode/capture.d.ts.map +1 -0
- package/dist/core/run-mode/capture.js +43 -0
- package/dist/core/run-mode/capture.js.map +1 -0
- package/dist/core/run-mode/index.d.ts +9 -0
- package/dist/core/run-mode/index.d.ts.map +1 -0
- package/dist/core/run-mode/index.js +3 -0
- package/dist/core/run-mode/index.js.map +1 -0
- package/dist/core/run-mode/run-mode.d.ts +35 -0
- package/dist/core/run-mode/run-mode.d.ts.map +1 -0
- package/dist/core/run-mode/run-mode.js +51 -0
- package/dist/core/run-mode/run-mode.js.map +1 -0
- package/dist/core/run-mode/types.d.ts +36 -0
- package/dist/core/run-mode/types.d.ts.map +1 -0
- package/dist/core/run-mode/types.js +15 -0
- package/dist/core/run-mode/types.js.map +1 -0
- package/dist/core/run-quota.d.ts +22 -0
- package/dist/core/run-quota.d.ts.map +1 -0
- package/dist/core/run-quota.js +44 -0
- package/dist/core/run-quota.js.map +1 -0
- package/dist/core/security-audit/index.d.ts +9 -0
- package/dist/core/security-audit/index.d.ts.map +1 -0
- package/dist/core/security-audit/index.js +10 -0
- package/dist/core/security-audit/index.js.map +1 -0
- package/dist/core/security-audit/sentinel.d.ts +196 -0
- package/dist/core/security-audit/sentinel.d.ts.map +1 -0
- package/dist/core/security-audit/sentinel.js +725 -0
- package/dist/core/security-audit/sentinel.js.map +1 -0
- package/dist/core/security-audit/types.d.ts +240 -0
- package/dist/core/security-audit/types.d.ts.map +1 -0
- package/dist/core/security-audit/types.js +42 -0
- package/dist/core/security-audit/types.js.map +1 -0
- package/dist/core/tech-debt/index.d.ts +11 -0
- package/dist/core/tech-debt/index.d.ts.map +1 -0
- package/dist/core/tech-debt/index.js +11 -0
- package/dist/core/tech-debt/index.js.map +1 -0
- package/dist/core/tech-debt/tech-debt-tracker.d.ts +46 -0
- package/dist/core/tech-debt/tech-debt-tracker.d.ts.map +1 -0
- package/dist/core/tech-debt/tech-debt-tracker.js +533 -0
- package/dist/core/tech-debt/tech-debt-tracker.js.map +1 -0
- package/dist/core/tech-debt/types.d.ts +263 -0
- package/dist/core/tech-debt/types.d.ts.map +1 -0
- package/dist/core/tech-debt/types.js +2 -0
- package/dist/core/tech-debt/types.js.map +1 -0
- package/dist/core/tester/diff-planner.d.ts +18 -0
- package/dist/core/tester/diff-planner.d.ts.map +1 -0
- package/dist/core/tester/diff-planner.js +37 -0
- package/dist/core/tester/diff-planner.js.map +1 -0
- package/dist/core/tester/honest-report.d.ts +13 -0
- package/dist/core/tester/honest-report.d.ts.map +1 -0
- package/dist/core/tester/honest-report.js +64 -0
- package/dist/core/tester/honest-report.js.map +1 -0
- package/dist/core/tester/index.d.ts +9 -0
- package/dist/core/tester/index.d.ts.map +1 -0
- package/dist/core/tester/index.js +3 -0
- package/dist/core/tester/index.js.map +1 -0
- package/dist/core/tester/types.d.ts +55 -0
- package/dist/core/tester/types.d.ts.map +1 -0
- package/dist/core/tester/types.js +8 -0
- package/dist/core/tester/types.js.map +1 -0
- package/dist/core/triggers/index.d.ts +9 -0
- package/dist/core/triggers/index.d.ts.map +1 -0
- package/dist/core/triggers/index.js +3 -0
- package/dist/core/triggers/index.js.map +1 -0
- package/dist/core/triggers/trigger-bus.d.ts +49 -0
- package/dist/core/triggers/trigger-bus.d.ts.map +1 -0
- package/dist/core/triggers/trigger-bus.js +167 -0
- package/dist/core/triggers/trigger-bus.js.map +1 -0
- package/dist/core/triggers/types.d.ts +56 -0
- package/dist/core/triggers/types.d.ts.map +1 -0
- package/dist/core/triggers/types.js +13 -0
- package/dist/core/triggers/types.js.map +1 -0
- package/dist/core/trust.d.ts +12 -0
- package/dist/core/trust.d.ts.map +1 -0
- package/dist/core/trust.js +13 -0
- package/dist/core/trust.js.map +1 -0
- package/dist/core/types.d.ts +24 -2
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/ui-ux/index.d.ts +12 -0
- package/dist/core/ui-ux/index.d.ts.map +1 -0
- package/dist/core/ui-ux/index.js +13 -0
- package/dist/core/ui-ux/index.js.map +1 -0
- package/dist/core/ui-ux/orchestrator.d.ts +206 -0
- package/dist/core/ui-ux/orchestrator.d.ts.map +1 -0
- package/dist/core/ui-ux/orchestrator.js +672 -0
- package/dist/core/ui-ux/orchestrator.js.map +1 -0
- package/dist/core/ui-ux/types.d.ts +339 -0
- package/dist/core/ui-ux/types.d.ts.map +1 -0
- package/dist/core/ui-ux/types.js +17 -0
- package/dist/core/ui-ux/types.js.map +1 -0
- package/dist/enterprise/audit-trail.d.ts +31 -0
- package/dist/enterprise/audit-trail.d.ts.map +1 -0
- package/dist/enterprise/audit-trail.js +111 -0
- package/dist/enterprise/audit-trail.js.map +1 -0
- package/dist/enterprise/sla.d.ts +26 -0
- package/dist/enterprise/sla.d.ts.map +1 -0
- package/dist/enterprise/sla.js +101 -0
- package/dist/enterprise/sla.js.map +1 -0
- package/dist/helpers/element-discovery.js +1 -1
- package/dist/helpers/element-discovery.js.map +1 -1
- package/dist/helpers/env-resolver.d.ts +2 -2
- package/dist/helpers/quality-gate.d.ts.map +1 -1
- package/dist/helpers/quality-gate.js +21 -3
- package/dist/helpers/quality-gate.js.map +1 -1
- package/dist/helpers/shape-fingerprint.d.ts +18 -0
- package/dist/helpers/shape-fingerprint.d.ts.map +1 -0
- package/dist/helpers/shape-fingerprint.js +40 -0
- package/dist/helpers/shape-fingerprint.js.map +1 -0
- package/dist/sdk/custom-agent.d.ts +51 -0
- package/dist/sdk/custom-agent.d.ts.map +1 -0
- package/dist/sdk/custom-agent.js +94 -0
- package/dist/sdk/custom-agent.js.map +1 -0
- package/dist/sdk/index.d.ts +5 -0
- package/dist/sdk/index.d.ts.map +1 -0
- package/dist/sdk/index.js +3 -0
- package/dist/sdk/index.js.map +1 -0
- package/dist/sdk/loader.d.ts +28 -0
- package/dist/sdk/loader.d.ts.map +1 -0
- package/dist/sdk/loader.js +140 -0
- package/dist/sdk/loader.js.map +1 -0
- package/package.json +46 -20
- package/agents/01-analyst.ts +0 -100
- package/agents/02-seed-architect.ts +0 -59
- package/agents/03-test-generator.ts +0 -191
- package/agents/04-unit-runner.ts +0 -160
- package/agents/05-browser-crawler.ts +0 -790
- package/agents/06-api-exerciser.ts +0 -311
- package/agents/07-security-scout.ts +0 -188
- package/agents/08-a11y-guardian.ts +0 -212
- package/agents/09-healer.ts +0 -228
- package/agents/10-reporter.ts +0 -266
- package/agents/11-fixer.ts +0 -253
- package/agents/12-ux-inspector.ts +0 -444
- package/agents/13-performance-profiler.ts +0 -271
- package/agents/14-data-integrity-auditor.ts +0 -417
- package/agents/15-regression-sentinel.ts +0 -307
- package/agents/16-chaos-agent.ts +0 -228
- package/agents/17-documentation-validator.ts +0 -266
- package/agents/18-integration-watchdog.ts +0 -178
- package/agents/19-tenant-isolation-auditor.ts +0 -199
- package/agents/20-workflow-completion-tester.ts +0 -203
- package/agents/21-state-session-tester.ts +0 -262
- package/agents/22-email-notification-verifier.ts +0 -244
- package/agents/23-migration-tester.ts +0 -80
- package/agents/24-signup-onboarding-tester.ts +0 -429
- package/agents/25-crud-flow-tester.ts +0 -302
- package/agents/26-form-validator.ts +0 -297
- package/agents/27-search-filter-tester.ts +0 -326
- package/agents/28-navigation-routing-tester.ts +0 -425
- package/agents/29-responsive-interaction-tester.ts +0 -350
- package/agents/30-multi-user-scenario-tester.ts +0 -319
- package/agents/31-load-tester.ts +0 -134
- package/agents/32-memory-leak-detector.ts +0 -194
- package/agents/33-bundle-analyzer.ts +0 -132
- package/agents/34-xss-scanner.ts +0 -191
- package/agents/35-csrf-tester.ts +0 -82
- package/agents/36-auth-fuzzer.ts +0 -194
- package/agents/37-dependency-scanner.ts +0 -176
- package/agents/38-secrets-scanner.ts +0 -137
- package/agents/39-api-contract-tester.ts +0 -199
- package/agents/40-rate-limit-tester.ts +0 -94
- package/agents/41-api-pagination-tester.ts +0 -97
- package/agents/42-graphql-tester.ts +0 -222
- package/agents/43-data-consistency-checker.ts +0 -205
- package/agents/44-backup-recovery-tester.ts +0 -152
- package/agents/45-data-privacy-scanner.ts +0 -125
- package/agents/46-seo-auditor.ts +0 -294
- package/agents/47-social-preview-tester.ts +0 -232
- package/agents/48-lighthouse-auditor.ts +0 -213
- package/agents/49-i18n-tester.ts +0 -198
- package/agents/50-timezone-tester.ts +0 -173
- package/agents/51-error-recovery-tester.ts +0 -155
- package/agents/52-offline-mode-tester.ts +0 -180
- package/agents/53-graceful-degradation-tester.ts +0 -156
- package/agents/54-websocket-tester.ts +0 -151
- package/agents/55-realtime-sync-tester.ts +0 -194
- package/agents/56-file-upload-tester.ts +0 -194
- package/agents/57-export-tester.ts +0 -174
- package/agents/58-payment-flow-tester.ts +0 -183
- package/agents/59-ssl-tls-auditor.ts +0 -141
- package/agents/60-dns-cdn-tester.ts +0 -117
- package/agents/61-docker-health-checker.ts +0 -111
- package/agents/62-env-config-validator.ts +0 -152
- package/agents/63-log-quality-auditor.ts +0 -136
- package/agents/64-analytics-tracker-tester.ts +0 -165
- package/agents/65-gdpr-compliance-tester.ts +0 -215
- package/agents/66-soc2-control-validator.ts +0 -210
- package/agents/67-wcag-aaa-tester.ts +0 -241
- package/agents/68-dead-code-detector.ts +0 -135
- package/agents/69-type-safety-auditor.ts +0 -164
- package/agents/70-complexity-analyzer.ts +0 -179
- package/agents/__tests__/01-analyst.test.ts +0 -188
- package/agents/__tests__/02-seed-architect.test.ts +0 -152
- package/agents/__tests__/03-test-generator-full.test.ts +0 -321
- package/agents/__tests__/03-test-generator.test.ts +0 -318
- package/agents/__tests__/04-unit-runner.test.ts +0 -320
- package/agents/__tests__/05-browser-crawler-beta.test.ts +0 -492
- package/agents/__tests__/05-browser-crawler-release.test.ts +0 -412
- package/agents/__tests__/05-browser-crawler-uat.test.ts +0 -578
- package/agents/__tests__/05-browser-crawler.test.ts +0 -518
- package/agents/__tests__/06-api-exerciser.test.ts +0 -619
- package/agents/__tests__/07-security-scout.test.ts +0 -382
- package/agents/__tests__/08-a11y-guardian.test.ts +0 -530
- package/agents/__tests__/09-healer.test.ts +0 -384
- package/agents/__tests__/10-reporter.test.ts +0 -366
- package/agents/__tests__/11-fixer.test.ts +0 -406
- package/agents/__tests__/12-ux-inspector-extended.test.ts +0 -465
- package/agents/__tests__/12-ux-inspector.test.ts +0 -443
- package/agents/__tests__/13-performance-profiler.test.ts +0 -411
- package/agents/__tests__/14-data-integrity-auditor-extended.test.ts +0 -573
- package/agents/__tests__/14-data-integrity-auditor.test.ts +0 -407
- package/agents/__tests__/15-regression-sentinel.test.ts +0 -657
- package/agents/__tests__/16-chaos-agent.test.ts +0 -427
- package/agents/__tests__/17-documentation-validator.test.ts +0 -402
- package/agents/__tests__/18-integration-watchdog.test.ts +0 -263
- package/agents/__tests__/19-tenant-isolation-auditor.test.ts +0 -400
- package/agents/__tests__/20-workflow-completion-tester.test.ts +0 -586
- package/agents/__tests__/21-state-session-tester.test.ts +0 -374
- package/agents/__tests__/22-email-notification-verifier.test.ts +0 -441
- package/agents/__tests__/23-migration-tester.test.ts +0 -145
- package/agents/__tests__/24-signup-onboarding-tester.test.ts +0 -274
- package/agents/__tests__/25-crud-flow-tester.test.ts +0 -322
- package/agents/__tests__/26-form-validator.test.ts +0 -345
- package/agents/__tests__/27-search-filter-tester.test.ts +0 -311
- package/agents/__tests__/28-navigation-routing-tester.test.ts +0 -328
- package/agents/__tests__/29-responsive-interaction-tester.test.ts +0 -297
- package/agents/__tests__/30-multi-user-scenario-tester.test.ts +0 -328
- package/agents/__tests__/31-load-tester.test.ts +0 -189
- package/agents/__tests__/32-memory-leak-detector.test.ts +0 -251
- package/agents/__tests__/33-bundle-analyzer.test.ts +0 -237
- package/agents/__tests__/34-xss-scanner.test.ts +0 -258
- package/agents/__tests__/35-csrf-tester.test.ts +0 -200
- package/agents/__tests__/36-auth-fuzzer.test.ts +0 -214
- package/agents/__tests__/37-dependency-scanner.test.ts +0 -266
- package/agents/__tests__/38-secrets-scanner.test.ts +0 -224
- package/agents/__tests__/39-api-contract-tester.test.ts +0 -312
- package/agents/__tests__/40-rate-limit-tester.test.ts +0 -192
- package/agents/__tests__/41-api-pagination-tester.test.ts +0 -198
- package/agents/__tests__/42-graphql-tester.test.ts +0 -252
- package/agents/__tests__/43-data-consistency-checker.test.ts +0 -232
- package/agents/__tests__/44-backup-recovery-tester.test.ts +0 -222
- package/agents/__tests__/45-data-privacy-scanner.test.ts +0 -223
- package/agents/__tests__/46-seo-auditor.test.ts +0 -261
- package/agents/__tests__/47-social-preview-tester.test.ts +0 -245
- package/agents/__tests__/48-lighthouse-auditor.test.ts +0 -276
- package/agents/__tests__/49-i18n-tester.test.ts +0 -201
- package/agents/__tests__/50-timezone-tester.test.ts +0 -172
- package/agents/__tests__/51-error-recovery-tester.test.ts +0 -162
- package/agents/__tests__/52-offline-mode-tester.test.ts +0 -164
- package/agents/__tests__/53-graceful-degradation-tester.test.ts +0 -168
- package/agents/__tests__/54-websocket-tester.test.ts +0 -157
- package/agents/__tests__/55-realtime-sync-tester.test.ts +0 -181
- package/agents/__tests__/56-file-upload-tester.test.ts +0 -172
- package/agents/__tests__/57-export-tester.test.ts +0 -169
- package/agents/__tests__/58-payment-flow-tester.test.ts +0 -182
- package/agents/__tests__/59-ssl-tls-auditor.test.ts +0 -179
- package/agents/__tests__/60-dns-cdn-tester.test.ts +0 -176
- package/agents/__tests__/61-docker-health-checker.test.ts +0 -150
- package/agents/__tests__/62-env-config-validator.test.ts +0 -166
- package/agents/__tests__/63-log-quality-auditor.test.ts +0 -175
- package/agents/__tests__/64-analytics-tracker-tester.test.ts +0 -158
- package/agents/__tests__/65-gdpr-compliance-tester.test.ts +0 -174
- package/agents/__tests__/66-soc2-control-validator.test.ts +0 -183
- package/agents/__tests__/67-wcag-aaa-tester.test.ts +0 -190
- package/agents/__tests__/68-dead-code-detector.test.ts +0 -174
- package/agents/__tests__/69-type-safety-auditor.test.ts +0 -173
- package/agents/__tests__/70-complexity-analyzer.test.ts +0 -177
- package/agents/__tests__/base-agent.test.ts +0 -188
- package/agents/__tests__/registry.test.ts +0 -218
- package/agents/base-agent.ts +0 -77
- package/agents/registry.ts +0 -277
- package/baselines/api-schemas/.gitkeep +0 -0
- package/baselines/performance/.gitkeep +0 -0
- package/baselines/screenshots/.gitkeep +0 -0
- package/core/__tests__/ci-output.test.ts +0 -430
- package/core/__tests__/cli.test.ts +0 -387
- package/core/__tests__/config.test.ts +0 -78
- package/core/__tests__/cost-tracker.test.ts +0 -158
- package/core/__tests__/evidence.test.ts +0 -265
- package/core/__tests__/fix-loop.test.ts +0 -210
- package/core/__tests__/health-check.test.ts +0 -44
- package/core/__tests__/init.test.ts +0 -609
- package/core/__tests__/integration.test.ts +0 -204
- package/core/__tests__/license-gen.test.ts +0 -227
- package/core/__tests__/license.test.ts +0 -326
- package/core/__tests__/multi-browser.test.ts +0 -278
- package/core/__tests__/orchestrator.test.ts +0 -520
- package/core/__tests__/phase-gate.test.ts +0 -43
- package/core/__tests__/report-html.test.ts +0 -398
- package/core/__tests__/report-upload.test.ts +0 -325
- package/core/__tests__/run-counter.test.ts +0 -234
- package/core/ci-output.ts +0 -240
- package/core/cli.ts +0 -232
- package/core/config.ts +0 -178
- package/core/cost-tracker.ts +0 -59
- package/core/evidence.ts +0 -132
- package/core/fix-loop.ts +0 -85
- package/core/health-check.ts +0 -54
- package/core/init.ts +0 -546
- package/core/license-gen.ts +0 -212
- package/core/license.ts +0 -208
- package/core/messages.ts +0 -67
- package/core/multi-browser.ts +0 -136
- package/core/orchestrator.ts +0 -356
- package/core/phase-gate.ts +0 -55
- package/core/report-html.ts +0 -657
- package/core/report-upload.ts +0 -188
- package/core/run-counter.ts +0 -175
- package/core/types.ts +0 -57
- package/dist/core/multi-browser.d.ts +0 -36
- package/dist/core/multi-browser.d.ts.map +0 -1
- package/dist/core/multi-browser.js +0 -88
- package/dist/core/multi-browser.js.map +0 -1
- package/helpers/__tests__/api-client.test.ts +0 -199
- package/helpers/__tests__/element-discovery.test.ts +0 -202
- package/helpers/__tests__/form-filler-extended.test.ts +0 -212
- package/helpers/__tests__/form-filler.test.ts +0 -99
- package/helpers/__tests__/modal-handler.test.ts +0 -152
- package/helpers/__tests__/navigation.test.ts +0 -214
- package/helpers/__tests__/quality-gate.test.ts +0 -117
- package/helpers/__tests__/screenshot.test.ts +0 -139
- package/helpers/__tests__/seed-validator.test.ts +0 -114
- package/helpers/api-client.ts +0 -111
- package/helpers/element-discovery.ts +0 -105
- package/helpers/env-resolver.ts +0 -69
- package/helpers/form-filler.ts +0 -126
- package/helpers/modal-handler.ts +0 -108
- package/helpers/navigation.ts +0 -100
- package/helpers/quality-gate.ts +0 -180
- package/helpers/screenshot.ts +0 -111
- package/helpers/seed-validator.ts +0 -70
|
@@ -0,0 +1,1103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bridge HTTP Server
|
|
3
|
+
*
|
|
4
|
+
* Exposes the BridgeRouter over HTTP using Node's built-in http module.
|
|
5
|
+
* No external dependencies required — keeps TestTeam dependency-light.
|
|
6
|
+
*
|
|
7
|
+
* Endpoints:
|
|
8
|
+
* GET /health — liveness check
|
|
9
|
+
* GET /agents — full agent capability list with executor types
|
|
10
|
+
* GET /runs — summaries of past runs read from the .run/ directory
|
|
11
|
+
* GET /runs/:id — full detail (summary + agent results) for one run
|
|
12
|
+
* POST /execute — execute a BridgeTask and return BridgeResult
|
|
13
|
+
*/
|
|
14
|
+
import { createServer } from 'node:http';
|
|
15
|
+
import { randomUUID, timingSafeEqual } from 'node:crypto';
|
|
16
|
+
import * as path from 'node:path';
|
|
17
|
+
import { BridgeRouter } from './router.js';
|
|
18
|
+
import { PlaywrightPool } from './playwright-pool.js';
|
|
19
|
+
import { ShellExecutor } from './shell-executor.js';
|
|
20
|
+
import { FileScanner } from './file-scanner.js';
|
|
21
|
+
import { buildSystemMapSnapshot } from './knowledge-reader.js';
|
|
22
|
+
import { buildSecurityPostureSnapshot } from './sentinel-reader.js';
|
|
23
|
+
import { buildCompliancePostureSnapshot } from './compliance-reader.js';
|
|
24
|
+
import { buildApiContractSnapshot } from './api-contract-reader.js';
|
|
25
|
+
import { buildDesignPostureSnapshot } from './design-reader.js';
|
|
26
|
+
import { buildTechDebtSnapshot } from './tech-debt-reader.js';
|
|
27
|
+
import { buildDataIntegritySnapshot } from './data-integrity-reader.js';
|
|
28
|
+
import { buildReliabilityPostureSnapshot } from './reliability-reader.js';
|
|
29
|
+
import { buildLoopEngineCockpit } from './loop-engine-reader.js';
|
|
30
|
+
import { HttpClient } from './http-client.js';
|
|
31
|
+
import { RateLimiter } from './rate-limiter.js';
|
|
32
|
+
import { AGENT_REGISTRY } from './agent-registry.js';
|
|
33
|
+
import { getAgentTier } from '../agents/registry.js';
|
|
34
|
+
import { listRuns, readRun } from './runs-reader.js';
|
|
35
|
+
import { CanvasStore, CanvasPathError } from '../core/canvas/store.js';
|
|
36
|
+
import { CanvasValidationError } from '../core/canvas/schema.js';
|
|
37
|
+
import { RunEventEmitter, SseRunEventSink, SseFrameSink, SseLoopEventSink, initSse } from '../core/run-events/index.js';
|
|
38
|
+
import { FrameStreamer } from '../core/run-mode/index.js';
|
|
39
|
+
import { runLoopEngineDemo } from '../core/loop-engine/index.js';
|
|
40
|
+
import { PauseGate } from '../core/escalation/pause-gate.js';
|
|
41
|
+
import { FeatureArtifactStore, FeatureStorePathError, FeatureStoreValidationError, } from '../core/feature-bdd/store.js';
|
|
42
|
+
import { FeatureBddValidationError } from '../core/feature-bdd/schema.js';
|
|
43
|
+
import { generateBdd, generateTests } from '../core/feature-bdd/generate.js';
|
|
44
|
+
import { runFeatureTests, FEATURE_BDD_AGENT_ID } from '../core/feature-bdd/run.js';
|
|
45
|
+
import { fixFeature } from '../core/feature-bdd/fix.js';
|
|
46
|
+
import { AnthropicProvider, LLMProviderError, } from '../core/feature-bdd/llm-provider.js';
|
|
47
|
+
import { FEATURE_PROVENANCE_VERSION } from '../core/feature-bdd/schema.js';
|
|
48
|
+
function toSafeLogMessage(error) {
|
|
49
|
+
const raw = error instanceof Error ? error.message : String(error);
|
|
50
|
+
return raw.replace(/[\r\n]+/g, ' ');
|
|
51
|
+
}
|
|
52
|
+
/** Build the agent capability list from the registry. */
|
|
53
|
+
function buildAgentList() {
|
|
54
|
+
return AGENT_REGISTRY.map((entry) => ({
|
|
55
|
+
agentId: entry.agentId,
|
|
56
|
+
name: entry.name,
|
|
57
|
+
executorType: entry.executorType,
|
|
58
|
+
squad: entry.squad,
|
|
59
|
+
licenseTier: getAgentTier(entry.agentId),
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
/** Maximum accepted request-body size (bytes). Canvas graphs cap ~1.5 MB; 5 MB is generous. */
|
|
63
|
+
const MAX_BODY_BYTES = 5 * 1024 * 1024;
|
|
64
|
+
/** Read the full request body as a string, rejecting bodies over MAX_BODY_BYTES. */
|
|
65
|
+
function readBody(req) {
|
|
66
|
+
return new Promise((resolve, reject) => {
|
|
67
|
+
const chunks = [];
|
|
68
|
+
let total = 0;
|
|
69
|
+
req.on('data', (chunk) => {
|
|
70
|
+
total += chunk.length;
|
|
71
|
+
if (total > MAX_BODY_BYTES) {
|
|
72
|
+
req.destroy();
|
|
73
|
+
reject(new Error('request body too large'));
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
chunks.push(chunk);
|
|
77
|
+
});
|
|
78
|
+
req.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));
|
|
79
|
+
req.on('error', reject);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/** Send a JSON response. */
|
|
83
|
+
function jsonResponse(res, status, body) {
|
|
84
|
+
const payload = JSON.stringify(body);
|
|
85
|
+
res.writeHead(status, {
|
|
86
|
+
'Content-Type': 'application/json',
|
|
87
|
+
'Content-Length': Buffer.byteLength(payload),
|
|
88
|
+
});
|
|
89
|
+
res.end(payload);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Strip CR/LF + control chars from a (possibly user-derived) value before
|
|
93
|
+
* logging it — prevents forged / multi-line log entries (CodeQL js/log-injection).
|
|
94
|
+
*/
|
|
95
|
+
function logSafe(v) {
|
|
96
|
+
const s = v instanceof Error ? v.message : String(v);
|
|
97
|
+
// Remove CR/LF first (the log-forging vector — the explicit newline-removal
|
|
98
|
+
// pattern CodeQL's js/log-injection recognises as a sanitizer), then strip any
|
|
99
|
+
// remaining control chars and cap the length.
|
|
100
|
+
// eslint-disable-next-line no-control-regex
|
|
101
|
+
return s.replace(/[\r\n]/g, '').replace(/[\t\x00-\x1f\x7f]/g, ' ').slice(0, 500);
|
|
102
|
+
}
|
|
103
|
+
/** Return a stable, non-user-derived error category for logging. */
|
|
104
|
+
function logErrorKind(err) {
|
|
105
|
+
if (err && typeof err === 'object') {
|
|
106
|
+
const ctor = err.constructor;
|
|
107
|
+
if (ctor && typeof ctor.name === 'string' && ctor.name.length > 0) {
|
|
108
|
+
return logSafe(ctor.name);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return 'UnknownError';
|
|
112
|
+
}
|
|
113
|
+
/** Validate that a parsed body conforms to the minimal BridgeTask shape. */
|
|
114
|
+
function isValidBridgeTask(body) {
|
|
115
|
+
if (typeof body !== 'object' || body === null)
|
|
116
|
+
return false;
|
|
117
|
+
const obj = body;
|
|
118
|
+
const validExecutors = ['playwright', 'shell', 'file-scan', 'http', 'hybrid'];
|
|
119
|
+
return (typeof obj['agentId'] === 'number' &&
|
|
120
|
+
typeof obj['agentName'] === 'string' &&
|
|
121
|
+
typeof obj['executorType'] === 'string' &&
|
|
122
|
+
validExecutors.includes(obj['executorType']) &&
|
|
123
|
+
typeof obj['config'] === 'object' &&
|
|
124
|
+
obj['config'] !== null);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Validate the executor-specific `config` shape at the route boundary so a
|
|
128
|
+
* structurally-wrong task (e.g. a shell task with no `command`, an http task
|
|
129
|
+
* with no `url`) returns a clear 400 rather than crashing the executor into a
|
|
130
|
+
* generic 500 (or, worse, calling ShellExecutor.execute(undefined, …)).
|
|
131
|
+
* Returns an error string, or null when the shape is valid for the executor.
|
|
132
|
+
*/
|
|
133
|
+
function configShapeError(task) {
|
|
134
|
+
const c = task.config;
|
|
135
|
+
const needsString = (key) => typeof c[key] === 'string' && c[key].length > 0;
|
|
136
|
+
switch (task.executorType) {
|
|
137
|
+
case 'playwright':
|
|
138
|
+
return needsString('url') ? null : 'playwright config requires a non-empty string url';
|
|
139
|
+
case 'http':
|
|
140
|
+
return needsString('url') ? null : 'http config requires a non-empty string url';
|
|
141
|
+
case 'shell':
|
|
142
|
+
return needsString('command') ? null : 'shell config requires a non-empty string command';
|
|
143
|
+
case 'file-scan':
|
|
144
|
+
if (!needsString('rootDir'))
|
|
145
|
+
return 'file-scan config requires a non-empty string rootDir';
|
|
146
|
+
if (!Array.isArray(c['patterns']))
|
|
147
|
+
return 'file-scan config requires a patterns array';
|
|
148
|
+
return null;
|
|
149
|
+
case 'hybrid':
|
|
150
|
+
return Array.isArray(c['steps']) && c['steps'].length > 0
|
|
151
|
+
? null
|
|
152
|
+
: 'hybrid config requires a non-empty steps array';
|
|
153
|
+
default:
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Resource-intensive routes that must be rate-limited even though they are GET:
|
|
159
|
+
* the unauthenticated SSE run-triggers START full pipeline runs / spawn child
|
|
160
|
+
* processes / run an in-process kernel demo, so an enabled limiter must cover them
|
|
161
|
+
* — not just mutating POSTs. Matches GET /runs/stream, GET /loop-engine/stream, and
|
|
162
|
+
* GET /canvas/:id/bdd/{run,fix}. Cheap read-only GETs (/health, /agents, /runs,
|
|
163
|
+
* /runs/:id, /loop-engine/cockpit, canvas load) stay unthrottled.
|
|
164
|
+
*/
|
|
165
|
+
function isExpensiveGet(method, url) {
|
|
166
|
+
if (method !== 'GET')
|
|
167
|
+
return false;
|
|
168
|
+
const p = url.split('?')[0];
|
|
169
|
+
if (p === '/runs/stream')
|
|
170
|
+
return true;
|
|
171
|
+
// Runs an in-process kernel demo (bounded, but CPU) — throttle it like the other SSE GETs.
|
|
172
|
+
if (p === '/loop-engine/stream')
|
|
173
|
+
return true;
|
|
174
|
+
const segs = p.split('/').filter(Boolean); // ['canvas', id, 'bdd', sub]
|
|
175
|
+
return segs[0] === 'canvas' && segs[2] === 'bdd' && (segs[3] === 'run' || segs[3] === 'fix');
|
|
176
|
+
}
|
|
177
|
+
/** Valid phase values accepted on the query string for GET /runs/stream. */
|
|
178
|
+
const VALID_PHASES = new Set(['alpha', 'beta', 'uat', 'release', 'exploratory']);
|
|
179
|
+
/**
|
|
180
|
+
* Per-run registry of active gate + emitter pairs, used by POST /runs/answer to
|
|
181
|
+
* route answers back to the correct in-flight run.
|
|
182
|
+
*/
|
|
183
|
+
const runRegistry = new Map();
|
|
184
|
+
/**
|
|
185
|
+
* Returns true and sets the appropriate ACAO header if the origin is allowed;
|
|
186
|
+
* returns false and sets no ACAO header otherwise.
|
|
187
|
+
*/
|
|
188
|
+
function applyCors(req, res, allowed) {
|
|
189
|
+
const origin = req.headers['origin'];
|
|
190
|
+
if (typeof origin === 'string' && allowed.includes(origin)) {
|
|
191
|
+
res.setHeader('Access-Control-Allow-Origin', origin);
|
|
192
|
+
res.setHeader('Vary', 'Origin');
|
|
193
|
+
}
|
|
194
|
+
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
|
195
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, x-bridge-token');
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Check the x-bridge-token header when a token is configured.
|
|
199
|
+
* Returns true if auth passes (or no token is configured).
|
|
200
|
+
* Returns false after sending a 401 response.
|
|
201
|
+
*/
|
|
202
|
+
/** Constant-time string compare — avoids leaking the token via comparison timing. */
|
|
203
|
+
function safeEqual(a, b) {
|
|
204
|
+
const ab = Buffer.from(a);
|
|
205
|
+
const bb = Buffer.from(b);
|
|
206
|
+
// timingSafeEqual throws on length mismatch; the length check is not secret.
|
|
207
|
+
if (ab.length !== bb.length)
|
|
208
|
+
return false;
|
|
209
|
+
return timingSafeEqual(ab, bb);
|
|
210
|
+
}
|
|
211
|
+
function checkAuth(req, res, token) {
|
|
212
|
+
if (token === '')
|
|
213
|
+
return true;
|
|
214
|
+
const provided = req.headers['x-bridge-token'];
|
|
215
|
+
if (typeof provided === 'string' && safeEqual(provided, token))
|
|
216
|
+
return true;
|
|
217
|
+
jsonResponse(res, 401, { error: 'unauthorized' });
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Stricter auth for CODE-WRITING routes (BDD scenario/test generation): these persist
|
|
222
|
+
* LLM-generated code to disk which the runner later executes via vitest. Unlike the
|
|
223
|
+
* read routes, they must NEVER be open — so when no TESTTEAM_BRIDGE_TOKEN is configured
|
|
224
|
+
* they are refused outright (503), closing the unauthenticated write→execute (RCE) chain
|
|
225
|
+
* even in the bridge's dev-default unauth posture. The SSE run/fix routes (which
|
|
226
|
+
* EventSource cannot add a header to) then only ever execute already-authored artifacts.
|
|
227
|
+
*/
|
|
228
|
+
function requireConfiguredAuth(req, res, token) {
|
|
229
|
+
if (token === '') {
|
|
230
|
+
jsonResponse(res, 503, {
|
|
231
|
+
error: 'this route generates+persists executable code and requires TESTTEAM_BRIDGE_TOKEN to be configured',
|
|
232
|
+
});
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
return checkAuth(req, res, token);
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Create and return the HTTP server without starting it.
|
|
239
|
+
* Useful for testing — call `server.listen(port)` yourself.
|
|
240
|
+
*/
|
|
241
|
+
export function createBridgeServer(options = {}) {
|
|
242
|
+
const router = options.router ??
|
|
243
|
+
new BridgeRouter(new PlaywrightPool(), new ShellExecutor(), new FileScanner(), new HttpClient());
|
|
244
|
+
const runsDir = options.runsDir ?? path.join(process.cwd(), '.run');
|
|
245
|
+
const runStreamDriver = options.runStreamDriver;
|
|
246
|
+
const agentRunner = options.agentRunner;
|
|
247
|
+
const canvasStore = new CanvasStore(options.canvasDir ?? path.join(process.cwd(), '.testteam', 'canvases'));
|
|
248
|
+
const llmProvider = options.llmProvider ?? new AnthropicProvider();
|
|
249
|
+
const featureStore = new FeatureArtifactStore(options.featuresDir ?? path.join(process.cwd(), '.testteam', 'features'));
|
|
250
|
+
const shellExecutor = options.shellExecutor ?? new ShellExecutor();
|
|
251
|
+
const allowed = options.allowedOrigins ??
|
|
252
|
+
process.env['TESTTEAM_BRIDGE_ORIGINS']?.split(',').map((s) => s.trim()).filter(Boolean) ??
|
|
253
|
+
['http://localhost:5173'];
|
|
254
|
+
const authToken = options.authToken ?? process.env['TESTTEAM_BRIDGE_TOKEN'] ?? '';
|
|
255
|
+
if (authToken === '') {
|
|
256
|
+
console.warn('[bridge] WARNING: no auth token set (TESTTEAM_BRIDGE_TOKEN); mutating routes are unauthenticated');
|
|
257
|
+
}
|
|
258
|
+
// Rate limiter for mutating requests — OFF by default. Enable via options.rateLimit
|
|
259
|
+
// or TESTTEAM_BRIDGE_RATE_LIMIT (set to "1"/"true" for the default 60/min, or a number
|
|
260
|
+
// for a custom per-minute cap).
|
|
261
|
+
const rlEnv = process.env['TESTTEAM_BRIDGE_RATE_LIMIT'];
|
|
262
|
+
const rlEnvOn = rlEnv === '1' || rlEnv === 'true' || (rlEnv !== undefined && Number(rlEnv) > 0);
|
|
263
|
+
const limiter = (options.rateLimit?.enabled ?? rlEnvOn)
|
|
264
|
+
? new RateLimiter({
|
|
265
|
+
max: options.rateLimit?.max ?? (rlEnv && Number(rlEnv) > 1 ? Number(rlEnv) : 60),
|
|
266
|
+
windowMs: options.rateLimit?.windowMs ?? 60_000,
|
|
267
|
+
})
|
|
268
|
+
: null;
|
|
269
|
+
const server = createServer(async (req, res) => {
|
|
270
|
+
const url = req.url ?? '/';
|
|
271
|
+
const method = req.method ?? 'GET';
|
|
272
|
+
// CORS headers for all responses (allowlist-based)
|
|
273
|
+
applyCors(req, res, allowed);
|
|
274
|
+
// Handle OPTIONS preflight
|
|
275
|
+
if (method === 'OPTIONS') {
|
|
276
|
+
res.writeHead(204);
|
|
277
|
+
res.end();
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
// Rate limit mutating (non-GET/HEAD) requests AND the resource-intensive SSE
|
|
281
|
+
// run-trigger GETs (/runs/stream, /canvas/:id/bdd/{run,fix}) — which spawn
|
|
282
|
+
// processes / start pipeline runs — when the limiter is enabled. Cheap read-only
|
|
283
|
+
// GETs (/health, /agents, /runs, canvas load) stay unthrottled.
|
|
284
|
+
if (limiter && ((method !== 'GET' && method !== 'HEAD') || isExpensiveGet(method, url))) {
|
|
285
|
+
const key = req.socket.remoteAddress ?? 'unknown';
|
|
286
|
+
const verdict = limiter.check(key, Date.now());
|
|
287
|
+
if (!verdict.allowed) {
|
|
288
|
+
res.setHeader('Retry-After', String(Math.ceil(verdict.retryAfterMs / 1000)));
|
|
289
|
+
jsonResponse(res, 429, { error: 'rate limit exceeded', retryAfterMs: verdict.retryAfterMs });
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
try {
|
|
294
|
+
// GET /health
|
|
295
|
+
if (method === 'GET' && url === '/health') {
|
|
296
|
+
jsonResponse(res, 200, { healthy: true, agents: AGENT_REGISTRY.length, product: 'testteam' });
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
// GET /agents
|
|
300
|
+
if (method === 'GET' && url === '/agents') {
|
|
301
|
+
jsonResponse(res, 200, { agents: buildAgentList() });
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
// GET /features — list persisted BDD feature keys (browse independent of a canvas).
|
|
305
|
+
if (method === 'GET' && url.split('?')[0] === '/features') {
|
|
306
|
+
jsonResponse(res, 200, { features: await featureStore.list() });
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
// GET /knowledge/system-map — the Master-Knowledge dependency graph (agents +
|
|
310
|
+
// phases, phase→agent dispatch edges) for the dashboard blast-radius view.
|
|
311
|
+
// Read-only + derived from the registry, so unauth like /agents (dashboard S2).
|
|
312
|
+
if (method === 'GET' && url.split('?')[0] === '/knowledge/system-map') {
|
|
313
|
+
jsonResponse(res, 200, buildSystemMapSnapshot());
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
// GET /security/posture — The Sentinel's security posture (score, attack
|
|
317
|
+
// paths, ranked findings) derived from the latest run's security-squad
|
|
318
|
+
// findings. Read-only + derived from persisted run artifacts, so unauth
|
|
319
|
+
// like /agents and /knowledge/system-map (dashboard S3).
|
|
320
|
+
if (method === 'GET' && url.split('?')[0] === '/security/posture') {
|
|
321
|
+
jsonResponse(res, 200, buildSecurityPostureSnapshot(runsDir));
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
// GET /compliance/posture — The Inspector's compliance posture (per-control
|
|
325
|
+
// status, gaps, drift, per-framework %) derived from the latest run's
|
|
326
|
+
// compliance-agent findings. Read-only + run-derived → unauth like the
|
|
327
|
+
// sibling posture/knowledge GETs (dashboard S4).
|
|
328
|
+
if (method === 'GET' && url.split('?')[0] === '/compliance/posture') {
|
|
329
|
+
jsonResponse(res, 200, buildCompliancePostureSnapshot(runsDir));
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
// GET /api-contract/posture — The Border Guard's runtime api-contract posture
|
|
333
|
+
// (api-squad findings #39/#41/#42, per-agent + severity rollup, blocking flag)
|
|
334
|
+
// derived from the latest run. Read-only + run-derived → unauth like the
|
|
335
|
+
// sibling posture/knowledge GETs (dashboard S5).
|
|
336
|
+
if (method === 'GET' && url.split('?')[0] === '/api-contract/posture') {
|
|
337
|
+
jsonResponse(res, 200, buildApiContractSnapshot(runsDir));
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
// GET /design/posture — The Designer's design posture (a11y hard-floor gate,
|
|
341
|
+
// usability score, responsive result, per-agent rollup) derived from the
|
|
342
|
+
// latest run's design-squad findings (#8/#67/#12/#80/#29) via the ui-ux
|
|
343
|
+
// orchestrator's pure helpers. Read-only + run-derived → unauth like the
|
|
344
|
+
// sibling posture/knowledge GETs (dashboard S6).
|
|
345
|
+
if (method === 'GET' && url.split('?')[0] === '/design/posture') {
|
|
346
|
+
jsonResponse(res, 200, buildDesignPostureSnapshot(runsDir));
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
// GET /tech-debt/posture — The Tech-Debt Tracker's posture (ROI-ranked debt
|
|
350
|
+
// inventory, per-category rollup, sequenced refactor roadmap) derived from
|
|
351
|
+
// the latest run's engine findings (#68/#69/#70/#83) via the pure
|
|
352
|
+
// runTechDebtTracker. Read-only + run-derived → unauth like the sibling
|
|
353
|
+
// posture/knowledge GETs (dashboard S7).
|
|
354
|
+
if (method === 'GET' && url.split('?')[0] === '/tech-debt/posture') {
|
|
355
|
+
jsonResponse(res, 200, buildTechDebtSnapshot(runsDir));
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
// GET /data-integrity/posture — the Data-Integrity notary's posture
|
|
359
|
+
// (layer-computed IntegritySummary + severity-ranked engine findings from
|
|
360
|
+
// #14/#43/#44/#45 via DataIntegritySession). Read-only + run-derived →
|
|
361
|
+
// unauth like the sibling posture GETs (dashboard S8).
|
|
362
|
+
if (method === 'GET' && url.split('?')[0] === '/data-integrity/posture') {
|
|
363
|
+
jsonResponse(res, 200, buildDataIntegritySnapshot(runsDir));
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
// GET /reliability/posture — the Conductor+DR+Tester cluster's posture
|
|
367
|
+
// (Tester honest verdict + DR resilience score, both agent-granularity
|
|
368
|
+
// from AgentResult.status; Conductor deferred). Read-only + run-derived →
|
|
369
|
+
// unauth like the sibling posture GETs (dashboard S9).
|
|
370
|
+
if (method === 'GET' && url.split('?')[0] === '/reliability/posture') {
|
|
371
|
+
jsonResponse(res, 200, buildReliabilityPostureSnapshot(runsDir));
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
// GET /loop-engine/cockpit — the loop-engine observatory (dashboard S10).
|
|
375
|
+
// STRUCTURAL, not run-derived: per-run loop cognition is live-only and not
|
|
376
|
+
// persisted (D-UI-13), so this surfaces the engine's real structure (7
|
|
377
|
+
// loops, statuses, breaker states) from core constants + discloses the
|
|
378
|
+
// live stream. Read-only + no run input → unauth like the sibling GETs.
|
|
379
|
+
if (method === 'GET' && url.split('?')[0] === '/loop-engine/cockpit') {
|
|
380
|
+
jsonResponse(res, 200, buildLoopEngineCockpit());
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
// GET /loop-engine/stream — LIVE loop-cognition demonstration (dashboard S11).
|
|
384
|
+
//
|
|
385
|
+
// Streams GENUINE per-cycle LoopEvents from a real kernel run on a dedicated
|
|
386
|
+
// `event: loop-event` SSE channel (decision D-UI-14). No production agent drives
|
|
387
|
+
// the kernel at runtime yet (that is Option B), so this runs the engine against a
|
|
388
|
+
// demonstration workload — the events are real kernel output, not fabricated, so
|
|
389
|
+
// the live cockpit stays honest (D-UI-12). Read-only, in-process, bounded (the demo
|
|
390
|
+
// clamps its own cycle count) and self-terminating. Unauth like the sibling GETs.
|
|
391
|
+
if (method === 'GET' && url.split('?')[0] === '/loop-engine/stream') {
|
|
392
|
+
const loopQs = url.includes('?') ? url.slice(url.indexOf('?') + 1) : '';
|
|
393
|
+
const cyclesParam = new URLSearchParams(loopQs).get('cycles');
|
|
394
|
+
const parsedCycles = cyclesParam !== null ? Number(cyclesParam) : Number.NaN;
|
|
395
|
+
const demoOpts = Number.isFinite(parsedCycles) && parsedCycles > 0 ? { cycles: parsedCycles } : {};
|
|
396
|
+
initSse(res);
|
|
397
|
+
res.writeHead(200);
|
|
398
|
+
const loopSink = new SseLoopEventSink(res);
|
|
399
|
+
try {
|
|
400
|
+
await runLoopEngineDemo((event) => loopSink.push(event), demoOpts);
|
|
401
|
+
}
|
|
402
|
+
catch (err) {
|
|
403
|
+
console.error('Loop-engine demo stream failed:', err);
|
|
404
|
+
}
|
|
405
|
+
// Terminal `loop-done` event — the client listens for it and closes, so the browser's
|
|
406
|
+
// EventSource does NOT auto-reconnect on stream-end and silently restart the demo. Guarded
|
|
407
|
+
// so a client that already disconnected is skipped (a dead socket must never throw).
|
|
408
|
+
if (res.writableEnded !== true && res.destroyed !== true) {
|
|
409
|
+
res.write('event: loop-done\ndata: {}\n\n');
|
|
410
|
+
}
|
|
411
|
+
res.end();
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
// --- Feature Canvas (Phase 1) ---
|
|
415
|
+
// GET /canvas — list persisted canvases
|
|
416
|
+
if (method === 'GET' && url.split('?')[0] === '/canvas') {
|
|
417
|
+
jsonResponse(res, 200, { canvases: await canvasStore.list() });
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
// /canvas/:id — single-canvas load (GET) / save (POST).
|
|
421
|
+
// Note: deeper paths like /canvas/:id/nodes/... are reserved for Phase 3 (run trigger).
|
|
422
|
+
if (url.split('?')[0].startsWith('/canvas/')) {
|
|
423
|
+
const segs = url.split('?')[0].split('/').filter(Boolean); // ['canvas', id, ...]
|
|
424
|
+
let id = '';
|
|
425
|
+
try {
|
|
426
|
+
id = segs[1] ? decodeURIComponent(segs[1]) : '';
|
|
427
|
+
}
|
|
428
|
+
catch {
|
|
429
|
+
jsonResponse(res, 400, { error: 'Invalid canvas id encoding' });
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
// --- Phase 4: BDD sub-routes (/canvas/:id/bdd/*) ---
|
|
433
|
+
// These must appear BEFORE the segs.length === 2 guards because they
|
|
434
|
+
// have segs.length === 4 and would never match those guards.
|
|
435
|
+
if (segs.length >= 3 && segs[2] === 'bdd') {
|
|
436
|
+
const subRoute = segs[3] ?? '';
|
|
437
|
+
// (a) POST /canvas/:id/bdd/scenarios
|
|
438
|
+
if (method === 'POST' && subRoute === 'scenarios') {
|
|
439
|
+
if (!requireConfiguredAuth(req, res, authToken))
|
|
440
|
+
return;
|
|
441
|
+
let raw;
|
|
442
|
+
try {
|
|
443
|
+
raw = await readBody(req);
|
|
444
|
+
}
|
|
445
|
+
catch (err) {
|
|
446
|
+
if (err instanceof Error && err.message === 'request body too large') {
|
|
447
|
+
jsonResponse(res, 413, { error: err.message });
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
throw err;
|
|
451
|
+
}
|
|
452
|
+
let parsed;
|
|
453
|
+
try {
|
|
454
|
+
parsed = JSON.parse(raw);
|
|
455
|
+
}
|
|
456
|
+
catch {
|
|
457
|
+
jsonResponse(res, 400, { error: 'Invalid JSON body' });
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
if (typeof parsed !== 'object' ||
|
|
461
|
+
parsed === null ||
|
|
462
|
+
typeof parsed['featureKey'] !== 'string' ||
|
|
463
|
+
typeof parsed['description'] !== 'string') {
|
|
464
|
+
jsonResponse(res, 400, { error: 'body requires featureKey (string) and description (string)' });
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
const scenariosBody = parsed;
|
|
468
|
+
const featureKey = scenariosBody['featureKey'];
|
|
469
|
+
const description = scenariosBody['description'];
|
|
470
|
+
const context = typeof scenariosBody['context'] === 'string' ? scenariosBody['context'] : undefined;
|
|
471
|
+
let safeFeatureKey;
|
|
472
|
+
try {
|
|
473
|
+
safeFeatureKey = FeatureArtifactStore.safeKey(featureKey);
|
|
474
|
+
}
|
|
475
|
+
catch (err) {
|
|
476
|
+
jsonResponse(res, 400, { error: err instanceof Error ? err.message : 'invalid featureKey' });
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
try {
|
|
480
|
+
const bddSpec = await generateBdd(llmProvider, safeFeatureKey, description, { context });
|
|
481
|
+
const now = new Date().toISOString();
|
|
482
|
+
const provenance = {
|
|
483
|
+
version: FEATURE_PROVENANCE_VERSION,
|
|
484
|
+
featureKey: safeFeatureKey,
|
|
485
|
+
bddSpec,
|
|
486
|
+
testFiles: [],
|
|
487
|
+
lastRunFindings: [],
|
|
488
|
+
lastRunFailures: [],
|
|
489
|
+
createdAt: now,
|
|
490
|
+
updatedAt: now,
|
|
491
|
+
};
|
|
492
|
+
await featureStore.writeProvenance(safeFeatureKey, provenance);
|
|
493
|
+
jsonResponse(res, 200, { featureKey: bddSpec.featureKey, scenarios: bddSpec.scenarios });
|
|
494
|
+
}
|
|
495
|
+
catch (err) {
|
|
496
|
+
if (err instanceof LLMProviderError) {
|
|
497
|
+
const status = err.kind === 'no-key' ? 503 : err.kind === 'bad-response' ? 422 : 502;
|
|
498
|
+
// Never include err.message (may contain API key or internal details)
|
|
499
|
+
console.error('[bridge] LLM error in POST /bdd/scenarios:', logSafe(err.message));
|
|
500
|
+
jsonResponse(res, status, { error: 'LLM generation failed' });
|
|
501
|
+
}
|
|
502
|
+
else if (err instanceof FeatureBddValidationError) {
|
|
503
|
+
console.error('[bridge] BDD validation error in POST /bdd/scenarios:', logSafe(err.message));
|
|
504
|
+
jsonResponse(res, 422, { error: 'BDD spec validation failed' });
|
|
505
|
+
}
|
|
506
|
+
else if (err instanceof FeatureStorePathError || err instanceof FeatureStoreValidationError) {
|
|
507
|
+
jsonResponse(res, 400, { error: err instanceof Error ? err.message : 'store error' });
|
|
508
|
+
}
|
|
509
|
+
else {
|
|
510
|
+
console.error('[bridge] Unexpected error in POST /bdd/scenarios:', logSafe(err));
|
|
511
|
+
jsonResponse(res, 500, { error: 'Internal server error' });
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
// (b) POST /canvas/:id/bdd/tests
|
|
517
|
+
if (method === 'POST' && subRoute === 'tests') {
|
|
518
|
+
if (!requireConfiguredAuth(req, res, authToken))
|
|
519
|
+
return;
|
|
520
|
+
let raw;
|
|
521
|
+
try {
|
|
522
|
+
raw = await readBody(req);
|
|
523
|
+
}
|
|
524
|
+
catch (err) {
|
|
525
|
+
if (err instanceof Error && err.message === 'request body too large') {
|
|
526
|
+
jsonResponse(res, 413, { error: err.message });
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
529
|
+
throw err;
|
|
530
|
+
}
|
|
531
|
+
let parsed;
|
|
532
|
+
try {
|
|
533
|
+
parsed = JSON.parse(raw);
|
|
534
|
+
}
|
|
535
|
+
catch {
|
|
536
|
+
jsonResponse(res, 400, { error: 'Invalid JSON body' });
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
if (typeof parsed !== 'object' ||
|
|
540
|
+
parsed === null ||
|
|
541
|
+
typeof parsed['featureKey'] !== 'string') {
|
|
542
|
+
jsonResponse(res, 400, { error: 'body requires featureKey (string)' });
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
const testsBody = parsed;
|
|
546
|
+
const featureKey = testsBody['featureKey'];
|
|
547
|
+
const framework = typeof testsBody['framework'] === 'string' ? testsBody['framework'] : 'vitest';
|
|
548
|
+
// Validate the client-supplied enum at the route boundary → 400
|
|
549
|
+
// (rather than letting it surface as 422 from a deeper validator).
|
|
550
|
+
if (!['vitest', 'jest', 'mocha'].includes(framework)) {
|
|
551
|
+
jsonResponse(res, 400, { error: 'invalid framework; allowed: vitest, jest, mocha' });
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
554
|
+
let safeFeatureKey;
|
|
555
|
+
try {
|
|
556
|
+
safeFeatureKey = FeatureArtifactStore.safeKey(featureKey);
|
|
557
|
+
}
|
|
558
|
+
catch (err) {
|
|
559
|
+
jsonResponse(res, 400, { error: err instanceof Error ? err.message : 'invalid featureKey' });
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
try {
|
|
563
|
+
const provenance = await featureStore.readProvenance(safeFeatureKey);
|
|
564
|
+
if (provenance === null) {
|
|
565
|
+
jsonResponse(res, 404, { error: `no provenance for "${safeFeatureKey}"; call /bdd/scenarios first` });
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
if (!provenance.bddSpec) {
|
|
569
|
+
jsonResponse(res, 409, { error: 'no BDD spec found; call /bdd/scenarios first' });
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
572
|
+
const generated = await generateTests(llmProvider, provenance.bddSpec, { framework });
|
|
573
|
+
const writtenFiles = [];
|
|
574
|
+
for (const f of generated.files) {
|
|
575
|
+
await featureStore.writeTestFile(safeFeatureKey, f.filename, f.content);
|
|
576
|
+
writtenFiles.push(f.filename);
|
|
577
|
+
}
|
|
578
|
+
// Update provenance with testFiles list
|
|
579
|
+
const now = new Date().toISOString();
|
|
580
|
+
const updatedProvenance = {
|
|
581
|
+
...provenance,
|
|
582
|
+
testFiles: [
|
|
583
|
+
...provenance.testFiles,
|
|
584
|
+
...generated.files.map((f) => ({
|
|
585
|
+
filename: f.filename,
|
|
586
|
+
generatedAt: now,
|
|
587
|
+
fromLoopStage: 'generate-tests',
|
|
588
|
+
})),
|
|
589
|
+
],
|
|
590
|
+
updatedAt: now,
|
|
591
|
+
};
|
|
592
|
+
await featureStore.writeProvenance(safeFeatureKey, updatedProvenance);
|
|
593
|
+
jsonResponse(res, 200, { featureKey: safeFeatureKey, files: writtenFiles });
|
|
594
|
+
}
|
|
595
|
+
catch (err) {
|
|
596
|
+
if (err instanceof LLMProviderError) {
|
|
597
|
+
const status = err.kind === 'no-key' ? 503 : err.kind === 'bad-response' ? 422 : 502;
|
|
598
|
+
console.error('[bridge] LLM error in POST /bdd/tests:', `kind=${err.kind}`, `status=${status}`);
|
|
599
|
+
jsonResponse(res, status, { error: 'LLM generation failed' });
|
|
600
|
+
}
|
|
601
|
+
else if (err instanceof FeatureBddValidationError) {
|
|
602
|
+
console.error('[bridge] BDD validation error in POST /bdd/tests:', logSafe(err.message));
|
|
603
|
+
jsonResponse(res, 422, { error: 'BDD tests validation failed' });
|
|
604
|
+
}
|
|
605
|
+
else if (err instanceof FeatureStorePathError) {
|
|
606
|
+
jsonResponse(res, 400, { error: err.message });
|
|
607
|
+
}
|
|
608
|
+
else if (err instanceof FeatureStoreValidationError) {
|
|
609
|
+
jsonResponse(res, 422, { error: err.message });
|
|
610
|
+
}
|
|
611
|
+
else {
|
|
612
|
+
console.error('[bridge] Unexpected error in POST /bdd/tests:', logSafe(err));
|
|
613
|
+
jsonResponse(res, 500, { error: 'Internal server error' });
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
return;
|
|
617
|
+
}
|
|
618
|
+
// (c) GET /canvas/:id/bdd/run?featureKey=...
|
|
619
|
+
if (method === 'GET' && subRoute === 'run') {
|
|
620
|
+
const qs = url.includes('?') ? url.slice(url.indexOf('?') + 1) : '';
|
|
621
|
+
const rawFeatureKey = new URLSearchParams(qs).get('featureKey');
|
|
622
|
+
if (!rawFeatureKey) {
|
|
623
|
+
jsonResponse(res, 400, { error: 'missing required query param: featureKey' });
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
let safeFeatureKey;
|
|
627
|
+
try {
|
|
628
|
+
safeFeatureKey = FeatureArtifactStore.safeKey(rawFeatureKey);
|
|
629
|
+
}
|
|
630
|
+
catch (err) {
|
|
631
|
+
jsonResponse(res, 400, { error: err instanceof Error ? err.message : 'invalid featureKey' });
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
634
|
+
// SSE setup — mirrors GET /runs/stream exactly
|
|
635
|
+
initSse(res);
|
|
636
|
+
res.writeHead(200);
|
|
637
|
+
const ac = new AbortController();
|
|
638
|
+
req.once('close', () => ac.abort());
|
|
639
|
+
const runId = `run-${randomUUID()}`;
|
|
640
|
+
const emitter = new RunEventEmitter(new SseRunEventSink(res));
|
|
641
|
+
const gate = new PauseGate();
|
|
642
|
+
gate.subscribe((q) => {
|
|
643
|
+
emitter.questionAsked({
|
|
644
|
+
questionId: q.id,
|
|
645
|
+
agentId: q.agentId,
|
|
646
|
+
title: q.title,
|
|
647
|
+
detail: q.detail,
|
|
648
|
+
...(q.proposedAction !== undefined ? { proposedAction: q.proposedAction } : {}),
|
|
649
|
+
});
|
|
650
|
+
});
|
|
651
|
+
ac.signal.addEventListener('abort', () => gate.cancelAll('client disconnected'));
|
|
652
|
+
runRegistry.set(runId, { gate, emitter });
|
|
653
|
+
emitter.runStarted({ runId, phase: 'alpha', scheduledAgentIds: [FEATURE_BDD_AGENT_ID] });
|
|
654
|
+
try {
|
|
655
|
+
// DoS guard (this route is unauthenticated): only spawn the vitest
|
|
656
|
+
// child when the feature actually has generated test files. Avoids
|
|
657
|
+
// a process-creation/glob DoS via repeated calls with random keys.
|
|
658
|
+
const provenance = await featureStore.readProvenance(safeFeatureKey);
|
|
659
|
+
if (!provenance || provenance.testFiles.length === 0) {
|
|
660
|
+
res.write(`: error no test files for feature\n\n`);
|
|
661
|
+
emitter.runFinished({ runId, passed: false });
|
|
662
|
+
return;
|
|
663
|
+
}
|
|
664
|
+
const runResult = await runFeatureTests(safeFeatureKey, {
|
|
665
|
+
executor: shellExecutor,
|
|
666
|
+
store: featureStore,
|
|
667
|
+
signal: ac.signal,
|
|
668
|
+
});
|
|
669
|
+
// Part A: persist failures into provenance BEFORE emitting run-finished
|
|
670
|
+
// so /bdd/fix SSE can read them after this stream closes. Routed through
|
|
671
|
+
// the store's per-key serialised recordRunFailures so concurrent runs of
|
|
672
|
+
// the same feature can't race the read-modify-write (lost failures).
|
|
673
|
+
try {
|
|
674
|
+
const lastRunFailures = runResult.failures.map((f) => ({
|
|
675
|
+
file: f.file,
|
|
676
|
+
errorText: f.errorText.slice(0, 4096),
|
|
677
|
+
...(f.scenarioId !== undefined ? { scenarioId: f.scenarioId } : {}),
|
|
678
|
+
}));
|
|
679
|
+
await featureStore.recordRunFailures(safeFeatureKey, lastRunFailures);
|
|
680
|
+
}
|
|
681
|
+
catch (persistErr) {
|
|
682
|
+
// Non-fatal: log server-side + warn the client so a later /bdd/fix
|
|
683
|
+
// reporting "no failures" isn't surprising.
|
|
684
|
+
console.error('[bridge] BDD run: failed to persist lastRunFailures:', logErrorKind(persistErr));
|
|
685
|
+
res.write(`: warning failed to persist failures for fix\n\n`);
|
|
686
|
+
}
|
|
687
|
+
emitter.runFinished({ runId, passed: runResult.passed });
|
|
688
|
+
}
|
|
689
|
+
catch (err) {
|
|
690
|
+
// The SSE channel is client-visible — keep internal error strings
|
|
691
|
+
// server-side only (mirrors the POST routes' generic-error discipline).
|
|
692
|
+
console.error('[bridge] BDD run error:', logErrorKind(err));
|
|
693
|
+
res.write(`: error internal\n\n`);
|
|
694
|
+
emitter.runFinished({ runId, passed: false });
|
|
695
|
+
}
|
|
696
|
+
finally {
|
|
697
|
+
runRegistry.delete(runId);
|
|
698
|
+
res.end();
|
|
699
|
+
}
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
702
|
+
// (d) GET /canvas/:id/bdd/fix?featureKey=... (SSE — mirrors /bdd/run)
|
|
703
|
+
//
|
|
704
|
+
// Design: unauthenticated GET SSE (mirrors /bdd/run and /runs/stream) because
|
|
705
|
+
// the real security gate is the pause-and-ask flow that requires a human to
|
|
706
|
+
// approve each finding via POST /runs/answer (which IS auth-gated). Untrusted
|
|
707
|
+
// test findings always force route='pause-and-ask', so no auto-heal can fire
|
|
708
|
+
// without explicit human approval through the authenticated answer endpoint.
|
|
709
|
+
if (method === 'GET' && subRoute === 'fix') {
|
|
710
|
+
const qs = url.includes('?') ? url.slice(url.indexOf('?') + 1) : '';
|
|
711
|
+
const rawFeatureKey = new URLSearchParams(qs).get('featureKey');
|
|
712
|
+
if (!rawFeatureKey) {
|
|
713
|
+
jsonResponse(res, 400, { error: 'missing required query param: featureKey' });
|
|
714
|
+
return;
|
|
715
|
+
}
|
|
716
|
+
let safeFeatureKey;
|
|
717
|
+
try {
|
|
718
|
+
safeFeatureKey = FeatureArtifactStore.safeKey(rawFeatureKey);
|
|
719
|
+
}
|
|
720
|
+
catch (err) {
|
|
721
|
+
jsonResponse(res, 400, { error: err instanceof Error ? err.message : 'invalid featureKey' });
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
// SSE setup — mirrors GET /bdd/run exactly
|
|
725
|
+
initSse(res);
|
|
726
|
+
res.writeHead(200);
|
|
727
|
+
const fixAc = new AbortController();
|
|
728
|
+
req.once('close', () => fixAc.abort());
|
|
729
|
+
const fixRunId = `run-${randomUUID()}`;
|
|
730
|
+
const fixEmitter = new RunEventEmitter(new SseRunEventSink(res));
|
|
731
|
+
const fixGate = new PauseGate();
|
|
732
|
+
fixGate.subscribe((q) => {
|
|
733
|
+
fixEmitter.questionAsked({
|
|
734
|
+
questionId: q.id,
|
|
735
|
+
agentId: q.agentId,
|
|
736
|
+
title: q.title,
|
|
737
|
+
detail: q.detail,
|
|
738
|
+
...(q.proposedAction !== undefined ? { proposedAction: q.proposedAction } : {}),
|
|
739
|
+
});
|
|
740
|
+
});
|
|
741
|
+
fixAc.signal.addEventListener('abort', () => fixGate.cancelAll('client disconnected'));
|
|
742
|
+
runRegistry.set(fixRunId, { gate: fixGate, emitter: fixEmitter });
|
|
743
|
+
fixEmitter.runStarted({ runId: fixRunId, phase: 'alpha', scheduledAgentIds: [FEATURE_BDD_AGENT_ID] });
|
|
744
|
+
try {
|
|
745
|
+
// Read persisted failures from provenance (written by /bdd/run Part A).
|
|
746
|
+
const fixProv = await featureStore.readProvenance(safeFeatureKey);
|
|
747
|
+
const persistedFailures = (fixProv?.lastRunFailures ?? []).map((f) => ({
|
|
748
|
+
file: f.file,
|
|
749
|
+
errorText: f.errorText,
|
|
750
|
+
...(f.scenarioId !== undefined ? { scenarioId: f.scenarioId } : {}),
|
|
751
|
+
}));
|
|
752
|
+
if (persistedFailures.length === 0) {
|
|
753
|
+
res.write(`: no failures to fix\n\n`);
|
|
754
|
+
fixEmitter.runFinished({ runId: fixRunId, passed: true });
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
757
|
+
// fixFeature routes each failure through pause-and-ask (untrusted findings
|
|
758
|
+
// always force gate.ask() — auto-heal is structurally impossible here).
|
|
759
|
+
// Questions propagate to the client via fixGate.subscribe → fixEmitter.questionAsked.
|
|
760
|
+
// Client answers via POST /runs/answer (auth-gated), which calls gate.answer().
|
|
761
|
+
await fixFeature(safeFeatureKey, persistedFailures, { gate: fixGate });
|
|
762
|
+
fixEmitter.runFinished({ runId: fixRunId, passed: true });
|
|
763
|
+
}
|
|
764
|
+
catch (err) {
|
|
765
|
+
console.error('[bridge] BDD fix error:', logErrorKind(err));
|
|
766
|
+
res.write(`: error internal\n\n`);
|
|
767
|
+
fixEmitter.runFinished({ runId: fixRunId, passed: false });
|
|
768
|
+
}
|
|
769
|
+
finally {
|
|
770
|
+
runRegistry.delete(fixRunId);
|
|
771
|
+
res.end();
|
|
772
|
+
}
|
|
773
|
+
return;
|
|
774
|
+
}
|
|
775
|
+
// Unknown BDD sub-route
|
|
776
|
+
jsonResponse(res, 404, { error: 'Not found' });
|
|
777
|
+
return;
|
|
778
|
+
}
|
|
779
|
+
// GET /canvas/:id — load + validate
|
|
780
|
+
if (method === 'GET' && segs.length === 2) {
|
|
781
|
+
try {
|
|
782
|
+
jsonResponse(res, 200, await canvasStore.load(id));
|
|
783
|
+
}
|
|
784
|
+
catch (err) {
|
|
785
|
+
if (err.code === 'ENOENT') {
|
|
786
|
+
jsonResponse(res, 404, { error: `canvas "${id}" not found` });
|
|
787
|
+
}
|
|
788
|
+
else if (err instanceof CanvasPathError) {
|
|
789
|
+
console.error('Canvas load path error:', toSafeLogMessage(err));
|
|
790
|
+
jsonResponse(res, 400, { error: 'invalid canvas path' });
|
|
791
|
+
}
|
|
792
|
+
else {
|
|
793
|
+
console.error('Canvas load failed:', toSafeLogMessage(err));
|
|
794
|
+
jsonResponse(res, 400, { error: 'invalid canvas' });
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
return;
|
|
798
|
+
}
|
|
799
|
+
// POST /canvas/:id — validate-then-save (malformed graph never reaches disk)
|
|
800
|
+
if (method === 'POST' && segs.length === 2) {
|
|
801
|
+
if (!checkAuth(req, res, authToken))
|
|
802
|
+
return;
|
|
803
|
+
let raw;
|
|
804
|
+
try {
|
|
805
|
+
raw = await readBody(req);
|
|
806
|
+
}
|
|
807
|
+
catch (err) {
|
|
808
|
+
if (err instanceof Error && err.message === 'request body too large') {
|
|
809
|
+
jsonResponse(res, 413, { error: 'request body too large' });
|
|
810
|
+
return;
|
|
811
|
+
}
|
|
812
|
+
throw err;
|
|
813
|
+
}
|
|
814
|
+
let parsed;
|
|
815
|
+
try {
|
|
816
|
+
parsed = JSON.parse(raw);
|
|
817
|
+
}
|
|
818
|
+
catch {
|
|
819
|
+
jsonResponse(res, 400, { error: 'Invalid JSON body' });
|
|
820
|
+
return;
|
|
821
|
+
}
|
|
822
|
+
try {
|
|
823
|
+
jsonResponse(res, 200, await canvasStore.save(id, parsed));
|
|
824
|
+
}
|
|
825
|
+
catch (err) {
|
|
826
|
+
if (err instanceof CanvasValidationError || err instanceof CanvasPathError) {
|
|
827
|
+
console.error('Canvas save rejected:', toSafeLogMessage(err));
|
|
828
|
+
jsonResponse(res, 400, { error: 'invalid canvas graph' });
|
|
829
|
+
}
|
|
830
|
+
else {
|
|
831
|
+
console.error('Canvas save failed:', toSafeLogMessage(err));
|
|
832
|
+
jsonResponse(res, 500, { error: 'Internal Server Error' });
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
return;
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
// GET /runs/stream — live SSE event stream for a pipeline run.
|
|
839
|
+
//
|
|
840
|
+
// Design: intentionally unauthenticated GET SSE (EventSource cannot send an
|
|
841
|
+
// Authorization header). This is the read/observe surface; every MUTATING action
|
|
842
|
+
// is auth-gated — POST /execute, POST /runs/answer, POST /canvas/:id — and the
|
|
843
|
+
// pause-and-ask flow requires a human to approve each finding via the auth-gated
|
|
844
|
+
// POST /runs/answer, so no auto-heal can fire without authenticated approval.
|
|
845
|
+
// Residual (see docs/CLEANUP_PHASE.md): this GET starts a run, so when the bridge
|
|
846
|
+
// is exposed beyond localhost a query-param/cookie token for the SSE routes should
|
|
847
|
+
// gate run-triggering. Mirrors the /bdd/run and /bdd/fix SSE rationale above.
|
|
848
|
+
if (method === 'GET' && url.split('?')[0] === '/runs/stream') {
|
|
849
|
+
// 503 when no driver is configured
|
|
850
|
+
if (!runStreamDriver) {
|
|
851
|
+
jsonResponse(res, 503, { error: 'no run driver configured' });
|
|
852
|
+
return;
|
|
853
|
+
}
|
|
854
|
+
// Parse and validate the 'phase' query param
|
|
855
|
+
const qs = url.includes('?') ? url.slice(url.indexOf('?') + 1) : '';
|
|
856
|
+
const rawPhase = new URLSearchParams(qs).get('phase') ?? 'alpha';
|
|
857
|
+
if (!VALID_PHASES.has(rawPhase)) {
|
|
858
|
+
jsonResponse(res, 400, {
|
|
859
|
+
error: `invalid phase "${rawPhase}"; must be one of: alpha, beta, uat, release, exploratory`,
|
|
860
|
+
});
|
|
861
|
+
return;
|
|
862
|
+
}
|
|
863
|
+
const phase = rawPhase;
|
|
864
|
+
// Optional `?headed=1` requests a visible run (Phase 3.2) — browsers open headed and the
|
|
865
|
+
// driver may stream frames to the Cockpit.
|
|
866
|
+
const headedParam = new URLSearchParams(qs).get('headed');
|
|
867
|
+
const headed = headedParam === '1' || headedParam === 'true';
|
|
868
|
+
// Switch the response to SSE mode (CORS headers already set above).
|
|
869
|
+
initSse(res);
|
|
870
|
+
res.writeHead(200);
|
|
871
|
+
// Wire the AbortController to the client disconnect event.
|
|
872
|
+
const ac = new AbortController();
|
|
873
|
+
req.once('close', () => ac.abort());
|
|
874
|
+
// randomUUID (not Date.now) so two runs started in the same millisecond can't collide.
|
|
875
|
+
const runId = `run-${randomUUID()}`;
|
|
876
|
+
const emitter = new RunEventEmitter(new SseRunEventSink(res));
|
|
877
|
+
// Frames stream on the SAME response as `event: frame` SSE lines (a channel distinct from
|
|
878
|
+
// run-events). The driver pushes screencast frames into this FrameStreamer; a closed/dropped
|
|
879
|
+
// socket is skipped by the sink, so a dead screencast never breaks the run.
|
|
880
|
+
const frames = new FrameStreamer(new SseFrameSink(res));
|
|
881
|
+
// Loop cognition (Option B) streams on the SAME response as `event: loop-event` lines,
|
|
882
|
+
// tagged with the emitting agent's id + name. A dropped socket is skipped by the sink, so
|
|
883
|
+
// a dead consumer never breaks the run. Bypasses the RunEventEmitter log (D-UI-14).
|
|
884
|
+
const loopSink = new SseLoopEventSink(res);
|
|
885
|
+
// Create a PauseGate and subscribe it to forward questions onto the event stream.
|
|
886
|
+
const gate = new PauseGate();
|
|
887
|
+
gate.subscribe((q) => {
|
|
888
|
+
emitter.questionAsked({
|
|
889
|
+
questionId: q.id,
|
|
890
|
+
agentId: q.agentId,
|
|
891
|
+
title: q.title,
|
|
892
|
+
detail: q.detail,
|
|
893
|
+
...(q.proposedAction !== undefined ? { proposedAction: q.proposedAction } : {}),
|
|
894
|
+
});
|
|
895
|
+
});
|
|
896
|
+
// If the client disconnects while a question is pending, cancel it so the awaiting agent
|
|
897
|
+
// unwinds, the driver returns, and the finally block cleans up (no leaked gate/socket/agent).
|
|
898
|
+
ac.signal.addEventListener('abort', () => gate.cancelAll('client disconnected'));
|
|
899
|
+
runRegistry.set(runId, { gate, emitter });
|
|
900
|
+
// Emit run-started so the client knows the runId immediately.
|
|
901
|
+
emitter.runStarted({ runId, phase, scheduledAgentIds: [] });
|
|
902
|
+
try {
|
|
903
|
+
await runStreamDriver({ phase, headed }, emitter, ac.signal, gate, frames, (agentId, agentName, event) => loopSink.pushForAgent(agentId, agentName, event));
|
|
904
|
+
emitter.runFinished({ runId, passed: true });
|
|
905
|
+
}
|
|
906
|
+
catch (err) {
|
|
907
|
+
console.error('Run stream failed:', err);
|
|
908
|
+
// Write a terminal SSE comment so the client can detect failure (the
|
|
909
|
+
// detailed error is logged server-side, never sent to the client).
|
|
910
|
+
res.write(`: error\n\n`);
|
|
911
|
+
emitter.runFinished({ runId, passed: false });
|
|
912
|
+
}
|
|
913
|
+
finally {
|
|
914
|
+
runRegistry.delete(runId);
|
|
915
|
+
res.end();
|
|
916
|
+
}
|
|
917
|
+
return;
|
|
918
|
+
}
|
|
919
|
+
// POST /runs/answer — deliver a human answer to a paused gate question
|
|
920
|
+
if (method === 'POST' && url === '/runs/answer') {
|
|
921
|
+
if (!checkAuth(req, res, authToken))
|
|
922
|
+
return;
|
|
923
|
+
let raw;
|
|
924
|
+
try {
|
|
925
|
+
raw = await readBody(req);
|
|
926
|
+
}
|
|
927
|
+
catch (err) {
|
|
928
|
+
if (err instanceof Error && err.message === 'request body too large') {
|
|
929
|
+
jsonResponse(res, 413, { error: err.message });
|
|
930
|
+
}
|
|
931
|
+
else {
|
|
932
|
+
jsonResponse(res, 400, { error: 'failed to read request body' });
|
|
933
|
+
}
|
|
934
|
+
return;
|
|
935
|
+
}
|
|
936
|
+
let parsed;
|
|
937
|
+
try {
|
|
938
|
+
parsed = JSON.parse(raw);
|
|
939
|
+
}
|
|
940
|
+
catch {
|
|
941
|
+
jsonResponse(res, 400, { error: 'Invalid JSON body' });
|
|
942
|
+
return;
|
|
943
|
+
}
|
|
944
|
+
if (typeof parsed !== 'object' ||
|
|
945
|
+
parsed === null ||
|
|
946
|
+
typeof parsed['runId'] !== 'string' ||
|
|
947
|
+
typeof parsed['questionId'] !== 'string' ||
|
|
948
|
+
!['approve', 'reject', 'modify'].includes(String(parsed['decision']))) {
|
|
949
|
+
jsonResponse(res, 400, { error: 'Invalid body: requires runId (string), questionId (string), decision ("approve"|"reject"|"modify")' });
|
|
950
|
+
return;
|
|
951
|
+
}
|
|
952
|
+
const body = parsed;
|
|
953
|
+
const runId = body['runId'];
|
|
954
|
+
const questionId = body['questionId'];
|
|
955
|
+
const decision = body['decision'];
|
|
956
|
+
const note = typeof body['note'] === 'string' ? body['note'] : undefined;
|
|
957
|
+
const entry = runRegistry.get(runId);
|
|
958
|
+
if (!entry) {
|
|
959
|
+
jsonResponse(res, 404, { error: `unknown run: ${runId}` });
|
|
960
|
+
return;
|
|
961
|
+
}
|
|
962
|
+
const resumed = entry.gate.answer(questionId, decision, note);
|
|
963
|
+
if (!resumed) {
|
|
964
|
+
jsonResponse(res, 404, { error: 'unknown question' });
|
|
965
|
+
return;
|
|
966
|
+
}
|
|
967
|
+
entry.emitter.questionAnswered({
|
|
968
|
+
questionId,
|
|
969
|
+
decision,
|
|
970
|
+
...(note !== undefined ? { note } : {}),
|
|
971
|
+
});
|
|
972
|
+
jsonResponse(res, 200, { ok: true, resumed });
|
|
973
|
+
return;
|
|
974
|
+
}
|
|
975
|
+
// GET /runs — summaries of past runs
|
|
976
|
+
if (method === 'GET' && url === '/runs') {
|
|
977
|
+
jsonResponse(res, 200, { runs: listRuns(runsDir) });
|
|
978
|
+
return;
|
|
979
|
+
}
|
|
980
|
+
// GET /runs/:id — full detail for one run
|
|
981
|
+
if (method === 'GET' && url.startsWith('/runs/')) {
|
|
982
|
+
const runId = decodeURIComponent(url.slice('/runs/'.length).split('?')[0]);
|
|
983
|
+
const detail = readRun(runsDir, runId);
|
|
984
|
+
if (!detail) {
|
|
985
|
+
jsonResponse(res, 404, { error: `Run not found: ${runId}` });
|
|
986
|
+
return;
|
|
987
|
+
}
|
|
988
|
+
jsonResponse(res, 200, detail);
|
|
989
|
+
return;
|
|
990
|
+
}
|
|
991
|
+
// POST /agents/:id/run — run ONE agent end-to-end via its real run()
|
|
992
|
+
// (the product's agent cognition), not the /execute executor primitive.
|
|
993
|
+
// Auth-gated like /execute; 503 when no runner is configured.
|
|
994
|
+
{
|
|
995
|
+
const runMatch = method === 'POST' ? url.split('?')[0].match(/^\/agents\/(\d+)\/run$/) : null;
|
|
996
|
+
if (runMatch) {
|
|
997
|
+
if (!checkAuth(req, res, authToken))
|
|
998
|
+
return;
|
|
999
|
+
if (!agentRunner) {
|
|
1000
|
+
jsonResponse(res, 503, { error: 'no agent runner configured' });
|
|
1001
|
+
return;
|
|
1002
|
+
}
|
|
1003
|
+
const agentId = Number(runMatch[1]);
|
|
1004
|
+
try {
|
|
1005
|
+
const result = await agentRunner(agentId);
|
|
1006
|
+
jsonResponse(res, 200, result);
|
|
1007
|
+
}
|
|
1008
|
+
catch (err) {
|
|
1009
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1010
|
+
if (msg.includes('not registered')) {
|
|
1011
|
+
jsonResponse(res, 404, { error: `unknown agent ${agentId}` });
|
|
1012
|
+
}
|
|
1013
|
+
else {
|
|
1014
|
+
// Log server-side; return generic (stack-trace-exposure hardening).
|
|
1015
|
+
console.error(`[bridge] agent ${agentId} run failed:`, msg);
|
|
1016
|
+
jsonResponse(res, 500, { error: 'agent run failed' });
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
return;
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
// POST /execute
|
|
1023
|
+
if (method === 'POST' && url === '/execute') {
|
|
1024
|
+
if (!checkAuth(req, res, authToken))
|
|
1025
|
+
return;
|
|
1026
|
+
let raw;
|
|
1027
|
+
try {
|
|
1028
|
+
raw = await readBody(req);
|
|
1029
|
+
}
|
|
1030
|
+
catch (err) {
|
|
1031
|
+
if (err instanceof Error && err.message === 'request body too large') {
|
|
1032
|
+
jsonResponse(res, 413, { success: false, error: err.message, durationMs: 0 });
|
|
1033
|
+
}
|
|
1034
|
+
else {
|
|
1035
|
+
jsonResponse(res, 400, { success: false, error: 'failed to read request body', durationMs: 0 });
|
|
1036
|
+
}
|
|
1037
|
+
return;
|
|
1038
|
+
}
|
|
1039
|
+
let parsed;
|
|
1040
|
+
try {
|
|
1041
|
+
parsed = JSON.parse(raw);
|
|
1042
|
+
}
|
|
1043
|
+
catch {
|
|
1044
|
+
jsonResponse(res, 400, { success: false, error: 'Invalid JSON body', durationMs: 0 });
|
|
1045
|
+
return;
|
|
1046
|
+
}
|
|
1047
|
+
if (!isValidBridgeTask(parsed)) {
|
|
1048
|
+
jsonResponse(res, 400, {
|
|
1049
|
+
success: false,
|
|
1050
|
+
error: 'Invalid BridgeTask: requires agentId (number), agentName (string), executorType, and config (object)',
|
|
1051
|
+
durationMs: 0,
|
|
1052
|
+
});
|
|
1053
|
+
return;
|
|
1054
|
+
}
|
|
1055
|
+
// Executor-specific config-shape gate: reject a structurally-wrong config
|
|
1056
|
+
// (e.g. shell with no command) with a clear 400 instead of a deep 500.
|
|
1057
|
+
const shapeErr = configShapeError(parsed);
|
|
1058
|
+
if (shapeErr) {
|
|
1059
|
+
jsonResponse(res, 400, { success: false, error: `Invalid config: ${shapeErr}`, durationMs: 0 });
|
|
1060
|
+
return;
|
|
1061
|
+
}
|
|
1062
|
+
const task = parsed;
|
|
1063
|
+
const result = await router.execute(task);
|
|
1064
|
+
jsonResponse(res, result.success ? 200 : 500, result);
|
|
1065
|
+
return;
|
|
1066
|
+
}
|
|
1067
|
+
// 404 for anything else
|
|
1068
|
+
jsonResponse(res, 404, { error: 'Not found' });
|
|
1069
|
+
}
|
|
1070
|
+
catch (error) {
|
|
1071
|
+
// Log the real error server-side; return a generic message so internal
|
|
1072
|
+
// details / stack traces are not exposed to the client (CodeQL js/stack-trace-exposure).
|
|
1073
|
+
console.error('Bridge server request failed:', toSafeLogMessage(error));
|
|
1074
|
+
jsonResponse(res, 500, { success: false, error: 'Internal server error', durationMs: 0 });
|
|
1075
|
+
}
|
|
1076
|
+
});
|
|
1077
|
+
// Periodically drop expired rate-limit entries so the keyed map can't grow
|
|
1078
|
+
// unbounded under IP churn (memory-exhaustion DoS). unref() so it never keeps the
|
|
1079
|
+
// process alive; cleared on server close so tests/short-lived servers don't leak timers.
|
|
1080
|
+
if (limiter) {
|
|
1081
|
+
const pruneTimer = setInterval(() => limiter.prune(Date.now()), 5 * 60_000);
|
|
1082
|
+
pruneTimer.unref();
|
|
1083
|
+
server.on('close', () => clearInterval(pruneTimer));
|
|
1084
|
+
}
|
|
1085
|
+
return server;
|
|
1086
|
+
}
|
|
1087
|
+
/**
|
|
1088
|
+
* Start the Bridge HTTP server on the given port.
|
|
1089
|
+
* Returns the server instance for graceful shutdown.
|
|
1090
|
+
*/
|
|
1091
|
+
export function startBridgeServer(port = 3310, options = {}) {
|
|
1092
|
+
const server = createBridgeServer({ ...options, port });
|
|
1093
|
+
server.listen(port, () => {
|
|
1094
|
+
console.log(`TestTeam Bridge running on http://localhost:${port}`);
|
|
1095
|
+
if (!options.runStreamDriver) {
|
|
1096
|
+
// Surfacing this loudly prevents the silent-503 class: without a driver the
|
|
1097
|
+
// dashboard's live-pipeline view + Screencast target a dead GET /runs/stream.
|
|
1098
|
+
console.log(' ⚠ live pipeline (GET /runs/stream) disabled — no run driver configured');
|
|
1099
|
+
}
|
|
1100
|
+
});
|
|
1101
|
+
return server;
|
|
1102
|
+
}
|
|
1103
|
+
//# sourceMappingURL=server.js.map
|