wup 0.2.41__tar.gz → 0.2.42__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. {wup-0.2.41/wup.egg-info → wup-0.2.42}/PKG-INFO +8 -5
  2. {wup-0.2.41 → wup-0.2.42}/README.md +7 -4
  3. {wup-0.2.41 → wup-0.2.42}/pyproject.toml +1 -1
  4. {wup-0.2.41 → wup-0.2.42}/tests/test_wup.py +7 -5
  5. {wup-0.2.41 → wup-0.2.42}/wup/__init__.py +1 -1
  6. {wup-0.2.41 → wup-0.2.42}/wup/config.py +1 -1
  7. {wup-0.2.41 → wup-0.2.42}/wup/core.py +13 -6
  8. {wup-0.2.41 → wup-0.2.42}/wup/models/config.py +1 -1
  9. {wup-0.2.41 → wup-0.2.42/wup.egg-info}/PKG-INFO +8 -5
  10. {wup-0.2.41 → wup-0.2.42}/LICENSE +0 -0
  11. {wup-0.2.41 → wup-0.2.42}/setup.cfg +0 -0
  12. {wup-0.2.41 → wup-0.2.42}/tests/test_e2e.py +0 -0
  13. {wup-0.2.41 → wup-0.2.42}/tests/test_monitoring_manifest.py +0 -0
  14. {wup-0.2.41 → wup-0.2.42}/tests/test_testql_monitor.py +0 -0
  15. {wup-0.2.41 → wup-0.2.42}/tests/test_testql_watcher.py +0 -0
  16. {wup-0.2.41 → wup-0.2.42}/tests/test_web_client.py +0 -0
  17. {wup-0.2.41 → wup-0.2.42}/wup/_ast_detector.py +0 -0
  18. {wup-0.2.41 → wup-0.2.42}/wup/_hash_detector.py +0 -0
  19. {wup-0.2.41 → wup-0.2.42}/wup/_yaml_detector.py +0 -0
  20. {wup-0.2.41 → wup-0.2.42}/wup/anomaly_detector.py +0 -0
  21. {wup-0.2.41 → wup-0.2.42}/wup/anomaly_models.py +0 -0
  22. {wup-0.2.41 → wup-0.2.42}/wup/assistant.py +0 -0
  23. {wup-0.2.41 → wup-0.2.42}/wup/cli.py +0 -0
  24. {wup-0.2.41 → wup-0.2.42}/wup/cli_config_generator.py +0 -0
  25. {wup-0.2.41 → wup-0.2.42}/wup/cli_scanner.py +0 -0
  26. {wup-0.2.41 → wup-0.2.42}/wup/dependency_mapper.py +0 -0
  27. {wup-0.2.41 → wup-0.2.42}/wup/models/__init__.py +0 -0
  28. {wup-0.2.41 → wup-0.2.42}/wup/monitoring_manifest.py +0 -0
  29. {wup-0.2.41 → wup-0.2.42}/wup/planfile_reporter.py +0 -0
  30. {wup-0.2.41 → wup-0.2.42}/wup/testql_cli_generator.py +0 -0
  31. {wup-0.2.41 → wup-0.2.42}/wup/testql_discovery.py +0 -0
  32. {wup-0.2.41 → wup-0.2.42}/wup/testql_monitor.py +0 -0
  33. {wup-0.2.41 → wup-0.2.42}/wup/testql_watcher.py +0 -0
  34. {wup-0.2.41 → wup-0.2.42}/wup/visual_diff.py +0 -0
  35. {wup-0.2.41 → wup-0.2.42}/wup/web_client.py +0 -0
  36. {wup-0.2.41 → wup-0.2.42}/wup.egg-info/SOURCES.txt +0 -0
  37. {wup-0.2.41 → wup-0.2.42}/wup.egg-info/dependency_links.txt +0 -0
  38. {wup-0.2.41 → wup-0.2.42}/wup.egg-info/entry_points.txt +0 -0
  39. {wup-0.2.41 → wup-0.2.42}/wup.egg-info/requires.txt +0 -0
  40. {wup-0.2.41 → wup-0.2.42}/wup.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wup
