gwc-pybundle 1.1.1__tar.gz → 1.4.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.

Potentially problematic release.


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

Files changed (61) hide show
  1. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/PKG-INFO +142 -9
  2. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/README.md +140 -7
  3. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/gwc_pybundle.egg-info/PKG-INFO +142 -9
  4. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/gwc_pybundle.egg-info/SOURCES.txt +16 -1
  5. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/cli.py +84 -11
  6. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/context.py +86 -25
  7. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/doctor.py +47 -0
  8. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/filters.py +10 -4
  9. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/manifest.py +2 -3
  10. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/packaging.py +9 -5
  11. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/policy.py +25 -7
  12. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/profiles.py +67 -0
  13. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/bandit.py +3 -5
  14. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/compileall.py +2 -2
  15. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/copy_pack.py +16 -4
  16. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/coverage.py +19 -13
  17. gwc_pybundle-1.4.1/pybundle/steps/cprofile_step.py +155 -0
  18. gwc_pybundle-1.4.1/pybundle/steps/dependency_sizes.py +120 -0
  19. gwc_pybundle-1.4.1/pybundle/steps/duplication.py +94 -0
  20. gwc_pybundle-1.4.1/pybundle/steps/import_time.py +165 -0
  21. gwc_pybundle-1.4.1/pybundle/steps/interrogate.py +84 -0
  22. gwc_pybundle-1.4.1/pybundle/steps/license_scan.py +96 -0
  23. gwc_pybundle-1.4.1/pybundle/steps/line_profiler.py +108 -0
  24. gwc_pybundle-1.4.1/pybundle/steps/memory_profile.py +173 -0
  25. gwc_pybundle-1.4.1/pybundle/steps/mutation_testing.py +136 -0
  26. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/mypy.py +2 -2
  27. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/pip_audit.py +3 -5
  28. gwc_pybundle-1.4.1/pybundle/steps/pipdeptree.py +61 -0
  29. gwc_pybundle-1.4.1/pybundle/steps/pylance.py +562 -0
  30. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/pytest.py +2 -2
  31. gwc_pybundle-1.4.1/pybundle/steps/radon.py +121 -0
  32. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/rg_scans.py +2 -2
  33. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/ruff.py +3 -3
  34. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/shell.py +11 -4
  35. gwc_pybundle-1.4.1/pybundle/steps/slow_tests.py +170 -0
  36. gwc_pybundle-1.4.1/pybundle/steps/test_flakiness.py +172 -0
  37. gwc_pybundle-1.4.1/pybundle/steps/unused_deps.py +112 -0
  38. gwc_pybundle-1.4.1/pybundle/steps/vulture.py +82 -0
  39. gwc_pybundle-1.4.1/pybundle/tools.py +63 -0
  40. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pyproject.toml +2 -2
  41. gwc_pybundle-1.1.1/pybundle/steps/pylance.py +0 -337
  42. gwc_pybundle-1.1.1/pybundle/tools.py +0 -7
  43. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/LICENSE.md +0 -0
  44. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/gwc_pybundle.egg-info/dependency_links.txt +0 -0
  45. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/gwc_pybundle.egg-info/entry_points.txt +0 -0
  46. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/gwc_pybundle.egg-info/top_level.txt +0 -0
  47. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/__init__.py +0 -0
  48. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/__main__.py +0 -0
  49. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/roadmap_model.py +0 -0
  50. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/roadmap_scan.py +0 -0
  51. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/root_detect.py +0 -0
  52. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/runner.py +0 -0
  53. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/__init__.py +0 -0
  54. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/base.py +0 -0
  55. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/context_expand.py +0 -0
  56. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/error_refs.py +0 -0
  57. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/handoff_md.py +0 -0
  58. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/repro_md.py +0 -0
  59. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/roadmap.py +0 -0
  60. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/tree.py +0 -0
  61. {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/setup.cfg +0 -0
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gwc-pybundle
3
- Version: 1.1.1
3
+ Version: 1.4.1
4
4
  Summary: Deterministic Python project context bundling for humans, automation, and AI
5
- Author: Jessica Brown
5
+ Author-email: Jessica Brown <jessica@codenamejessica.com>
6
6
  License: The MIT License (MIT)
7
7
  =====================
8
8
 
@@ -47,7 +47,8 @@ Description-Content-Type: text/markdown
47
47
  License-File: LICENSE.md
48
48
  Dynamic: license-file
49
49
 
50
- # 🧳 pybundle [![PyPI version](https://img.shields.io/pypi/v/gwc-pybundle.svg?color=2ea44f)](https://pypi.org/project/gwc-pybundle/)
50
+ # 🧳 pybundle ![PyPI - Version](https://img.shields.io/pypi/v/gwc-pybundle)
51
+
51
52
  ![GitHub Release Date](https://img.shields.io/github/release-date/girls-whocode/pybundle?color=orange)
52
53
 
53
54
  [![Python versions](https://img.shields.io/pypi/pyversions/gwc-pybundle.svg?color=3776AB)](https://pypi.org/project/gwc-pybundle/)
@@ -173,7 +174,7 @@ pytest
173
174
  pytest-cov
174
175
  bandit
175
176
  pip-audit
176
- gwc-pybundle==1.1.1
177
+ gwc-pybundle==1.3.1
177
178
  ```
178
179
 
179
180
  Then install:
@@ -210,7 +211,7 @@ See **Usage** for more details.
210
211
  #### From GitHub
211
212
 
212
213
  ```bash
213
- pip install "gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.1.1"
214
+ pip install "gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.3.1"
214
215
  ```
215
216
 
216
217
  Pinning to a tag ensures reproducible behavior.
@@ -359,6 +360,10 @@ The `analysis` and `debug` profiles run comprehensive quality and security check
359
360
  * **ruff** - Fast Python linter and formatter checks
360
361
  * **mypy** - Static type checking for type hints
361
362
  * **pylance** - Syntax error detection and import analysis
363
+ * **vulture** - Dead code detection (v1.3.0+)
364
+ * **radon** - Cyclomatic complexity and maintainability metrics (v1.3.0+)
365
+ * **interrogate** - Docstring coverage analysis (v1.3.0+)
366
+ * **pylint duplication** - Code duplication detection (v1.3.0+)
362
367
 
363
368
  #### Testing & Coverage
364
369
  * **pytest** - Test execution and results
@@ -368,13 +373,31 @@ The `analysis` and `debug` profiles run comprehensive quality and security check
368
373
  * **bandit** - Security vulnerability scanning for Python code
369
374
  * **pip-audit** - Dependency vulnerability checking against known CVEs
370
375
 
376
+ #### Dependency Analysis (v1.3.1+)
377
+ * **pipdeptree** - Full dependency tree with conflict detection
378
+ * **unused dependencies** - Identify installed but unused packages
379
+ * **pip-licenses** - License scanning and compatibility warnings
380
+ * **dependency sizes** - Disk usage analysis per package
381
+
382
+ #### Performance Profiling (v1.4.0+)
383
+ * **cProfile** - CPU profiling to identify bottlenecks
384
+ * **import time analysis** - Detect slow module imports
385
+ * **tracemalloc** - Memory profiling (optional, via `--profile-memory`)
386
+ * **line_profiler** - Line-by-line profiling (optional, requires `@profile` decorators and `--enable-line-profiler`)
387
+
388
+ #### Test Quality & Coverage Enhancement (v1.4.1+)
389
+ * **Test flakiness detection** - Run tests multiple times to identify non-deterministic failures
390
+ * **Branch coverage** - Enhanced coverage.py integration showing missing branches, not just lines
391
+ * **Slow test identification** - Automatically identify and rank tests exceeding time threshold
392
+ * **Mutation testing** - Optional mutmut integration to measure test suite effectiveness (VERY SLOW - disabled by default)
393
+
371
394
  #### Pattern Scanning
372
395
  * **ripgrep scans** - TODO detection, print statements, bare excepts
373
396
 
374
397
  All tools gracefully skip if not installed. Install recommended tools:
375
398
 
376
399
  ```bash
377
- pip install ruff mypy pytest pytest-cov bandit pip-audit
400
+ pip install ruff mypy pytest pytest-cov bandit pip-audit vulture radon interrogate pylint pipdeptree pip-licenses
378
401
  ```
379
402
 
380
403
  For ripgrep (system dependency):
@@ -445,7 +468,6 @@ Commonly used options:
445
468
  * `--outdir PATH` - output directory (default: `<project>/artifacts`)
446
469
  * `--name NAME` - override archive name prefix
447
470
  * `--strict` - fail with non-zero exit code if any step fails
448
- * `--no-spinner` - disable spinner output (CI-friendly)
449
471
  * `--redact / --no-redact` - control secret redaction
450
472
 
451
473
  Tool execution can be selectively disabled:
@@ -533,7 +555,7 @@ When enabled, `pybundle` emits **exactly one JSON object to stdout**, with a **s
533
555
  * AI orchestration
534
556
  * reproducible analysis
535
557
 
536
- No human text, spinners, or formatting are mixed into the output.
558
+ No human text or formatting are mixed into the output.
537
559
 
538
560
  ### Example
539
561
 
@@ -653,7 +675,118 @@ By default, pybundle:
653
675
  Use `--redact / --no-redact` to control behavior.
654
676
 
655
677
  ---
678
+ ## 🔒 Security Considerations
679
+
680
+ **pybundle** is a development tool designed for trusted environments.
681
+
682
+ ### Threat Model
683
+
684
+ * **Environment:** Development machines and CI/CD pipelines
685
+ * **Trust Boundary:** Assumes trusted development environment
686
+ * **Execution Context:** Runs external tools (git, ruff, mypy, pytest, etc.)
687
+ * **Input Sources:** Project files, git repository, installed packages
688
+
689
+ ### Security Posture
690
+
691
+ **Tool Path Resolution:**
692
+ - All external tools use full resolved paths (via `shutil.which()`)
693
+ - Tools are resolved at detection time and stored in `Tooling` dataclass
694
+ - No dynamic PATH manipulation or shell interpretation
695
+ - Eliminates partial path execution vulnerabilities (B607)
696
+ - **Optional strict-paths mode** for enhanced security (v1.2.0+)
697
+ - **Code quality tools** for dead code, complexity, docstrings, and duplication (v1.3.0+)
698
+ - **Dependency intelligence** for conflict detection, license scanning, and size analysis (v1.3.1+)
699
+
700
+ **Subprocess Execution:**
701
+ - All subprocess calls use `shell=False` (default, secure)
702
+ - Arguments passed as lists, never as strings
703
+ - No user-controlled command construction
704
+ - Commands are hardcoded in source code
705
+
706
+ **Data Handling:**
707
+ - Optional secret redaction for sensitive strings in logs
708
+ - Environment variables and paths logged for reproducibility
709
+ - All file operations respect `.gitignore` rules
710
+
711
+ ### Strict-Paths Mode (v1.2.0+)
712
+
713
+ For high-security environments, enable `--strict-paths` to enforce that all tools must be in trusted system directories:
714
+
715
+ ```bash
716
+ pybundle run analysis --strict-paths
717
+ ```
718
+
719
+ **Trusted directories** (configurable via `PYBUNDLE_TRUSTED_PATHS`):
720
+ - `/usr/bin/`, `/usr/local/bin/`, `/bin/`
721
+ - `/opt/homebrew/bin/` (macOS Homebrew)
722
+ - `/snap/bin/` (Ubuntu snaps)
723
+ - Virtual environment paths (`.venv`, `venv`, `.pybundle-venv`)
724
+
725
+ Tools outside trusted directories are excluded in strict mode. This prevents:
726
+ - Accidental execution of tools from user-writable directories
727
+ - PATH manipulation attacks
728
+ - Use of potentially compromised tool installations
729
+
730
+ **Example:** Verify tool paths before running:
731
+ ```bash
732
+ pybundle doctor --strict-paths
733
+ ```
734
+
735
+ Output shows trust status:
736
+ ```
737
+ 🔧 Tool Detection:
738
+ git ✅ /usr/bin/git
739
+ python ✅ /path/to/venv/bin/python
740
+ npm ⚠️ /home/user/.nvm/.../npm (untrusted in strict mode)
741
+ ```
742
+
743
+ **Configure custom trusted paths:**
744
+ ```bash
745
+ export PYBUNDLE_TRUSTED_PATHS="/opt/custom/bin:/company/tools/bin"
746
+ pybundle run debug --strict-paths
747
+ ```
748
+
749
+ ### Known Limitations
750
+
751
+ 1. **Requires Trusted Environment**
752
+ - Assumes developer controls their machine and installed tools
753
+ - Not designed for untrusted code execution or sandboxing
754
+ - Tool integrity depends on system package management
755
+
756
+ 2. **Tool Availability**
757
+ - External tools (git, ruff, mypy) are optional
758
+ - Missing tools result in SKIP status, not failure
759
+ - Use `pybundle doctor` to verify available tools
656
760
 
761
+ 3. **File System Access**
762
+ - Reads entire project tree (respecting ignore rules)
763
+ - Writes to `artifacts/` directory by default
764
+ - No privilege escalation or system modification
765
+
766
+ ### For Security Auditors
767
+
768
+ **Bandit Security Scan Results:**
769
+ - 33 low-severity findings (all expected for CLI tool)
770
+ - **B404** (subprocess import): Required for tool functionality
771
+ - **B603** (subprocess calls): Using secure pattern (shell=False, full paths)
772
+ - **B112** (try/except/continue): Acceptable error handling pattern
773
+
774
+ **Risk Classification:** LOW
775
+ - No user-controlled command injection
776
+ - No untrusted input in command execution
777
+ - Full path resolution prevents PATH manipulation attacks
778
+ - Standard development tool security posture
779
+
780
+ **Recommended Usage:**
781
+ ```bash
782
+ # Verify tool paths before execution
783
+ pybundle doctor
784
+
785
+ # Review what tools will be used
786
+ pybundle doctor analysis --json
787
+ ```
788
+
789
+ ---
657
790
  ## 🧩 Why pybundle?
658
791
 
659
792
  pybundle is designed for:
@@ -694,7 +827,7 @@ pybundle follows **Semantic Versioning**.
694
827
  Pinned Git tags are recommended when used as a dependency:
695
828
 
696
829
  ```txt
697
- gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.1.1
830
+ gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.3.1
698
831
  ```
699
832
 
700
833
  ---
@@ -1,4 +1,5 @@
1
- # 🧳 pybundle [![PyPI version](https://img.shields.io/pypi/v/gwc-pybundle.svg?color=2ea44f)](https://pypi.org/project/gwc-pybundle/)
1
+ # 🧳 pybundle ![PyPI - Version](https://img.shields.io/pypi/v/gwc-pybundle)
2
+
2
3
  ![GitHub Release Date](https://img.shields.io/github/release-date/girls-whocode/pybundle?color=orange)
3
4
 
4
5
  [![Python versions](https://img.shields.io/pypi/pyversions/gwc-pybundle.svg?color=3776AB)](https://pypi.org/project/gwc-pybundle/)
@@ -124,7 +125,7 @@ pytest
124
125
  pytest-cov
125
126
  bandit
126
127
  pip-audit
127
- gwc-pybundle==1.1.1
128
+ gwc-pybundle==1.3.1
128
129
  ```
129
130
 
130
131
  Then install:
@@ -161,7 +162,7 @@ See **Usage** for more details.
161
162
  #### From GitHub
162
163
 
163
164
  ```bash
164
- pip install "gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.1.1"
165
+ pip install "gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.3.1"
165
166
  ```
166
167
 
167
168
  Pinning to a tag ensures reproducible behavior.
@@ -310,6 +311,10 @@ The `analysis` and `debug` profiles run comprehensive quality and security check
310
311
  * **ruff** - Fast Python linter and formatter checks
311
312
  * **mypy** - Static type checking for type hints
312
313
  * **pylance** - Syntax error detection and import analysis
314
+ * **vulture** - Dead code detection (v1.3.0+)
315
+ * **radon** - Cyclomatic complexity and maintainability metrics (v1.3.0+)
316
+ * **interrogate** - Docstring coverage analysis (v1.3.0+)
317
+ * **pylint duplication** - Code duplication detection (v1.3.0+)
313
318
 
314
319
  #### Testing & Coverage
315
320
  * **pytest** - Test execution and results
@@ -319,13 +324,31 @@ The `analysis` and `debug` profiles run comprehensive quality and security check
319
324
  * **bandit** - Security vulnerability scanning for Python code
320
325
  * **pip-audit** - Dependency vulnerability checking against known CVEs
321
326
 
327
+ #### Dependency Analysis (v1.3.1+)
328
+ * **pipdeptree** - Full dependency tree with conflict detection
329
+ * **unused dependencies** - Identify installed but unused packages
330
+ * **pip-licenses** - License scanning and compatibility warnings
331
+ * **dependency sizes** - Disk usage analysis per package
332
+
333
+ #### Performance Profiling (v1.4.0+)
334
+ * **cProfile** - CPU profiling to identify bottlenecks
335
+ * **import time analysis** - Detect slow module imports
336
+ * **tracemalloc** - Memory profiling (optional, via `--profile-memory`)
337
+ * **line_profiler** - Line-by-line profiling (optional, requires `@profile` decorators and `--enable-line-profiler`)
338
+
339
+ #### Test Quality & Coverage Enhancement (v1.4.1+)
340
+ * **Test flakiness detection** - Run tests multiple times to identify non-deterministic failures
341
+ * **Branch coverage** - Enhanced coverage.py integration showing missing branches, not just lines
342
+ * **Slow test identification** - Automatically identify and rank tests exceeding time threshold
343
+ * **Mutation testing** - Optional mutmut integration to measure test suite effectiveness (VERY SLOW - disabled by default)
344
+
322
345
  #### Pattern Scanning
323
346
  * **ripgrep scans** - TODO detection, print statements, bare excepts
324
347
 
325
348
  All tools gracefully skip if not installed. Install recommended tools:
326
349
 
327
350
  ```bash
328
- pip install ruff mypy pytest pytest-cov bandit pip-audit
351
+ pip install ruff mypy pytest pytest-cov bandit pip-audit vulture radon interrogate pylint pipdeptree pip-licenses
329
352
  ```
330
353
 
331
354
  For ripgrep (system dependency):
@@ -396,7 +419,6 @@ Commonly used options:
396
419
  * `--outdir PATH` - output directory (default: `<project>/artifacts`)
397
420
  * `--name NAME` - override archive name prefix
398
421
  * `--strict` - fail with non-zero exit code if any step fails
399
- * `--no-spinner` - disable spinner output (CI-friendly)
400
422
  * `--redact / --no-redact` - control secret redaction
401
423
 
402
424
  Tool execution can be selectively disabled:
@@ -484,7 +506,7 @@ When enabled, `pybundle` emits **exactly one JSON object to stdout**, with a **s
484
506
  * AI orchestration
485
507
  * reproducible analysis
486
508
 
487
- No human text, spinners, or formatting are mixed into the output.
509
+ No human text or formatting are mixed into the output.
488
510
 
489
511
  ### Example
490
512
 
@@ -604,7 +626,118 @@ By default, pybundle:
604
626
  Use `--redact / --no-redact` to control behavior.
605
627
 
606
628
  ---
629
+ ## 🔒 Security Considerations
630
+
631
+ **pybundle** is a development tool designed for trusted environments.
632
+
633
+ ### Threat Model
634
+
635
+ * **Environment:** Development machines and CI/CD pipelines
636
+ * **Trust Boundary:** Assumes trusted development environment
637
+ * **Execution Context:** Runs external tools (git, ruff, mypy, pytest, etc.)
638
+ * **Input Sources:** Project files, git repository, installed packages
639
+
640
+ ### Security Posture
641
+
642
+ **Tool Path Resolution:**
643
+ - All external tools use full resolved paths (via `shutil.which()`)
644
+ - Tools are resolved at detection time and stored in `Tooling` dataclass
645
+ - No dynamic PATH manipulation or shell interpretation
646
+ - Eliminates partial path execution vulnerabilities (B607)
647
+ - **Optional strict-paths mode** for enhanced security (v1.2.0+)
648
+ - **Code quality tools** for dead code, complexity, docstrings, and duplication (v1.3.0+)
649
+ - **Dependency intelligence** for conflict detection, license scanning, and size analysis (v1.3.1+)
650
+
651
+ **Subprocess Execution:**
652
+ - All subprocess calls use `shell=False` (default, secure)
653
+ - Arguments passed as lists, never as strings
654
+ - No user-controlled command construction
655
+ - Commands are hardcoded in source code
656
+
657
+ **Data Handling:**
658
+ - Optional secret redaction for sensitive strings in logs
659
+ - Environment variables and paths logged for reproducibility
660
+ - All file operations respect `.gitignore` rules
661
+
662
+ ### Strict-Paths Mode (v1.2.0+)
663
+
664
+ For high-security environments, enable `--strict-paths` to enforce that all tools must be in trusted system directories:
665
+
666
+ ```bash
667
+ pybundle run analysis --strict-paths
668
+ ```
669
+
670
+ **Trusted directories** (configurable via `PYBUNDLE_TRUSTED_PATHS`):
671
+ - `/usr/bin/`, `/usr/local/bin/`, `/bin/`
672
+ - `/opt/homebrew/bin/` (macOS Homebrew)
673
+ - `/snap/bin/` (Ubuntu snaps)
674
+ - Virtual environment paths (`.venv`, `venv`, `.pybundle-venv`)
675
+
676
+ Tools outside trusted directories are excluded in strict mode. This prevents:
677
+ - Accidental execution of tools from user-writable directories
678
+ - PATH manipulation attacks
679
+ - Use of potentially compromised tool installations
680
+
681
+ **Example:** Verify tool paths before running:
682
+ ```bash
683
+ pybundle doctor --strict-paths
684
+ ```
685
+
686
+ Output shows trust status:
687
+ ```
688
+ 🔧 Tool Detection:
689
+ git ✅ /usr/bin/git
690
+ python ✅ /path/to/venv/bin/python
691
+ npm ⚠️ /home/user/.nvm/.../npm (untrusted in strict mode)
692
+ ```
693
+
694
+ **Configure custom trusted paths:**
695
+ ```bash
696
+ export PYBUNDLE_TRUSTED_PATHS="/opt/custom/bin:/company/tools/bin"
697
+ pybundle run debug --strict-paths
698
+ ```
699
+
700
+ ### Known Limitations
701
+
702
+ 1. **Requires Trusted Environment**
703
+ - Assumes developer controls their machine and installed tools
704
+ - Not designed for untrusted code execution or sandboxing
705
+ - Tool integrity depends on system package management
706
+
707
+ 2. **Tool Availability**
708
+ - External tools (git, ruff, mypy) are optional
709
+ - Missing tools result in SKIP status, not failure
710
+ - Use `pybundle doctor` to verify available tools
607
711
 
712
+ 3. **File System Access**
713
+ - Reads entire project tree (respecting ignore rules)
714
+ - Writes to `artifacts/` directory by default
715
+ - No privilege escalation or system modification
716
+
717
+ ### For Security Auditors
718
+
719
+ **Bandit Security Scan Results:**
720
+ - 33 low-severity findings (all expected for CLI tool)
721
+ - **B404** (subprocess import): Required for tool functionality
722
+ - **B603** (subprocess calls): Using secure pattern (shell=False, full paths)
723
+ - **B112** (try/except/continue): Acceptable error handling pattern
724
+
725
+ **Risk Classification:** LOW
726
+ - No user-controlled command injection
727
+ - No untrusted input in command execution
728
+ - Full path resolution prevents PATH manipulation attacks
729
+ - Standard development tool security posture
730
+
731
+ **Recommended Usage:**
732
+ ```bash
733
+ # Verify tool paths before execution
734
+ pybundle doctor
735
+
736
+ # Review what tools will be used
737
+ pybundle doctor analysis --json
738
+ ```
739
+
740
+ ---
608
741
  ## 🧩 Why pybundle?
609
742
 
610
743
  pybundle is designed for:
@@ -645,7 +778,7 @@ pybundle follows **Semantic Versioning**.
645
778
  Pinned Git tags are recommended when used as a dependency:
646
779
 
647
780
  ```txt
648
- gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.1.1
781
+ gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.3.1
649
782
  ```
650
783
 
651
784
  ---
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gwc-pybundle
3
- Version: 1.1.1
3
+ Version: 1.4.1
4
4
  Summary: Deterministic Python project context bundling for humans, automation, and AI
5
- Author: Jessica Brown
5
+ Author-email: Jessica Brown <jessica@codenamejessica.com>
6
6
  License: The MIT License (MIT)
7
7
  =====================
8
8
 
@@ -47,7 +47,8 @@ Description-Content-Type: text/markdown
47
47
  License-File: LICENSE.md
48
48
  Dynamic: license-file
49
49
 
50
- # 🧳 pybundle [![PyPI version](https://img.shields.io/pypi/v/gwc-pybundle.svg?color=2ea44f)](https://pypi.org/project/gwc-pybundle/)
50
+ # 🧳 pybundle ![PyPI - Version](https://img.shields.io/pypi/v/gwc-pybundle)
51
+
51
52
  ![GitHub Release Date](https://img.shields.io/github/release-date/girls-whocode/pybundle?color=orange)
52
53
 
53
54
  [![Python versions](https://img.shields.io/pypi/pyversions/gwc-pybundle.svg?color=3776AB)](https://pypi.org/project/gwc-pybundle/)
@@ -173,7 +174,7 @@ pytest
173
174
  pytest-cov
174
175
  bandit
175
176
  pip-audit
176
- gwc-pybundle==1.1.1
177
+ gwc-pybundle==1.3.1
177
178
  ```
178
179
 
179
180
  Then install:
@@ -210,7 +211,7 @@ See **Usage** for more details.
210
211
  #### From GitHub
211
212
 
212
213
  ```bash
213
- pip install "gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.1.1"
214
+ pip install "gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.3.1"
214
215
  ```
215
216
 
216
217
  Pinning to a tag ensures reproducible behavior.
@@ -359,6 +360,10 @@ The `analysis` and `debug` profiles run comprehensive quality and security check
359
360
  * **ruff** - Fast Python linter and formatter checks
360
361
  * **mypy** - Static type checking for type hints
361
362
  * **pylance** - Syntax error detection and import analysis
363
+ * **vulture** - Dead code detection (v1.3.0+)
364
+ * **radon** - Cyclomatic complexity and maintainability metrics (v1.3.0+)
365
+ * **interrogate** - Docstring coverage analysis (v1.3.0+)
366
+ * **pylint duplication** - Code duplication detection (v1.3.0+)
362
367
 
363
368
  #### Testing & Coverage
364
369
  * **pytest** - Test execution and results
@@ -368,13 +373,31 @@ The `analysis` and `debug` profiles run comprehensive quality and security check
368
373
  * **bandit** - Security vulnerability scanning for Python code
369
374
  * **pip-audit** - Dependency vulnerability checking against known CVEs
370
375
 
376
+ #### Dependency Analysis (v1.3.1+)
377
+ * **pipdeptree** - Full dependency tree with conflict detection
378
+ * **unused dependencies** - Identify installed but unused packages
379
+ * **pip-licenses** - License scanning and compatibility warnings
380
+ * **dependency sizes** - Disk usage analysis per package
381
+
382
+ #### Performance Profiling (v1.4.0+)
383
+ * **cProfile** - CPU profiling to identify bottlenecks
384
+ * **import time analysis** - Detect slow module imports
385
+ * **tracemalloc** - Memory profiling (optional, via `--profile-memory`)
386
+ * **line_profiler** - Line-by-line profiling (optional, requires `@profile` decorators and `--enable-line-profiler`)
387
+
388
+ #### Test Quality & Coverage Enhancement (v1.4.1+)
389
+ * **Test flakiness detection** - Run tests multiple times to identify non-deterministic failures
390
+ * **Branch coverage** - Enhanced coverage.py integration showing missing branches, not just lines
391
+ * **Slow test identification** - Automatically identify and rank tests exceeding time threshold
392
+ * **Mutation testing** - Optional mutmut integration to measure test suite effectiveness (VERY SLOW - disabled by default)
393
+
371
394
  #### Pattern Scanning
372
395
  * **ripgrep scans** - TODO detection, print statements, bare excepts
373
396
 
374
397
  All tools gracefully skip if not installed. Install recommended tools:
375
398
 
376
399
  ```bash
377
- pip install ruff mypy pytest pytest-cov bandit pip-audit
400
+ pip install ruff mypy pytest pytest-cov bandit pip-audit vulture radon interrogate pylint pipdeptree pip-licenses
378
401
  ```
379
402
 
380
403
  For ripgrep (system dependency):
@@ -445,7 +468,6 @@ Commonly used options:
445
468
  * `--outdir PATH` - output directory (default: `<project>/artifacts`)
446
469
  * `--name NAME` - override archive name prefix
447
470
  * `--strict` - fail with non-zero exit code if any step fails
448
- * `--no-spinner` - disable spinner output (CI-friendly)
449
471
  * `--redact / --no-redact` - control secret redaction
450
472
 
451
473
  Tool execution can be selectively disabled:
@@ -533,7 +555,7 @@ When enabled, `pybundle` emits **exactly one JSON object to stdout**, with a **s
533
555
  * AI orchestration
534
556
  * reproducible analysis
535
557
 
536
- No human text, spinners, or formatting are mixed into the output.
558
+ No human text or formatting are mixed into the output.
537
559
 
538
560
  ### Example
539
561
 
@@ -653,7 +675,118 @@ By default, pybundle:
653
675
  Use `--redact / --no-redact` to control behavior.
654
676
 
655
677
  ---
678
+ ## 🔒 Security Considerations
679
+
680
+ **pybundle** is a development tool designed for trusted environments.
681
+
682
+ ### Threat Model
683
+
684
+ * **Environment:** Development machines and CI/CD pipelines
685
+ * **Trust Boundary:** Assumes trusted development environment
686
+ * **Execution Context:** Runs external tools (git, ruff, mypy, pytest, etc.)
687
+ * **Input Sources:** Project files, git repository, installed packages
688
+
689
+ ### Security Posture
690
+
691
+ **Tool Path Resolution:**
692
+ - All external tools use full resolved paths (via `shutil.which()`)
693
+ - Tools are resolved at detection time and stored in `Tooling` dataclass
694
+ - No dynamic PATH manipulation or shell interpretation
695
+ - Eliminates partial path execution vulnerabilities (B607)
696
+ - **Optional strict-paths mode** for enhanced security (v1.2.0+)
697
+ - **Code quality tools** for dead code, complexity, docstrings, and duplication (v1.3.0+)
698
+ - **Dependency intelligence** for conflict detection, license scanning, and size analysis (v1.3.1+)
699
+
700
+ **Subprocess Execution:**
701
+ - All subprocess calls use `shell=False` (default, secure)
702
+ - Arguments passed as lists, never as strings
703
+ - No user-controlled command construction
704
+ - Commands are hardcoded in source code
705
+
706
+ **Data Handling:**
707
+ - Optional secret redaction for sensitive strings in logs
708
+ - Environment variables and paths logged for reproducibility
709
+ - All file operations respect `.gitignore` rules
710
+
711
+ ### Strict-Paths Mode (v1.2.0+)
712
+
713
+ For high-security environments, enable `--strict-paths` to enforce that all tools must be in trusted system directories:
714
+
715
+ ```bash
716
+ pybundle run analysis --strict-paths
717
+ ```
718
+
719
+ **Trusted directories** (configurable via `PYBUNDLE_TRUSTED_PATHS`):
720
+ - `/usr/bin/`, `/usr/local/bin/`, `/bin/`
721
+ - `/opt/homebrew/bin/` (macOS Homebrew)
722
+ - `/snap/bin/` (Ubuntu snaps)
723
+ - Virtual environment paths (`.venv`, `venv`, `.pybundle-venv`)
724
+
725
+ Tools outside trusted directories are excluded in strict mode. This prevents:
726
+ - Accidental execution of tools from user-writable directories
727
+ - PATH manipulation attacks
728
+ - Use of potentially compromised tool installations
729
+
730
+ **Example:** Verify tool paths before running:
731
+ ```bash
732
+ pybundle doctor --strict-paths
733
+ ```
734
+
735
+ Output shows trust status:
736
+ ```
737
+ 🔧 Tool Detection:
738
+ git ✅ /usr/bin/git
739
+ python ✅ /path/to/venv/bin/python
740
+ npm ⚠️ /home/user/.nvm/.../npm (untrusted in strict mode)
741
+ ```
742
+
743
+ **Configure custom trusted paths:**
744
+ ```bash
745
+ export PYBUNDLE_TRUSTED_PATHS="/opt/custom/bin:/company/tools/bin"
746
+ pybundle run debug --strict-paths
747
+ ```
748
+
749
+ ### Known Limitations
750
+
751
+ 1. **Requires Trusted Environment**
752
+ - Assumes developer controls their machine and installed tools
753
+ - Not designed for untrusted code execution or sandboxing
754
+ - Tool integrity depends on system package management
755
+
756
+ 2. **Tool Availability**
757
+ - External tools (git, ruff, mypy) are optional
758
+ - Missing tools result in SKIP status, not failure
759
+ - Use `pybundle doctor` to verify available tools
656
760
 
761
+ 3. **File System Access**
762
+ - Reads entire project tree (respecting ignore rules)
763
+ - Writes to `artifacts/` directory by default
764
+ - No privilege escalation or system modification
765
+
766
+ ### For Security Auditors
767
+
768
+ **Bandit Security Scan Results:**
769
+ - 33 low-severity findings (all expected for CLI tool)
770
+ - **B404** (subprocess import): Required for tool functionality
771
+ - **B603** (subprocess calls): Using secure pattern (shell=False, full paths)
772
+ - **B112** (try/except/continue): Acceptable error handling pattern
773
+
774
+ **Risk Classification:** LOW
775
+ - No user-controlled command injection
776
+ - No untrusted input in command execution
777
+ - Full path resolution prevents PATH manipulation attacks
778
+ - Standard development tool security posture
779
+
780
+ **Recommended Usage:**
781
+ ```bash
782
+ # Verify tool paths before execution
783
+ pybundle doctor
784
+
785
+ # Review what tools will be used
786
+ pybundle doctor analysis --json
787
+ ```
788
+
789
+ ---
657
790
  ## 🧩 Why pybundle?
658
791
 
659
792
  pybundle is designed for:
@@ -694,7 +827,7 @@ pybundle follows **Semantic Versioning**.
694
827
  Pinned Git tags are recommended when used as a dependency:
695
828
 
696
829
  ```txt
697
- gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.1.1
830
+ gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.3.1
698
831
  ```
699
832
 
700
833
  ---
@@ -28,15 +28,30 @@ pybundle/steps/compileall.py
28
28
  pybundle/steps/context_expand.py
29
29
  pybundle/steps/copy_pack.py
30
30
  pybundle/steps/coverage.py
31
+ pybundle/steps/cprofile_step.py
32
+ pybundle/steps/dependency_sizes.py
33
+ pybundle/steps/duplication.py
31
34
  pybundle/steps/error_refs.py
32
35
  pybundle/steps/handoff_md.py
36
+ pybundle/steps/import_time.py
37
+ pybundle/steps/interrogate.py
38
+ pybundle/steps/license_scan.py
39
+ pybundle/steps/line_profiler.py
40
+ pybundle/steps/memory_profile.py
41
+ pybundle/steps/mutation_testing.py
33
42
  pybundle/steps/mypy.py
34
43
  pybundle/steps/pip_audit.py
44
+ pybundle/steps/pipdeptree.py
35
45
  pybundle/steps/pylance.py
36
46
  pybundle/steps/pytest.py
47
+ pybundle/steps/radon.py
37
48
  pybundle/steps/repro_md.py
38
49
  pybundle/steps/rg_scans.py
39
50
  pybundle/steps/roadmap.py
40
51
  pybundle/steps/ruff.py
41
52
  pybundle/steps/shell.py
42
- pybundle/steps/tree.py
53
+ pybundle/steps/slow_tests.py
54
+ pybundle/steps/test_flakiness.py
55
+ pybundle/steps/tree.py
56
+ pybundle/steps/unused_deps.py
57
+ pybundle/steps/vulture.py