npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@octos-org/octos-tui

v0.2.1

Published

Terminal UI client for the Octos UI Protocol

Readme

octos-tui

██████╗ ██████╗████████╗ ██████╗ ███████╗ ██╔═══██╗██╔════╝╚══██╔══╝██╔═══██╗██╔════╝ ██║ ██║██║ ██║ ██║ ██║███████╗ ██║ ██║██║ ██║ ██║ ██║╚════██║ ╚██████╔╝╚██████╗ ██║ ╚██████╔╝███████║ ╚═════╝ ╚═════╝ ╚═╝ ╚═════╝ ╚══════╝ Welcome to Octos — Your Coding Buddy

octos-tui is the terminal app for Octos — an AI coding assistant in your terminal, in the spirit of Claude Code and Codex. The Octos server runs the agent, the models, and the tools; octos-tui is the fast, keyboard-driven way to talk to it: chat, diffs, tool approvals, background tasks — all without leaving the shell.

Start here

Two pieces: the Octos server (the brain) and this TUI (the terminal client). One command installs both:

npm install -g @octos-org/octos @octos-org/octos-tui
# or with Homebrew (each repo is its own tap):
#   brew tap octos-org/octos     https://github.com/octos-org/octos
#   brew tap octos-org/octos-tui https://github.com/octos-org/octos-tui
#   brew install octos-org/octos/octos octos-org/octos-tui/octos-tui

Then start the TUI with its own private local server:

octos-tui --mode protocol \
  --stdio-command "octos serve --stdio --solo --data-dir ~/.octos-tui-data"

You'll land on the "Welcome to Octos" screen. In the next five minutes: create your local profile (three fields — the email is local metadata only), pick an AI provider, paste its API key, and open your first coding chat. The Quickstart below walks every screen.

Heads-up: plain octos-tui with no flags opens a mock demo with canned replies — nice for a look around, but not connected to anything. Use the command above for the real thing.

If something looks wrong

| Symptom | Fix | |---|---| | command not found: octos | The server isn't installed — npm install -g @octos-org/octos (or the server install guide). | | Replies are instant and feel canned | You're in mock mode (no flags). Start with the --stdio-command ... command above. | | "Test provider" fails during onboarding | Re-check the API key and the provider choice; you can redo it anytime with /onboard or /setup. |

More in the full Troubleshooting table below.


On a fresh first launch the main window shows the OCTOS block-letter wordmark with the tagline "Welcome to Octos — Your Coding Buddy" above a short onboarding menu — your starting point for the walkthrough below.

octos-tui is intentionally separate from octos-cli: the octos repo owns the server/runtime and the shared octos-core protocol types; this repo owns the terminal client. Architecture and ownership boundaries live in docs/ARCHITECTURE.md.


Install

Every method installs a single self-contained octos-tui binary. Then run octos-tui --help.

Prebuilt binary — no Rust toolchain needed (recommended)

Same model as Claude Code and Codex: each GitHub Release ships prebuilt binaries for macOS (Apple Silicon), Linux (x86-64 + arm64), and Windows (x86-64), distributed via:

# npm
npm install -g @octos-org/octos-tui

# Homebrew (this repo is its own tap)
brew tap octos-org/octos-tui https://github.com/octos-org/octos-tui
brew install octos-org/octos-tui/octos-tui

# shell installer (macOS / Linux)
curl --proto '=https' --tlsv1.2 -LsSf \
  https://github.com/octos-org/octos-tui/releases/latest/download/octos-tui-installer.sh | sh

# PowerShell installer (Windows)
powershell -ExecutionPolicy Bypass -c "irm https://github.com/octos-org/octos-tui/releases/latest/download/octos-tui-installer.ps1 | iex"

Once installed, octos-tui update checks for a newer release — and for shell/PowerShell-installer installs it self-updates in place; npm/brew/cargo installs are owned by their package manager, so it prints the matching upgrade command instead. octos-tui doctor diagnoses the local environment and connection prerequisites.

From source with Cargo (needs Rust 1.85+)

# straight from git — no crates.io publish required
cargo install --git https://github.com/octos-org/octos-tui octos-tui

# or, once published to crates.io
cargo install octos-tui

octos-core (the shared protocol crate) is pulled automatically as a git dependency, so installing needs no sibling octos checkout.


Quickstart: solo onboarding

A copy-pasteable, first-time walkthrough. By the end you have a local profile, an LLM provider, and a live coding session — no dashboard, no email OTP.

1. Install the binaries

Install the TUI and the server as shown in Start here — the npm and brew routes install both pieces. (The shell/PowerShell installers in Install ship the TUI only; pair them with a server install from the octos repo.)

Building from source works too — octos-core (the shared protocol crate) is pulled automatically as a git dependency, so a plain clone builds with no sibling checkout required (needs Rust 1.85+):

git clone https://github.com/octos-org/octos-tui.git
cd octos-tui
cargo build --release
# produces ./target/release/octos-tui — substitute it for `octos-tui` below

Developing against a local octos? To build against an uncommitted sibling ../octos/crates/octos-core instead of the pinned git revision, run cp .cargo/config.toml.example .cargo/config.toml (gitignored) — see the comment in that file. This restores the live-sibling edit loop of the old path dependency.

2. First run → the welcome screen

For a true first run, spawn an octos serve --stdio backend with a fresh, empty data directory and pass no --profile-id. The TUI launches the server as a child process over stdio, so you only run one command:

octos-tui \
  --mode protocol \
  --stdio-command "octos serve --stdio --solo --data-dir ./octos-data"

You land on the "Welcome to Octos" screen (subtitle "Set up a local solo profile to continue."), with the OCTOS wordmark above the menu.

Notes:

  • --solo and --data-dir are arguments to the spawned octos serve --stdio child, not octos-tui flags.
  • Use a brand-new --data-dir; an existing one may already have a profile and skip the welcome screen.
  • Do not pass --profile-id on first run — it selects an existing profile and bypasses onboarding.

3. Create your local profile

On the welcome screen, fill the three fields (the email is local metadata only — no OTP is sent):

| Field | How to enter it | |---|---| | Full name | select the row and type, or /onboard name <your name> | | Username | select the row and type, or /onboard username <handle> | | Email | select the row and type, or /onboard email <address> |

Then choose "Create your local Octos profile" / Continue. This calls profile/local/create and advances to provider setup.

4. Set up an LLM provider

The screen now reads "Set Up LLM Provider" ("Choose a dashboard model route, enter its API key, then save."). Work down the rows:

  1. Load provider catalog — pulls the dashboard's model families and routes.
  2. Model family → Model → Provider route — pick one route.
  3. API key — select the row and type the key (/onboard key <secret>); it is masked in state, logs, and snapshots.
  4. (optional) Test provider to verify the route.
  5. Save provider to profile — persists it via profile/llm/upsert (the same profile JSON the dashboard writes).

The catalog and provider schema are owned by octos/the dashboard; the TUI never hard-codes provider/model truth.

5. Open a coding session and chat

Once a provider is saved, choose "Open coding session". This calls session/open with the resolved profile and drops you into the normal coding UI. Type a request in the composer and press Enter — you're chatting with Octos.

You can reopen this wizard at any time with the /setup slash command.


Other ways to run

Connect to a running octos serve over WebSocket

If a server is already running (locally or remote), connect over its UI Protocol WebSocket instead of spawning a child. Start the server from the sibling repo:

cd ../octos
export OCTOS_AUTH_TOKEN=local-dev-token
cargo run -p octos-cli --features api --bin octos -- serve \
  --host 127.0.0.1 --port 50080 \
  --cwd "$PWD" \
  --data-dir /tmp/octos-tui-dev-data \
  --auth-token "$OCTOS_AUTH_TOKEN"

Then connect in another terminal:

octos-tui \
  --mode protocol \
  --endpoint ws://127.0.0.1:50080/api/ui-protocol/ws \
  --auth-token local-dev-token \
  --cwd "$PWD/my-project"

Use the same token for --auth-token on both sides (or set OCTOS_AUTH_TOKEN). Add --profile-id <id> to open an existing profile and skip onboarding; add --readonly for a view-only session that never sends turns.

Mock mode (no server)

For render/keyboard/theme smoke tests with no backend at all:

cargo run -- --mode mock
cargo run -- --mode mock --theme claude

--mode mock is also the default when no --endpoint/--stdio-command is given.


Reference

CLI flags

--config <json-file>     JSON launch config; CLI flags override its values
--mode mock|protocol     mock (no server) or protocol (live). Default: mock
--endpoint <ws-url>      UI Protocol WebSocket (ws:// or wss://)
--stdio-command "<cmd>"  spawn an `octos serve --stdio` child instead of --endpoint
--session <session-id>   session to open first
--profile-id <id>        existing profile to use (skips onboarding)
--cwd <dir>              workspace cwd to request; defaults to the launch dir
--auth-token <token>     bearer token; falls back to OCTOS_AUTH_TOKEN
--readonly / --no-readonly   open as a view-only session, or force read-write
--theme <name>           codex | claude | slate | solarized | terminal
--lang en|zh             UI language; falls back to OCTOS_LANG / LANG. Default: en
--scroll-mode <mode>     native (terminal scrollback, default) | pinned (composer pinned)
--vim-mode               enable Vim modal editing in the composer (default off)

--endpoint and --stdio-command are mutually exclusive — pick one transport. Do not put provider or model anywhere: those are server-owned Octos settings loaded by octos serve, and the TUI config rejects them.

Config file

--config FILE reads JSON launch defaults (CLI flags win on conflict):

{
  "mode": "protocol",
  "stdio_command": "octos serve --stdio --solo --data-dir ./octos-data",
  "session": "coding:local:main",
  "profile_id": "coding",
  "cwd": "/path/to/project",
  "readonly": false,
  "theme": "codex",
  "lang": "en",
  "scroll-mode": "native",
  "vim-mode": false
}

/saveconfig writes the active theme / lang / scroll-mode / vim-mode back into this file (merging — it never clobbers transport keys like stdio_command); without --config it falls back to ~/.config/octos-tui/config.json.

Themes

codex, claude, slate, solarized, terminal

terminal keeps foreground/background on your terminal defaults where ratatui allows it, using only restrained ANSI colors for borders, accents, and errors.

Set the palette at launch with --theme <name>, or switch live with /theme (a *-marked menu; the change repaints immediately and survives reconnects).

In-session keys and slash commands

Tab        switch to the inspector pane (Esc returns to chat)
PgUp/PgDn  scroll the transcript (PgUp also opens the pager)
y / s / n  approve once / approve for session / deny a pending tool approval
Alt+A      re-show the pending approval prompt
[ / ]      select previous / next inline diff hunk
c          stage the selected hunk as next-turn context
Ctrl+U     clear the composer
Ctrl+C     interrupt the active turn
Esc        with no active turn: cancel the first running background task
q          quit
/help       local slash-command help
/ps         show local task/process status and focus the Tasks pane
/stop       interrupt the active turn (or report locally if none is active)
/setup      reopen the onboarding wizard
/model      browse the server-returned profile models / catalog
/theme      switch the TUI palette at runtime (menu, or /theme claude)
/lang       switch the UI language (menu, or /lang zh) — English / 中文
/thinking   set reasoning effort for thinking models, per session (menu, or /thinking high)
/scrollmode switch wheel-scroll behavior (toggle, or /scrollmode native|pinned)
/vimmode    toggle Vim modal editing in the composer (Normal/Insert)
/saveconfig persist the active theme / language / scroll-mode / vim-mode to the config file
/onboard    set onboarding fields inline (name, username, email, key, ...)
/copy       copy the last assistant reply to the clipboard (works over SSH)
/status     snapshot-backed session, runtime, and connection status
/cost       server-reported token and cost usage
/title      configure terminal-title items
/keymap     inspect and edit TUI key bindings
/login      sign in with email OTP, or inspect current auth state
/exit       quit the TUI

Sessions and autonomy (shown when the server advertises the capability):

/resume     switch to a prior session and reload its transcript (alias: /sessions)
/rewind     go back to an earlier checkpoint in this session to edit & resend (alias: /backtrack)
/loop       create, list, pause, resume, fire-now, or delete backend loops
/goal       view, set, pause, resume, or clear the persisted session goal

/resume lists sessions newest-first; /rewind shows codex-style checkpoint rows (#n message preview) and rolls the session back to the one you pick, so you can edit and resend from there. When a session has loops, the status bar shows a loop chip (active/paused), and the context gauge reflects the real per-model context window reported by the server, not a fixed default.

/activity (search sessions/tasks/activity) and /statusline (status-bar items) are always available. Further capability-gated commands (/provider, /permissions, /mcp, /tools, /skills, /task, /threads, /turn, /agents, /review) appear in the / popup only when the connected server supports them — /help always lists what is live.

/model, /theme, /lang, and /thinking open a selection menu when run with no argument (or apply inline with an arg). In every selection menu the active choice is marked with a leading * (distinct from the > navigation cursor).

Slash-command completion is two-step, like Codex: pick an entry from the / popup (or type a prefix and press Enter) and the full /command lands in the composer; press Enter again to run it (or type an argument first). Typing a command's exact name and pressing Enter runs it directly. This is uniform for every command.

Unknown slash commands are handled locally with a warning and are not sent to the model.

Composer editing

The composer is multi-line: Enter sends, Shift+Enter (or Ctrl+J as a portable fallback) inserts a newline, and the box grows as you add lines.

Arrow Up from an empty composer recalls your command history — newest first, persisted across sessions, shell-style; once browsing, Down steps back toward newer entries. With text present the arrows move the cursor between lines (and fall back to scrolling the transcript at the first/last line). Emacs-style keys also work (Ctrl+A/E, Alt+B/F, Ctrl+W, Ctrl+K, …).

Vim mode is opt-in — --vim-mode, config "vim-mode": true, or /vimmode at runtime; the composer title then shows NORMAL / INSERT. It implements a pragmatic subset:

motions   h l j k   0 $   w b e   gg G
edits     x   dd   dw   cc
insert    i a A I o O      (Esc returns to Normal)

Enter still sends in both modes. Visual mode, registers/yank-paste, and numeric counts (3dd) are out of scope.

Scrolling and the transcript pager

By default (native scroll-mode) the wheel scrolls the terminal's own scrollback, so native selection/copy stay intact and the composer scrolls away with the screen. Press Ctrl+T (or PageUp) to open a full-screen transcript pager where history scrolls in the upper pane while the composer stays pinned to the bottom; Esc (or Ctrl+T again) closes it.

--scroll-mode pinned (or /scrollmode pinned) opts into app-side wheel handling: the wheel always scrolls the transcript and the composer never moves, at the cost of native mouse selection (use Shift+drag). Settled tool-activity groups collapse to a one-line summary; Ctrl+O expands them — the same toggle also expands the diff preview's selected hunk in full.

Markdown rendering

Assistant replies render markdown live as they stream: headings, lists, checkboxes, blockquotes, tables, fenced code blocks with syntax highlighting (theme-matched, following /theme), inline bold/italic/code, ~~strikethrough~~, --- rules, and [links](url). Link urls render in full so the terminal can make them cmd/ctrl+clickable in the native scroll flow.

While a thinking model reasons, the transcript shows a terse codex-style · thinking… indicator instead of the verbose reasoning stream; the reply replaces it when the answer starts. Control the effort with /thinking.

Languages (i18n)

The UI is fully localized in English and Simplified Chinese (中文) — menus, the command palette, the onboarding wizard, transcript/status surfaces. Pick the language at launch with --lang {en,zh} (or OCTOS_LANG / LANG), or switch at runtime with /lang (a *-marked menu) — no restart needed. English is the source/fallback locale, so any untranslated string falls back to English.

Environment variables

| Variable | Purpose | |---|---| | OCTOS_AUTH_TOKEN | Fallback bearer token for the UI Protocol WebSocket. | | OCTOS_LANG / LANG | UI language fallback when --lang is unset. | | RUST_LOG=off | Keeps terminal output clean for live visual runs. | | TERM=xterm-256color | Avoids missing terminfo/color issues on remote hosts. | | OCTOS_TUI_BIN | Forces a specific built octos-tui binary for harnesses. | | OCTOS_TUI_DIR | Points Octos harness scripts at this standalone TUI repo. |

Workspace (cwd) behavior

octos-tui requests a session cwd through session/open. By default that is the terminal launch directory; --cwd DIR overrides it. octos serve canonicalizes the requested path and accepts it only if it is inside the server-approved roots — so start the server with a --cwd that contains the project you want to work in. For a remote server, pass a --cwd that exists on the server host. An out-of-bounds cwd fails session/open with a typed protocol error instead of silently running tools elsewhere.

Provider changes after the server is running

The AppUi backend agent is created when octos serve starts. If you add or change the provider/model after the server is already up (via the dashboard or a hand-edited profile), restart octos serve before opening a new coding session.

Troubleshooting

| Symptom | Fix | |---|---| | octos-core dependency not found | Keep octos and octos-tui as sibling directories. | | Welcome screen never appears | Use a fresh empty --data-dir and omit --profile-id. | | Endpoint rejected | Use a ws:// or wss:// URL; HTTP URLs are rejected. | | Auth failure | Use the same token on octos serve --auth-token and the TUI (--auth-token or OCTOS_AUTH_TOKEN). | | TUI opens but no live answer | Confirm the server has a provider/model/key and restart it after config changes. | | Wrong workspace | Start octos serve with the desired --cwd. | | can't find terminfo database | Set TERM=xterm-256color or install terminfo on the host. | | Raw logs/timestamps in the UI | Start both server and TUI with RUST_LOG=off. | | target lock or permission error | Run with CARGO_TARGET_DIR=/tmp/octos-tui-target. |


Testing and harnesses

Run the unit/integration suite (mock-backed, no server needed):

cargo test
# CARGO_TARGET_DIR=/tmp/octos-tui-target cargo test   # on shared/locked hosts

Heavier live and visual harnesses live alongside the code:

  • scripts/run-onboarding-tmux-soak.sh — reference end-to-end onboarding flow: starts a server, launches the TUI, and waits for the "Welcome to Octos" splash. See docs/ONBOARDING_TMUX_SOAK.md.
  • The tmux AppUi smoke and live Codex-parity harnesses live in the sibling octos repo (they start both the server and the TUI); point them at this repo with OCTOS_TUI_DIR="$PWD/../octos-tui".

For release packaging, pin octos-core to the matching Octos git tag or published crate version instead of the sibling path.


Protocol contract

octos-tui consumes Octos UI Protocol fields from octos-core and must not invent local wire extensions. Any protocol change must land through a formal UI Protocol change request with shared types, server tests, golden protocol tests, and TUI reducer/rendering tests.

In protocol mode the TUI requests pane.snapshots.v1 and hydrates optional pane data from session/open.panes when the server supports it, falling back to session snapshots, task tails, launch target, and status otherwise.

Auth, onboarding, and profile LLM provider setup are governed by UPCR-2026-016 in the octos repo. The TUI consumes auth/*, profile/local/create, profile/llm/*, and config/capabilities/list as server-owned AppUI methods over WebSocket or stdio; it never hard-codes provider/model truth or persists a parallel LLM registry. The current v1 bridge stages selected diff context as prompt text — structured context attachments are tracked in docs/M9_31_CONTEXT_ATTACHMENTS_UPCR.md.