Skip to content

lispking/harness-cli

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Harness CLI

A multi-turn conversational AI agent CLI built in Go, featuring dual agent roles (planner + executor), pluggable skills, and a rich terminal UI.

Features

  • Multi-turn conversations - Interactive chat with context maintained across turns
  • Dual agent architecture - Planner decomposes tasks, Executor runs them with tools
  • Pluggable tools - Built-in: shell execution, file read/write, code execution (Python, JavaScript, Go, Rust, etc.)
  • Agent Skills - Built-in domain expertise (git-commit, code-review, debugging, refactoring) + custom skills support
  • Dual LLM backend - OpenAI-compatible API and Anthropic API
  • Session memory - Remember instructions like "be concise" across turns
  • Session persistence - Save and resume chat sessions across restarts
  • TOML config file - Configuration stored in ~/.harness-cli/config.toml
  • Rich TUI - Bubble Tea powered terminal interface with live progress updates

Prerequisites

  • Go 1.21+
  • An API key for OpenAI or Anthropic

Install

git clone https://github.com/lispking/harness-cli.git
cd harness-cli
go build -o harness-cli .

Configuration

On first run, a config file is created at ~/.harness-cli/config.toml:

# LLM provider: "openai" or "anthropic"
provider = "openai"

# API key for the selected provider.
# You can also set OPENAI_API_KEY or ANTHROPIC_API_KEY environment variable instead.
api_key = ""

# API base URL. Leave empty to use the provider's default endpoint.
# Examples:
#   OpenAI:     https://api.openai.com/v1
#   Anthropic:  https://api.anthropic.com
#   Ollama:     http://localhost:11434/v1
#   DeepSeek:   https://api.deepseek.com/v1
base_url = ""

# Default model name. Can be overridden with --model flag.
model = "gpt-5.4"

Alternatively, you can set API keys via environment variables:

export OPENAI_API_KEY="sk-..."
# or
export ANTHROPIC_API_KEY="sk-ant-..."

Usage

Start a chat

# Launch the interactive TUI (uses config file settings)
./harness-cli

# Override the model
./harness-cli -m claude-sonnet-4-6

# Resume the most recent session
./harness-cli -c

# Resume a specific session by ID
./harness-cli -s 2026-04-12_14-30-00

Chat commands

Inside the chat session:

Command Description
/help Show available commands
/quit or /exit Exit the chat (auto-saves session)
/clear Clear conversation history
/remember <text> Remember an instruction for this session
/forget Clear all remembered instructions
/memory Show current remembered instructions
/save Save current session to disk
/sessions List all saved sessions
/skills Open skill picker to activate a skill

Example session

> list the Go files in the current directory
⣾  Planning...
[Calling tool: shell_exec]
[Executing tool: shell_exec]
[Result]: main.go
...

> /remember be concise
Remembered: be concise

> what time is it
[Calling tool: shell_exec]
[Executing tool: shell_exec]
[Result]: Sat Apr 12 14:32:01 CST 2026

Sat Apr 12 14:32:01 CST 2026

  (3.2s | in:45 out:120)

> write a python script to calculate fibonacci
[Calling tool: write_file]
[Executing tool: write_file]
[Result]: File written successfully

[Calling tool: code_exec]
[Executing tool: code_exec]
[Result]: [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

I've created a Python script to calculate the first 10 Fibonacci numbers:
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

  (5.8s | in:156 out:340)

Architecture

User Input
    |
    v
+----------+     +------------------+
|  Planner  |---->|  Plan (JSON)     |
|  Agent    |     |  {steps:[...]}   |
+----------+     +--------+---------+
                          |
                          v
                 +------------------+
                 |   Executor Agent  |
                 |   (tool-call loop)|
                 |                   |
                 |  +-------------+  |
                 |  | Tool Reg.   |  |
                 |  | - shell_exec|  |
                 |  | - read_file |  |
                 |  | - write_file|  |
                 |  | - code_exec |  |
                 |  +-------------+  |
                 +--------+---------+
                          |
                          v
                    Final Response

Project Structure

+-- main.go                   # Entry point
+-- cmd/
|   +-- root.go               # Root command + TUI launch
|   +-- version.go            # Version command
+-- config/
|   +-- config.go             # TOML config file loading
+-- internal/
|   +-- llm/
|   |   +-- types.go          # Message, ToolCall, Response
|   |   +-- client.go         # Client interface
|   |   +-- openai.go         # OpenAI implementation
|   |   +-- anthropic.go      # Anthropic implementation
|   |   +-- retry.go          # Retry with exponential backoff
|   +-- agent/
|   |   +-- agent.go          # Agent interface
|   |   +-- planner.go        # Task decomposition
|   |   +-- executor.go       # Step execution with tools
|   +-- tool/
|   |   +-- tool.go           # Tool interface + Registry
|   |   +-- shell.go          # Shell command execution
|   |   +-- read.go           # File reading
|   |   +-- write.go          # File writing
|   |   +-- code.go           # Code execution (Python, JS, Go, Rust, etc.)
|   +-- skill/
|   |   +-- skill.go          # Agent Skills support
|   |   +-- builtin/          # Built-in skills
|   |       +-- git-commit/
|   |       +-- code-review/
|   |       +-- debugging/
|   |       +-- refactoring/
|   +-- memory/
|   |   +-- memory.go         # Session-scoped memory
|   +-- session/
|   |   +-- session.go        # Session persistence to disk
|   +-- tui/
|       +-- model.go          # Bubble Tea model
|       +-- view.go           # Rendering
|       +-- update.go         # Message handling

Agent Skills

Harness CLI includes built-in skills for common tasks and supports custom skills via agentskills.io specification.

Built-in Skills

Skill Description Activated When
git-commit Conventional Commits style messages "commit this", "write commit message"
code-review Code quality & security review "review this code", "check this"
debugging Systematic debugging guidance "it's not working", "fix this bug"
refactoring Safe refactoring techniques "clean up this code", "refactor"

Skills activate automatically when relevant to your task.

Manual Activation: Type /skills to open the skill picker and manually activate a skill. Use ↑↓ to navigate, Enter to activate, Esc to cancel.

Custom Skills

Create your own skills in ~/.harness-cli/skills/:

skills/
└── my-skill/
    ├── SKILL.md          # Required: metadata + instructions
    ├── scripts/          # Optional: executable code
    ├── references/       # Optional: documentation
    └── assets/           # Optional: templates

SKILL.md format:

---
name: my-skill
description: What this does. Use when the user needs X.
---

# My Skill

## When to Use
Explain when to activate this skill.

## Instructions
Step-by-step guidance for the agent.

Skills are automatically discovered and activated when relevant.

Adding a Custom Tool

Implement the Tool interface and register it:

// internal/tool/my_tool.go
package tool

import "context"

type MyTool struct{}

func (t *MyTool) Name() string { return "my_tool" }
func (t *MyTool) Description() string { return "Does something custom" }
func (t *MyTool) Parameters() map[string]any {
    return schema(map[string]any{
        "input": map[string]any{"type": "string"},
    }, []string{"input"})
}
func (t *MyTool) Execute(ctx context.Context, argsJSON string) (string, error) {
    // Your logic here
    return "result", nil
}

Then register in cmd/root.go:

registry.Register(tool.NewMyTool())

License

MIT

About

A multi-turn conversational AI agent CLI built in Go, featuring dual agent roles (planner + executor), pluggable skills, and a rich terminal UI.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages