masakirocorp

hako

"Control hako from inside it. Manage workspaces and tabs, split panes, spawn agents, read output, and wait for state changes — all via CLI commands that talk to the running hako instance over a local unix socket. Use when running inside hako (HAKO_ENV=1)."

masakirocorp 0 Updated 2w ago

Resources

12
GitHub

Install

npx skillscat add masakirocorp/hako

Install via the SkillsCat registry.

SKILL.md

hako — agent skill

before using this skill, check that HAKO_ENV=1. if it is not set to 1, say you are not running inside a hako-managed pane and stop. do not inspect or control the focused hako pane from outside hako.

you are running inside hako, a terminal-native agent multiplexer. hako gives you workspaces, tabs, and panes — each pane is a real terminal with its own shell, agent, server, or log stream — and you can control all of it from the cli.

this means you can:

  • see what other panes and agents are doing
  • create tabs for separate subcontexts inside one workspace
  • split panes and run commands in them
  • start servers, watch logs, and run tests in sibling panes
  • wait for specific output before continuing
  • wait for another agent to finish
  • spawn more agent instances

the hako binary is available in your PATH. its workspace, tab, pane, and wait commands talk to the running hako instance over a local unix socket.

if you need the raw protocol or full api reference, read the socket api docs.

concepts

workspaces are project contexts. each workspace has one or more tabs. unless manually renamed, a workspace's label follows the first tab's root pane — usually the repo name, otherwise the root pane's current folder name.

tabs are subcontexts inside a workspace. each tab has one or more panes.

panes are terminal splits inside a tab. each pane runs its own process — a shell, an agent, a server, anything.

agent status is detected automatically by hako. the api exposes one public field for it:

  • agent_statusidle, working, blocked, done, unknown

done means the agent finished, but you have not looked at that finished pane yet.

plain shells still exist as panes, but hako's sidebar agent section intentionally focuses on detected agents rather than listing every shell.

ids — workspace ids look like 1, 2. tab ids look like 1:1, 1:2, 2:1. pane ids look like 1-1, 1-2, 2-1. these are compact public ids for the current live session.

important: ids can compact when tabs, panes, or workspaces are closed. do not treat them as durable ids. re-read ids from workspace list, tab list, pane list, or create/split responses when you need a current id. do not guess that an older 1-3 is still the same pane later.

discover yourself

see what panes exist and which one is focused:

hako pane list

the focused pane is yours. other panes are your neighbors.

list workspaces:

hako workspace list

list sidebar groups:

hako group list

tab management

list tabs in the current workspace:

hako tab list --workspace 1

create a new tab:

hako tab create --workspace 1

without --label, the new tab keeps the default numbered tab name.

create and name it in one step:

hako tab create --workspace 1 --label "logs"

rename it:

hako tab rename 1:2 "logs"

focus it:

hako tab focus 1:2

close it:

hako tab close 1:2

read another pane

see what is on another pane's screen:

hako pane read 1-1 --source recent --lines 50
  • --source visible = current viewport
  • --source recent = recent scrollback as rendered in the pane
  • --source recent-unwrapped = recent terminal text with soft wraps joined back together

split a pane and run a command

split your pane to the right and keep focus on your current pane:

hako pane split 1-2 --direction right --no-focus

that prints json with the new pane nested at result.pane.pane_id. parse that value, then run a command in that pane:

NEW_PANE=$(hako pane split 1-2 --direction right --no-focus | python3 -c 'import sys,json; print(json.load(sys.stdin)["result"]["pane"]["pane_id"])')
hako pane run "$NEW_PANE" "npm run dev"

split downward instead:

hako pane split 1-2 --direction down --no-focus

wait for output

block until specific text appears in a pane. useful for waiting on servers, builds, and tests.

for --source recent, matching uses unwrapped recent terminal text, so pane width and soft wrapping do not break matches. pane read --source recent still shows the pane as rendered. if you want to inspect the same transcript that the waiter matches, use pane read --source recent-unwrapped.

hako wait output 1-3 --match "ready on port 3000" --timeout 30000

with regex:

hako wait output 1-3 --match "server.*ready" --regex --timeout 30000

if it times out, exit code is 1.

wait for an agent status

block until another agent reaches a specific status:

hako wait agent-status 1-1 --status done --timeout 60000

use this when you want the same done / idle distinction the UI shows.

send text or keys to a pane

send text without pressing Enter:

hako pane send-text 1-1 "hello from claude"

press Enter or other keys:

hako pane send-keys 1-1 Enter

pane run sends the text and then a real Enter key in one request:

hako pane run 1-1 "echo hello"

workspace management

groups are sidebar filters inside the current session. they do not create separate hako server sockets.

create and focus a group:

hako group create "client work"
hako group focus 2

create a new workspace:

hako workspace create --cwd /path/to/project

without --label, the new workspace keeps the default cwd-based name.

create and name one in one step:

hako workspace create --cwd /path/to/project --label "api server"

create one without focusing it:

hako workspace create --no-focus

focus a workspace:

hako workspace focus 2

move a workspace to a group:

hako workspace move-to-group 2 1

rename:

hako workspace rename 1 "api server"

close:

hako workspace close 2

close a pane

hako pane close 1-3

recipes

run a server and wait until it is ready

NEW_PANE=$(hako pane split 1-2 --direction right --no-focus | python3 -c 'import sys,json; print(json.load(sys.stdin)["result"]["pane"]["pane_id"])')
hako pane run "$NEW_PANE" "npm run dev"
hako wait output "$NEW_PANE" --match "ready" --timeout 30000
hako pane read "$NEW_PANE" --source recent --lines 20

run tests in a separate pane and inspect the result

hako pane split 1-2 --direction down --no-focus
hako pane run 1-3 "cargo test"
hako wait output 1-3 --match "test result" --timeout 60000
hako pane read 1-3 --source recent --lines 30

check what another agent is working on

hako pane list
hako pane read 1-1 --source recent --lines 80

watch another pane robustly

use this pattern when you need to coordinate with a sibling pane:

# inspect what is already there
hako pane read 1-3 --source recent --lines 40

# wait only for the next output you expect
hako wait output 1-3 --match "ready" --timeout 30000

# if you need to inspect the same transcript the waiter matched,
# read the unwrapped recent text directly
hako pane read 1-3 --source recent-unwrapped --lines 40

spawn a new agent and give it a task

hako pane split 1-2 --direction right --no-focus
hako pane run 1-3 "claude"
hako wait output 1-3 --match ">" --timeout 15000
hako pane run 1-3 "review the test coverage in apps/hako/src/api/"

coordinate with another agent

hako wait agent-status 1-1 --status done --timeout 120000
hako pane read 1-1 --source recent --lines 100

notes

  • workspace list, workspace create, tab list, tab create, tab get, tab focus, tab rename, tab close, pane list, pane get, pane split, wait output, and wait agent-status print json on success.
  • pane read prints text, not json.
  • pane read --format ansi or pane read --ansi returns a rendered ANSI snapshot for TUI feedback loops.
  • pane read --source recent-unwrapped is useful when you want to inspect the same unwrapped transcript that wait output --source recent matches against.
  • pane send-text, pane send-keys, and pane run print nothing on success.
  • parse ids from workspace create, tab create, and pane split responses when you need new ids. workspace create returns result.workspace, result.tab, and result.root_pane. tab create returns result.tab and result.root_pane. for pane split, the new pane id is at result.pane.pane_id.
  • use pane read for current output that already exists. use wait output for future output you expect next.
  • --no-focus on split, tab create, and workspace create keeps your current terminal context focused.
  • without --label, workspace create keeps cwd-based naming and tab create keeps numbered naming.
  • --label on tab create and workspace create applies the custom name immediately.
  • if you are running inside hako, the HAKO_ENV environment variable is set to 1.

Categories