appsnap 0.2.0__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.
@@ -0,0 +1,59 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*" # Trigger on version tags like v0.2.0, v1.0.0, etc.
7
+ release:
8
+ types: [published] # Also trigger on GitHub releases
9
+ workflow_dispatch: # Allow manual trigger from Actions tab
10
+
11
+ jobs:
12
+ build-and-publish:
13
+ runs-on: ubuntu-latest
14
+
15
+ steps:
16
+ - name: Checkout code
17
+ uses: actions/checkout@v4
18
+
19
+ - name: Set up Python
20
+ uses: actions/setup-python@v5
21
+ with:
22
+ python-version: "3.11"
23
+
24
+ - name: Install uv
25
+ uses: astral-sh/setup-uv@v3
26
+
27
+ - name: Install build dependencies
28
+ run: |
29
+ uv pip install --system build twine
30
+
31
+ - name: Build package
32
+ run: |
33
+ python -m build
34
+
35
+ - name: Check package
36
+ run: |
37
+ twine check dist/*
38
+
39
+ - name: Publish to PyPI
40
+ env:
41
+ TWINE_USERNAME: __token__
42
+ TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
43
+ run: |
44
+ twine upload dist/*
45
+
46
+ - name: Upload build artifacts
47
+ uses: actions/upload-artifact@v4
48
+ with:
49
+ name: dist
50
+ path: dist/
51
+
52
+ - name: Create GitHub Release (if tag push)
53
+ if: startsWith(github.ref, 'refs/tags/')
54
+ uses: softprops/action-gh-release@v1
55
+ with:
56
+ files: dist/*
57
+ generate_release_notes: true
58
+ env:
59
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,48 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [main, master]
6
+ pull_request:
7
+ branches: [main, master]
8
+ workflow_dispatch:
9
+
10
+ jobs:
11
+ test:
12
+ runs-on: windows-latest
13
+
14
+ strategy:
15
+ matrix:
16
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
17
+
18
+ steps:
19
+ - name: Checkout code
20
+ uses: actions/checkout@v4
21
+
22
+ - name: Set up Python ${{ matrix.python-version }}
23
+ uses: actions/setup-python@v5
24
+ with:
25
+ python-version: ${{ matrix.python-version }}
26
+
27
+ - name: Install uv
28
+ uses: astral-sh/setup-uv@v3
29
+
30
+ - name: Install dependencies
31
+ run: |
32
+ uv pip install --system -e .
33
+
34
+ - name: Test CLI
35
+ run: |
36
+ appsnap --version
37
+ appsnap --help
38
+ appsnap --list
39
+
40
+ - name: Build package
41
+ run: |
42
+ uv pip install --system build
43
+ python -m build
44
+
45
+ - name: Check distribution
46
+ run: |
47
+ uv pip install --system twine
48
+ twine check dist/*
@@ -0,0 +1,154 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ *.manifest
31
+ *.spec
32
+
33
+ # Installer logs
34
+ pip-log.txt
35
+ pip-delete-this-directory.txt
36
+
37
+ # Unit test / coverage reports
38
+ htmlcov/
39
+ .tox/
40
+ .nox/
41
+ .coverage
42
+ .coverage.*
43
+ .cache
44
+ nosetests.xml
45
+ coverage.xml
46
+ *.cover
47
+ *.py,cover
48
+ .hypothesis/
49
+ .pytest_cache/
50
+ cover/
51
+
52
+ # Translations
53
+ *.mo
54
+ *.pot
55
+
56
+ # Django stuff:
57
+ *.log
58
+ local_settings.py
59
+ db.sqlite3
60
+ db.sqlite3-journal
61
+
62
+ # Flask stuff:
63
+ instance/
64
+ .webassets-cache
65
+
66
+ # Scrapy stuff:
67
+ .scrapy
68
+
69
+ # Sphinx documentation
70
+ docs/_build/
71
+
72
+ # PyBuilder
73
+ .pybuilder/
74
+ target/
75
+
76
+ # Jupyter Notebook
77
+ .ipynb_checkpoints
78
+
79
+ # IPython
80
+ profile_default/
81
+ ipython_config.py
82
+
83
+ # pyenv
84
+ .python-version
85
+
86
+ # pipenv
87
+ Pipfile.lock
88
+
89
+ # poetry
90
+ poetry.lock
91
+
92
+ # pdm
93
+ .pdm.toml
94
+
95
+ # PEP 582
96
+ __pypackages__/
97
+
98
+ # Celery stuff
99
+ celerybeat-schedule
100
+ celerybeat.pid
101
+
102
+ # SageMath parsed files
103
+ *.sage.py
104
+
105
+ # Environments
106
+ .env
107
+ .venv
108
+ env/
109
+ venv/
110
+ ENV/
111
+ env.bak/
112
+ venv.bak/
113
+
114
+ # Spyder project settings
115
+ .spyderproject
116
+ .spyproject
117
+
118
+ # Rope project settings
119
+ .ropeproject
120
+
121
+ # mkdocs documentation
122
+ /site
123
+
124
+ # mypy
125
+ .mypy_cache/
126
+ .dmypy.json
127
+ dmypy.json
128
+
129
+ # Pyre type checker
130
+ .pyre/
131
+
132
+ # pytype static type analyzer
133
+ .pytype/
134
+
135
+ # Cython debug symbols
136
+ cython_debug/
137
+
138
+ # IDEs
139
+ .vscode/
140
+ .idea/
141
+ *.swp
142
+ *.swo
143
+ *~
144
+
145
+ # OS
146
+ .DS_Store
147
+ Thumbs.db
148
+
149
+ # Project specific
150
+ *.png
151
+ *.jpg
152
+ *.jpeg
153
+ *.bmp
154
+ screenshots/
appsnap-0.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 appsnap contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,5 @@
1
+ include README.md
2
+ include LICENSE
3
+ include PUBLISHING.md
4
+ include pyproject.toml
5
+ recursive-include src *.py
appsnap-0.2.0/PKG-INFO ADDED
@@ -0,0 +1,281 @@
1
+ Metadata-Version: 2.4
2
+ Name: appsnap
3
+ Version: 0.2.0
4
+ Summary: Fast Windows screenshot tool for AI coding agents
5
+ Project-URL: Homepage, https://github.com/detroittommy879/appsnap
6
+ Project-URL: Repository, https://github.com/detroittommy879/appsnap
7
+ Project-URL: Issues, https://github.com/detroittommy879/appsnap/issues
8
+ Project-URL: Documentation, https://github.com/detroittommy879/appsnap#readme
9
+ Project-URL: Changelog, https://github.com/detroittommy879/appsnap/releases
10
+ Author: appsnap contributors
11
+ License: MIT
12
+ License-File: LICENSE
13
+ Keywords: ai-agent,automation,cli,desktop,screenshot,windows
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Environment :: Console
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: License :: OSI Approved :: MIT License
18
+ Classifier: Operating System :: Microsoft :: Windows
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Topic :: Software Development :: Testing
25
+ Classifier: Topic :: Utilities
26
+ Requires-Python: >=3.10
27
+ Requires-Dist: fuzzywuzzy>=0.18.0
28
+ Requires-Dist: pillow>=11.0.0
29
+ Requires-Dist: python-levenshtein>=0.25.0
30
+ Requires-Dist: pywin32>=306
31
+ Provides-Extra: dev
32
+ Requires-Dist: black>=24.0.0; extra == 'dev'
33
+ Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
34
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
35
+ Requires-Dist: ruff>=0.3.0; extra == 'dev'
36
+ Description-Content-Type: text/markdown
37
+
38
+ # 📸 appsnap
39
+
40
+ **Fast Windows screenshot tool for AI coding agents**
41
+
42
+ `appsnap` is a simple, fast CLI tool for capturing screenshots of Windows application windows. Perfect for AI agents that need to verify UI changes during development iterations.
43
+
44
+ ## ✨ Features
45
+
46
+ - 🎯 **Window-specific capture** - Target apps by name with fuzzy matching
47
+ - � **Bulk capture** - Screenshot all windows at once for testing
48
+ - 🚀 **Fast** - Screenshots in ~0.1-0.3 seconds
49
+ - 🤖 **Agent-friendly** - JSON output and stdout paths for easy parsing
50
+ - 📁 **Smart defaults** - Temp directory with auto-cleanup
51
+ - 🔍 **List windows** - See all capturable windows
52
+ - 🎨 **DPI-aware** - Handles high-DPI displays correctly
53
+ - 🔢 **Duplicate handling** - Auto-numbers windows with identical titles
54
+
55
+ ## 🚀 Quick Start
56
+
57
+ ### Installation
58
+
59
+ ```bash
60
+ # Install from PyPI with uvx (recommended)
61
+ uvx appsnap
62
+
63
+ # Or install as a tool with uv
64
+ uv tool install appsnap
65
+
66
+ # Or with pipx
67
+ pipx install appsnap
68
+
69
+ # Install from GitHub (development version)
70
+ uv tool install git+https://github.com/detroittommy879/appsnap.git
71
+
72
+ # Development mode (local testing)
73
+ git clone https://github.com/detroittommy879/appsnap.git
74
+ cd appsnap
75
+ uv venv
76
+ uv pip install -e .
77
+ ```
78
+
79
+ ### Usage
80
+
81
+ **Option 1: After activating venv**
82
+
83
+ ```bash
84
+ # Activate the virtual environment first
85
+ .venv\Scripts\activate # Windows
86
+ # source .venv/bin/activate # Linux/Mac
87
+
88
+ # Then use appsnap directly
89
+ appsnap --list
90
+ appsnap "Visual Studio Code"
91
+ ```
92
+
93
+ **Option 2: Using uv run (no activation needed)**
94
+
95
+ ```bash
96
+ # Run from within the appsnap directory
97
+ cd appsnap
98
+ uv run appsnap --list
99
+ uv run appsnap "Chrome" --output screenshot.png
100
+ ```
101
+
102
+ **Common Commands:**
103
+
104
+ ```bash
105
+ # List all capturable windows
106
+ appsnap --list
107
+
108
+ # Capture a window (saves to temp directory)
109
+ appsnap "Visual Studio Code"
110
+
111
+ # Capture with custom output path
112
+ appsnap "Chrome" --output screenshot.png
113
+
114
+ # JSON output for agents
115
+ appsnap "Notepad" --json
116
+ # {"path": "C:\\Temp\\appsnap\\appsnap_20260202_153045.png", "window": "Notepad", "bbox": [100, 200, 800, 600]}
117
+
118
+ # Adjust fuzzy matching threshold (0-100, default 70)
119
+ appsnap "VS" --threshold 60
120
+
121
+ # Capture ALL windows to a folder (great for testing!)
122
+ appsnap --all ./screenshots
123
+
124
+ # Capture all with JSON summary
125
+ appsnap --all ./test-screens --json
126
+ ```
127
+
128
+ ## 🤖 AI Agent Integration
129
+
130
+ ### Claude Desktop Skill
131
+
132
+ Add to your agent prompt or skill:
133
+
134
+ ```
135
+ When you need to verify UI changes, use: appsnap "App Name" --json
136
+ Parse the JSON output to get the screenshot path and window metadata.
137
+ ```
138
+
139
+ ### Python Integration
140
+
141
+ ```python
142
+ import subprocess
143
+ import json
144
+
145
+ result = subprocess.run(
146
+ ["appsnap", "Chrome", "--json"],
147
+ capture_output=True,
148
+ text=True
149
+ )
150
+ data = json.loads(result.stdout)
151
+ screenshot_path = data["path"]
152
+ ```
153
+
154
+ ### PowerShell Integration
155
+
156
+ ```powershell
157
+ $result = appsnap "VSCode" --json | ConvertFrom-Json
158
+ Write-Host "Screenshot: $($result.path)"
159
+ ```
160
+
161
+ ## 📖 CLI Options
162
+
163
+ ```
164
+ positional arguments:
165
+ window_name Window title to search for (fuzzy matching)
166
+
167
+ options:
168
+ -h, --help Show this help message and exit
169
+ -l, --list List all capturable windows
170
+ -a DIR, --all DIR Capture all windows to specified directory
171
+ -o PATH, --output PATH
172
+ Output file path (default: temp directory)
173
+ -t N, --threshold N Fuzzy match threshold 0-100 (default: 70)
174
+ -j, --json Output JSON with path and metadata
175
+ ```
176
+
177
+ ### Bulk Capture Example
178
+
179
+ The `--all` flag is perfect for quickly testing that all windows capture correctly:
180
+
181
+ ```bash
182
+ # Capture all windows to a test folder
183
+ uv run appsnap --all ./test-captures
184
+
185
+ # Output:
186
+ # Capturing 42 window(s) to C:\path\to\test-captures...
187
+ #
188
+ # [OK] Visual Studio Code
189
+ # [OK] Chrome - Google Search
190
+ # [OK] Task Manager
191
+ # [OK] Settings
192
+ # [OK] PowerShell_1 # Auto-numbered duplicate
193
+ # [OK] PowerShell_2 # Auto-numbered duplicate
194
+ # ...
195
+ #
196
+ # Complete: 40 successful, 2 failed
197
+ # Screenshots saved to: C:\path\to\test-captures
198
+ ```
199
+
200
+ Windows with the same title automatically get numbered (e.g., `PowerShell_1.png`, `PowerShell_2.png`).
201
+
202
+ ## 🛠️ How It Works
203
+
204
+ 1. **DPI Awareness** - Sets process DPI awareness for correct scaling on high-DPI displays
205
+ 2. **Window Enumeration** - Uses Win32 API to enumerate all visible, non-minimized windows
206
+ 3. **Fuzzy Matching** - Finds windows using `fuzzywuzzy` for flexible name matching
207
+ 4. **Direct Window Capture** - Uses Win32 `PrintWindow` API to capture window content directly (works even when partially occluded)
208
+ 5. **Output** - Saves to temp or custom location, prints path to stdout for easy agent parsing
209
+
210
+ ## 🔧 Development
211
+
212
+ ```bash
213
+ # Clone and install dev dependencies
214
+ git clone <repo>
215
+ cd appsnap
216
+ uv pip install -e ".[dev]"
217
+
218
+ # Run tests
219
+ uv run pytest
220
+
221
+ # Run with local changes
222
+ uv run appsnap --list
223
+ ```
224
+
225
+ ## 🐛 Troubleshooting
226
+
227
+ ### "No window found matching..."
228
+
229
+ - Use `appsnap --list` to see exact window titles
230
+ - Try lowering the threshold: `--threshold 60`
231
+ - Make sure the window is visible (not minimized)
232
+
233
+ ### Screenshots are blank, wrong window, or multiple windows
234
+
235
+ **v0.1.1 Fix:** Switched to Win32 PrintWindow API for direct window content capture.
236
+
237
+ This method captures the actual window content, not screen regions, so it:
238
+
239
+ - Works correctly on multi-monitor setups
240
+ - Captures partially occluded windows
241
+ - Handles DPI scaling properly
242
+
243
+ If you still have issues:
244
+
245
+ - Ensure the window is not minimized (minimized windows cannot be captured)
246
+ - Some apps (especially GPU-accelerated ones) may not respond to PrintWindow correctly
247
+ - Try bringing the window to foreground if capture fails
248
+
249
+ ### DPI/Scaling issues
250
+
251
+ The tool automatically handles DPI awareness. If you see incorrect sizing:
252
+
253
+ - Ensure Windows display scaling is consistent
254
+ - Check that the app respects DPI settings
255
+
256
+ ## 📝 License
257
+
258
+ MIT License - see [LICENSE](LICENSE) for details
259
+
260
+ ## 🙏 Acknowledgments
261
+
262
+ Built on the excellent Windows-MCP project patterns and libraries:
263
+
264
+ - [Pillow](https://github.com/python-pillow/Pillow) - Screenshot capture and image processing
265
+ - [fuzzywuzzy](https://github.com/seatgeek/fuzzywuzzy) - Fuzzy string matching
266
+ - [pywin32](https://github.com/mhammond/pywin32) - Windows API access
267
+
268
+ ## 🤝 Contributing
269
+
270
+ Contributions welcome! Please feel free to submit issues or pull requests.
271
+
272
+ For maintainers publishing to PyPI, see [PUBLISHING.md](PUBLISHING.md) for detailed instructions on:
273
+
274
+ - Setting up GitHub Actions for automated PyPI releases
275
+ - Manual publishing workflow
276
+ - AI agent skill integration
277
+ - Troubleshooting
278
+
279
+ ---
280
+
281
+ Made for AI agents, by developers 🤖❤️