gwc-pybundle 0.4.2__tar.gz → 1.1.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 (45) hide show
  1. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/PKG-INFO +261 -13
  2. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/README.md +259 -11
  3. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/gwc_pybundle.egg-info/PKG-INFO +261 -13
  4. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/gwc_pybundle.egg-info/SOURCES.txt +6 -0
  5. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pybundle/cli.py +81 -17
  6. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pybundle/context.py +69 -0
  7. gwc_pybundle-1.1.1/pybundle/filters.py +172 -0
  8. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pybundle/policy.py +22 -84
  9. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pybundle/profiles.py +80 -17
  10. gwc_pybundle-1.1.1/pybundle/roadmap_model.py +42 -0
  11. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pybundle/roadmap_scan.py +55 -22
  12. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pybundle/runner.py +8 -2
  13. gwc_pybundle-1.1.1/pybundle/steps/__init__.py +26 -0
  14. gwc_pybundle-1.1.1/pybundle/steps/bandit.py +74 -0
  15. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pybundle/steps/copy_pack.py +99 -118
  16. gwc_pybundle-1.1.1/pybundle/steps/coverage.py +95 -0
  17. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pybundle/steps/handoff_md.py +7 -6
  18. gwc_pybundle-1.1.1/pybundle/steps/pip_audit.py +47 -0
  19. gwc_pybundle-1.1.1/pybundle/steps/pylance.py +337 -0
  20. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pybundle/steps/roadmap.py +50 -55
  21. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pybundle/steps/tree.py +12 -32
  22. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pyproject.toml +2 -2
  23. gwc_pybundle-0.4.2/pybundle/roadmap_model.py +0 -38
  24. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/LICENSE.md +0 -0
  25. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/gwc_pybundle.egg-info/dependency_links.txt +0 -0
  26. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/gwc_pybundle.egg-info/entry_points.txt +0 -0
  27. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/gwc_pybundle.egg-info/top_level.txt +0 -0
  28. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pybundle/__init__.py +0 -0
  29. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pybundle/__main__.py +0 -0
  30. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pybundle/doctor.py +0 -0
  31. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pybundle/manifest.py +0 -0
  32. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pybundle/packaging.py +0 -0
  33. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pybundle/root_detect.py +0 -0
  34. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pybundle/steps/base.py +0 -0
  35. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pybundle/steps/compileall.py +0 -0
  36. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pybundle/steps/context_expand.py +0 -0
  37. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pybundle/steps/error_refs.py +0 -0
  38. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pybundle/steps/mypy.py +0 -0
  39. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pybundle/steps/pytest.py +0 -0
  40. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pybundle/steps/repro_md.py +0 -0
  41. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pybundle/steps/rg_scans.py +0 -0
  42. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pybundle/steps/ruff.py +0 -0
  43. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pybundle/steps/shell.py +0 -0
  44. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/pybundle/tools.py +0 -0
  45. {gwc_pybundle-0.4.2 → gwc_pybundle-1.1.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gwc-pybundle
3
- Version: 0.4.2
3
+ Version: 1.1.1
4
4
  Summary: Deterministic Python project context bundling for humans, automation, and AI
5
5
  Author: Jessica Brown
6
6
  License: The MIT License (MIT)
@@ -31,7 +31,7 @@ License: The MIT License (MIT)
31
31
  Project-URL: Homepage, https://github.com/girls-whocode/pybundle
32
32
  Project-URL: Repository, https://github.com/girls-whocode/pybundle
33
33
  Project-URL: Issues, https://github.com/girls-whocode/pybundle/issues
34
- Classifier: Development Status :: 4 - Beta
34
+ Classifier: Development Status :: 5 - Production/Stable
35
35
  Classifier: Intended Audience :: Developers
36
36
  Classifier: License :: OSI Approved :: MIT License
37
37
  Classifier: Programming Language :: Python :: 3
@@ -47,9 +47,21 @@ Description-Content-Type: text/markdown
47
47
  License-File: LICENSE.md
48
48
  Dynamic: license-file
49
49
 
50
- # 🧳 pybundle
51
-
52
- **pybundle** is a deterministic, automation-friendly tool for collecting Python project context into a single, shareable bundle - ideal for debugging, audits, AI assistance, CI artifacts, or handoff between engineers.
50
+ # 🧳 pybundle [![PyPI version](https://img.shields.io/pypi/v/gwc-pybundle.svg?color=2ea44f)](https://pypi.org/project/gwc-pybundle/)
51
+ ![GitHub Release Date](https://img.shields.io/github/release-date/girls-whocode/pybundle?color=orange)
52
+
53
+ [![Python versions](https://img.shields.io/pypi/pyversions/gwc-pybundle.svg?color=3776AB)](https://pypi.org/project/gwc-pybundle/)
54
+ [![License](https://img.shields.io/badge/license-MIT-yellow.svg)](LICENSE.md)
55
+ [![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)
56
+ ![GitHub Sponsors](https://img.shields.io/github/sponsors/girls-whocode?color=ec4899)
57
+
58
+ [![CI](https://github.com/girls-whocode/pybundle/actions/workflows/publish.yml/badge.svg?color=fb923c)](https://github.com/girls-whocode/pybundle/actions)
59
+ [![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-14b8a6.svg)](https://github.com/astral-sh/ruff)
60
+ [![Type checked](https://img.shields.io/badge/type%20checked-mypy-0ea5e9.svg)](https://mypy-lang.org/)
61
+ ![Commit Activity](https://img.shields.io/github/commit-activity/t/girls-whocode/pybundle?color=f59e0b)
62
+
63
+
64
+ **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.
53
65
 
54
66
  It produces **machine-readable outputs first**, with optional human-readable summaries layered on top.
55
67
 
@@ -111,7 +123,8 @@ For humans, automation, and AI alike.
111
123
  * 🧾 **Structured summaries** (`SUMMARY.json`)
112
124
  * 🧭 **Respects `.gitignore`** exactly when available
113
125
  * 🛑 **Safely ignores virtualenvs and caches** (even with non-standard names)
114
- * 🔍 Optional tooling checks (ruff, mypy, pytest, ripgrep scans)
126
+ * 🔍 Optional tooling checks (ruff, mypy, pytest, pylance, bandit, pip-audit, coverage)
127
+ * 🛡️ Security scanning (bandit for code issues, pip-audit for dependency CVEs)
115
128
  * 🧪 Deterministic output (stable paths, timestamps, schemas)
116
129
  * 🔒 Secret-safe (optional redaction)
117
130
 
@@ -125,7 +138,7 @@ At minimum, a bundle contains:
125
138
  MANIFEST.json # stable, machine-readable metadata
126
139
  SUMMARY.json # structured summary of collected data
127
140
  src/ # filtered project source snapshot
128
- logs/ # tool outputs (ruff, mypy, etc.)
141
+ logs/ # tool outputs (ruff, mypy, pytest, pylance, bandit, pip-audit, coverage, rg scans)
129
142
  meta/ # environment + tool detection
130
143
  ```
131
144
 
@@ -157,7 +170,10 @@ Create a dedicated requirements file in the root of your project:
157
170
  ruff
158
171
  mypy
159
172
  pytest
160
- gwc-pybundle==0.4.2
173
+ pytest-cov
174
+ bandit
175
+ pip-audit
176
+ gwc-pybundle==1.1.1
161
177
  ```
162
178
 
163
179
  Then install:
@@ -194,7 +210,7 @@ See **Usage** for more details.
194
210
  #### From GitHub
195
211
 
196
212
  ```bash
197
- pip install "gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v0.4.2"
213
+ pip install "gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.1.1"
198
214
  ```
199
215
 
200
216
  Pinning to a tag ensures reproducible behavior.
@@ -225,7 +241,7 @@ Available profiles include:
225
241
 
226
242
  * `analysis` - **full diagnostics** (lint, type-check, tests, scans)
227
243
  * `debug` - **analysis + additional environment validation**
228
- * `backup` - **minimal environment snapshot**
244
+ * `backup` - **minimal source + environment snapshot** (no analysis tools)
229
245
  * `ai` - **AI-optimized context bundle** (lean, source-first)
230
246
 
231
247
  To list all available profiles:
@@ -239,6 +255,132 @@ Profiles are always invoked via:
239
255
  ```bash
240
256
  pybundle run <profile>
241
257
  ```
258
+
259
+ ---
260
+
261
+ ### 💾 Backup profile
262
+
263
+ The `backup` profile creates a minimal, lightweight snapshot ideal for version archival or disaster recovery.
264
+
265
+ Run it with:
266
+
267
+ ```bash
268
+ pybundle run backup
269
+ ```
270
+
271
+ #### What `backup` includes
272
+
273
+ * ✅ Full source code snapshot (respects `.gitignore`)
274
+ * ✅ Git status and diff (`meta/00_git_status.txt`, `meta/01_git_diff.txt`)
275
+ * ✅ Python version (`meta/20_python_version.txt`)
276
+ * ✅ Installed packages (`meta/22_pip_freeze.txt`)
277
+ * ✅ Copy manifest (`meta/50_copy_manifest.txt`)
278
+ * ❌ No linting, type-checking, or tests
279
+ * ❌ No security scanning
280
+ * ❌ No ripgrep scans
281
+
282
+ The result is a **fast, small, restorable archive** with just source code and environment context.
283
+
284
+ #### Restoring a backup
285
+
286
+ Backups are created as either `.zip` or `.tar.gz` archives (see Archive Format below).
287
+
288
+ To extract and inspect:
289
+
290
+ **For .zip archives:**
291
+ ```bash
292
+ # Look for filename with *_backup_<TIMESTAMP>.zip
293
+ unzip <FILENAME>.zip -d restored/
294
+ cd restored/<FILENAME>/
295
+ ```
296
+
297
+ **For .tar.gz archives:**
298
+ ```bash
299
+ # Look for filename with *_backup_<TIMESTAMP>.tar.gz
300
+ tar -xzf <FILENAME>.tar.gz -C restored/
301
+ cd restored/<FILENAME>/
302
+ ```
303
+
304
+ Inside the extracted directory:
305
+
306
+ ```text
307
+ src/ # Your project source code
308
+ meta/
309
+ 00_git_status.txt # Git working tree status at backup time
310
+ 01_git_diff.txt # Uncommitted changes (if any)
311
+ 20_python_version.txt # Python version used
312
+ 22_pip_freeze.txt # Exact package versions
313
+ 50_copy_manifest.txt # List of files included
314
+ MANIFEST.json # Machine-readable metadata
315
+ SUMMARY.json # Structured summary
316
+ RUN_LOG.txt # Execution log
317
+ ```
318
+
319
+ The `src/` directory contains your complete project structure.
320
+ The `meta/22_pip_freeze.txt` file can be used to recreate the exact environment:
321
+
322
+ ```bash
323
+ python -m venv venv
324
+ source venv/bin/activate # or venv\Scripts\activate on Windows
325
+ pip install -r meta/22_pip_freeze.txt
326
+ ```
327
+
328
+ Then copy your source code back:
329
+
330
+ ```bash
331
+ cp -r src/* /path/to/your/project/
332
+ ```
333
+
334
+ #### Archive format fallback
335
+
336
+ pybundle uses **zip** by default for maximum portability.
337
+
338
+ If the `zip` command is not available on your system, pybundle **automatically falls back to tar.gz** format without requiring configuration.
339
+
340
+ This ensures backups can be created on any system, regardless of installed compression tools.
341
+
342
+ To explicitly control the format:
343
+
344
+ ```bash
345
+ pybundle run backup --format zip # Force zip (requires zip command)
346
+ pybundle run backup --format tar.gz # Force tar.gz (requires tar command)
347
+ pybundle run backup --format auto # Auto-detect (default behavior)
348
+ ```
349
+
350
+ Both formats preserve the same internal structure and metadata.
351
+
352
+ ---
353
+
354
+ ### 🔍 Analysis Tools
355
+
356
+ The `analysis` and `debug` profiles run comprehensive quality and security checks:
357
+
358
+ #### Code Quality
359
+ * **ruff** - Fast Python linter and formatter checks
360
+ * **mypy** - Static type checking for type hints
361
+ * **pylance** - Syntax error detection and import analysis
362
+
363
+ #### Testing & Coverage
364
+ * **pytest** - Test execution and results
365
+ * **coverage** - Code coverage analysis (shows tested vs untested code)
366
+
367
+ #### Security
368
+ * **bandit** - Security vulnerability scanning for Python code
369
+ * **pip-audit** - Dependency vulnerability checking against known CVEs
370
+
371
+ #### Pattern Scanning
372
+ * **ripgrep scans** - TODO detection, print statements, bare excepts
373
+
374
+ All tools gracefully skip if not installed. Install recommended tools:
375
+
376
+ ```bash
377
+ pip install ruff mypy pytest pytest-cov bandit pip-audit
378
+ ```
379
+
380
+ For ripgrep (system dependency):
381
+ * macOS: `brew install ripgrep`
382
+ * Ubuntu/Debian: `sudo apt install ripgrep`
383
+
242
384
  ---
243
385
 
244
386
  ### 🤖 AI profile (NEW)
@@ -311,7 +453,11 @@ Tool execution can be selectively disabled:
311
453
  ```bash
312
454
  --no-ruff
313
455
  --no-mypy
456
+ --no-pylance
314
457
  --no-pytest
458
+ --no-bandit
459
+ --no-pip-audit
460
+ --no-coverage
315
461
  --no-rg
316
462
  --no-error-refs
317
463
  --no-context
@@ -373,7 +519,109 @@ pybundle falls back to safe structural rules:
373
519
  * detects virtual environments by structure (`pyvenv.cfg`, `bin/activate`), not by name
374
520
  → works with `.venv`, `.pybundle-venv`, `env-prod-2025`, etc.
375
521
 
376
- No filename guessing. No surprises.
522
+ ---
523
+
524
+ ## 🧾 Machine-Readable Output (`--json`)
525
+
526
+ All `pybundle` commands support a **machine-readable JSON output mode** via the `--json` flag.
527
+
528
+ When enabled, `pybundle` emits **exactly one JSON object to stdout**, with a **stable schema** intended for:
529
+
530
+ * CI pipelines
531
+ * automation scripts
532
+ * external tooling
533
+ * AI orchestration
534
+ * reproducible analysis
535
+
536
+ No human text, spinners, or formatting are mixed into the output.
537
+
538
+ ### Example
539
+
540
+ ```bash
541
+ pybundle run analysis --json
542
+ ```
543
+
544
+ Output:
545
+
546
+ ```json
547
+ {
548
+ "status": "ok",
549
+ "command": "run",
550
+ "profile": "analysis",
551
+ "files_included": 39,
552
+ "files_excluded": 0,
553
+ "duration_ms": 394,
554
+ "bundle_path": "/home/jessica/repositories/python/pybundle/artifacts/pybundle_analysis_20260103T102440Z.zip"
555
+ }
556
+ ```
557
+
558
+ The same structure applies to **all profiles**:
559
+
560
+ ```bash
561
+ pybundle run ai --json
562
+ pybundle run debug --json
563
+ pybundle run backup --json
564
+ ```
565
+
566
+ ---
567
+
568
+ ### JSON Field Definitions
569
+
570
+ | Field | Description |
571
+ | ---------------- | -------------------------------------------------- |
572
+ | `status` | `"ok"` or `"fail"` based on execution result |
573
+ | `command` | The command executed (`run` or `doctor`) |
574
+ | `profile` | The profile used (`analysis`, `ai`, `debug`, etc.) |
575
+ | `files_included` | Number of files copied into the bundle |
576
+ | `files_excluded` | Number of *evaluated* files skipped by policy |
577
+ | `duration_ms` | Total execution time in milliseconds |
578
+ | `bundle_path` | Absolute path to the generated archive |
579
+
580
+ ---
581
+
582
+ ### Important Semantics: `files_excluded`
583
+
584
+ `files_excluded` **does not** mean “everything in the repository that was not bundled.”
585
+
586
+ Instead, it means:
587
+
588
+ > Files that were **eligible under the active profile’s policy** and were *explicitly skipped* after evaluation.
589
+
590
+ Files and directories that are **intentionally out of scope** — such as:
591
+
592
+ * `.git/`
593
+ * `node_modules/`
594
+ * virtual environments
595
+ * build artifacts
596
+ * caches
597
+
598
+ are **never considered**, and therefore are **not counted as excluded**.
599
+
600
+ This design keeps metrics honest and avoids inflating counts with known-irrelevant infrastructure.
601
+
602
+ A value of `files_excluded = 0` simply means:
603
+
604
+ > *Everything that was evaluated was worth keeping.*
605
+
606
+ This is expected and normal for clean, well-structured projects — especially in `ai` mode.
607
+
608
+ ---
609
+
610
+ ### JSON Stability Guarantee
611
+
612
+ The JSON schema emitted by `--json` is considered **part of the public API**.
613
+
614
+ Starting with **v1.0**, field names and meanings will remain stable.
615
+ New fields may be added, but existing fields will not be renamed or removed.
616
+
617
+ This allows `pybundle` to be safely embedded into:
618
+
619
+ * CI workflows
620
+ * automation scripts
621
+ * AI pipelines
622
+ * external tooling
623
+
624
+ without fear of breaking changes.
377
625
 
378
626
  ---
379
627
 
@@ -446,7 +694,7 @@ pybundle follows **Semantic Versioning**.
446
694
  Pinned Git tags are recommended when used as a dependency:
447
695
 
448
696
  ```txt
449
- gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v0.4.2
697
+ gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.1.1
450
698
  ```
451
699
 
452
700
  ---
@@ -469,7 +717,7 @@ The project name, imports, and CLI remain **`pybundle`**.
469
717
  pip install gwc-pybundle
470
718
  pybundle run analysis
471
719
  ```
472
- Look in the autocreated `artifacts/` folder
720
+ Look in the autocreated `artifacts/` folder.
473
721
 
474
722
  ## 📄 License
475
723
 
@@ -1,6 +1,18 @@
1
- # 🧳 pybundle
2
-
3
- **pybundle** is a deterministic, automation-friendly tool for collecting Python project context into a single, shareable bundle - ideal for debugging, audits, AI assistance, CI artifacts, or handoff between engineers.
1
+ # 🧳 pybundle [![PyPI version](https://img.shields.io/pypi/v/gwc-pybundle.svg?color=2ea44f)](https://pypi.org/project/gwc-pybundle/)
2
+ ![GitHub Release Date](https://img.shields.io/github/release-date/girls-whocode/pybundle?color=orange)
3
+
4
+ [![Python versions](https://img.shields.io/pypi/pyversions/gwc-pybundle.svg?color=3776AB)](https://pypi.org/project/gwc-pybundle/)
5
+ [![License](https://img.shields.io/badge/license-MIT-yellow.svg)](LICENSE.md)
6
+ [![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)
7
+ ![GitHub Sponsors](https://img.shields.io/github/sponsors/girls-whocode?color=ec4899)
8
+
9
+ [![CI](https://github.com/girls-whocode/pybundle/actions/workflows/publish.yml/badge.svg?color=fb923c)](https://github.com/girls-whocode/pybundle/actions)
10
+ [![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-14b8a6.svg)](https://github.com/astral-sh/ruff)
11
+ [![Type checked](https://img.shields.io/badge/type%20checked-mypy-0ea5e9.svg)](https://mypy-lang.org/)
12
+ ![Commit Activity](https://img.shields.io/github/commit-activity/t/girls-whocode/pybundle?color=f59e0b)
13
+
14
+
15
+ **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.
4
16
 
5
17
  It produces **machine-readable outputs first**, with optional human-readable summaries layered on top.
6
18
 
@@ -62,7 +74,8 @@ For humans, automation, and AI alike.
62
74
  * 🧾 **Structured summaries** (`SUMMARY.json`)
63
75
  * 🧭 **Respects `.gitignore`** exactly when available
64
76
  * 🛑 **Safely ignores virtualenvs and caches** (even with non-standard names)
65
- * 🔍 Optional tooling checks (ruff, mypy, pytest, ripgrep scans)
77
+ * 🔍 Optional tooling checks (ruff, mypy, pytest, pylance, bandit, pip-audit, coverage)
78
+ * 🛡️ Security scanning (bandit for code issues, pip-audit for dependency CVEs)
66
79
  * 🧪 Deterministic output (stable paths, timestamps, schemas)
67
80
  * 🔒 Secret-safe (optional redaction)
68
81
 
@@ -76,7 +89,7 @@ At minimum, a bundle contains:
76
89
  MANIFEST.json # stable, machine-readable metadata
77
90
  SUMMARY.json # structured summary of collected data
78
91
  src/ # filtered project source snapshot
79
- logs/ # tool outputs (ruff, mypy, etc.)
92
+ logs/ # tool outputs (ruff, mypy, pytest, pylance, bandit, pip-audit, coverage, rg scans)
80
93
  meta/ # environment + tool detection
81
94
  ```
82
95
 
@@ -108,7 +121,10 @@ Create a dedicated requirements file in the root of your project:
108
121
  ruff
109
122
  mypy
110
123
  pytest
111
- gwc-pybundle==0.4.2
124
+ pytest-cov
125
+ bandit
126
+ pip-audit
127
+ gwc-pybundle==1.1.1
112
128
  ```
113
129
 
114
130
  Then install:
@@ -145,7 +161,7 @@ See **Usage** for more details.
145
161
  #### From GitHub
146
162
 
147
163
  ```bash
148
- pip install "gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v0.4.2"
164
+ pip install "gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.1.1"
149
165
  ```
150
166
 
151
167
  Pinning to a tag ensures reproducible behavior.
@@ -176,7 +192,7 @@ Available profiles include:
176
192
 
177
193
  * `analysis` - **full diagnostics** (lint, type-check, tests, scans)
178
194
  * `debug` - **analysis + additional environment validation**
179
- * `backup` - **minimal environment snapshot**
195
+ * `backup` - **minimal source + environment snapshot** (no analysis tools)
180
196
  * `ai` - **AI-optimized context bundle** (lean, source-first)
181
197
 
182
198
  To list all available profiles:
@@ -190,6 +206,132 @@ Profiles are always invoked via:
190
206
  ```bash
191
207
  pybundle run <profile>
192
208
  ```
209
+
210
+ ---
211
+
212
+ ### 💾 Backup profile
213
+
214
+ The `backup` profile creates a minimal, lightweight snapshot ideal for version archival or disaster recovery.
215
+
216
+ Run it with:
217
+
218
+ ```bash
219
+ pybundle run backup
220
+ ```
221
+
222
+ #### What `backup` includes
223
+
224
+ * ✅ Full source code snapshot (respects `.gitignore`)
225
+ * ✅ Git status and diff (`meta/00_git_status.txt`, `meta/01_git_diff.txt`)
226
+ * ✅ Python version (`meta/20_python_version.txt`)
227
+ * ✅ Installed packages (`meta/22_pip_freeze.txt`)
228
+ * ✅ Copy manifest (`meta/50_copy_manifest.txt`)
229
+ * ❌ No linting, type-checking, or tests
230
+ * ❌ No security scanning
231
+ * ❌ No ripgrep scans
232
+
233
+ The result is a **fast, small, restorable archive** with just source code and environment context.
234
+
235
+ #### Restoring a backup
236
+
237
+ Backups are created as either `.zip` or `.tar.gz` archives (see Archive Format below).
238
+
239
+ To extract and inspect:
240
+
241
+ **For .zip archives:**
242
+ ```bash
243
+ # Look for filename with *_backup_<TIMESTAMP>.zip
244
+ unzip <FILENAME>.zip -d restored/
245
+ cd restored/<FILENAME>/
246
+ ```
247
+
248
+ **For .tar.gz archives:**
249
+ ```bash
250
+ # Look for filename with *_backup_<TIMESTAMP>.tar.gz
251
+ tar -xzf <FILENAME>.tar.gz -C restored/
252
+ cd restored/<FILENAME>/
253
+ ```
254
+
255
+ Inside the extracted directory:
256
+
257
+ ```text
258
+ src/ # Your project source code
259
+ meta/
260
+ 00_git_status.txt # Git working tree status at backup time
261
+ 01_git_diff.txt # Uncommitted changes (if any)
262
+ 20_python_version.txt # Python version used
263
+ 22_pip_freeze.txt # Exact package versions
264
+ 50_copy_manifest.txt # List of files included
265
+ MANIFEST.json # Machine-readable metadata
266
+ SUMMARY.json # Structured summary
267
+ RUN_LOG.txt # Execution log
268
+ ```
269
+
270
+ The `src/` directory contains your complete project structure.
271
+ The `meta/22_pip_freeze.txt` file can be used to recreate the exact environment:
272
+
273
+ ```bash
274
+ python -m venv venv
275
+ source venv/bin/activate # or venv\Scripts\activate on Windows
276
+ pip install -r meta/22_pip_freeze.txt
277
+ ```
278
+
279
+ Then copy your source code back:
280
+
281
+ ```bash
282
+ cp -r src/* /path/to/your/project/
283
+ ```
284
+
285
+ #### Archive format fallback
286
+
287
+ pybundle uses **zip** by default for maximum portability.
288
+
289
+ If the `zip` command is not available on your system, pybundle **automatically falls back to tar.gz** format without requiring configuration.
290
+
291
+ This ensures backups can be created on any system, regardless of installed compression tools.
292
+
293
+ To explicitly control the format:
294
+
295
+ ```bash
296
+ pybundle run backup --format zip # Force zip (requires zip command)
297
+ pybundle run backup --format tar.gz # Force tar.gz (requires tar command)
298
+ pybundle run backup --format auto # Auto-detect (default behavior)
299
+ ```
300
+
301
+ Both formats preserve the same internal structure and metadata.
302
+
303
+ ---
304
+
305
+ ### 🔍 Analysis Tools
306
+
307
+ The `analysis` and `debug` profiles run comprehensive quality and security checks:
308
+
309
+ #### Code Quality
310
+ * **ruff** - Fast Python linter and formatter checks
311
+ * **mypy** - Static type checking for type hints
312
+ * **pylance** - Syntax error detection and import analysis
313
+
314
+ #### Testing & Coverage
315
+ * **pytest** - Test execution and results
316
+ * **coverage** - Code coverage analysis (shows tested vs untested code)
317
+
318
+ #### Security
319
+ * **bandit** - Security vulnerability scanning for Python code
320
+ * **pip-audit** - Dependency vulnerability checking against known CVEs
321
+
322
+ #### Pattern Scanning
323
+ * **ripgrep scans** - TODO detection, print statements, bare excepts
324
+
325
+ All tools gracefully skip if not installed. Install recommended tools:
326
+
327
+ ```bash
328
+ pip install ruff mypy pytest pytest-cov bandit pip-audit
329
+ ```
330
+
331
+ For ripgrep (system dependency):
332
+ * macOS: `brew install ripgrep`
333
+ * Ubuntu/Debian: `sudo apt install ripgrep`
334
+
193
335
  ---
194
336
 
195
337
  ### 🤖 AI profile (NEW)
@@ -262,7 +404,11 @@ Tool execution can be selectively disabled:
262
404
  ```bash
263
405
  --no-ruff
264
406
  --no-mypy
407
+ --no-pylance
265
408
  --no-pytest
409
+ --no-bandit
410
+ --no-pip-audit
411
+ --no-coverage
266
412
  --no-rg
267
413
  --no-error-refs
268
414
  --no-context
@@ -324,7 +470,109 @@ pybundle falls back to safe structural rules:
324
470
  * detects virtual environments by structure (`pyvenv.cfg`, `bin/activate`), not by name
325
471
  → works with `.venv`, `.pybundle-venv`, `env-prod-2025`, etc.
326
472
 
327
- No filename guessing. No surprises.
473
+ ---
474
+
475
+ ## 🧾 Machine-Readable Output (`--json`)
476
+
477
+ All `pybundle` commands support a **machine-readable JSON output mode** via the `--json` flag.
478
+
479
+ When enabled, `pybundle` emits **exactly one JSON object to stdout**, with a **stable schema** intended for:
480
+
481
+ * CI pipelines
482
+ * automation scripts
483
+ * external tooling
484
+ * AI orchestration
485
+ * reproducible analysis
486
+
487
+ No human text, spinners, or formatting are mixed into the output.
488
+
489
+ ### Example
490
+
491
+ ```bash
492
+ pybundle run analysis --json
493
+ ```
494
+
495
+ Output:
496
+
497
+ ```json
498
+ {
499
+ "status": "ok",
500
+ "command": "run",
501
+ "profile": "analysis",
502
+ "files_included": 39,
503
+ "files_excluded": 0,
504
+ "duration_ms": 394,
505
+ "bundle_path": "/home/jessica/repositories/python/pybundle/artifacts/pybundle_analysis_20260103T102440Z.zip"
506
+ }
507
+ ```
508
+
509
+ The same structure applies to **all profiles**:
510
+
511
+ ```bash
512
+ pybundle run ai --json
513
+ pybundle run debug --json
514
+ pybundle run backup --json
515
+ ```
516
+
517
+ ---
518
+
519
+ ### JSON Field Definitions
520
+
521
+ | Field | Description |
522
+ | ---------------- | -------------------------------------------------- |
523
+ | `status` | `"ok"` or `"fail"` based on execution result |
524
+ | `command` | The command executed (`run` or `doctor`) |
525
+ | `profile` | The profile used (`analysis`, `ai`, `debug`, etc.) |
526
+ | `files_included` | Number of files copied into the bundle |
527
+ | `files_excluded` | Number of *evaluated* files skipped by policy |
528
+ | `duration_ms` | Total execution time in milliseconds |
529
+ | `bundle_path` | Absolute path to the generated archive |
530
+
531
+ ---
532
+
533
+ ### Important Semantics: `files_excluded`
534
+
535
+ `files_excluded` **does not** mean “everything in the repository that was not bundled.”
536
+
537
+ Instead, it means:
538
+
539
+ > Files that were **eligible under the active profile’s policy** and were *explicitly skipped* after evaluation.
540
+
541
+ Files and directories that are **intentionally out of scope** — such as:
542
+
543
+ * `.git/`
544
+ * `node_modules/`
545
+ * virtual environments
546
+ * build artifacts
547
+ * caches
548
+
549
+ are **never considered**, and therefore are **not counted as excluded**.
550
+
551
+ This design keeps metrics honest and avoids inflating counts with known-irrelevant infrastructure.
552
+
553
+ A value of `files_excluded = 0` simply means:
554
+
555
+ > *Everything that was evaluated was worth keeping.*
556
+
557
+ This is expected and normal for clean, well-structured projects — especially in `ai` mode.
558
+
559
+ ---
560
+
561
+ ### JSON Stability Guarantee
562
+
563
+ The JSON schema emitted by `--json` is considered **part of the public API**.
564
+
565
+ Starting with **v1.0**, field names and meanings will remain stable.
566
+ New fields may be added, but existing fields will not be renamed or removed.
567
+
568
+ This allows `pybundle` to be safely embedded into:
569
+
570
+ * CI workflows
571
+ * automation scripts
572
+ * AI pipelines
573
+ * external tooling
574
+
575
+ without fear of breaking changes.
328
576
 
329
577
  ---
330
578
 
@@ -397,7 +645,7 @@ pybundle follows **Semantic Versioning**.
397
645
  Pinned Git tags are recommended when used as a dependency:
398
646
 
399
647
  ```txt
400
- gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v0.4.2
648
+ gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.1.1
401
649
  ```
402
650
 
403
651
  ---
@@ -420,7 +668,7 @@ The project name, imports, and CLI remain **`pybundle`**.
420
668
  pip install gwc-pybundle
421
669
  pybundle run analysis
422
670
  ```
423
- Look in the autocreated `artifacts/` folder
671
+ Look in the autocreated `artifacts/` folder.
424
672
 
425
673
  ## 📄 License
426
674