WUP (What's Up) - Intelligent file watcher for regression testing in large projects
- Metadata
- Architecture
- Interfaces
- Workflows
- Configuration
- Dependencies
- Deployment
- Environment Variables (
.env.example) - Release Management (
goal.yaml) - Code Analysis
- Source Map
- Call Graph
- Test Contracts
- Intent
- name:
wup - version:
0.2.54 - python_requires:
>=3.9 - license: Apache-2.0
- ai_model:
openrouter/qwen/qwen3-coder-next - ecosystem: SUMD + DOQL + testql + taskfile
- generated_from: pyproject.toml, Taskfile.yml, testql(4), app.doql.less, goal.yaml, .env.example, src(23 mod), project/(3 analysis files)
SUMD (description) → DOQL/source (code) → taskfile (automation) → testql (verification)
// LESS format — define @variables here as needed
app {
name: wup;
version: 0.2.54;
}
dependencies {
runtime: "watchdog>=4.0.0, psutil>=5.9.0, rich>=13.0.0, typer>=0.9.0, pyyaml>=6.0";
}
interface[type="api"] {
type: rest;
framework: fastapi;
}
interface[type="cli"] {
framework: argparse;
}
interface[type="cli"] page[name="wup"] {
}
workflow[name="wup:watch"] {
trigger: manual;
step-1: run cmd=poetry run wup watch;
}
workflow[name="wup:status"] {
trigger: manual;
step-1: run cmd=poetry run wup status;
}
workflow[name="wup:sync"] {
trigger: manual;
step-1: run cmd=poetry run wup sync-testql . --write;
}
workflow[name="wup:endpoints"] {
trigger: manual;
step-1: run cmd=poetry run wup testql-endpoints;
}
workflow[name="wup:map"] {
trigger: manual;
step-1: run cmd=poetry run wup map-deps;
}
workflow[name="test"] {
trigger: manual;
step-1: run cmd=poetry run pytest;
}
deploy {
target: docker;
}
environment[name="local"] {
runtime: docker-compose;
env_file: .env;
python_version: >=3.9;
}wup._ast_detectorwup._base_detectorwup._hash_detectorwup._yaml_detectorwup.anomaly_detectorwup.anomaly_modelswup.assistantwup.buswup.cliwup.cli_config_generatorwup.cli_scannerwup.configwup.corewup.dependency_mapperwup.event_storewup.monitoring_manifestwup.planfile_reporterwup.testql_cli_generatorwup.testql_discoverywup.testql_monitorwup.testql_watcherwup.visual_diffwup.web_client
wup
# SCENARIO: CLI Smoke Tests
# TYPE: cli
# GENERATED: true
CONFIG[2]{key, value}:
cli_command, wup
timeout_ms, 15000
# Test: wup --help
SHELL "wup --help" 5000
ASSERT_EXIT_CODE 0
ASSERT_STDOUT_CONTAINS "Usage"
# Test: wup --version
SHELL "wup version" 5000
ASSERT_EXIT_CODE 0
# SCENARIO: wup Command Tests
# TYPE: cli
# GENERATED: true
CONFIG[2]{key, value}:
cli_command, wup
timeout_ms, 30000
# Test 1: wup --help
SHELL "wup --help" 5000
ASSERT_EXIT_CODE 0
ASSERT_STDOUT_CONTAINS "Usage"
# Test 2: wup --version
SHELL "wup version" 5000
ASSERT_EXIT_CODE 0
# SCENARIO: CLI Command Tests
# TYPE: cli
# GENERATED: true
CONFIG[2]{key, value}:
cli_command, python -m wup
timeout_ms, 10000
# Test 1: CLI help command
SHELL "python -m wup --help" 5000
ASSERT_EXIT_CODE 0
ASSERT_STDOUT_CONTAINS "Usage"
# Test 2: CLI version command
SHELL "python -m wup version" 5000
ASSERT_EXIT_CODE 0
# Test 3: CLI main workflow (dry-run)
SHELL "python -m wup --help" 10000
ASSERT_EXIT_CODE 0
# SCENARIO: Auto-generated from Python Tests
# TYPE: integration
# GENERATED: true
CONFIG[2]{key, value}:
base_url, ${api_url:-http://localhost:8101}
timeout_ms, 10000
# Converted 72 assertions from pytest
ASSERT[72]{field, operator, expected}:
len(watcher.test_queue), ==, 1
test_type, ==, "quick"
service_name, ==, "users"
len(endpoints), ==, 3 # Limited by quick_tests.max_endpoints
len(watcher.changed_services), ==, 1
inferred1, ==, "users-shell"
inferred2, ==, "payments"
config.type, ==, "http+file"
config.url, ==, "http://localhost:8001"
config.file, ==, "notify.json"
watcher.config.project.name, ==, "test"
len(watcher.config.watch.paths), ==, 1
watcher.debounce_seconds, ==, 5
len(paths), ==, 2
inferred, ==, "users"
svc_config.name, ==, "users"
svc_config.quick_tests.max_endpoints, ==, 5
len(endpoints), ==, 5 # Config limit
len(watcher.changed_services), ==, 0
config.type, ==, "http+file"
config.url, ==, "http://localhost:8001"
config.file, ==, "notify.json"
result.returncode, ==, 0
result.returncode, ==, 0
result.returncode, ==, 0
result.returncode, ==, 0
result.returncode, ==, 0
result.returncode, ==, 0
result.returncode, !=, 0
result.returncode, !=, 0
result.returncode, ==, 0
result.returncode, ==, 0
result.returncode, ==, 0
result.returncode, ==, 0
result.returncode, ==, 0
result.returncode, ==, 0
len(watcher.test_queue), ==, 1
test_type, ==, "quick"
service_name, ==, "users"
len(endpoints), ==, 3 # Limited by quick_tests.max_endpoints
len(watcher.changed_services), ==, 1
inferred1, ==, "users-shell"
inferred2, ==, "payments"
config.type, ==, "http+file"
config.url, ==, "http://localhost:8001"
config.file, ==, "notify.json"
watcher.config.project.name, ==, "test"
len(watcher.config.watch.paths), ==, 1
watcher.debounce_seconds, ==, 5
len(paths), ==, 2
inferred, ==, "users"
svc_config.name, ==, "users"
svc_config.quick_tests.max_endpoints, ==, 5
len(endpoints), ==, 5 # Config limit
len(watcher.changed_services), ==, 0
config.type, ==, "http+file"
config.url, ==, "http://localhost:8001"
config.file, ==, "notify.json"
result.returncode, ==, 0
result.returncode, ==, 0
result.returncode, ==, 0
result.returncode, ==, 0
result.returncode, ==, 0
result.returncode, ==, 0
result.returncode, !=, 0
result.returncode, !=, 0
result.returncode, ==, 0
result.returncode, ==, 0
result.returncode, ==, 0
result.returncode, ==, 0
result.returncode, ==, 0
result.returncode, ==, 0
version: '3'
tasks:
wup:watch:
desc: "Watch project for file changes and run WUP regression tests"
cmds:
- poetry run wup watch
wup:status:
desc: "Show dependency map status and configuration"
cmds:
- poetry run wup status
wup:sync:
desc: "Discover monitoring targets and update wup.yaml manifest"
cmds:
- poetry run wup sync-testql . --write
wup:endpoints:
desc: "Verify TestQL scenarios and discover endpoints"
cmds:
- poetry run wup testql-endpoints
wup:map:
desc: "Build dependency map from codebase"
cmds:
- poetry run wup map-deps
test:
desc: "Run WUP pytest test suite"
cmds:
- poetry run pytestproject:
name: wup
version: 0.2.54
env: localwatchdog>=4.0.0
psutil>=5.9.0
rich>=13.0.0
typer>=0.9.0
pyyaml>=6.0
pip install wup
# development install
pip install -e .[dev]| Variable | Default | Description |
|---|---|---|
OPENROUTER_API_KEY |
*(not set)* |
Required: OpenRouter API key (https://openrouter.ai/keys) |
LLM_MODEL |
openrouter/qwen/qwen3-coder-next |
Model (default: openrouter/qwen/qwen3-coder-next) |
PFIX_AUTO_APPLY |
true |
true = apply fixes without asking |
PFIX_AUTO_INSTALL_DEPS |
true |
true = auto pip/uv install |
PFIX_AUTO_RESTART |
false |
true = os.execv restart after fix |
PFIX_MAX_RETRIES |
3 |
|
PFIX_DRY_RUN |
false |
|
PFIX_ENABLED |
true |
|
PFIX_GIT_COMMIT |
false |
true = auto-commit fixes |
PFIX_GIT_PREFIX |
pfix: |
commit message prefix |
PFIX_CREATE_BACKUPS |
false |
false = disable .pfix_backups/ directory |
- versioning:
semver - commits:
conventionalscope=wup - changelog:
keep-a-changelog - build strategies:
python,nodejs,rust - version files:
VERSION,pyproject.toml:version,wup/__init__.py:__version__
# wup | 70f 14265L | python:67,shell:2,less:1 | 2026-05-25
# stats: 231 func | 70 cls | 70 mod | CC̄=3.4 | critical:8 | cycles:0
# alerts[5]: CC main=14; CC test_service_health_transitions_are_persisted=13; CC sync_testql=13; CC _assign_by_path_prefix=13; CC _map_docker_to_wup_service=11
# hotspots[5]: status fan=35; sync_testql fan=28; main fan=19; testql_endpoints fan=19; map_deps fan=18
# evolution: baseline
# Keys: M=modules, D=details, i=imports, e=exports, c=classes, f=functions, m=methods
M[70]:
app.doql.less,63
examples/c2004_monorepo_demo.py,259
examples/ci_cd_integration.py,340
examples/fastapi-app/app/__init__.py,1
examples/fastapi-app/app/users/__init__.py,1
examples/fastapi-app/app/users/routes.py,39
examples/fastapi-app/main.py,17
examples/flask-app/app/__init__.py,1
examples/flask-app/app/auth/__init__.py,1
examples/flask-app/app/auth/routes.py,34
examples/flask-app/main.py,21
examples/multi-service/auth-service/app/auth/routes.py,14
examples/multi-service/auth-service/main.py,21
examples/multi-service/payments-service/app/payments/routes.py,19
examples/multi-service/payments-service/main.py,17
examples/multi-service/users-service/app/users/routes.py,19
examples/multi-service/users-service/main.py,17
examples/testql_demo.py,192
examples/testql_integration.py,287
examples/visual_diff_demo.py,306
examples/webhook_notifications.py,376
project.sh,49
scripts/run_probe_smoke.py,65
tests/test_auto_detection.py,195
tests/test_cli_filtering.py,266
tests/test_e2e.py,517
tests/test_health_summary_passed.py,54
tests/test_monitoring_manifest.py,73
tests/test_probe_mutex.py,39
tests/test_service_inference.py,212
tests/test_testql_monitor.py,169
tests/test_testql_watcher.py,560
tests/test_visual_diff_periodic_skip.py,41
tests/test_visual_diff_progress.py,57
tests/test_watch_exclude.py,35
tests/test_web_client.py,168
tests/test_wup.py,1819
tree.sh,2
wup/__init__.py,47
wup/_ast_detector.py,125
wup/_base_detector.py,19
wup/_hash_detector.py,73
wup/_yaml_detector.py,129
wup/anomaly_detector.py,176
wup/anomaly_models.py,36
wup/assistant.py,695
wup/bus.py,66
wup/cli.py,800
wup/cli_config_generator.py,224
wup/cli_scanner.py,303
wup/config.py,528
wup/core.py,676
wup/dependency_mapper.py,285
wup/event_store.py,42
wup/file_watcher/events/file_events.py,11
wup/models/__init__.py,35
wup/models/config.py,170
wup/monitoring_manifest.py,341
wup/planfile_reporter.py,204
wup/testing/events/health_events.py,12
wup/testing/events/test_results.py,23
wup/testing/handlers/event_handlers.py,56
wup/testing/handlers/health_handlers.py,120
wup/testing/queries/health_queries.py,8
wup/testql_cli_generator.py,216
wup/testql_discovery.py,230
wup/testql_monitor.py,522
wup/testql_watcher.py,959
wup/visual_diff.py,582
wup/web_client.py,186
D:
examples/c2004_monorepo_demo.py:
e: _discover_modules,_print_config_summary,_analyze_module,_analyze_module_structure,_test_file_inference,_print_endpoints_summary,_print_recommendations,analyze_monorepo,simulate_monorepo,main
_discover_modules(project_root)
_print_config_summary(config)
_analyze_module(module_path)
_analyze_module_structure(project_root;modules)
_test_file_inference(project_root;config)
_print_endpoints_summary(config)
_print_recommendations()
analyze_monorepo(project_path)
simulate_monorepo()
main()
examples/ci_cd_integration.py:
e: generate_github_actions,generate_gitlab_ci,show_ci_cd_demo,main
generate_github_actions()
generate_gitlab_ci()
show_ci_cd_demo()
main()
examples/fastapi-app/app/__init__.py:
examples/fastapi-app/app/users/__init__.py:
examples/fastapi-app/app/users/routes.py:
e: list_users,get_user,create_user,update_user,delete_user,User
User:
list_users()
get_user(user_id)
create_user(user)
update_user(user_id;user)
delete_user(user_id)
examples/fastapi-app/main.py:
e: root,health
root()
health()
examples/flask-app/app/__init__.py:
examples/flask-app/app/auth/__init__.py:
examples/flask-app/app/auth/routes.py:
e: login,logout,register,profile,change_password
login()
logout()
register()
profile()
change_password()
examples/flask-app/main.py:
e: root,health
root()
health()
examples/multi-service/auth-service/app/auth/routes.py:
e: login,register
login()
register()
examples/multi-service/auth-service/main.py:
e: root,health
root()
health()
examples/multi-service/payments-service/app/payments/routes.py:
e: list_payments,get_payment,create_payment
list_payments()
get_payment(payment_id)
create_payment()
examples/multi-service/payments-service/main.py:
e: root,health
root()
health()
examples/multi-service/users-service/app/users/routes.py:
e: list_users,get_user,create_user
list_users()
get_user(user_id)
create_user()
examples/multi-service/users-service/main.py:
e: root,health
root()
health()
examples/testql_demo.py:
e: _run_with_mock_services,_build_mock_services,simulate_testql_analysis,simulate_with_mock_data
_run_with_mock_services(mapper;mock_services)
_build_mock_services(mapper)
simulate_testql_analysis(testql_path)
simulate_with_mock_data()
examples/testql_integration.py:
e: main,CustomTestQLWatcher
CustomTestQLWatcher: __init__(2),run_quick_test(2),run_detail_test(2),_find_scenarios_for_service(1),_generate_blame_report(2) # Custom WUP watcher integrated with TestQL test framework.
main()
examples/visual_diff_demo.py:
e: _make_dom,_save_snapshot,demo_diff_algorithm,demo_page_slug,demo_snapshot_persistence,demo_config_yaml_round_trip,demo_disabled_is_noop,demo_live_page,main
_make_dom(n_divs)
_save_snapshot(path;dom)
demo_diff_algorithm()
demo_page_slug()
demo_snapshot_persistence()
demo_config_yaml_round_trip()
demo_disabled_is_noop()
demo_live_page(url)
main()
examples/webhook_notifications.py:
e: create_slack_payload,create_teams_payload,create_discord_payload,show_webhook_demo,main,NotificationRouter
NotificationRouter: __init__(0),add_slack(1),add_teams(1),add_discord(1),send(1) # Routes WUP events to configured notification channels.
create_slack_payload(event)
create_teams_payload(event)
create_discord_payload(event)
show_webhook_demo()
main()
scripts/run_probe_smoke.py:
e: main
main()
tests/test_auto_detection.py:
e: test_cli_scanner_detects_from_pyproject_toml,test_cli_scanner_detects_from_setup_py,test_cli_scanner_no_cli_packages,test_cli_config_generator_creates_shell_service,test_cli_config_generator_web_project_uses_default,test_auto_generate_config_detects_cli,test_auto_generate_config_web_uses_default
test_cli_scanner_detects_from_pyproject_toml()
test_cli_scanner_detects_from_setup_py()
test_cli_scanner_no_cli_packages()
test_cli_config_generator_creates_shell_service()
test_cli_config_generator_web_project_uses_default()
test_auto_generate_config_detects_cli()
test_auto_generate_config_web_uses_default()
tests/test_cli_filtering.py:
e: test_filter_scenarios_web_service_excludes_cli_scenarios,test_filter_scenarios_shell_service_only_cli_scenarios,test_filter_scenarios_auto_service_all_scenarios,test_score_scenario_cli_requires_exact_match,test_score_scenario_non_cli_uses_original_scoring,test_scenario_matches_type
test_filter_scenarios_web_service_excludes_cli_scenarios()
test_filter_scenarios_shell_service_only_cli_scenarios()
test_filter_scenarios_auto_service_all_scenarios()
test_score_scenario_cli_requires_exact_match()
test_score_scenario_non_cli_uses_original_scoring()
test_scenario_matches_type()
tests/test_e2e.py:
e: run_wup_command,TestE2ECLI,TestE2EWorkflow,TestE2EIntegration,TestE2EErrorHandling,TestE2EPerformance,TestE2EConfigScenarios
TestE2ECLI: test_cli_init_creates_config_file(0),test_cli_init_default_location(0),test_cli_map_deps_creates_dependency_file(0),test_cli_status_shows_dependency_info(0) # End-to-end tests for CLI commands.
TestE2EWorkflow: test_full_workflow_with_config(0),test_workflow_with_custom_config(0),test_workflow_with_file_type_filtering(0) # End-to-end tests for complete workflows.
TestE2EIntegration: test_integration_with_testql_scenarios(0),test_integration_with_multiple_frameworks(0) # End-to-end integration tests with external tools.
TestE2EErrorHandling: test_cli_handles_invalid_config(0),test_cli_handles_missing_project(0),test_cli_handles_empty_project(0) # End-to-end tests for error handling.
TestE2EPerformance: test_map_deps_performance_on_small_project(0),test_init_performance(0) # End-to-end tests for performance characteristics.
TestE2EConfigScenarios: test_config_with_multiple_services(0),test_config_with_service_coincidence(0) # End-to-end tests for configuration scenarios.
run_wup_command(args;cwd;timeout;capture_output;text)
tests/test_health_summary_passed.py:
e: test_health_summary_all_passed_parser,test_fleet_health_nonzero_exit_all_passed_counts_as_up
test_health_summary_all_passed_parser()
test_fleet_health_nonzero_exit_all_passed_counts_as_up()
tests/test_monitoring_manifest.py:
e: test_discover_docker_compose,test_patch_and_load_monitoring_block
test_discover_docker_compose()
test_patch_and_load_monitoring_block()
tests/test_probe_mutex.py:
e: _minimal_watcher,test_periodic_probe_skipped_when_watch_lock_held
_minimal_watcher()
test_periodic_probe_skipped_when_watch_lock_held()
tests/test_service_inference.py:
e: test_infer_service_with_empty_paths_uses_configured_services,test_infer_service_with_explicit_paths_matches_path_patterns,test_infer_service_with_auto_detection_matches_name_segments,test_infer_service_returns_none_for_unmatched_files,test_infer_service_with_duplicate_service_names,test_file_change_uses_configured_services_when_inference_fails
test_infer_service_with_empty_paths_uses_configured_services()
test_infer_service_with_explicit_paths_matches_path_patterns()
test_infer_service_with_auto_detection_matches_name_segments()
test_infer_service_returns_none_for_unmatched_files()
test_infer_service_with_duplicate_service_names()
test_file_change_uses_configured_services_when_inference_fails()
tests/test_testql_monitor.py:
e: test_parse_scenario_probes_full_url,test_firmware_plugin_health_on_8202_not_live_probe,test_connect_api_paths_on_8100_are_not_monitoring_probes,test_connect_health_on_8103_not_assigned_to_backend,test_assign_firmware_service,test_monitor_merges_config_and_service_map,test_probes_for_service_ignores_non_health_extra_paths,test_live_probe_failure_updates_health
test_parse_scenario_probes_full_url()
test_firmware_plugin_health_on_8202_not_live_probe()
test_connect_api_paths_on_8100_are_not_monitoring_probes()
test_connect_health_on_8103_not_assigned_to_backend()
test_assign_firmware_service()
test_monitor_merges_config_and_service_map()
test_probes_for_service_ignores_non_health_extra_paths()
test_live_probe_failure_updates_health()
tests/test_testql_watcher.py:
e: test_process_changed_file_creates_track_on_failure,test_browser_event_file_is_written_without_service_url,test_config_endpoints_use_base_url_from_yaml_config,test_config_endpoints_use_base_url_from_env_when_yaml_missing,test_service_health_transitions_are_persisted,test_planfile_reporter_creates_deduped_ticket,test_planfile_reporter_clears_dedupe_after_recovery,test_health_transition_creates_planfile_ticket,test_normalize_fleet_health_entry_down_to_degraded,test_fleet_health_scenario_non_strict_records_degraded_not_down,test_visual_differ_disabled_by_default,test_visual_differ_initialized_when_enabled,test_get_config_endpoints_for_service_keeps_connect_pages_on_frontend,test_quick_pass_actions_prefer_config_endpoints_for_visual_diff,test_quick_interrupt_does_not_create_failure_track
test_process_changed_file_creates_track_on_failure()
test_browser_event_file_is_written_without_service_url()
test_config_endpoints_use_base_url_from_yaml_config()
test_config_endpoints_use_base_url_from_env_when_yaml_missing()
test_service_health_transitions_are_persisted()
test_planfile_reporter_creates_deduped_ticket(monkeypatch)
test_planfile_reporter_clears_dedupe_after_recovery(monkeypatch)
test_health_transition_creates_planfile_ticket(monkeypatch)
test_normalize_fleet_health_entry_down_to_degraded()
test_fleet_health_scenario_non_strict_records_degraded_not_down()
test_visual_differ_disabled_by_default()
test_visual_differ_initialized_when_enabled()
test_get_config_endpoints_for_service_keeps_connect_pages_on_frontend()
test_quick_pass_actions_prefer_config_endpoints_for_visual_diff()
test_quick_interrupt_does_not_create_failure_track()
tests/test_visual_diff_periodic_skip.py:
e: _make_watcher,test_visual_diff_runs_on_file_change_cycles,test_visual_diff_skipped_on_periodic_probe_by_default,test_visual_diff_runs_on_periodic_probe_when_opted_in,test_visual_diff_skipped_when_disabled
_make_watcher(tmp_path)
test_visual_diff_runs_on_file_change_cycles(tmp_path)
test_visual_diff_skipped_on_periodic_probe_by_default(tmp_path)
test_visual_diff_runs_on_periodic_probe_when_opted_in(tmp_path)
test_visual_diff_skipped_when_disabled(tmp_path)
tests/test_visual_diff_progress.py:
e: _make_differ,test_progress_returned_for_big_scans,test_progress_skipped_for_small_scans,test_progress_can_be_disabled_via_env,test_progress_uses_injected_console
_make_differ(tmp_path)
test_progress_returned_for_big_scans(tmp_path;monkeypatch)
test_progress_skipped_for_small_scans(tmp_path)
test_progress_can_be_disabled_via_env(tmp_path;monkeypatch)
test_progress_uses_injected_console(tmp_path)
tests/test_watch_exclude.py:
e: _watcher,test_nested_tests_directory_ignored,test_src_file_not_ignored,test_glob_exclude_pattern
_watcher()
test_nested_tests_directory_ignored()
test_src_file_not_ignored()
test_glob_exclude_pattern()
tests/test_web_client.py:
e: _make_handler,recorder_server,test_resolve_endpoint_from_config,test_resolve_endpoint_from_env,test_resolve_endpoint_empty,test_is_active_false_when_disabled,test_is_active_false_when_no_endpoint,test_send_event_disabled_returns_false,test_send_event_posts_to_recorder,test_send_event_with_api_key,test_send_event_swallows_connection_error,test_send_regression_helper,test_send_health_transition_helper,_Recorder
_Recorder: __init__(0)
_make_handler(recorder;status)
recorder_server()
test_resolve_endpoint_from_config()
test_resolve_endpoint_from_env(monkeypatch)
test_resolve_endpoint_empty(monkeypatch)
test_is_active_false_when_disabled()
test_is_active_false_when_no_endpoint()
test_send_event_disabled_returns_false()
test_send_event_posts_to_recorder(recorder_server)
test_send_event_with_api_key(recorder_server)
test_send_event_swallows_connection_error()
test_send_regression_helper(recorder_server)
test_send_health_transition_helper(recorder_server)
tests/test_wup.py:
e: test_import,TestDependencyMapper,TestWupWatcher,TestIntegrationWorkflow,TestFileFiltering,TestConfigModels,TestVisualDiffer,TestConfigLoader,TestConfigIntegration,TestTestQLWatcherConfig
TestDependencyMapper: test_init(0),test_infer_service_from_path(0),test_build_from_codebase_empty(0),test_build_from_codebase_with_fastapi(0),test_save_and_load(0),test_infer_service_from_path_edge_cases(0),test_get_service_for_file_empty_mapper(0),test_get_endpoints_for_service_empty_mapper(0),test_build_from_codebase_with_flask(0),test_service_to_files_tracking(0),test_build_from_codebase_nonexistent_directory(0) # Tests for the DependencyMapper class.
TestWupWatcher: test_init(0),test_init_with_custom_params(0),test_infer_service(0),test_infer_service_with_auto_detection(0),test_infer_service_with_explicit_paths(0),test_infer_service_priority_config_over_mapper(0),test_infer_service_fallback_to_heuristics(0),test_should_test_cooldown(0),test_schedule_quick_test(0),test_schedule_detail_test(0),test_on_file_change_skip_dirs(0),test_detect_service_coincidences_shell_web(0),test_detect_service_coincidences_auto_type(0),test_detect_service_coincidences_no_config(0),test_detect_service_coincidences_unknown_service(0),test_services_share_domain(0),test_on_file_change_filters_by_file_type(0),test_on_file_change_no_file_type_filter(0),test_create_and_start_observer_fallback_on_enospc(0),test_create_and_start_observer_fallback_on_emfile(0),test_create_and_start_observer_reraises_other_oserror(0) # Tests for the WupWatcher class.
TestIntegrationWorkflow: test_full_workflow_file_change_to_test_scheduling(0),test_workflow_with_file_type_filtering(0),test_workflow_with_service_coincidence(0),test_workflow_with_multiple_file_changes(0),test_workflow_with_auto_detection_and_explicit_paths(0) # Integration tests for complete workflows.
TestFileFiltering: test_should_watch_file_with_config(0),test_should_watch_file_without_config(0) # Tests for file type filtering.
TestConfigModels: test_project_config(0),test_notify_config(0),test_service_test_config(0),test_service_config(0),test_watch_config(0),test_test_strategy_config(0),test_testql_config(0),test_wup_config(0),test_visual_diff_config_defaults(0),test_visual_diff_config_custom(0) # Tests for configuration dataclasses.
TestVisualDiffer: test_resolve_base_url_from_config(0),test_resolve_base_url_from_env(1),test_resolve_base_url_empty(1),test_page_slug(0),test_pages_for_service_explicit(0),test_pages_for_service_from_endpoints(0),test_looks_like_visual_page_skips_api_health_routes(0),test_pages_for_service_from_endpoints_skips_non_html_probes(0),test_pages_for_service_fallback(0),test_pages_for_service_absolute_url_passthrough(0),test_diff_snapshots_baseline(0),test_diff_snapshots_identical(0),test_diff_snapshots_changed(0),test_run_for_service_disabled_returns_empty(0),test_run_for_service_summarizes_fetch_errors(1),test_get_recent_diffs_empty(0),test_get_recent_diffs_filters_by_age(0) # Tests for the VisualDiffer class (no Playwright required).
TestConfigLoader: test_get_default_config(0),test_save_and_load_config(0),test_load_config_from_yaml(0),test_load_config_auto_detect(0),test_load_config_no_file_returns_default(0),test_load_config_invalid_yaml(0),test_load_config_missing_project_name(0),test_load_config_extra_args_normalization(0),test_save_and_load_visual_diff_config(0),test_load_config_visual_diff_from_yaml(0),test_load_config_visual_diff_defaults_when_section_absent(0),test_load_config_visual_diff_env_overrides_page_discovery(1),test_save_and_load_planfile_config(0),test_load_config_planfile_env_override(1),test_load_dotenv_sets_env_var(0),test_load_dotenv_does_not_overwrite_existing(0) # Tests for configuration loading and saving.
TestConfigIntegration: test_watcher_with_config(0),test_watcher_uses_config_debounce(0),test_watcher_build_watched_paths_from_config(0),test_watcher_infer_service_from_config(0),test_watcher_get_service_config(0),test_watcher_schedule_quick_test_uses_config_limit(0),test_watcher_on_file_change_uses_exclude_patterns(0) # Tests for configuration integration with WupWatcher.
TestTestQLWatcherConfig: test_testql_watcher_with_config(0),test_testql_watcher_uses_config_scenarios_dir(0),test_testql_watcher_get_service_config(0),test_testql_watcher_select_scenarios_uses_config_limit(0),test_testql_watcher_uses_config_timeout(0),test_testql_watcher_without_config_loads_default(0) # Tests for TestQLWatcher configuration integration.
test_import()
wup/__init__.py:
e: __getattr__
__getattr__(name)
wup/_ast_detector.py:
e: ASTDetector
ASTDetector: __init__(1),_collect_import(1),_collect_import_from(1),_collect_class(1),_collect_function(1),_extract_ast_info(1),_snapshot_path(1),_compute_changes(2),detect(1) # Detect changes in Python files using AST comparison.
wup/_base_detector.py:
e: BaseDetector
BaseDetector: __init__(2),detect(1) # Base anomaly detector.
wup/_hash_detector.py:
e: HashDetector
HashDetector: __init__(1),_compute_hash(1),_snapshot_path(1),detect(1) # Fast anomaly detection using file hashes.
wup/_yaml_detector.py:
e: YAMLStructureDetector
YAMLStructureDetector: __init__(1),_load_yaml(1),_extract_structure(3),_snapshot_path(1),_compare_structures(3),_compare_dict_structures(3),detect(1),_generate_suggestions(1) # Detect structural changes in YAML files.
wup/anomaly_detector.py:
e: quick_scan,scan_yaml_changes,AnomalyDetector
AnomalyDetector: __init__(2),_should_scan(1),scan_file(1),scan_directory(3),get_summary(1),print_report(1) # Main anomaly detector combining multiple detection methods.
quick_scan(project_root;files)
scan_yaml_changes(project_root;yaml_dir)
wup/anomaly_models.py:
e: AnomalyResult,YAMLAnomalyConfig
AnomalyResult: # Result of anomaly detection.
YAMLAnomalyConfig: # Configuration for YAML anomaly detection.
wup/assistant.py:
e: main,WupAssistant
WupAssistant: __init__(1),_dispatch_menu_choice(2),run(2),_init_project(1),_detect_framework(0),_auto_detect_services(1),_detect_service_type(2),_configure_services(0),_add_service_interactive(0),_edit_service(1),_setup_watch(0),_configure_testql(0),_setup_web_dashboard(0),_setup_visual_diff(0),_setup_anomaly_detection(0),_review_and_validate(0),_validate_config(0),_generate_suggestions(0),_save_configuration(0),_save_draft(0),_load_draft(0),_config_to_dict(1),_quick_setup(1) # Interactive configuration assistant.
main()
wup/bus.py:
e: Message,Command,Event,Query,EventBus
Message: # Base message type.
Command: # Command changes state.
Event: # Event indicates something happened.
Query: # Query requests data without changing state.
EventBus: __init__(0),subscribe(2),publish(1),execute(1),query(1) # Simple in-memory event bus and command/query dispatcher.
wup/cli.py:
e: _load_watch_config,_print_watch_header,_refresh_monitoring_manifest,_create_watcher,watch,_auto_generate_config,map_deps,status,init,testql_endpoints,map_deps,sync_testql,assistant,version,init_cli
_load_watch_config(project_path;config_path;probe_interval;mode)
_print_watch_header(wup_config;cpu_throttle;debounce;cooldown;config_path)
_refresh_monitoring_manifest(project_path;wup_config;cfg_path)
_create_watcher(mode;project_path;deps_file;cpu_throttle;debounce;cooldown;scenarios_dir;testql_bin;browser_service_url;track_dir;quick_limit;config)
watch(project;deps_file;cpu_throttle;debounce;cooldown;dashboard;mode;scenarios_dir;testql_bin;browser_service_url;track_dir;quick_limit;probe_interval;config)
_auto_generate_config(project_path;mode)
map_deps(project;output;framework;config)
status(deps_file;config;delta_seconds;failed_only;watch;interval)
init(project;output)
testql_endpoints(scenarios_dir;output;testql_bin)
map_deps(project;output;framework)
sync_testql(project;write;merge_endpoints;config)
assistant(quick;template;project)
version()
init_cli(project;output_config;output_scenarios;merge;infer_args)
wup/cli_config_generator.py:
e: CLIConfigGenerator
CLIConfigGenerator: __init__(1),generate(2),_generate_config(2),_create_shell_service(1),_save_config(2),print_summary(1) # Generate wup.yaml configuration for CLI/shell services.
wup/cli_scanner.py:
e: CLICommand,CLIPackage,CLIScanner
CLICommand: # Represents a detected CLI command.
CLIPackage: # Represents a detected CLI package.
CLIScanner: __init__(1),scan(0),_scan_setup_py(1),_scan_setup_cfg(1),_scan_pyproject_toml(1),_scan_main_modules(0),_parse_entry_points_dict(2),_add_entry_point(4),infer_command_args(1),_find_module_path(1),_get_help_arguments(1),to_dict(0) # Scanner for detecting CLI commands in a project.
wup/config.py:
e: find_config_file,_load_dotenv,load_config,_parse_project_config,_parse_watch_config,_parse_services_config,_parse_strategy_config,_normalize_testql_timeout,_parse_testql_extra_args,_normalize_testql_extra_args,_parse_testql_config,_parse_visual_diff_config,_parse_web_config,_parse_planfile_config,validate_config,get_default_config,save_config
find_config_file(project_root)
_load_dotenv(project_root)
load_config(project_root;config_path)
_parse_project_config(raw)
_parse_watch_config(raw)
_parse_services_config(raw)
_parse_strategy_config(raw)
_normalize_testql_timeout(val)
_parse_testql_extra_args(extra_args_raw)
_normalize_testql_extra_args(extra_args_raw)
_parse_testql_config(raw)
_parse_visual_diff_config(raw)
_parse_web_config(raw)
_parse_planfile_config(raw)
validate_config(raw)
get_default_config(project_root)
save_config(config;output_path)
wup/core.py:
e: WupWatcher,WupEventHandler
WupWatcher: __init__(6),_to_relative_path(1),infer_service(1),_is_coincident_pair(2),detect_service_coincidences(1),_services_share_domain(2),get_service_config(1),should_test(1),schedule_quick_test(1),schedule_detail_test(1),process_test_queue_once(0),cpu_ok(0),run_quick_test(2),run_detail_test(2),test_loop(0),should_watch_file(1),_path_matches_exclude_pattern(2),_is_file_ignored(1),_notify_all_configured_services(1),on_file_change(1),build_watched_paths(0),_create_and_start_observer(2),start_watching(1),create_status_table(0),run_with_dashboard(0) # Intelligent file watcher for regression testing.
WupEventHandler: __init__(1),on_modified(1),on_created(1),on_deleted(1) # File system event handler for WUP watcher.
wup/dependency_mapper.py:
e: DependencyMapper
DependencyMapper: __init__(1),build_from_codebase(1),_detect_framework(0),_search_codebase(1),_scan_endpoints(1),_scan_python_endpoints(1),_scan_js_endpoints(0),_infer_service(1),get_endpoints_for_file(1),get_endpoints_for_service(1),get_files_for_service(1),get_service_for_file(1),to_dict(0),save(1),load(1),build_from_testql_scenarios(2) # Maps project dependencies for intelligent testing.
wup/event_store.py:
e: EventStore
EventStore: __init__(1),append(1),read_all(0) # Append-only store for domain events.
wup/file_watcher/events/file_events.py:
e: FileChanged
FileChanged:
wup/models/__init__.py:
wup/models/config.py:
e: NotifyConfig,ServiceTestConfig,ServiceConfig,WatchConfig,TestStrategyConfig,TestQLConfig,VisualDiffConfig,WebConfig,PlanfileConfig,AnomalyDetectionConfig,ProjectConfig,WupConfig
NotifyConfig: # Notification configuration for a service.
ServiceTestConfig: # Test configuration for a service (quick or detail).
ServiceConfig: # Configuration for a single service.
WatchConfig: # Configuration for file watching.
TestStrategyConfig: # Global test strategy configuration.
TestQLConfig: # TestQL-specific configuration.
VisualDiffConfig: # Configuration for visual DOM diff after file changes.
WebConfig: # Configuration for sending events to wupbro backend.
PlanfileConfig: # Configuration for creating planfile tickets from WUP failure
AnomalyDetectionConfig: # Configuration for fast anomaly detection without Playwright.
ProjectConfig: # Project metadata.
WupConfig: # Main WUP configuration.
wup/monitoring_manifest.py:
e: _parse_port_mapping,_load_compose_yaml,_extract_healthcheck_test,_extract_service_from_spec,discover_docker_compose_services,_host_port_from_mapping,_map_docker_to_wup_service,_probe_row,_build_wup_service_dicts,_build_docker_rows,_build_scenario_rows,build_monitoring_manifest,manifest_to_yaml_block,patch_wup_yaml_monitoring,load_monitoring_manifest_from_yaml,format_manifest_summary,DockerComposeService
DockerComposeService:
_parse_port_mapping(raw)
_load_compose_yaml(compose_path)
_extract_healthcheck_test(spec)
_extract_service_from_spec(name;spec;source_file)
discover_docker_compose_services(project_root)
_host_port_from_mapping(mapping)
_map_docker_to_wup_service(docker;wup_services)
_probe_row(probe)
_build_wup_service_dicts(config)
_build_docker_rows(docker_all;wup_names;by_wup)
_build_scenario_rows(monitor;project_root;wup_names;by_wup)
build_monitoring_manifest(project_root;config)
manifest_to_yaml_block(manifest)
patch_wup_yaml_monitoring(config_path;manifest)
load_monitoring_manifest_from_yaml(config_path)
format_manifest_summary(manifest)
wup/planfile_reporter.py:
e: PlanfileReporter
PlanfileReporter: __init__(3),enabled(0),report_failure(0),clear_service_stage(0),_create_ticket(0),_wait_for_planfile_store_ready(1),_load_dedupe(0),_save_dedupe(1),_fingerprint(0),_parse_ticket_id(1),_ticket_name(0),_ticket_description(0) # Create deduplicated planfile tickets for WUP-detected failur
wup/testing/events/health_events.py:
e: ServiceHealthChanged
ServiceHealthChanged:
wup/testing/events/test_results.py:
e: ScenarioPassed,ScenarioFailed
ScenarioPassed:
ScenarioFailed:
wup/testing/handlers/event_handlers.py:
e: register_testing_event_handlers,TestResultEventHandler
TestResultEventHandler: __init__(3),handle_test_failed(1),handle_test_passed(1) # Handles test result events to update planfile reporter and w
register_testing_event_handlers(bus;planfile_reporter;web_client;console)
wup/testing/handlers/health_handlers.py:
e: register_health_handlers,ServiceHealthProjection
ServiceHealthProjection: __init__(5),_load_initial_state(0),_save_state(0),handle_health_changed(1),handle_get_health(1) # Maintains the materialized view of service health.
register_health_handlers(bus;health_state_path;event_store;planfile_reporter;browser_notifier;web_client)
wup/testing/queries/health_queries.py:
e: GetServiceHealth
GetServiceHealth:
wup/testql_cli_generator.py:
e: TestQLCLIGenerator
TestQLCLIGenerator: __init__(1),generate(2),_generate_smoke_scenario(2),_generate_command_scenario(3),generate_custom_scenario(3),print_summary(1) # Generate TestQL scenarios for CLI command testing.
wup/testql_discovery.py:
e: TestQLEndpointDiscovery
TestQLEndpointDiscovery: __init__(2),discover_scenarios(0),parse_scenario_endpoints(1),infer_service_from_scenario(1),discover_all_endpoints(0),discover_via_testql_cli(1),to_dependency_map(0) # Discover endpoints from TestQL scenario files.
wup/testql_monitor.py:
e: _parse_api_lines,parse_scenario_probes,_extract_base_url,_parse_endpoint_row,parse_service_map_probes,_connect_module_api_on_frontend_proxy,_firmware_plugin_probe_without_runtime,is_monitoring_probe,_service_path_patterns,_find_service_by_name,_find_service_by_token,_assign_by_port_8101,_assign_by_port_8202,_assign_by_port_8100,_assign_by_connect_backend,_assign_http_probe,_assign_by_longest_token,_assign_by_path_prefix,assign_probe_to_service,ProbeTarget,_ProbeAccumulator,TestQLMonitor
ProbeTarget: probe(1) # Single HTTP probe derived from TestQL scenarios or service m
_ProbeAccumulator: __init__(1),add(2) # Deduplicated probe collector for discover_probes_by_service.
TestQLMonitor: __init__(2),_service_map_paths(0),_add_config_endpoints(1),_add_scenario_probes(1),_add_service_map_probes(1),discover_probes_by_service(0),_resolve_base_url_for_service(1),_probeable_url(2),probes_for_service(2),_sort_probes_for_live(1),run_probes(2),suggested_endpoints_by_service(0),_resolve_base_url(0),_join_base(2) # Build and run live probes from TestQL scenarios + WUP config
_parse_api_lines(content;source)
parse_scenario_probes(scenario_path)
_extract_base_url(data)
_parse_endpoint_row(row;base_url;source)
parse_service_map_probes(map_path)
_connect_module_api_on_frontend_proxy(probe)
_firmware_plugin_probe_without_runtime(probe)
is_monitoring_probe(probe)
_service_path_patterns(services)
_find_service_by_name(services;name)
_find_service_by_token(services;token)
_assign_by_port_8101(services)
_assign_by_port_8202(services)
_assign_by_port_8100(services;path_lower)
_assign_by_connect_backend(services;path_lower)
_assign_http_probe(probe;services;path_lower)
_assign_by_longest_token(path_lower;services)
_assign_by_path_prefix(path_lower;services)
assign_probe_to_service(probe;services)
wup/testql_watcher.py:
e: BrowserNotifier,TestQLWatcher
BrowserNotifier: __init__(2),notify(1) # Send watcher events to browser-facing service and local file
TestQLWatcher: __init__(7),_normalize_fleet_health_entry(0),_load_service_health(0),_record_health_transition(0),_tokenize_service(1),_get_config_endpoints_for_service(1),_to_full_url_for_service(2),_resolve_base_url_for_service(1),_resolve_base_url(0),_to_full_url(1),_discover_scenarios(0),get_service_config(1),_score_scenario(2),_get_scored_scenarios(3),_get_smoke_fallback(1),_health_summary_all_passed(1),_select_scenarios_for_service(1),_filter_scenarios_by_type(2),_scenario_matches_type(2),_run_testql(2),_is_interrupted_result(1),_write_track(0),_quick_timeout(0),_merge_endpoints(2),_run_scenario_quick(3),_should_run_visual_diff(0),_quick_pass_actions(2),_quick_probe_limit(1),_quick_probe_timeout(0),_run_live_http_probes(2),_try_parse_json_summary(1),_try_find_line_summary(1),_summarize_testql_failure(1),_summarize_health_scenario_failure(1),_run_fleet_health_scenario(0),_run_quick_test_no_scenarios(2),_get_quick_scenarios(1),_run_quick_scenarios_loop(3),run_quick_test(2),_publish_visual_events(2),run_detail_test(2),process_test_queue_once(0),process_changed_file_once(1),_run_periodic_probes_once(0),_start_periodic_probe_thread(0),start_watching(1) # WUP watcher running selective TestQL scenarios for changed s
wup/visual_diff.py:
e: _playwright_available,_warn_playwright_missing,_fetch_dom_snapshot,_detect_content_issues,_page_slug,_short_url,_compact_error_message,_sample_list,_looks_like_visual_page,_snapshot_path,_load_snapshot,_save_snapshot,_node_signature,_flatten,_diff_snapshots,_resolve_base_url,VisualDiffer
VisualDiffer: __init__(2),_pages_for_service(2),_categorize_page_result(7),_print_scan_summary(4),run_for_service(2),_build_progress(2),_check_page(2),_write_diff_event(3),get_recent_diffs(1) # Triggered by TestQLWatcher after a file change.
_playwright_available()
_warn_playwright_missing()
_fetch_dom_snapshot(url;max_depth;headless;error_selectors)
_detect_content_issues(snapshot;cfg)
_page_slug(url)
_short_url(url)
_compact_error_message(message;max_len)
_sample_list(items;limit)
_looks_like_visual_page(url)
_snapshot_path(snapshot_dir;service;url)
_load_snapshot(path)
_save_snapshot(path;snapshot)
_node_signature(node;depth)
_flatten(node;depth;max_depth)
_diff_snapshots(old;new;max_depth;threshold_added;threshold_removed;threshold_changed)
_resolve_base_url(cfg)
wup/web_client.py:
e: _httpx_available,resolve_endpoint,_normalize,WebClient
WebClient: __init__(1),is_active(0),_headers(0),send_event(1),send_regression(5),send_pass(2),send_health_transition(3),send_visual_diff(3) # Async event sink for the wupbro backend.
_httpx_available()
resolve_endpoint(cfg)
_normalize(payload)
% ── Project Metadata ─────────────────────────────────────
project_metadata('wup', '0.2.54', 'python').
% ── Project Files ────────────────────────────────────────
project_file('app.doql.less', 63, 'less').
project_file('examples/c2004_monorepo_demo.py', 259, 'python').
project_file('examples/ci_cd_integration.py', 340, 'python').
project_file('examples/fastapi-app/app/__init__.py', 1, 'python').
project_file('examples/fastapi-app/app/users/__init__.py', 1, 'python').
project_file('examples/fastapi-app/app/users/routes.py', 39, 'python').
project_file('examples/fastapi-app/main.py', 17, 'python').
project_file('examples/flask-app/app/__init__.py', 1, 'python').
project_file('examples/flask-app/app/auth/__init__.py', 1, 'python').
project_file('examples/flask-app/app/auth/routes.py', 34, 'python').
project_file('examples/flask-app/main.py', 21, 'python').
project_file('examples/multi-service/auth-service/app/auth/routes.py', 14, 'python').
project_file('examples/multi-service/auth-service/main.py', 21, 'python').
project_file('examples/multi-service/payments-service/app/payments/routes.py', 19, 'python').
project_file('examples/multi-service/payments-service/main.py', 17, 'python').
project_file('examples/multi-service/users-service/app/users/routes.py', 19, 'python').
project_file('examples/multi-service/users-service/main.py', 17, 'python').
project_file('examples/testql_demo.py', 192, 'python').
project_file('examples/testql_integration.py', 287, 'python').
project_file('examples/visual_diff_demo.py', 306, 'python').
project_file('examples/webhook_notifications.py', 376, 'python').
project_file('project.sh', 49, 'shell').
project_file('scripts/run_probe_smoke.py', 65, 'python').
project_file('tests/test_auto_detection.py', 195, 'python').
project_file('tests/test_cli_filtering.py', 266, 'python').
project_file('tests/test_e2e.py', 517, 'python').
project_file('tests/test_health_summary_passed.py', 54, 'python').
project_file('tests/test_monitoring_manifest.py', 73, 'python').
project_file('tests/test_probe_mutex.py', 39, 'python').
project_file('tests/test_service_inference.py', 212, 'python').
project_file('tests/test_testql_monitor.py', 169, 'python').
project_file('tests/test_testql_watcher.py', 560, 'python').
project_file('tests/test_visual_diff_periodic_skip.py', 41, 'python').
project_file('tests/test_visual_diff_progress.py', 57, 'python').
project_file('tests/test_watch_exclude.py', 35, 'python').
project_file('tests/test_web_client.py', 168, 'python').
project_file('tests/test_wup.py', 1819, 'python').
project_file('tree.sh', 2, 'shell').
project_file('wup/__init__.py', 47, 'python').
project_file('wup/_ast_detector.py', 125, 'python').
project_file('wup/_base_detector.py', 19, 'python').
project_file('wup/_hash_detector.py', 73, 'python').
project_file('wup/_yaml_detector.py', 129, 'python').
project_file('wup/anomaly_detector.py', 176, 'python').
project_file('wup/anomaly_models.py', 36, 'python').
project_file('wup/assistant.py', 695, 'python').
project_file('wup/bus.py', 66, 'python').
project_file('wup/cli.py', 800, 'python').
project_file('wup/cli_config_generator.py', 224, 'python').
project_file('wup/cli_scanner.py', 303, 'python').
project_file('wup/config.py', 528, 'python').
project_file('wup/core.py', 676, 'python').
project_file('wup/dependency_mapper.py', 285, 'python').
project_file('wup/event_store.py', 42, 'python').
project_file('wup/file_watcher/events/file_events.py', 11, 'python').
project_file('wup/models/__init__.py', 35, 'python').
project_file('wup/models/config.py', 170, 'python').
project_file('wup/monitoring_manifest.py', 341, 'python').
project_file('wup/planfile_reporter.py', 204, 'python').
project_file('wup/testing/events/health_events.py', 12, 'python').
project_file('wup/testing/events/test_results.py', 23, 'python').
project_file('wup/testing/handlers/event_handlers.py', 56, 'python').
project_file('wup/testing/handlers/health_handlers.py', 120, 'python').
project_file('wup/testing/queries/health_queries.py', 8, 'python').
project_file('wup/testql_cli_generator.py', 216, 'python').
project_file('wup/testql_discovery.py', 230, 'python').
project_file('wup/testql_monitor.py', 522, 'python').
project_file('wup/testql_watcher.py', 959, 'python').
project_file('wup/visual_diff.py', 582, 'python').
project_file('wup/web_client.py', 186, 'python').
% ── Python Functions ─────────────────────────────────────
python_function('examples/c2004_monorepo_demo.py', '_discover_modules', 1, 5, 6).
python_function('examples/c2004_monorepo_demo.py', '_print_config_summary', 1, 3, 2).
python_function('examples/c2004_monorepo_demo.py', '_analyze_module', 1, 3, 4).
python_function('examples/c2004_monorepo_demo.py', '_analyze_module_structure', 2, 7, 6).
python_function('examples/c2004_monorepo_demo.py', '_test_file_inference', 2, 3, 4).
python_function('examples/c2004_monorepo_demo.py', '_print_endpoints_summary', 1, 5, 2).
python_function('examples/c2004_monorepo_demo.py', '_print_recommendations', 0, 1, 1).
python_function('examples/c2004_monorepo_demo.py', 'analyze_monorepo', 1, 2, 11).
python_function('examples/c2004_monorepo_demo.py', 'simulate_monorepo', 0, 2, 2).
python_function('examples/c2004_monorepo_demo.py', 'main', 0, 2, 2).
python_function('examples/ci_cd_integration.py', 'generate_github_actions', 0, 1, 4).
python_function('examples/ci_cd_integration.py', 'generate_gitlab_ci', 0, 3, 7).
python_function('examples/ci_cd_integration.py', 'show_ci_cd_demo', 0, 2, 1).
python_function('examples/ci_cd_integration.py', 'main', 0, 3, 6).
python_function('examples/fastapi-app/app/users/routes.py', 'list_users', 0, 1, 1).
python_function('examples/fastapi-app/app/users/routes.py', 'get_user', 1, 1, 1).
python_function('examples/fastapi-app/app/users/routes.py', 'create_user', 1, 1, 1).
python_function('examples/fastapi-app/app/users/routes.py', 'update_user', 2, 1, 1).
python_function('examples/fastapi-app/app/users/routes.py', 'delete_user', 1, 1, 1).
python_function('examples/fastapi-app/main.py', 'root', 0, 1, 1).
python_function('examples/fastapi-app/main.py', 'health', 0, 1, 1).
python_function('examples/flask-app/app/auth/routes.py', 'login', 0, 2, 4).
python_function('examples/flask-app/app/auth/routes.py', 'logout', 0, 1, 2).
python_function('examples/flask-app/app/auth/routes.py', 'register', 0, 2, 4).
python_function('examples/flask-app/app/auth/routes.py', 'profile', 0, 1, 2).
python_function('examples/flask-app/app/auth/routes.py', 'change_password', 0, 2, 3).
python_function('examples/flask-app/main.py', 'root', 0, 1, 1).
python_function('examples/flask-app/main.py', 'health', 0, 1, 1).
python_function('examples/multi-service/auth-service/app/auth/routes.py', 'login', 0, 1, 2).
python_function('examples/multi-service/auth-service/app/auth/routes.py', 'register', 0, 1, 2).
python_function('examples/multi-service/auth-service/main.py', 'root', 0, 1, 1).
python_function('examples/multi-service/auth-service/main.py', 'health', 0, 1, 1).
python_function('examples/multi-service/payments-service/app/payments/routes.py', 'list_payments', 0, 1, 1).
python_function('examples/multi-service/payments-service/app/payments/routes.py', 'get_payment', 1, 1, 1).
python_function('examples/multi-service/payments-service/app/payments/routes.py', 'create_payment', 0, 1, 1).
python_function('examples/multi-service/payments-service/main.py', 'root', 0, 1, 1).
python_function('examples/multi-service/payments-service/main.py', 'health', 0, 1, 1).
python_function('examples/multi-service/users-service/app/users/routes.py', 'list_users', 0, 1, 1).
python_function('examples/multi-service/users-service/app/users/routes.py', 'get_user', 1, 1, 1).
python_function('examples/multi-service/users-service/app/users/routes.py', 'create_user', 0, 1, 1).
python_function('examples/multi-service/users-service/main.py', 'root', 0, 1, 1).
python_function('examples/multi-service/users-service/main.py', 'health', 0, 1, 1).
python_function('examples/testql_demo.py', '_run_with_mock_services', 2, 6, 8).
python_function('examples/testql_demo.py', '_build_mock_services', 1, 5, 2).
python_function('examples/testql_demo.py', 'simulate_testql_analysis', 1, 2, 7).
python_function('examples/testql_demo.py', 'simulate_with_mock_data', 0, 1, 4).
python_function('examples/testql_integration.py', 'main', 0, 5, 10).
python_function('examples/visual_diff_demo.py', '_make_dom', 1, 2, 1).
python_function('examples/visual_diff_demo.py', '_save_snapshot', 2, 1, 3).
python_function('examples/visual_diff_demo.py', 'demo_diff_algorithm', 0, 3, 4).
python_function('examples/visual_diff_demo.py', 'demo_page_slug', 0, 2, 2).
python_function('examples/visual_diff_demo.py', 'demo_snapshot_persistence', 0, 3, 17).
python_function('examples/visual_diff_demo.py', 'demo_config_yaml_round_trip', 0, 6, 10).
python_function('examples/visual_diff_demo.py', 'demo_disabled_is_noop', 0, 2, 6).
python_function('examples/visual_diff_demo.py', 'demo_live_page', 1, 3, 7).
python_function('examples/visual_diff_demo.py', 'main', 0, 2, 9).
python_function('examples/webhook_notifications.py', 'create_slack_payload', 1, 6, 5).
python_function('examples/webhook_notifications.py', 'create_teams_payload', 1, 6, 2).
python_function('examples/webhook_notifications.py', 'create_discord_payload', 1, 5, 4).
python_function('examples/webhook_notifications.py', 'show_webhook_demo', 0, 4, 16).
python_function('examples/webhook_notifications.py', 'main', 0, 3, 5).
python_function('scripts/run_probe_smoke.py', 'main', 0, 14, 19).
python_function('tests/test_auto_detection.py', 'test_cli_scanner_detects_from_pyproject_toml', 0, 4, 7).
python_function('tests/test_auto_detection.py', 'test_cli_scanner_detects_from_setup_py', 0, 5, 7).
python_function('tests/test_auto_detection.py', 'test_cli_scanner_no_cli_packages', 0, 2, 7).
python_function('tests/test_auto_detection.py', 'test_cli_config_generator_creates_shell_service', 0, 5, 9).
python_function('tests/test_auto_detection.py', 'test_cli_config_generator_web_project_uses_default', 0, 4, 6).
python_function('tests/test_auto_detection.py', 'test_auto_generate_config_detects_cli', 0, 4, 7).
python_function('tests/test_auto_detection.py', 'test_auto_generate_config_web_uses_default', 0, 3, 6).
python_function('tests/test_cli_filtering.py', 'test_filter_scenarios_web_service_excludes_cli_scenarios', 0, 4, 15).
python_function('tests/test_cli_filtering.py', 'test_filter_scenarios_shell_service_only_cli_scenarios', 0, 4, 15).
python_function('tests/test_cli_filtering.py', 'test_filter_scenarios_auto_service_all_scenarios', 0, 4, 15).
python_function('tests/test_cli_filtering.py', 'test_score_scenario_cli_requires_exact_match', 0, 3, 12).
python_function('tests/test_cli_filtering.py', 'test_score_scenario_non_cli_uses_original_scoring', 0, 2, 12).
python_function('tests/test_cli_filtering.py', 'test_scenario_matches_type', 0, 6, 11).
python_function('tests/test_e2e.py', 'run_wup_command', 5, 1, 5).
python_function('tests/test_health_summary_passed.py', 'test_health_summary_all_passed_parser', 0, 3, 1).
python_function('tests/test_health_summary_passed.py', 'test_fleet_health_nonzero_exit_all_passed_counts_as_up', 0, 4, 15).
python_function('tests/test_monitoring_manifest.py', 'test_discover_docker_compose', 0, 4, 5).
python_function('tests/test_monitoring_manifest.py', 'test_patch_and_load_monitoring_block', 0, 7, 13).
python_function('tests/test_probe_mutex.py', '_minimal_watcher', 0, 1, 7).
python_function('tests/test_probe_mutex.py', 'test_periodic_probe_skipped_when_watch_lock_held', 0, 3, 7).
python_function('tests/test_service_inference.py', 'test_infer_service_with_empty_paths_uses_configured_services', 0, 2, 11).
python_function('tests/test_service_inference.py', 'test_infer_service_with_explicit_paths_matches_path_patterns', 0, 2, 11).
python_function('tests/test_service_inference.py', 'test_infer_service_with_auto_detection_matches_name_segments', 0, 2, 11).
python_function('tests/test_service_inference.py', 'test_infer_service_returns_none_for_unmatched_files', 0, 2, 11).
python_function('tests/test_service_inference.py', 'test_infer_service_with_duplicate_service_names', 0, 2, 11).
python_function('tests/test_service_inference.py', 'test_file_change_uses_configured_services_when_inference_fails', 0, 2, 12).
python_function('tests/test_testql_monitor.py', 'test_parse_scenario_probes_full_url', 0, 5, 9).
python_function('tests/test_testql_monitor.py', 'test_firmware_plugin_health_on_8202_not_live_probe', 0, 3, 2).
python_function('tests/test_testql_monitor.py', 'test_connect_api_paths_on_8100_are_not_monitoring_probes', 0, 3, 4).
python_function('tests/test_testql_monitor.py', 'test_connect_health_on_8103_not_assigned_to_backend', 0, 2, 3).
python_function('tests/test_testql_monitor.py', 'test_assign_firmware_service', 0, 2, 3).
python_function('tests/test_testql_monitor.py', 'test_monitor_merges_config_and_service_map', 0, 5, 11).
python_function('tests/test_testql_monitor.py', 'test_probes_for_service_ignores_non_health_extra_paths', 0, 3, 9).
python_function('tests/test_testql_monitor.py', 'test_live_probe_failure_updates_health', 0, 4, 15).
python_function('tests/test_testql_watcher.py', 'test_process_changed_file_creates_track_on_failure', 0, 5, 16).
python_function('tests/test_testql_watcher.py', 'test_browser_event_file_is_written_without_service_url', 0, 5, 11).
python_function('tests/test_testql_watcher.py', 'test_config_endpoints_use_base_url_from_yaml_config', 0, 3, 9).
python_function('tests/test_testql_watcher.py', 'test_config_endpoints_use_base_url_from_env_when_yaml_missing', 0, 3, 11).
python_function('tests/test_testql_watcher.py', 'test_service_health_transitions_are_persisted', 0, 13, 15).
python_function('tests/test_testql_watcher.py', 'test_planfile_reporter_creates_deduped_ticket', 1, 9, 9).
python_function('tests/test_testql_watcher.py', 'test_planfile_reporter_clears_dedupe_after_recovery', 1, 4, 10).
python_function('tests/test_testql_watcher.py', 'test_health_transition_creates_planfile_ticket', 1, 1, 13).
python_function('tests/test_testql_watcher.py', 'test_normalize_fleet_health_entry_down_to_degraded', 0, 2, 14).
python_function('tests/test_testql_watcher.py', 'test_fleet_health_scenario_non_strict_records_degraded_not_down', 0, 4, 16).
python_function('tests/test_testql_watcher.py', 'test_visual_differ_disabled_by_default', 0, 4, 10).
python_function('tests/test_testql_watcher.py', 'test_visual_differ_initialized_when_enabled', 0, 4, 9).
python_function('tests/test_testql_watcher.py', 'test_get_config_endpoints_for_service_keeps_connect_pages_on_frontend', 0, 5, 10).
python_function('tests/test_testql_watcher.py', 'test_quick_pass_actions_prefer_config_endpoints_for_visual_diff', 0, 2, 14).
python_function('tests/test_testql_watcher.py', 'test_quick_interrupt_does_not_create_failure_track', 0, 2, 17).
python_function('tests/test_visual_diff_periodic_skip.py', '_make_watcher', 1, 1, 3).
python_function('tests/test_visual_diff_periodic_skip.py', 'test_visual_diff_runs_on_file_change_cycles', 1, 2, 2).
python_function('tests/test_visual_diff_periodic_skip.py', 'test_visual_diff_skipped_on_periodic_probe_by_default', 1, 2, 2).
python_function('tests/test_visual_diff_periodic_skip.py', 'test_visual_diff_runs_on_periodic_probe_when_opted_in', 1, 2, 2).
python_function('tests/test_visual_diff_periodic_skip.py', 'test_visual_diff_skipped_when_disabled', 1, 2, 2).
python_function('tests/test_visual_diff_progress.py', '_make_differ', 1, 1, 3).
python_function('tests/test_visual_diff_progress.py', 'test_progress_returned_for_big_scans', 2, 3, 3).
python_function('tests/test_visual_diff_progress.py', 'test_progress_skipped_for_small_scans', 1, 2, 2).
python_function('tests/test_visual_diff_progress.py', 'test_progress_can_be_disabled_via_env', 2, 2, 3).
python_function('tests/test_visual_diff_progress.py', 'test_progress_uses_injected_console', 1, 3, 6).
python_function('tests/test_watch_exclude.py', '_watcher', 0, 1, 4).
python_function('tests/test_watch_exclude.py', 'test_nested_tests_directory_ignored', 0, 2, 3).
python_function('tests/test_watch_exclude.py', 'test_src_file_not_ignored', 0, 2, 3).
python_function('tests/test_watch_exclude.py', 'test_glob_exclude_pattern', 0, 2, 3).
python_function('tests/test_web_client.py', '_make_handler', 2, 1, 10).
python_function('tests/test_web_client.py', 'recorder_server', 0, 1, 7).
python_function('tests/test_web_client.py', 'test_resolve_endpoint_from_config', 0, 2, 2).
python_function('tests/test_web_client.py', 'test_resolve_endpoint_from_env', 1, 2, 3).
python_function('tests/test_web_client.py', 'test_resolve_endpoint_empty', 1, 2, 3).
python_function('tests/test_web_client.py', 'test_is_active_false_when_disabled', 0, 2, 2).
python_function('tests/test_web_client.py', 'test_is_active_false_when_no_endpoint', 0, 2, 2).
python_function('tests/test_web_client.py', 'test_send_event_disabled_returns_false', 0, 2, 4).
python_function('tests/test_web_client.py', 'test_send_event_posts_to_recorder', 1, 9, 5).
python_function('tests/test_web_client.py', 'test_send_event_with_api_key', 1, 2, 5).
python_function('tests/test_web_client.py', 'test_send_event_swallows_connection_error', 0, 2, 4).
python_function('tests/test_web_client.py', 'test_send_regression_helper', 1, 5, 4).
python_function('tests/test_web_client.py', 'test_send_health_transition_helper', 1, 5, 4).
python_function('tests/test_wup.py', 'test_import', 0, 1, 0).
python_function('wup/__init__.py', '__getattr__', 1, 2, 1).
python_function('wup/anomaly_detector.py', 'quick_scan', 2, 2, 3).
python_function('wup/anomaly_detector.py', 'scan_yaml_changes', 2, 1, 3).
python_function('wup/assistant.py', 'main', 0, 1, 5).
python_function('wup/cli.py', '_load_watch_config', 4, 4, 3).
python_function('wup/cli.py', '_print_watch_header', 5, 3, 1).
python_function('wup/cli.py', '_refresh_monitoring_manifest', 3, 3, 3).
python_function('wup/cli.py', '_create_watcher', 12, 2, 5).
python_function('wup/cli.py', 'watch', 14, 8, 17).
python_function('wup/cli.py', '_auto_generate_config', 2, 3, 9).
python_function('wup/cli.py', 'map_deps', 4, 2, 18).
python_function('wup/cli.py', 'status', 6, 5, 35).
python_function('wup/cli.py', 'init', 2, 3, 10).
python_function('wup/cli.py', 'testql_endpoints', 3, 3, 19).
python_function('wup/cli.py', 'map_deps', 3, 2, 15).
python_function('wup/cli.py', 'sync_testql', 4, 13, 28).
python_function('wup/cli.py', 'assistant', 3, 2, 11).
python_function('wup/cli.py', 'version', 0, 1, 2).
python_function('wup/cli.py', 'init_cli', 5, 8, 16).
python_function('wup/config.py', 'find_config_file', 1, 3, 1).
python_function('wup/config.py', '_load_dotenv', 1, 10, 6).
python_function('wup/config.py', 'load_config', 2, 5, 8).
python_function('wup/config.py', '_parse_project_config', 1, 2, 3).
python_function('wup/config.py', '_parse_watch_config', 1, 1, 2).
python_function('wup/config.py', '_parse_services_config', 1, 3, 5).
python_function('wup/config.py', '_parse_strategy_config', 1, 1, 2).
python_function('wup/config.py', '_normalize_testql_timeout', 1, 3, 4).
python_function('wup/config.py', '_parse_testql_extra_args', 1, 5, 5).
python_function('wup/config.py', '_normalize_testql_extra_args', 1, 5, 5).
python_function('wup/config.py', '_parse_testql_config', 1, 2, 6).
python_function('wup/config.py', '_parse_visual_diff_config', 1, 6, 7).
python_function('wup/config.py', '_parse_web_config', 1, 1, 3).
python_function('wup/config.py', '_parse_planfile_config', 1, 5, 7).
python_function('wup/config.py', 'validate_config', 1, 1, 9).
python_function('wup/config.py', 'get_default_config', 1, 1, 5).
python_function('wup/config.py', 'save_config', 2, 2, 11).
python_function('wup/monitoring_manifest.py', '_parse_port_mapping', 1, 5, 2).
python_function('wup/monitoring_manifest.py', '_load_compose_yaml', 1, 5, 4).
python_function('wup/monitoring_manifest.py', '_extract_healthcheck_test', 1, 6, 4).
python_function('wup/monitoring_manifest.py', '_extract_service_from_spec', 3, 7, 6).
python_function('wup/monitoring_manifest.py', 'discover_docker_compose_services', 1, 7, 10).
python_function('wup/monitoring_manifest.py', '_host_port_from_mapping', 1, 3, 3).
python_function('wup/monitoring_manifest.py', '_map_docker_to_wup_service', 2, 11, 4).
python_function('wup/monitoring_manifest.py', '_probe_row', 1, 2, 0).
python_function('wup/monitoring_manifest.py', '_build_wup_service_dicts', 1, 3, 2).
python_function('wup/monitoring_manifest.py', '_build_docker_rows', 3, 5, 2).
python_function('wup/monitoring_manifest.py', '_build_scenario_rows', 4, 5, 7).
python_function('wup/monitoring_manifest.py', 'build_monitoring_manifest', 2, 9, 15).
python_function('wup/monitoring_manifest.py', 'manifest_to_yaml_block', 1, 1, 2).
python_function('wup/monitoring_manifest.py', 'patch_wup_yaml_monitoring', 2, 5, 10).
python_function('wup/monitoring_manifest.py', 'load_monitoring_manifest_from_yaml', 1, 9, 8).
python_function('wup/monitoring_manifest.py', 'format_manifest_summary', 1, 10, 6).
python_function('wup/testing/handlers/event_handlers.py', 'register_testing_event_handlers', 4, 1, 2).
python_function('wup/testing/handlers/health_handlers.py', 'register_health_handlers', 6, 1, 2).
python_function('wup/testql_monitor.py', '_parse_api_lines', 2, 3, 6).
python_function('wup/testql_monitor.py', 'parse_scenario_probes', 1, 2, 3).
python_function('wup/testql_monitor.py', '_extract_base_url', 1, 4, 4).
python_function('wup/testql_monitor.py', '_parse_endpoint_row', 3, 8, 8).
python_function('wup/testql_monitor.py', 'parse_service_map_probes', 1, 6, 8).
python_function('wup/testql_monitor.py', '_connect_module_api_on_frontend_proxy', 1, 5, 4).
python_function('wup/testql_monitor.py', '_firmware_plugin_probe_without_runtime', 1, 5, 4).
python_function('wup/testql_monitor.py', 'is_monitoring_probe', 1, 9, 7).
python_function('wup/testql_monitor.py', '_service_path_patterns', 1, 6, 7).
python_function('wup/testql_monitor.py', '_find_service_by_name', 2, 3, 1).
python_function('wup/testql_monitor.py', '_find_service_by_token', 2, 3, 1).
python_function('wup/testql_monitor.py', '_assign_by_port_8101', 1, 1, 1).
python_function('wup/testql_monitor.py', '_assign_by_port_8202', 1, 1, 1).
python_function('wup/testql_monitor.py', '_assign_by_port_8100', 2, 2, 3).
python_function('wup/testql_monitor.py', '_assign_by_connect_backend', 2, 4, 3).
python_function('wup/testql_monitor.py', '_assign_http_probe', 3, 4, 5).
python_function('wup/testql_monitor.py', '_assign_by_longest_token', 2, 7, 3).
python_function('wup/testql_monitor.py', '_assign_by_path_prefix', 2, 13, 2).
python_function('wup/testql_monitor.py', 'assign_probe_to_service', 2, 5, 6).
python_function('wup/visual_diff.py', '_playwright_available', 0, 3, 0).
python_function('wup/visual_diff.py', '_warn_playwright_missing', 0, 2, 1).
python_function('wup/visual_diff.py', '_fetch_dom_snapshot', 4, 9, 14).
python_function('wup/visual_diff.py', '_detect_content_issues', 2, 6, 5).
python_function('wup/visual_diff.py', '_page_slug', 1, 2, 3).
python_function('wup/visual_diff.py', '_short_url', 1, 3, 1).
python_function('wup/visual_diff.py', '_compact_error_message', 2, 3, 3).
python_function('wup/visual_diff.py', '_sample_list', 2, 3, 2).
python_function('wup/visual_diff.py', '_looks_like_visual_page', 1, 7, 4).
python_function('wup/visual_diff.py', '_snapshot_path', 3, 1, 2).
python_function('wup/visual_diff.py', '_load_snapshot', 1, 3, 3).
python_function('wup/visual_diff.py', '_save_snapshot', 2, 1, 3).
python_function('wup/visual_diff.py', '_node_signature', 2, 3, 3).
python_function('wup/visual_diff.py', '_flatten', 3, 4, 4).
python_function('wup/visual_diff.py', '_diff_snapshots', 6, 11, 5).
python_function('wup/visual_diff.py', '_resolve_base_url', 1, 3, 2).
python_function('wup/web_client.py', '_httpx_available', 0, 4, 1).
python_function('wup/web_client.py', 'resolve_endpoint', 1, 3, 2).
python_function('wup/web_client.py', '_normalize', 1, 6, 5).
% ── Python Classes ───────────────────────────────────────
python_class('examples/fastapi-app/app/users/routes.py', 'User').
python_class('examples/testql_integration.py', 'CustomTestQLWatcher').
python_method('CustomTestQLWatcher', '__init__', 2, 2, 5).
python_method('CustomTestQLWatcher', 'run_quick_test', 2, 6, 7).
python_method('CustomTestQLWatcher', 'run_detail_test', 2, 5, 7).
python_method('CustomTestQLWatcher', '_find_scenarios_for_service', 1, 5, 6).
python_method('CustomTestQLWatcher', '_generate_blame_report', 2, 3, 5).
python_class('examples/webhook_notifications.py', 'NotificationRouter').
python_method('NotificationRouter', '__init__', 0, 1, 0).
python_method('NotificationRouter', 'add_slack', 1, 1, 0).
python_method('NotificationRouter', 'add_teams', 1, 1, 0).
python_method('NotificationRouter', 'add_discord', 1, 1, 0).
python_method('NotificationRouter', 'send', 1, 3, 4).
python_class('tests/test_e2e.py', 'TestE2ECLI').
python_method('TestE2ECLI', 'test_cli_init_creates_config_file', 0, 5, 6).
python_method('TestE2ECLI', 'test_cli_init_default_location', 0, 3, 4).
python_method('TestE2ECLI', 'test_cli_map_deps_creates_dependency_file', 0, 5, 8).
python_method('TestE2ECLI', 'test_cli_status_shows_dependency_info', 0, 1, 7).
python_class('tests/test_e2e.py', 'TestE2EWorkflow').
python_method('TestE2EWorkflow', 'test_full_workflow_with_config', 0, 3, 6).
python_method('TestE2EWorkflow', 'test_workflow_with_custom_config', 0, 3, 6).
python_method('TestE2EWorkflow', 'test_workflow_with_file_type_filtering', 0, 2, 5).
python_class('tests/test_e2e.py', 'TestE2EIntegration').
python_method('TestE2EIntegration', 'test_integration_with_testql_scenarios', 0, 3, 5).
python_method('TestE2EIntegration', 'test_integration_with_multiple_frameworks', 0, 4, 8).
python_class('tests/test_e2e.py', 'TestE2EErrorHandling').
python_method('TestE2EErrorHandling', 'test_cli_handles_invalid_config', 0, 2, 4).
python_method('TestE2EErrorHandling', 'test_cli_handles_missing_project', 0, 2, 1).
python_method('TestE2EErrorHandling', 'test_cli_handles_empty_project', 0, 4, 6).
python_class('tests/test_e2e.py', 'TestE2EPerformance').
python_method('TestE2EPerformance', 'test_map_deps_performance_on_small_project', 0, 4, 7).
python_method('TestE2EPerformance', 'test_init_performance', 0, 3, 3).
python_class('tests/test_e2e.py', 'TestE2EConfigScenarios').
python_method('TestE2EConfigScenarios', 'test_config_with_multiple_services', 0, 4, 6).
python_method('TestE2EConfigScenarios', 'test_config_with_service_coincidence', 0, 3, 5).
python_class('tests/test_web_client.py', '_Recorder').
python_method('_Recorder', '__init__', 0, 1, 0).
python_class('tests/test_wup.py', 'TestDependencyMapper').
python_method('TestDependencyMapper', 'test_init', 0, 5, 4).
python_method('TestDependencyMapper', 'test_infer_service_from_path', 0, 4, 3).
python_method('TestDependencyMapper', 'test_build_from_codebase_empty', 0, 5, 4).
python_method('TestDependencyMapper', 'test_build_from_codebase_with_fastapi', 0, 3, 7).
python_method('TestDependencyMapper', 'test_save_and_load', 0, 4, 8).
python_method('TestDependencyMapper', 'test_infer_service_from_path_edge_cases', 0, 5, 3).
python_method('TestDependencyMapper', 'test_get_service_for_file_empty_mapper', 0, 2, 5).
python_method('TestDependencyMapper', 'test_get_endpoints_for_service_empty_mapper', 0, 2, 3).
python_method('TestDependencyMapper', 'test_build_from_codebase_with_flask', 0, 3, 7).
python_method('TestDependencyMapper', 'test_service_to_files_tracking', 0, 3, 4).
python_method('TestDependencyMapper', 'test_build_from_codebase_nonexistent_directory', 0, 3, 3).
python_class('tests/test_wup.py', 'TestWupWatcher').
python_method('TestWupWatcher', 'test_init', 0, 5, 3).
python_method('TestWupWatcher', 'test_init_with_custom_params', 0, 4, 7).
python_method('TestWupWatcher', 'test_infer_service', 0, 2, 5).
python_method('TestWupWatcher', 'test_infer_service_with_auto_detection', 0, 3, 11).
python_method('TestWupWatcher', 'test_infer_service_with_explicit_paths', 0, 3, 11).
python_method('TestWupWatcher', 'test_infer_service_priority_config_over_mapper', 0, 2, 11).
python_method('TestWupWatcher', 'test_infer_service_fallback_to_heuristics', 0, 2, 10).
python_method('TestWupWatcher', 'test_should_test_cooldown', 0, 3, 4).
python_method('TestWupWatcher', 'test_schedule_quick_test', 0, 5, 4).
python_method('TestWupWatcher', 'test_schedule_detail_test', 0, 5, 4).
python_method('TestWupWatcher', 'test_on_file_change_skip_dirs', 0, 3, 6).
python_method('TestWupWatcher', 'test_detect_service_coincidences_shell_web', 0, 5, 9).
python_method('TestWupWatcher', 'test_detect_service_coincidences_auto_type', 0, 2, 9).
python_method('TestWupWatcher', 'test_detect_service_coincidences_no_config', 0, 2, 9).
python_method('TestWupWatcher', 'test_detect_service_coincidences_unknown_service', 0, 2, 10).
python_method('TestWupWatcher', 'test_services_share_domain', 0, 8, 3).
python_method('TestWupWatcher', 'test_on_file_change_filters_by_file_type', 0, 1, 11).
python_method('TestWupWatcher', 'test_on_file_change_no_file_type_filter', 0, 1, 11).
python_method('TestWupWatcher', 'test_create_and_start_observer_fallback_on_enospc', 0, 2, 7).
python_method('TestWupWatcher', 'test_create_and_start_observer_fallback_on_emfile', 0, 2, 7).
python_method('TestWupWatcher', 'test_create_and_start_observer_reraises_other_oserror', 0, 1, 7).
python_class('tests/test_wup.py', 'TestIntegrationWorkflow').
python_method('TestIntegrationWorkflow', 'test_full_workflow_file_change_to_test_scheduling', 0, 6, 14).
python_method('TestIntegrationWorkflow', 'test_workflow_with_file_type_filtering', 0, 3, 13).
python_method('TestIntegrationWorkflow', 'test_workflow_with_service_coincidence', 0, 2, 9).
python_method('TestIntegrationWorkflow', 'test_workflow_with_multiple_file_changes', 0, 4, 13).
python_method('TestIntegrationWorkflow', 'test_workflow_with_auto_detection_and_explicit_paths', 0, 3, 12).
python_class('tests/test_wup.py', 'TestFileFiltering').
python_method('TestFileFiltering', 'test_should_watch_file_with_config', 0, 7, 8).
python_method('TestFileFiltering', 'test_should_watch_file_without_config', 0, 4, 8).
python_class('tests/test_wup.py', 'TestConfigModels').
python_method('TestConfigModels', 'test_project_config', 0, 3, 1).
python_method('TestConfigModels', 'test_notify_config', 0, 4, 1).
python_method('TestConfigModels', 'test_service_test_config', 0, 3, 1).
python_method('TestConfigModels', 'test_service_config', 0, 5, 4).
python_method('TestConfigModels', 'test_watch_config', 0, 3, 2).
python_method('TestConfigModels', 'test_test_strategy_config', 0, 3, 1).
python_method('TestConfigModels', 'test_testql_config', 0, 5, 2).
python_method('TestConfigModels', 'test_wup_config', 0, 6, 8).
python_method('TestConfigModels', 'test_visual_diff_config_defaults', 0, 11, 1).
python_method('TestConfigModels', 'test_visual_diff_config_custom', 0, 5, 1).
python_class('tests/test_wup.py', 'TestVisualDiffer').
python_method('TestVisualDiffer', 'test_resolve_base_url_from_config', 0, 2, 2).
python_method('TestVisualDiffer', 'test_resolve_base_url_from_env', 1, 2, 3).
python_method('TestVisualDiffer', 'test_resolve_base_url_empty', 1, 2, 3).
python_method('TestVisualDiffer', 'test_page_slug', 0, 3, 1).
python_method('TestVisualDiffer', 'test_pages_for_service_explicit', 0, 2, 4).
python_method('TestVisualDiffer', 'test_pages_for_service_from_endpoints', 0, 3, 4).
python_method('TestVisualDiffer', 'test_looks_like_visual_page_skips_api_health_routes', 0, 4, 1).
python_method('TestVisualDiffer', 'test_pages_for_service_from_endpoints_skips_non_html_probes', 0, 4, 4).
python_method('TestVisualDiffer', 'test_pages_for_service_fallback', 0, 2, 4).
python_method('TestVisualDiffer', 'test_pages_for_service_absolute_url_passthrough', 0, 2, 4).
python_method('TestVisualDiffer', 'test_diff_snapshots_baseline', 0, 2, 1).
python_method('TestVisualDiffer', 'test_diff_snapshots_identical', 0, 4, 1).
python_method('TestVisualDiffer', 'test_diff_snapshots_changed', 0, 3, 1).
python_method('TestVisualDiffer', 'test_run_for_service_disabled_returns_empty', 0, 2, 5).
python_method('TestVisualDiffer', 'test_run_for_service_summarizes_fetch_errors', 1, 6, 9).
python_method('TestVisualDiffer', 'test_get_recent_diffs_empty', 0, 2, 4).
python_method('TestVisualDiffer', 'test_get_recent_diffs_filters_by_age', 0, 3, 10).
python_class('tests/test_wup.py', 'TestConfigLoader').
python_method('TestConfigLoader', 'test_get_default_config', 0, 5, 5).
python_method('TestConfigLoader', 'test_save_and_load_config', 0, 5, 12).
python_method('TestConfigLoader', 'test_load_config_from_yaml', 0, 9, 5).
python_method('TestConfigLoader', 'test_load_config_auto_detect', 0, 2, 4).
python_method('TestConfigLoader', 'test_load_config_no_file_returns_default', 0, 3, 4).
python_method('TestConfigLoader', 'test_load_config_invalid_yaml', 0, 1, 5).
python_method('TestConfigLoader', 'test_load_config_missing_project_name', 0, 1, 5).
python_method('TestConfigLoader', 'test_load_config_extra_args_normalization', 0, 2, 4).
python_method('TestConfigLoader', 'test_save_and_load_visual_diff_config', 0, 10, 7).
python_method('TestConfigLoader', 'test_load_config_visual_diff_from_yaml', 0, 14, 4).
python_method('TestConfigLoader', 'test_load_config_visual_diff_defaults_when_section_absent', 0, 7, 4).
python_method('TestConfigLoader', 'test_load_config_visual_diff_env_overrides_page_discovery', 1, 3, 5).
python_method('TestConfigLoader', 'test_save_and_load_planfile_config', 0, 8, 7).
python_method('TestConfigLoader', 'test_load_config_planfile_env_override', 1, 2, 5).
python_method('TestConfigLoader', 'test_load_dotenv_sets_env_var', 0, 3, 6).
python_method('TestConfigLoader', 'test_load_dotenv_does_not_overwrite_existing', 0, 2, 5).
python_class('tests/test_wup.py', 'TestConfigIntegration').
python_method('TestConfigIntegration', 'test_watcher_with_config', 0, 3, 8).
python_method('TestConfigIntegration', 'test_watcher_uses_config_debounce', 0, 2, 7).
python_method('TestConfigIntegration', 'test_watcher_build_watched_paths_from_config', 0, 4, 12).
python_method('TestConfigIntegration', 'test_watcher_infer_service_from_config', 0, 2, 11).
python_method('TestConfigIntegration', 'test_watcher_get_service_config', 0, 5, 10).
python_method('TestConfigIntegration', 'test_watcher_schedule_quick_test_uses_config_limit', 0, 3, 12).
python_method('TestConfigIntegration', 'test_watcher_on_file_change_uses_exclude_patterns', 0, 2, 12).
python_class('tests/test_wup.py', 'TestTestQLWatcherConfig').
python_method('TestTestQLWatcherConfig', 'test_testql_watcher_with_config', 0, 3, 7).
python_method('TestTestQLWatcherConfig', 'test_testql_watcher_uses_config_scenarios_dir', 0, 2, 8).
python_method('TestTestQLWatcherConfig', 'test_testql_watcher_get_service_config', 0, 4, 10).
python_method('TestTestQLWatcherConfig', 'test_testql_watcher_select_scenarios_uses_config_limit', 0, 3, 15).
python_method('TestTestQLWatcherConfig', 'test_testql_watcher_uses_config_timeout', 0, 3, 7).
python_method('TestTestQLWatcherConfig', 'test_testql_watcher_without_config_loads_default', 0, 3, 3).
python_class('wup/_ast_detector.py', 'ASTDetector').
python_method('ASTDetector', '__init__', 1, 1, 2).
python_method('ASTDetector', '_collect_import', 1, 2, 0).
python_method('ASTDetector', '_collect_import_from', 1, 3, 1).
python_method('ASTDetector', '_collect_class', 1, 5, 3).
python_method('ASTDetector', '_collect_function', 1, 1, 1).
python_method('ASTDetector', '_extract_ast_info', 1, 6, 11).
python_method('ASTDetector', '_snapshot_path', 1, 1, 2).
python_method('ASTDetector', '_compute_changes', 2, 11, 3).
python_method('ASTDetector', 'detect', 1, 6, 13).
python_class('wup/_base_detector.py', 'BaseDetector').
python_method('BaseDetector', '__init__', 2, 1, 1).
python_method('BaseDetector', 'detect', 1, 1, 0).
python_class('wup/_hash_detector.py', 'HashDetector').
python_method('HashDetector', '__init__', 1, 1, 2).
python_method('HashDetector', '_compute_hash', 1, 1, 3).
python_method('HashDetector', '_snapshot_path', 1, 1, 2).
python_method('HashDetector', 'detect', 1, 5, 9).
python_class('wup/_yaml_detector.py', 'YAMLStructureDetector').
python_method('YAMLStructureDetector', '__init__', 1, 1, 2).
python_method('YAMLStructureDetector', '_load_yaml', 1, 2, 2).
python_method('YAMLStructureDetector', '_extract_structure', 3, 6, 6).
python_method('YAMLStructureDetector', '_snapshot_path', 1, 1, 2).
python_method('YAMLStructureDetector', '_compare_structures', 3, 7, 4).
python_method('YAMLStructureDetector', '_compare_dict_structures', 3, 7, 6).
python_method('YAMLStructureDetector', 'detect', 1, 8, 14).
python_method('YAMLStructureDetector', '_generate_suggestions', 1, 6, 2).
python_class('wup/anomaly_detector.py', 'AnomalyDetector').
python_method('AnomalyDetector', '__init__', 2, 6, 6).
python_method('AnomalyDetector', '_should_scan', 1, 7, 4).
python_method('AnomalyDetector', 'scan_file', 1, 6, 7).
python_method('AnomalyDetector', 'scan_directory', 3, 6, 9).
python_method('AnomalyDetector', 'get_summary', 1, 2, 2).
python_method('AnomalyDetector', 'print_report', 1, 7, 12).
python_class('wup/anomaly_models.py', 'AnomalyResult').
python_class('wup/anomaly_models.py', 'YAMLAnomalyConfig').
python_class('wup/assistant.py', 'WupAssistant').
python_method('WupAssistant', '__init__', 1, 1, 4).
python_method('WupAssistant', '_dispatch_menu_choice', 2, 3, 3).
python_method('WupAssistant', 'run', 2, 8, 7).
python_method('WupAssistant', '_init_project', 1, 7, 7).
python_method('WupAssistant', '_detect_framework', 0, 6, 4).
python_method('WupAssistant', '_auto_detect_services', 1, 7, 8).
python_method('WupAssistant', '_detect_service_type', 2, 10, 5).
python_method('WupAssistant', '_configure_services', 0, 14, 11).
python_method('WupAssistant', '_add_service_interactive', 0, 11, 6).
python_method('WupAssistant', '_edit_service', 1, 5, 5).
python_method('WupAssistant', '_setup_watch', 0, 7, 7).
python_method('WupAssistant', '_configure_testql', 0, 3, 6).
python_method('WupAssistant', '_setup_web_dashboard', 0, 3, 3).
python_method('WupAssistant', '_setup_visual_diff', 0, 6, 4).
python_method('WupAssistant', '_setup_anomaly_detection', 0, 8, 6).
python_method('WupAssistant', '_review_and_validate', 0, 11, 7).
python_method('WupAssistant', '_validate_config', 0, 9, 3).
python_method('WupAssistant', '_generate_suggestions', 0, 6, 2).
python_method('WupAssistant', '_save_configuration', 0, 3, 10).
python_method('WupAssistant', '_save_draft', 0, 1, 4).
python_method('WupAssistant', '_load_draft', 0, 2, 4).
python_method('WupAssistant', '_config_to_dict', 1, 1, 4).
python_method('WupAssistant', '_quick_setup', 1, 4, 7).
python_class('wup/bus.py', 'Message').
python_class('wup/bus.py', 'Command').
python_class('wup/bus.py', 'Event').
python_class('wup/bus.py', 'Query').
python_class('wup/bus.py', 'EventBus').
python_method('EventBus', '__init__', 0, 1, 0).
python_method('EventBus', 'subscribe', 2, 4, 2).
python_method('EventBus', 'publish', 1, 2, 3).
python_method('EventBus', 'execute', 1, 3, 4).
python_method('EventBus', 'query', 1, 3, 4).
python_class('wup/cli_config_generator.py', 'CLIConfigGenerator').
python_method('CLIConfigGenerator', '__init__', 1, 1, 3).
python_method('CLIConfigGenerator', 'generate', 2, 4, 5).
python_method('CLIConfigGenerator', '_generate_config', 2, 6, 8).
python_method('CLIConfigGenerator', '_create_shell_service', 1, 1, 5).
python_method('CLIConfigGenerator', '_save_config', 2, 2, 4).
python_method('CLIConfigGenerator', 'print_summary', 1, 3, 6).
python_class('wup/cli_scanner.py', 'CLICommand').
python_class('wup/cli_scanner.py', 'CLIPackage').
python_class('wup/cli_scanner.py', 'CLIScanner').
python_method('CLIScanner', '__init__', 1, 1, 2).
python_method('CLIScanner', 'scan', 0, 4, 5).
python_method('CLIScanner', '_scan_setup_py', 1, 3, 4).
python_method('CLIScanner', '_scan_setup_cfg', 1, 10, 6).
python_method('CLIScanner', '_scan_pyproject_toml', 1, 6, 8).
python_method('CLIScanner', '_scan_main_modules', 0, 5, 5).
python_method('CLIScanner', '_parse_entry_points_dict', 2, 4, 4).
python_method('CLIScanner', '_add_entry_point', 4, 6, 5).
python_method('CLIScanner', 'infer_command_args', 1, 7, 7).
python_method('CLIScanner', '_find_module_path', 1, 8, 5).
python_method('CLIScanner', '_get_help_arguments', 1, 7, 8).
python_method('CLIScanner', 'to_dict', 0, 3, 0).
python_class('wup/core.py', 'WupWatcher').
python_method('WupWatcher', '__init__', 6, 1, 15).
python_method('WupWatcher', '_to_relative_path', 1, 2, 2).
python_method('WupWatcher', 'infer_service', 1, 10, 9).
python_method('WupWatcher', '_is_coincident_pair', 2, 6, 0).
python_method('WupWatcher', 'detect_service_coincidences', 1, 9, 3).
python_method('WupWatcher', '_services_share_domain', 2, 1, 3).
python_method('WupWatcher', 'get_service_config', 1, 3, 0).
python_method('WupWatcher', 'should_test', 1, 1, 2).
python_method('WupWatcher', 'schedule_quick_test', 1, 3, 4).
python_method('WupWatcher', 'schedule_detail_test', 1, 1, 2).
python_method('WupWatcher', 'process_test_queue_once', 0, 7, 6).
python_method('WupWatcher', 'cpu_ok', 0, 2, 1).
python_method('WupWatcher', 'run_quick_test', 2, 6, 5).
python_method('WupWatcher', 'run_detail_test', 2, 10, 10).
python_method('WupWatcher', 'test_loop', 0, 2, 2).
python_method('WupWatcher', 'should_watch_file', 1, 3, 4).
python_method('WupWatcher', '_path_matches_exclude_pattern', 2, 5, 4).
python_method('WupWatcher', '_is_file_ignored', 1, 11, 3).
python_method('WupWatcher', '_notify_all_configured_services', 1, 4, 4).
python_method('WupWatcher', 'on_file_change', 1, 11, 9).
python_method('WupWatcher', 'build_watched_paths', 0, 6, 6).
python_method('WupWatcher', '_create_and_start_observer', 2, 5, 6).
python_method('WupWatcher', 'start_watching', 1, 7, 11).
python_method('WupWatcher', 'create_status_table', 0, 3, 10).
python_method('WupWatcher', 'run_with_dashboard', 0, 5, 12).
python_class('wup/core.py', 'WupEventHandler').
python_method('WupEventHandler', '__init__', 1, 1, 2).
python_method('WupEventHandler', 'on_modified', 1, 2, 1).
python_method('WupEventHandler', 'on_created', 1, 2, 1).
python_method('WupEventHandler', 'on_deleted', 1, 2, 1).
python_class('wup/dependency_mapper.py', 'DependencyMapper').
python_method('DependencyMapper', '__init__', 1, 1, 2).
python_method('DependencyMapper', 'build_from_codebase', 1, 5, 7).
python_method('DependencyMapper', '_detect_framework', 0, 4, 2).
python_method('DependencyMapper', '_search_codebase', 1, 4, 2).
python_method('DependencyMapper', '_scan_endpoints', 1, 3, 3).
python_method('DependencyMapper', '_scan_python_endpoints', 1, 10, 9).
python_method('DependencyMapper', '_scan_js_endpoints', 0, 4, 7).
python_method('DependencyMapper', '_infer_service', 1, 6, 4).
python_method('DependencyMapper', 'get_endpoints_for_file', 1, 1, 4).
python_method('DependencyMapper', 'get_endpoints_for_service', 1, 1, 1).
python_method('DependencyMapper', 'get_files_for_service', 1, 1, 2).
python_method('DependencyMapper', 'get_service_for_file', 1, 3, 5).
python_method('DependencyMapper', 'to_dict', 0, 2, 5).
python_method('DependencyMapper', 'save', 1, 1, 3).
python_method('DependencyMapper', 'load', 1, 2, 6).
python_method('DependencyMapper', 'build_from_testql_scenarios', 2, 3, 7).
python_class('wup/event_store.py', 'EventStore').
python_method('EventStore', '__init__', 1, 1, 1).
python_method('EventStore', 'append', 1, 2, 8).
python_method('EventStore', 'read_all', 0, 4, 5).
python_class('wup/file_watcher/events/file_events.py', 'FileChanged').
python_class('wup/models/config.py', 'NotifyConfig').
python_class('wup/models/config.py', 'ServiceTestConfig').
python_class('wup/models/config.py', 'ServiceConfig').
python_class('wup/models/config.py', 'WatchConfig').
python_class('wup/models/config.py', 'TestStrategyConfig').
python_class('wup/models/config.py', 'TestQLConfig').
python_class('wup/models/config.py', 'VisualDiffConfig').
python_class('wup/models/config.py', 'WebConfig').
python_class('wup/models/config.py', 'PlanfileConfig').
python_class('wup/models/config.py', 'AnomalyDetectionConfig').
python_class('wup/models/config.py', 'ProjectConfig').
python_class('wup/models/config.py', 'WupConfig').
python_class('wup/monitoring_manifest.py', 'DockerComposeService').
python_class('wup/planfile_reporter.py', 'PlanfileReporter').
python_method('PlanfileReporter', '__init__', 3, 2, 2).
python_method('PlanfileReporter', 'enabled', 0, 1, 1).
python_method('PlanfileReporter', 'report_failure', 0, 4, 8).
python_method('PlanfileReporter', 'clear_service_stage', 0, 7, 6).
python_method('PlanfileReporter', '_create_ticket', 0, 13, 7).
python_method('PlanfileReporter', '_wait_for_planfile_store_ready', 1, 6, 7).
python_method('PlanfileReporter', '_load_dedupe', 0, 4, 4).
python_method('PlanfileReporter', '_save_dedupe', 1, 1, 3).
python_method('PlanfileReporter', '_fingerprint', 0, 1, 5).
python_method('PlanfileReporter', '_parse_ticket_id', 1, 2, 2).
python_method('PlanfileReporter', '_ticket_name', 0, 1, 0).
python_method('PlanfileReporter', '_ticket_description', 0, 3, 0).
python_class('wup/testing/events/health_events.py', 'ServiceHealthChanged').
python_class('wup/testing/events/test_results.py', 'ScenarioPassed').
python_class('wup/testing/events/test_results.py', 'ScenarioFailed').
python_class('wup/testing/handlers/event_handlers.py', 'TestResultEventHandler').
python_method('TestResultEventHandler', '__init__', 3, 1, 0).
python_method('TestResultEventHandler', 'handle_test_failed', 1, 5, 8).
python_method('TestResultEventHandler', 'handle_test_passed', 1, 1, 0).
python_class('wup/testing/handlers/health_handlers.py', 'ServiceHealthProjection').
python_method('ServiceHealthProjection', '__init__', 5, 1, 1).
python_method('ServiceHealthProjection', '_load_initial_state', 0, 3, 3).
python_method('ServiceHealthProjection', '_save_state', 0, 1, 3).
python_method('ServiceHealthProjection', 'handle_health_changed', 1, 6, 9).
python_method('ServiceHealthProjection', 'handle_get_health', 1, 2, 1).
python_class('wup/testing/queries/health_queries.py', 'GetServiceHealth').
python_class('wup/testql_cli_generator.py', 'TestQLCLIGenerator').
python_method('TestQLCLIGenerator', '__init__', 1, 1, 3).
python_method('TestQLCLIGenerator', 'generate', 2, 6, 7).
python_method('TestQLCLIGenerator', '_generate_smoke_scenario', 2, 5, 3).
python_method('TestQLCLIGenerator', '_generate_command_scenario', 3, 4, 5).
python_method('TestQLCLIGenerator', 'generate_custom_scenario', 3, 3, 5).
python_method('TestQLCLIGenerator', 'print_summary', 1, 4, 5).
python_class('wup/testql_discovery.py', 'TestQLEndpointDiscovery').
python_method('TestQLEndpointDiscovery', '__init__', 2, 1, 1).
python_method('TestQLEndpointDiscovery', 'discover_scenarios', 0, 2, 3).
python_method('TestQLEndpointDiscovery', 'parse_scenario_endpoints', 1, 11, 12).
python_method('TestQLEndpointDiscovery', 'infer_service_from_scenario', 1, 4, 2).
python_method('TestQLEndpointDiscovery', 'discover_all_endpoints', 0, 6, 9).
python_method('TestQLEndpointDiscovery', 'discover_via_testql_cli', 1, 8, 6).
python_method('TestQLEndpointDiscovery', 'to_dependency_map', 0, 4, 3).
python_class('wup/testql_monitor.py', 'ProbeTarget').
python_method('ProbeTarget', 'probe', 1, 5, 4).
python_class('wup/testql_monitor.py', '_ProbeAccumulator').
python_method('_ProbeAccumulator', '__init__', 1, 2, 1).
python_method('_ProbeAccumulator', 'add', 2, 3, 3).
python_class('wup/testql_monitor.py', 'TestQLMonitor').
python_method('TestQLMonitor', '__init__', 2, 2, 2).
python_method('TestQLMonitor', '_service_map_paths', 0, 3, 3).
python_method('TestQLMonitor', '_add_config_endpoints', 1, 11, 7).
python_method('TestQLMonitor', '_add_scenario_probes', 1, 5, 5).
python_method('TestQLMonitor', '_add_service_map_probes', 1, 5, 5).
python_method('TestQLMonitor', 'discover_probes_by_service', 0, 2, 4).
python_method('TestQLMonitor', '_resolve_base_url_for_service', 1, 8, 7).
python_method('TestQLMonitor', '_probeable_url', 2, 4, 2).
python_method('TestQLMonitor', 'probes_for_service', 2, 9, 10).
python_method('TestQLMonitor', '_sort_probes_for_live', 1, 1, 2).
python_method('TestQLMonitor', 'run_probes', 2, 5, 4).
python_method('TestQLMonitor', 'suggested_endpoints_by_service', 0, 5, 6).
python_method('TestQLMonitor', '_resolve_base_url', 0, 4, 3).
python_method('TestQLMonitor', '_join_base', 2, 5, 1).
python_class('wup/testql_watcher.py', 'BrowserNotifier').
python_method('BrowserNotifier', '__init__', 2, 13, 1).
python_method('BrowserNotifier', 'notify', 1, 3, 8).
python_class('wup/testql_watcher.py', 'TestQLWatcher').
python_method('TestQLWatcher', '__init__', 7, 13, 15).
python_method('TestQLWatcher', '_normalize_fleet_health_entry', 0, 7, 9).
python_method('TestQLWatcher', '_load_service_health', 0, 1, 0).
python_method('TestQLWatcher', '_record_health_transition', 0, 6, 5).
python_method('TestQLWatcher', '_tokenize_service', 1, 3, 3).
python_method('TestQLWatcher', '_get_config_endpoints_for_service', 1, 10, 5).
python_method('TestQLWatcher', '_to_full_url_for_service', 2, 5, 2).
python_method('TestQLWatcher', '_resolve_base_url_for_service', 1, 8, 7).
python_method('TestQLWatcher', '_resolve_base_url', 0, 5, 3).
python_method('TestQLWatcher', '_to_full_url', 1, 5, 2).
python_method('TestQLWatcher', '_discover_scenarios', 0, 2, 3).
python_method('TestQLWatcher', 'get_service_config', 1, 3, 0).
python_method('TestQLWatcher', '_score_scenario', 2, 10, 4).
python_method('TestQLWatcher', '_get_scored_scenarios', 3, 4, 2).
python_method('TestQLWatcher', '_get_smoke_fallback', 1, 6, 3).
python_method('TestQLWatcher', '_health_summary_all_passed', 1, 5, 4).
python_method('TestQLWatcher', '_select_scenarios_for_service', 1, 10, 7).
python_method('TestQLWatcher', '_filter_scenarios_by_type', 2, 8, 1).
python_method('TestQLWatcher', '_scenario_matches_type', 2, 4, 1).
python_method('TestQLWatcher', '_run_testql', 2, 4, 3).
python_method('TestQLWatcher', '_is_interrupted_result', 1, 4, 1).
python_method('TestQLWatcher', '_write_track', 0, 13, 10).
python_method('TestQLWatcher', '_quick_timeout', 0, 3, 1).
python_method('TestQLWatcher', '_merge_endpoints', 2, 3, 3).
python_method('TestQLWatcher', '_run_scenario_quick', 3, 3, 9).
python_method('TestQLWatcher', '_should_run_visual_diff', 0, 4, 2).
python_method('TestQLWatcher', '_quick_pass_actions', 2, 10, 9).
python_method('TestQLWatcher', '_quick_probe_limit', 1, 3, 1).
python_method('TestQLWatcher', '_quick_probe_timeout', 0, 3, 2).
python_method('TestQLWatcher', '_run_live_http_probes', 2, 6, 7).
python_method('TestQLWatcher', '_try_parse_json_summary', 1, 8, 4).
python_method('TestQLWatcher', '_try_find_line_summary', 1, 7, 4).
python_method('TestQLWatcher', '_summarize_testql_failure', 1, 3, 2).
python_method('TestQLWatcher', '_summarize_health_scenario_failure', 1, 8, 4).
python_method('TestQLWatcher', '_run_fleet_health_scenario', 0, 12, 17).
python_method('TestQLWatcher', '_run_quick_test_no_scenarios', 2, 11, 8).
python_method('TestQLWatcher', '_get_quick_scenarios', 1, 3, 2).
python_method('TestQLWatcher', '_run_quick_scenarios_loop', 3, 3, 1).
python_method('TestQLWatcher', 'run_quick_test', 2, 4, 8).
python_method('TestQLWatcher', '_publish_visual_events', 2, 6, 4).
python_method('TestQLWatcher', 'run_detail_test', 2, 11, 14).
python_method('TestQLWatcher', 'process_test_queue_once', 0, 4, 5).
python_method('TestQLWatcher', 'process_changed_file_once', 1, 4, 5).
python_method('TestQLWatcher', '_run_periodic_probes_once', 0, 6, 6).
python_method('TestQLWatcher', '_start_periodic_probe_thread', 0, 3, 6).
python_method('TestQLWatcher', 'start_watching', 1, 1, 3).
python_class('wup/visual_diff.py', 'VisualDiffer').
python_method('VisualDiffer', '__init__', 2, 2, 3).
python_method('VisualDiffer', '_pages_for_service', 2, 11, 4).
python_method('VisualDiffer', '_categorize_page_result', 7, 7, 6).
python_method('VisualDiffer', '_print_scan_summary', 4, 8, 7).
python_method('VisualDiffer', 'run_for_service', 2, 10, 17).
python_method('VisualDiffer', '_build_progress', 2, 3, 7).
python_method('VisualDiffer', '_check_page', 2, 4, 9).
python_method('VisualDiffer', '_write_diff_event', 3, 1, 6).
python_method('VisualDiffer', 'get_recent_diffs', 1, 7, 11).
python_class('wup/web_client.py', 'WebClient').
python_method('WebClient', '__init__', 1, 2, 2).
python_method('WebClient', 'is_active', 0, 3, 2).
python_method('WebClient', '_headers', 0, 2, 0).
python_method('WebClient', 'send_event', 1, 5, 8).
python_method('WebClient', 'send_regression', 5, 1, 1).
python_method('WebClient', 'send_pass', 2, 1, 1).
python_method('WebClient', 'send_health_transition', 3, 1, 1).
python_method('WebClient', 'send_visual_diff', 3, 1, 1).
% ── Dependencies ─────────────────────────────────────────
% ── Makefile Targets ─────────────────────────────────────
% ── Taskfile Tasks ───────────────────────────────────────
taskfile_task('', 'Watch project for file changes and run WUP regression tests').
taskfile_task('', 'Show dependency map status and configuration').
taskfile_task('', 'Discover monitoring targets and update wup.yaml manifest').
taskfile_task('', 'Verify TestQL scenarios and discover endpoints').
taskfile_task('', 'Build dependency map from codebase').
taskfile_task('', 'Run WUP pytest test suite').
% ── Environment Variables ────────────────────────────────
env_variable('OPENROUTER_API_KEY', '*(not set)*', 'Required: OpenRouter API key (https://openrouter.ai/keys)').
env_variable('LLM_MODEL', 'openrouter/qwen/qwen3-coder-next', 'Model (default: openrouter/qwen/qwen3-coder-next)').
env_variable('PFIX_AUTO_APPLY', 'true', 'true = apply fixes without asking').
env_variable('PFIX_AUTO_INSTALL_DEPS', 'true', 'true = auto pip/uv install').
env_variable('PFIX_AUTO_RESTART', 'false', 'true = os.execv restart after fix').
env_variable('PFIX_MAX_RETRIES', '3', '').
env_variable('PFIX_DRY_RUN', 'false', '').
env_variable('PFIX_ENABLED', 'true', '').
env_variable('PFIX_GIT_COMMIT', 'false', 'true = auto-commit fixes').
env_variable('PFIX_GIT_PREFIX', 'pfix:', 'commit message prefix').
env_variable('PFIX_CREATE_BACKUPS', 'false', 'false = disable .pfix_backups/ directory').
% ── TestQL Scenarios ─────────────────────────────────────
testql_scenario('cli-smoke.testql.toon.yaml', 'cli').
testql_scenario('cli-wup.testql.toon.yaml', 'cli').
testql_scenario('generated-cli-tests.testql.toon.yaml', 'cli').
testql_scenario('generated-from-pytests.testql.toon.yaml', 'integration').
% ── Semantic Facts from SUMD.md ──────────────────────────
sumd_declared_file('app.doql.less', 'doql').
sumd_declared_file('testql-scenarios/cli-smoke.testql.toon.yaml', 'testql').
sumd_declared_file('testql-scenarios/cli-wup.testql.toon.yaml', 'testql').
sumd_declared_file('testql-scenarios/generated-cli-tests.testql.toon.yaml', 'testql').
sumd_declared_file('testql-scenarios/generated-from-pytests.testql.toon.yaml', 'testql').
sumd_declared_file('Taskfile.yml', 'taskfile').
sumd_declared_file('project/map.toon.yaml', 'analysis').
sumd_declared_file('project/logic.pl', 'analysis').
sumd_declared_file('project/calls.toon.yaml', 'analysis').
sumd_interface('api', '').
sumd_interface('cli', 'argparse').
sumd_interface('cli', '').
sumd_workflow('wup:watch', 'manual').
sumd_workflow_step('wup:watch', 1, 'poetry run wup watch').
sumd_workflow('wup:status', 'manual').
sumd_workflow_step('wup:status', 1, 'poetry run wup status').
sumd_workflow('wup:sync', 'manual').
sumd_workflow_step('wup:sync', 1, 'poetry run wup sync-testql . --write').
sumd_workflow('wup:endpoints', 'manual').
sumd_workflow_step('wup:endpoints', 1, 'poetry run wup testql-endpoints').
sumd_workflow('wup:map', 'manual').
sumd_workflow_step('wup:map', 1, 'poetry run wup map-deps').
sumd_workflow('test', 'manual').
sumd_workflow_step('test', 1, 'poetry run pytest').Top 5 modules by symbol density — signatures for LLM orientation.
class BrowserNotifier: # Send watcher events to browser-facing service and local file
def __init__(service_url, events_file) # CC=13 ⚠
def notify(payload) # CC=3
class TestQLWatcher: # WUP watcher running selective TestQL scenarios for changed s
def __init__(project_root, scenarios_dir, testql_bin, track_dir, browser_service_url, quick_limit, config) # CC=13 ⚠
def _normalize_fleet_health_entry() # CC=7
def _load_service_health() # CC=1
def _record_health_transition() # CC=6
def _tokenize_service(service) # CC=3
def _get_config_endpoints_for_service(service) # CC=10 ⚠
def _to_full_url_for_service(service, endpoint) # CC=5
def _resolve_base_url_for_service(service) # CC=8
def _resolve_base_url() # CC=5
def _to_full_url(endpoint) # CC=5
def _discover_scenarios() # CC=2
def get_service_config(service_name) # CC=3
def _score_scenario(scenario, tokens) # CC=10 ⚠
def _get_scored_scenarios(scenarios, tokens, limit) # CC=4
def _get_smoke_fallback(svc_type) # CC=6
def _health_summary_all_passed(summary) # CC=5
def _select_scenarios_for_service(service) # CC=10 ⚠
def _filter_scenarios_by_type(scenarios, svc_type) # CC=8
def _scenario_matches_type(scenario, svc_type) # CC=4
def _run_testql(args, timeout) # CC=4
def _is_interrupted_result(result) # CC=4
def _write_track() # CC=13 ⚠
def _quick_timeout() # CC=3
def _merge_endpoints(service, endpoints) # CC=3
def _run_scenario_quick(service, scenario, merged_endpoints) # CC=3
def _should_run_visual_diff() # CC=4
def _quick_pass_actions(service, merged_endpoints) # CC=10 ⚠
def _quick_probe_limit(service) # CC=3
def _quick_probe_timeout() # CC=3
def _run_live_http_probes(service, merged_endpoints) # CC=6
def _try_parse_json_summary(blob) # CC=8
def _try_find_line_summary(blob) # CC=7
def _summarize_testql_failure(result) # CC=3
def _summarize_health_scenario_failure(result) # CC=8
def _run_fleet_health_scenario() # CC=12 ⚠
def _run_quick_test_no_scenarios(service, merged_endpoints) # CC=11 ⚠
def _get_quick_scenarios(service) # CC=3
def _run_quick_scenarios_loop(service, scenarios, merged_endpoints) # CC=3
def run_quick_test(service, endpoints) # CC=4
def _publish_visual_events(service, visual_results) # CC=6
def run_detail_test(service, endpoints) # CC=11 ⚠
def process_test_queue_once() # CC=4
def process_changed_file_once(file_path) # CC=4
def _run_periodic_probes_once() # CC=6
def _start_periodic_probe_thread() # CC=3
def start_watching(watch_paths) # CC=1def _parse_api_lines(content, source) # CC=3, fan=6
def parse_scenario_probes(scenario_path) # CC=2, fan=3
def _extract_base_url(data) # CC=4, fan=4
def _parse_endpoint_row(row, base_url, source) # CC=8, fan=8
def parse_service_map_probes(map_path) # CC=6, fan=8
def _connect_module_api_on_frontend_proxy(probe) # CC=5, fan=4
def _firmware_plugin_probe_without_runtime(probe) # CC=5, fan=4
def is_monitoring_probe(probe) # CC=9, fan=7
def _service_path_patterns(services) # CC=6, fan=7
def _find_service_by_name(services, name) # CC=3, fan=1
def _find_service_by_token(services, token) # CC=3, fan=1
def _assign_by_port_8101(services) # CC=1, fan=1
def _assign_by_port_8202(services) # CC=1, fan=1
def _assign_by_port_8100(services, path_lower) # CC=2, fan=3
def _assign_by_connect_backend(services, path_lower) # CC=4, fan=3
def _assign_http_probe(probe, services, path_lower) # CC=4, fan=5
def _assign_by_longest_token(path_lower, services) # CC=7, fan=3
def _assign_by_path_prefix(path_lower, services) # CC=13, fan=2 ⚠
def assign_probe_to_service(probe, services) # CC=5, fan=6
class ProbeTarget: # Single HTTP probe derived from TestQL scenarios or service m
def probe(timeout_s) # CC=5
class _ProbeAccumulator: # Deduplicated probe collector for discover_probes_by_service.
def __init__(services) # CC=2
def add(service, probe) # CC=3
class TestQLMonitor: # Build and run live probes from TestQL scenarios + WUP config
def __init__(project_root, config) # CC=2
def _service_map_paths() # CC=3
def _add_config_endpoints(accumulator) # CC=11 ⚠
def _add_scenario_probes(accumulator) # CC=5
def _add_service_map_probes(accumulator) # CC=5
def discover_probes_by_service() # CC=2
def _resolve_base_url_for_service(service) # CC=8
def _probeable_url(path, base) # CC=4
def probes_for_service(service, extra_paths) # CC=9
def _sort_probes_for_live(probes) # CC=1
def run_probes(service, probes) # CC=5
def suggested_endpoints_by_service() # CC=5
def _resolve_base_url() # CC=4
def _join_base(base, path) # CC=5class WupWatcher: # Intelligent file watcher for regression testing.
def __init__(project_root, deps_file, cpu_throttle, debounce_seconds, test_cooldown_seconds, config) # CC=1
def _to_relative_path(file_path) # CC=2
def infer_service(file_path) # CC=10 ⚠
def _is_coincident_pair(type_a, type_b) # CC=6
def detect_service_coincidences(changed_service) # CC=9
def _services_share_domain(service1, service2) # CC=1
def get_service_config(service_name) # CC=3
def should_test(service) # CC=1
def schedule_quick_test(service) # CC=3
def schedule_detail_test(service) # CC=1
def process_test_queue_once() # CC=7
def cpu_ok() # CC=2
def run_quick_test(service, endpoints) # CC=6
def run_detail_test(service, endpoints) # CC=10 ⚠
def test_loop() # CC=2
def should_watch_file(file_path) # CC=3
def _path_matches_exclude_pattern(rel_path, pattern) # CC=5
def _is_file_ignored(rel_path) # CC=11 ⚠
def _notify_all_configured_services(rel_path) # CC=4
def on_file_change(file_path) # CC=11 ⚠
def build_watched_paths() # CC=6
def _create_and_start_observer(event_handler, watch_paths) # CC=5
def start_watching(watch_paths) # CC=7
def create_status_table() # CC=3
def run_with_dashboard() # CC=5
class WupEventHandler: # File system event handler for WUP watcher.
def __init__(watcher) # CC=1
def on_modified(event) # CC=2
def on_created(event) # CC=2
def on_deleted(event) # CC=2def _playwright_available() # CC=3, fan=0
def _warn_playwright_missing() # CC=2, fan=1
def _fetch_dom_snapshot(url, max_depth, headless, error_selectors) # CC=9, fan=14
def _detect_content_issues(snapshot, cfg) # CC=6, fan=5
def _page_slug(url) # CC=2, fan=3
def _short_url(url) # CC=3, fan=1
def _compact_error_message(message, max_len) # CC=3, fan=3
def _sample_list(items, limit) # CC=3, fan=2
def _looks_like_visual_page(url) # CC=7, fan=4
def _snapshot_path(snapshot_dir, service, url) # CC=1, fan=2
def _load_snapshot(path) # CC=3, fan=3
def _save_snapshot(path, snapshot) # CC=1, fan=3
def _node_signature(node, depth) # CC=3, fan=3
def _flatten(node, depth, max_depth) # CC=4, fan=4
def _diff_snapshots(old, new, max_depth, threshold_added, threshold_removed, threshold_changed) # CC=11, fan=5 ⚠
def _resolve_base_url(cfg) # CC=3, fan=2
class VisualDiffer: # Triggered by TestQLWatcher after a file change.
def __init__(project_root, cfg) # CC=2
def _pages_for_service(service, endpoints) # CC=11 ⚠
def _categorize_page_result(service, url, result, ok_urls, new_urls, error_results, pending_notices) # CC=7
def _print_scan_summary(service, ok_urls, new_urls, error_results) # CC=8
def run_for_service(service, endpoints) # CC=10 ⚠
def _build_progress(service, total) # CC=3
def _check_page(service, url) # CC=4
def _write_diff_event(service, url, result) # CC=1
def get_recent_diffs(seconds) # CC=7def main() # CC=1, fan=5
class WupAssistant: # Interactive configuration assistant.
def __init__(project_root) # CC=1
def _dispatch_menu_choice(choice, template) # CC=3
def run(quick, template) # CC=8
def _init_project(template) # CC=7
def _detect_framework() # CC=6
def _auto_detect_services(framework) # CC=7
def _detect_service_type(name, path) # CC=10 ⚠
def _configure_services() # CC=14 ⚠
def _add_service_interactive() # CC=11 ⚠
def _edit_service(idx) # CC=5
def _setup_watch() # CC=7
def _configure_testql() # CC=3
def _setup_web_dashboard() # CC=3
def _setup_visual_diff() # CC=6
def _setup_anomaly_detection() # CC=8
def _review_and_validate() # CC=11 ⚠
def _validate_config() # CC=9
def _generate_suggestions() # CC=6
def _save_configuration() # CC=3
def _save_draft() # CC=1
def _load_draft() # CC=2
def _config_to_dict(config) # CC=1
def _quick_setup(template) # CC=4117 nodes · 113 edges · 18 modules · CC̄=4.1
| Function | CC | in | out | total |
|---|---|---|---|---|
status (in wup.cli) |
5 | 0 | 121 | 121 |
show_ci_cd_demo (in examples.ci_cd_integration) |
2 | 1 | 69 | 70 |
show_webhook_demo (in examples.webhook_notifications) |
4 | 1 | 68 | 69 |
_run_with_mock_services (in examples.testql_demo) |
6 | 2 | 60 | 62 |
sync_testql (in wup.cli) |
13 ⚠ | 0 | 45 | 45 |
_parse_visual_diff_config (in wup.config) |
6 | 1 | 42 | 43 |
main (in scripts.run_probe_smoke) |
14 ⚠ | 0 | 38 | 38 |
demo_snapshot_persistence (in examples.visual_diff_demo) |
3 | 1 | 26 | 27 |
# code2llm call graph | /home/tom/github/semcod/wup
# generated in 0.06s
# nodes: 117 | edges: 113 | modules: 18
# CC̄=4.1
HUBS[20]:
wup.cli.status
CC=5 in:0 out:121 total:121
examples.ci_cd_integration.show_ci_cd_demo
CC=2 in:1 out:69 total:70
examples.webhook_notifications.show_webhook_demo
CC=4 in:1 out:68 total:69
examples.testql_demo._run_with_mock_services
CC=6 in:2 out:60 total:62
wup.cli.sync_testql
CC=13 in:0 out:45 total:45
wup.config._parse_visual_diff_config
CC=6 in:1 out:42 total:43
scripts.run_probe_smoke.main
CC=14 in:0 out:38 total:38
examples.visual_diff_demo.demo_snapshot_persistence
CC=3 in:1 out:26 total:27
examples.c2004_monorepo_demo.analyze_monorepo
CC=2 in:1 out:26 total:27
wup.config._parse_testql_config
CC=2 in:1 out:23 total:24
wup.config._parse_services_config
CC=3 in:1 out:21 total:22
wup.visual_diff.VisualDiffer.run_for_service
CC=10 in:0 out:22 total:22
wup.monitoring_manifest.build_monitoring_manifest
CC=9 in:4 out:15 total:19
wup.core.WupWatcher.__init__
CC=7 in:0 out:18 total:18
examples.testql_demo.simulate_testql_analysis
CC=2 in:0 out:18 total:18
wup.visual_diff._fetch_dom_snapshot
CC=9 in:1 out:17 total:18
wup.visual_diff._diff_snapshots
CC=11 in:2 out:15 total:17
examples.visual_diff_demo.demo_config_yaml_round_trip
CC=6 in:1 out:16 total:17
wup.testql_watcher.TestQLWatcher.__init__
CC=13 in:0 out:17 total:17
wup.config.load_config
CC=5 in:9 out:8 total:17
MODULES:
examples.c2004_monorepo_demo [5 funcs]
_analyze_module CC=3 out:9
_analyze_module_structure CC=7 out:10
_discover_modules CC=5 out:8
analyze_monorepo CC=2 out:26
main CC=2 out:2
examples.ci_cd_integration [4 funcs]
generate_github_actions CC=1 out:9
generate_gitlab_ci CC=3 out:10
main CC=3 out:7
show_ci_cd_demo CC=2 out:69
examples.testql_demo [4 funcs]
_build_mock_services CC=5 out:4
_run_with_mock_services CC=6 out:60
simulate_testql_analysis CC=2 out:18
simulate_with_mock_data CC=1 out:12
examples.visual_diff_demo [8 funcs]
_make_dom CC=2 out:1
demo_config_yaml_round_trip CC=6 out:16
demo_diff_algorithm CC=3 out:16
demo_disabled_is_noop CC=2 out:11
demo_live_page CC=3 out:14
demo_page_slug CC=2 out:6
demo_snapshot_persistence CC=3 out:26
main CC=2 out:15
examples.webhook_notifications [2 funcs]
main CC=3 out:7
show_webhook_demo CC=4 out:68
scripts.run_probe_smoke [1 funcs]
main CC=14 out:38
wup._hash_detector [1 funcs]
_snapshot_path CC=1 out:3
wup.cli [6 funcs]
_auto_generate_config CC=3 out:13
_load_watch_config CC=4 out:3
_refresh_monitoring_manifest CC=3 out:4
init CC=3 out:16
status CC=5 out:121
sync_testql CC=13 out:45
wup.cli_config_generator [1 funcs]
generate CC=4 out:5
wup.config [17 funcs]
_load_dotenv CC=10 out:10
_normalize_testql_extra_args CC=5 out:10
_normalize_testql_timeout CC=3 out:4
_parse_planfile_config CC=5 out:15
_parse_project_config CC=2 out:5
_parse_services_config CC=3 out:21
_parse_strategy_config CC=1 out:4
_parse_testql_config CC=2 out:23
_parse_testql_extra_args CC=5 out:8
_parse_visual_diff_config CC=6 out:42
wup.core [1 funcs]
__init__ CC=7 out:18
wup.monitoring_manifest [13 funcs]
_build_docker_rows CC=5 out:3
_build_scenario_rows CC=5 out:8
_build_wup_service_dicts CC=3 out:2
_extract_healthcheck_test CC=6 out:7
_extract_service_from_spec CC=7 out:12
_load_compose_yaml CC=5 out:5
_map_docker_to_wup_service CC=11 out:7
_parse_port_mapping CC=5 out:4
build_monitoring_manifest CC=9 out:15
discover_docker_compose_services CC=7 out:10
wup.testing.handlers.event_handlers [1 funcs]
register_testing_event_handlers CC=1 out:3
wup.testing.handlers.health_handlers [1 funcs]
register_health_handlers CC=1 out:3
wup.testql_monitor [23 funcs]
_add_config_endpoints CC=11 out:13
_add_scenario_probes CC=5 out:5
_add_service_map_probes CC=5 out:5
probes_for_service CC=9 out:11
_assign_by_connect_backend CC=4 out:4
_assign_by_longest_token CC=7 out:5
_assign_by_path_prefix CC=13 out:7
_assign_by_port_8100 CC=2 out:3
_assign_by_port_8101 CC=1 out:1
_assign_by_port_8202 CC=1 out:1
wup.testql_watcher [2 funcs]
__init__ CC=13 out:17
_get_config_endpoints_for_service CC=10 out:7
wup.visual_diff [23 funcs]
__init__ CC=2 out:3
_categorize_page_result CC=7 out:12
_check_page CC=4 out:9
_pages_for_service CC=11 out:8
_print_scan_summary CC=8 out:13
_write_diff_event CC=1 out:6
run_for_service CC=10 out:22
_compact_error_message CC=3 out:3
_detect_content_issues CC=6 out:11
_diff_snapshots CC=11 out:15
wup.web_client [4 funcs]
__init__ CC=2 out:2
send_event CC=5 out:9
_normalize CC=6 out:7
resolve_endpoint CC=3 out:3
EDGES:
wup.config.load_config → wup.config._load_dotenv
wup.config.load_config → wup.config.validate_config
wup.config.load_config → wup.config.find_config_file
wup.config.load_config → wup.config.get_default_config
wup.config._normalize_testql_extra_args → wup.config._normalize_testql_timeout
wup.config._parse_testql_config → wup.config._parse_testql_extra_args
wup.config._parse_testql_config → wup.config._normalize_testql_extra_args
wup.config.validate_config → wup.config._parse_project_config
wup.config.validate_config → wup.config._parse_watch_config
wup.config.validate_config → wup.config._parse_services_config
wup.config.validate_config → wup.config._parse_strategy_config
wup.config.validate_config → wup.config._parse_testql_config
wup.config.validate_config → wup.config._parse_visual_diff_config
wup.config.validate_config → wup.config._parse_web_config
wup.config.validate_config → wup.config._parse_planfile_config
wup.web_client.WebClient.__init__ → wup.web_client.resolve_endpoint
wup.web_client.WebClient.send_event → wup.web_client._normalize
wup.core.WupWatcher.__init__ → wup.config.load_config
wup.visual_diff._fetch_dom_snapshot → wup.visual_diff._playwright_available
wup.visual_diff._fetch_dom_snapshot → wup.visual_diff._warn_playwright_missing
wup.visual_diff._snapshot_path → wup.visual_diff._page_slug
wup.visual_diff._flatten → wup.visual_diff._node_signature
wup.visual_diff._diff_snapshots → wup.visual_diff._flatten
wup.visual_diff.VisualDiffer.__init__ → wup.visual_diff._resolve_base_url
wup.visual_diff.VisualDiffer._pages_for_service → wup.visual_diff._looks_like_visual_page
wup.visual_diff.VisualDiffer._categorize_page_result → wup.visual_diff._short_url
wup.visual_diff.VisualDiffer._print_scan_summary → wup.visual_diff._compact_error_message
wup.visual_diff.VisualDiffer._print_scan_summary → wup.visual_diff._sample_list
wup.visual_diff.VisualDiffer.run_for_service → wup.visual_diff._playwright_available
wup.visual_diff.VisualDiffer.run_for_service → wup.visual_diff._warn_playwright_missing
wup.visual_diff.VisualDiffer._check_page → wup._hash_detector.HashDetector._snapshot_path
wup.visual_diff.VisualDiffer._check_page → wup.visual_diff._load_snapshot
wup.visual_diff.VisualDiffer._check_page → wup.visual_diff._diff_snapshots
wup.visual_diff.VisualDiffer._check_page → wup.visual_diff._detect_content_issues
wup.visual_diff.VisualDiffer._check_page → wup.visual_diff._save_snapshot
wup.visual_diff.VisualDiffer._check_page → wup.visual_diff._fetch_dom_snapshot
wup.visual_diff.VisualDiffer._check_page → wup.visual_diff._compact_error_message
wup.visual_diff.VisualDiffer._write_diff_event → wup.visual_diff._page_slug
wup.testql_monitor.parse_scenario_probes → wup.testql_monitor._parse_api_lines
wup.testql_monitor.parse_service_map_probes → wup.testql_monitor._extract_base_url
wup.testql_monitor.parse_service_map_probes → wup.testql_monitor._parse_endpoint_row
wup.testql_monitor.is_monitoring_probe → wup.testql_monitor._connect_module_api_on_frontend_proxy
wup.testql_monitor.is_monitoring_probe → wup.testql_monitor._firmware_plugin_probe_without_runtime
wup.testql_monitor._assign_by_port_8101 → wup.testql_monitor._find_service_by_name
wup.testql_monitor._assign_by_port_8202 → wup.testql_monitor._find_service_by_token
wup.testql_monitor._assign_by_port_8100 → wup.testql_monitor._find_service_by_name
wup.testql_monitor._assign_by_port_8100 → wup.testql_monitor._find_service_by_token
wup.testql_monitor._assign_http_probe → wup.testql_monitor._assign_by_connect_backend
wup.testql_monitor._assign_http_probe → wup.testql_monitor._assign_by_port_8101
wup.testql_monitor._assign_http_probe → wup.testql_monitor._assign_by_port_8202
Scenarios as contract signatures — what the system guarantees.
CLI Smoke Tests
wup Command Tests
CLI Command Tests
Auto-generated from Python Tests
- assert
test_type == "quick" - assert
service_name == "users" - assert
inferred == "users"
WUP (What's Up) - Intelligent file watcher for regression testing in large projects