Skip to content

Repository files navigation

✦ Wisp

A local coding agent orchestrator. Claude implements. Codex ships. You stay in control.

CI CDnpm License: MIT Platform

한국어 · 简体中文 · Quick Start · How It Works · Configuration · Docs


Wisp is a local-first agent orchestrator that coordinates Claude and Codex through a structured 4-step workflow — implement → patch → review → ship — entirely on your machine, with no cloud dependency beyond the agents themselves.

Everything defaults to dry-run preview. Nothing changes in your repo until you say so. Every session is fully audited to .wisp/sessions/.

  ┌─ [1/4]  Claude  ─  implement    writes the solution
     [2/4]  Codex   ─  patch        reviews diff, applies fixes
     [3/4]  Claude  ─  review       APPROVED / CHANGES_REQUESTED
  └─ [4/4]  Codex   ─  ship         suggests commit message

Quick Start

# Install (binary auto-downloaded from GitHub Releases)
npm install -g @lka09/wisp

# Initialize your project
cd your-project
wisp init

# Preview what agents would do — no files changed
wisp summon "add rate limiting to the API endpoints"

# Actually run it
wisp summon "add rate limiting to the API endpoints" --execute-agents

Prerequisite: Claude CLI and/or Codex CLI installed and authenticated. Dry-run works without them.


Monorepo Layout

Wisp is now split into a Cargo workspace:

Wisp/
  Cargo.toml
  crates/
    wisp-core/   reusable engine, workflows, session/event logging
    wisp-cli/    `wisp` binary, CLI formatting, interactive TUI
  app/           Electron desktop app (spawns the CLI as a child process)
  npm/           npm package wrapper and shipped binaries

The desktop app is separate from the CLI. It calls the Wisp CLI as a child process and reads the shared project records below. See app/README.md for building and packaging it.

Shared Project Records

The CLI and future GUI both use the same project data:

  • wisp.toml
  • .wisp/settings.toml
  • .wisp/sessions/

Debate and workflow runs write session outputs plus timeline.jsonl, which is intended for both terminal and GUI consumers.

Modes

Wisp supports three persisted modes:

  • wisp mode dry-run
  • wisp mode execute
  • wisp mode debate

wisp mode shows the current mode. Bare task input respects the saved mode in .wisp/settings.toml.

Debate example

wisp mode debate
wisp "add CSRF protection to admin APIs"

Debate flow:

Codex proposal -> Claude rebuttal -> Codex counter -> Claude risk review -> Judge comparison -> user approval

Both CLI mode and future GUI mode still require installed and authenticated Codex CLI and Claude CLI. Wisp does not bundle either tool.


Why Wisp

Problem Wisp's answer
AI edits your files while you look away Everything is dry-run by default
Can't tell what the agent actually did Full session log — prompts, diffs, timing, policy results
One agent makes one big messy change Four-role pipeline: implement → patch → review → ship
AI pushes commits you didn't approve Hard policy block on commit and push
Agents ignore your project conventions Load .wisp/instructions.md into every prompt
Korean task input breaks English-only tools Auto-detects Korean, responds in Korean

How It Works

Workflow

You: wisp summon "refactor the payment module"
      │
      ├─ 1. implement   Claude reads your task + project instructions,
      │                 writes the solution.
      │
      ├─ 2. patch       Codex reviews the diff, applies fixes.
      │                 (Repeats up to max_review_rounds times)
      │
      ├─ 3. review      Claude reviews the final diff.
      │                 → APPROVED  ·  CHANGES_REQUESTED  ·  NEEDS_USER_DECISION
      │
      └─ 4. ship        Codex prepares a commit message suggestion.
                        You decide whether to commit.

Session audit trail

Every run writes a timestamped session under .wisp/sessions/:

.wisp/sessions/20260619-143022-123-p4801/
  task.original.txt              what you typed
  task.normalized.en.md          English translation for agents
  instructions.loaded.md         all project instruction files merged
  prompts/
    implementer.en.md            prompt sent to Claude
    patcher.en.md
    reviewer.en.md
    shipper.en.md
  outputs/
    implement.out.md             stdout + stderr
    implement.meta.txt           timing, exit code, git delta, policy checks
    implement.diff.before.patch  git state before this step
    implement.diff.after.patch   git state after this step
    patch.out.md  /  patch.meta.txt  /  ...
    review.out.md /  review.meta.txt /  ...
    ship.out.md   /  ship.meta.txt   /  ...
  git/
    before/  diff.patch  diff.cached.patch  status.porcelain.txt  ...
    after/   diff.patch  diff.cached.patch  status.porcelain.txt  ...
  summary.md

Installation

Option 1 — npm (recommended)

npm install -g @lka09/wisp

The postinstall script downloads the pre-built binary for your platform from GitHub Releases. If the download fails, it prints exact instructions for building from source.

Supported platforms

OS Architecture Asset
Windows x86_64 wisp-windows-x86_64.exe
Windows ARM64 wisp-windows-aarch64.exe
Linux x86_64 wisp-linux-x86_64
Linux ARM64 wisp-linux-aarch64
macOS x86_64 wisp-darwin-x86_64
macOS Apple Silicon wisp-darwin-aarch64

