kojo

module
v0.116.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 9, 2026 License: MIT

README

kojo

Release Go

日本語

Remotely operate AI coding CLIs (Claude Code, Codex, Grok Build) from your mobile device — and run persistent AI agents, across one or more machines, that think, remember, and collaborate on their own.

┌───────────────────┐       Tailscale        ┌──────────────────┐
│  macOS / Win / Linux│◄─────(P2P encrypted)─────►│  Mobile Browser  │
│                     │                        │                  │
│  kojo server        │   WebSocket / HTTP     │  Web UI          │
│  ├─ PTY sessions    │◄─────────────────────►│  ├─ xterm.js     │
│  ├─ AI agents       │                        │  ├─ React        │
│  └─ credentials DB  │                        │  └─ Web Push     │
└───────────────────┘                        └──────────────────┘

Features

  • Single binary — Built with Go, web UI embedded
  • Cross-platform — macOS/Linux (tmux + PTY) and Windows (ConPTY) native support
  • AI agents — Persistent AI personas with memory, scheduled execution, encrypted credentials, and group DM
  • tmux-backed sessions (macOS/Linux) — CLI tools run inside tmux for crash resilience and persistence across kojo restarts
  • Unified PTY — All CLIs handled uniformly via PTY. No SDK dependencies
  • Tailscale P2P — No central server or database. Encrypted with WireGuard
  • Zero config — Just run kojo with Tailscale running

Requirements

macOS / Linux
  • Go 1.25+
  • Node.js 20+
  • tmux
  • Tailscale
  • Supported CLIs: claude, codex, grok (Grok Build) — at least one
Windows
  • Go 1.25+
  • Node.js 20+
  • Windows 10 1809+ / Windows 11 (ConPTY support required)
  • Tailscale
  • Supported CLIs: claude, codex, grok (Grok Build) — at least one

Note: On Windows, sessions run via ConPTY instead of tmux. Session persistence across kojo restarts is not available.

Build

# Production build (macOS/Linux)
make build

# Cross-compile for Windows (from macOS/Linux)
make build-windows

# Build on Windows
build.bat

# Development (two terminals)
make dev-server   # Go server (--dev mode, proxies to Vite)
make dev-web      # Vite dev server

# Hot reload (auto rebuild on Go file changes)
make watch

Usage

# Via Tailscale (default, auto HTTPS)
kojo

# Local only
kojo --local

# Custom port (auto-increments if busy)
kojo --port 9090

By default, kojo listens on the Tailscale network via tsnet with HTTPS. Use --local or --dev to bind to localhost only.

Multi-device cluster (peer mode)

A second machine joins the Hub as a peer with a single command. Any combination of macOS, Linux, and Windows machines is supported.

# On the peer host
kojo --peer

