Skip to content

Likhith-Sanathi/tack

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

57 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tack

tack is a terminal-native autonomous coding harness for OpenRouter.

It runs in your terminal, keeps a live transcript, and can plan, edit, run, and verify changes inside the current workspace.

What it gives you:

  • an autonomous agent loop that can inspect the repo, make edits, and execute commands
  • streaming chat responses when you want to steer manually
  • model, provider, and reasoning selection
  • transcript search and history recall
  • markdown-rendered output with syntax highlighting and rich formatting
  • approval gates for risky commands and external paths

It is a single Rust binary crate built on ratatui, crossterm, and OpenRouter's chat and model endpoints.

Autonomous Loop

The core operating model is:

  1. Take a goal in agent mode.
  2. Generate a concise plan from workspace context.
  3. Execute one tool action at a time.
  4. Record each step, reflection, and changed file set.
  5. Verify with the project-aware test command when possible.
  6. Repair, retry, or finish when the goal is complete.

That loop keeps the app closer to a terminal-native coding agent than a traditional chat client.

Operator View

The app works like a live control panel for autonomous work:

  • the top bar shows the active model, provider route, reasoning level, and chat or agent mode
  • the center pane shows the conversation and the agent's progress
  • the composer at the bottom is where you type goals, prompts, and slash commands
  • the footer shows status, context usage, latency, throughput, pricing, and the last response usage
  • when an agent run is active and the terminal is wide enough, a side panel appears with the agent's phase, step budget, workspace, changed files, verification state, and latest reflection

Quick Start

  1. Install a recent stable Rust toolchain.
  2. Set your OpenRouter API key.
  3. Run the app.
export OPENROUTER_API_KEY=your_key_here
cargo run

If you prefer to keep the key in your shell startup file, the app also reads OPENROUTER_API_KEY from ~/.zshrc.

Configuration

The app reads a small set of environment variables on startup:

  • OPENROUTER_API_KEY - required unless it can be found in ~/.zshrc
  • OPENROUTER_MODEL - optional starting model, defaults to openai/gpt-4o-mini
  • AGENT_MAX_STEPS - optional agent step cap, defaults to 24
  • AGENT_MAX_RUNTIME_SECS - optional agent runtime cap in seconds, defaults to 1200

The app also persists preferences in a hidden JSON file in your home directory:

  • model
  • provider_slug
  • reasoning_effort

That file is how the app remembers the last model, provider route, and reasoning choice between launches.

Interactive Modes

Chat Mode

Chat mode is the manual steering lane.

  • type a prompt and press Enter to send it
  • Shift+Enter inserts a newline without submitting
  • OpenRouter responses stream token-by-token into the transcript
  • if the response exposes reasoning text, it is rendered as a separate reasoning message before the assistant answer
  • the footer updates with first-token latency, average latency, tokens per second, and usage cost when the response completes

Agent Mode

Agent mode is the autonomous lane. It treats the current directory as a workspace and drives the plan/act/verify loop for you.

  • press Shift+Tab to toggle between chat and agent mode
  • or run /agent with no arguments to toggle
  • run /agent <goal> to start an agent run immediately

The agent flow is:

  • create an AgentRun for the current directory
  • ask OpenRouter for a concise plan
  • execute one structured action at a time
  • record each step, reflection, and changed file set
  • verify the result with a project-aware test command when possible
  • stop when the goal is complete, the budget is exhausted, or verification fails too many times

The default verification command is chosen from the workspace:

  • cargo test when Cargo.toml exists
  • bun test when bun.lockb exists
  • npm test when package.json exists
  • go test ./... when go.mod exists
  • python -m pytest when pyproject.toml or pytest.ini exists
  • git diff --check when the repo only looks like a git checkout

Agent Toolset

The agent can ask the model to emit structured JSON actions. Supported actions are:

  • search
  • glob_paths
  • list_dir
  • exists_path
  • stat_path
  • read_file
  • create_dir
  • write_file
  • append_file
  • prepend_file
  • patch_edit
  • diff_file
  • copy_path
  • move_path
  • delete_path
  • read_link
  • create_symlink
  • create_archive
  • extract_archive
  • run_command
  • finish

Read-only and write-capable actions are separated in the implementation, and the app refuses obviously dangerous mutations such as writing directly to the workspace root.

Agent Safety

The agent has a few safety rails built in:

  • commands are run through zsh -lc
  • shell commands have a timeout
  • action results are summarized so huge command output does not flood the transcript
  • commands that look like they mutate the workspace are treated as higher risk
  • external paths outside the workspace can trigger approval
  • approvals can be remembered for the current session

If the agent asks for approval, the keybinds are:

  • Enter, 1, y, or Y approve
  • 2, a, or A approve and remember the current command or external root for the session
  • Esc, 3, n, or N deny
  • s or S stop the agent run

Slash Commands

Use /help inside the app to print the full list. The main commands are:

  • /help - show the command list
  • /agent [goal] - toggle agent mode or start an agent run
  • /agent-status - print a detailed status summary for the active agent run
  • /agent-stop - cancel the active agent run
  • /find <text> - search the transcript
  • /find-next - move to the next transcript match
  • /find-prev - move to the previous transcript match
  • /model [query] - open the model picker, optionally filtered
  • /use-model <id-or-query> - set a model directly, then choose a provider
  • /provider <slug|auto> - choose a provider route
  • /reasoning [auto|level] - open or set the reasoning level
  • /refresh - reload OpenRouter model metadata
  • /clear - clear chat history
  • /quit or /q - exit the app

Keyboard Shortcuts

  • Enter - submit the current input
  • Shift+Enter - insert a newline
  • Shift+Tab - toggle chat and agent mode
  • Ctrl+S - submit the current input
  • Ctrl+F - prefill /find
  • Alt+Up and Alt+Down - recall previous inputs
  • Ctrl+Up and Ctrl+Down - scroll the transcript
  • Ctrl+PageUp and Ctrl+PageDown - page through the transcript
  • Ctrl+Home and Ctrl+End - jump to the top or bottom of the chat
  • Tab - autocomplete slash commands
  • Esc - contextual cancel, clear, or stop action, usually with a second press to confirm
  • Ctrl+C - quit

While in multiline composer mode, the editor also supports common line navigation and deletion shortcuts such as Ctrl+A, Ctrl+E, Ctrl+U, Ctrl+K, Ctrl+W, Alt+Backspace, and Alt+Delete.

Model, Provider, and Reasoning Selection

The app fetches OpenRouter model metadata on launch.

  • /model opens a filtered model search
  • choosing a model loads its provider routes
  • /provider auto restores OpenRouter's automatic route selection
  • /provider <slug> pins a specific provider route when one is available
  • /reasoning shows the reasoning levels advertised by the current model
  • the current model's context window, pricing, supported parameters, architecture details, and reasoning metadata are shown in the model picker
  • the selected model, provider route, and reasoning effort are persisted across launches

If the model changes and OpenRouter returns a resolved model ID that is in the loaded catalog, the app updates the active model preference to match it.

Chat Rendering

The transcript renderer is intentionally rich. It supports:

  • fenced code blocks
  • syntax highlighting for several common languages
  • diff blocks with added and removed line coloring
  • task lists
  • tables
  • definition lists
  • footnotes
  • inline code styling that treats path-like spans differently from shell commands

That makes model responses, code reviews, and agent output easier to scan inside the terminal.

UI Layout

The screen is split into four main regions:

  • top bar
  • transcript area
  • input composer
  • status footer

The top bar shows the active model, provider route, reasoning level, and whether the app is busy.

The footer shows:

  • current status
  • chat or agent mode
  • context usage
  • current pricing for the selected model
  • last response token usage and cost
  • speed and reliability metrics

When an agent run is active and the terminal is at least 96 columns wide, the transcript area splits into chat plus an agent detail panel.

Repository Layout

src/main.rs           binary entrypoint
src/lib.rs            crate wiring and shared constants
src/runtime.rs        terminal setup, event loop, and input handling
src/app.rs            application state, commands, search, metrics, and model selection
src/services.rs       OpenRouter streaming, model/provider fetch, and shared helpers
src/agent.rs          agent orchestration and run lifecycle
src/agent_services.rs filesystem actions, command execution, verification, and approval logic
src/ui.rs             ratatui layout and widgets
src/markdown.rs       markdown rendering for chat messages
src/styles.rs         theme, colors, icons, and text styling
src/models.rs         shared data models and agent state types
src/config.rs         environment loading and persisted preferences
src/tests.rs          behavior-focused tests

Development

Common local checks:

cargo fmt
cargo test
cargo clippy

The tests cover:

  • markdown rendering behavior
  • agent JSON repair and plan parsing
  • command summarization
  • verification command selection
  • transcript search and history recall
  • agent budgeting and verification flow
  • model/provider/reasoning selection

Troubleshooting

  • If you see OPENROUTER_API_KEY was not found in the environment or ~/.zshrc, export the key or add it to ~/.zshrc.
  • If the model list will not load, check network access and whether the key is valid for OpenRouter.
  • If the wrong model keeps coming back, delete the persisted preferences file in your home directory to clear saved settings.
  • If agent commands keep asking for approval, use approve and remember once for the current command or external root.
  • If the agent behaves like it is stalled, check the footer and the agent side panel for the current phase, step budget, verification state, and last reflection.

Notes

  • The agent runs from the current directory, so it is best used inside a git checkout you are comfortable modifying.
  • The app uses Unix-specific shell and filesystem features for agent commands and symlinks, so it is best suited to Unix-like systems.
  • The OpenRouter model catalog and provider metadata are fetched live, so available routes can change over time.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages