RepoPack
Pack/unpack any source workspace regardless of technology stack (Python, Node.js, React, Angular, Vue, Rust, Go, Java, C#, and more) into a portable, structured JSON payload — and restore it faithfully from that payload.
Features
- Universal ignore engine — respects root and nested
.gitignorefiles plus stack-agnostic defaults (node_modules, pycache, .venv, target/, dist/, secrets, lock files, …) - Polyglot stack detection — auto-detects Node.js, React, TypeScript, Angular, Next.js, Vue, Python, Rust, Go, Java, C# from project sentinel files
- Binary safety — text files encoded as UTF-8; binaries skipped by default or included as Base64 with
--include-binary - 5 MB guard — files larger than 5 MB are skipped with a warning
- Dry-run mode — preview exactly which files would be packed or unpacked before committing with
--dry-run - Path traversal shield —
unpackvalidates every path against the destination root before writing anything; blocks../, absolute paths, and injection attempts (CWE-22) - Secure PyPI version check — uses
http.client.HTTPSConnection(noturlopen) to enforce HTTPS at the type level - MCP server — expose pack/unpack as tools to any MCP-compatible AI client (Claude Desktop, etc.)
- Automated security auditing — weekly
pip-audit+banditCI scans on all dependencies
Installation
From PyPI (recommended)
pip install RepoPackPy
Requires Python 3.10+.
Quick start after install
# Verify the install
repopack --version
repopack --help
# Pack your project
repopack pack . -o my-workspace.json
# Preview what would be packed (no output written)
repopack pack . --dry-run
# Restore it somewhere else
repopack unpack my-workspace.json -t ./restored
# Preview what would be unpacked (nothing written)
repopack unpack my-workspace.json -t ./restored --dry-run
For development
git clone https://github.com/ShanKonduru/RepoPack.git
cd RepoPack
pip install ".[dev]"
Note: Install without
-e(editable) sopip-auditcan audit the package metadata correctly.
CLI Usage
repopack pack [DIRECTORY] [-o output.json] [--include-binary] [--custom-ignore ".next,dist"] [--dry-run]
repopack unpack <input.json> [-t TARGET_DIR] [--force] [--dry-run]
repopack validate <input.json> [DIRECTORY]
repopack fix <input.json> [DIRECTORY] [--include-binary]
repopack serve
Options
| Command | Flag | Description |
|---|---|---|
pack |
-o / --output |
Write packed JSON to this file (prints to stdout if omitted) |
pack |
--include-binary |
Include binary files encoded as Base64 |
pack |
--custom-ignore |
Comma-separated extra ignore patterns |
pack |
--dry-run |
List files that would be packed — encoding, size, path — without writing anything |
unpack |
-t / --target |
Destination directory (default: current directory) |
unpack |
--force |
Overwrite existing files |
unpack |
--dry-run |
List files that would be extracted or skipped without writing anything |
validate |
(none) | Compare JSON against the live workspace; exit 1 if outdated |
fix |
--include-binary |
Re-pack workspace into the JSON file, adding/removing/refreshing as needed |
Examples
# Pack current directory
repopack pack . -o workspace.json
# Dry-run: see what would be packed
repopack pack . --dry-run
# Pack a specific project, include binaries
repopack pack ~/projects/my-app -o my-app.json --include-binary
# Unpack into a new directory
repopack unpack workspace.json -t ./restored
# Dry-run: see what would be unpacked (and what would be skipped)
repopack unpack workspace.json -t ./restored --dry-run
# Unpack and overwrite existing files
repopack unpack workspace.json -t ./restored --force
# Validate: check if workspace.json is complete and up to date
repopack validate workspace.json .
# Fix: update workspace.json with all latest files and folders
repopack fix workspace.json .
Sample --dry-run output
# pack --dry-run
Dry run — would pack 42 files (186320 bytes)
Root : /home/user/my-app
Stack : Node.js, React, TypeScript
utf-8 1024 src/App.tsx
utf-8 512 src/index.tsx
base64 8192 public/favicon.ico
...
# unpack --dry-run
Dry run — destination: /home/user/restored
Would extract : 40
Would skip : 2
create src/App.tsx
create src/index.tsx
skip (exists) README.md
...
Sample validate output
Status : OUTDATED
JSON : workspace.json
Workspace: /home/user/my-app
Missing from JSON : 2
Extra in JSON : 1
Stale in JSON : 3
Up to date : 36
Missing (in workspace, not in JSON):
+ src/NewComponent.tsx
+ src/utils/helper.ts
Extra (in JSON, not in workspace):
- src/OldComponent.tsx
Stale (content changed since packing):
~ README.md
~ src/App.tsx
~ package.json
Sample fix output
Updated : workspace.json
Workspace: /home/user/my-app
Added : 2 files
Removed : 1 files
Refreshed: 3 files
Total : 42 files (189440 bytes)
JSON Payload Schema
{
"version": "1.0",
"metadata": {
"created_at": "2026-07-26T12:00:00Z",
"root_directory_name": "my-app",
"detected_stack": ["Node.js", "React", "TypeScript"],
"total_files": 38,
"total_bytes": 128450
},
"files": [
{ "path": "src/App.tsx", "encoding": "utf-8", "content": "..." },
{ "path": "public/favicon.ico", "encoding": "base64", "content": "..." }
]
}
MCP Server Tools
When running repopack serve, two tools are registered via FastMCP:
| Tool | Parameters | Description |
|---|---|---|
export_workspace |
workspace_path, output_json_path, include_binary, dry_run |
Pack a directory into JSON |
import_workspace |
json_input, destination_path, overwrite, dry_run |
Unpack JSON into a directory |
validate_workspace_tool |
json_path, workspace_path |
Report missing, extra, and stale files vs the live workspace |
fix_workspace_tool |
json_path, workspace_path, include_binary |
Re-pack and overwrite the JSON with all latest files and folders |
Set dry_run=true on export_workspace or import_workspace to get a plain-text report without reading file content or writing to disk.
Security
Path traversal protection
Every path in an incoming JSON payload is validated before the filesystem is touched:
- Absolute paths are rejected.
- Any path component equal to
..is rejected. - The resolved output path is checked with
os.path.commonpathto confirm it stays inside the destination root.
This blocks directory traversal attacks (CWE-22) regardless of how the JSON was produced.
PyPI version check
The --version flag checks for newer releases on PyPI using http.client.HTTPSConnection directly, which enforces HTTPS at the type level and is not susceptible to file:// or custom-scheme abuse (bandit B310 / CWE-22).
CI security scanning
Every push and weekly schedule runs:
pip-audit --strict— checks all third-party dependencies against known CVE databases.bandit -r repopack/ -ll -ii— static analysis for common Python security issues.
Project Structure
repopack/
├── pyproject.toml
├── README.md
└── repopack/
├── __init__.py
├── cli.py # Typer CLI (pack / unpack / serve)
├── mcp_server.py # FastMCP server
├── packer.py # Directory walker & JSON builder
├── unpacker.py # JSON extractor & path-safe reconstructor
└── utils.py # Ignore engine, binary detector, stack detection
tests/
└── test_repopack.py
Running Tests
pytest tests/ -v
Dependencies
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file repopackpy-0.2.0.tar.gz.
File metadata
- Download URL: repopackpy-0.2.0.tar.gz
- Upload date:
- Size: 18.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
713dc060ef51f7af8ef8aad4ed07e4c0c761edbb2bb5273a4133035e0a573565
|
|
| MD5 |
1cc9f8379124427df2a1d20cea5393a3
|
|
| BLAKE2b-256 |
4100ca6f655e9f8eaadcf95012552d8a7852222859d6941cc0e8afb8475f9909
|
Provenance
The following attestation bundles were made for repopackpy-0.2.0.tar.gz:
Publisher:
publish.yml on ShanKonduru/RepoPack
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
repopackpy-0.2.0.tar.gz -
Subject digest:
713dc060ef51f7af8ef8aad4ed07e4c0c761edbb2bb5273a4133035e0a573565 - Sigstore transparency entry: 2256135890
- Sigstore integration time:
-
Permalink:
ShanKonduru/RepoPack@6eb5bfb29d7d1aa2800cc2bcf96278cdd994deec -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/ShanKonduru
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6eb5bfb29d7d1aa2800cc2bcf96278cdd994deec -
Trigger Event:
push
-
Statement type:
File details
Details for the file repopackpy-0.2.0-py3-none-any.whl.
File metadata
- Download URL: repopackpy-0.2.0-py3-none-any.whl
- Upload date:
- Size: 13.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5d740dfbf68cc719caacc7da103fa54ad7afc4678ab0a281021d57a4e9572ea7
|
|
| MD5 |
9c318a8193a867d4730f1be262847421
|
|
| BLAKE2b-256 |
7925a3b28ab4e8602b532521a54fe17d4f547059019c6f0fa41403c5a01daa36
|
Provenance
The following attestation bundles were made for repopackpy-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on ShanKonduru/RepoPack
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
repopackpy-0.2.0-py3-none-any.whl -
Subject digest:
5d740dfbf68cc719caacc7da103fa54ad7afc4678ab0a281021d57a4e9572ea7 - Sigstore transparency entry: 2256135901
- Sigstore integration time:
-
Permalink:
ShanKonduru/RepoPack@6eb5bfb29d7d1aa2800cc2bcf96278cdd994deec -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/ShanKonduru
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6eb5bfb29d7d1aa2800cc2bcf96278cdd994deec -
Trigger Event:
push
-
Statement type: