Skip to main content

contextzip

Package exactly the right parts of your codebase and paste it into any AI tool — in one command.

pip install contextzip

Why contextzip

Every AI session starts the same way: hunt down the relevant files, manually skip node_modules, build artifacts, and lock files, zip them, find the zip, upload it. Then do it all again next session.

contextzip eliminates that entirely. Run it from your project root — it detects your stack, applies smart exclusions, produces a lean ZIP, and opens your file manager with the archive already selected. One Ctrl+C and you're done.

And when the AI tool hands you a ZIP back with the changes, contextzip apply-zip closes the loop — no manual unzip-and-hope, no losing track of what actually changed.


Features

  • Smart framework detection — automatically identifies Node.js, Next.js, Python, Django, FastAPI, Rust, Go, and Ruby, applying the right exclusion rules for each. Detection isn't limited to the project root: a shallow, bounded scan of subdirectories means a monorepo (frontend/ + backend/, etc.) gets every ecosystem it contains detected and excluded correctly, not just whatever sits at the top level
  • Respects .gitignore — your existing ignore patterns are honoured automatically
  • Git-aware packaging — use --git-changes to package only modified, staged, and untracked files; perfect for incremental debugging and PR review sessions
  • AI-powered file selection — describe your task in plain English with --prompt and Gemini selects the minimum relevant files automatically, no manual hunting required
  • Apply AI-returned changes backcontextzip apply-zip takes the ZIP an AI tool hands you back and writes it into your project safely: diffed against what was actually sent, backed up before anything is overwritten, and never silently deleting anything
  • Terminal error watcher — wrap any dev server with contextzip watch to auto-detect errors and package a ready-to-upload debug context in one keypress
  • Configurable workspace location.contextzip/ lives at the git root by default, but you can pin it elsewhere per-machine (contextzip config --set-workspace) or for the whole team via a committed .contextzip.json
  • Persistent workspace — all generated ZIPs land in .contextzip/, discoverable, reusable, and git-ignored automatically
  • Warns before it's a problem — flags large (≥ 1 MB) and binary files that AI tools can't read, before you waste an upload
  • Handles edge cases — dangling symlinks, unreadable files, and paths outside the project tree are caught and reported, never silently dropped
  • Full CLI control--include, --exclude, --dry-run, --output, all composable

Installation

Requires Python 3.9+

pip install contextzip

With pipx (recommended for CLI tools — keeps it isolated):

pipx install contextzip

Verify:

contextzip --version

Quick start

Navigate to any project and run:

cd ~/projects/my-app
contextzip

contextzip will:

  1. Detect your framework (e.g. Next.js + Node.js)
  2. Apply the appropriate exclusion rules
  3. Create a compressed ZIP in .contextzip/ at your project root
  4. Open your file manager with the ZIP selected and ready to copy

Usage

contextzip [OPTIONS]
Option Description
-p, --prompt TEXT Describe your task in plain English — Gemini selects only the relevant files
-i, --include PATH Only include files under this path (repeatable)
-e, --exclude PATTERN Add exclusion patterns in gitignore syntax (repeatable)
--git-changes Only include files reported by git as modified, staged, or untracked
-n, --dry-run Preview what would be included without creating a ZIP
-o, --output FILE Write ZIP to a custom path
-v, --verbose Show every included and excluded file with sizes
--no-clipboard Skip the clipboard / folder-open step
--no-gitignore Ignore the project's .gitignore

Subcommands: exclude, include, apply-zip, watch, config — run contextzip --help for full details.


Examples

# Preview what would be packaged
contextzip --dry-run --verbose

# Package only specific directories
contextzip --include src --include app

# Exclude additional patterns
contextzip --exclude "*.log" --exclude "tests/"

# Package only git-modified files
contextzip --git-changes

# Let AI pick only the files relevant to your task
contextzip --prompt "Change toast color on failed login"

# Preview AI file selection without creating a ZIP
contextzip --prompt "Refactor auth middleware" --dry-run

# Save to a custom path
contextzip --output ~/Desktop/project-context.zip

# Apply the ZIP an AI tool handed back
contextzip apply-zip

Python API

contextzip is also usable as a library. All CLI capabilities are available as plain Python functions — no Click, no Rich output, no SystemExit.

from contextzip import get_git_changes, get_files, create_zip, apply_zip

# Get changed files and use them directly
collection = get_git_changes()
for f in collection.files:          # plain pathlib.Path objects
    upload(f)                       # no zip required

# Or zip them and upload the archive
pkg = create_zip(collection, output="/tmp/changes.zip")
with open(pkg.zip_path, "rb") as f:
    upload_to_s3(f)

# Full project scan with filters
collection = get_files(include=["src/"], exclude=["tests/"])
pkg = create_zip(collection, output="/tmp/upload.zip")
print(f"{pkg.file_count} files, {pkg.compressed_bytes} bytes")

# Apply a ZIP an AI tool returned (auto-detects from .contextzip/inbox/)
result = apply_zip()
print(f"Wrote {len(result.written)} files, backup at {result.backup_dir}")
Function Description
get_git_changes(path?) Modified, added, and untracked files from git
get_files(path?, include?, exclude?) All project files after exclusion rules
create_zip(collection, output?) Write a FileCollection to a ZIP archive
apply_zip(zip_path?, project_dir?, manifest?) Apply an AI-returned ZIP back into the project
detect_ecosystem(path?) Detect framework and confidence level

All functions default path to Path.cwd(). Errors raise typed exceptions (NotARepositoryError, GitNotFoundError, NoFilesError, ZipNotFoundError, etc.) rather than exiting.


AI-powered file selection

The --prompt flag lets you describe a task in plain English. contextzip scans your project, builds a lightweight file map, and asks Gemini to return the minimum set of files needed for that task — typically 2–5, never more than 10. The result is a tightly scoped ZIP with only what you'd actually open to make the change.

contextzip --prompt "Change toast color on failed login"
# → components/ui/toast.tsx, app/login/page.tsx, lib/auth.ts

The ZIP also includes a prompt.txt describing the task, so when you drop it into Claude, ChatGPT, or any other AI tool, it immediately understands what you're trying to do.

First-time setup: --prompt requires a free Gemini API key from Google AI Studio — no credit card needed. On first use, contextzip guides you through obtaining and saving one. You can also skip the setup entirely with an environment variable:

export GEMINI_API_KEY=AIza...

Manage your key at any time:

contextzip config               # show current key status
contextzip config --reset-key   # clear and re-run setup

Applying AI-returned changes

Once an AI tool has made its edits and handed you back a ZIP, contextzip apply-zip writes those changes into your project — safely.

# Drop the AI's returned zip into .contextzip/inbox/, then:
contextzip apply-zip

# Or point at it directly, wherever it landed:
contextzip apply-zip ~/Downloads/fixed-project.zip

# Preview first, with full per-file detail:
contextzip apply-zip --dry-run --verbose

# Skip the confirmation prompt (e.g. in a script):
contextzip apply-zip --yes

How it knows what's safe to apply

Every ZIP contextzip creates gets a small manifest written next to it in .contextzip/output/ — a hash of each included file, taken at zip-time. This manifest is never added to the ZIP itself. It stays local, so it's never uploaded and never visible to whatever AI tool the ZIP is pasted into — nothing for a model, or a curious teammate, to notice or ask about.

When you run apply-zip, it diffs the returned ZIP against that manifest and classifies every file:

Status Meaning Applied automatically?
New Wasn't part of the original ZIP Yes
Modified Was sent, content changed, and your local copy hasn't moved since Yes
Unchanged Identical to what's already on disk Skipped — nothing to do
Drifted Your local file changed (or was deleted) since you zipped it No — flagged, asks first
Untracked In the returned ZIP but has no baseline to compare against No — flagged, asks first

The common case — you zip some files, the AI edits them, nothing else touched your project meanwhile — applies straight through with just a summary printed, no prompt. Anything that could clobber your own work, or introduce a path you didn't expect, stops and asks before writing.

If a ZIP arrives with no matching manifest at all (e.g. it wasn't produced by a contextzip round trip), every already-existing path is treated as untracked and you'll be asked to confirm the whole batch.

What it does and doesn't do

  • Only adds and modifies files. Deletions are never inferred from a ZIP's contents — a file that's simply missing from the returned ZIP is left alone.
  • Backs up before overwriting. Every file about to be touched is copied into .contextzip/backups/<timestamp>/ first, preserving its relative path.
  • Rejects unsafe paths outright. Any ZIP entry that would resolve outside your project (../../etc/passwd-style path traversal) is refused before anything is written — no override flag, no exceptions.
  • Archives what it consumes. Once applied, the ZIP is moved to .contextzip/inbox/applied/<timestamp>-name.zip — it won't be picked up again by accident, and stays around as an audit trail. ZIPs applied via an explicit path outside the inbox are left where you put them.

Finding the right ZIP and manifest

contextzip apply-zip                    # exactly one *.zip in .contextzip/inbox/ → uses it
contextzip apply-zip path/to/fix.zip    # explicit path always overrides the inbox
contextzip apply-zip --manifest path/to/codebase.manifest.json   # override auto-detection

If .contextzip/inbox/ has more than one ZIP and you don't specify which, apply-zip lists them and asks you to be explicit rather than guessing. Manifest auto-detection picks the most recently created *.manifest.json under .contextzip/output/ — correct for the normal one-round-trip-at-a-time flow; pass --manifest explicitly if you've generated several ZIPs before getting a response back.


Terminal error watcher

The watch command wraps your dev server, buffers its output, and packages a debug-ready ZIP the moment you spot an error — no manual file hunting, no copy-pasting stack traces.

contextzip watch -- npm run dev
contextzip watch -- python manage.py runserver

contextzip starts your process normally. You see output exactly as you would without it. In the background, it watches the stream for errors. When one is detected, a prompt appears directly beneath the error output:

╭─ contextzip · error detected ─────────────────────╮
│  Press [D] to package debug context  [S] to skip  │
╰───────────────────────────────────────────────────╯

Press D and contextzip immediately writes .contextzip/output/debug-context.zip. Your server keeps running — no restart, no interruption.

What's in the ZIP:

File Contents
prompt.txt Auto-generated: detected framework, error type, and task description — ready to paste into any AI tool
terminal-error.txt The cleaned, noise-stripped error block and stack trace
source-files.zip Source files referenced in the stack trace, paths preserved

On Ctrl+C: If no errors were packaged during the session, contextzip offers one final prompt to capture the full session output — useful when something looked wrong but didn't match a known error pattern.

Supported frameworks: Python, Django, FastAPI, Node.js, Next.js, React. Each has its own error detection patterns and noise filters so the output stays clean across stacks.

Note: watch works best with dev servers that don't read stdin interactively (npm run dev, manage.py runserver, etc.). PTY emulation is not used — on Windows, color passthrough may be limited.


What gets excluded

contextzip stacks exclusion rules based on your detected stack, on top of your .gitignore.

Always excluded: .git/, .env files, logs, caches, editor config (.vscode/, .idea/), OS files (.DS_Store, Thumbs.db), common binary formats, and contextzip's own .contextzip/ working folder.

By framework:

Stack Additional exclusions
Node.js / Next.js node_modules/, .next/, dist/, build/, lock files, *.min.js, *.d.ts
Python / Django / FastAPI __pycache__/, .venv/, *.pyc, migrations/, .pytest_cache/, lock files
Rust target/, Cargo.lock, *.rlib
Go vendor/, go.sum, bin/

Detection is additive — a monorepo with both package.json and pyproject.toml gets both rule sets applied. Marker files don't have to sit at the project root: contextzip also does a shallow, bounded scan of subdirectories (2 levels deep, skipping node_modules/, .venv/, .git/, and other dependency/build dirs it would never want to look inside anyway), so a layout like

root/
  frontend/package.json
  backend/requirements.txt

detects both Node.js and Python from root/, without either marker existing at the top level. Run with default output (not --dry-run --verbose) and you'll see which subdirectory each ecosystem came from, e.g. Next.js (frontend/) + FastAPI (backend/).


Workspace location

By default, .contextzip/ is created at your git root — that's _find_git_root() walking up from the current directory until it finds a .git folder; outside a repo, it falls back to the current directory. This can be overridden two ways, in order of priority:

  1. CONTEXTZIP_WORKSPACE_LOCATION environment variable — for a one-off override on a single run
  2. A committed .contextzip.json at the project root — team-shared, applies to everyone who clones the repo:
    { "workspace_location": "git-root" }
    
  3. Your personal config — a per-machine default that doesn't get committed:
    contextzip config --set-workspace cwd          # always use ./.contextzip wherever you run it
    contextzip config --set-workspace git-root      # back to the default
    contextzip config --set-workspace ~/zips        # a fixed custom location, anywhere
    contextzip config --reset-workspace             # clear your personal override
    

Accepted values are "git-root", "cwd", or any path (absolute, or relative to the git root). Run contextzip config with no flags to see which value is currently active and where it came from.

This matters most for monorepos where you sometimes run contextzip from a subdirectory (cd frontend && contextzip) — with the default git-root setting, the workspace still lands at the repo root no matter where you ran it from, so you don't end up with scattered .contextzip/ folders across frontend/, backend/, etc. Set workspace_location: "cwd" in a project's .contextzip.json instead if you'd rather each subproject keep its own.

Workspace layout:

.contextzip/
  config.json               # team-shared preferences (committed)
  .gitignore                # ignores everything below except itself + config.json
  output/
    codebase.zip            # what you generate and send out
    codebase.manifest.json  # local-only — never uploaded, used by apply-zip
  inbox/
    <ai-returned>.zip        # drop AI-returned zips here for apply-zip to pick up
    applied/
      <timestamp>-name.zip   # archived after a successful apply-zip
  backups/
    <timestamp>/             # pre-overwrite copies, one folder per apply-zip run

Contributing

Contributions are welcome — especially new framework rule sets, edge case fixes, and platform-specific clipboard improvements.

See CONTRIBUTING.md for local setup, how to add a new framework, and PR guidelines. Please open an issue before starting a large PR so we can align on the approach first.


License

MIT — see LICENSE for details.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

contextzip-0.3.8.tar.gz (102.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

contextzip-0.3.8-py3-none-any.whl (110.2 kB view details)

Uploaded Python 3

File details

Details for the file contextzip-0.3.8.tar.gz.

File metadata

  • Download URL: contextzip-0.3.8.tar.gz
  • Upload date:
  • Size: 102.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for contextzip-0.3.8.tar.gz
Algorithm Hash digest
SHA256 c402e48b2b63628b8f8b63de3f9110c42460ea6b39ce37e1ccea7c86c94e387f
MD5 d86dc3e5f78f9e86b9f0b8fa9df69588
BLAKE2b-256 c4494b1db5e1fc9f3be2de2f759993e807b038ce0e3b95220dff8d20302d9ce0

See more details on using hashes here.

Provenance

The following attestation bundles were made for contextzip-0.3.8.tar.gz:

Publisher: python-publish.yml on akadeepesh/contextzip

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file contextzip-0.3.8-py3-none-any.whl.

File metadata

  • Download URL: contextzip-0.3.8-py3-none-any.whl
  • Upload date:
  • Size: 110.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for contextzip-0.3.8-py3-none-any.whl
Algorithm Hash digest
SHA256 b7f7b401ffc2a2e0cc412bf44fe127e8e5e646a89582c813eaf0f5955907ef47
MD5 50a290320fe09ccd93378f9b36d2cddc
BLAKE2b-256 a082526a9a25db40df442238c4465d6b5c40eb13a57a5af3f763b49550013c3e

See more details on using hashes here.

Provenance

The following attestation bundles were made for contextzip-0.3.8-py3-none-any.whl:

Publisher: python-publish.yml on akadeepesh/contextzip

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.3.8 This release

2 files

0.3.7

2 files

0.3.6

2 files

0.3.5

2 files

0.3.4

2 files

0.3.3

2 files

0.3.2

2 files

0.3.1

2 files

0.3.0

2 files

0.2.4

2 files

0.2.3

2 files

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

0.1.2

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page