Serialize a repository into XML-like workspace context for LLM input
Project description
simple-workspace-contextualizer
A small CLI for serializing a source repository into a structured, LLM-friendly context format.
It prints:
- a filtered file tree for the workspace
- the full contents of selected files
- stable XML-like wrapper tags so the output can be pasted directly into an LLM prompt
The intended use case is: "take a repo and turn it into a single prompt payload that gives an LLM useful project context."
Why this exists
LLMs usually perform better when they can see:
- the repository structure
- the important source files
- toolchain and config files
- README / markdown documentation
- the exact source text, without reformatting or lossy transformations
This tool packages that information into one stream.
Features
- Recursively prints a workspace file tree
- Includes common source files by default
- Includes common toolchain / config files by default
- Supports additional user-supplied glob patterns
- Supports
--overrideto disable the built-in file selection globs - Supports
--ignore GLOBto add extra ignore globs, one per flag occurrence - Hides ignored paths from the file tree
- Allows user-supplied globs to explicitly include ignored files in the emitted file contents
- Produces a simple structured output format that is easy to paste into an LLM
Installation
From PyPI
pip install simple-workspace-contextualizer
Local development
git clone <your-repo-url>
cd simple-workspace-contextualizer
python -m pip install -e .
This installs the CLI command:
swc
If you expose an additional alias, document it here too:
simple_workspace_contextualizer
Requirements
- Python 3.13+
Usage
swc ROOT [--override] [--ignore GLOB]... [GLOB ...]
Arguments
ROOT
Root project directory to scan.
--override
Disable the built-in default include globs.
When --override is present, only the user-supplied globs are used for <file_contents>.
--ignore GLOB
Add one extra ignore glob pattern.
This option may be provided multiple times. Each --ignore consumes exactly one glob. Ignore globs affect:
- the emitted
<file_tree> - files selected by the built-in default include globs
User-supplied positional include globs still override ignore rules for <file_contents>.
Examples:
swc . --ignore ".venv/**"
swc . --ignore ".venv/**" --ignore "dist/**"
swc . --ignore ".env" "**/*.custom"
In the last example, .env is ignored and **/*.custom is treated as a positional include glob, not another ignore glob.
GLOB ...
Zero or more additional file glob patterns to include in <file_contents>.
These user globs are additive by default, and they can explicitly include files that would otherwise be ignored.
Examples
Serialize a repo with the default built-in file patterns:
swc .
Add a few extra file patterns:
swc . "docs/**/*.txt" "proto/**/*.proto"
Only include files matching your own globs:
swc . --override "src/**/*.py" "tests/**/*.py"
Add extra ignore rules on top of the built-in ignore list:
swc . --ignore ".venv/**" --ignore "dist/**"
Combine extra ignore rules with explicit include globs:
swc . --ignore "**/*.min.js" "**/*.map" "src/**/*.ts"
Explicitly include something under an otherwise ignored path:
swc . ".venv/lib/python3.13/site-packages/pip-25.3.dist-info/LICENSE.txt"
Output format
The tool emits XML-like structured text:
<workspace_context>
<file_tree>
...
</file_tree>
<file_contents>
<file path="src/example.py">
...
</file>
<file path="pyproject.toml">
...
</file>
</file_contents>
</workspace_context>
Semantics
<file_tree>contains the filtered directory tree<file_contents>contains the full contents of selected files- each
<file>element has apathattribute relative to the workspace root
File selection model
The set of files included in <file_contents> is:
- the built-in default glob set
- plus any user-supplied globs
If --override is used, the built-in default glob set becomes empty.
So the effective rule is:
- default mode:
default globs ∪ user globs - override mode:
user globs
Ignore behavior
Ignored paths are hidden from the file tree and excluded from files selected by the built-in default glob set.
You can also add extra ignore rules with --ignore.
However, user-supplied positional include globs are allowed to explicitly include ignored files.
That means:
- ignored paths do not appear in
<file_tree> - ignored files do not get included by default
--ignoreadds more ignore rules on top of the built-in ignore list- ignored files can still appear in
<file_contents>if the user explicitly requests them with a positional glob
This is intentional: it keeps the default output clean while still allowing targeted overrides.
Default included files
The built-in include globs are aimed at "files that are useful to show an LLM."
They include:
- source files such as Python, JavaScript, TypeScript, Go, Rust, Java, C/C++, shell, SQL, and others
- markdown files
- common toolchain and config files such as:
MakefileDockerfilepyproject.tomlrequirements.txtpackage.jsontsconfig.jsongo.modCargo.tomlpom.xml- Gradle files
- common lint / formatter config files
Typical ignored paths
The ignore list is intended to filter out noisy or generated content such as:
- VCS metadata
- editor / IDE folders
- caches
- virtual environments
node_modules- build outputs
- coverage artifacts
- generated packaging metadata
Examples include:
.git/.venv/node_modules/dist/build/__pycache__/*.egg-info/*.dist-info/
You can add more patterns at runtime with repeated --ignore GLOB flags.
Example workflow with an LLM
Generate workspace context:
swc . > workspace_context.xml
Then paste that output into your LLM prompt along with a task, for example:
Here is the current repository context. Please explain the architecture, identify likely entry points, and suggest how to add feature X.
Design goals
- Minimal dependencies
- Easy to inspect
- Easy to pipe to stdout
- Easy to compose with shell tooling
- Optimized for LLM context generation rather than archival fidelity
Non-goals
- Full XML document modeling
- Perfect reproduction of every file in a repository
- Preserving large binary assets
- Replacing dedicated indexing or retrieval systems
Limitations
- Large repositories can produce very large outputs
- The default globs are heuristic, not exhaustive
- Ignored paths are policy-driven and may need adjustment for your codebase
- Prompt quality still depends on what files are included
Development
Run locally:
python -m simple_workspace_contextualizer.cli .
Or, if installed in editable mode:
swc .
Project details
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 simple_workspace_contextualizer-0.1.2.tar.gz.
File metadata
- Download URL: simple_workspace_contextualizer-0.1.2.tar.gz
- Upload date:
- Size: 7.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fd7ab2edf3d1743b5f043f016bfd229d642d94f758b1bbe3ec92e3023aad01ff
|
|
| MD5 |
442bd8897226b27ac8b69cd4580d4bdd
|
|
| BLAKE2b-256 |
a2dc826977708eca16e70e724993c98af66f142ab67a242a73d94e34912d7c74
|
File details
Details for the file simple_workspace_contextualizer-0.1.2-py3-none-any.whl.
File metadata
- Download URL: simple_workspace_contextualizer-0.1.2-py3-none-any.whl
- Upload date:
- Size: 8.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4a42cfe65c99e266c447ff24abc03621fbe15135abd72ddff39e36097da6b0a7
|
|
| MD5 |
85d5ec7fec270228b66b5c9d0d0c5c9f
|
|
| BLAKE2b-256 |
59c9ad39823b739a755fc1989b74f401c6487b8b474dda9edbc8873d25316aed
|