neuron-explorer
Qwen3.5‑4B 전용 조향형 뉴런 탐색기, 모든 MLP 뉴런을 밀어 결과를 보관·탐색
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Build agents with agents, in one tmux window. Several coding-agent sessions side by side, each in its own git worktree, plus a shell, a file editor that follows it, and a chat pane wired to the agent you built. Claude Code, Codex or any CLI. Close the window and nothing dies. ~850 lines of zsh, no daemon.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Several agents. One window.
Each one in its own git worktree. The one that has stopped and is waiting on you
says so, on its own border, without being asked.
Several coding agents side by side, each in its own git worktree, plus shells
and a file editor, in one window. "Your turn" and how full each context
window is, right on the border. Claude Code out of the box, Codex, a local
model, or any other CLI — one more line in OFFICE_AGENTS.
The product page ·
Our other tools ·
What we do for companiesREADME 전문 보기 ↗A whole agent developer setup, out of one box.
Agent Office is a small, opinionated distribution of the tools one developer
uses every day to run several coding agents at once: herdr for the
terminal, Firstmate to supervise the agents, treehouse for their git
worktrees, the kunchenguid tools around them, and a context meter and
visual preset that make it all readable at a glance. One private config file.
One office command to install, start, stop and update the lot.
The product page · Getting started · Every key · Contributing
spaces │ 1 2 +
○ api │┌───────────────────────┐┌──────────────────────┐
main ││ Firstmate ││ a worker │
· website ││ ││ │
main ││ ││ │
─────────────────────────────────││ ││ │
agents ││ ││ │
○ api ││ ││ │
firstmate · 88k · 3m · idle ││ ││ │
89% · main ││ ││ │
● api ││ ││ │
claude · 412k▲ · blocked ││ ││ │
89% · #109 · fix/login │└───────────────────────┘└──────────────────────┘
On the left you see every agent: its state from herdr, and from the Agent Office meter how full its context is, how long it has been quiet, how much of your plan's quota is left, and the branch and open pull request it works on. Amber means "this needs you". Shift+arrow walks you there. No mouse.
You need macOS or Linux, git, Node 22.19 or newer, and a coding agent you installed and signed in to yourself (Claude Code or Codex).
git clone https://github.com/ZyxWorks/agent-office ~/agent-office && ~/agent-office/bin/office setup
It asks four questions, installs the tools you lack, clones Firstmate, writes the office and the agent working setup, and checks the result. Every step shows what it changes first and asks before it installs anything or changes a file of yours. It never asks for a token, an account, a name or an email address. Run it again any time: a step with nothing to do says so.
Then:
office on # open the office and its Firstmate
office break # walk away. Everything keeps running
office on # come back
office off # go home. Firstmate saves its work first, then the office stops
Getting started has every step, and what to do when one fails.
Agent Office 1.0 is the herdr-first version. Every command in this README works today, and each has a probe that CI runs on macOS and Linux.
office doctor and office update report a Firstmate revision or
treehouse version with no tested run as not tested and exit 1. The office
starts and runs either way.office off and workers. It refuses while an agent is still working or
waiting, and names it. --stop-workers drains only Firstmate's own workers,
through Firstmate's control plane: an agent Firstmate has no task record for
is yours to stop.Running three or four coding agents at once is normal now. The tools for it exist, and they are good: herdr runs the panes and knows each agent's state, Firstmate supervises a fleet of workers, treehouse hands each one a warm git worktree. But each is its own install, its own config and its own update, and wiring them together into a daily setup lived in one person's dotfiles.
Agent Office packages that wiring, so anyone can have the same setup with one install and one config, and so the wiring gets tested instead of copied.
It does not rewrite any of those tools. Each one stays independently maintained upstream. Agent Office owns only:
Two profiles. core is the office. workstation is optional.
| component | what it does | owner |
|---|---|---|
| herdr | terminal sessions, panes, tabs, and each agent's native state (working, idle, done, blocked) | herdr upstream |
| Agent Office herdr preset | keys for an office with no mouse, sidebar, theme and a silent "done" sound, plus an optional WezTerm example with Mac text keys | this repo (preset/) |
| Agent Office meter | a herdr plugin that shows how full each agent's context window is, its transcript age, the quota left on its provider, and its git branch and open PR, in the sidebar. It also carries the Shift+arrow keys | this repo (herdr/) |
| Agent Office editor pane (optional) | an editor next to an agent, in its worktree: nvim with a small config (file tree, fuzzy find, git signs, the office colours, the files the agent changed), or your own $EDITOR. Off by default. Its two nvim plugins are checked out at pinned commits | this repo (editor/); the plugins, their authors |
| Firstmate | supervises coding agents: dispatch, status, review, cleanup | Firstmate upstream |
| treehouse | a pool of pre-warmed git worktrees, one per worker | treehouse upstream |
| kunchenguid tools | no-mistakes, gh-axi, chrome-devtools-axi, lavish-axi, quota-axi, tasks-axi, gnhf, backpass | their upstreams |
| other agent tools |
jq is also required: the meter reads transcripts with it. The office
command needs python3, 3.8 or newer; the one macOS ships is enough. The
Node-based tools need Node 22.19 or newer with npm, which you install yourself
(with fnm, say). office tools installs every
tool in this table that is missing: see
What office tools installs.
Generic command-line tools that make the terminal pleasant but that the office
does not need to run: git, fnm, ripgrep, fd, fzf, bat, eza,
tree, git-delta, lazygit, zoxide, starship, micro, neovim,
btop, htop, shellcheck, shfmt, uv, wget, tmux and WezTerm, all
from Homebrew. office tools --workstation installs the ones you lack, after
showing the list. Nothing personal is in it: no apps, accounts, fonts or
editor extensions. Those stay in your own dotfiles.
Agent Office never installs or signs you in to an agent itself. Claude Code, Codex and any other harness are installed and authenticated by you, through their own setup.
All of it is driven by one private file:
~/.config/agent-office/config.toml
office install writes a starter the first time and checks the file on every
run. The keys, with the release defaults
(config/defaults.toml):
schema = 1
[office]
session = "office" # the herdr session this office owns
[firstmate]
source = "<public-upstream-or-your-fork>"
code = "<local-code-checkout>"
home = "<private-operational-home>"
harness = "claude"
[treehouse]
# root = "<local-pool-root>" # optional; treehouse's own default otherwise
[open]
roots = [] # say ["~/code"]: office open offers the checkouts in it
[meter]
enabled = true
interval_seconds = 30
warn_tokens = 200000
alarm_tokens = 600000
[herdr.ui] # passed through to herdr as-is
agent_panel_sort = "spaces"
What each part does:
| keys | what it does |
|---|---|
schema | required, must be 1 |
[herdr] | merged over the preset into the generated herdr config. herdr itself checks it |
[open] | roots: folders whose git checkouts office open offers next to Firstmate's projects, say ["~/code"]. Only the folders directly inside each root are looked at. Empty by default |
[dictate] | push-to-talk dictation, off by default and local only: enabled, model (the whisper.cpp model file you downloaded), language ("auto" or a code such as "en") and max_seconds (120). Used by office dictate and prefix+m. See Dictation |
[editor] | the editor pane, off by default: enabled, command (the editor; else $VISUAL, $EDITOR, then nvim), office_config (nvim gets the office's config, true) and split ("right" or "down"). Used by office editor and prefix+i. See Editor |
[notify] | phone notifications, off by default: enabled, provider ("ntfy"), url (your server and topic, which only your file holds) and quiet. Used by office notify and the meter plugin's hook |
[setup] | the agent working setup: test workers and subagents, models, the cold-cache minutes, branches, gate commands, review and captain preferences, Firstmate's switches, the Claude Code theme. Checked like the rest. office setup fills setup/'s templates in from it |
The generated herdr config is written to
~/.local/state/agent-office/herdr/config.toml, next to the preset's sound. It
is not ~/.config/herdr/config.toml, which office install never touches: a
herdr you start yourself keeps your own config. office on is what starts
herdr against the generated one, and gives it to the window it opens, because
herdr reads its keys there.
herdr writes one line into the config it runs with: onboarding = false, once
you have been through its first-run setup. Agent Office keeps that line and
does not count it as a change by hand.
The rules the config follows:
[herdr] pass through to herdr
unchanged, so tuning herdr needs no second file.config.toml.| command | what it does |
|---|---|
office install | check the config, write the generated herdr config and the office command, link the meter plugin into herdr, stop loading the tmux office's shell function; with [editor] on, check out the editor pane's nvim plugins at their pins; show every change first and back up what it replaces. Starts nothing. --check only plans. |
office setup | the whole setup in one run, the one line after the clone: four questions while you have no config yet (your coding agent, where Firstmate goes, whether to write the agent working setup, test workers and subagents), then office tools, Firstmate cloned at a tested revision, office install, office setup agents, herdr's integration for your coding agent, and office doctor. Each step shows its changes first and asks before it installs anything or changes a file of yours. --check only plans; --yes asks nothing. |
office setup agents | write the agent working setup into your home from your [setup] keys: the agent rules (~/AGENTS.md, linked as ~/.claude/CLAUDE.md and ~/.codex/AGENTS.md), the review and release process, Claude Code's settings and hooks, Firstmate's model picks and switches, the no-mistakes and gnhf settings. Agent Office owns only what it puts in: a marked block, its own keys, its own files; yours stay. Shows every change first; asks before changing what you changed, and backs it up. --check only plans; --remove takes out what it put in. See setup/README.md. |
office tools | install the tools the office uses that are missing, at pinned versions, each through its owner. A tool you have is left as it is. Shows the list and asks first. --check only plans; --workstation adds the optional workstation tools. |
office config check / office config show | check the config, and the herdr config made from it / print the config in effect |
office on | check the config, the generated herdr config and herdr's version; create the configured herdr session against the generated config, or use the one that runs; make sure one Firstmate is running for the configured home; attach. Running it again focuses what is there. Starts no workers. |
office install, office setup, office config, office keys, office dictate, office editor, office notify, office remote, office tools, office doctor, office update, office help,
office version, office on, office break, office off, office status, office open, officeoff-all, fm and fm restart are 1.0. Every other verb still runs the tmux office, documented in the
legacy README, until its 1.0 version lands. The
1.0 commands replace them; they are not additions to them. The tmux office's own
doctor, what runs and its RAM, is still there as office list.
office doctor checksThe components and the versions this release is tested with are data, in
config/components.toml. A version is listed there
only with the run that verified it. Today that is herdr 0.9.1, which CI pins.
A treehouse version or Firstmate revision with no run behind it is reported by
office doctor as not tested, with exit 1, until a lab run adds it.
A tool with a pin but no tested versions, such as each npm tool, is checked
against its pin: the version that was read before it was trusted. Another
version is a problem until the pin moves. Of the optional workstation tools,
office doctor checks the ones you have and does not miss the rest.
Who updates a program is read from where it is installed: Homebrew, npm, Nix or the system's packages, or the tool itself when it has its own update command. Anything else is reported as an unknown owner, which is a problem.
Installed is not active, so for the herdr config and the meter it shows both:
office install), and which meter
folder herdr links.office.session) runs:
the config that session started with, and the version, settings and last
pass of the meter running in it. herdr reports neither, so they come from
the meter plugin's own records in herdr's plugin state folder. A generated
config that changed after the session started counts as not active: herdr
does not report a herdr server reload-config, so only a restart is proof.
The one thing it asks herdr is whether that session's server runs.office tools installsThe same list, config/components.toml, says how
each tool installs. Always through the tool's own owner, so its usual update
path keeps working:
| kind | tools | how |
|---|---|---|
| GitHub release | herdr, treehouse, no-mistakes | the owner's release asset at the pinned version, checked against the SHA-256 in the manifest before it is unpacked, put where the owner's own installer puts it (~/.local/bin; no-mistakes in ~/.no-mistakes/bin, linked from ~/.local/bin). Its own update command keeps working there. |
| npm | the kunchenguid tools, chrome-devtools-mcp, acpx | npm install -g --ignore-scripts <package>@<pin>: no package's install scripts run. Needs Node 22.19 or newer. |
| Homebrew | jq, gh, the workstation tools | brew install. Homebrew owns those versions. Without Homebrew it tells you which package to install with your own package manager. |
It never pipes a downloaded script into a shell, never uses sudo, and never
replaces, updates or moves a tool you already have, whatever its version:
office doctor tells you when that version is not the pinned one. After each
install it checks the tool reports the pinned version, and it exits 1 if one
failed or is left for you. It does not install Node, a harness (Claude Code,
Codex) or Firstmate, and it starts nothing.
office update doesIt moves each component to the version this release names in
config/components.toml, never to "the latest". It
shows the plan, asks, and then works through it one component at a time:
| component | target | what runs |
|---|---|---|
| this checkout (the CLI, preset and meter) | the tip of the branch it follows | git fetch, then git merge --ff-only. Never a merge commit, a rebase or a reset. When it moved, the new release's office update takes over, so the rest follows the new release's list. |
| a tool npm owns | its pin | npm install -g --ignore-scripts <package>@<pin> |
| a tool Homebrew owns | its pin or tested version | brew info first; brew upgrade only if Homebrew has exactly that version, otherwise skipped |
herdr, treehouse, no-mistakes, where office tools puts them | its pin or tested version | the owner's release asset at that version, SHA-256 checked, put over the program. The program it replaces is kept in ~/.local/state/agent-office/previous/, and put back when the new one does not report the target version |
| a tool Nix or the system's packages own, or that sits somewhere else | skipped: it tells you to update it there | |
| Firstmate | the newest tested revision | Firstmate's own updater when the checkout has one and its origin is at a tested revision; otherwise git fetch and git merge --ff-only to that revision. Each secondmate its updater reports gets a result of its own |
| the generated herdr config, meter settings and links | your config | office install --yes, with its backups |
the agent working setup, once office setup agents has written it | your config and this release's templates | office setup agents --yes, with its backups. A whole file you changed is never replaced: the new version goes beside it once, and then it is yours to compare. A block or key of Agent Office's that you changed is put back after the plan's one question, backed up first. A key you took out stays out. Off with setup.enabled = false |
A self-updating tool's own update command is not run: herdr's, treehouse's
and no-mistakes' each take no version and go to the latest release, which is
not the one this release names, and herdr's can hand over a running server.
The pinned release asset is installed instead, exactly as office tools does,
and only over a program that sits where office tools puts it.
A component with no pinned or tested version, such as jq, gh and the
workstation tools, is left to its owner. So is your harness (Claude Code,
Codex). A tool that is not installed is office tools' job. Nothing is ever
downgraded.
Before anything changes, each component is checked, and a blocker skips that
one component and says why: a checkout with uncommitted changes, one that has
diverged from its remote or follows none, a remote that did not answer, a
Firstmate checkout whose remote is not your firstmate.source, a tool with an
unknown owner, a version that cannot be read. While no Firstmate revision is
tested, Firstmate is skipped, and office update exits 1 for the same reason
office doctor does.
After each update it reads the version again, and only the target counts:
office update prints the restart to run and never runs it: it stops,
restarts or reloads no server, no Firstmate, no secondmate and no daemon.
For the office session's herdr, config and meter, every later office update checks again, and reports them pending until the session runs them.It exits 0 only when every component is updated or unchanged, and 1 otherwise.
One component's failure does not hide the others' results, and running it
again does only what is left: a component the last run failed or was cut off
on is tried again, also when its program no longer reports a version, and so
is a secondmate Firstmate's updater skipped, by running that updater again.
There is no rollback across components: one that was updated stays updated.
For a release asset the program it replaced stays in
~/.local/state/agent-office/previous/ until its next update, for a rollback
you decide on.
Only one runs at a time (a lock in ~/.local/state/agent-office/, held
across the move to a new release too). Its
progress is recorded there in update.json, so a run that was killed or lost
its terminal is reported by office update --check and picked up by the next
office update. --check asks each remote for its tip with git ls-remote.
It changes no checkout, installs nothing and writes no record. To read a commit
it does not have yet, it fetches only that commit into a temporary folder and
removes the folder again.
office update --check shows one plan for all components, taken from one release. When this checkout will move, the Targets: line names the release it moves to, and every target comes from that release's components.toml. When it cannot read that release, the line says the targets are this release's. For each component the plan shows its owner, its target and what runs. Under it, it shows:
cli: version change, the preset: files that change, and the meter: version change.secondmates: it has registered in data/secondmates.md, read with Firstmate's own parser. It says which of them Firstmate's own updater moves, and that this check reaches no remote host.office install changes, with its diff. When this checkout moves, it is planned again from the new release.fm finds FirstmateThe office's Firstmate is the herdr agent named firstmate in the herdr
session office.session. herdr never gives two live agents one name, so fm
cannot pick the wrong one of two. Before it touches that agent, fm checks it
runs your firstmate.harness in your firstmate.code; anything else is
refused and left alone. fm also never adopts an agent in that checkout that
is not named firstmate: it prints the one herdr agent rename command that
adopts it, for you to run.
fm [args] focuses that agent, or starts it in a new tab of the session,
in firstmate.code with FM_HOME set to firstmate.home when you set one.
Your arguments go to the harness unchanged, as separate arguments. A running
Firstmate never gets them silently dropped: fm refuses instead. fm -- restart passes the word restart itself. In a terminal outside herdr, fm
then attaches to the session; inside another herdr session it prints the
attach command instead of nesting.fm restart waits for Firstmate's turn to end, asks it to /stow and to
end its receipt with a result line, and reads that line back. Only a
"safe to reset" answer is followed by /clear. A missing line, a "not safe",
a question on screen, a timeout (--timeout MINUTES, 30 by default) or
Ctrl-C resets nothing, says so and exits non-zero. It runs in the foreground,
so you see every outcome. /clear resets the conversation; Firstmate's
launch-time wiring (hooks, model, flags) is read again only when it starts
again: quit it, then run fm.One fm runs at a time per office: a second one, a start or a restart, is
refused while the first runs.
office on, break, off and status workOwnership is a record, not a name. office on starts the herdr server for
office.session itself and writes
~/.local/state/agent-office/offices/<session>.json: that server's process id,
when the process started, its socket, and the Firstmate it was started for.
office off stops a session only while the server behind the name is that
recorded process. A session with no record, or with another server behind the
name, is somebody else's: office off says so, leaves it running and exits 1.
office on first checks that the config is valid, that the generated
herdr config is the one your config makes now (if not: office install),
that herdr reports a version, and that the Firstmate checkout and home
exist. A herdr version this release is not tested with is a warning, and
office doctor has the details. Then it starts the session, or uses the one
that runs. A session it did not start is used as it is, with the config it
started with, and stays not owned. Firstmate is started or focused by the
same code as fm, and in a terminal outside herdr it attaches. It never
starts a worker.office break detaches and stops nothing. herdr 0.9.1 has no command
that detaches a client, so office on and fm record the client they
become, and office break sends exactly those the hangup a closing terminal
window sends. A herdr you attached yourself is not on that record: for it,
office break prints the detach key.office off lists what stops: the session and its server, Firstmate
with its checkout and home, Firstmate's workers by task, every other agent
in the session, the pane count, the meter, the attached terminals. It asks,
then asks Firstmate to save through the same /stow contract as
fm restart, and stops the session with herdr session stop only when
Firstmate answers that the save worked. A failed, unclear, timed out or
cancelled save stops nothing. So does an agent in the session that is still
working or waiting for an answer: office off refuses and names it. After
the session it stops that session's meter, checks both are gone, and clears
the record. It never deletes a worktree, empties a pool or touches a repo.--stop-workers drains Firstmate's workers instead of refusing. A
worker is an agent whose pane a task record in Firstmate's home names
(state/<task>.meta, herdr_session and herdr_pane_id) while it runs in
that record's worktree: never a guess from its folder or name alone, and a
record left from an earlier server makes no agent a worker. Each busy one is
stopped by Firstmate itself, with bin/fm-control.sh <task> exit in the
Firstmate checkout, which keeps its pane, worktree, uncommitted changes and
task record. Only then does Firstmate save, so the save records the stopped
workers and its next session picks the tasks up. No worker is stopped when
the save could not be asked for anyway (a harness other than claude, a
Firstmate that cannot be reached), or from a worker's own pane. The stops
run at once, each in a session of its own, so a Ctrl-C does not cut one off
half way. If Firstmate does not confirm a worker stopped, the session keeps
running. An agent with no task record is not Firstmate's: while it is busy,
still refuses.A session office on did not start is stopped by its owner only. After herdr update --handoff replaces a running server,
the record no longer names the process, and office off leaves that session
running: stop it with herdr session stop <name>.
office install writes| path | what | when it exists already |
|---|---|---|
~/.config/agent-office/config.toml | your config, from a starter | never touched again: it is yours |
~/.local/state/agent-office/herdr/ | the generated herdr config and the preset's sound | updated if Agent Office wrote it and nobody changed it since; otherwise shown, backed up, asked |
~/.local/state/agent-office/meter.json | your [meter] keys, which the meter plugin reads on every pass | the same |
~/.config/herdr/plugins.json | the meter plugin's entry, written by herdr itself: office install runs herdr plugin link on the herdr/ folder of your checkout. The sidebar numbers and Shift+arrow come from that plugin | linked again when this release has a newer plugin. A link to another folder is shown, backed up, asked. A plugin you disabled stays disabled |
~/.local/bin/office, ~/.local/bin/fm, ~/.local/bin/officeoff-all | links to bin/office, bin/fm and bin/officeoff-all in your checkout | the same: replaced only after a backup and a yes |
~/.zshrc and the other zsh startup files | the line that loads the tmux office's office function removed: zsh finds a function before any command, so it would hide the 1.0 one | shown as a diff, backed up, asked. A file that is a link (into a dotfiles repo, say) is never written through: you get the exact lines to remove. A function or alias of your own named fm hides fm the same way: it is pointed out, never removed |
~/.tmux.conf keeps its tmux office lines for now: the verbs 1.0 has not built
yet still run the tmux office, which needs them. Run that way, from
bin/office-tmux, it is a separate process, so office cd cannot move your
shell.
Backups go to ~/.local/state/agent-office/backups/<time>/, and
~/.local/state/agent-office/manifest.json lists every file Agent Office
owns. --yes skips the question, never the backup. Without a terminal to
ask on and without --yes, it changes nothing. ./install.sh in the checkout
is the same as office install.
office off --all stops only what this
installation started and recorded. It never stops every claude, codex or
herdr process on the machine, never runs a blanket pkill, and never stops a
herdr session it does not own.office update reports each component as
updated, unchanged, skipped, failed, or updated on disk but not yet active.
It succeeds only when everything it promised is verified.Push-to-talk into the focused pane, for a prompt that is quicker to say than to type. It is off until you turn it on, and nothing leaves the machine: sox records from your microphone into a file in ~/.local/state/agent-office/dictate/, whisper.cpp turns it into text on this machine, and herdr types the text into the pane (herdr pane send-text). No other program runs and there is no cloud fallback. The recording is deleted once it is read.
Press ctrl+space m, talk, press ctrl+space m again. herdr shows "recording", then "transcribing", and the words appear in the pane that has the focus at the second press. They are typed, not sent: read them, then press Enter yourself. A line break becomes a space. A recording stops by itself after max_seconds; the next press types it. office dictate cancel throws a recording away.
Set it up once. Agent Office installs none of it for you, and ships no model:
The programs, from their owners. On macOS: brew install whisper.cpp sox. On Linux: sox from your distribution (apt install sox), whisper.cpp from Homebrew on Linux or built from its README. You need rec and whisper-cli on your PATH.
A model, from where whisper.cpp publishes them: huggingface.co/ggerganov/whisper.cpp, or its own models/download-ggml-model.sh. base.en (148 MB) is a good start for English; base or small for other languages. For example:
mkdir -p ~/.local/share/whisper.cpp
curl -fL -o ~/.local/share/whisper.cpp/ggml-base.en.bin \
https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en.bin
The model is a data file: it runs nothing. Downloading it is the only time any of this uses the network.
Turn it on in your config.toml:
[dictate]
enabled = true
model = "~/.local/share/whisper.cpp/ggml-base.en.bin"
language = "en" # "auto" detects it; an .en model only knows English
office doctor then reports dictation as on, and names anything that is missing. On macOS the first recording asks for microphone access for the terminal app herdr runs in. Without it sox records silence, and dictation says it heard nothing.
An editor pane next to an agent, to read what it wrote or change a line yourself. It is off until you turn it on.
Press ctrl+space i. A new pane opens on the right of the focused one. It is in the agent's worktree: the git top level of the folder the agent runs in, not your shell's folder. Quit the editor and the pane closes. The agent's pane is not touched.
The editor is [editor] command, else $VISUAL, else $EDITOR, else nvim. It is split into words and started directly, never through a shell. Your shell's $VISUAL and $EDITOR count: if $EDITOR is micro, you get micro, and command = "nvim" gets you the office's nvim.
nvim gets a small config of the office's own, editor/nvim/init.lua. It never reads or writes your ~/.config/nvim, and its swap, undo and history files are apart from your nvim's (NVIM_APPNAME=agent-office-nvim). Leader is Space:
| keys | what it does |
|---|---|
Space c | the files this branch changed, committed or not, since it left the default branch. Pick one to open it. When the pane opens, it says how many there are |
Space e | the file tree, with git marks: M changed, ? new. It opens with the pane. q closes it |
Space f / Space / / Space b | find a file / search the text / the open files |
Space g | show the git changes in the file. The sign column shows them always |
Files the agent changes on disk are read in again within two seconds. A file you changed yourself is never overwritten: nvim asks first. The colours are the office's: amber and red mark only warnings and errors.
The tree, the finder and the git signs are two plugins, mini.nvim (MIT) and nvim-tree.lua (GPL-3.0). config/components.toml pins each to a commit and a SHA-256 of its files. office install checks them out into ~/.local/share/agent-office/nvim/ and checks the hash; a new release's pin shows as an update with a link to the change. There is no plugin manager, and nothing in the config fetches anything. Without the plugins nvim still opens, with the colours, the changed files in a list and nvim's own file browser; herdr says to run office install.
Set it up once:
nvim 0.10 or newer, from its owner: brew install neovim on macOS, or your distribution's package.
Turn it on in your config.toml:
[editor]
enabled = true
command = "nvim" # optional: else $VISUAL, $EDITOR, then nvim
# office_config = false # nvim with your own config instead
# split = "down" # below the agent, not beside it
Run office install. It checks out the two plugins.
office doctor then reports the editor pane as on, and names anything that is missing.
Look at the office, answer an agent or start a task from your phone, the same way a second terminal does it: an SSH app logs in to this machine over a private network, and office on there attaches to the office that already runs. There is no office server and no new port: it is SSH, which you turn on yourself, and herdr, which takes more than one terminal at once. Your terminal at the desk stays attached. Closing the app on the phone only detaches it, and everything keeps running. It is off until you set it up, and Agent Office turns none of it on for you.
Set it up once:
A private network. Install Tailscale on this machine and on your phone, signed in to the same account. Any other private network or VPN works the same way, but office remote checks only Tailscale. Never forward the SSH port to the internet.
SSH on this machine. On macOS: System Settings > General > Sharing > Remote Login, and under its (i) allow only your own user. On Linux: your distribution's OpenSSH server (apt install openssh-server). That listens on port 22 on every network the machine joins, not only Tailscale's, so sign in with a key: make one in your phone's SSH app and add its public key to ~/.ssh/authorized_keys here. Agent Office writes no key and no SSH config.
An SSH app on the phone, such as Blink or Termius on iOS, or Termius or JuiceSSH on Android.
Check it at this machine:
office remote
It says whether the office runs, whether something answers on port 22 and what Tailscale calls this machine. When all three are there, it prints the two lines to type on the phone:
ssh <you>@<this-machine>.<tailnet>.ts.net
office on
Otherwise it says what is missing and exits 1.
Start the office at this machine, and from the phone only attach. An office takes the environment of the shell that starts it and hands it to every agent: started from an SSH login, that is the SSH session's, and on macOS an agent there may not reach the login keychain it signed in with. On the phone, ctrl+space d detaches (or close the app), and office break at the desk detaches the phone too.
The public package holds nothing personal. These live only in your own
config.toml, your dotfiles, or the tool that owns them:
Examples in this repo use placeholders, never a real machine's output.
office doctor output is meant to be pasted into an issue, so it shows your
home folder as ~. It does print your configured Firstmate source and any
path outside your home: read it before you post it.
macOS and Linux. Windows, including WSL2, is not supported.
The prefix is ctrl+space: press it, let go, then the key.
| keys | what it does |
|---|---|
shift+arrow (no prefix) | left and right: the pane on that side, then the tab before or after. Up and down: the pane on that side, then the space above or below |
ctrl+space n / shift+n | new space / new tab. For a tab herdr asks for a name: type one, or press Enter |
ctrl+space c / shift+c | close space / close tab (both ask first) |
ctrl+space r / shift+r | rename space / rename tab |
ctrl+space v / minus | new pane on the right / below |
ctrl+space g | go to an agent |
ctrl+space s | settings |
ctrl+space d | leave herdr. Everything keeps running |
ctrl+space m | dictate: press, talk, press again. Off until you turn on dictation |
ctrl+space i | an editor pane in the focused agent's worktree. Off until you turn on the editor |
The same letter does the same thing one level down: plain for a space, with
Shift for a tab. office keys prints them all on one screen, and
the preset's README explains each.
Every part has a probe, a script that runs it in a throwaway home and checks what it did. CI runs them all on every pull request. None of them touches your own herdr, config or office.
| part | probe | against |
|---|---|---|
| the meter plugin: context size and transcript age for Claude Code, Codex, and Claude Code on a local Ollama model; quota runway, git branch and open PR. An agent it cannot identify, or a reading it does not have, stays blank, never guessed | herdr/meter-probe | recorded transcripts, a fake quota-axi and gh, no herdr server |
| Shift+arrow | herdr/nav-probe | a stand-in herdr |
| the preset: keys, sidebar, theme, sound, the WezTerm example | preset/preset-probe | herdr and WezTerm themselves |
the config, office install, office doctor, office tools | bin/install-probe | throwaway homes, a real herdr, stand-in installers |
office update | bin/update-probe | throwaway homes, stand-in owners |
office open | bin/open-probe | stand-ins for herdr and fzf, a stand-in Firstmate home |
fm and fm restart | bin/fm-probe | a throwaway herdr session, a stand-in agent |
office on, break, off, off --all, status | bin/lifecycle-probe | throwaway herdr sessions, a stand-in agent |
| phone notifications | bin/notify-probe | a stand-in ntfy server |
| dictation | bin/dictate-probe | stand-ins for rec, whisper-cli and herdr |
the editor pane: office editor, its plugins, its nvim config | bin/editor-probe | stand-ins for herdr and the editors, a local plugin repository, nvim itself when installed |
office remote | bin/remote-probe | stand-ins for herdr and Tailscale, an SSH port of its own |
| nothing private ships | bin/leak-scan-probe | throwaway git repositories |
the agent setup: setup/'s templates and the keys |
CI also runs office tools for real, on a Linux and a macOS machine that have
none of the pinned tools: office setup --yes, so the GitHub release downloads with their SHA-256, the
npm installs, the Firstmate clone, office install, office setup agents and office doctor. That run proves the
pins and hashes in config/components.toml still exist.
Agent Office 0.x was a tmux cockpit: office on, a six-pane grid, iTerm2
profile, "your turn" on each pane border. It is retired, through a major
version change, not deleted.
main, the last tmux commit is tagged as the final 0.x release (planned;
this README will name the exact tag). Its docs travel with it:
README,
Getting started,
Contributing.office update pulls the branch you are on, so on main it would pull 1.0.
On the tag it refuses to update, which is what you want. Until the tag
exists, the tmux installer on main is bin/install-tmux [--theme];
./install.sh is now the 1.0 installer.office install (works today) finds the line that loads
the old office shell function and the old office link, shows them, backs
them up and replaces them, after you say yes. It never overwrites a file it
did not write without showing the difference first. Your tmux sessions and
.tmux.conf are not touched; the .tmux.conf lines go when the tmux office
is retired. A zsh that is already open keeps the old function until you open
a new one.The legacy tmux office receives no further changes.
See CONTRIBUTING.md. It says what is in scope, and how to test without touching a live office.
MIT. See LICENSE.
Made by Zyx. Firstmate, treehouse and the kunchenguid tools are by kunchenguid. herdr is by its own authors at herdr.dev.
chrome-devtools-mcp (Chrome's DevTools for agents, which chrome-devtools-axi drives), acpx (the Agent Client Protocol from the command line), gh (gh-axi drives GitHub through it) |
| their upstreams |
| agent integrations | herdr's Claude Code and Codex integrations, and the optional skill packs office setup agents checks out at pinned commits (setup/README.md) | upstream tools and, for the skill packs, their authors. You run herdr integration install claude (or codex) once; office doctor checks it |
[office], [firstmate], [treehouse], [meter] | checked (an unknown key or a wrong type is an error). office install writes [meter] where the meter plugin reads it on every pass. office doctor reports [firstmate], treehouse.root and the settings the running meter uses. fm, office on, office off and office status use office.session and [firstmate] except source. treehouse.root is only reported |
office break | detach only: the terminals office on and fm attached. Firstmate, the workers and the terminals keep running. herdr has no detach command, so a herdr you attached yourself detaches with its key, which office break prints. |
office off | stop this office: show what will stop, ask, let Firstmate save its work, and only when the save is confirmed stop the owned session and its meter. A session office on did not start is left running. It refuses while an agent in the session is working or waiting; --stop-workers has Firstmate stop its own busy workers first, keeping their worktrees and task records. --force, confirmed separately on the terminal, stops when the save fails. Repos and worktree pools are kept. |
office off --all / officeoff-all | stop every office this installation owns, after showing the targets and asking to confirm. Two spellings, one implementation. Anything left running makes it exit non-zero. |
office update | move every component (this checkout with its CLI, preset and meter, the generated config, the agent working setup, herdr, treehouse, no-mistakes, the npm tools and Firstmate) to the version this release names, each through its owner. Shows the plan and asks first; restarts nothing. Reports each as updated, unchanged, skipped, failed, or updated on disk but not yet active, and exits 0 only when all are updated or unchanged. --check only plans: it changes nothing. |
office doctor | read-only: each component's installed version, who updates it (a package manager or the tool itself), and whether this release is tested with that version; herdr's integration for your harness; your Firstmate source, checkout, revision and home; the herdr config and meter, installed and, while the office session runs, active; the agent working setup that office setup agents wrote, in place or behind. Changes nothing. Unknown is never reported as healthy: it exits 1 on any problem. |
office status | read-only: what is running, what the office owns, meter health, pending restarts, and the result of the last office off. Unknown is never reported as healthy: it exits 1 on any problem. Pending updates are planned, with office update. |
office open [<project>] | go to a project's space in the office's herdr session, or make one with its first pane in the project; attach when the terminal is outside herdr. With no project named, fzf picks one from the projects Firstmate has registered and cloned (its data/projects.md, read only) and the git checkouts directly inside each open.roots folder. An exact name opens without a picker, a part of one opens the picker typed in, a folder (office open .) opens that folder. A space is the project's when its label is the project's name and one of its panes is in the project's folder; nothing is closed or renamed. --list prints the projects. Inside the office, prefix+f runs it in a popup. Needs the herdr session running; office on starts it. |
fm [args] | open or focus the configured Firstmate, with your arguments passed through unchanged. Needs the herdr session running; office on starts it. |
fm restart | make Firstmate save its work, check that the save worked, then reset it. If the save fails, nothing is reset. Harness claude only. |
office keys | print one screen of every office key: the herdr preset's keys and the Mac text keys. Read-only. Inside the office, ctrl+space then ? shows herdr's own list. |
office dictate / office dictate cancel | push-to-talk, if [dictate] is on: the first run records from the microphone, the next one stops, transcribes on this machine and types the words into the focused pane, without Enter. prefix+m runs it. cancel throws the recording away. See Dictation. |
office editor / office editor --pane PANE | if [editor] is on: the editor in this folder's worktree, or a new pane next to PANE that runs it in the worktree of PANE's agent. prefix+i runs the second one. See Editor. |
office notify needs-you|pr-ready <message> | push one line to your phone through [notify]. Off by default; quiet mode holds everything but needs-you. The meter plugin calls it when an agent turns blocked; anything that knows a PR is ready can call pr-ready. |
office remote | read-only: can your phone reach the running office, and what to type there. Checks the office's herdr session, an SSH server on this machine and Tailscale, then prints the ssh line and office on, or what is missing. Turns nothing on and opens no port. See From your phone. |
--stop-workers--force is for a save that cannot be confirmed. The save is still tried
first. If it fails, office off --force warns that unsaved conversations may
be lost and asks again, on the terminal, for the session name typed out.
--yes answers only the first question: without a terminal, nothing is
forced. A forced stop is the same herdr session stop of the same owned
session, nothing wider.office off --all and officeoff-all do this for every recorded
office, and name the running herdr sessions they leave alone. Each office is
reported as stopped, already stopped, left, kept or incomplete; anything but
the first two makes the exit code 1.office off in too. The stop runs in a helper outside every
session, and the result is written to
~/.local/state/agent-office/last-off.json before it is printed, so
office status shows it afterwards. Firstmate cannot run office off from
its own pane: it could not save while it waits for the command, so that is
refused.office status shows whether the session runs, who started it, the herdr
config it started with and the meter (the same checks as office doctor),
Firstmate and the other agents with their state, the terminals attached by
office on or fm, whether herdr says its server needs a restart, other
offices this installation started, and the last office off.[setup]bin/setup-probe |
a stand-in user, rendered in memory, then bin/leak-scan |
office setup agents, --check, --remove | bin/setup-home-probe | throwaway homes with files of "yours" |
office setup, the one-line install | bin/setup-all-probe | throwaway homes, stand-in tools, a local Firstmate, a real herdr, the questions on a terminal |