bugcap 0.5.0__tar.gz → 0.5.1__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.
- {bugcap-0.5.0/src/bugcap.egg-info → bugcap-0.5.1}/PKG-INFO +14 -9
- {bugcap-0.5.0 → bugcap-0.5.1}/README.md +12 -8
- {bugcap-0.5.0 → bugcap-0.5.1}/pyproject.toml +12 -2
- bugcap-0.5.1/src/bugcap/__init__.py +1 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/cli.py +4 -4
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/live.py +1 -1
- {bugcap-0.5.0 → bugcap-0.5.1/src/bugcap.egg-info}/PKG-INFO +14 -9
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap.egg-info/requires.txt +1 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_backends.py +0 -1
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_cli_init_capture_list.py +1 -1
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_cli_live_headless.py +5 -1
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_cli_media.py +2 -2
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_cli_no_image_delete.py +1 -1
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_cli_setup.py +9 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_cli_triage.py +0 -1
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_drafts.py +2 -1
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_github_media_sync.py +2 -1
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_github_sync.py +1 -1
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_ingest.py +4 -2
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_mcp.py +0 -1
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_mcp_logging.py +0 -1
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_recorder_run.py +3 -3
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_refs_validate_rewrite.py +3 -1
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_regression_output.py +1 -1
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_repo_values.py +0 -1
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_sync_consent.py +0 -3
- bugcap-0.5.0/src/bugcap/__init__.py +0 -1
- {bugcap-0.5.0 → bugcap-0.5.1}/LICENSE +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/setup.cfg +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/agent_api.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/backends.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/capture.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/config.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/dashboard/__init__.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/dashboard/api.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/dashboard/media.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/dashboard/server.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/dashboard/static/app.css +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/dashboard/static/app.js +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/dashboard/static/index.html +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/drafts.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/errors.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/ghcli.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/ingest.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/live_session.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/logs.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/mcp_server.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/paths.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/recorder.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/refs.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/repo.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/service.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/store.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/sync.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/tomlio.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap/validation.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap.egg-info/SOURCES.txt +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap.egg-info/dependency_links.txt +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap.egg-info/entry_points.txt +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/src/bugcap.egg-info/top_level.txt +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_agent_api.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_capture.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_cli_attach.py +1 -1
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_cli_dashboard.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_cli_record.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_dashboard_api.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_dashboard_media.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_dashboard_mutations.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_dashboard_security.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_dashboard_ui_static.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_ghcli.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_github_pull.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_image_refs.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_ingest_url.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_live_session.py +1 -1
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_paths.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_recorder_argv.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_recorder_devices.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_recorder_media_real.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_refs.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_repo_config.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_service_media.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_service_refs.py +0 -0
- {bugcap-0.5.0 → bugcap-0.5.1}/tests/test_store_migration.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bugcap
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.1
|
|
4
4
|
Summary: Local-first, agent-readable bug capture: annotated screenshots + notes, stored locally, synced to trackers on your own schedule.
|
|
5
5
|
Author: Konrad Tagnon Amen ALAHASSA
|
|
6
6
|
License: MIT
|
|
@@ -12,10 +12,11 @@ Provides-Extra: mcp
|
|
|
12
12
|
Requires-Dist: mcp<2,>=1.2; extra == "mcp"
|
|
13
13
|
Provides-Extra: dev
|
|
14
14
|
Requires-Dist: pytest>=7; extra == "dev"
|
|
15
|
+
Requires-Dist: ruff>=0.6; extra == "dev"
|
|
15
16
|
Dynamic: license-file
|
|
16
17
|
|
|
17
18
|
<p align="center">
|
|
18
|
-
<img src="docs/assets/logo.svg" alt="bugcap" width="96">
|
|
19
|
+
<img src="https://raw.githubusercontent.com/amenalahassa/bugcap/master/docs/assets/logo.svg" alt="bugcap" width="96">
|
|
19
20
|
</p>
|
|
20
21
|
|
|
21
22
|
<h1 align="center">bugcap</h1>
|
|
@@ -28,7 +29,7 @@ Dynamic: license-file
|
|
|
28
29
|
<p align="center">
|
|
29
30
|
<a href="https://github.com/amenalahassa/bugcap/actions/workflows/release.yml"><img alt="tests" src="https://github.com/amenalahassa/bugcap/actions/workflows/release.yml/badge.svg"></a>
|
|
30
31
|
<img alt="python" src="https://img.shields.io/badge/python-3.10%2B-3776ab?logo=python&logoColor=white">
|
|
31
|
-
<a href="LICENSE"><img alt="license" src="https://img.shields.io/badge/license-MIT-green"></a>
|
|
32
|
+
<a href="https://github.com/amenalahassa/bugcap/blob/master/LICENSE"><img alt="license" src="https://img.shields.io/badge/license-MIT-green"></a>
|
|
32
33
|
<a href="https://amenalahassa.github.io/bugcap/"><img alt="docs" src="https://img.shields.io/badge/docs-website-d9480f"></a>
|
|
33
34
|
</p>
|
|
34
35
|
|
|
@@ -37,11 +38,11 @@ Dynamic: license-file
|
|
|
37
38
|
<a href="https://amenalahassa.github.io/bugcap/usage.html">Usage guide</a> ·
|
|
38
39
|
<a href="#quick-start">Quick start</a> ·
|
|
39
40
|
<a href="#connect-your-agent-mcp">Agents (MCP)</a> ·
|
|
40
|
-
<a href="CHANGELOG.md">Changelog</a>
|
|
41
|
+
<a href="https://github.com/amenalahassa/bugcap/blob/master/CHANGELOG.md">Changelog</a>
|
|
41
42
|
</p>
|
|
42
43
|
|
|
43
44
|
<p align="center">
|
|
44
|
-
<img src="docs/assets/demo.gif" alt="bugcap
|
|
45
|
+
<img src="https://raw.githubusercontent.com/amenalahassa/bugcap/master/docs/assets/demo.gif" alt="bugcap live: screenshot a broken page, file a bug with a note, then read it back with bugcap show" width="760">
|
|
45
46
|
</p>
|
|
46
47
|
|
|
47
48
|
---
|
|
@@ -120,7 +121,7 @@ the error toast"*. It can read the picture because it's a local file, not a CDN
|
|
|
120
121
|
Working. Roadmap items 1–5, 7 and 8 are implemented and tested, along with spec 002 (images,
|
|
121
122
|
`@` references, recording, live mode and the dashboard). S3/R2 object storage (item 6) and other
|
|
122
123
|
trackers (item 9) are deferred. The `Destination` seam is in place, so they can be added without
|
|
123
|
-
changing the CLI. See [ROADMAP.md](ROADMAP.md).
|
|
124
|
+
changing the CLI. See [ROADMAP.md](https://github.com/amenalahassa/bugcap/blob/master/ROADMAP.md).
|
|
124
125
|
|
|
125
126
|
## Installation
|
|
126
127
|
|
|
@@ -150,9 +151,13 @@ Notes on the more involved behaviour:
|
|
|
150
151
|
- **Repo values** (`init`, `sync`, `config repo set`) are checked for format and, with `gh`, for existence. Changing the repo identity offers to move existing reports.
|
|
151
152
|
- **Media sync** over `[sync] max_upload_mb` (default 25) is skipped with a warning.
|
|
152
153
|
|
|
154
|
+
## Contributing
|
|
155
|
+
|
|
156
|
+
Contributions are welcome. Read [CONTRIBUTING.md](https://github.com/amenalahassa/bugcap/blob/master/CONTRIBUTING.md) for the workflow and project rules, and the [Code of Conduct](https://github.com/amenalahassa/bugcap/blob/master/CODE_OF_CONDUCT.md). Report security issues privately, see [SECURITY.md](https://github.com/amenalahassa/bugcap/blob/master/SECURITY.md).
|
|
157
|
+
|
|
153
158
|
## Development
|
|
154
159
|
|
|
155
|
-
See [DEVELOPMENT.md](DEVELOPMENT.md). Run the tests with:
|
|
160
|
+
See [DEVELOPMENT.md](https://github.com/amenalahassa/bugcap/blob/master/DEVELOPMENT.md). Run the tests with:
|
|
156
161
|
|
|
157
162
|
```bash
|
|
158
163
|
uv run --extra dev --extra mcp pytest -q
|
|
@@ -203,7 +208,7 @@ succeeds, so a re-run skips what is already recorded.
|
|
|
203
208
|
|
|
204
209
|
## Roadmap
|
|
205
210
|
|
|
206
|
-
See [ROADMAP.md](ROADMAP.md).
|
|
211
|
+
See [ROADMAP.md](https://github.com/amenalahassa/bugcap/blob/master/ROADMAP.md).
|
|
207
212
|
|
|
208
213
|
## Design notes / deliberate non-goals
|
|
209
214
|
|
|
@@ -222,4 +227,4 @@ See [ROADMAP.md](ROADMAP.md).
|
|
|
222
227
|
|
|
223
228
|
## License
|
|
224
229
|
|
|
225
|
-
MIT — see [LICENSE](LICENSE).
|
|
230
|
+
MIT — see [LICENSE](https://github.com/amenalahassa/bugcap/blob/master/LICENSE).
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="docs/assets/logo.svg" alt="bugcap" width="96">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/amenalahassa/bugcap/master/docs/assets/logo.svg" alt="bugcap" width="96">
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<h1 align="center">bugcap</h1>
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<p align="center">
|
|
13
13
|
<a href="https://github.com/amenalahassa/bugcap/actions/workflows/release.yml"><img alt="tests" src="https://github.com/amenalahassa/bugcap/actions/workflows/release.yml/badge.svg"></a>
|
|
14
14
|
<img alt="python" src="https://img.shields.io/badge/python-3.10%2B-3776ab?logo=python&logoColor=white">
|
|
15
|
-
<a href="LICENSE"><img alt="license" src="https://img.shields.io/badge/license-MIT-green"></a>
|
|
15
|
+
<a href="https://github.com/amenalahassa/bugcap/blob/master/LICENSE"><img alt="license" src="https://img.shields.io/badge/license-MIT-green"></a>
|
|
16
16
|
<a href="https://amenalahassa.github.io/bugcap/"><img alt="docs" src="https://img.shields.io/badge/docs-website-d9480f"></a>
|
|
17
17
|
</p>
|
|
18
18
|
|
|
@@ -21,11 +21,11 @@
|
|
|
21
21
|
<a href="https://amenalahassa.github.io/bugcap/usage.html">Usage guide</a> ·
|
|
22
22
|
<a href="#quick-start">Quick start</a> ·
|
|
23
23
|
<a href="#connect-your-agent-mcp">Agents (MCP)</a> ·
|
|
24
|
-
<a href="CHANGELOG.md">Changelog</a>
|
|
24
|
+
<a href="https://github.com/amenalahassa/bugcap/blob/master/CHANGELOG.md">Changelog</a>
|
|
25
25
|
</p>
|
|
26
26
|
|
|
27
27
|
<p align="center">
|
|
28
|
-
<img src="docs/assets/demo.gif" alt="bugcap
|
|
28
|
+
<img src="https://raw.githubusercontent.com/amenalahassa/bugcap/master/docs/assets/demo.gif" alt="bugcap live: screenshot a broken page, file a bug with a note, then read it back with bugcap show" width="760">
|
|
29
29
|
</p>
|
|
30
30
|
|
|
31
31
|
---
|
|
@@ -104,7 +104,7 @@ the error toast"*. It can read the picture because it's a local file, not a CDN
|
|
|
104
104
|
Working. Roadmap items 1–5, 7 and 8 are implemented and tested, along with spec 002 (images,
|
|
105
105
|
`@` references, recording, live mode and the dashboard). S3/R2 object storage (item 6) and other
|
|
106
106
|
trackers (item 9) are deferred. The `Destination` seam is in place, so they can be added without
|
|
107
|
-
changing the CLI. See [ROADMAP.md](ROADMAP.md).
|
|
107
|
+
changing the CLI. See [ROADMAP.md](https://github.com/amenalahassa/bugcap/blob/master/ROADMAP.md).
|
|
108
108
|
|
|
109
109
|
## Installation
|
|
110
110
|
|
|
@@ -134,9 +134,13 @@ Notes on the more involved behaviour:
|
|
|
134
134
|
- **Repo values** (`init`, `sync`, `config repo set`) are checked for format and, with `gh`, for existence. Changing the repo identity offers to move existing reports.
|
|
135
135
|
- **Media sync** over `[sync] max_upload_mb` (default 25) is skipped with a warning.
|
|
136
136
|
|
|
137
|
+
## Contributing
|
|
138
|
+
|
|
139
|
+
Contributions are welcome. Read [CONTRIBUTING.md](https://github.com/amenalahassa/bugcap/blob/master/CONTRIBUTING.md) for the workflow and project rules, and the [Code of Conduct](https://github.com/amenalahassa/bugcap/blob/master/CODE_OF_CONDUCT.md). Report security issues privately, see [SECURITY.md](https://github.com/amenalahassa/bugcap/blob/master/SECURITY.md).
|
|
140
|
+
|
|
137
141
|
## Development
|
|
138
142
|
|
|
139
|
-
See [DEVELOPMENT.md](DEVELOPMENT.md). Run the tests with:
|
|
143
|
+
See [DEVELOPMENT.md](https://github.com/amenalahassa/bugcap/blob/master/DEVELOPMENT.md). Run the tests with:
|
|
140
144
|
|
|
141
145
|
```bash
|
|
142
146
|
uv run --extra dev --extra mcp pytest -q
|
|
@@ -187,7 +191,7 @@ succeeds, so a re-run skips what is already recorded.
|
|
|
187
191
|
|
|
188
192
|
## Roadmap
|
|
189
193
|
|
|
190
|
-
See [ROADMAP.md](ROADMAP.md).
|
|
194
|
+
See [ROADMAP.md](https://github.com/amenalahassa/bugcap/blob/master/ROADMAP.md).
|
|
191
195
|
|
|
192
196
|
## Design notes / deliberate non-goals
|
|
193
197
|
|
|
@@ -206,4 +210,4 @@ See [ROADMAP.md](ROADMAP.md).
|
|
|
206
210
|
|
|
207
211
|
## License
|
|
208
212
|
|
|
209
|
-
MIT — see [LICENSE](LICENSE).
|
|
213
|
+
MIT — see [LICENSE](https://github.com/amenalahassa/bugcap/blob/master/LICENSE).
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "bugcap"
|
|
7
|
-
version = "0.5.
|
|
7
|
+
version = "0.5.1"
|
|
8
8
|
description = "Local-first, agent-readable bug capture: annotated screenshots + notes, stored locally, synced to trackers on your own schedule."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -14,7 +14,7 @@ dependencies = ["tomli>=2; python_version < '3.11'"]
|
|
|
14
14
|
|
|
15
15
|
[project.optional-dependencies]
|
|
16
16
|
mcp = ["mcp>=1.2,<2"]
|
|
17
|
-
dev = ["pytest>=7"]
|
|
17
|
+
dev = ["pytest>=7", "ruff>=0.6"]
|
|
18
18
|
|
|
19
19
|
[project.scripts]
|
|
20
20
|
bugcap = "bugcap.cli:main"
|
|
@@ -27,3 +27,13 @@ bugcap = ["dashboard/static/*"]
|
|
|
27
27
|
|
|
28
28
|
[tool.pytest.ini_options]
|
|
29
29
|
testpaths = ["tests"]
|
|
30
|
+
|
|
31
|
+
[tool.ruff]
|
|
32
|
+
line-length = 120
|
|
33
|
+
target-version = "py310"
|
|
34
|
+
|
|
35
|
+
[tool.ruff.lint]
|
|
36
|
+
select = ["E4", "E7", "E9", "F", "I"]
|
|
37
|
+
|
|
38
|
+
[tool.ruff.lint.per-file-ignores]
|
|
39
|
+
"tests/*" = ["E702", "E731"]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.5.1"
|
|
@@ -7,13 +7,12 @@ import threading
|
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
from typing import Optional
|
|
9
9
|
|
|
10
|
-
from . import backends, capture, config, ghcli, recorder, refs, repo, service, sync, validation
|
|
10
|
+
from . import __version__, backends, capture, config, ghcli, recorder, refs, repo, service, sync, validation
|
|
11
11
|
from .capture import CaptureError
|
|
12
12
|
from .errors import ServiceError
|
|
13
13
|
from .ghcli import GhError
|
|
14
14
|
from .store import STATUSES, Store
|
|
15
15
|
|
|
16
|
-
|
|
17
16
|
# --- shared helpers (T014) ----------------------------------------------------
|
|
18
17
|
|
|
19
18
|
def current_repo():
|
|
@@ -161,7 +160,7 @@ def print_report(report) -> None:
|
|
|
161
160
|
print(f" repo: {report.repo}")
|
|
162
161
|
print(f" tags: {', '.join(report.tags) or '(none)'}")
|
|
163
162
|
print(f" notes: {refs.display_notes(report.notes, report.media) or '(none)'}")
|
|
164
|
-
print(
|
|
163
|
+
print(" images:")
|
|
165
164
|
for path in report.image_paths:
|
|
166
165
|
print(f" - {path}")
|
|
167
166
|
detailed = [m for m in report.media if not (m.kind == "image" and m.source == "legacy")]
|
|
@@ -171,7 +170,7 @@ def print_report(report) -> None:
|
|
|
171
170
|
where = m.path or f"({len(m.frames)} frames)"
|
|
172
171
|
origin = f" (source: {m.source})" if m.source else ""
|
|
173
172
|
print(f" {refs.media_token(m)} {m.kind:8s} {m.label or '-':12s} {where} {human_size(m.size_bytes)}{origin}")
|
|
174
|
-
print(
|
|
173
|
+
print(" synced_refs:")
|
|
175
174
|
if report.synced_refs:
|
|
176
175
|
for tracker, ref in report.synced_refs.items():
|
|
177
176
|
print(f" - {tracker}: {ref}")
|
|
@@ -850,6 +849,7 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
850
849
|
prog="bugcap",
|
|
851
850
|
description="Local-first, agent-readable bug capture: annotated screenshots + notes.",
|
|
852
851
|
)
|
|
852
|
+
parser.add_argument("--version", action="version", version=f"bugcap {__version__}")
|
|
853
853
|
sub = parser.add_subparsers(dest="command", required=True)
|
|
854
854
|
|
|
855
855
|
p = sub.add_parser("setup", help="Detect a capture tool, or recommend/install one.")
|
|
@@ -85,7 +85,7 @@ class _App:
|
|
|
85
85
|
|
|
86
86
|
def style(self) -> None:
|
|
87
87
|
"""One consistent look for every window: a flat light theme with an accent button."""
|
|
88
|
-
|
|
88
|
+
ttk = self.ttk
|
|
89
89
|
import tkinter.font as tkfont
|
|
90
90
|
|
|
91
91
|
base = tkfont.nametofont("TkDefaultFont")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bugcap
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.1
|
|
4
4
|
Summary: Local-first, agent-readable bug capture: annotated screenshots + notes, stored locally, synced to trackers on your own schedule.
|
|
5
5
|
Author: Konrad Tagnon Amen ALAHASSA
|
|
6
6
|
License: MIT
|
|
@@ -12,10 +12,11 @@ Provides-Extra: mcp
|
|
|
12
12
|
Requires-Dist: mcp<2,>=1.2; extra == "mcp"
|
|
13
13
|
Provides-Extra: dev
|
|
14
14
|
Requires-Dist: pytest>=7; extra == "dev"
|
|
15
|
+
Requires-Dist: ruff>=0.6; extra == "dev"
|
|
15
16
|
Dynamic: license-file
|
|
16
17
|
|
|
17
18
|
<p align="center">
|
|
18
|
-
<img src="docs/assets/logo.svg" alt="bugcap" width="96">
|
|
19
|
+
<img src="https://raw.githubusercontent.com/amenalahassa/bugcap/master/docs/assets/logo.svg" alt="bugcap" width="96">
|
|
19
20
|
</p>
|
|
20
21
|
|
|
21
22
|
<h1 align="center">bugcap</h1>
|
|
@@ -28,7 +29,7 @@ Dynamic: license-file
|
|
|
28
29
|
<p align="center">
|
|
29
30
|
<a href="https://github.com/amenalahassa/bugcap/actions/workflows/release.yml"><img alt="tests" src="https://github.com/amenalahassa/bugcap/actions/workflows/release.yml/badge.svg"></a>
|
|
30
31
|
<img alt="python" src="https://img.shields.io/badge/python-3.10%2B-3776ab?logo=python&logoColor=white">
|
|
31
|
-
<a href="LICENSE"><img alt="license" src="https://img.shields.io/badge/license-MIT-green"></a>
|
|
32
|
+
<a href="https://github.com/amenalahassa/bugcap/blob/master/LICENSE"><img alt="license" src="https://img.shields.io/badge/license-MIT-green"></a>
|
|
32
33
|
<a href="https://amenalahassa.github.io/bugcap/"><img alt="docs" src="https://img.shields.io/badge/docs-website-d9480f"></a>
|
|
33
34
|
</p>
|
|
34
35
|
|
|
@@ -37,11 +38,11 @@ Dynamic: license-file
|
|
|
37
38
|
<a href="https://amenalahassa.github.io/bugcap/usage.html">Usage guide</a> ·
|
|
38
39
|
<a href="#quick-start">Quick start</a> ·
|
|
39
40
|
<a href="#connect-your-agent-mcp">Agents (MCP)</a> ·
|
|
40
|
-
<a href="CHANGELOG.md">Changelog</a>
|
|
41
|
+
<a href="https://github.com/amenalahassa/bugcap/blob/master/CHANGELOG.md">Changelog</a>
|
|
41
42
|
</p>
|
|
42
43
|
|
|
43
44
|
<p align="center">
|
|
44
|
-
<img src="docs/assets/demo.gif" alt="bugcap
|
|
45
|
+
<img src="https://raw.githubusercontent.com/amenalahassa/bugcap/master/docs/assets/demo.gif" alt="bugcap live: screenshot a broken page, file a bug with a note, then read it back with bugcap show" width="760">
|
|
45
46
|
</p>
|
|
46
47
|
|
|
47
48
|
---
|
|
@@ -120,7 +121,7 @@ the error toast"*. It can read the picture because it's a local file, not a CDN
|
|
|
120
121
|
Working. Roadmap items 1–5, 7 and 8 are implemented and tested, along with spec 002 (images,
|
|
121
122
|
`@` references, recording, live mode and the dashboard). S3/R2 object storage (item 6) and other
|
|
122
123
|
trackers (item 9) are deferred. The `Destination` seam is in place, so they can be added without
|
|
123
|
-
changing the CLI. See [ROADMAP.md](ROADMAP.md).
|
|
124
|
+
changing the CLI. See [ROADMAP.md](https://github.com/amenalahassa/bugcap/blob/master/ROADMAP.md).
|
|
124
125
|
|
|
125
126
|
## Installation
|
|
126
127
|
|
|
@@ -150,9 +151,13 @@ Notes on the more involved behaviour:
|
|
|
150
151
|
- **Repo values** (`init`, `sync`, `config repo set`) are checked for format and, with `gh`, for existence. Changing the repo identity offers to move existing reports.
|
|
151
152
|
- **Media sync** over `[sync] max_upload_mb` (default 25) is skipped with a warning.
|
|
152
153
|
|
|
154
|
+
## Contributing
|
|
155
|
+
|
|
156
|
+
Contributions are welcome. Read [CONTRIBUTING.md](https://github.com/amenalahassa/bugcap/blob/master/CONTRIBUTING.md) for the workflow and project rules, and the [Code of Conduct](https://github.com/amenalahassa/bugcap/blob/master/CODE_OF_CONDUCT.md). Report security issues privately, see [SECURITY.md](https://github.com/amenalahassa/bugcap/blob/master/SECURITY.md).
|
|
157
|
+
|
|
153
158
|
## Development
|
|
154
159
|
|
|
155
|
-
See [DEVELOPMENT.md](DEVELOPMENT.md). Run the tests with:
|
|
160
|
+
See [DEVELOPMENT.md](https://github.com/amenalahassa/bugcap/blob/master/DEVELOPMENT.md). Run the tests with:
|
|
156
161
|
|
|
157
162
|
```bash
|
|
158
163
|
uv run --extra dev --extra mcp pytest -q
|
|
@@ -203,7 +208,7 @@ succeeds, so a re-run skips what is already recorded.
|
|
|
203
208
|
|
|
204
209
|
## Roadmap
|
|
205
210
|
|
|
206
|
-
See [ROADMAP.md](ROADMAP.md).
|
|
211
|
+
See [ROADMAP.md](https://github.com/amenalahassa/bugcap/blob/master/ROADMAP.md).
|
|
207
212
|
|
|
208
213
|
## Design notes / deliberate non-goals
|
|
209
214
|
|
|
@@ -222,4 +227,4 @@ See [ROADMAP.md](ROADMAP.md).
|
|
|
222
227
|
|
|
223
228
|
## License
|
|
224
229
|
|
|
225
|
-
MIT — see [LICENSE](LICENSE).
|
|
230
|
+
MIT — see [LICENSE](https://github.com/amenalahassa/bugcap/blob/master/LICENSE).
|
|
@@ -20,8 +20,12 @@ def test_missing_tkinter_exits_3_with_install_hint(monkeypatch, capsys):
|
|
|
20
20
|
assert "python3-tk" in capsys.readouterr().err
|
|
21
21
|
|
|
22
22
|
|
|
23
|
+
@pytest.mark.skipif(
|
|
24
|
+
sys.platform in ("win32", "darwin"),
|
|
25
|
+
reason="DISPLAY only means something on X11; elsewhere Tk opens a real window and blocks",
|
|
26
|
+
)
|
|
23
27
|
def test_unreachable_display_exits_3(monkeypatch, capsys):
|
|
24
|
-
|
|
28
|
+
pytest.importorskip("tkinter")
|
|
25
29
|
monkeypatch.setenv("DISPLAY", ":99999")
|
|
26
30
|
assert cli.main(["live"]) == 3
|
|
27
31
|
assert "cannot open a window" in capsys.readouterr().err
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""`capture --no-image` saves a text-only report; `delete` removes a report and its files."""
|
|
2
|
-
import pytest
|
|
3
2
|
|
|
4
3
|
from fixtures.make_images import png_bytes
|
|
4
|
+
|
|
5
5
|
from bugcap import cli, service
|
|
6
6
|
from bugcap.paths import resolve_data_path
|
|
7
7
|
from bugcap.store import Store
|
|
@@ -79,3 +79,12 @@ def test_no_package_manager_prints_guidance(monkeypatch, record_run, capsys):
|
|
|
79
79
|
assert cli.main(["setup"]) == 1
|
|
80
80
|
assert "manually" in capsys.readouterr().err.lower()
|
|
81
81
|
assert record_run == []
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def test_version_flag(capsys):
|
|
85
|
+
from bugcap import __version__
|
|
86
|
+
|
|
87
|
+
with pytest.raises(SystemExit) as exc:
|
|
88
|
+
cli.main(["--version"])
|
|
89
|
+
assert exc.value.code == 0
|
|
90
|
+
assert capsys.readouterr().out.strip() == f"bugcap {__version__}"
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
import base64
|
|
3
3
|
import json
|
|
4
4
|
|
|
5
|
+
from fixtures.make_images import png_bytes
|
|
6
|
+
|
|
5
7
|
from bugcap import service, sync
|
|
6
8
|
from bugcap.store import Store
|
|
7
9
|
from bugcap.sync import GitHubDestination, ImagesTarget, SyncOptions
|
|
8
|
-
from fixtures.make_images import png_bytes
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
def _setup(fake_gh):
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
1
3
|
import pytest
|
|
4
|
+
from fixtures.make_images import gif_bytes, jpeg_bytes, png_bytes, webp_bytes
|
|
2
5
|
|
|
3
6
|
from bugcap import ingest
|
|
4
7
|
from bugcap.errors import ServiceError
|
|
5
|
-
from fixtures.make_images import gif_bytes, jpeg_bytes, png_bytes, webp_bytes
|
|
6
8
|
|
|
7
9
|
|
|
8
10
|
def test_classify_sources(tmp_path):
|
|
@@ -54,7 +56,7 @@ def test_import_copies_into_store(bugcap_home, sample_images):
|
|
|
54
56
|
|
|
55
57
|
def test_glob_sorted_and_no_match(sample_images):
|
|
56
58
|
matches = ingest.resolve_glob(str(sample_images / "sample.*"))
|
|
57
|
-
assert [m.
|
|
59
|
+
assert [Path(m).name for m in matches] == ["sample.gif", "sample.jpg", "sample.png", "sample.webp"]
|
|
58
60
|
items = ingest.expand_sources([str(sample_images / "nope-*.png")])
|
|
59
61
|
assert items[0].error.code == "not_found" and "nope-*.png" in items[0].error.message
|
|
60
62
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import signal
|
|
2
2
|
import subprocess
|
|
3
|
+
from pathlib import Path
|
|
3
4
|
|
|
4
5
|
import pytest
|
|
5
6
|
|
|
@@ -156,11 +157,10 @@ def test_animated_runs_postprocess_and_removes_raw(env, tmp_path):
|
|
|
156
157
|
|
|
157
158
|
|
|
158
159
|
def test_frames_result(env, tmp_path):
|
|
159
|
-
frames_dir_files = []
|
|
160
160
|
|
|
161
161
|
def runner(argv, **kw):
|
|
162
162
|
pattern = argv[-1]
|
|
163
|
-
folder =
|
|
163
|
+
folder = Path(pattern).parent
|
|
164
164
|
for n in (1, 2, 3):
|
|
165
165
|
(folder / f"frame-00{n}.png").write_bytes(b"x")
|
|
166
166
|
return subprocess.CompletedProcess(argv, 0, "", "")
|
|
@@ -168,7 +168,7 @@ def test_frames_result(env, tmp_path):
|
|
|
168
168
|
result = recorder.run_recording("ffmpeg", "frames", 5, 30, 25, tmp_path, lambda: True,
|
|
169
169
|
**env.kwargs(runner=runner))
|
|
170
170
|
assert result.kind == "frames" and len(result.frames) == 3 and result.path is None
|
|
171
|
-
assert [p.
|
|
171
|
+
assert [Path(p).name for p, _ in result.frames] == ["frame-001.png", "frame-002.png", "frame-003.png"]
|
|
172
172
|
|
|
173
173
|
|
|
174
174
|
def test_macos_probes_screen_device(env, tmp_path):
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
The expected strings below are the exact pre-feature formats; the test fails if any
|
|
4
4
|
scoping/repo change leaks into output when there is no .bugcap.toml in scope."""
|
|
5
|
-
import pytest
|
|
6
5
|
|
|
7
6
|
from fixtures.make_images import png_bytes
|
|
7
|
+
|
|
8
8
|
from bugcap import cli
|
|
9
9
|
from bugcap.store import Store
|
|
10
10
|
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
"""T031: image-commit consent rules (FR-018a) and images-target resolution (FR-018b/R2)."""
|
|
2
|
-
import base64
|
|
3
2
|
import json
|
|
4
3
|
|
|
5
|
-
import pytest
|
|
6
|
-
|
|
7
4
|
from bugcap import config, repo, sync
|
|
8
5
|
from bugcap.store import Store
|
|
9
6
|
from bugcap.sync import GitHubDestination, ImagesTarget, SyncOptions, resolve_images_target
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.5.0"
|
|
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
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
|
|
3
3
|
import pytest
|
|
4
|
+
from fixtures.make_images import png_bytes
|
|
4
5
|
|
|
5
6
|
from bugcap import drafts, live_session, recorder
|
|
6
7
|
from bugcap.errors import ServiceError
|
|
7
8
|
from bugcap.live_session import LiveSession, LiveState
|
|
8
9
|
from bugcap.paths import images_dir, media_dir
|
|
9
10
|
from bugcap.store import Store
|
|
10
|
-
from fixtures.make_images import png_bytes
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class Cfg:
|
|
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
|