diff --git a/README.md b/README.md index 3f1a833..7c7a24d 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ contextzip eliminates that entirely. Run it from your project root, it detects y - **Smart framework detection** : automatically identifies Node.js, Next.js, Python, Django, FastAPI, Rust, Go, Ruby and applies the right exclusion rules for each - **Respects your `.gitignore`** : patterns from your existing gitignore are honoured automatically - **Git-aware packaging** : package only modified, staged, unstaged, and untracked files with `--git-changes` — perfect for AI review sessions, incremental debugging, and PR workflows +- **Persistent workspace** : all generated ZIPs land in a `.contextzip/` directory at your project root, not a random temp folder — discoverable, reusable, and git-ignored automatically - **Warns before it's a problem** : flags large files (≥ 1 MB) and binary files that AI tools can't read, before you waste an upload - **Handles the messy stuff** : dangling symlinks, unreadable files, and files outside the project tree are all caught and reported, never silently dropped - **Full CLI control** : `--include`, `--exclude`, `--dry-run`, `--verbose`, `--output`, all composable @@ -69,7 +70,7 @@ That's it. contextzip will: 1. Detect your framework (e.g. `Next.js + Node.js`) 2. Apply the appropriate exclusion rules 3. Scan and summarise what will be included -4. Create a compressed ZIP in your system temp directory +4. Create a compressed ZIP in `.contextzip/` at your project root 5. Open your file manager with the ZIP selected and ready to copy --- @@ -88,7 +89,7 @@ contextzip [OPTIONS] | `include` | Subcommand: include only specific paths. `contextzip include src/ app/` | | `--git-changes` | Only include files reported by git as modified, staged, or untracked. | | `-n`, `--dry-run` | Preview what would be included, no ZIP created. | -| `-o`, `--output FILE` | Custom output path for the ZIP file. | +| `-o`, `--output FILE` | Write ZIP to a custom path. Bypasses the `.contextzip/` workspace entirely. | | `--no-clipboard` | Skip the clipboard / folder-open step. | | `--no-gitignore` | Ignore the project's `.gitignore` file. | | `-v`, `--verbose` | Show every included and excluded file with sizes. | @@ -134,7 +135,7 @@ contextzip include src/ app/ contextzip --git-changes ``` -**Save ZIP to a specific path:** +**Save ZIP to a specific path (bypasses workspace):** ```bash contextzip --output ~/Desktop/my-project-context.zip ``` @@ -151,6 +152,51 @@ contextzip --include src --exclude "**/*.test.ts" --- +## Workspace directory + +contextzip stores all generated packages in a `.contextzip/` directory at your project root, keeping your AI context artifacts persistent, discoverable, and out of the way. + +### Location + +contextzip looks for a `.git/` directory walking up from your current working directory and places `.contextzip/` alongside it — the true project root. If no git repository is found, it falls back to the current working directory. + +### Output naming + +The output filename is determined by how you invoke contextzip: + +| Command | Output | +|---|---| +| `contextzip` | `.contextzip/codebase.zip` | +| `contextzip --git-changes` | `.contextzip/changes.zip` | +| `contextzip --output PATH` | `PATH` (workspace bypassed entirely) | + +All other flags (`--include`, `--exclude`, subcommands) do not affect the filename — they refine what goes into `codebase.zip`. + +Each run overwrites the previous file of the same name, so `.contextzip/codebase.zip` is always your latest full snapshot and `.contextzip/changes.zip` is always your latest git-diff context. + +### `.gitignore` management + +contextzip automatically keeps `.contextzip/` out of version control: + +- If `.gitignore` exists → `.contextzip/` is appended if not already present +- If `.gitignore` does not exist and a `.git/` directory is found → a minimal `.gitignore` is created containing `.contextzip/` +- If no git repository is detected → `.gitignore` is left untouched + +The `.contextzip/` directory is also always excluded from packaging itself, regardless of `.gitignore` state. + +### Workspace structure + +``` +project/ +├── .contextzip/ +│ ├── codebase.zip ← latest full snapshot +│ └── changes.zip ← latest git-changes snapshot +├── src/ +└── ... +``` + +--- + ## Framework detection & auto-exclusions contextzip detects your stack from config files in the project root and stacks the appropriate rules. @@ -173,7 +219,7 @@ Detection is **additive**. A monorepo with both `package.json` and `pyproject.to ### What gets excluded **Always (every project):** -`.git/`, `.env`, `.env.*`, `*.log`, `logs/`, `.cache/`, `tmp/`, editor files (`.vscode/`, `.idea/`), OS files (`.DS_Store`, `Thumbs.db`), common binary formats (images, audio, video, archives) +`.git/`, `.env`, `.env.*`, `*.log`, `logs/`, `.cache/`, `tmp/`, `.contextzip/`, editor files (`.vscode/`, `.idea/`), OS files (`.DS_Store`, `Thumbs.db`), common binary formats (images, audio, video, archives) **Node.js / Next.js:** `node_modules/`, `.next/`, `.nuxt/`, `dist/`, `build/`, `out/`, `.turbo/`, `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`, `*.min.js`, `*.d.ts`, `tsconfig.tsbuildinfo` @@ -227,10 +273,10 @@ contextzip/ │ ├── detector.py # framework/language detection engine │ ├── filters.py # pathspec-based file filtering + ResolveResult │ ├── git.py # git status parsing + changed-file detection -│ ├── packager.py # ZIP creation, compression stats, PackageResult +│ ├── packager.py # ZIP creation, workspace management, PackageResult │ ├── clipboard.py # tiered clipboard strategy (all platforms) │ └── rules/ -│ ├── base.py # universal exclusions +│ ├── base.py # universal exclusions (includes .contextzip/) │ ├── node.py # Node.js / Next.js / Vite │ ├── python.py # Python / Django / FastAPI │ ├── rust.py # Rust / Cargo @@ -304,4 +350,4 @@ Please open an issue before submitting a large PR so we can discuss the approach ## License -MIT - see [LICENSE](https://github.com/akadeepesh/smart-context-packager/blob/main/LICENSE) for details. +MIT - see [LICENSE](https://github.com/akadeepesh/smart-context-packager/blob/main/LICENSE) for details. \ No newline at end of file