CLI + API reference
The human index of everything the kobe binary does. Two machine-readable
surfaces stay authoritative when this page and the binary disagree:
kobe --help: the top-level command list. It is a single tested string (packages/kobe/src/cli/usage.ts); adding a subcommand fails CI until help and completions agree.kobe api schema: the fullkobe apiverb/flag spec as JSON. This is the source of truth for the scriptable surface: names, types, required flags, enum values. Agents should read it once and drill in with--verb <name>instead of parsing this page.
Design rationale (why a CLI instead of MCP) lives in design/cli-api.md, which is historical; the shipped surface outgrew it.
Install + update
Requires Bun ≥ 1.3.11, git, and at least one engine CLI on PATH.
bun install -g @sma1lboy/kobe # install
bunx @sma1lboy/kobe # zero-install trialkobe update is a thin wrapper that delegates to the GitHub-hosted
scripts/update.sh (so install-flow changes ship without a binary release):
kobe update # update to latest
kobe update 0.7.90 # pin an exact version
kobe update list # browse recent versions (TUI when interactive, plain text when piped)
kobe update dry-run # print the command without running it--list / --dry-run are accepted aliases of the verbs. The script updates
with the same package manager that owns the kobe on PATH (bun or npm),
so the new version doesn't land in a shadowed prefix. Manual fallback:
npm install -g @sma1lboy/kobe@latest.
Installing across a version registered as breaking prints a heads-up: the
next launch refuses to start until you run kobe reset (the boot gate is
the enforcement point; worktrees are never touched). kobe update list
marks those versions (breaking — needs kobe reset).
Launching
kobe # launch the TUI (first run: onboarding wizard instead)
kobe . # open a directory as a standalone task — the `code .` gesture
kobe <path> # same, for any path-like argument
kobe web # the browser dashboard on http://localhost:5174An unrecognized subcommand prints usage and exits 2; a typo never silently opens the TUI.
Projects: add / remove / adopt
kobe add [path] # save a repo for the new-task picker (path defaults to .)
kobe remove [path]
kobe adopt [glob] [--repo <path>] [--vendor <v>] [--yes]kobe addrequires a real git repository. It also creates the repo's PROJECTS sidebar row and folds in any existing unlinked git worktrees as tasks (most-recently-active first).kobe add --remote --host <host> --user <user> --path <basePath> [--port N] [--key [path] | --password]registers an SSH-backed project whose worktrees + engine run on the remote host. Experimental; enable Settings → Dev → Experimental → Remote projects first. Auth is one of--key(ssh-agent when the path is omitted) or--password(prompted, stored in the OS keychain, never in state.json).kobe removeis the inverse: forget a saved project. Non-destructive: files, worktrees, branches, and tasks stay on disk; a remote project's stored connection config is dropped. With no match it prints the saved list so you can copy the exact entry.kobe adoptimports existing git worktrees as tasks. No glob → dry-run listing; a glob lists matches (absolute path or basename, e.g.kobe adopt 'feature-*');--yesactually adopts them.
Top-level commands
As rendered by kobe --help:
Usage: kobe [command] [options]
web [options] Launch the browser dashboard
completions <shell> Generate shell completion script (bash/zsh/fish)
add [path] Save a repo path for the new-task picker
remove [path] Forget a saved project (inverse of add; non-destructive)
adopt [glob] Import existing git worktrees as tasks
export [--csv|--json] Print the task list (json/csv/table; daemon-free)
repo <verb> Per-repo init script + first prompt (show|set|unset)
api <verb> Scriptable RPC surface for agents (see `kobe api --help`)
daemon <verb> Manage the daemon (start|stop|status|restart)
doctor [--report] Diagnose daemon/PTY/engines/git; --report writes a bundle
config [--path] Open kobe's config file (state.json) in your editor
reset [--hard] Stop runtimes; optionally wipe task/UI state
theme <verb> Manage user themes (list|add|remove)
skill <verb> Install the kobe agent skill (install|status|command)
plugin <verb> Install and run plugins (install|link|list|action|…)
feedback Send feedback to GitHub Discussions
update [version|list] Self-update kobe, or browse versions with `list`
Options:
-v, --version Print version
-h, --help Print this helpweb
kobe web [--port <n>] [--routes-only] [--no-takeover]Serves the web dashboard through the daemon-hosted HTTP/SSE transport on
:5174 (override with --port), plus a PTY sidecar for browser terminal
tabs. --routes-only starts only the daemon web routes (Vite serves the SPA
separately, for dev). --no-takeover is reserved for compatibility; the
daemon owns the web port. The daemon's web port can also be set (or
disabled with 0/off/false) via KOBE_DAEMON_WEB_PORT.
completions
source <(kobe completions zsh) # zsh
kobe completions bash > ~/.bash_completion.d/kobe # bash
kobe completions fish > ~/.config/fish/completions/kobe.fishCompletes subcommands only (each subcommand owns its own flags).
export
kobe export [--json | --csv | --format <json|csv|table>]Prints the task list from ~/.kobe/tasks.json. Read-only and daemon-free:
it works with the daemon down (complement to kobe api list, which is
JSON-only and needs the daemon). Default is a JSON array of rows with
columns id, title, status, archived, vendor, branch, repo, worktreePath;
--csv emits RFC-4180-style CSV with a header; --format table aligns
columns for humans.
repo
kobe repo show [path]
kobe repo set [path] --init-script <text> | --init-script-file <path>
[--init-prompt <text> | --init-prompt-file <path>]
kobe repo unset [path] [--init-script] [--init-prompt]Manages a repo's per-user init override (state.json), the fallback for
repos that don't ship their own .kobe/init.sh / .kobe/init-prompt.md
(the in-repo files win when present; see AGENTS.md "Per-repo init"). Path
defaults to the current directory, resolved to its git toplevel. unset
with no field flag clears both.
config
kobe config [--path]Opens kobe's user config, ~/.config/kobe/state.json (theme, locale,
engine + editor prefs), in your editor: $VISUAL / $EDITOR, else the
configured editor (Settings → General → Editor), else the first of
nvim / vim / emacs / nano. --path just prints the path. kobe re-reads the
file on next launch; a missing file is seeded as {}.
theme
kobe theme list # bundled + user themes
kobe theme add <source> [--name <name>] [--force] # URL or local theme JSON
kobe theme remove <name>User themes land in ~/.kobe/themes/<name>.json and may shadow a bundled
name. remove refuses bundled (read-only) themes. ls / rm are accepted
aliases.
skill
kobe skill install [--agent NAME] # wraps `npx skills add Sma1lboy/kobe`
kobe skill status
kobe skill command [--agent NAME] # print the npx command without running itInstalls the kobe agent skill, the thing that teaches a coding agent how
to drive kobe api. Default agent: claude-code. kobe doctor reports
the skill as missing/stale and points here.
plugin
kobe plugin install <owner/repo[/subdir]> [--yes] [--ref <rev>]
kobe plugin link <dir> register a local plugin directory (dev)
kobe plugin list installed + linked plugins
kobe plugin search [query] browse the marketplace (GitHub topic kobe-plugin)
kobe plugin outdated check GitHub installs against upstream
kobe plugin update <id…> | --all [--yes] reinstall stale plugins from GitHub
kobe plugin enable <id> | disable <id> toggle without unregistering
kobe plugin unlink <id> unregister a linked plugin (files untouched)
kobe plugin uninstall <id-or-spec> unregister + remove the managed checkout
kobe plugin config-dir <id> print the plugin's config directory
kobe plugin log <id> [-n <count>] tail the plugin's command-run log (default 20)
kobe plugin action list [--plugin <id>] declared actions
kobe plugin action invoke <plugin-id.action-id> [args…]
kobe plugin pane open <plugin-id.pane-id> [--task <task-id>]The registry is ~/.kobe/plugins.json; the daemon's PluginHost watches it,
so changes apply to a running daemon without a restart. Authoring contract:
PLUGIN-AUTHORING.md. Marketplace:
https://github.com/topics/kobe-plugin.
feedback
kobe feedback --title <text> (--body <text> | --body-file <path>) [--category <slug>]Creates a GitHub Discussion in the kobe repo via the gh CLI (requires
gh auth login). --body-file - reads the body from stdin; default
category is feedback.
doctor
kobe doctor [--report]Read-only diagnosis: build + home, terminal env, git, engine CLIs and
account state (claude / codex / copilot), daemon reachability (with
stale-build warning), PTY host inventory, legacy pre-v0.8 tmux sessions,
agent-skill state, and the state files (tasks.json / state.json /
daemon.log / pty-host.log). Never mutates. --report additionally writes a
bug bundle (diagnosis + recent logs + env) to a file and prints its path;
attach it to bug reports. See TROUBLESHOOTING.md.
reset
kobe reset [--hard] [--yes]Recovers a wedged install: stops the daemon (graceful → SIGTERM → SIGKILL)
and removes its socket/pidfile, stops the standalone PTY host (ending all
background terminal/engine sessions), and stops any pre-v0.8 tmux sessions.
Never touches git worktrees. --hard additionally deletes the task
index (~/.kobe/tasks.json) and the UI state (state.json). Interactive
y/N confirmation unless --yes (a non-TTY without --yes prints the
re-run hint and changes nothing).
daemon
kobe daemon status # status JSON (default verb); exit 1 when no daemon runs
kobe daemon start # run the daemon in the FOREGROUND (this process becomes it)
kobe daemon stop # ask the daemon to shut down (exit 0 when none running)
kobe daemon restart # stop, then respawn detachedThe daemon is a long-lived background process, refcounted on attached
GUIs; kobe api and the TUI auto-start it as needed, so start is
mainly for debugging. Logs: ~/.kobe/daemon.log (rotated at boot, one
generation kept as daemon.log.old); read it first when debugging.
After editing daemon/orchestrator/engine code in a checkout, run
kobe daemon restart, since Bun doesn't hot-reload. Mechanics:
design/daemon.md.
Internal subcommands
Not in kobe --help; documented so their behavior isn't a mystery:
kobe pty-host: the standalone PTY host process that owns embedded terminal PTYs so they survive TUI exits and daemon restarts. Spawned detached when a terminal pane needs it; runs in the foreground when invoked by hand. It's a separate process from the daemon precisely sokobe daemon restartnever ends running engine sessions.kobe hook <verb>: fired by an engine's own hooks (installed into e.g.~/.claude/settings.json) to report normalized activity events to the daemon. Contract: always exits 0 and never spawns the daemon; a hook must never fail the engine or resurrect an idle-stopped daemon.kobe hook setupis deprecated (cleanup-only no-op).
kobe api: the scriptable surface
Each invocation is a short-lived process: connect to (or auto-start) the daemon, do the work, print one JSON object to stdout, exit. Read-only verbs marked offline below skip the daemon entirely.
Output + exit-code contract
- Success → one JSON object on stdout, newline-terminated, exit 0.
--prettyindents it (humans only). - Error →
{ "error": { "message", "code", ... } }on stderr. Common rejections additionally carryhintandnextCommandArgs(argv runnable verbatim) so a caller can self-heal without parsing prose. - Exit codes:
0success ·1handler/RPC failure ·2usage errors (unknown verb, bad/missing flag, unreachable daemon) ·3partial fan-out (some tasks created, some failed; the full payload still goes to stdout so created tasks are never lost). kobe api <verb> --helpprints that verb's usage and exits 0.
Flag parsing: --key value and --key=value both work; boolean flags may
be given bare (--force ⇒ true) or explicitly (--archived=false);
--task-id / enum / positive-int values are validated against the verb's
spec, and unknown flags are rejected (exit 2). --repo resolves relative
paths against $PWD (~ expanded). Engine vendors: claude, codex,
copilot, kimi. spawn-task is an alias of add.
Discovery
schema(offline): the API, as JSON. Default is a compact index (groups + verb summaries, no flags); drill in with--verb <name>(full flag detail for one verb),--group <g>, or--all(everything; large). Includes anapiVersionagents can gate on.
read
list: list all tasks (incl. archived). Returns{ tasks }.get-task --task-id <id>: one task's metadata;.running= its hosted engine session is live.collect [--task-ids a,b,c] [--repo PATH]: read-only comparison snapshot of several tasks: identity, branch,.running, uncommitted.changes, and committed.base(ahead count + diffstat vs base).pty-list(offline): hosted PTY sessions (key, alive, pid, command, live window title). Empty when no PTY host runs.read-output [--task-id ID] [--source auto|history|terminal] [--cursor C] [--limit N]: a task's engine output as bounded, cursor-paged JSON: the engine's structured history when available, else a labeled terminal tail (fallbackReason). Read-only; the cursor stays pinned to one source/session and returns a typedSOURCE_CHANGEDerror when it moved.
create
add --repo PATH [--title T] [--branch B] [--base-branch B] [--vendor V] [--status S] [--pin] [--activate] [--prompt TEXT]: create a task (appears in the sidebar immediately). With--promptit also materializes the worktree, starts the engine, and delivers the prompt. Does not steal focus unless--activate. Alias:spawn-task.fan-out --repo PATH --prompt TEXT (--count N | --agents claude:2,codex:1) [--vendor V] [--title T] [--base-branch B]: spawn N tasks of one prompt in a single call (parallel attempts). Capped at 10.
drive
send [--task-id ID] --prompt TEXT: paste a follow-up into a task's running engine (one full turn). Defaults to the active task.dispatch --task-id ID --prompt TEXT: route text into a task's live session via the daemon'ssession.deliverchannel; requires an already-hosted session (the dispatcher's messenger; see design/dispatcher.md).note --task-id ID --text TEXT: file a one-line field note (a resolved, repo-level gotcha); kobe forwards it to the repo's dispatcher session, which relays it to in-flight tasks.set-active [--task-id ID] [--none]: set (or clear) the shared active task every Tasks pane highlights.
supervise
report --outcome succeeded|failed [--task-id ID] [--summary TEXT]: worker-side. Files an EXPLICIT outcome for a task, stored verbatim as itsworkerReport(worker report, not kobe-verified; kobe never infers an outcome). Task defaults to$KOBE_TASK_ID, then the cwd's worktree.await --task-ids a,b,c [--timeout-secs N]: coordinator-side. Blocks (poll-free, on daemon push) until every listed task has a worker report, then returns all outcomes as JSON. A timeout is a checkpoint, not a failure: exit 0 with{ timedOut: true, ... }(default 900 s).
edit
rename --task-id ID --title T: set a task's title.set-branch --task-id ID --branch B: rename a task's branch (git branch -mif materialized, else recorded).set-vendor --task-id ID --vendor V: change the engine vendor (takes effect on next session rebuild).set-status --task-id ID --status S: set lifecycle status:backlog,in_progress,in_review,done,canceled,error.
issues
The daemon-owned issue store (backlog; see
WORK-TRACKING.md). Statuses: open, doing, hold,
done.
issue-list --repo PATH: list a repo's issues.issue-create --repo PATH --title T [--body TEXT]: create an issue.issue-set-status --repo PATH --id N --status S: set an issue's status.issue-update --repo PATH --id N [--title T] [--body TEXT] [--task ID]: edit title/body and/or link a task (kanban: In progress;--task noneunlinks).
lifecycle
archive --task-id ID [--archived=false]: archive/unarchive. Non-destructive: worktree, branch, and history stay.pin --task-id ID [--pinned=false]: pin/unpin a task to the top of the sidebar.land --task-id ID [--strategy merge|squash] [--delete-branch] [--then-archive]: merge a task's branch back into its base repo's current branch (--no-ffmerge, or one squash commit). Refuses a dirty base checkout; on conflict it aborts and returns the conflicted files. Returns{ landedOn, commit }.delete --task-id ID [--force]: permanently remove a task and its worktree. Destructive; preferarchive. Needs--forceon a dirty worktree.
worktree
ensure-worktree --task-id ID: materialize a task's git worktree on disk now (without starting an engine). Returns{ worktreePath }.discover-adoptable --repo PATH: list existing git worktrees not yet tracked as kobe tasks.adopt --repo PATH --worktree PATH [--branch B] [--vendor V] [--title T]: import an existing git worktree as a kobe task.
feedback + other
feedback --title T --body TEXT [--category SLUG](offline): create a GitHub Discussion in the kobe repo's Feedback category viagh.notify --title TEXT [--kind KIND] [--task-id ID] [--source TAG]: show a toast in every attached kobe UI.done/needs_input/errorget severity styling; any other kind renders neutrally.prompt --title TEXT [--placeholder T] [--initial T] [--timeout MS]: ask the human for a line of text through the attached TUI's input dialog; blocks until answered/cancelled/timeout (default 120000 ms, max 600000) and returns{ value }or{ cancelled, reason }.
Exit codes + output conventions (whole CLI)
There is no global exit-code registry; the conventions that hold across the binary:
- 2: malformed invocation everywhere: unknown command/verb/flag, missing required value. The error always comes with usage text.
- 1: runtime failure (
kobe addon a non-repo,kobe configwith no editor,kobe daemon statuswith no daemon, plugin errors, ...). - 0: success, including "already in the requested state" (
daemon stopwith no daemon) andkobe api awaittimeouts.kobe hookexits 0 unconditionally. kobe apiis the only JSON-first surface (stdout JSON on success, JSON error envelope on stderr). Other subcommands print human text; machine-readable task data without a daemon is whatkobe export --jsonis for.kobe daemon statusprints status JSON when the daemon is up.
Environment variables + state paths
Env vars the binary respects (accessor home: packages/kobe/src/env.ts):
KOBE_HOME_DIR: override the home kobe persists under (everything below moves with it); used by tests and the dev sandbox.KOBE_DAEMON_WEB_PORT: daemon web transport port (default 5174;0/off/falsedisables it).KOBE_WEB_HOST,KOBE_DAEMON_WEB_STATIC_DIR: web transport host / static dir overrides.KOBE_DEV=1: declares a developer checkout (suppresses the update-available chip).KOBE_DEBUG=1: print full startup errors instead of the one-line message.KOBE_TASK_ID/KOBE_TAB_ID: exported into engine tabs; hooks andkobe api reportresolve their task from these.
State layout (defaults; all under KOBE_HOME_DIR when set):
~/.kobe/: task index (tasks.json), worktrees (worktrees/<repo-key>/<task-slug>/), daemon socket/pidfile/daemon.log, PTY host socket/pidfile/pty-host.log, plugins (plugins.json,plugins/<id>/), user themes (themes/), settings (settings/keybindings.yaml).~/.config/kobe/state.json: the KV user configkobe configopens.