Option 2 — Build from source

Windows (PowerShell)

git clone https://github.com/LKA09/Wisp
cd Wisp
cargo build --release
New-Item -ItemType Directory -Force -Path npm\dist | Out-Null
Copy-Item target\release\wisp.exe npm\dist\wisp.exe
cd npm
npm link

Linux / macOS

git clone https://github.com/LKA09/Wisp
cd Wisp
cargo build --release
mkdir -p npm/dist
cp target/release/wisp npm/dist/wisp
cd npm
npm link

Prerequisites

Tool When needed Install
Node.js ≥ 16 Always nodejs.org
Git Always git-scm.com
Rust + Cargo Source build only rustup.rs
Claude CLI --execute-agents npm i -g @anthropic-ai/claude-code
Codex CLI --execute-agents npm i -g @openai/codex

Interactive TUI

Run wisp with no arguments to open the full-screen interactive TUI. It shows the current branch, mode, and recent sessions, and streams workflow output live. (A real terminal is required — piped stdin is rejected with a clear message.)

wisp
 Wisp  │ feature/my-branch   mode: dry-run   cfg: ok
──────────────────────────────────────────────────────────────
  Wisp  —  local coding agent orchestrator

  Type a task and press Enter.  /help for commands.

──────────────────────────────────────────────────────────────
  > /
──────────────────────────────────────────────────────────────
  /run              execute workflow interactively
  /auto             execute workflow (auto-approve)
  /dry              dry-run preview workflow
  /debate           run debate workflow
  /claude           run Claude directly
  /codex            run Codex directly
  /mode             show or set dry-run / execute / debate mode
  /paste            how to enter multi-line tasks
  /doctor           check environment
  /init             initialize wisp
  /help             show commands
  /exit             exit wisp

Type / to open the live command picker. Completions filter as you type.

Commands

Input Action
<task> Run task (respects /mode setting — dry-run by default)
/run <task> Execute full workflow interactively
/auto <task> Execute full workflow (auto-approve)
/dry <task> Dry-run preview of the workflow
/debate <task> Run the debate workflow
/claude <task> Run Claude as a single direct agent
/codex <task> Run Codex as a single direct agent
/mode [dry-run|execute|debate] Show or set the default execution mode
/paste Show multi-line input help
/doctor Check git, agents, and config
/init Initialize wisp in this project
/help Show help
exit / quit / Ctrl+C Exit

Default mode

By default, bare task input (without /run or /auto) shows a dry-run preview. Use /mode to change this:

  > /mode execute    # bare tasks now invoke agents
  > /mode debate     # bare tasks run the debate workflow
  > /mode dry-run    # back to preview-only (default)
  > /mode            # show current mode

The setting is saved to .wisp/settings.toml and persists across sessions.

Multi-line task input

  • Paste directly — bracketed paste keeps newlines, so a multi-line paste lands in the input bar as one block (Windows Terminal, iTerm2, and other modern terminals).
  • Shift+Enter (or Alt+Enter) inserts a newline manually.
  • Put a command on the last line to choose how the task runs, then press Enter:
fix the payment module
handle the edge case where currency is null
also update the tests
/run
Trailing line Effect
/run Execute full workflow interactively
/auto Execute full workflow (auto-approve)
/dry Dry-run preview
/debate Run the debate workflow
/claude Run Claude as single agent
/codex Run Codex as single agent
(none) Respects the current /mode setting

CLI Reference

# Project setup
wisp init                                           # create wisp.toml + .wisp/
wisp doctor                                         # check git, agents, config
wisp update                                         # update wisp to the latest version
wisp mode                                           # show current default mode
wisp mode dry-run                                   # set default to dry-run preview
wisp mode execute                                   # set default to execute agents
wisp mode debate                                    # set default to debate workflow

# Workflow (4-step: implement → patch → review → ship)
wisp summon "<task>"                                # dry-run preview
wisp summon "<task>" --execute-agents               # execute
wisp summon "<task>" --execute-agents --allow-dirty
wisp summon "<task>" --execute-agents --permission auto

# Debate (5-step: proposal → rebuttal → counter → risk review → judge)
wisp debate "<task>"                                # dry-run preview
wisp debate "<task>" --execute-agents               # execute

# Single agent
wisp ask claude "<task>"                            # dry-run
wisp ask claude "<task>" --execute-agents           # execute
wisp ask codex  "<task>" --execute-agents --permission auto
wisp ask codex  "<task>" --permission skip

# Info
wisp --help
wisp --version
wisp summon --help

Flags

Flag Default Description
--execute-agents off Actually invoke agent CLIs
--allow-dirty off Skip uncommitted-changes check
--allow-protected-branch off Allow execution on protected branches (main, master)
--permission interactive Agent prompts user for approval
--permission auto Pass auto-approve flags to agent
--permission skip Skip permission-gated steps

Configuration

wisp init creates wisp.toml in your project root. Edit it to customize agents, workflow, and policy.

