astwire
Docsastwire

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 v1.0.0Updated Oct 1, 202621 pages
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.0

Start here

The shortest path from nothing to your first result.

  1. 13 min readInstallationmacOS & Linux (bash):
  2. 27 min readCommand Referenceastwire has a single-command surface — every feature is a flag rather than a subcommand.
  3. 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.

Release License: MIT Platform Architecture Python Version Zero Dependencies


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:

  1. Context Bloat: Blind dumps capture tests, build artifacts, migrations, and third-party files, overwhelming context windows.
  2. Token Waste: Redundant empty lines, trailing spaces, and imperative bodies consume quotas without adding reasoning value.
  3. 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 enters node_modules, stdlib, or other-module caches.
  • Git-Aware Change Scoping (--since REF): Seeds the bundle from files changed against REF (tracked + untracked, gitignore-aware) instead of walking targets. REF is always taken as given — no base branch or remote is ever auto-detected.
  • Depth Control (--max-depth, --decay-depth): With -i, --max-depth drops files more than N import-hops from a seed; --decay-depth skeletonizes 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

macOS & Linux (bash):

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.0

Windows (PowerShell as Administrator):

powershell
# latest
irm https://install.djangoplay.org/astwire.ps1 | iex

# specific version
$env:ASTWIRE_VERSION = "v0.1.0"; irm https://install.djangoplay.org/astwire.ps1 | iex

2. 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:

bash
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 --version

make 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:

bash
astwire --languages

Default output is LLM-native XML (context.xml), not Markdown. Paths can be positional or --targets.

bash
astwire --skeleton --targets ../djangoplay-site/
# same as:
astwire --skeleton ../djangoplay-site/

Python

bash
astwire src/cli.py -i --skeleton
astwire src/ --skeleton -o skeleton.md    # human-readable; .md selects markdown

Node / TypeScript

Relative ./ imports only. Bare specifiers (react) and node_modules are ignored. Nearest package.json is attached when -i is on.

bash
astwire src/index.ts -i --skeleton
astwire src/ --lang ts,tsx,js -o frontend.md

Go

Follows in-module import paths using go.mod. Stdlib and other modules are ignored. Nearest go.mod is attached when -i is on.

bash
astwire ./cmd/server -i --skeleton

Mixed repo

bash
astwire src/ --skeleton --strip-waste

Python/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:

bash
astwire src/ -i --strip-waste

4. Audit Waste Without Writing (--analysis)

Run an in-terminal dry run displaying exact token counts, waste lines, waste bytes, and recoverable ratios:

bash
astwire src/ -i --analysis

Example audit output:

text
📊 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):

bash
astwire src/ --since main -i --skeleton

Without -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:

bash
# 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 1

Manifests (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:

bash
astwire src/ -i --graph -o context.md

Output 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:

bash
astwire src/ --skeleton
# writes context.xml
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:

bash
astwire src/ -o context.md

With -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:

bash
astwire src/ -f json -o context.json

With -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):

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

bash
# Remove astwire completely along with local configuration files (if any)
astwire --uninstall

Manual 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:
bash
# 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):
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 | bash moves the latest binary directly over /usr/local/bin/astwire via mv.
  • Windows: irm https://install.djangoplay.org/astwire.ps1 | iex overwrites astwire.exe in $env:LOCALAPPDATA\Programs\astwire via Invoke-WebRequest.
  • Users do not need to uninstall before upgrading; the old binary is replaced atomically in-place.

CLI Reference

text
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 files

Security & Privacy

  • Local Execution: astwire never uploads source and never executes the files it reads. Python uses the stdlib ast module; 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 .gitignore exclusion hierarchies automatically.

License

astwire software licensed under proprietary License.