gwc-pybundle 2.1.2__py3-none-any.whl

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.

Potentially problematic release.


This version of gwc-pybundle might be problematic. Click here for more details.

Files changed (82) hide show
  1. gwc_pybundle-2.1.2.dist-info/METADATA +903 -0
  2. gwc_pybundle-2.1.2.dist-info/RECORD +82 -0
  3. gwc_pybundle-2.1.2.dist-info/WHEEL +5 -0
  4. gwc_pybundle-2.1.2.dist-info/entry_points.txt +2 -0
  5. gwc_pybundle-2.1.2.dist-info/licenses/LICENSE.md +25 -0
  6. gwc_pybundle-2.1.2.dist-info/top_level.txt +1 -0
  7. pybundle/__init__.py +0 -0
  8. pybundle/__main__.py +4 -0
  9. pybundle/cli.py +546 -0
  10. pybundle/context.py +404 -0
  11. pybundle/doctor.py +148 -0
  12. pybundle/filters.py +228 -0
  13. pybundle/manifest.py +77 -0
  14. pybundle/packaging.py +45 -0
  15. pybundle/policy.py +132 -0
  16. pybundle/profiles.py +454 -0
  17. pybundle/roadmap_model.py +42 -0
  18. pybundle/roadmap_scan.py +328 -0
  19. pybundle/root_detect.py +14 -0
  20. pybundle/runner.py +180 -0
  21. pybundle/steps/__init__.py +26 -0
  22. pybundle/steps/ai_context.py +791 -0
  23. pybundle/steps/api_docs.py +219 -0
  24. pybundle/steps/asyncio_analysis.py +358 -0
  25. pybundle/steps/bandit.py +72 -0
  26. pybundle/steps/base.py +20 -0
  27. pybundle/steps/blocking_call_detection.py +291 -0
  28. pybundle/steps/call_graph.py +219 -0
  29. pybundle/steps/compileall.py +76 -0
  30. pybundle/steps/config_docs.py +319 -0
  31. pybundle/steps/config_validation.py +302 -0
  32. pybundle/steps/container_image.py +294 -0
  33. pybundle/steps/context_expand.py +272 -0
  34. pybundle/steps/copy_pack.py +293 -0
  35. pybundle/steps/coverage.py +101 -0
  36. pybundle/steps/cprofile_step.py +166 -0
  37. pybundle/steps/dependency_sizes.py +136 -0
  38. pybundle/steps/django_checks.py +214 -0
  39. pybundle/steps/dockerfile_lint.py +282 -0
  40. pybundle/steps/dockerignore.py +311 -0
  41. pybundle/steps/duplication.py +103 -0
  42. pybundle/steps/env_completeness.py +269 -0
  43. pybundle/steps/env_var_usage.py +253 -0
  44. pybundle/steps/error_refs.py +204 -0
  45. pybundle/steps/event_loop_patterns.py +280 -0
  46. pybundle/steps/exception_patterns.py +190 -0
  47. pybundle/steps/fastapi_integration.py +250 -0
  48. pybundle/steps/flask_debugging.py +312 -0
  49. pybundle/steps/git_analytics.py +315 -0
  50. pybundle/steps/handoff_md.py +176 -0
  51. pybundle/steps/import_time.py +175 -0
  52. pybundle/steps/interrogate.py +106 -0
  53. pybundle/steps/license_scan.py +96 -0
  54. pybundle/steps/line_profiler.py +117 -0
  55. pybundle/steps/link_validation.py +287 -0
  56. pybundle/steps/logging_analysis.py +233 -0
  57. pybundle/steps/memory_profile.py +176 -0
  58. pybundle/steps/migration_history.py +336 -0
  59. pybundle/steps/mutation_testing.py +141 -0
  60. pybundle/steps/mypy.py +103 -0
  61. pybundle/steps/orm_optimization.py +316 -0
  62. pybundle/steps/pip_audit.py +45 -0
  63. pybundle/steps/pipdeptree.py +62 -0
  64. pybundle/steps/pylance.py +562 -0
  65. pybundle/steps/pytest.py +66 -0
  66. pybundle/steps/query_pattern_analysis.py +334 -0
  67. pybundle/steps/radon.py +161 -0
  68. pybundle/steps/repro_md.py +161 -0
  69. pybundle/steps/rg_scans.py +78 -0
  70. pybundle/steps/roadmap.py +153 -0
  71. pybundle/steps/ruff.py +117 -0
  72. pybundle/steps/secrets_detection.py +235 -0
  73. pybundle/steps/security_headers.py +309 -0
  74. pybundle/steps/shell.py +74 -0
  75. pybundle/steps/slow_tests.py +178 -0
  76. pybundle/steps/sqlalchemy_validation.py +269 -0
  77. pybundle/steps/test_flakiness.py +184 -0
  78. pybundle/steps/tree.py +116 -0
  79. pybundle/steps/type_coverage.py +277 -0
  80. pybundle/steps/unused_deps.py +211 -0
  81. pybundle/steps/vulture.py +167 -0
  82. pybundle/tools.py +63 -0
@@ -0,0 +1,903 @@
1
+ Metadata-Version: 2.4
2
+ Name: gwc-pybundle
3
+ Version: 2.1.2
4
+ Summary: Deterministic Python project context bundling for humans, automation, and AI
5
+ Author-email: Jessica Brown <jessica@codenamejessica.com>
6
+ License: The MIT License (MIT)
7
+ =====================
8
+
9
+ Copyright Β© 2025 Jessica Brown
10
+
11
+ Permission is hereby granted, free of charge, to any person
12
+ obtaining a copy of this software and associated documentation
13
+ files (the β€œSoftware”), to deal in the Software without
14
+ restriction, including without limitation the rights to use,
15
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
16
+ copies of the Software, and to permit persons to whom the
17
+ Software is furnished to do so, subject to the following
18
+ conditions:
19
+
20
+ The above copyright notice and this permission notice shall be
21
+ included in all copies or substantial portions of the Software.
22
+
23
+ THE SOFTWARE IS PROVIDED β€œAS IS”, WITHOUT WARRANTY OF ANY KIND,
24
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
25
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
27
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
28
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
30
+ OTHER DEALINGS IN THE SOFTWARE.
31
+ Project-URL: Homepage, https://github.com/girls-whocode/pybundle
32
+ Project-URL: Repository, https://github.com/girls-whocode/pybundle
33
+ Project-URL: Issues, https://github.com/girls-whocode/pybundle/issues
34
+ Classifier: Development Status :: 5 - Production/Stable
35
+ Classifier: Intended Audience :: Developers
36
+ Classifier: License :: OSI Approved :: MIT License
37
+ Classifier: Programming Language :: Python :: 3
38
+ Classifier: Programming Language :: Python :: 3.9
39
+ Classifier: Programming Language :: Python :: 3.10
40
+ Classifier: Programming Language :: Python :: 3.11
41
+ Classifier: Programming Language :: Python :: 3.12
42
+ Classifier: Topic :: Software Development :: Build Tools
43
+ Classifier: Topic :: Software Development :: Debuggers
44
+ Classifier: Topic :: Software Development :: Quality Assurance
45
+ Requires-Python: >=3.9
46
+ Description-Content-Type: text/markdown
47
+ License-File: LICENSE.md
48
+ Requires-Dist: colorama>=0.4.6
49
+ Requires-Dist: pdoc>=16.0.0
50
+ Provides-Extra: dev
51
+ Requires-Dist: build; extra == "dev"
52
+ Requires-Dist: twine; extra == "dev"
53
+ Dynamic: license-file
54
+
55
+ # 🧳 pybundle ![PyPI - Version](https://img.shields.io/pypi/v/gwc-pybundle)
56
+
57
+ ![GitHub Release Date](https://img.shields.io/github/release-date/girls-whocode/pybundle?color=orange)
58
+
59
+ [![Python versions](https://img.shields.io/pypi/pyversions/gwc-pybundle.svg?color=3776AB)](https://pypi.org/project/gwc-pybundle/)
60
+ [![License](https://img.shields.io/badge/license-MIT-yellow.svg)](LICENSE.md)
61
+ [![PyPI Downloads](https://static.pepy.tech/personalized-badge/gwc-pybundle?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLUE&right_color=GREY&left_text=downloads)](https://pepy.tech/projects/gwc-pybundle)
62
+ ![GitHub Sponsors](https://img.shields.io/github/sponsors/girls-whocode?color=ec4899)
63
+
64
+ [![CI](https://github.com/girls-whocode/pybundle/actions/workflows/publish.yml/badge.svg?color=fb923c)](https://github.com/girls-whocode/pybundle/actions)
65
+ [![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-14b8a6.svg)](https://github.com/astral-sh/ruff)
66
+ [![Type checked](https://img.shields.io/badge/type%20checked-mypy-0ea5e9.svg)](https://mypy-lang.org/)
67
+ ![Commit Activity](https://img.shields.io/github/commit-activity/t/girls-whocode/pybundle?color=f59e0b)
68
+
69
+
70
+ **pybundle** is a deterministic, automation-friendly CLI that captures Python project context into a single, reproducible bundle β€” ideal for debugging, CI artifacts, audits, and AI-assisted workflows.
71
+
72
+ It produces **machine-readable outputs first**, with optional human-readable summaries layered on top.
73
+
74
+ > Think β€œ`git archive` + diagnostics + metadata”, without guessing or heuristics.
75
+
76
+ > **Note:** The PyPI package name is `gwc-pybundle`, but the tool is installed and used as `pybundle`.
77
+ ---
78
+
79
+ ## 🧠 Why pybundle exists
80
+
81
+ Modern software development compresses what used to be entire teams into a single role.
82
+
83
+ Today, one developer is often responsible for:
84
+ - application code
85
+ - build systems
86
+ - test tooling
87
+ - deployment logic
88
+ - CI/CD behavior
89
+ - environment differences
90
+ - security implications
91
+ - and increasingly, AI-assisted workflows
92
+
93
+ The problem is no longer *how* to write code.
94
+
95
+ It’s answering:
96
+
97
+ > **β€œWhy is this system behaving the way it is?”**
98
+
99
+ That question is hard to answer when:
100
+ - context is scattered
101
+ - tooling output is ephemeral
102
+ - environment details are lost
103
+ - source snapshots are incomplete or noisy
104
+
105
+ AI didn’t create this problem - it exposed it.
106
+
107
+ Large language models don’t fail because they lack intelligence.
108
+ They fail because we give them **uncurated context**.
109
+
110
+ Humans don’t fail because they can’t debug.
111
+ They fail because the **cost of reconstructing context** exceeds the time they have.
112
+
113
+ **pybundle exists to reduce context debt.**
114
+
115
+ It captures *what matters*, ignores what doesn’t, and produces a deterministic artifact that explains:
116
+ - what code exists
117
+ - what tools ran
118
+ - what environment was used
119
+ - and why the outputs exist
120
+
121
+ For humans, automation, and AI alike.
122
+
123
+ ---
124
+
125
+ ## ✨ Features
126
+
127
+ * πŸ“¦ **Single archive output** (`.zip` or `.tar.gz`)
128
+ * 🧠 **Machine-readable manifest** (`MANIFEST.json`) for automation
129
+ * 🧾 **Structured summaries** (`SUMMARY.json`)
130
+ * 🧭 **Respects `.gitignore`** exactly when available
131
+ * πŸ›‘ **Safely ignores virtualenvs and caches** (even with non-standard names)
132
+ * πŸ” Optional tooling checks (ruff, mypy, pytest, pylance, bandit, pip-audit, coverage)
133
+ * πŸ›‘οΈ Security scanning (bandit for code issues, pip-audit for dependency CVEs)
134
+ * πŸ§ͺ Deterministic output (stable paths, timestamps, schemas)
135
+ * πŸ”’ Secret-safe (optional redaction)
136
+ * **v2.1.0 NEW:** Enhanced AI context, smarter dead code detection, confidence-scored dependency analysis
137
+ * **v2.0.1:** 22 advanced analysis steps including:
138
+ - πŸ” Security hardening (secrets detection, security headers)
139
+ - ⚑ Async/await pattern detection
140
+ - πŸ“Š Database & ORM optimization
141
+ - πŸ—οΈ Framework-specific analysis (Django, FastAPI, Flask)
142
+ - 🐳 Container & deployment analysis
143
+
144
+ ---
145
+
146
+ ## πŸ“‚ What’s in a pybundle archive?
147
+
148
+ At minimum, a bundle contains:
149
+
150
+ ```text
151
+ MANIFEST.json # stable, machine-readable metadata
152
+ SUMMARY.json # structured summary of collected data
153
+ src/ # filtered project source snapshot
154
+ logs/ # tool outputs (ruff, mypy, pytest, pylance, bandit, pip-audit, coverage, rg scans)
155
+ meta/ # environment + tool detection
156
+ ```
157
+
158
+ ### `MANIFEST.json` (automation fuel)
159
+
160
+ Includes:
161
+
162
+ * tool paths detected
163
+ * options used
164
+ * archive name + format
165
+ * git commit hash (if available)
166
+ * UTC timestamp
167
+ * schema version (stable)
168
+
169
+ Another script can fully understand a bundle **without reading markdown**.
170
+
171
+ ---
172
+
173
+ ## πŸš€ Installation
174
+
175
+ We recommend using a Python virtual environment for development tooling.
176
+
177
+ ### Quick installation (pybundle tooling) - RECOMMENDED
178
+
179
+ Create a dedicated requirements file in the root of your project:
180
+
181
+ ```txt
182
+ # requirements-pybundle.txt
183
+ ruff
184
+ mypy
185
+ pytest
186
+ pytest-cov
187
+ bandit
188
+ pip-audit
189
+ gwc-pybundle==2.1.2
190
+ ```
191
+
192
+ Then install:
193
+
194
+ ```bash
195
+ pip install -r requirements-pybundle.txt
196
+ ```
197
+
198
+ > **System dependency:**
199
+ > pybundle uses `ripgrep (rg)` for source scanning and expects the system binary.
200
+ >
201
+ > * macOS: `brew install ripgrep`
202
+ > * Ubuntu/Debian: `sudo apt install ripgrep`
203
+ > * Fedora: `sudo dnf install ripgrep`
204
+
205
+ After installation, run:
206
+
207
+ ```bash
208
+ pybundle run analysis
209
+ ```
210
+
211
+ A new `artifacts/` directory will be created containing:
212
+
213
+ * the compressed bundle
214
+ * an extracted working directory
215
+ * machine-readable metadata (`MANIFEST.json`, `SUMMARY.json`)
216
+
217
+ See **Usage** for more details.
218
+
219
+ ---
220
+
221
+ ### Advanced installation
222
+
223
+ #### From GitHub
224
+
225
+ ```bash
226
+ pip install "gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.3.1"
227
+ ```
228
+
229
+ Pinning to a tag ensures reproducible behavior.
230
+
231
+ #### Editable install (for development)
232
+
233
+ ```bash
234
+ pip install -e .
235
+ ```
236
+
237
+ ---
238
+
239
+ ## πŸ§ͺ Usage
240
+
241
+ From the root of a Python project, run a profile using the `run` command:
242
+
243
+ ```bash
244
+ pybundle run analysis
245
+ ```
246
+
247
+ This builds a timestamped diagnostic bundle under the default `artifacts/` directory.
248
+
249
+ ### Profiles
250
+
251
+ Profiles define *what* pybundle collects and *which tools* are run.
252
+
253
+ **Available profiles** (v1.4.3+):
254
+
255
+ * **`analysis`** - What the code IS (structure, metrics, dependencies, docs)
256
+ - Code structure, complexity metrics, documentation coverage
257
+ - Dependency analysis, licenses, performance profiling
258
+ - No error detection or linting
259
+
260
+ * **`debug`** - What's WRONG with the code (errors, issues, problems)
261
+ - Linting, type checking, testing, security scans
262
+ - Error context extraction, anti-pattern detection
263
+ - Includes everything needed for troubleshooting
264
+
265
+ * **`ai`** - Debug optimized for AI (reduced noise, problem-focused)
266
+ - Same as debug but with defaults tuned for AI consumption
267
+
268
+ * **`backup`** - Minimal snapshot (source + git + env, no analysis)
269
+
270
+ To list all available profiles:
271
+
272
+ ```bash
273
+ pybundle list-profiles
274
+ ```
275
+
276
+ Profiles are always invoked via:
277
+
278
+ ```bash
279
+ pybundle run <profile>
280
+ ```
281
+
282
+ ---
283
+
284
+ ### πŸ’Ύ Backup profile
285
+
286
+ The `backup` profile creates a minimal, lightweight snapshot ideal for version archival or disaster recovery.
287
+
288
+ Run it with:
289
+
290
+ ```bash
291
+ pybundle run backup
292
+ ```
293
+
294
+ #### What `backup` includes
295
+
296
+ * βœ… Full source code snapshot (respects `.gitignore`)
297
+ * βœ… Git status and diff (`meta/00_git_status.txt`, `meta/01_git_diff.txt`)
298
+ * βœ… Python version (`meta/20_python_version.txt`)
299
+ * βœ… Installed packages (`meta/22_pip_freeze.txt`)
300
+ * βœ… Copy manifest (`meta/50_copy_manifest.txt`)
301
+ * ❌ No linting, type-checking, or tests
302
+ * ❌ No security scanning
303
+ * ❌ No ripgrep scans
304
+
305
+ The result is a **fast, small, restorable archive** with just source code and environment context.
306
+
307
+ #### Restoring a backup
308
+
309
+ Backups are created as either `.zip` or `.tar.gz` archives (see Archive Format below).
310
+
311
+ To extract and inspect:
312
+
313
+ **For .zip archives:**
314
+ ```bash
315
+ # Look for filename with *_backup_<TIMESTAMP>.zip
316
+ unzip <FILENAME>.zip -d restored/
317
+ cd restored/<FILENAME>/
318
+ ```
319
+
320
+ **For .tar.gz archives:**
321
+ ```bash
322
+ # Look for filename with *_backup_<TIMESTAMP>.tar.gz
323
+ tar -xzf <FILENAME>.tar.gz -C restored/
324
+ cd restored/<FILENAME>/
325
+ ```
326
+
327
+ Inside the extracted directory:
328
+
329
+ ```text
330
+ src/ # Your project source code
331
+ meta/
332
+ 00_git_status.txt # Git working tree status at backup time
333
+ 01_git_diff.txt # Uncommitted changes (if any)
334
+ 20_python_version.txt # Python version used
335
+ 22_pip_freeze.txt # Exact package versions
336
+ 50_copy_manifest.txt # List of files included
337
+ MANIFEST.json # Machine-readable metadata
338
+ SUMMARY.json # Structured summary
339
+ RUN_LOG.txt # Execution log
340
+ ```
341
+
342
+ The `src/` directory contains your complete project structure.
343
+ The `meta/22_pip_freeze.txt` file can be used to recreate the exact environment:
344
+
345
+ ```bash
346
+ python -m venv venv
347
+ source venv/bin/activate # or venv\Scripts\activate on Windows
348
+ pip install -r meta/22_pip_freeze.txt
349
+ ```
350
+
351
+ Then copy your source code back:
352
+
353
+ ```bash
354
+ cp -r src/* /path/to/your/project/
355
+ ```
356
+
357
+ #### Archive format fallback
358
+
359
+ pybundle uses **zip** by default for maximum portability.
360
+
361
+ If the `zip` command is not available on your system, pybundle **automatically falls back to tar.gz** format without requiring configuration.
362
+
363
+ This ensures backups can be created on any system, regardless of installed compression tools.
364
+
365
+ To explicitly control the format:
366
+
367
+ ```bash
368
+ pybundle run backup --format zip # Force zip (requires zip command)
369
+ pybundle run backup --format tar.gz # Force tar.gz (requires tar command)
370
+ pybundle run backup --format auto # Auto-detect (default behavior)
371
+ ```
372
+
373
+ Both formats preserve the same internal structure and metadata.
374
+
375
+ ---
376
+
377
+ ### πŸ” Analysis Tools
378
+
379
+ The `analysis` and `debug` profiles run comprehensive quality and security checks:
380
+
381
+ #### Code Quality
382
+ * **ruff** - Fast Python linter and formatter checks
383
+ * **mypy** - Static type checking for type hints
384
+ * **pylance** - Syntax error detection and import analysis
385
+ * **vulture** - Dead code detection (v1.3.0+)
386
+ * **radon** - Cyclomatic complexity and maintainability metrics (v1.3.0+)
387
+ * **interrogate** - Docstring coverage analysis (v1.3.0+)
388
+ * **pylint duplication** - Code duplication detection (v1.3.0+)
389
+
390
+ #### Testing & Coverage
391
+ * **pytest** - Test execution and results
392
+ * **coverage** - Code coverage analysis (shows tested vs untested code)
393
+
394
+ #### Security
395
+ * **bandit** - Security vulnerability scanning for Python code
396
+ * **pip-audit** - Dependency vulnerability checking against known CVEs
397
+
398
+ #### Dependency Analysis (v1.3.1+)
399
+ * **pipdeptree** - Full dependency tree with conflict detection
400
+ * **unused dependencies** - Identify installed but unused packages
401
+ * **pip-licenses** - License scanning and compatibility warnings
402
+ * **dependency sizes** - Disk usage analysis per package
403
+
404
+ #### Performance Profiling (v1.4.0+)
405
+ * **cProfile** - CPU profiling to identify bottlenecks
406
+ * **import time analysis** - Detect slow module imports
407
+ * **tracemalloc** - Memory profiling (*enabled by default in v1.4.2+*)
408
+ * **line_profiler** - Line-by-line profiling (optional, requires `@profile` decorators and `--enable-line-profiler`)
409
+
410
+ #### Test Quality & Coverage Enhancement (v1.4.1+)
411
+ * **Colorful progress indicators** - Real-time colored output with step counts (🟒 green = success, 🟑 yellow = skipped, πŸ”΄ red = failed)
412
+ - *v1.4.2: Fixed color support for xterm and other terminals*
413
+ * **Test flakiness detection** - Run tests multiple times to identify non-deterministic failures
414
+ * **Branch coverage** - Enhanced coverage.py integration showing missing branches, not just lines
415
+ * **Slow test identification** - Automatically identify and rank tests exceeding time threshold
416
+ * **Mutation testing** - Optional mutmut integration to measure test suite effectiveness (VERY SLOW - disabled by default)
417
+
418
+ #### Performance Profiling (v1.4.0+)
419
+ * **cProfile integration** - CPU profiling showing slowest functions
420
+ * **import time analysis** - Detect slow module imports
421
+ * **tracemalloc** - Memory profiling (*v1.4.2: enabled by default*)
422
+ * **line_profiler** - Line-by-line profiling (optional, requires `@profile` decorators and `--enable-line-profiler`)
423
+
424
+ #### Pattern Scanning
425
+ * **ripgrep scans** - TODO detection, print statements, bare excepts
426
+
427
+ All tools gracefully skip if not installed. Install recommended tools:
428
+
429
+ ```bash
430
+ pip install ruff mypy pytest pytest-cov bandit pip-audit vulture radon interrogate pylint pipdeptree pip-licenses
431
+ ```
432
+
433
+ For ripgrep (system dependency):
434
+ * macOS: `brew install ripgrep`
435
+ * Ubuntu/Debian: `sudo apt install ripgrep`
436
+
437
+ ---
438
+
439
+ ### πŸ€– AI profile (NEW)
440
+
441
+ The `ai` profile is optimized for handing a project to AI tooling
442
+ (ChatGPT, local LLMs, code assistants, etc.).
443
+
444
+ It prioritizes **source code and reproducible context**, while skipping
445
+ expensive or noisy steps by default.
446
+
447
+ Run it with:
448
+
449
+ ```bash
450
+ pybundle run ai
451
+ ```
452
+
453
+ #### What `ai` does by default
454
+
455
+ * βœ… Includes full curated source snapshot (`src/`)
456
+ * βœ… Includes environment + git metadata
457
+ * βœ… Generates `REPRO.md` and `HANDOFF.md`
458
+ * ❌ Skips linting, type-checking, tests
459
+ * ❌ Skips ripgrep scans and error-context expansion
460
+ * ❌ Skips `compileall` unless explicitly enabled
461
+
462
+ The result is a **small, fast, AI-friendly bundle** that still preserves
463
+ determinism and traceability.
464
+
465
+ You may selectively re-enable tools:
466
+
467
+ ```bash
468
+ pybundle run ai --ruff --mypy
469
+ pybundle run ai --compileall
470
+ ```
471
+
472
+ This makes `ai` suitable for:
473
+
474
+ * AI-assisted refactoring
475
+ * Large-context summarization
476
+ * Code review handoff
477
+ * Offline or local LLM workflows
478
+
479
+ ---
480
+
481
+ ### Common options
482
+
483
+ Most usage customizations are done through flags on `pybundle run`.
484
+
485
+ Example:
486
+
487
+ ```bash
488
+ pybundle run analysis \
489
+ --format zip \
490
+ --outdir ./artifacts \
491
+ --name myproject-bundle \
492
+ --strict
493
+ ```
494
+
495
+ Commonly used options:
496
+
497
+ * `--format {auto,zip,tar.gz}` - archive format
498
+ * `--outdir PATH` - output directory (default: `<project>/artifacts`)
499
+ * `--name NAME` - override archive name prefix
500
+ * `--strict` - fail with non-zero exit code if any step fails
501
+ * `--redact / --no-redact` - control secret redaction
502
+
503
+ Tool execution can be selectively disabled:
504
+
505
+ ```bash
506
+ --no-ruff
507
+ --no-mypy
508
+ --no-pylance
509
+ --no-pytest
510
+ --no-bandit
511
+ --no-pip-audit
512
+ --no-coverage
513
+ --no-rg
514
+ --no-error-refs
515
+ --no-context
516
+ ```
517
+
518
+ For the full list of options:
519
+
520
+ ```bash
521
+ pybundle run --help
522
+ ```
523
+
524
+ ---
525
+
526
+ ### Doctor mode
527
+
528
+ To see which tools are available and what *would* run (without creating a bundle):
529
+
530
+ ```bash
531
+ pybundle doctor
532
+ ```
533
+
534
+ You may optionally specify a profile to preview:
535
+
536
+ ```bash
537
+ pybundle doctor analysis
538
+ ```
539
+
540
+ This is useful for validating environment readiness (CI, fresh machines, etc.).
541
+
542
+ ---
543
+
544
+ ### Version
545
+
546
+ To check the installed version:
547
+
548
+ ```bash
549
+ pybundle version
550
+ ```
551
+
552
+ ---
553
+
554
+ ## 🧠 Ignore behavior (important)
555
+
556
+ ### If inside a Git repository
557
+
558
+ pybundle uses **Git itself** to determine which files are included:
559
+
560
+ * `.gitignore`
561
+ * `.git/info/exclude`
562
+ * global gitignore rules
563
+
564
+ This guarantees pybundle sees the project **exactly as Git does**.
565
+
566
+ ### If Git is unavailable
567
+
568
+ pybundle falls back to safe structural rules:
569
+
570
+ * ignores `__pycache__`, `.ruff_cache`, `.mypy_cache`, `.pytest_cache`, etc.
571
+ * detects virtual environments by structure (`pyvenv.cfg`, `bin/activate`), not by name
572
+ β†’ works with `.venv`, `.pybundle-venv`, `env-prod-2025`, etc.
573
+
574
+ ---
575
+
576
+ ## 🧾 Machine-Readable Output (`--json`)
577
+
578
+ All `pybundle` commands support a **machine-readable JSON output mode** via the `--json` flag.
579
+
580
+ When enabled, `pybundle` emits **exactly one JSON object to stdout**, with a **stable schema** intended for:
581
+
582
+ * CI pipelines
583
+ * automation scripts
584
+ * external tooling
585
+ * AI orchestration
586
+ * reproducible analysis
587
+
588
+ No human text or formatting are mixed into the output.
589
+
590
+ ### Example
591
+
592
+ ```bash
593
+ pybundle run analysis --json
594
+ ```
595
+
596
+ Output:
597
+
598
+ ```json
599
+ {
600
+ "status": "ok",
601
+ "command": "run",
602
+ "profile": "analysis",
603
+ "files_included": 39,
604
+ "files_excluded": 0,
605
+ "duration_ms": 394,
606
+ "bundle_path": "/home/jessica/repositories/python/pybundle/artifacts/pybundle_analysis_20260103T102440Z.zip"
607
+ }
608
+ ```
609
+
610
+ The same structure applies to **all profiles**:
611
+
612
+ ```bash
613
+ pybundle run ai --json
614
+ pybundle run debug --json
615
+ pybundle run backup --json
616
+ ```
617
+
618
+ ---
619
+
620
+ ### JSON Field Definitions
621
+
622
+ | Field | Description |
623
+ | ---------------- | -------------------------------------------------- |
624
+ | `status` | `"ok"` or `"fail"` based on execution result |
625
+ | `command` | The command executed (`run` or `doctor`) |
626
+ | `profile` | The profile used (`analysis`, `ai`, `debug`, etc.) |
627
+ | `files_included` | Number of files copied into the bundle |
628
+ | `files_excluded` | Number of *evaluated* files skipped by policy |
629
+ | `duration_ms` | Total execution time in milliseconds |
630
+ | `bundle_path` | Absolute path to the generated archive |
631
+
632
+ ---
633
+
634
+ ### Important Semantics: `files_excluded`
635
+
636
+ `files_excluded` **does not** mean β€œeverything in the repository that was not bundled.”
637
+
638
+ Instead, it means:
639
+
640
+ > Files that were **eligible under the active profile’s policy** and were *explicitly skipped* after evaluation.
641
+
642
+ Files and directories that are **intentionally out of scope** β€” such as:
643
+
644
+ * `.git/`
645
+ * `node_modules/`
646
+ * virtual environments
647
+ * build artifacts
648
+ * caches
649
+
650
+ are **never considered**, and therefore are **not counted as excluded**.
651
+
652
+ This design keeps metrics honest and avoids inflating counts with known-irrelevant infrastructure.
653
+
654
+ A value of `files_excluded = 0` simply means:
655
+
656
+ > *Everything that was evaluated was worth keeping.*
657
+
658
+ This is expected and normal for clean, well-structured projects β€” especially in `ai` mode.
659
+
660
+ ---
661
+
662
+ ### JSON Stability Guarantee
663
+
664
+ The JSON schema emitted by `--json` is considered **part of the public API**.
665
+
666
+ Starting with **v1.0**, field names and meanings will remain stable.
667
+ New fields may be added, but existing fields will not be renamed or removed.
668
+
669
+ This allows `pybundle` to be safely embedded into:
670
+
671
+ * CI workflows
672
+ * automation scripts
673
+ * AI pipelines
674
+ * external tooling
675
+
676
+ without fear of breaking changes.
677
+
678
+ ---
679
+
680
+ ## πŸ“œ Profiles
681
+
682
+ pybundle is profile-driven. Each profile defines:
683
+
684
+ * what files are collected
685
+ * which tools run
686
+ * what metadata is emitted
687
+
688
+ Example profiles:
689
+
690
+ * `analysis`
691
+ * `source`
692
+ * `minimal`
693
+
694
+ Profiles are extensible - add your own without modifying core logic.
695
+
696
+ ---
697
+
698
+ ## πŸ” Safety & Redaction
699
+
700
+ By default, pybundle:
701
+
702
+ * avoids scanning known secret locations
703
+ * supports optional redaction of sensitive strings in logs
704
+
705
+ Use `--redact / --no-redact` to control behavior.
706
+
707
+ ---
708
+ ## πŸ”’ Security Considerations
709
+
710
+ **pybundle** is a development tool designed for trusted environments.
711
+
712
+ ### Threat Model
713
+
714
+ * **Environment:** Development machines and CI/CD pipelines
715
+ * **Trust Boundary:** Assumes trusted development environment
716
+ * **Execution Context:** Runs external tools (git, ruff, mypy, pytest, etc.)
717
+ * **Input Sources:** Project files, git repository, installed packages
718
+
719
+ ### Security Posture
720
+
721
+ **Tool Path Resolution:**
722
+ - All external tools use full resolved paths (via `shutil.which()`)
723
+ - Tools are resolved at detection time and stored in `Tooling` dataclass
724
+ - No dynamic PATH manipulation or shell interpretation
725
+ - Eliminates partial path execution vulnerabilities (B607)
726
+ - **Optional strict-paths mode** for enhanced security (v1.2.0+)
727
+ - **Code quality tools** for dead code, complexity, docstrings, and duplication (v1.3.0+)
728
+ - **Dependency intelligence** for conflict detection, license scanning, and size analysis (v1.3.1+)
729
+
730
+ **Subprocess Execution:**
731
+ - All subprocess calls use `shell=False` (default, secure)
732
+ - Arguments passed as lists, never as strings
733
+ - No user-controlled command construction
734
+ - Commands are hardcoded in source code
735
+
736
+ **Data Handling:**
737
+ - Optional secret redaction for sensitive strings in logs
738
+ - Environment variables and paths logged for reproducibility
739
+ - All file operations respect `.gitignore` rules
740
+
741
+ ### Strict-Paths Mode (v1.2.0+)
742
+
743
+ For high-security environments, enable `--strict-paths` to enforce that all tools must be in trusted system directories:
744
+
745
+ ```bash
746
+ pybundle run analysis --strict-paths
747
+ ```
748
+
749
+ **Trusted directories** (configurable via `PYBUNDLE_TRUSTED_PATHS`):
750
+ - `/usr/bin/`, `/usr/local/bin/`, `/bin/`
751
+ - `/opt/homebrew/bin/` (macOS Homebrew)
752
+ - `/snap/bin/` (Ubuntu snaps)
753
+ - Virtual environment paths (`.venv`, `venv`, `.pybundle-venv`)
754
+
755
+ Tools outside trusted directories are excluded in strict mode. This prevents:
756
+ - Accidental execution of tools from user-writable directories
757
+ - PATH manipulation attacks
758
+ - Use of potentially compromised tool installations
759
+
760
+ **Example:** Verify tool paths before running:
761
+ ```bash
762
+ pybundle doctor --strict-paths
763
+ ```
764
+
765
+ Output shows trust status:
766
+ ```
767
+ πŸ”§ Tool Detection:
768
+ git βœ… /usr/bin/git
769
+ python βœ… /path/to/venv/bin/python
770
+ npm ⚠️ /home/user/.nvm/.../npm (untrusted in strict mode)
771
+ ```
772
+
773
+ **Configure custom trusted paths:**
774
+ ```bash
775
+ export PYBUNDLE_TRUSTED_PATHS="/opt/custom/bin:/company/tools/bin"
776
+ pybundle run debug --strict-paths
777
+ ```
778
+
779
+ ### Known Limitations
780
+
781
+ 1. **Requires Trusted Environment**
782
+ - Assumes developer controls their machine and installed tools
783
+ - Not designed for untrusted code execution or sandboxing
784
+ - Tool integrity depends on system package management
785
+
786
+ 2. **Tool Availability**
787
+ - External tools (git, ruff, mypy) are optional
788
+ - Missing tools result in SKIP status, not failure
789
+ - Use `pybundle doctor` to verify available tools
790
+
791
+ 3. **File System Access**
792
+ - Reads entire project tree (respecting ignore rules)
793
+ - Writes to `artifacts/` directory by default
794
+ - No privilege escalation or system modification
795
+
796
+ ### For Security Auditors
797
+
798
+ **Bandit Security Scan Results:**
799
+ - 33 low-severity findings (all expected for CLI tool)
800
+ - **B404** (subprocess import): Required for tool functionality
801
+ - **B603** (subprocess calls): Using secure pattern (shell=False, full paths)
802
+ - **B112** (try/except/continue): Acceptable error handling pattern
803
+
804
+ **Risk Classification:** LOW
805
+ - No user-controlled command injection
806
+ - No untrusted input in command execution
807
+ - Full path resolution prevents PATH manipulation attacks
808
+ - Standard development tool security posture
809
+
810
+ **Recommended Usage:**
811
+ ```bash
812
+ # Verify tool paths before execution
813
+ pybundle doctor
814
+
815
+ # Review what tools will be used
816
+ pybundle doctor analysis --json
817
+ ```
818
+
819
+ ---
820
+ ## 🧩 Why pybundle?
821
+
822
+ pybundle is designed for:
823
+
824
+ * handing a project to another engineer
825
+ * attaching context to a bug report
826
+ * feeding a codebase to AI tooling
827
+ * generating CI artifacts
828
+ * preserving β€œwhat exactly did we run?”
829
+ * producing **AI-consumable project context** without guesswork
830
+
831
+ It prioritizes **determinism, traceability, and automation** over clever heuristics.
832
+
833
+ ---
834
+
835
+ ## πŸ›  Development Notes
836
+
837
+ * Python β‰₯ 3.9
838
+ * Uses modern tooling (ruff, mypy)
839
+ * Fully type-checked
840
+ * Formatter-clean
841
+ * No test suite *yet* (intentional; coming later)
842
+
843
+ During development, run:
844
+
845
+ ```bash
846
+ python -m pybundle ...
847
+ ```
848
+
849
+ to bypass shell caching.
850
+
851
+ ### Release Process
852
+
853
+ To release a new version:
854
+
855
+ ```bash
856
+ ./release.sh --push-release v2.1.0
857
+ ```
858
+
859
+ The script automates:
860
+ - Version updates (pyproject.toml, README.md)
861
+ - Git tagging and pushing
862
+ - GitHub release creation
863
+ - Triggers PyPI publish via CI
864
+
865
+ See [docs/RELEASE_PROCESS.md](docs/RELEASE_PROCESS.md) for details.
866
+
867
+ ---
868
+
869
+ ## πŸ“Œ Versioning
870
+
871
+ pybundle follows **Semantic Versioning**.
872
+
873
+ Pinned Git tags are recommended when used as a dependency:
874
+
875
+ ```txt
876
+ gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.3.1
877
+ ```
878
+
879
+ ---
880
+
881
+ ## 🧠 Philosophy
882
+
883
+ > If a tool produces output, it should also produce metadata about **how** and **why** that output exists.
884
+
885
+ pybundle treats context as a first-class artifact.
886
+
887
+ ---
888
+
889
+ ## πŸ“¦ Package naming note
890
+
891
+ The distribution name on PyPI is **`gwc-pybundle`** to avoid conflicts with existing packages.
892
+
893
+ The project name, imports, and CLI remain **`pybundle`**.
894
+
895
+ ```bash
896
+ pip install gwc-pybundle
897
+ pybundle run analysis
898
+ ```
899
+ Look in the autocreated `artifacts/` folder.
900
+
901
+ ## πŸ“„ License
902
+
903
+ MIT License