The peer auto-discovers the Hub via Tailscale MagicDNS (https://kojo.<tailnet>.ts.net:8080), writes the Hub into its local peer registry, and POSTs a join request. The Hub holds the request and surfaces it in Settings → Peers → "Pending join requests". Click Approve to grant the peer the privileged surface (sessions, files, git). Reject drops the request; the peer is free to retry.

Override the discovery target when needed:

kojo --peer --hub https://hub.example.ts.net:8080
KOJO_HUB_URL=https://hub.example.ts.net:8080 kojo --peer

Bind the peer listener to the Tailscale interface only (refuse to fall back to 0.0.0.0):

kojo --peer --tailnet-only

The legacy manual pairing path (--peer-add / --peer-trust / --peer-remove) still works as an escape hatch.

See docs/multi-device.md for the full multi-device setup, agent device-switch, and Hub failover procedure.

Upgrading from an earlier release

The on-disk config layout changed in v0.101.0. If you ran an earlier kojo release (v0.x using ~/.config/kojo/ on macOS / Linux or %APPDATA%\kojo\ on Windows), see docs/migration.md for the --migrate flow, rollback path, and the list of features that did not carry over (Gemini CLI backend and Gmail notifications were removed).

Tailscale HTTPS Setup

kojo uses tsnet to join your Tailscale network directly as a node named kojo. All traffic is encrypted with WireGuard — no ports to open, no certificates to manage.

Prerequisites
  1. Install Tailscale on your machine and your mobile device
  2. Sign in to the same Tailscale account on both devices
  3. Ensure both devices appear in Tailscale admin console
How it works

When you run kojo (without --local):

  1. kojo starts an embedded Tailscale node via tsnet
  2. The node registers itself as kojo on your tailnet
  3. HTTPS is automatically provisioned using Tailscale's built-in Let's Encrypt integration
  4. Your server becomes reachable at https://kojo.<tailnet-name>.ts.net
$ kojo

  kojo v0.110.0 running at:

    https://kojo.tail1234.ts.net
    https://100.x.y.z:8080
First run

On the first launch, tsnet will print an authentication URL to stderr. Open it in your browser to authorize the node. This is a one-time step — credentials are cached in ~/.config/tsnet-kojo/.

Access from mobile
  1. Install the Tailscale app on your phone
  2. Sign in with the same account
  3. Open https://kojo.<tailnet-name>.ts.net in your mobile browser

All communication is peer-to-peer via WireGuard. No data passes through a central server.

Security model
Layer Protection
Network WireGuard encryption (Tailscale P2P)
TLS Auto-provisioned HTTPS via Let's Encrypt
WebSocket Origin restricted to Tailscale IPs (100.*), *.ts.net, and localhost
Access Only devices on your tailnet can reach kojo
ACL (optional)

You can restrict which devices can access kojo using Tailscale ACLs:

{
  "acls": [
    {
      "action": "accept",
      "src": ["tag:mobile"],
      "dst": ["tag:kojo:*"]
    }
  ],
  "tagOwners": {
    "tag:mobile": ["autogroup:admin"],
    "tag:kojo":   ["autogroup:admin"]
  }
}
Troubleshooting
Problem Solution
Auth URL not appearing Check stderr output, or remove ~/.config/tsnet-kojo/ and restart
Cannot reach from mobile Ensure both devices are on the same tailnet and Tailscale is connected
Port conflict Use --port <number> (auto-increments up to 10 times if busy)
Want localhost only Use --local or --dev to skip Tailscale entirely

What it does

Terminal Sessions
  • Manage multiple sessions simultaneously (newest first)
  • Session persistence via tmux on macOS/Linux (~/.config/kojo/sessions.json, auto-cleanup after 7 days). Sessions survive kojo restarts and crashes
  • Session restart with tool-specific resume (claude --resume, codex resume, grok --resume)
  • Real-time PTY output streaming (xterm.js)
  • Text input (Enter for newline, Shift+Enter to send) and special keys (Esc, Tab, Ctrl, arrows)
  • Working directory path completion
  • File browser (syntax highlighting for text, image preview)
  • File attachment (camera, images, text)
  • Git panel (status, log, diff, commit diff view)
  • Web Push notifications (permission prompts, completion alerts)
  • Yolo mode (auto-approve permissions)
  • Minimal system prompt option for claude (override default with a working-directory note)
AI Agents
  • Create persistent AI personas with custom name, personality, avatar, and backend (Claude / Codex / Grok Build, plus custom Anthropic Messages API endpoints like llama-server)
  • AI-assisted persona generation (via claude/codex/grok CLI) and avatar generation (Gemini Image API)
  • Interactive chat with streaming responses, thinking display, and tool-use cards
  • Markdown rendering in agent messages
  • Scheduled autonomous execution (10 min – 24 h intervals) with auto-staggering, per-agent timeout, and cross-process dedup
  • Persistent memory: long-term MEMORY.md + daily notes with full-text search (SQLite FTS5)
  • Encrypted credential vault (AES-256-GCM SQLite) with TOTP 2FA support
  • Public profile and agent directory for inter-agent discovery
  • Group DM: multi-agent conversations with notification-based messaging
  • Slack integration (Socket Mode) — per-agent bot with live streaming replies, per-thread session resumption, and channel/thread-aware system prompt
  • Agent data reset (clear conversations and memory while keeping settings, persona, avatar, and credentials)
  • Fork agents preserving persona and memory

Tech Stack

Layer Technology
Server Go, net/http, coder/websocket, creack/pty (Unix) / ConPTY (Windows), tmux (Unix), tsnet
Web UI React 19, Vite, TypeScript, Tailwind CSS, xterm.js
Agents Claude / Codex / Custom API backends, encrypted SQLite (credentials + FTS5 memory)
Notifications Web Push (VAPID)
Network Tailscale WireGuard P2P

Install

go install github.com/loppo-llc/kojo/cmd/kojo@latest

License

MIT

Directories

Path Synopsis
cmd
kojo command
internal
auth
Package auth provides a lightweight, role-based access control layer for kojo's HTTP API.
Package auth provides a lightweight, role-based access control layer for kojo's HTTP API.
blob
Package blob is the native blob store described in docs/multi-device-storage.md §2.4 and §4.2.
Package blob is the native blob store described in docs/multi-device-storage.md §2.4 and §4.2.
chathistory
Package chathistory provides platform-agnostic chat history storage and formatting for external messaging platforms (Slack, Discord, etc.).
Package chathistory provides platform-agnostic chat history storage and formatting for external messaging platforms (Slack, Discord, etc.).
configdir
Package configdir resolves the on-disk location for kojo's configuration directory.
Package configdir resolves the on-disk location for kojo's configuration directory.
eventbus
Package eventbus implements the in-memory invalidation broadcast bus described in docs/multi-device-storage.md §3.5 / §4.1.
Package eventbus implements the in-memory invalidation broadcast bus described in docs/multi-device-storage.md §3.5 / §4.1.
fsyncdir
Package fsyncdir centralizes kojo's directory-fsync recipe: open a directory read-only and Sync it so a preceding rename/unlink is durable across a crash.
Package fsyncdir centralizes kojo's directory-fsync recipe: open a directory read-only and Sync it so a preceding rename/unlink is durable across a crash.
git
migrate
Package migrate is the one-shot v0 → v1 importer described in docs/multi-device-storage.md section 5.
Package migrate is the one-shot v0 → v1 importer described in docs/multi-device-storage.md section 5.
migrate/externalcli
Package externalcli implements docs/multi-device-storage.md §5.5.1's continuity layer for path-hashed external-CLI transcript stores (claude, codex).
Package externalcli implements docs/multi-device-storage.md §5.5.1's continuity layer for path-hashed external-CLI transcript stores (claude, codex).
migrate/importers
Package importers contains the per-domain v0→v1 importers wired into the migrate orchestrator's Register() list.
Package importers contains the per-domain v0→v1 importers wired into the migrate orchestrator's Register() list.
oplog
Package oplog defines the bounded per-agent operation log record format described in docs/multi-device-storage.md §3.13.1.
Package oplog defines the bounded per-agent operation log record format described in docs/multi-device-storage.md §3.13.1.
peer
Package peer manages this kojo binary's peer identity in the multi- device storage cluster (docs/multi-device-storage.md §3.5–§3.7).
Package peer manages this kojo binary's peer identity in the multi- device storage cluster (docs/multi-device-storage.md §3.5–§3.7).
session
Package session is the runtime persistence layer for live PTY sessions (this binary's runtime state).
Package session is the runtime persistence layer for live PTY sessions (this binary's runtime state).
slackbot
Package slackbot provides Slack Socket Mode integration for Kojo agents.
Package slackbot provides Slack Socket Mode integration for Kojo agents.
snapshot
Package snapshot implements docs/multi-device-storage.md §3.6's "snapshot 起点復旧" path: a periodic, atomic point-in-time copy of the Hub's authoritative state that a backup peer can take over.
Package snapshot implements docs/multi-device-storage.md §3.6's "snapshot 起点復旧" path: a periodic, atomic point-in-time copy of the Hub's authoritative state that a backup peer can take over.
store
Package store owns the SQLite database that holds kojo v1's structured state.
Package store owns the SQLite database that holds kojo v1's structured state.
store/secretcrypto
Package secretcrypto implements the envelope encryption used by the kv table's secret rows and (future) by the snapshot path described in docs/multi-device-storage.md §3.5 / §3.6.
Package secretcrypto implements the envelope encryption used by the kv table's secret rows and (future) by the snapshot path described in docs/multi-device-storage.md §3.5 / §3.6.
thumbnail
Package thumbnail generates and caches low-resolution JPEG thumbnails for images on disk.
Package thumbnail generates and caches low-resolution JPEG thumbnails for images on disk.
tts
uploadpath
Package uploadpath centralizes the on-disk location and filename sanitization for user-uploaded attachments so the WebUI upload handler and the Slack file-download path agree byte-for-byte.
Package uploadpath centralizes the on-disk location and filename sanitization for user-uploaded attachments so the WebUI upload handler and the Slack file-download path agree byte-for-byte.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL