| cli | Remove REPL (not part of intended interaction model) | |
| examples | Add trace persistence to disk | |
| .gitignore | nice | |
| design.md | VV interpreter v0.1: Python syntax with tracing | |
| README.md | Remove REPL (not part of intended interaction model) | |
| runtimeedittime.md | nice | |
| values-reveal-truth.md | init | |
| vv-idea.md | init | |
| vv-manifesto.md | Add VV manifesto: LLM-first language vision | |
VV: Shell Scripts You Can Debug
VV is an orchestration language with full execution tracing.
Write automation in Python syntax. Every shell command is traced. Query any step. Never echo debug again.
# deploy.vv
status = sh("git status --porcelain")
if status.stdout:
fail("Uncommitted changes!")
version = sh("cat VERSION").stdout.strip()
sh(f"docker build -t myapp:{version} .")
sh(f"docker push myapp:{version}")
print(f"✅ Deployed {version}")
$ vv run deploy.vv
✅ Deployed 1.2.3
# Query any binding from the trace
$ vv show status
{"code": 0, "stdout": "", "stderr": "", "ok": True}
$ vv show version
"1.2.3"
$ vv trace
1: status = {code: 0, stdout: "", ...}
2: version = "1.2.3"
3: sh(docker build) = {code: 0, ...}
4: sh(docker push) = {code: 0, ...}
Why VV?
| Problem | Solution |
|---|---|
| "What did that command return?" | Every sh() call is traced |
| "Why did it fail at step 3?" | vv trace shows you |
Debugging with echo |
Query any binding with vv show |
| Scripts are opaque to LLMs | LLM can query trace to understand |
| Bash is unreadable | Python syntax, Bash power |
Features
- Python syntax - Familiar, readable, LLM-friendly
- Shell commands -
sh("command")executes and traces - Full tracing - Every binding recorded, queryable
- Single binary - No dependencies, fast startup
- Error messages - Clear context, not cryptic exits
Installation
# Clone and build
git clone https://github.com/yourusername/vv
cd vv/cli
cargo build --release
# Add to PATH
cp target/release/vv /usr/local/bin/
Examples
System Check
# check.vv
print("🔍 Running system checks...")
git = sh("which git")
if git.ok:
version = sh("git --version")
print(f"✅ Git: {version.stdout}")
else:
print("❌ Git not found")
docker = sh("which docker", False) # check=False, don't fail
if docker.ok:
print(f"✅ Docker: {docker.stdout}")
else:
print("⚠️ Docker not found (optional)")
Data Pipeline
# pipeline.vv
data = sh("curl https://api.example.com/data").stdout
cleaned = sh(f"echo '{data}' | jq .items").stdout
result = sh(f"echo '{cleaned}' | wc -l").stdout
print(f"Processed {result} items")
# Query any step:
# $ vv show data
# $ vv show cleaned
# $ vv trace
CI/CD Pipeline
# ci.vv
print("🧪 Running tests...")
tests = sh("pytest tests/")
if not tests.ok:
fail("Tests failed!")
print("🔨 Building...")
build = sh("docker build -t myapp:${GIT_SHA} .")
print("📤 Pushing...")
push = sh("docker push myapp:${GIT_SHA}")
print("🚢 Deploying...")
deploy = sh("kubectl apply -f k8s/")
print("✅ CI/CD complete!")
CLI Commands
# Run a script
vv run script.vv
# Show a binding's value (after run, in same terminal)
vv show result
# Show full trace
vv trace
# Explode a binding into subexpressions (future)
vv explode result
Language Reference
Shell Commands
# Basic usage
result = sh("ls -la")
print(result.stdout)
# Check return code
if result.ok:
print("Success!")
# Access fields
result.code # exit code (int)
result.stdout # stdout (string)
result.stderr # stderr (string)
result.ok # True if code == 0 (bool)
# Chain with string methods
version = sh("cat VERSION").stdout.strip()
# Disable automatic failure on error
result = sh("docker build .", False) # check=False
if not result.ok:
print(f"Build failed: {result.stderr}")
Failure
# Fail with a message
fail("Deployment prerequisites not met")
# Like Python's raise, but simpler
Built-in Functions
print(*args) # Print to stdout
len(x) # Length of string/list/dict
str(x) # Convert to string
int(x) # Convert to int
type(x) # Type name
range(n) # List of integers
range(a, b) # List from a to b
Control Flow
# If/else
if condition:
do_thing()
else:
do_other()
# For loops
for item in items:
print(item)
for i in range(10):
print(i)
# While loops
while condition:
do_thing()
Functions
def deploy(version):
print(f"Deploying {version}...")
sh(f"docker push myapp:{version}")
return True
result = deploy("1.2.3")
What VV Is Good For
✅ CI/CD pipelines - Build, test, deploy with full tracing
✅ DevOps automation - System checks, deployments, monitoring
✅ Data pipelines - ETL with shell tools, fully traced
✅ Build scripts - Better than Make, clearer than Bash
✅ LLM agents - Query execution state, debug easily
What VV Is NOT
❌ Web development
❌ Machine learning
❌ Application backend
❌ Real-time systems
VV is for orchestration and automation, not application logic.
Comparison
| Tool | Tracing | Syntax | Speed | Ecosystem |
|---|---|---|---|---|
| Bash | ❌ | 👎 | ⚡ | 🌟🌟🌟 |
| Python | ❌ | 👍 | 🐌 | 🌟🌟🌟 |
| Babashka | ❌ | 🤔 | ⚡ | 🌟🌟 |
| VV | ✅ | 👍 | ⚡ | 🌟 |
Roadmap
- Python syntax parser
- Shell command execution (
sh()) - Execution tracing
- Cross-terminal trace queries (
vv trace,vv show) - Trace persistence (query across runs)
- Subexpression tracing (
vv explode) - Python interop (import Python libraries)
- JSON/YAML parsing
- HTTP requests
- Environment variable helpers
Philosophy
Values reveal truth where types hide it.
VV is designed for LLM-first development. When an LLM is debugging your script, it can query vv show variable instead of adding print statements. The execution trace is the interface.
Contributing
VV is early. Ideas, issues, and PRs welcome.
License
MIT
Credits
Inspired by:
- Babashka - Fast-starting Clojure scripting
- Garden - Git-tracked execution traces
- spy - Clojure REPL inspection
Built with:
- RustPython Parser - Python syntax in Rust
- Rust - Fast, safe, single-binary