3
- Version: 0.2.41
3
+ Version: 0.2.42
4
4
  Summary: WUP (What's Up) - Intelligent file watcher for regression testing in large projects
5
5
  Author-email: Tom Sapletta <tom@sapletta.com>
6
6
  License-Expression: Apache-2.0
@@ -31,17 +31,17 @@ Dynamic: license-file
31
31
 
32
32
  ## AI Cost Tracking
33
33
 
34
- ![PyPI](https://img.shields.io/badge/pypi-costs-blue) ![Version](https://img.shields.io/badge/version-0.2.41-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
35
- ![AI Cost](https://img.shields.io/badge/AI%20Cost-$3.18-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-20.5h-blue) ![Model](https://img.shields.io/badge/Model-openrouter%2Fqwen%2Fqwen3--coder--next-lightgrey)
34
+ ![PyPI](https://img.shields.io/badge/pypi-costs-blue) ![Version](https://img.shields.io/badge/version-0.2.42-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
35
+ ![AI Cost](https://img.shields.io/badge/AI%20Cost-$3.09-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-20.5h-blue) ![Model](https://img.shields.io/badge/Model-openrouter%2Fqwen%2Fqwen3--coder--next-lightgrey)
36
36
 
37
- - 🤖 **LLM usage:** $3.1847 (51 commits)
37
+ - 🤖 **LLM usage:** $3.0939 (52 commits)
38
38
  - 👤 **Human dev:** ~$2047 (20.5h @ $100/h, 30min dedup)
39
39
 
40
40
  Generated on 2026-05-22 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
41
41
 
42
42
  ---
43
43
 
44
- ![PyPI](https://img.shields.io/badge/pypi-wup-blue) ![Version](https://img.shields.io/badge/version-0.2.41-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
44
+ ![PyPI](https://img.shields.io/badge/pypi-wup-blue) ![Version](https://img.shields.io/badge/version-0.2.42-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
45
45
 
46
46
  **WUP (What's Up)** - Intelligent file watcher for regression testing in large projects.
47
47
 
@@ -461,9 +461,12 @@ wup/
461
461
  │ ├── core.py # WupWatcher: detection, inference, scheduling
462
462
  │ ├── dependency_mapper.py # DependencyMapper: codebase → deps.json
463
463
  │ ├── testql_discovery.py # TestQLEndpointDiscovery: scenario parsing
464
+ │ ├── testql_monitor.py # TestQLMonitor: extracts live HTTP probes and Docker services
464
465
  │ ├── testql_watcher.py # TestQLWatcher: scenario runner + health tracking
465
466
  │ ├── visual_diff.py # VisualDiffer: Playwright DOM snapshot + diff engine
466
467
  │ ├── web_client.py # WebClient: async HTTP event sink → wupbro
468
+ │ ├── monitoring_manifest.py # Builds and patches the wup.yaml monitoring block
469
+ │ ├── planfile_reporter.py # PlanfileReporter: creates and deduplicates Planfile tickets
467
470
  │ └── models/
468
471
  │ ├── __init__.py
469
472
  │ └── config.py # Dataclasses: WupConfig, ServiceConfig, WatchConfig, TestStrategyConfig, TestQLConfig, VisualDiffConfig, WebConfig, AnomalyDetectionConfig...
@@ -3,17 +3,17 @@
3
3
 
4
4
  ## AI Cost Tracking
5
5
 
6
- ![PyPI](https://img.shields.io/badge/pypi-costs-blue) ![Version](https://img.shields.io/badge/version-0.2.41-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
7
- ![AI Cost](https://img.shields.io/badge/AI%20Cost-$3.18-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-20.5h-blue) ![Model](https://img.shields.io/badge/Model-openrouter%2Fqwen%2Fqwen3--coder--next-lightgrey)
6
+ ![PyPI](https://img.shields.io/badge/pypi-costs-blue) ![Version](https://img.shields.io/badge/version-0.2.42-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
7
+ ![AI Cost](https://img.shields.io/badge/AI%20Cost-$3.09-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-20.5h-blue) ![Model](https://img.shields.io/badge/Model-openrouter%2Fqwen%2Fqwen3--coder--next-lightgrey)
8
8
 
9
- - 🤖 **LLM usage:** $3.1847 (51 commits)
9
+ - 🤖 **LLM usage:** $3.0939 (52 commits)
10
10
  - 👤 **Human dev:** ~$2047 (20.5h @ $100/h, 30min dedup)
11
11
 
12
12
  Generated on 2026-05-22 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
13
13
 
14
14
  ---
15
15
 
16
- ![PyPI](https://img.shields.io/badge/pypi-wup-blue) ![Version](https://img.shields.io/badge/version-0.2.41-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
16
+ ![PyPI](https://img.shields.io/badge/pypi-wup-blue) ![Version](https://img.shields.io/badge/version-0.2.42-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
17
17
 
18
18
  **WUP (What's Up)** - Intelligent file watcher for regression testing in large projects.
19
19
 
@@ -433,9 +433,12 @@ wup/
433
433
  │ ├── core.py # WupWatcher: detection, inference, scheduling
434
434
  │ ├── dependency_mapper.py # DependencyMapper: codebase → deps.json
435
435
  │ ├── testql_discovery.py # TestQLEndpointDiscovery: scenario parsing
436
+ │ ├── testql_monitor.py # TestQLMonitor: extracts live HTTP probes and Docker services
436
437
  │ ├── testql_watcher.py # TestQLWatcher: scenario runner + health tracking
437
438
  │ ├── visual_diff.py # VisualDiffer: Playwright DOM snapshot + diff engine
438
439
  │ ├── web_client.py # WebClient: async HTTP event sink → wupbro
440
+ │ ├── monitoring_manifest.py # Builds and patches the wup.yaml monitoring block
441
+ │ ├── planfile_reporter.py # PlanfileReporter: creates and deduplicates Planfile tickets
439
442
  │ └── models/
440
443
  │ ├── __init__.py
441
444
  │ └── config.py # Dataclasses: WupConfig, ServiceConfig, WatchConfig, TestStrategyConfig, TestQLConfig, VisualDiffConfig, WebConfig, AnomalyDetectionConfig...
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "wup"
7
- version = "0.2.41"
7
+ version = "0.2.42"
8
8
  description = "WUP (What's Up) - Intelligent file watcher for regression testing in large projects"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -952,11 +952,12 @@ class TestConfigModels:
952
952
  scenario_dir="scenarios/tests",
953
953
  smoke_scenario="smoke.testql.toon.yaml",
954
954
  output_format="json",
955
- extra_args=["--timeout 10s"]
955
+ extra_args=["--timeout", "10"]
956
956
  )
957
957
  assert config.scenario_dir == "scenarios/tests"
958
+ assert config.smoke_scenario == "smoke.testql.toon.yaml"
958
959
  assert config.output_format == "json"
959
- assert len(config.extra_args) == 1
960
+ assert len(config.extra_args) == 2
960
961
 
961
962
  def test_wup_config(self):
962
963
  """Test WupConfig dataclass."""
@@ -1283,7 +1284,8 @@ testql:
1283
1284
  smoke_scenario: "smoke.testql.toon.yaml"
1284
1285
  output_format: "json"
1285
1286
  extra_args:
1286
- - "--timeout 10s"
1287
+ - "--timeout"
1288
+ - "10"
1287
1289
  """
1288
1290
  config_path = Path(tmpdir) / "wup.yaml"
1289
1291
  config_path.write_text(config_content)
@@ -1694,7 +1696,7 @@ class TestTestQLWatcherConfig:
1694
1696
  testql_config = TestQLConfig(
1695
1697
  scenario_dir="scenarios/tests",
1696
1698
  smoke_scenario="smoke.testql.toon.yaml",
1697
- extra_args=["--timeout 10s"]
1699
+ extra_args=["--timeout", "10"]
1698
1700
  )
1699
1701
  config = WupConfig(
1700
1702
  project=ProjectConfig(name="test"),
@@ -1706,7 +1708,7 @@ class TestTestQLWatcherConfig:
1706
1708
 
1707
1709
  watcher = TestQLWatcher(tmpdir, config=config)
1708
1710
  assert watcher.config.project.name == "test"
1709
- assert watcher.testql_extra_args == ["--timeout 10s"]
1711
+ assert watcher.testql_extra_args == ["--timeout", "10"]
1710
1712
 
1711
1713
  def test_testql_watcher_uses_config_scenarios_dir(self):
1712
1714
  """Test that TestQLWatcher uses config scenario directory."""
@@ -7,7 +7,7 @@ WUP monitors file changes and runs intelligent regression tests using a 3-layer
7
7
  3. Detail Layer: Full tests with blame reports (only on failure)
8
8
  """
9
9
 
10
- __version__ = "0.2.41"
10
+ __version__ = "0.2.42"
11
11
  __author__ = "Tom Sapletta"
12
12
 
13
13
  from .config import load_config, save_config, get_default_config
@@ -175,7 +175,7 @@ def validate_config(raw: dict) -> WupConfig:
175
175
  scenario_dir=testql_raw.get("scenario_dir", "scenarios/tests"),
176
176
  smoke_scenario=testql_raw.get("smoke_scenario", "smoke.testql.toon.yaml"),
177
177
  output_format=testql_raw.get("output_format", "json"),
178
- extra_args=testql_raw.get("extra_args", ["--timeout", "10s"]),
178
+ extra_args=testql_raw.get("extra_args", ["--timeout", "10"]),
179
179
  endpoint_discovery=testql_raw.get("endpoint_discovery", True),
180
180
  probe_interval_s=int(testql_raw.get("probe_interval_s", 0) or 0),
181
181
  health_scenario=testql_raw.get("health_scenario", ""),
@@ -155,12 +155,8 @@ class WupWatcher:
155
155
  if service:
156
156
  return service
157
157
 
158
- # Fallback: use first two meaningful parts (only if file exists)
159
- if len(parts) >= 2:
160
- # Check if file exists (absolute path)
161
- if Path(file_path).is_file():
162
- return "/".join(parts[:2])
163
-
158
+ # Fallback: return None to let caller handle configured services
159
+ # Don't construct fake service names from path parts
164
160
  return None
165
161
 
166
162
  def _is_coincident_pair(self, type_a: str, type_b: str) -> bool:
@@ -479,6 +475,17 @@ class WupWatcher:
479
475
  # Infer service from file path
480
476
  service = self.infer_service(file_path)
481
477
 
478
+ # If inference failed or returned invalid service, use configured services
479
+ # Invalid services: None, "//home", or other non-configured names
480
+ invalid_services = {None, "//home"}
481
+ if service in invalid_services and self.config.services:
482
+ for svc in self.config.services:
483
+ if self.should_test(svc.name):
484
+ self.changed_services.add(svc.name)
485
+ self.console.print(f"[yellow]📝 Changed: {rel_path} → Service: {svc.name}[/yellow]")
486
+ self.schedule_quick_test(svc.name)
487
+ return
488
+
482
489
  if service and self.should_test(service):
483
490
  self.changed_services.add(service)
484
491
  self.console.print(f"[yellow]📝 Changed: {rel_path} → Service: {service}[/yellow]")
@@ -61,7 +61,7 @@ class TestQLConfig:
61
61
  scenario_dir: str = "scenarios/tests"
62
62
  smoke_scenario: str = "smoke.testql.toon.yaml"
63
63
  output_format: str = "json"
64
- extra_args: List[str] = field(default_factory=lambda: ["--timeout", "10s"])
64
+ extra_args: List[str] = field(default_factory=lambda: ["--timeout", "10"])
65
65
  endpoint_discovery: bool = True # Merge health probes from scenarios + service maps
66
66
  probe_interval_s: int = 0 # Periodic live probes for all services (0 = file-change only)
67
67
  health_scenario: str = "" # Fleet TestQL scenario on each periodic probe cycle (live run)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wup
3
- Version: 0.2.41
3
+ Version: 0.2.42
4
4
  Summary: WUP (What's Up) - Intelligent file watcher for regression testing in large projects
5
5
  Author-email: Tom Sapletta <tom@sapletta.com>
6
6
  License-Expression: Apache-2.0
@@ -31,17 +31,17 @@ Dynamic: license-file
31
31
 
32
32
  ## AI Cost Tracking
33
33
 
34
- ![PyPI](https://img.shields.io/badge/pypi-costs-blue) ![Version](https://img.shields.io/badge/version-0.2.41-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
35
- ![AI Cost](https://img.shields.io/badge/AI%20Cost-$3.18-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-20.5h-blue) ![Model](https://img.shields.io/badge/Model-openrouter%2Fqwen%2Fqwen3--coder--next-lightgrey)
34
+ ![PyPI](https://img.shields.io/badge/pypi-costs-blue) ![Version](https://img.shields.io/badge/version-0.2.42-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
35
+ ![AI Cost](https://img.shields.io/badge/AI%20Cost-$3.09-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-20.5h-blue) ![Model](https://img.shields.io/badge/Model-openrouter%2Fqwen%2Fqwen3--coder--next-lightgrey)
36
36
 
37
- - 🤖 **LLM usage:** $3.1847 (51 commits)
37
+ - 🤖 **LLM usage:** $3.0939 (52 commits)
38
38
  - 👤 **Human dev:** ~$2047 (20.5h @ $100/h, 30min dedup)
39
39
 
40
40
  Generated on 2026-05-22 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
41
41
 
42
42
  ---
43
43
 
44
- ![PyPI](https://img.shields.io/badge/pypi-wup-blue) ![Version](https://img.shields.io/badge/version-0.2.41-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
44
+ ![PyPI](https://img.shields.io/badge/pypi-wup-blue) ![Version](https://img.shields.io/badge/version-0.2.42-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
45
45
 
46
46
  **WUP (What's Up)** - Intelligent file watcher for regression testing in large projects.
47
47
 
@@ -461,9 +461,12 @@ wup/
461
461
  │ ├── core.py # WupWatcher: detection, inference, scheduling
462
462
  │ ├── dependency_mapper.py # DependencyMapper: codebase → deps.json
463
463
  │ ├── testql_discovery.py # TestQLEndpointDiscovery: scenario parsing
464
+ │ ├── testql_monitor.py # TestQLMonitor: extracts live HTTP probes and Docker services
464
465
  │ ├── testql_watcher.py # TestQLWatcher: scenario runner + health tracking
465
466
  │ ├── visual_diff.py # VisualDiffer: Playwright DOM snapshot + diff engine
466
467
  │ ├── web_client.py # WebClient: async HTTP event sink → wupbro
468
+ │ ├── monitoring_manifest.py # Builds and patches the wup.yaml monitoring block
469
+ │ ├── planfile_reporter.py # PlanfileReporter: creates and deduplicates Planfile tickets
467
470
  │ └── models/
468
471
  │ ├── __init__.py
469
472
  │ └── config.py # Dataclasses: WupConfig, ServiceConfig, WatchConfig, TestStrategyConfig, TestQLConfig, VisualDiffConfig, WebConfig, AnomalyDetectionConfig...
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes