wup 0.2.80__tar.gz → 0.2.81__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.80 → wup-0.2.81}/PKG-INFO +4 -4
  2. {wup-0.2.80 → wup-0.2.81}/README.md +3 -3
  3. {wup-0.2.80 → wup-0.2.81}/pyproject.toml +1 -1
  4. {wup-0.2.80 → wup-0.2.81}/tests/test_planfile_reporter_dedupe.py +7 -0
  5. {wup-0.2.80 → wup-0.2.81}/tests/test_testql_watcher.py +6 -3
  6. {wup-0.2.80 → wup-0.2.81}/wup/__init__.py +1 -1
  7. {wup-0.2.80 → wup-0.2.81}/wup/planfile_reporter.py +19 -2
  8. {wup-0.2.80 → wup-0.2.81}/wup.egg-info/PKG-INFO +4 -4
  9. {wup-0.2.80 → wup-0.2.81}/LICENSE +0 -0
  10. {wup-0.2.80 → wup-0.2.81}/setup.cfg +0 -0
  11. {wup-0.2.80 → wup-0.2.81}/tests/test_aql.py +0 -0
  12. {wup-0.2.80 → wup-0.2.81}/tests/test_assistant.py +0 -0
  13. {wup-0.2.80 → wup-0.2.81}/tests/test_auto_detection.py +0 -0
  14. {wup-0.2.80 → wup-0.2.81}/tests/test_bootstrap.py +0 -0
  15. {wup-0.2.80 → wup-0.2.81}/tests/test_cli_bridge.py +0 -0
  16. {wup-0.2.80 → wup-0.2.81}/tests/test_cli_filtering.py +0 -0
  17. {wup-0.2.80 → wup-0.2.81}/tests/test_control.py +0 -0
  18. {wup-0.2.80 → wup-0.2.81}/tests/test_discovery_adapters.py +0 -0
  19. {wup-0.2.80 → wup-0.2.81}/tests/test_e2e.py +0 -0
  20. {wup-0.2.80 → wup-0.2.81}/tests/test_endpoints_init_cli.py +0 -0
  21. {wup-0.2.80 → wup-0.2.81}/tests/test_genericity.py +0 -0
  22. {wup-0.2.80 → wup-0.2.81}/tests/test_health_summary_passed.py +0 -0
  23. {wup-0.2.80 → wup-0.2.81}/tests/test_intent_monitor.py +0 -0
  24. {wup-0.2.80 → wup-0.2.81}/tests/test_monitoring_manifest.py +0 -0
  25. {wup-0.2.80 → wup-0.2.81}/tests/test_multi_project.py +0 -0
  26. {wup-0.2.80 → wup-0.2.81}/tests/test_oql.py +0 -0
  27. {wup-0.2.80 → wup-0.2.81}/tests/test_probe_mutex.py +0 -0
  28. {wup-0.2.80 → wup-0.2.81}/tests/test_service_inference.py +0 -0
  29. {wup-0.2.80 → wup-0.2.81}/tests/test_status_data.py +0 -0
  30. {wup-0.2.80 → wup-0.2.81}/tests/test_sync.py +0 -0
  31. {wup-0.2.80 → wup-0.2.81}/tests/test_testql_monitor.py +0 -0
  32. {wup-0.2.80 → wup-0.2.81}/tests/test_visual_diff_periodic_skip.py +0 -0
  33. {wup-0.2.80 → wup-0.2.81}/tests/test_visual_diff_progress.py +0 -0
  34. {wup-0.2.80 → wup-0.2.81}/tests/test_watch_exclude.py +0 -0
  35. {wup-0.2.80 → wup-0.2.81}/tests/test_watch_no_paths_exit.py +0 -0
  36. {wup-0.2.80 → wup-0.2.81}/tests/test_web_client.py +0 -0
  37. {wup-0.2.80 → wup-0.2.81}/tests/test_wup.py +0 -0
  38. {wup-0.2.80 → wup-0.2.81}/tests/test_wup_generate.py +0 -0
  39. {wup-0.2.80 → wup-0.2.81}/wup/_ast_detector.py +0 -0
  40. {wup-0.2.80 → wup-0.2.81}/wup/_base_detector.py +0 -0
  41. {wup-0.2.80 → wup-0.2.81}/wup/_hash_detector.py +0 -0
  42. {wup-0.2.80 → wup-0.2.81}/wup/_yaml_detector.py +0 -0
  43. {wup-0.2.80 → wup-0.2.81}/wup/anomaly_detector.py +0 -0
  44. {wup-0.2.80 → wup-0.2.81}/wup/anomaly_models.py +0 -0
  45. {wup-0.2.80 → wup-0.2.81}/wup/aql.py +0 -0
  46. {wup-0.2.80 → wup-0.2.81}/wup/assistant.py +0 -0
  47. {wup-0.2.80 → wup-0.2.81}/wup/assistant_discovery.py +0 -0
  48. {wup-0.2.80 → wup-0.2.81}/wup/assistant_validator.py +0 -0
  49. {wup-0.2.80 → wup-0.2.81}/wup/bootstrap.py +0 -0
  50. {wup-0.2.80 → wup-0.2.81}/wup/bus.py +0 -0
  51. {wup-0.2.80 → wup-0.2.81}/wup/cli.py +0 -0
  52. {wup-0.2.80 → wup-0.2.81}/wup/cli_bridge.py +0 -0
  53. {wup-0.2.80 → wup-0.2.81}/wup/cli_config_generator.py +0 -0
  54. {wup-0.2.80 → wup-0.2.81}/wup/cli_scanner.py +0 -0
  55. {wup-0.2.80 → wup-0.2.81}/wup/config.py +0 -0
  56. {wup-0.2.80 → wup-0.2.81}/wup/control.py +0 -0
  57. {wup-0.2.80 → wup-0.2.81}/wup/core.py +0 -0
  58. {wup-0.2.80 → wup-0.2.81}/wup/dependency_mapper.py +0 -0
  59. {wup-0.2.80 → wup-0.2.81}/wup/discovery.py +0 -0
  60. {wup-0.2.80 → wup-0.2.81}/wup/endpoints.py +0 -0
  61. {wup-0.2.80 → wup-0.2.81}/wup/event_store.py +0 -0
  62. {wup-0.2.80 → wup-0.2.81}/wup/file_watcher/events/file_events.py +0 -0
  63. {wup-0.2.80 → wup-0.2.81}/wup/generate.py +0 -0
  64. {wup-0.2.80 → wup-0.2.81}/wup/init_cli.py +0 -0
  65. {wup-0.2.80 → wup-0.2.81}/wup/intent_monitor.py +0 -0
  66. {wup-0.2.80 → wup-0.2.81}/wup/models/__init__.py +0 -0
  67. {wup-0.2.80 → wup-0.2.81}/wup/models/config.py +0 -0
  68. {wup-0.2.80 → wup-0.2.81}/wup/models/target.py +0 -0
  69. {wup-0.2.80 → wup-0.2.81}/wup/monitoring_manifest.py +0 -0
  70. {wup-0.2.80 → wup-0.2.81}/wup/multi.py +0 -0
  71. {wup-0.2.80 → wup-0.2.81}/wup/oql.py +0 -0
  72. {wup-0.2.80 → wup-0.2.81}/wup/paths.py +0 -0
  73. {wup-0.2.80 → wup-0.2.81}/wup/status_data.py +0 -0
  74. {wup-0.2.80 → wup-0.2.81}/wup/sync.py +0 -0
  75. {wup-0.2.80 → wup-0.2.81}/wup/testing/events/health_events.py +0 -0
  76. {wup-0.2.80 → wup-0.2.81}/wup/testing/events/test_results.py +0 -0
  77. {wup-0.2.80 → wup-0.2.81}/wup/testing/handlers/event_handlers.py +0 -0
  78. {wup-0.2.80 → wup-0.2.81}/wup/testing/handlers/health_handlers.py +0 -0
  79. {wup-0.2.80 → wup-0.2.81}/wup/testing/queries/health_queries.py +0 -0
  80. {wup-0.2.80 → wup-0.2.81}/wup/testql_cli_generator.py +0 -0
  81. {wup-0.2.80 → wup-0.2.81}/wup/testql_discovery.py +0 -0
  82. {wup-0.2.80 → wup-0.2.81}/wup/testql_monitor.py +0 -0
  83. {wup-0.2.80 → wup-0.2.81}/wup/testql_watcher.py +0 -0
  84. {wup-0.2.80 → wup-0.2.81}/wup/validate.py +0 -0
  85. {wup-0.2.80 → wup-0.2.81}/wup/visual_diff.py +0 -0
  86. {wup-0.2.80 → wup-0.2.81}/wup/web_client.py +0 -0
  87. {wup-0.2.80 → wup-0.2.81}/wup.egg-info/SOURCES.txt +0 -0
  88. {wup-0.2.80 → wup-0.2.81}/wup.egg-info/dependency_links.txt +0 -0
  89. {wup-0.2.80 → wup-0.2.81}/wup.egg-info/entry_points.txt +0 -0
  90. {wup-0.2.80 → wup-0.2.81}/wup.egg-info/requires.txt +0 -0
  91. {wup-0.2.80 → wup-0.2.81}/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.80
3
+ Version: 0.2.81
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.80-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
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
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)
52
52
 
53
- - 🤖 **LLM usage:** $7.7365 (111 commits)
53
+ - 🤖 **LLM usage:** $7.7367 (112 commits)
54
54
  - 👤 **Human dev:** ~$5566 (55.7h @ $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.80-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.81-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.80-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
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
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)
8
8
 
9
- - 🤖 **LLM usage:** $7.7365 (111 commits)
9
+ - 🤖 **LLM usage:** $7.7367 (112 commits)
10
10
  - 👤 **Human dev:** ~$5566 (55.7h @ $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.80-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.81-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.80"
7
+ version = "0.2.81"
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"
@@ -35,6 +35,13 @@ def _seed_dedupe(rep: PlanfileReporter, fingerprint_kwargs: dict, ticket_id: str
35
35
  FAIL = {"service": "svc", "status": "down", "stage": "probe", "message": "connection refused"}
36
36
 
37
37
 
38
+ def test_parse_ticket_id_supports_project_specific_prefixes(tmp_path):
39
+ rep = _reporter(tmp_path)
40
+
41
+ assert rep._parse_ticket_id("✓ Created STARTER-074: intent failure") == "STARTER-074"
42
+ assert rep._parse_ticket_id("Created PLF-2") == "PLF-2"
43
+
44
+
38
45
  def test_open_ticket_still_mutes_recurrence(tmp_path, monkeypatch):
39
46
  rep = _reporter(tmp_path)
40
47
  _seed_dedupe(rep, FAIL, "PLF-1")
@@ -253,8 +253,11 @@ def test_planfile_reporter_creates_deduped_ticket(monkeypatch):
253
253
  assert calls[0][:3] == ["planfile", "ticket", "create"]
254
254
  assert "--label" in calls[0]
255
255
  assert "llm-ready" in calls[0]
256
- assert "--files" in calls[0]
257
- assert ".wup/tracks/one.json" in calls[0]
256
+ # Runtime evidence remains linked in the description but must not
257
+ # become Koru's source-edit scope in Planfile ``files``.
258
+ assert "--files" not in calls[0]
259
+ description = calls[0][calls[0].index("--description") + 1]
260
+ assert ".wup/tracks/one.json" in description
258
261
 
259
262
 
260
263
  def test_planfile_reporter_clears_dedupe_after_recovery(monkeypatch):
@@ -307,7 +310,7 @@ def test_planfile_reporter_retries_without_files_for_old_planfile_cli(monkeypatc
307
310
  status="failed",
308
311
  stage="detail",
309
312
  message="detail failed",
310
- track_file=".wup/tracks/firmware_detail.json",
313
+ track_file="src/firmware.py",
311
314
  )
312
315
 
313
316
  assert ticket_id == "PLF-998"
@@ -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.80"
10
+ __version__ = "0.2.81"
11
11
  __author__ = "Tom Sapletta"
12
12
 
13
13
  from .config import load_config, save_config, get_default_config
@@ -137,10 +137,23 @@ class PlanfileReporter:
137
137
  ]
138
138
  for label in self.config.labels:
139
139
  cmd.extend(["--label", label])
140
- if track_file:
140
+ # Koru treats Planfile ``files`` as the agent's allowed edit scope.
141
+ # WUP runtime evidence under .wup/.intent is not source code and must
142
+ # remain a description link rather than constraining the agent to edit
143
+ # diagnostics.json or a generated track file.
144
+ if track_file and not self._is_runtime_artifact(track_file):
141
145
  cmd.extend(["--files", track_file])
142
146
  return cmd
143
147
 
148
+ def _is_runtime_artifact(self, track_file: str) -> bool:
149
+ path = Path(track_file)
150
+ if path.is_absolute():
151
+ try:
152
+ path = path.resolve().relative_to(self.project_root.resolve())
153
+ except ValueError:
154
+ return False
155
+ return bool(path.parts and path.parts[0] in {".wup", ".intent"})
156
+
144
157
  def _run_planfile(self, cmd: list[str]) -> Optional[tuple[int, str, str]]:
145
158
  """Run a planfile command; return (returncode, stdout, stderr) or None on OS/timeout error."""
146
159
  try:
@@ -243,7 +256,11 @@ class PlanfileReporter:
243
256
 
244
257
  @staticmethod
245
258
  def _parse_ticket_id(text: str) -> Optional[str]:
246
- match = re.search(r"\bPLF-\d+\b", text)
259
+ # Planfile projects choose their own ticket prefix (for example PLF,
260
+ # STARTER or API). Do not hard-code the default prefix: otherwise the
261
+ # ticket is created successfully but WUP persists it as ``unknown`` and
262
+ # can no longer inspect its lifecycle for recurrence deduplication.
263
+ match = re.search(r"\b[A-Z][A-Z0-9_]*-\d+\b", text, re.IGNORECASE)
247
264
  return match.group(0) if match else None
248
265
 
249
266
  @staticmethod
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wup
3
- Version: 0.2.80
3
+ Version: 0.2.81
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.80-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
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
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)
52
52
 
53
- - 🤖 **LLM usage:** $7.7365 (111 commits)
53
+ - 🤖 **LLM usage:** $7.7367 (112 commits)
54
54
  - 👤 **Human dev:** ~$5566 (55.7h @ $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.80-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.81-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