[language]
ui       = "auto"    # "auto" → detects Korean input, responds in Korean
fallback = "en"
internal = "en"

[agents.claude]
cmd   = "claude"
args  = ["-p", "{prompt}"]
input = "arg"
permission_interactive_args = []
permission_auto_args         = []
permission_skip_args         = []

[agents.codex]
cmd   = "codex"
args  = ["exec", "-s", "workspace-write", "{prompt}"]
input = "arg"
permission_interactive_args = []
permission_auto_args         = []
permission_skip_args         = []

[workflow]
implementer       = "claude"
patcher           = "codex"
reviewer          = "claude"
shipper           = "codex"
max_review_rounds = 2         # max patch/review retries before giving up

[approval]
push                        = "deny"   # always block push
commit                      = "ask"    # ask before commit
add_dependency              = "ask"
delete_file                 = "ask"
modify_protected_file       = "deny"
continue_after_test_failure = "ask"

[instructions]
files = [
  ".wisp/instructions.md",
  "WISP.md",
  "AGENTS.md",
  "AGENT.md",
  "CLAUDE.md",
  "CODEX.md",
]
max_bytes              = 32768
include_agent_specific = true

[policy]
protected_branches = ["main", "master"]
protected_paths    = [".env", ".env.local", ".git", "id_rsa", "secrets.toml", "credentials.json"]
deny_commands      = ["git push --force", "cargo publish", "npm publish", "rm -rf /"]

Prompt placeholders

Placeholder Value
{prompt} Full prompt text
{prompt_file} Path to prompt file in the session directory
{session_dir} Session directory path
{task} Raw task string from the user

Project instructions

Create .wisp/instructions.md to inject project context into every agent prompt:

# Project Instructions

- TypeScript + React 18. Use functional components and hooks only.
- Run `npm test` before considering any task complete.
- Never modify files under `src/generated/`.
- Commit messages must follow Conventional Commits.

AGENTS.md, AGENT.md, CLAUDE.md, CODEX.md, and WISP.md are loaded automatically if they exist.


Safety Model

Wisp is built around the principle that agents should suggest, not decide.

Guarantee Mechanism
No changes without consent Dry-run is the default; --execute-agents is explicit
Protected branches safe Execution blocked on main, master (configurable)
Dirty tree protected Blocked unless --allow-dirty is set
No surprise commits Agents instructed never to git commit
No surprise pushes push approval is deny by default in policy
Protected files safe deny_commands and protected_paths in wisp.toml
Dependency changes flagged add_dependency triggers approval gate
Full audit trail Every session logged to .wisp/sessions/

Note: Wisp is not a security sandbox. Agents run with your full user permissions. The policy layer blocks specific commands and paths, but cannot prevent every possible unsafe action. Always review agent output before approving commits.

Session logs are verbatim. Everything in a run — your task text, project instructions, agent prompts and outputs, and full git diffs — is stored unredacted under .wisp/sessions/. The directory is gitignored, but it lives on disk: review and delete sessions that contain sensitive data before sharing a machine or backup.


Publishing

This section is for maintainers who publish Wisp releases to GitHub and npm.

Release order

  1. Bump versions — only crates/wisp-cli/Cargo.toml needs to be updated manually:

    • crates/wisp-cli/Cargo.tomlversion = "x.y.z"
    • npm/package.json — updated automatically by the CD workflow
  2. Run local validation (from the repo root):

    cargo fmt --all --check
    cargo clippy --workspace --all-targets -- -D warnings
    cargo test --workspace
    npm pack --dry-run --prefix npm
  3. Create and push a version tag (or trigger the Release workflow manually with the same tag):

    git tag v0.1.0
    git push origin v0.1.0
  4. Confirm all GitHub Release assets are present (the CD workflow handles npm publish automatically after this):

    • wisp-windows-x86_64.exe
    • wisp-windows-aarch64.exe
    • wisp-linux-x86_64
    • wisp-linux-aarch64
    • wisp-darwin-x86_64
    • wisp-darwin-aarch64

The CD workflow automatically publishes to npm once all GitHub Release assets are confirmed. No manual npm publish step needed.

Important: publish order matters

The npm postinstall script is intentionally non-fatal — if the binary download fails it prints a source-build fallback message and exits cleanly. The CD workflow runs npm publish only after the GitHub Release job completes, so the assets are always available first.

Windows ARM64 note

The wisp-windows-aarch64.exe asset requires a GitHub-hosted Windows ARM64 runner. If that runner type is unavailable at release time, omit the Windows ARM64 asset and either remove it from the supported-platforms table or mark it as source-build only.


Contributing

git clone https://github.com/LKA09/Wisp
cd Wisp

cargo fmt --all
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
  • Core code lives in crates/wisp-core/src/
  • CLI code lives in crates/wisp-cli/src/
  • Lean dependency set — clap, serde, toml, anyhow, chrono, ureq, serde_json, plus ratatui/crossterm for the TUI
  • PRs against develop-ai branch

License

MIT © LKA09

About

🤖 A local personal coding agent orchestrator.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages