{"id":35408569,"url":"https://github.com/girls-whocode/pybundle","last_synced_at":"2026-01-18T14:20:22.156Z","repository":{"id":331264141,"uuid":"1125889634","full_name":"girls-whocode/pybundle","owner":"girls-whocode","description":"Deterministic, automation-friendly Python tool that bundles source code, diagnostics, and metadata into reproducible artifacts for debugging, CI, and AI workflows.","archived":false,"fork":false,"pushed_at":"2026-01-04T21:53:04.000Z","size":73,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-13T19:50:57.960Z","etag":null,"topics":["ai-tools","automation","ci","cli","debugging","developer-experience","devtools","diagnostics","mypy","packaging","pytest","python","ruff","static-analysis"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/gwc-pybundle/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/girls-whocode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-31T15:22:25.000Z","updated_at":"2026-01-08T11:09:21.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/girls-whocode/pybundle","commit_stats":null,"previous_names":["girls-whocode/pybundle"],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/girls-whocode/pybundle","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/girls-whocode%2Fpybundle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/girls-whocode%2Fpybundle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/girls-whocode%2Fpybundle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/girls-whocode%2Fpybundle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/girls-whocode","download_url":"https://codeload.github.com/girls-whocode/pybundle/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/girls-whocode%2Fpybundle/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28537514,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T13:04:05.990Z","status":"ssl_error","status_checked_at":"2026-01-18T13:01:44.092Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-tools","automation","ci","cli","debugging","developer-experience","devtools","diagnostics","mypy","packaging","pytest","python","ruff","static-analysis"],"created_at":"2026-01-02T13:24:35.836Z","updated_at":"2026-01-18T14:20:22.141Z","avatar_url":"https://github.com/girls-whocode.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🧳 pybundle ![PyPI - Version](https://img.shields.io/pypi/v/gwc-pybundle)\n\n![GitHub Release Date](https://img.shields.io/github/release-date/girls-whocode/pybundle?color=orange)\n\n[![Python versions](https://img.shields.io/pypi/pyversions/gwc-pybundle.svg?color=3776AB)](https://pypi.org/project/gwc-pybundle/)\n[![License](https://img.shields.io/badge/license-MIT-yellow.svg)](LICENSE.md)\n[![PyPI Downloads](https://static.pepy.tech/personalized-badge/gwc-pybundle?period=total\u0026units=INTERNATIONAL_SYSTEM\u0026left_color=BLUE\u0026right_color=GREY\u0026left_text=downloads)](https://pepy.tech/projects/gwc-pybundle)\n![GitHub Sponsors](https://img.shields.io/github/sponsors/girls-whocode?color=ec4899)\n\n[![CI](https://github.com/girls-whocode/pybundle/actions/workflows/publish.yml/badge.svg?color=fb923c)](https://github.com/girls-whocode/pybundle/actions)\n[![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-14b8a6.svg)](https://github.com/astral-sh/ruff)\n[![Type checked](https://img.shields.io/badge/type%20checked-mypy-0ea5e9.svg)](https://mypy-lang.org/)\n![Commit Activity](https://img.shields.io/github/commit-activity/t/girls-whocode/pybundle?color=f59e0b)\n\n\n**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.\n\nIt produces **machine-readable outputs first**, with optional human-readable summaries layered on top.\n\n\u003e Think “`git archive` + diagnostics + metadata”, without guessing or heuristics.  \n\n\u003e **Note:** The PyPI package name is `gwc-pybundle`, but the tool is installed and used as `pybundle`.\n---\n\n## 🧠 Why pybundle exists\n\nModern software development compresses what used to be entire teams into a single role.\n\nToday, one developer is often responsible for:\n- application code\n- build systems\n- test tooling\n- deployment logic\n- CI/CD behavior\n- environment differences\n- security implications\n- and increasingly, AI-assisted workflows\n\nThe problem is no longer *how* to write code.\n\nIt’s answering:\n\n\u003e **“Why is this system behaving the way it is?”**\n\nThat question is hard to answer when:\n- context is scattered\n- tooling output is ephemeral\n- environment details are lost\n- source snapshots are incomplete or noisy\n\nAI didn’t create this problem - it exposed it.\n\nLarge language models don’t fail because they lack intelligence.\nThey fail because we give them **uncurated context**.\n\nHumans don’t fail because they can’t debug.\nThey fail because the **cost of reconstructing context** exceeds the time they have.\n\n**pybundle exists to reduce context debt.**\n\nIt captures *what matters*, ignores what doesn’t, and produces a deterministic artifact that explains:\n- what code exists\n- what tools ran\n- what environment was used\n- and why the outputs exist\n\nFor humans, automation, and AI alike.\n\n---\n\n## ✨ Features\n\n* 📦 **Single archive output** (`.zip` or `.tar.gz`)\n* 🧠 **Machine-readable manifest** (`MANIFEST.json`) for automation\n* 🧾 **Structured summaries** (`SUMMARY.json`)\n* 🧭 **Respects `.gitignore`** exactly when available\n* 🛑 **Safely ignores virtualenvs and caches** (even with non-standard names)\n* 🔍 Optional tooling checks (ruff, mypy, pytest, pylance, bandit, pip-audit, coverage)\n* 🛡️ Security scanning (bandit for code issues, pip-audit for dependency CVEs)\n* 🧪 Deterministic output (stable paths, timestamps, schemas)\n* 🔒 Secret-safe (optional redaction)\n\n---\n\n## 📂 What’s in a pybundle archive?\n\nAt minimum, a bundle contains:\n\n```text\nMANIFEST.json        # stable, machine-readable metadata\nSUMMARY.json         # structured summary of collected data\nsrc/                 # filtered project source snapshot\nlogs/                # tool outputs (ruff, mypy, pytest, pylance, bandit, pip-audit, coverage, rg scans)\nmeta/                # environment + tool detection\n```\n\n### `MANIFEST.json` (automation fuel)\n\nIncludes:\n\n* tool paths detected\n* options used\n* archive name + format\n* git commit hash (if available)\n* UTC timestamp\n* schema version (stable)\n\nAnother script can fully understand a bundle **without reading markdown**.\n\n---\n\n## 🚀 Installation\n\nWe recommend using a Python virtual environment for development tooling.\n\n### Quick installation (pybundle tooling) - RECOMMENDED\n\nCreate a dedicated requirements file in the root of your project:\n\n```txt\n# requirements-pybundle.txt\nruff\nmypy\npytest\npytest-cov\nbandit\npip-audit\ngwc-pybundle==1.2.1\n```\n\nThen install:\n\n```bash\npip install -r requirements-pybundle.txt\n```\n\n\u003e **System dependency:**\n\u003e pybundle uses `ripgrep (rg)` for source scanning and expects the system binary.\n\u003e\n\u003e * macOS: `brew install ripgrep`\n\u003e * Ubuntu/Debian: `sudo apt install ripgrep`\n\u003e * Fedora: `sudo dnf install ripgrep`\n\nAfter installation, run:\n\n```bash\npybundle run analysis\n```\n\nA new `artifacts/` directory will be created containing:\n\n* the compressed bundle\n* an extracted working directory\n* machine-readable metadata (`MANIFEST.json`, `SUMMARY.json`)\n\nSee **Usage** for more details.\n\n---\n\n### Advanced installation\n\n#### From GitHub\n\n```bash\npip install \"gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.2.1\"\n```\n\nPinning to a tag ensures reproducible behavior.\n\n#### Editable install (for development)\n\n```bash\npip install -e .\n```\n\n---\n\n## 🧪 Usage\n\nFrom the root of a Python project, run a profile using the `run` command:\n\n```bash\npybundle run analysis\n```\n\nThis builds a timestamped diagnostic bundle under the default `artifacts/` directory.\n\n### Profiles\n\nProfiles define *what* pybundle collects and *which tools* are run.\n\nAvailable profiles include:\n\n* `analysis` - **full diagnostics** (lint, type-check, tests, scans)\n* `debug` - **analysis + additional environment validation**\n* `backup` - **minimal source + environment snapshot** (no analysis tools)\n* `ai` - **AI-optimized context bundle** (lean, source-first)\n\nTo list all available profiles:\n\n```bash\npybundle list-profiles\n```\n\nProfiles are always invoked via:\n\n```bash\npybundle run \u003cprofile\u003e\n```\n\n---\n\n### 💾 Backup profile\n\nThe `backup` profile creates a minimal, lightweight snapshot ideal for version archival or disaster recovery.\n\nRun it with:\n\n```bash\npybundle run backup\n```\n\n#### What `backup` includes\n\n* ✅ Full source code snapshot (respects `.gitignore`)\n* ✅ Git status and diff (`meta/00_git_status.txt`, `meta/01_git_diff.txt`)\n* ✅ Python version (`meta/20_python_version.txt`)\n* ✅ Installed packages (`meta/22_pip_freeze.txt`)\n* ✅ Copy manifest (`meta/50_copy_manifest.txt`)\n* ❌ No linting, type-checking, or tests\n* ❌ No security scanning\n* ❌ No ripgrep scans\n\nThe result is a **fast, small, restorable archive** with just source code and environment context.\n\n#### Restoring a backup\n\nBackups are created as either `.zip` or `.tar.gz` archives (see Archive Format below).\n\nTo extract and inspect:\n\n**For .zip archives:**\n```bash\n# Look for filename with *_backup_\u003cTIMESTAMP\u003e.zip\nunzip \u003cFILENAME\u003e.zip -d restored/\ncd restored/\u003cFILENAME\u003e/\n```\n\n**For .tar.gz archives:**\n```bash\n# Look for filename with *_backup_\u003cTIMESTAMP\u003e.tar.gz\ntar -xzf \u003cFILENAME\u003e.tar.gz -C restored/\ncd restored/\u003cFILENAME\u003e/\n```\n\nInside the extracted directory:\n\n```text\nsrc/                      # Your project source code\nmeta/\n  00_git_status.txt       # Git working tree status at backup time\n  01_git_diff.txt         # Uncommitted changes (if any)\n  20_python_version.txt   # Python version used\n  22_pip_freeze.txt       # Exact package versions\n  50_copy_manifest.txt    # List of files included\nMANIFEST.json             # Machine-readable metadata\nSUMMARY.json              # Structured summary\nRUN_LOG.txt               # Execution log\n```\n\nThe `src/` directory contains your complete project structure.\nThe `meta/22_pip_freeze.txt` file can be used to recreate the exact environment:\n\n```bash\npython -m venv venv\nsource venv/bin/activate  # or venv\\Scripts\\activate on Windows\npip install -r meta/22_pip_freeze.txt\n```\n\nThen copy your source code back:\n\n```bash\ncp -r src/* /path/to/your/project/\n```\n\n#### Archive format fallback\n\npybundle uses **zip** by default for maximum portability.\n\nIf the `zip` command is not available on your system, pybundle **automatically falls back to tar.gz** format without requiring configuration.\n\nThis ensures backups can be created on any system, regardless of installed compression tools.\n\nTo explicitly control the format:\n\n```bash\npybundle run backup --format zip      # Force zip (requires zip command)\npybundle run backup --format tar.gz   # Force tar.gz (requires tar command)\npybundle run backup --format auto     # Auto-detect (default behavior)\n```\n\nBoth formats preserve the same internal structure and metadata.\n\n---\n\n### 🔍 Analysis Tools\n\nThe `analysis` and `debug` profiles run comprehensive quality and security checks:\n\n#### Code Quality\n* **ruff** - Fast Python linter and formatter checks\n* **mypy** - Static type checking for type hints\n* **pylance** - Syntax error detection and import analysis\n\n#### Testing \u0026 Coverage\n* **pytest** - Test execution and results\n* **coverage** - Code coverage analysis (shows tested vs untested code)\n\n#### Security\n* **bandit** - Security vulnerability scanning for Python code\n* **pip-audit** - Dependency vulnerability checking against known CVEs\n\n#### Pattern Scanning\n* **ripgrep scans** - TODO detection, print statements, bare excepts\n\nAll tools gracefully skip if not installed. Install recommended tools:\n\n```bash\npip install ruff mypy pytest pytest-cov bandit pip-audit\n```\n\nFor ripgrep (system dependency):\n* macOS: `brew install ripgrep`\n* Ubuntu/Debian: `sudo apt install ripgrep`\n\n---\n\n### 🤖 AI profile (NEW)\n\nThe `ai` profile is optimized for handing a project to AI tooling\n(ChatGPT, local LLMs, code assistants, etc.).\n\nIt prioritizes **source code and reproducible context**, while skipping\nexpensive or noisy steps by default.\n\nRun it with:\n\n```bash\npybundle run ai\n```\n\n#### What `ai` does by default\n\n* ✅ Includes full curated source snapshot (`src/`)\n* ✅ Includes environment + git metadata\n* ✅ Generates `REPRO.md` and `HANDOFF.md`\n* ❌ Skips linting, type-checking, tests\n* ❌ Skips ripgrep scans and error-context expansion\n* ❌ Skips `compileall` unless explicitly enabled\n\nThe result is a **small, fast, AI-friendly bundle** that still preserves\ndeterminism and traceability.\n\nYou may selectively re-enable tools:\n\n```bash\npybundle run ai --ruff --mypy\npybundle run ai --compileall\n```\n\nThis makes `ai` suitable for:\n\n* AI-assisted refactoring\n* Large-context summarization\n* Code review handoff\n* Offline or local LLM workflows\n\n---\n\n### Common options\n\nMost usage customizations are done through flags on `pybundle run`.\n\nExample:\n\n```bash\npybundle run analysis \\\n  --format zip \\\n  --outdir ./artifacts \\\n  --name myproject-bundle \\\n  --strict\n```\n\nCommonly used options:\n\n* `--format {auto,zip,tar.gz}` - archive format\n* `--outdir PATH` - output directory (default: `\u003cproject\u003e/artifacts`)\n* `--name NAME` - override archive name prefix\n* `--strict` - fail with non-zero exit code if any step fails\n* `--redact / --no-redact` - control secret redaction\n\nTool execution can be selectively disabled:\n\n```bash\n--no-ruff\n--no-mypy\n--no-pylance\n--no-pytest\n--no-bandit\n--no-pip-audit\n--no-coverage\n--no-rg\n--no-error-refs\n--no-context\n```\n\nFor the full list of options:\n\n```bash\npybundle run --help\n```\n\n---\n\n### Doctor mode\n\nTo see which tools are available and what *would* run (without creating a bundle):\n\n```bash\npybundle doctor\n```\n\nYou may optionally specify a profile to preview:\n\n```bash\npybundle doctor analysis\n```\n\nThis is useful for validating environment readiness (CI, fresh machines, etc.).\n\n---\n\n### Version\n\nTo check the installed version:\n\n```bash\npybundle version\n```\n\n---\n\n## 🧠 Ignore behavior (important)\n\n### If inside a Git repository\n\npybundle uses **Git itself** to determine which files are included:\n\n* `.gitignore`\n* `.git/info/exclude`\n* global gitignore rules\n\nThis guarantees pybundle sees the project **exactly as Git does**.\n\n### If Git is unavailable\n\npybundle falls back to safe structural rules:\n\n* ignores `__pycache__`, `.ruff_cache`, `.mypy_cache`, `.pytest_cache`, etc.\n* detects virtual environments by structure (`pyvenv.cfg`, `bin/activate`), not by name\n  → works with `.venv`, `.pybundle-venv`, `env-prod-2025`, etc.\n\n---\n\n## 🧾 Machine-Readable Output (`--json`)\n\nAll `pybundle` commands support a **machine-readable JSON output mode** via the `--json` flag.\n\nWhen enabled, `pybundle` emits **exactly one JSON object to stdout**, with a **stable schema** intended for:\n\n* CI pipelines\n* automation scripts\n* external tooling\n* AI orchestration\n* reproducible analysis\n\nNo human text or formatting are mixed into the output.\n\n### Example\n\n```bash\npybundle run analysis --json\n```\n\nOutput:\n\n```json\n{\n  \"status\": \"ok\",\n  \"command\": \"run\",\n  \"profile\": \"analysis\",\n  \"files_included\": 39,\n  \"files_excluded\": 0,\n  \"duration_ms\": 394,\n  \"bundle_path\": \"/home/jessica/repositories/python/pybundle/artifacts/pybundle_analysis_20260103T102440Z.zip\"\n}\n```\n\nThe same structure applies to **all profiles**:\n\n```bash\npybundle run ai --json\npybundle run debug --json\npybundle run backup --json\n```\n\n---\n\n### JSON Field Definitions\n\n| Field            | Description                                        |\n| ---------------- | -------------------------------------------------- |\n| `status`         | `\"ok\"` or `\"fail\"` based on execution result       |\n| `command`        | The command executed (`run` or `doctor`)           |\n| `profile`        | The profile used (`analysis`, `ai`, `debug`, etc.) |\n| `files_included` | Number of files copied into the bundle             |\n| `files_excluded` | Number of *evaluated* files skipped by policy      |\n| `duration_ms`    | Total execution time in milliseconds               |\n| `bundle_path`    | Absolute path to the generated archive             |\n\n---\n\n### Important Semantics: `files_excluded`\n\n`files_excluded` **does not** mean “everything in the repository that was not bundled.”\n\nInstead, it means:\n\n\u003e Files that were **eligible under the active profile’s policy** and were *explicitly skipped* after evaluation.\n\nFiles and directories that are **intentionally out of scope** — such as:\n\n* `.git/`\n* `node_modules/`\n* virtual environments\n* build artifacts\n* caches\n\nare **never considered**, and therefore are **not counted as excluded**.\n\nThis design keeps metrics honest and avoids inflating counts with known-irrelevant infrastructure.\n\nA value of `files_excluded = 0` simply means:\n\n\u003e *Everything that was evaluated was worth keeping.*\n\nThis is expected and normal for clean, well-structured projects — especially in `ai` mode.\n\n---\n\n### JSON Stability Guarantee\n\nThe JSON schema emitted by `--json` is considered **part of the public API**.\n\nStarting with **v1.0**, field names and meanings will remain stable.\nNew fields may be added, but existing fields will not be renamed or removed.\n\nThis allows `pybundle` to be safely embedded into:\n\n* CI workflows\n* automation scripts\n* AI pipelines\n* external tooling\n\nwithout fear of breaking changes.\n\n---\n\n## 📜 Profiles\n\npybundle is profile-driven. Each profile defines:\n\n* what files are collected\n* which tools run\n* what metadata is emitted\n\nExample profiles:\n\n* `analysis`\n* `source`\n* `minimal`\n\nProfiles are extensible - add your own without modifying core logic.\n\n---\n\n## 🔐 Safety \u0026 Redaction\n\nBy default, pybundle:\n\n* avoids scanning known secret locations\n* supports optional redaction of sensitive strings in logs\n\nUse `--redact / --no-redact` to control behavior.\n\n---\n## 🔒 Security Considerations\n\n**pybundle** is a development tool designed for trusted environments.\n\n### Threat Model\n\n* **Environment:** Development machines and CI/CD pipelines\n* **Trust Boundary:** Assumes trusted development environment\n* **Execution Context:** Runs external tools (git, ruff, mypy, pytest, etc.)\n* **Input Sources:** Project files, git repository, installed packages\n\n### Security Posture\n\n**Tool Path Resolution:**\n- All external tools use full resolved paths (via `shutil.which()`)\n- Tools are resolved at detection time and stored in `Tooling` dataclass\n- No dynamic PATH manipulation or shell interpretation\n- Eliminates partial path execution vulnerabilities (B607)\n- **Optional strict-paths mode** for enhanced security (v1.2.1+)\n\n**Subprocess Execution:**\n- All subprocess calls use `shell=False` (default, secure)\n- Arguments passed as lists, never as strings\n- No user-controlled command construction\n- Commands are hardcoded in source code\n\n**Data Handling:**\n- Optional secret redaction for sensitive strings in logs\n- Environment variables and paths logged for reproducibility\n- All file operations respect `.gitignore` rules\n\n### Strict-Paths Mode (v1.2.1+)\n\nFor high-security environments, enable `--strict-paths` to enforce that all tools must be in trusted system directories:\n\n```bash\npybundle run analysis --strict-paths\n```\n\n**Trusted directories** (configurable via `PYBUNDLE_TRUSTED_PATHS`):\n- `/usr/bin/`, `/usr/local/bin/`, `/bin/`\n- `/opt/homebrew/bin/` (macOS Homebrew)\n- `/snap/bin/` (Ubuntu snaps)\n- Virtual environment paths (`.venv`, `venv`, `.pybundle-venv`)\n\nTools outside trusted directories are excluded in strict mode. This prevents:\n- Accidental execution of tools from user-writable directories\n- PATH manipulation attacks\n- Use of potentially compromised tool installations\n\n**Example:** Verify tool paths before running:\n```bash\npybundle doctor --strict-paths\n```\n\nOutput shows trust status:\n```\n🔧 Tool Detection:\ngit        ✅ /usr/bin/git\npython     ✅ /path/to/venv/bin/python\nnpm        ⚠️  /home/user/.nvm/.../npm  (untrusted in strict mode)\n```\n\n**Configure custom trusted paths:**\n```bash\nexport PYBUNDLE_TRUSTED_PATHS=\"/opt/custom/bin:/company/tools/bin\"\npybundle run debug --strict-paths\n```\n\n### Known Limitations\n\n1. **Requires Trusted Environment**\n   - Assumes developer controls their machine and installed tools\n   - Not designed for untrusted code execution or sandboxing\n   - Tool integrity depends on system package management\n\n2. **Tool Availability**\n   - External tools (git, ruff, mypy) are optional\n   - Missing tools result in SKIP status, not failure\n   - Use `pybundle doctor` to verify available tools\n\n3. **File System Access**\n   - Reads entire project tree (respecting ignore rules)\n   - Writes to `artifacts/` directory by default\n   - No privilege escalation or system modification\n\n### For Security Auditors\n\n**Bandit Security Scan Results:**\n- 33 low-severity findings (all expected for CLI tool)\n- **B404** (subprocess import): Required for tool functionality\n- **B603** (subprocess calls): Using secure pattern (shell=False, full paths)\n- **B112** (try/except/continue): Acceptable error handling pattern\n\n**Risk Classification:** LOW\n- No user-controlled command injection\n- No untrusted input in command execution\n- Full path resolution prevents PATH manipulation attacks\n- Standard development tool security posture\n\n**Recommended Usage:**\n```bash\n# Verify tool paths before execution\npybundle doctor\n\n# Review what tools will be used\npybundle doctor analysis --json\n```\n\n---\n## 🧩 Why pybundle?\n\npybundle is designed for:\n\n* handing a project to another engineer\n* attaching context to a bug report\n* feeding a codebase to AI tooling\n* generating CI artifacts\n* preserving “what exactly did we run?”\n* producing **AI-consumable project context** without guesswork\n\nIt prioritizes **determinism, traceability, and automation** over clever heuristics.\n\n---\n\n## 🛠 Development Notes\n\n* Python ≥ 3.9\n* Uses modern tooling (ruff, mypy)\n* Fully type-checked\n* Formatter-clean\n* No test suite *yet* (intentional; coming later)\n\nDuring development, run:\n\n```bash\npython -m pybundle ...\n```\n\nto bypass shell caching.\n\n---\n\n## 📌 Versioning\n\npybundle follows **Semantic Versioning**.\n\nPinned Git tags are recommended when used as a dependency:\n\n```txt\ngwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.2.1\n```\n\n---\n\n## 🧠 Philosophy\n\n\u003e If a tool produces output, it should also produce metadata about **how** and **why** that output exists.\n\npybundle treats context as a first-class artifact.\n\n---\n\n## 📦 Package naming note\n\nThe distribution name on PyPI is **`gwc-pybundle`** to avoid conflicts with existing packages.\n\nThe project name, imports, and CLI remain **`pybundle`**.\n\n```bash\npip install gwc-pybundle\npybundle run analysis\n```\nLook in the autocreated `artifacts/` folder.\n\n## 📄 License\n\nMIT License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgirls-whocode%2Fpybundle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgirls-whocode%2Fpybundle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgirls-whocode%2Fpybundle/lists"}