tmux-based agent + shell "harness" and tools for monitoring and controlling agents.
- Idea is to spawn a tmux session per agent session, with starting off two panels:
- One for the agent TUI (such as OpenCode or Codex)
- One for a shell, which the agent can use to run commands and scripts. The shell panel will be the "main" panel that the agent interacts with, and the TUI panel will be for visualizing the agent's thought process and actions.
- Agent can spawn more shells if needed
- Additional: we can use a oh-my-opencode like plugin to let the agent spawn background agents as opencode panels and such to extend this concept
- This allows the user to easy tab into sessions and manage them
- Allows the agent to (optionall but recommended to) to use tmux buffer / send-keys to interace with the shell vs normal command running or pty.
- The agent can use an MCP or call the CLI directly (knowing its tmux session info) to control tmux or read/write to the shell in place of its existing tools.
- Host CLI will be in charge of tracking (sqlite?) session info, and providing a CLI for users to manage sessions, view logs, etc. It will also be responsible for spawning tmux sessions and panels as needed.
- Host CLI will have basic abstractions for different agent tools. Mostly involves just defining metadata / command to invoke and what to pass prompt info in the args
tvcli- the main CLI for managing sessions, spawning agents, etc.tmux- for session and panel managementrust+clapfor CLI- If we need local session storage, use
sqlitewithrusqlitecrate and some ODM abstraction (what ever is easiest to work with, maybesea-ormordiesel) - Exposed REST and MCP APIs for agent interaction and control, using
warporaxumfor the server implementation thiserror/anyhowfor error handling in Rustlog+tracing+tracing-subscriberfor logging in Rust
- Root command:
tinyverse - In this repo, run commands via:
cargo run -p tinyverse_cli -- <command> - Running
tinyversewith no subcommand launchestinyverse tui. - Global override for tinyverse home path:
--tinyverse-dir-home <path>TINYVERSE_DIR_HOME=<path>
- Tinyverse path resolution order:
--tinyverse-dir-homeTINYVERSE_DIR_HOME- repo-local
<repo_root>/.tinyversewhen running in this repo - cwd-local
.tinyverseif present ~/.tinyverse
- Active config file:
<tinyverse_home>/config.toml - Legacy fallback file (read-only fallback):
<tinyverse_home>/tinyverse.toml - When active home is not
~/.tinyverse, config loading merges in this order:~/.tinyverse/config.toml(or legacy~/.tinyverse/tinyverse.toml)- active home config (
<tinyverse_home>/config.toml, legacy fallback if needed)
tinyverse config exportwrites the effective config to disk (defaults toactive_path) and prints metadata comments (selected_source,active_path,written_to,loaded_from) so you can verify exactly which file(s) were used.- TUI theme file:
theme.toml- Loaded from
~/.tinyverse/theme.tomlfirst, then cwd./theme.toml(cwd overrides matching keys). - Supports Dark-Factory style palette keys such as
pill_ok_fg,pill_ok_bg,pane_focused_border,text_secondary, andselected_card_bg.
- Loaded from
- Preferred Rust test runner:
cargo nextest run - Fallback when
cargo-nextestis unavailable or fails in this environment:cargo test
- Tracing logs write to both stdout and a file.
- Log files are created under
<tinyverse_home>/logs/. - File name format:
tinyverse-<unix_millis>.log. tinyverse_homefollows the same resolution order documented inCLI / Commands.
- Moon workspace config lives in
.moon/workspace.ymland.moon/toolchains.yml. - Rust project configs live in
tinyverse_lib/moon.ymlandtinyverse_cli/moon.yml. - Example commands:
moon :installmoon run tinyverse_lib:checkmoon run tinyverse_cli:test
bun scripts/build.sh.ts// runmoon :buildbun scripts/check.sh.ts// runmoon :checkbun scripts/test.sh.ts// runmoon :testbun scripts/dev.sh.ts// run default watch loop fortinyverse_clibun scripts/ci.sh.ts [mode]// local CI orchestration (same entrypoints used by GitHub Actions)bun scripts/docker_build.sh.ts [targets...]// docker compose build wrapperbun scripts/docker_ci.sh.ts [run --] [command...]// run CI command insidecicontainerbun scripts/docker_publish.sh.ts --image-repo <repo> --tag <tag> [--push]
list// List tmux sessions known to tinyverse (defaults to tinyverse-only sessions).- Source of truth is the local tinyverse SQLite session DB.
- Reconciles DB sessions against tmux before reads (debounced/rate-limited).
--allincludes unmanaged tmux sessions in addition to DB sessions.--tmuxbypasses TinyVerse storage and lists tmux sessions directly.--format={table|text|json|toml|yaml}(default:table)
spawn// Create a new tinyverse session (console + agent panes).- Default pane layout:
agenton left,consoleon right. - Initial tmux window size and split behavior are configurable via
tmux.*config keys. --agent={opencode}(defaults fromspawn.default_agentconfig)--prompt={file_or_string}- OpenCode receives a default TinyVerse context prompt template from
tinyverse_cli/prompts/opencode_default_context.md. - When
--promptis provided, TinyVerse appends it as aTask Requestsection to that default OpenCode context. --model={model}(defaults fromspawn.default_modelconfig when set)--agent_args={string}(supports{prompt}placeholder)--clean-shell(starts panes withzsh -f, ignores user~/.zshrc)--no-clean-shell(forces default shell startup behavior)- Working directory defaults to
workspace.default_dirwhen configured, otherwise current directory.
- Default pane layout:
prompt render// Render effective launch prompt for an agent.--agent={opencode}(default:opencode)--prompt={file_or_string}
config print// Print effective config.--output={full|raw}(default:full;rawprints config data only)--format={table|text|json|toml|yaml}(default:table)
config export// Export effective config as TOML (with source/path metadata comments).- Writes to resolved
active_pathby default. --path <config_file>writes to that explicit output file path.
- Writes to resolved
config set <key> <value>// Persist a config value in<tinyverse_home>/config.toml.- Supported keys:
shell.clean(true|false)workspace.default_dir(path string; usenoneto clear)git.branch_prefix(string)spawn.default_agent(string)spawn.default_model(string; usenoneto clear)tmux.initial_window_width(integer)tmux.initial_window_height(integer)tmux.layout.direction(horizontal|vertical)tmux.layout.primary(agent|console)tmux.layout.secondary_percent(1-99)tui.refresh_hz(integer; updates per second)
- Supported keys:
attach <session>// Attach to an existing session by key or name.- Session lookup first tries an exact match.
- If exact match is not found, tinyverse also tries
tinyverse_<session>.- Example:
attach reddingresolvestinyverse_reddingwhen present.
- Example:
- If
<session>is omitted in an interactive terminal, tinyverse opens a TUI selector.
detach// Detach current tmux client without closing the session.kill <session>// Kill session by key or name.- If
<session>is omitted in an interactive terminal, tinyverse opens a TUI selector. --tmuxbypasses TinyVerse storage and targets tmux sessions directly.--tmux --allkills all tmux sessions.
- If
view// Capture pane output.--session={key_or_name}(optional inside tmux, required outside tmux)--panel={console|agent|%pane_id}--output={full|raw}(default:full;rawprints pane buffer text only)--export=<path>(writes rendered output to file; adds.mdwhen extension is missing)
send <command>// Send keys to pane.--session={key_or_name}(optional inside tmux, required outside tmux)--panel={console|agent|%pane_id}
debug self// Inspect current tmux context.--format={table|text|json|toml|yaml}
debug reset-db// Backup and reset local tinyverse session DB.
# Spawn a new session with default agent
# (defaults key to an available California city, e.g. tinyverse_san_bernardino)
cargo run -p tinyverse_cli -- spawn
# Spawn with a prompt string
cargo run -p tinyverse_cli -- spawn --prompt "you are a helpful coding agent"
# Preview full rendered launch prompt
cargo run -p tinyverse_cli -- prompt render --agent opencode --prompt "triage failing tests"
# Spawn with clean zsh (no ~/.zshrc)
cargo run -p tinyverse_cli -- spawn --clean-shell
# Persist clean shell as the default for future spawns
cargo run -p tinyverse_cli -- config set shell.clean true
# Set default spawn and workspace values
cargo run -p tinyverse_cli -- config set spawn.default_agent opencode
cargo run -p tinyverse_cli -- config set spawn.default_model gpt-5.3-codex
cargo run -p tinyverse_cli -- config set workspace.default_dir ~/repos/vfp/tinyverse
# Tune default tmux spawn layout
cargo run -p tinyverse_cli -- config set tmux.initial_window_width 220
cargo run -p tinyverse_cli -- config set tmux.initial_window_height 64
cargo run -p tinyverse_cli -- config set tmux.layout.direction horizontal
cargo run -p tinyverse_cli -- config set tmux.layout.primary agent
cargo run -p tinyverse_cli -- config set tmux.layout.secondary_percent 35
# Set TUI refresh rate (2 Hz = 500ms)
cargo run -p tinyverse_cli -- config set tui.refresh_hz 2
# Check effective config and export as TOML
cargo run -p tinyverse_cli -- config print
cargo run -p tinyverse_cli -- config export
# Config print as machine formats
cargo run -p tinyverse_cli -- config print --format yaml
cargo run -p tinyverse_cli -- config print --output raw --format toml
# Export a specific config file
cargo run -p tinyverse_cli -- config export --path ./.tinyverse/config.toml
# Spawn with an explicit key/name
cargo run -p tinyverse_cli -- spawn --key my-session
# List tinyverse sessions only (default)
cargo run -p tinyverse_cli -- list
# List TinyVerse + unmanaged tmux sessions
cargo run -p tinyverse_cli -- list --all
# List tmux sessions directly (bypass TinyVerse DB)
cargo run -p tinyverse_cli -- list --tmux
# Override tinyverse home path for this invocation
cargo run -p tinyverse_cli -- --tinyverse-dir-home ./.tinyverse list
# List as JSON (for scripting)
cargo run -p tinyverse_cli -- list --format json
# Attach to a session
cargo run -p tinyverse_cli -- attach tinyverse_123
# Attach and choose from interactive TUI selector
cargo run -p tinyverse_cli -- attach
# Attach using implicit tinyverse_ prefix fallback
cargo run -p tinyverse_cli -- attach redding
# Detach from current tmux client (session keeps running)
cargo run -p tinyverse_cli -- detach
# Send a command to a specific session console pane
cargo run -p tinyverse_cli -- send "pwd" --session tinyverse_123 --panel console
# View latest console output for a session
cargo run -p tinyverse_cli -- view --session tinyverse_123 --panel console
# View raw pane buffer only (agent-friendly)
cargo run -p tinyverse_cli -- view --session tinyverse_123 --panel console --output raw
# Export captured output to markdown
cargo run -p tinyverse_cli -- view --session tinyverse_123 --panel console --export ./captures/redding
# Debug current context as text/json
cargo run -p tinyverse_cli -- debug self
cargo run -p tinyverse_cli -- debug self --format json
# Debug current context as YAML/TOML
cargo run -p tinyverse_cli -- debug self --format yaml
cargo run -p tinyverse_cli -- debug self --format toml
# Backup and reset session DB
cargo run -p tinyverse_cli -- debug reset-db
# Kill a session
cargo run -p tinyverse_cli -- kill tinyverse_123
# Kill and choose from interactive TUI selector
cargo run -p tinyverse_cli -- kill
# Kill a tmux session directly (bypass TinyVerse DB)
cargo run -p tinyverse_cli -- kill --tmux my-tmux-session
# Kill all tmux sessions directly
cargo run -p tinyverse_cli -- kill --tmux --all$ cargo run -p tinyverse_cli -- config print --output full --format text
selected_source: repo_local
selected_home: /Users/alex/repos/vfp/tinyverse/.tinyverse
active_path: /Users/alex/repos/vfp/tinyverse/.tinyverse/config.toml
legacy_path: /Users/alex/repos/vfp/tinyverse/.tinyverse/tinyverse.toml
loaded_from: /Users/alex/repos/vfp/tinyverse/.tinyverse/config.toml
shell.clean: false
workspace.default_dir: <unset>
git.branch_prefix: tv/
spawn.default_agent: opencode
spawn.default_model: <unset>
tmux.initial_window_width: 220
tmux.initial_window_height: 64
tmux.layout.direction: horizontal
tmux.layout.primary: agent
tmux.layout.secondary_percent: 35
$ cargo run -p tinyverse_cli -- config print --output raw --format yaml
shell:
clean: false
workspace:
default_dir: null
git:
branch_prefix: tv/
spawn:
default_agent: opencode
default_model: null
tmux:
initial_window_width: 220
initial_window_height: 64
layout:
direction: horizontal
primary: agent
secondary_percent: 35