astwire
Dependency-aware context compiler and token tree-shaker for Python — traces internal import graphs via static AST analysis, skeletonizes symbols, strips token waste, and partitions output into clean LLM context bundles. Distributed as a standalone native binary compiled with Nuitka.
# latest
curl -fsSL https://install.djangoplay.org/astwire | bash
# specific version — note the -s -- before args when piping into bash
curl -fsSL https://install.djangoplay.org/astwire | bash -s -- v0.1.0Start here
The shortest path from nothing to your first result.
- 13 min readInstallationmacOS & Linux (bash):
- 27 min readCommand Referenceastwire has a single-command surface — every feature is a flag rather than a subcommand.
- 33 min readConfiguration Guideastwire works with zero configuration — every setting has a sane default and can be overridden per-run with CLI flags. .astwire.toml exists for when you want a project's defaults to be shared acros...
Browse by topic
Grouped the same way as the sidebar.
Works with
Projects that astwire declares a relationship with in project.json.
Full project README
Dependency-aware context compiler and token tree-shaker.
Python, JavaScript/TypeScript, and Go get import tracing and skeletonization. Markdown, JSON, YAML, HTML, CSS, and the rest of the 1.0 language set are packed, cleaned, and redacted as-is.
Distributed as a standalone native binary compiled via Nuitka, astwire runs locally without requiring a Python runtime or pip environment.
The Problem
Feeding entire codebases into LLMs leads to three persistent bottlenecks:
- Context Bloat: Blind dumps capture tests, build artifacts, migrations, and third-party files, overwhelming context windows.
- Token Waste: Redundant empty lines, trailing spaces, and imperative bodies consume quotas without adding reasoning value.
- Broken Dependency Clues: Supplying isolated target files forces models to guess function signatures and internal types.
What astwire Does
- Recursive Import Tracing (
-i): Follows local imports for Python, JS/TS/TSX, and Go. Never entersnode_modules, stdlib, or other-module caches. - Git-Aware Change Scoping (
--since REF): Seeds the bundle from files changed againstREF(tracked + untracked, gitignore-aware) instead of walking targets.REFis always taken as given — no base branch or remote is ever auto-detected. - Depth Control (
--max-depth,--decay-depth): With-i,--max-depthdrops files more than N import-hops from a seed;--decay-depthskeletonizes them instead of dropping them. Manifests (package.json/go.mod) are always kept regardless of depth. - Dependency Graph (
--graph): With-i, emits the import edges between bundled files as a graph block ahead of the file contents, in every output format. - Symbol Skeletonization (
--skeleton): Empties function/method bodies in supported languages. Other files pass through unchanged. - Deterministic Cleansing (
--strip-waste): Removes trailing whitespace, collapses consecutive blank lines, and normalizes line endings. - Partitioned Budgets (
--max-tokens): Chunks oversized contexts across deterministic partitions without splitting individual file boundaries. - Secret Redaction: Detects and sanitizes high-entropy keys, passwords, bearer tokens, and connection strings.
Installation
1. Quick Install (Recommended)
macOS & Linux (bash):
# latest
curl -fsSL https://install.djangoplay.org/astwire | bash
# specific version — note the -s -- before args when piping into bash
curl -fsSL https://install.djangoplay.org/astwire | bash -s -- v0.1.0Windows (PowerShell as Administrator):
# latest
irm https://install.djangoplay.org/astwire.ps1 | iex
# specific version
$env:ASTWIRE_VERSION = "v0.1.0"; irm https://install.djangoplay.org/astwire.ps1 | iex2. Build Native Binary From Source
For customized environments, build via the provided script rather than invoking Nuitka directly — it resolves the version from pyproject.toml, sets up onefile caching, and stamps the binary's version metadata for you:
git clone https://github.com/codefleetx/astwire.git
cd astwire
# Install compilation prerequisites into your virtualenv
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]" # includes nuitka
# Compile into a standalone single-file binary
make compile
./bin/astwire --versionmake compile runs scripts/install/compile.sh, which reads the current version out of pyproject.toml, generates src/_version.py so it's baked into the binary (so astwire --version always matches the package version), and invokes Nuitka with --standalone --onefile --prefer-source-code. The resulting binary is written to bin/astwire.
Supported Platforms & Asset Coverage
| Binary File | Target OS / Environment | Target Architecture |
|---|---|---|
astwire-darwin-arm64 |
macOS (Apple Silicon: M1, M2, M3, M4) | ARM 64-bit (arm64) |
astwire-linux-amd64 |
Linux (Ubuntu, Debian, RedHat, standard cloud VMs) | Intel/AMD 64-bit (x86_64) |
astwire-linux-arm64 |
Linux (AWS Graviton, Raspberry Pi, Apple Silicon Docker) | ARM 64-bit (aarch64/arm64) |
astwire-windows-amd64.exe |
Windows 10, 11, Server | 64-bit (x86_64) |
Quickstart
List what 1.0 can pack and which languages support -i / --skeleton:
astwire --languagesDefault output is LLM-native XML (context.xml), not Markdown. Paths can be positional or --targets.
astwire --skeleton --targets ../djangoplay-site/
# same as:
astwire --skeleton ../djangoplay-site/Python
astwire src/cli.py -i --skeleton
astwire src/ --skeleton -o skeleton.md # human-readable; .md selects markdownNode / TypeScript
Relative ./ imports only. Bare specifiers (react) and node_modules are ignored. Nearest package.json is attached when -i is on.
astwire src/index.ts -i --skeleton
astwire src/ --lang ts,tsx,js -o frontend.mdGo
Follows in-module import paths using go.mod. Stdlib and other modules are ignored. Nearest go.mod is attached when -i is on.
astwire ./cmd/server -i --skeletonMixed repo
astwire src/ --skeleton --strip-wastePython/JS/Go files are skeletonized; Markdown/JSON/YAML stay full text.
3. Strip Token Waste Across Modules
Sanitize trailing whitespace and collapse consecutive empty lines across your codebase:
astwire src/ -i --strip-waste4. Audit Waste Without Writing (--analysis)
Run an in-terminal dry run displaying exact token counts, waste lines, waste bytes, and recoverable ratios:
astwire src/ -i --analysisExample audit output:
📊 Token Analysis Report
File Path (Relative) Tokens Wasted Waste Lines Waste Bytes Recoverable %
─────────────────────────────────────────────────────────────────────────────────────────────
src/cli.py 1,568 13 16 121 0.83%
src/config.py 556 1 2 4 0.18%
src/core/ast_crawler.py 1,538 1 1 4 0.07%
src/core/skeleton.py 490 0 0 0 0.00%
─────────────────────────────────────────────────────────────────────────────────────────────
Overall 4,152 15 19 129 0.36%
Combined with -i, the table gains a Depth column (import-hops from the nearest seed; - for seeds themselves or when -i isn't used).
5. Bundle Only What Changed (--since)
Seed from a git diff instead of the given targets. Accepts at most one scope path, and REF is never resolved or guessed — pass exactly what you mean (main, HEAD~3, a commit SHA):
astwire src/ --since main -i --skeletonWithout -i this just bundles the changed files themselves; without an accompanying --decay-depth, -i pulls in their full-text imports at depth 0 decay (--since implies --decay-depth 0 when -i is on and --decay-depth isn't set explicitly).
6. Limit or Decay by Import Depth (--max-depth, --decay-depth)
Both require -i and are no-ops (with a stderr note) otherwise:
# Drop anything more than 2 import-hops from a seed
astwire src/ -i --max-depth 2
# Keep everything, but skeletonize anything more than 1 hop away
astwire src/ -i --decay-depth 1Manifests (package.json, go.mod) are exempt from both — they're always attached in full.
7. Emit a Dependency Graph (--graph)
Requires -i; renders the actual import edges between bundled files ahead of the file contents, in whichever output format you chose:
astwire src/ -i --graph -o context.mdOutput Formats
Default is LLM-native XML — the format models consume well, with less token overhead than Markdown trees and fences. -o extension selects a format if -f is omitted: .xml/.llm → llm, .md → markdown, .json → json.
LLM-Optimized XML (-f llm, default)
Compact <context> / <file path language> tags. This is what you want to paste or pipe into a model:
astwire src/ --skeleton
# writes context.xml<context skeleton="true">
<files>
src/config.py
</files>
<!-- Function/method bodies omitted; '...' is not the implementation. -->
<file path="src/config.py" language="python" skeleton="true">
# Module contents
</file>
</context>With -i --graph, a <graph> block of <edge from="..." to=".../> tags is emitted before <files>.
Markdown (-f markdown)
ASCII directory tree and language-tagged fences — for humans inspecting a bundle:
astwire src/ -o context.mdWith -i --graph, a ## Dependency Graph section (one bullet per file, listing its outgoing imports) is emitted before ## Files.
JSON (-f json)
Structured schema for tools that want to parse the bundle:
astwire src/ -f json -o context.jsonWith -i --graph, each partition's payload includes a top-level "graph": [{"from": ..., "to": ...}, ...] array; it's [] without --graph. In every format, a multi-part run (--max-tokens) only ever renders edges whose both endpoints landed in that same partition.
Configuration (.astwire.toml)
astwire discovers configuration files placed in the project root (.astwire.toml):
[general]
format = "llm"
output = "context.xml"
strip_waste = true
show_tree = true
[targeting]
languages = ["python", "javascript", "go"]
skip = [
"tests/",
"migrations/",
"docs/",
]CLI --lang overrides targeting.languages. Default skip already includes node_modules/, vendor/, dist/, target/, .venv/, and lockfiles.
Uninstallation & Upgrade Guide
Uninstallation
CLI Uninstall
# Remove astwire completely along with local configuration files (if any)
astwire --uninstallManual Uninstall
Because astwire is distributed as a self-contained, standalone single-file binary, uninstallation requires removing the installed binary and any user configuration or cache files.
- macOS & Linux:
# Remove the global binary
sudo rm -f /usr/local/bin/astwire
# Remove local configuration files (if created)
rm -f ~/.astwire.toml .astwire.toml .astwireignore- Windows (PowerShell):
# Remove installation directory
Remove-Item -Recurse -Force "$env:LOCALAPPDATA\Programs\astwire"
# Clean up user PATH environment variable
$UserPath = [Environment]::GetEnvironmentVariable("Path", [EnvironmentVariableTarget]::User)
$CleanPath = ($UserPath -split ";" | Where-Object { $_ -ne "$env:LOCALAPPDATA\Programs\astwire" }) -join ";"
[Environment]::SetEnvironmentVariable("Path", $CleanPath, [EnvironmentVariableTarget]::User)Upgrading astwire
- How upgrades work right now:
- Re-running the original install command cleanly overwrites the existing binary:
- macOS & Linux:
curl -fsSL https://install.djangoplay.org/astwire | bashmoves the latest binary directly over/usr/local/bin/astwireviamv. - Windows:
irm https://install.djangoplay.org/astwire.ps1 | iexoverwritesastwire.exein$env:LOCALAPPDATA\Programs\astwireviaInvoke-WebRequest. - Users do not need to uninstall before upgrading; the old binary is replaced atomically in-place.
CLI Reference
usage: astwire [-h] [-i] [--languages] [--lang NAME[,NAME]] [--targets PATH]
[--since REF] [--max-depth N] [--decay-depth N] [--graph]
[--analysis] [--strip-waste] [--skeleton]
[--max-tokens N] [-f {markdown,llm,json}]
[-o OUTPUT] [-v] [--uninstall] [targets ...]
--targets PATH Same as positional paths
-i, --resolve-imports Follow local imports (Python, JS/TS, Go)
--since REF Seed from files changed since REF (git, gitignore-aware) instead
of targets. One scope path max. REF is never auto-detected.
--max-depth N Only with -i: drop files more than N import-hops from a seed.
Manifests are always kept. No effect without -i.
--decay-depth N Only with -i: skeletonize (don't drop) files more than N
import-hops from a seed. No effect without -i.
--graph Only with -i: emit a dependency-graph block before file contents.
No-op with a stderr note without -i.
--languages Print the capability table and exit
--lang NAME[,NAME] Only these languages (names or extensions)
--skeleton Strip bodies where supported; other files pass through
-f llm|markdown|json Default llm. .md / .json / .xml on -o also select format
-v, --version Print the installed astwire version and exit
--uninstall Remove the astwire binary and local config filesSecurity & Privacy
- Local Execution: astwire never uploads source and never executes the files it reads. Python uses the stdlib
astmodule; JS/TS and Go use conservative static scanners. - Secret Redaction: Automated pattern matching masks private keys, bearer headers, tokens, and database passwords before bundling.
- Gitignore Compliant: Honors
.gitignoreexclusion hierarchies automatically.
License
astwire software licensed under proprietary License.