wup 0.2.81__tar.gz → 0.2.82__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 (91) hide show
  1. {wup-0.2.81 → wup-0.2.82}/PKG-INFO +6 -6
  2. {wup-0.2.81 → wup-0.2.82}/README.md +5 -5
  3. {wup-0.2.81 → wup-0.2.82}/pyproject.toml +1 -1
  4. {wup-0.2.81 → wup-0.2.82}/tests/test_intent_monitor.py +54 -0
  5. {wup-0.2.81 → wup-0.2.82}/wup/__init__.py +1 -1
  6. {wup-0.2.81 → wup-0.2.82}/wup/intent_monitor.py +14 -0
  7. {wup-0.2.81 → wup-0.2.82}/wup.egg-info/PKG-INFO +6 -6
  8. {wup-0.2.81 → wup-0.2.82}/LICENSE +0 -0
  9. {wup-0.2.81 → wup-0.2.82}/setup.cfg +0 -0
  10. {wup-0.2.81 → wup-0.2.82}/tests/test_aql.py +0 -0
  11. {wup-0.2.81 → wup-0.2.82}/tests/test_assistant.py +0 -0
  12. {wup-0.2.81 → wup-0.2.82}/tests/test_auto_detection.py +0 -0
  13. {wup-0.2.81 → wup-0.2.82}/tests/test_bootstrap.py +0 -0
  14. {wup-0.2.81 → wup-0.2.82}/tests/test_cli_bridge.py +0 -0
  15. {wup-0.2.81 → wup-0.2.82}/tests/test_cli_filtering.py +0 -0
  16. {wup-0.2.81 → wup-0.2.82}/tests/test_control.py +0 -0
  17. {wup-0.2.81 → wup-0.2.82}/tests/test_discovery_adapters.py +0 -0
  18. {wup-0.2.81 → wup-0.2.82}/tests/test_e2e.py +0 -0
  19. {wup-0.2.81 → wup-0.2.82}/tests/test_endpoints_init_cli.py +0 -0
  20. {wup-0.2.81 → wup-0.2.82}/tests/test_genericity.py +0 -0
  21. {wup-0.2.81 → wup-0.2.82}/tests/test_health_summary_passed.py +0 -0
  22. {wup-0.2.81 → wup-0.2.82}/tests/test_monitoring_manifest.py +0 -0
  23. {wup-0.2.81 → wup-0.2.82}/tests/test_multi_project.py +0 -0
  24. {wup-0.2.81 → wup-0.2.82}/tests/test_oql.py +0 -0
  25. {wup-0.2.81 → wup-0.2.82}/tests/test_planfile_reporter_dedupe.py +0 -0
  26. {wup-0.2.81 → wup-0.2.82}/tests/test_probe_mutex.py +0 -0
  27. {wup-0.2.81 → wup-0.2.82}/tests/test_service_inference.py +0 -0
  28. {wup-0.2.81 → wup-0.2.82}/tests/test_status_data.py +0 -0
  29. {wup-0.2.81 → wup-0.2.82}/tests/test_sync.py +0 -0
  30. {wup-0.2.81 → wup-0.2.82}/tests/test_testql_monitor.py +0 -0
  31. {wup-0.2.81 → wup-0.2.82}/tests/test_testql_watcher.py +0 -0
  32. {wup-0.2.81 → wup-0.2.82}/tests/test_visual_diff_periodic_skip.py +0 -0
  33. {wup-0.2.81 → wup-0.2.82}/tests/test_visual_diff_progress.py +0 -0
  34. {wup-0.2.81 → wup-0.2.82}/tests/test_watch_exclude.py +0 -0
  35. {wup-0.2.81 → wup-0.2.82}/tests/test_watch_no_paths_exit.py +0 -0
  36. {wup-0.2.81 → wup-0.2.82}/tests/test_web_client.py +0 -0
  37. {wup-0.2.81 → wup-0.2.82}/tests/test_wup.py +0 -0
  38. {wup-0.2.81 → wup-0.2.82}/tests/test_wup_generate.py +0 -0
  39. {wup-0.2.81 → wup-0.2.82}/wup/_ast_detector.py +0 -0
  40. {wup-0.2.81 → wup-0.2.82}/wup/_base_detector.py +0 -0
  41. {wup-0.2.81 → wup-0.2.82}/wup/_hash_detector.py +0 -0
  42. {wup-0.2.81 → wup-0.2.82}/wup/_yaml_detector.py +0 -0
  43. {wup-0.2.81 → wup-0.2.82}/wup/anomaly_detector.py +0 -0
  44. {wup-0.2.81 → wup-0.2.82}/wup/anomaly_models.py +0 -0
  45. {wup-0.2.81 → wup-0.2.82}/wup/aql.py +0 -0
  46. {wup-0.2.81 → wup-0.2.82}/wup/assistant.py +0 -0
  47. {wup-0.2.81 → wup-0.2.82}/wup/assistant_discovery.py +0 -0
  48. {wup-0.2.81 → wup-0.2.82}/wup/assistant_validator.py +0 -0
  49. {wup-0.2.81 → wup-0.2.82}/wup/bootstrap.py +0 -0
  50. {wup-0.2.81 → wup-0.2.82}/wup/bus.py +0 -0
  51. {wup-0.2.81 → wup-0.2.82}/wup/cli.py +0 -0
  52. {wup-0.2.81 → wup-0.2.82}/wup/cli_bridge.py +0 -0
  53. {wup-0.2.81 → wup-0.2.82}/wup/cli_config_generator.py +0 -0
  54. {wup-0.2.81 → wup-0.2.82}/wup/cli_scanner.py +0 -0
  55. {wup-0.2.81 → wup-0.2.82}/wup/config.py +0 -0
  56. {wup-0.2.81 → wup-0.2.82}/wup/control.py +0 -0
  57. {wup-0.2.81 → wup-0.2.82}/wup/core.py +0 -0
  58. {wup-0.2.81 → wup-0.2.82}/wup/dependency_mapper.py +0 -0
  59. {wup-0.2.81 → wup-0.2.82}/wup/discovery.py +0 -0
  60. {wup-0.2.81 → wup-0.2.82}/wup/endpoints.py +0 -0
  61. {wup-0.2.81 → wup-0.2.82}/wup/event_store.py +0 -0
  62. {wup-0.2.81 → wup-0.2.82}/wup/file_watcher/events/file_events.py +0 -0
  63. {wup-0.2.81 → wup-0.2.82}/wup/generate.py +0 -0
  64. {wup-0.2.81 → wup-0.2.82}/wup/init_cli.py +0 -0
  65. {wup-0.2.81 → wup-0.2.82}/wup/models/__init__.py +0 -0
  66. {wup-0.2.81 → wup-0.2.82}/wup/models/config.py +0 -0
  67. {wup-0.2.81 → wup-0.2.82}/wup/models/target.py +0 -0
  68. {wup-0.2.81 → wup-0.2.82}/wup/monitoring_manifest.py +0 -0
  69. {wup-0.2.81 → wup-0.2.82}/wup/multi.py +0 -0
  70. {wup-0.2.81 → wup-0.2.82}/wup/oql.py +0 -0
  71. {wup-0.2.81 → wup-0.2.82}/wup/paths.py +0 -0
  72. {wup-0.2.81 → wup-0.2.82}/wup/planfile_reporter.py +0 -0
  73. {wup-0.2.81 → wup-0.2.82}/wup/status_data.py +0 -0
  74. {wup-0.2.81 → wup-0.2.82}/wup/sync.py +0 -0
  75. {wup-0.2.81 → wup-0.2.82}/wup/testing/events/health_events.py +0 -0
  76. {wup-0.2.81 → wup-0.2.82}/wup/testing/events/test_results.py +0 -0
  77. {wup-0.2.81 → wup-0.2.82}/wup/testing/handlers/event_handlers.py +0 -0
  78. {wup-0.2.81 → wup-0.2.82}/wup/testing/handlers/health_handlers.py +0 -0
  79. {wup-0.2.81 → wup-0.2.82}/wup/testing/queries/health_queries.py +0 -0
  80. {wup-0.2.81 → wup-0.2.82}/wup/testql_cli_generator.py +0 -0
  81. {wup-0.2.81 → wup-0.2.82}/wup/testql_discovery.py +0 -0
  82. {wup-0.2.81 → wup-0.2.82}/wup/testql_monitor.py +0 -0
  83. {wup-0.2.81 → wup-0.2.82}/wup/testql_watcher.py +0 -0
  84. {wup-0.2.81 → wup-0.2.82}/wup/validate.py +0 -0
  85. {wup-0.2.81 → wup-0.2.82}/wup/visual_diff.py +0 -0
  86. {wup-0.2.81 → wup-0.2.82}/wup/web_client.py +0 -0
  87. {wup-0.2.81 → wup-0.2.82}/wup.egg-info/SOURCES.txt +0 -0
  88. {wup-0.2.81 → wup-0.2.82}/wup.egg-info/dependency_links.txt +0 -0
  89. {wup-0.2.81 → wup-0.2.82}/wup.egg-info/entry_points.txt +0 -0
  90. {wup-0.2.81 → wup-0.2.82}/wup.egg-info/requires.txt +0 -0
  91. {wup-0.2.81 → wup-0.2.82}/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.81
