Skip to main content

Micro-agent runner for task automation using markdown definitions

Project description

tsugite

Tsugite (Japanese: 継ぎ手, the art of joinery in woodworking) is a developer-facing agentic CLI.

Define AI agents as markdown files with YAML frontmatter. Chain multiple steps together, pass data between them, and use any LLM (OpenAI, Anthropic, Ollama, etc).

Installation

# Recommended: Install with uv
uv tool install tsugite-cli

# Alternative: Install with pipx
pipx install tsugite-cli

# Or with pip
pip install tsugite-cli

Note: The package name is tsugite-cli, but the command is tsugite (or tsu for short).

Quick Start

# Run an agent
tsugite run examples/simple_variable_injection.md "test it"

# Create your own agent
cat > my_agent.md << 'EOF'
---
name: hello
model: openai:gpt-4o-mini
---

Task: {{ user_prompt }}

Just say hello and use final_answer() to return your greeting.
EOF

tsugite run my_agent.md "greet the user"

Features

  • Multi-step workflows - Chain steps with <!-- tsu:step -->, pass data between them
  • Variable injection - Step outputs automatically available as Python variables
  • Multiple LLM providers - OpenAI, Anthropic, Ollama, Google, GitHub Copilot
  • MCP integration - Connect to Model Context Protocol servers
  • Temperature control - Set per-step model parameters
  • Copy-paste friendly output - --plain flag or auto-detection for pipe/redirect

CLI Options

# Plain output (no box-drawing characters, copy-paste friendly)
tsugite run +assistant "task" --plain

# Auto-detection: plain mode activates when piped or NO_COLOR is set
tsugite run +assistant "task" | grep result

# Headless mode for scripts (result to stdout, progress to stderr)
tsugite run +assistant "task" --headless

# Continue latest conversation (auto-detects agent)
tsugite run --continue "follow-up prompt"

# Continue specific conversation
tsugite run --continue --conversation-id CONV_ID "follow-up prompt"
tsugite chat --continue CONV_ID

# View conversation history
tsugite history list
tsugite history show CONV_ID

Sandbox

Agent code can run inside a bubblewrap sandbox with filesystem and network isolation.

# Sandbox with specific domains allowed
tsu run +default "task" --sandbox --allow-domain "github.com" --allow-domain "*.openai.com"

# Full network isolation
tsu run +default "task" --sandbox --no-network

How it works:

CLI --sandbox --allow-domain "*.github.com"
 └─ SubprocessExecutor writes harness script
     └─ bwrap --unshare-pid --unshare-net --die-with-parent ...
         └─ TCP↔UDS bridge (HTTP_PROXY → Unix socket)
             └─ ConnectProxy filters CONNECT requests by domain:port

Default mounts:

  • Read-only: /usr, /lib, /lib64, /bin, /sbin, /etc/ssl, /etc/resolv.conf, CA certs, Python venv + sys.path
  • Read-write: workspace directory, internal state directory
  • Tmpfs: /tmp (fresh each run)

Extra bind mounts can be added programmatically via SandboxConfig.extra_ro_binds and extra_rw_binds, but these are not yet exposed through CLI flags or agent frontmatter.

Network:

  • Network is namespace-isolated; outbound HTTP/HTTPS goes through a filtering CONNECT proxy
  • Direct connections to bare IP addresses are always blocked
  • --no-network skips the proxy entirely — no connectivity at all

--allow-domain syntax:

Pattern Allows
github.com ports 80, 443
github.com:22 port 22 only
*.github.com:8080 port 8080 on subdomains
*:* all domains, all ports

Hooks

Hooks fire shell commands at lifecycle points. Configure in .tsugite/hooks.yaml:

hooks:
  post_tool:
    - tools: [write_file]
      run: git add {{ path }}
      wait: true

  pre_message:
    - run: uridx search "{{ message }}" --limit 5
      capture_as: rag_context
    - run: cat memory/preferences.md
      capture_as: user_preferences

  pre_compact:
    - run: ./scripts/extract-facts.sh {{ turns_file }}
      wait: true

  post_compact:
    - run: echo "Compacted {{ turns_compacted }} turns"

Hook fields: run (Jinja2 shell command), tools (tool filter, post_tool only), match (Jinja2 condition), wait (block until done), capture_as (capture stdout into a template variable, implies wait).

Hook types:

  • post_tool — After successful tool calls. Context: tool, plus tool arguments.
  • pre_message — Before agent execution. Context: message, user_id, agent_name. Use capture_as to inject results into agent templates as {{ var_name }}.
  • pre_compact / post_compact — Around session compaction. Context: conversation_id, user_id, agent_name, turns_file, turn_count.

Development

# Clone and install for development
git clone https://github.com/justyns/tsugite.git
cd tsugite
uv sync --dev

See examples/ for working agents and CLAUDE.md for AI-generated documentation.

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

tsugite_cli-0.9.4.tar.gz (798.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tsugite_cli-0.9.4-py3-none-any.whl (488.2 kB view details)

Uploaded Python 3

File details

Details for the file tsugite_cli-0.9.4.tar.gz.

File metadata

  • Download URL: tsugite_cli-0.9.4.tar.gz
  • Upload date:
  • Size: 798.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for tsugite_cli-0.9.4.tar.gz
Algorithm Hash digest
SHA256 b043075f3947b357ed3b6f9cf77f6a338603f1b21761e17e9176ff4d1abfc87d
MD5 6fa4e0a77b5bf55a64c9126e1b9bdfe9
BLAKE2b-256 8935538be566497ae37ff4f6e29ddd2ca474b0e453fbce69ffb26fbba2cac020

See more details on using hashes here.

Provenance

The following attestation bundles were made for tsugite_cli-0.9.4.tar.gz:

Publisher: pypi-publish.yml on justyns/tsugite

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tsugite_cli-0.9.4-py3-none-any.whl.

File metadata

  • Download URL: tsugite_cli-0.9.4-py3-none-any.whl
  • Upload date:
  • Size: 488.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for tsugite_cli-0.9.4-py3-none-any.whl
Algorithm Hash digest
SHA256 d8c22d0679a17af78f6aa6209f0b9dd7c86b6ae6fd68f4803b84e3331d5d46f8
MD5 412ed90e58e8741bbc893871d2e041af
BLAKE2b-256 c720528b14f968b4ea456626afa6eb7751ee5c45b154d9b310adc083638dad5b

See more details on using hashes here.

Provenance

The following attestation bundles were made for tsugite_cli-0.9.4-py3-none-any.whl:

Publisher: pypi-publish.yml on justyns/tsugite

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page