3
+ Version: 0.2.82
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
@@ -47,17 +47,17 @@ Dynamic: license-file
47
47
 
48
48
  ## AI Cost Tracking
49
49
 
50
- ![PyPI](https://img.shields.io/badge/pypi-costs-blue) ![Version](https://img.shields.io/badge/version-0.2.81-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
51
- ![AI Cost](https://img.shields.io/badge/AI%20Cost-$7.74-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-55.7h-blue) ![Model](https://img.shields.io/badge/Model-openrouter%2Fqwen%2Fqwen3--coder--next-lightgrey)
50
+ ![PyPI](https://img.shields.io/badge/pypi-costs-blue) ![Version](https://img.shields.io/badge/version-0.2.82-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
51
+ ![AI Cost](https://img.shields.io/badge/AI%20Cost-$7.59-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-57.8h-blue) ![Model](https://img.shields.io/badge/Model-openrouter%2Fqwen%2Fqwen3--coder--next-lightgrey)
52
52
 
53
- - 🤖 **LLM usage:** $7.7367 (112 commits)
54
- - 👤 **Human dev:** ~$5566 (55.7h @ $100/h, 30min dedup)
53
+ - 🤖 **LLM usage:** $7.5884 (114 commits)
54
+ - 👤 **Human dev:** ~$5778 (57.8h @ $100/h, 30min dedup)
55
55
 
56
56
  Generated on 2026-08-01 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
57
57
 
58
58
  ---
59
59
 
60
- ![PyPI](https://img.shields.io/badge/pypi-wup-blue) ![Version](https://img.shields.io/badge/version-0.2.81-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
60
+ ![PyPI](https://img.shields.io/badge/pypi-wup-blue) ![Version](https://img.shields.io/badge/version-0.2.82-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
61
61
 
62
62
  **WUP (What's Up)** - Intelligent file watcher for regression testing in large projects.
63
63
 
@@ -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.81-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-$7.74-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-55.7h-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.82-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-$7.59-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-57.8h-blue) ![Model](https://img.shields.io/badge/Model-openrouter%2Fqwen%2Fqwen3--coder--next-lightgrey)
8
8
 
9
- - 🤖 **LLM usage:** $7.7367 (112 commits)
10
- - 👤 **Human dev:** ~$5566 (55.7h @ $100/h, 30min dedup)
9
+ - 🤖 **LLM usage:** $7.5884 (114 commits)
10
+ - 👤 **Human dev:** ~$5778 (57.8h @ $100/h, 30min dedup)
11
11
 
12
12
  Generated on 2026-08-01 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.81-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.82-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
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "wup"
7
- version = "0.2.81"
7
+ version = "0.2.82"
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.10"
@@ -3,6 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import json
6
+ import os
6
7
  import sys
7
8
  import types
8
9
  from pathlib import Path
@@ -107,6 +108,59 @@ def test_cli_monitor_resolves_single_javascript_launcher(tmp_path: Path, monkeyp
107
108
  assert observed["command"][:2] == ["node", str(cli_path.resolve())]
108
109
 
109
110
 
111
+ def test_cli_monitor_passes_project_dotenv_without_global_leakage(
112
+ tmp_path: Path, monkeypatch
113
+ ) -> None:
114
+ path = _diagnostics(tmp_path, [])
115
+ (tmp_path / ".wup.env").write_text(
116
+ "T2C_ENV_FILE=/secure/todo2code.env\n"
117
+ "OPENROUTER_MODEL=mistralai/codestral-2508\n",
118
+ encoding="utf-8",
119
+ )
120
+ observed = {}
121
+
122
+ def fake_run(command, **kwargs):
123
+ observed["env"] = kwargs["env"]
124
+ return SimpleNamespace(
125
+ returncode=0,
126
+ stdout=json.dumps({"diagnosticsPath": str(path)}),
127
+ stderr="",
128
+ )
129
+
130
+ monkeypatch.delenv("T2C_ENV_FILE", raising=False)
131
+ monkeypatch.delenv("OPENROUTER_MODEL", raising=False)
132
+ monkeypatch.setattr("wup.intent_monitor.subprocess.run", fake_run)
133
+ monitor = Todo2CodeIntentMonitor(
134
+ tmp_path,
135
+ IntentMonitoringConfig(enabled=True, command=["t2c"]),
136
+ lambda result: None,
137
+ )
138
+
139
+ result = monitor.run_once()
140
+
141
+ assert result.status == "up"
142
+ assert observed["env"]["T2C_ENV_FILE"] == "/secure/todo2code.env"
143
+ assert observed["env"]["OPENROUTER_MODEL"] == "mistralai/codestral-2508"
144
+ assert "T2C_ENV_FILE" not in os.environ
145
+ assert "OPENROUTER_MODEL" not in os.environ
146
+
147
+
148
+ def test_cli_monitor_process_environment_overrides_project_dotenv(
149
+ tmp_path: Path, monkeypatch
150
+ ) -> None:
151
+ (tmp_path / ".wup.env").write_text(
152
+ "OPENROUTER_MODEL=mistralai/codestral-2508\n", encoding="utf-8"
153
+ )
154
+ monkeypatch.setenv("OPENROUTER_MODEL", "process/model")
155
+ monitor = Todo2CodeIntentMonitor(
156
+ tmp_path, IntentMonitoringConfig(enabled=True), lambda result: None
157
+ )
158
+
159
+ environment = monitor._subprocess_environment()
160
+
161
+ assert environment["OPENROUTER_MODEL"] == "process/model"
162
+
163
+
110
164
  def test_monitor_filters_codes_and_maps_review_required_to_degraded(tmp_path: Path) -> None:
111
165
  path = _diagnostics(
112
166
  tmp_path,
@@ -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.81"
10
+ __version__ = "0.2.82"
11
11
  __author__ = "Tom Sapletta"
12
12
 
13
13
  from .config import load_config, save_config, get_default_config
@@ -3,6 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import json
6
+ import os
6
7
  import shutil
7
8
  import subprocess
8
9
  import threading
@@ -13,6 +14,7 @@ from typing import Callable, Dict, List, Optional
13
14
 
14
15
  from rich.console import Console
15
16
 
17
+ from .config import _read_dotenv
16
18
  from .models.config import IntentMonitoringConfig
17
19
 
18
20
 
@@ -145,6 +147,7 @@ class Todo2CodeIntentMonitor:
145
147
  text=True,
146
148
  timeout=self.config.timeout_s,
147
149
  check=False,
150
+ env=self._subprocess_environment(),
148
151
  )
149
152
  if completed.returncode != 0:
150
153
  detail = completed.stderr.strip() or completed.stdout.strip()
@@ -156,6 +159,17 @@ class Todo2CodeIntentMonitor:
156
159
  raise ValueError("todo2code pipeline returned non-object JSON")
157
160
  return payload
158
161
 
162
+ def _subprocess_environment(self) -> dict[str, str]:
163
+ """Build a project-local environment without mutating ``os.environ``.
164
+
165
+ This keeps concurrent project watchers isolated while allowing the
166
+ todo2code CLI to receive model selection and an external env-file path
167
+ from ``.wup.env``. Explicit process variables retain precedence.
168
+ """
169
+ environment = _read_dotenv(self.project_root)
170
+ environment.update(os.environ)
171
+ return environment
172
+
159
173
  def _resolved_cli_command(self) -> List[str]:
160
174
  """Resolve a one-part JavaScript launcher to a direct Node invocation.
161
175
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wup
3
- Version: 0.2.81
3
+ Version: 0.2.82
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
@@ -47,17 +47,17 @@ Dynamic: license-file
47
47
 
48
48
  ## AI Cost Tracking
49
49
 
50
- ![PyPI](https://img.shields.io/badge/pypi-costs-blue) ![Version](https://img.shields.io/badge/version-0.2.81-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
51
- ![AI Cost](https://img.shields.io/badge/AI%20Cost-$7.74-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-55.7h-blue) ![Model](https://img.shields.io/badge/Model-openrouter%2Fqwen%2Fqwen3--coder--next-lightgrey)
50
+ ![PyPI](https://img.shields.io/badge/pypi-costs-blue) ![Version](https://img.shields.io/badge/version-0.2.82-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
51
+ ![AI Cost](https://img.shields.io/badge/AI%20Cost-$7.59-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-57.8h-blue) ![Model](https://img.shields.io/badge/Model-openrouter%2Fqwen%2Fqwen3--coder--next-lightgrey)
52
52
 
53
- - 🤖 **LLM usage:** $7.7367 (112 commits)
54
- - 👤 **Human dev:** ~$5566 (55.7h @ $100/h, 30min dedup)
53
+ - 🤖 **LLM usage:** $7.5884 (114 commits)
54
+ - 👤 **Human dev:** ~$5778 (57.8h @ $100/h, 30min dedup)
55
55
 
56
56
  Generated on 2026-08-01 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
57
57
 
58
58
  ---
59
59
 
60
- ![PyPI](https://img.shields.io/badge/pypi-wup-blue) ![Version](https://img.shields.io/badge/version-0.2.81-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
60
+ ![PyPI](https://img.shields.io/badge/pypi-wup-blue) ![Version](https://img.shields.io/badge/version-0.2.82-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
61
61
 
62
62
  **WUP (What's Up)** - Intelligent file watcher for regression testing in large projects.
63
63
 
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
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
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