# Hive documentation
> Hive runs your coding agents in isolated tmux sessions, and Hive Desktop adds an inbox that collects pull requests, issues, and alerts into feeds and hands any item to an agent.
Every page of https://hivedesktop.com/, in navigation order. The index with one link per page is at https://hivedesktop.com/llms.txt.
---
# Getting Started
Hive Desktop collects work from supported sources and routes it into local feeds. Flows decide which items enter a feed, show a notification, or run an action.
## Install
Direct downloads come from the release manifest. Use the install script below if they do not appear.
The macOS download is a `.dmg`: open it and drag **Hive** to Applications. The Linux downloads are tarballs: extract one and put the `hive-desktop` binary on your `PATH`.
### Install from the terminal
The install script picks the right build, verifies its checksum, and installs the app. It leaves the separate [`hive` CLI](https://hivedesktop.com/cli/getting-started/) unchanged.
```sh
curl -fsSL https://hivedesktop.com/install.sh | bash
```
=== "macOS"
Installs `/Applications/Hive.app`, or `~/Applications` when the first is not writable.
=== "Linux"
Hive requires the GTK 4 and WebKitGTK 6.0 runtime libraries. [Install the packages for your distribution](https://hivedesktop.com/desktop/getting-started/troubleshooting/#hive-does-not-start-on-linux) before you start Hive.
The installer puts the binary under `~/.local/share/hive` and adds Hive to your application menu. Set `HIVE_HOME` to choose another binary directory. A manually extracted tarball does not add the application-menu entry.
To inspect the installer first, omit `| bash`.
Hive updates itself. You can change the release channel under **Settings ▸ About**. See [Settings](https://hivedesktop.com/desktop/configuration/settings/#updates).
## First run
1. Choose a coding agent and the folders holding your repositories.
2. Connect GitHub, or skip it and connect another [source](https://hivedesktop.com/desktop/inbox/sources/).
3. Allow notifications if you want system banners.
4. Start a chat with your agent, or open the feed.
Hive creates a profile named **Default** for you; connecting GitHub fills it
with the starter feeds. The last step opens the built-in **Hive** workspace,
where your agent asks how you work and offers to set up your profiles and
feeds. Select **Not now** to go straight to the feed instead.
These pages cover each step:
- [Set up your agent and code](https://hivedesktop.com/desktop/getting-started/agent-and-repos/)
- [Sign in to GitHub](https://hivedesktop.com/desktop/getting-started/sign-in/)
- [Turn on notifications](https://hivedesktop.com/desktop/getting-started/notifications/)
- [See your first items](https://hivedesktop.com/desktop/getting-started/first-feed/)
## Configure Hive
Use the flow editor and Settings screens for normal configuration. You can also edit the YAML files under `~/.config/hive/desktop/`.
The built-in **Hive** workspace in **Chats** can create flows, connect generic sources, define actions, and change settings. It requires a supported coding agent CLI on your `PATH`.
Start with:
- [Feature overview](https://hivedesktop.com/desktop/getting-started/features/)
- [Sources](https://hivedesktop.com/desktop/inbox/sources/)
- [Flows](https://hivedesktop.com/desktop/inbox/flows/)
- [Actions](https://hivedesktop.com/desktop/inbox/actions/)
- [Keyboard shortcuts](https://hivedesktop.com/desktop/configuration/keybindings/)
---
# Features
Hive Desktop brings incoming work, coding sessions, and long-running agent workspaces into one app. Its three main areas can be used together or independently.
## Inbox
Inbox turns scattered updates into focused feeds. Connect the systems you already use, route each item through rules you control, and decide when Hive should notify you or start work.
- :lucide-plug:{ .lg .middle } __Multiple sources__
---
Collect work from GitHub, Gitea and Forgejo, Grafana, PostHog, RSS and Atom feeds, local webhooks, and commands that emit JSON.
- :lucide-workflow:{ .lg .middle } __Visual routing__
---
Connect sources to filters and JavaScript functions, then route matching items to feeds, notifications, and actions. A flow can branch to several destinations.
- :lucide-inbox:{ .lg .middle } __Focused feeds__
---
Organize feeds into folders, search and sort items, filter unread work, archive completed items, and restore ignored items from Trash.
- :lucide-history:{ .lg .middle } __Item timeline__
---
Inspect an item's content, source, noteworthy changes, available actions, and linked coding sessions in one detail view.
- :lucide-zap:{ .lg .middle } __Actions__
---
Start a coding session, run a shell command, or publish a message from an item or flow. Item actions can also copy rendered text.
- :lucide-bell-ring:{ .lg .middle } __Change-aware notifications__
---
Send one system banner or in-app notification when a routed item is new or changes. Read and archive state stays local to Hive.
See [How Hive works](https://hivedesktop.com/desktop/inbox/how-it-works/), [Sources](https://hivedesktop.com/desktop/inbox/sources/), [Flows](https://hivedesktop.com/desktop/inbox/flows/), and [Actions](https://hivedesktop.com/desktop/inbox/actions/).
## Code
Code is a desktop control surface for parallel coding-agent sessions. Each task gets an isolated checkout and persistent terminal, while Hive keeps the agent, tests, shell, git state, pull request, and task tree in view.
- :lucide-box:{ .lg .middle } __Persistent coding sessions__
---
Create repository sessions, start or stop their agents, and return to their tmux terminals after switching views or restarting Hive. Sessions are also available in the hive CLI when both use the same Hive data root, which is the default.
- :lucide-settings-2:{ .lg .middle } __Shared session configuration__
---
Use the hive CLI's config, commonly `~/.config/hive/config.yaml`, for repositories, agent profiles, clone strategies, setup commands, and starting windows.
- :lucide-panels-top-left:{ .lg .middle } __Windows and panes__
---
Create, rename, reorder, split, resize, zoom, search, and close tmux windows and panes from the app.
- :lucide-terminal:{ .lg .middle } __Scratch terminals__
---
Keep repository-free shells in a dedicated tmux session.
- :lucide-git-pull-request:{ .lg .middle } __Git and pull request status__
---
See the current branch, local changes, unpushed commits, and pull request review and check state. Open the checkout in your editor or file manager.
- :lucide-square-terminal:{ .lg .middle } __Pop-up and quick terminals__
---
Open a temporary shell from any area, or give tools such as `lazygit`, a test watcher, or `btop` their own command-palette entry and shortcut. Hiding the pop-up leaves its shell running.
- :lucide-list-checks:{ .lg .middle } __Tasks__
---
Inspect the same `hive hc` task tree used by coding agents, including epics, subtasks, blockers, comments, checkpoints, and linked sessions.
- :lucide-pin:{ .lg .middle } __Pinned chats__
---
Attach a persistent chat from Chats beside repository sessions without stopping or duplicating its agent.
See [Terminal mode](https://hivedesktop.com/desktop/code/terminal-mode/), [Actions](https://hivedesktop.com/desktop/inbox/actions/#quick-terminals), [Hive sessions](https://hivedesktop.com/cli/getting-started/sessions/), [Hive CLI configuration](https://hivedesktop.com/cli/configuration/), and [Hive task tracking](https://hivedesktop.com/cli/getting-started/task-tracking/).
## Chats
The Chats area gives ongoing agent work a durable home outside a repository session. Build a workspace around a purpose, give it the right instructions and tools, then use it interactively or run it on a schedule.
- :lucide-messages-square:{ .lg .middle } __Persistent agent workspaces__
---
Keep named chats, instructions, and generated agent configuration together. Chats continue when you switch areas or restart Hive.
- :lucide-command:{ .lg .middle } __Flexible agent commands__
---
Start from Claude Code or Codex presets, or provide a custom command for another CLI, wrapper, model, or permission setup.
- :lucide-wrench:{ .lg .middle } __Skills and MCP servers__
---
Choose reusable skill packages and tools for each workspace. Hive includes integrations for Hive Desktop, Hive Drive, Playwright, and Chrome DevTools.
- :lucide-calendar-clock:{ .lg .middle } __Scheduled jobs__
---
Run a workspace prompt hourly, daily, weekly, monthly, or on a custom local-time cron schedule. Run it on demand, pause it, choose what happens after a missed run, and inspect recent outcomes.
- :lucide-activity:{ .lg .middle } __Live agent state__
---
See which chats are working, need approval, are running, or are stopped. Stop, restart, rename, or delete a chat independently of its workspace.
- :lucide-panels-right-bottom:{ .lg .middle } __Drive__
---
Let agents publish durable Markdown, HTML, and canvas documents beside a chat or a Code session, then browse the folder tree, search every space, reorganize it, or read a document full page.
- :lucide-panel-left-open:{ .lg .middle } __Code integration__
---
Pin a chat into Code and use the same live tmux session from either area.
- :fontawesome-brands-hive:{ .lg .middle } __Built-in Hive workspace__
---
Ask an agent to configure feeds, flows, actions, settings, shortcuts, webhook sources, and other workspaces.
See [Agent workspaces](https://hivedesktop.com/desktop/chats/agent-workspaces/).
---
# Set up your agent and code
Hive starts coding sessions in your repositories. The first screen of first run asks for the two things it needs to do that: which coding agent to run, and where your code is.
Hive writes both to the hive CLI configuration file, so the `hive` command picks up the same setup. Nothing else in that file is touched.
## Choose an agent
Pick one or more from the list. Hive marks the ones it found on your `PATH`, and you can pick one you have not installed yet — it will work once the command is there.
Selecting more than one adds a **Start new sessions with** choice. That is the agent a new session uses when you do not name another.
!!! note "Skip-permission flags"
**Skip the agent's permission prompts** adds the flag that lets the agent act without asking, where the agent has one — `--dangerously-skip-permissions` for Claude Code, `--full-auto` for Codex. It is off by default.
## Point at your repositories
Select **Choose a folder** and pick the folder that *contains* your repositories. For a layout like this:
```
~/code/
hive-desktop/
my-app/
notes/
```
choose `~/code`, not `~/code/my-app`. Hive rejects a folder that is itself a git repository and tells you so.
Every repository under the folders you add shows up in the new session picker. Add as many folders as you like — work in one, side projects in another.
The row under each folder shows how many repositories Hive found there. If it says none, you probably picked a level too deep or too shallow.
## Already use the hive CLI?
If your config already names an agent and at least one folder, Hive says so and uses it as it is. Nothing is rewritten.
## Skipping
You can skip this step. The Inbox half of Hive — feeds, sources, flows, notifications — works without it. The new session picker stays empty until you set it.
## Changing it later
This screen is the only one that writes the file. To change either setting afterwards, edit the file yourself and restart Hive Desktop — **Settings ▸ Hive CLI** shows you where it is, opens it, and links to the hive CLI [configuration reference](https://hivedesktop.com/cli/configuration/).
The file is shared with the `hive` command, so anything else in it — rules, tmux settings, keybindings, your own agent profiles — is kept exactly as written.
!!! tip "`HIVE_DEFAULT_AGENT`"
If that variable is set in your shell, it overrides the agent you choose here. This screen says so when it is set.
---
# Sign in to GitHub
Select **Connect GitHub** during first run. Copy the displayed code, open `github.com/login/device`, and approve access.
Hive requests the `repo` and `notifications` scopes to read issues, pull requests, and GitHub notifications. It stores the token in the OS keychain.
You can also choose **Use a token instead** and provide a classic personal access token with those scopes.
If the code expires, start the connection again. Manage connected accounts later under **Settings ▸ Integrations ▸ GitHub**.
You can skip this step and connect another supported source. See [Sources](https://hivedesktop.com/desktop/inbox/sources/).
---
# Turn on notifications
Select **Allow notifications** during first run and approve the operating system prompt.
On macOS, Hive cannot show background banners until this permission is granted. If you skipped or denied it, open **Settings ▸ Notifications**. A denied permission must be changed in macOS System Settings.
The same Settings page controls:
- automatic delivery, which uses banners while Hive is in the background;
- system banners at all times;
- in-app toasts at all times;
- the notification master switch and sound.
You can skip notification permission and continue using feeds.
---
# See your first items
Connecting GitHub during first run creates these starter feeds:
- **My open PRs**
- **Assigned**
- **Notifications**
- **Review requests**
Select a feed in the sidebar, then select an item to open its details. New items arrive unread. Use the item menu to archive it, open it in a browser, or run an available action.
Sources poll every five minutes by default. Press r to refresh now. Press ? for the current shortcut list.
## Change the starter workspace
Open the flow editor to add sources, filters, feeds, actions, or notifications. You can also open **Chats**, select the **Hive** workspace, and describe the feed you want.
See [Flows](https://hivedesktop.com/desktop/inbox/flows/) for a small example and [Sources](https://hivedesktop.com/desktop/inbox/sources/) for supported providers.
---
# How Hive works
Hive collects work from external sources and routes it into local feeds.
## The model
- A **source** reads from a provider, a feed, a command, or a local webhook.
- A **flow** connects sources to filters and destinations.
- A **workspace** is the Inbox view of one flow.
- A **feed** is a list of items produced by a flow.
- An **action** starts a repository session or agent workspace chat, runs a command, publishes a message, or copies text.
- A **notify** node raises a system banner or an in-app toast.
- A **launch** node starts a repository session or an agent workspace chat for each item, without an action.
Hive stores item history and read state locally. Changing a flow recalculates feed membership without losing that history.
## Work with feed items
Use **Feed options** to sort a feed, refresh its sources, mark its items as read, or select multiple items.
In selection mode, choose items and use **Copy contents** to copy one readable block in feed order. **Copy with action** applies a configured clipboard action to every selected item.
Select **Create session** to open one editable New Session form with context from every selected item. Choose **Repository** for a coding session or **Agent workspace** for a chat that does not need a checkout. A repository session appears in each selected item's detail pane. An agent workspace chat appears in Chats, receives the same generated prompt, and appears in each selected item's detail pane.
A prompt larger than 32 KiB shows a warning in the form. Hive writes the full text to a private temporary file and asks the agent to read and delete it instead of passing the text as a command argument.
Selections remain active while you search, filter, sort, copy, or cancel the New Session form. Use **Cancel selection** to clear them.
## The app areas
Inbox is one of Hive's three main areas. See the [feature overview](https://hivedesktop.com/desktop/getting-started/features/) for the core Inbox, Code, and Chats capabilities.
## Configure Hive
Use the flow editor and Settings screens, edit the YAML files directly, or ask the built-in **Hive** workspace in Chats.
- [Sources](https://hivedesktop.com/desktop/inbox/sources/) lists supported providers and generic inputs.
- [Flows](https://hivedesktop.com/desktop/inbox/flows/) covers the graph and editor.
- [Actions](https://hivedesktop.com/desktop/inbox/actions/) covers reusable commands.
- [Settings](https://hivedesktop.com/desktop/configuration/settings/) lists configuration locations and categories.
---
# Flows
A flow is a graph that connects sources to filters and destinations. Each Inbox workspace is backed by one flow file.
## Use the editor
Open a workspace's flow editor to add nodes and connect them. Select **Deploy** to save the graph.
- **Source** nodes collect items. See [Sources](https://hivedesktop.com/desktop/inbox/sources/) for supported providers and generic inputs.
- **Filter** nodes pass matching items and can route rejected items through a second output.
- **Function** nodes use JavaScript to reshape or split messages.
- **Feed** nodes add items to an Inbox list.
- **Notify** nodes show a banner or toast.
- **Action** nodes run a named action.
- **Launch session** nodes start a coding session in a repository.
- **Launch chat** nodes open a chat in an agent workspace.
The editor and YAML file are two views of the same flow. Changes reload when the file is saved. If validation fails, Hive keeps the last valid version active and reports the error in Activity.
## A small flow
This flow puts GitHub review requests into a feed:
```yaml
version: 1
name: Reviews
nodes:
- id: prs
type: sources.github
credential: github/octocat
kind: search
query: "is:open is:pr review-requested:@me"
- id: reviews
type: feed
icon: git-branch
wires:
- { from: prs, to: reviews }
```
Every node needs an `id` and `type`. Type-specific fields sit beside them. Wires name the source and destination node IDs.
Add a filter between the source and feed when you need narrower routing. The GitHub filter can match CI states such as `passing` or `failing` and review states such as `approved` or `changes_requested`. Branch one output to several destinations when an item should enter a feed and raise a notification or action.
## Start work from a flow
A launch node starts work for each item that reaches it, once per item. A pull request that keeps changing does not start a new session on each update. The item's detail pane lists the session or chat it started.
```yaml
- id: review
type: launch-session
repo: "{{ .ItemRemote }}"
sessionName: "review-{{ .Payload.num }}"
prompt: "Review pull request #{{ .Payload.num }}"
- id: triage
type: launch-chat
workspace: incident-triage
prompt: "Triage {{ .Payload.title }}"
```
`launch-session` takes `repo` and `prompt`, plus an optional `agent` and `sessionName`. Set `repo` to `{{ .ItemRemote }}` to work in the item's own repository, to a remote URL to work in one fixed repository, or to any template that renders a remote URL. An item whose repository renders blank fails its launch, and the failure shows in Activity. `sessionName` becomes a slug of at most 60 characters. When it is empty or has no letters or digits, the session is named after the node and the item instead. When another active session already has the name, Hive adds the launch's command id, such as `review-hive-118`, so `review-{{ .Payload.repo }}` can start one session for each pull request in a repository. A retry of the same launch uses the same name, so it never starts a second session. `launch-chat` takes `workspace` and `prompt`. The templates see the same item fields as a `launch-session` action, so fence outside content as [Actions](https://hivedesktop.com/desktop/inbox/actions/) describes.
Use an **Action** node instead when the same launch also appears in the item menu. Then you define it once in `actions.yml`.
## Flow files
Flows live in `~/.config/hive/desktop/flows/` by default. The filename supplies the flow ID. Hive stores canvas positions in a sibling `.ui.yaml` file.
```text
flows/
├── reviews.yaml
└── reviews.ui.yaml
```
Flow YAML is strict. Unknown fields, invalid connections, and duplicate node IDs prevent deployment.
!!! tip "Ask the Hive workspace"
Open the **Hive** workspace in **Chats** and describe the feed you want. Its `hive-flows` skill can write and validate the flow.
## Testing a flow
The Hive workspace can dry-run a flow against sample input through the app's MCP server. A dry run reports what each node received and emitted without changing feeds or running actions.
Deploying or restarting recalculates feed membership. It does not replay notifications or actions for existing items.
---
# Sources
Add sources in the flow editor. Connect provider accounts under **Settings ▸ Integrations**.
| Source | Support | Available inputs |
| --- | --- | --- |
| GitHub | Stable | Search and notifications |
| Gitea and Forgejo | Stable | Filtered search and notifications |
| Grafana | Stable | Managed alerts, IRM alerts, and Prometheus metrics |
| PostHog | Stable | Error tracking and insight alerts |
| RSS feeds | Stable | Entries from an RSS, Atom, or JSON Feed URL |
| Webhooks | Stable | JSON sent to a local endpoint |
| Commands and CLIs | Stable | JSON returned by a shell command |
Provider tokens are stored in the OS keychain. Flow files refer to a connected account by name.
## GitHub
GitHub sources support:
- any GitHub search query;
- the connected account's notification inbox;
- multiple accounts with separate polling and rate limits.
Connect with GitHub's device flow or a classic personal access token. Hive requests `repo` for private repository results and `notifications` for the notification inbox.
Use `sources.github` in a flow. Choose `search` and provide a query, or choose `notifications`.
Search results for pull requests include CI and review status plus added and deleted line counts. These values appear in the feed and detail pane. Function nodes can read `ci`, `review`, `additions`, and `deletions` from the item payload. Notification results do not include these fields.
Hive does not update read, archive, or notification state on GitHub.
## Gitea and Forgejo
Gitea sources work with Gitea and Forgejo instances. They support:
- issue and pull request searches;
- filters for state, owner, labels, involvement, and text;
- the connected account's notifications.
Connect an instance URL and access token under **Settings ▸ Integrations**. The token needs `read:user`, `read:issue`, and `read:notification`. Use `sources.gitea` in a flow.
## Grafana
Connect a Grafana stack with its URL and a Viewer service account token. IRM also needs `grafana-irm-app.alert-groups:read`. The same account can be used by three source types:
- `sources.grafana_alerts` for firing Grafana-managed alerts;
- `sources.grafana_irm_alerts` for active IRM alert groups;
- `sources.grafana_metrics` for a PromQL query result.
Alert sources can be filtered by labels, integration, or team. An IRM alert group's details include the latest source description and common labels. Its payload exposes `alertLabels`, `annotations`, `cluster`, `namespace`, and `severity` to function nodes and action templates. Metrics sources require a Prometheus-compatible data source UID and an expression.
## PostHog
Connect a PostHog instance and personal API key, then select a project. Error tracking needs `project:read` and `error_tracking:read`; insight alerts need `project:read` and `alert:read`. PostHog provides:
- `sources.posthog_errors` for error-tracking issues;
- `sources.posthog_alerts` for insight alerts.
## RSS feeds
An RSS source reads one feed URL. RSS, Atom, and JSON Feed all use the same field; Hive reads the document, not the file extension. Use `sources.rss` in a flow.
The feed must be readable without credentials. This source sends no token and no basic auth.
Set these fields:
- `url`, the feed document;
- `limit`, how many of the newest entries to ingest per fetch (50 by default, 500 at most);
- `interval`, the shortest time between fetches. New nodes start at `30m`. A feed publishes far less often than the poll tick runs.
Each entry becomes an item with kind `Post`. Its title, link, author, categories, and dates come from the feed. Its body is the entry summary reduced to markdown text, with links kept. The feed's own title is shown above the entry. Actions target these items with `applies_to: [Post]`.
How much of that arrives is the feed's choice, not Hive's. A feed that publishes no summary gives you a title and a link. Where a site offers more than one feed, the fuller one is worth using: Hacker News's own feed at `news.ycombinator.com/rss` has no summary and no entry ids, while the same stories through `hnrss.org/frontpage` carry a summary, the submitter, and proper ids. Without ids an entry is matched on its title and date, so editing a title publishes it again as a new item.
The item's link is whatever the feed puts in its `link` element. For an aggregator that is usually the article it points at, not the discussion page.
Each fetch carries the previous response's `ETag` and `Last-Modified`, so an unchanged feed costs one request and no parse. Refreshing the inbox drops that cache and fetches every feed again.
A fetch either returns the whole window or fails. An unreachable host, a non-2xx response, a document over 8 MiB, and a page the parser cannot read as a feed are all failures. A failed fetch changes nothing: the previous entries stay, nothing is archived, and the error is recorded in Activity.
A feed is a window, not a list: publishers drop old entries as they add new ones. Hive does not archive an entry that scrolls off the end, because that means the entry is old, not finished. Adding a node ingests everything still in the window on the first tick, so point a notify node at a busy feed only if you want that.
## Webhooks
A webhook source accepts JSON from scripts and local tools. It listens on:
```
http://127.0.0.1:/hooks/
```
Create a `sources.webhook` node and give it a path. The local HTTP server must be enabled. **Settings ▸ Integrations ▸ Webhooks** shows the current base URL and lets you choose a fixed port.
```sh
curl -X POST "http://127.0.0.1:$PORT/hooks/ci-alerts" \
-H "Content-Type: application/json" \
-H "X-Hive-Secret: $SECRET" \
-d '{
"id": "build-4821",
"kind": "build",
"title": "Unit tests failed",
"url": "https://ci.example.com/builds/4821",
"state": "failing"
}'
```
Webhook rules:
- The listener only accepts local connections.
- Requests use `POST` with a JSON body of up to 1 MiB.
- An optional node secret is sent in `X-Hive-Secret`. Hive stores this secret in the flow file, so handle that file as a shared secret.
- A stable top-level `id` updates the same item on later deliveries.
- `title`, `url`, and `kind` control the basic feed display.
- `resolved`, `closed`, and `done` states archive the item.
Other fields remain available to function nodes and action templates.
!!! tip "Ask the Hive workspace"
The **Hive** workspace can create the webhook node and sender with the `hive-webhook-sources` skill.
## Commands and CLIs
A command source runs on the polling schedule and reads a JSON snapshot from stdout.
```yaml
- id: todo
type: sources.exec
command: "todo list --json | jq -s ."
timeout: 30s
interval: 1h
```
The command must define a timeout of no more than two minutes, exit successfully, and print a JSON array. Each object needs a stable top-level `id`. Items missing from the next successful snapshot are archived.
A failed command leaves the previous snapshot unchanged and records the error in Activity.
---
# Actions
Actions are reusable operations defined in `actions.yml`. Configure them under **Settings ▸ Actions** or edit the file directly.
Actions can appear on feed items, terminal sessions, terminal windows, or in a flow. A flow that only needs to start a session or chat can use a [launch node](https://hivedesktop.com/desktop/inbox/flows/#start-work-from-a-flow) instead.
## Action types
- **`launch-session`** starts a repository coding session or an agent workspace chat from an item.
- **`shell`** runs a shell command.
- **`publish-message`** sends a message to a topic.
- **`clipboard`** renders text and copies it.
A manual item action can limit itself to kinds such as pull requests or issues. An action can also ask for text or a selected value before running.
## Example
```yaml
version: 1
actions:
- id: review-pr
label: Review PR
type: launch-session
applies_to: [pr]
show_in_detail: true
repo_template: "https://github.com/{{ .Payload.repo }}.git"
prompt_template: |
Review pull request {{ .Payload.title }}
{{ .Payload.url }}
launchers: []
```
This action appears for pull requests and starts a session with the repository and prompt rendered from the item.
Use `workspace` instead of `repo_template` to send an item to an agent workspace:
```yaml
- id: triage-alert
label: Triage alert
type: launch-session
workspace: incident-triage
prompt_template: |
Triage {{ .Payload.alert }} in {{ .Payload.cluster }}.
{{ .Payload.thread_url }}
```
`workspace` is the workspace directory name. The workspace command must pass
`.Prompt` through `shq`, as the shipped command presets do. Hive refuses the
launch if the command would drop the item context or interpolate it as shell
syntax. `repo_template` and `workspace` cannot appear together.
Template fields depend on where the action runs:
- Item actions use `{{ .Payload. }}` and `{{ .Key }}`. `{{ .ItemRemote }}` is the clone URL of the item's repository, for `repo_template`.
- Session actions use values such as `{{ .Session.Path }}` and `{{ .Session.Branch }}`.
- Window actions can also use `{{ .Window.ID }}`.
- Declared inputs use `{{ .Inputs. }}`.
Use the `shq` template function when inserting item or input data into a shell command.
### Fence outside content in a prompt
A pull request body, an alert, or a webhook payload can contain text that reads like instructions. Wrap it in `{{ untrustedStart }}` and `{{ untrustedEnd }}` so the agent can tell where your prompt stops and the item starts:
```yaml
prompt_template: |
Triage this alert.
{{ untrustedNotice }}
{{ untrustedStart "source" "grafana" }}
{{ .Payload.title }}
{{ .Payload.url }}
{{ .Payload.body }}
{{ untrustedEnd }}
```
The helpers render an opening and closing tag, `>` and `>`. The id changes on every run, so a closing tag copied into the item's text cannot close the fence. `{{ untrustedNotice }}` renders a sentence that tells the agent what the tags mean, so put it before the fence. Pass key/value pairs to `untrustedStart` to add attributes to the opening tag, such as `{{ untrustedStart "source" "grafana" "kind" .Payload.kind }}`. Attribute values are escaped. The same helpers work in a notify node's templates.
Hive does not fence anything for you. Every value goes into the prompt exactly as the template writes it, so decide for each field:
| Field | Who wrote it | Fence it in a prompt? |
| --- | --- | --- |
| `{{ .Payload. }}`, `{{ .Raw }}` | The source: a PR author, an issue reporter, an alerting tool, a webhook sender | Yes, including short fields like `title` and `author` |
| `{{ .Payload.repo }}`, `{{ .Payload.num }}`, `{{ .Payload.url }}` on a GitHub or Gitea item | The forge, which fixes their shape | Optional. They can stay outside the fence to tell the agent what to work on |
| `{{ .Key }}` | Built from the item's id | Yes for webhook items, whose sender picks the id |
| `{{ .Inputs. }}` | You, when you run the action | No |
| `{{ .Session.* }}`, `{{ .Window.ID }}` | Hive | No |
Fence only text an agent reads, such as `prompt_template`. In a shell command a fence does nothing; quote values with `shq` instead. The starter actions and the New Session draft built from an item already fence the item's text.
## Run a command after the session starts
A `launch-session` action can run a `post_hook` once the session exists. The command runs in the new checkout with your shell's `PATH`, so it can check the pull request out and open your editor on it:
```yaml
- id: review-pr
label: Review PR
type: launch-session
applies_to: [pr]
repo_template: "https://github.com/{{ .Payload.repo }}.git"
prompt_template: "Review pull request #{{ .Payload.num }}"
post_hook: "gh pr checkout {{ .Payload.num }} && zed ."
post_hook_timeout: "2m"
```
The hook reads the same template fields as the action, plus `{{ .Session.Path }}` and `{{ .Session.Slug }}` for the session that was just created. `post_hook_timeout` defaults to one minute. A hook that fails leaves the session in place and reports its output in the action's run log.
## Where actions run
Use `targets` to choose where an action appears:
```yaml
- id: run-tests
label: Run tests
type: shell
targets: [session]
timeout: "10m"
command_template: "mise run test"
```
`item` is the default target. `session` and `window` add the action to row menus in Code. A `launch-session` action only supports item targets.
Item actions run independently. A long shell action stays **Running** until its command exits, while later manual and flow actions can continue. Hiding the window leaves it running; quitting Hive cancels it. Shell actions capture output but do not provide terminal input.
## Read what a run did
**Action runs** lists every run of an `actions.yml` action, newest first, whether you started it from an item or a flow started it. Open it from the views menu in the title bar, with g then l, from the command palette, from **View log** on an item's action, or from the jobs menu.
Select a run to read its log: the command line, its stdout and stderr in the order they were written, and the exit status. A session launch or a published message logs the steps it took instead. A running action's log updates as it runs, and you can cancel it from there. Automatic retries appear as separate attempts.
Hive keeps the newest 100 finished runs with their full logs; change that with `retention.action_runs` in `settings.yaml`. A single attempt that writes more than 8 MiB is truncated there. Notify and launch nodes, and actions run from a terminal session or window, do not appear here.
A flow runs its named action for every routed item, regardless of `applies_to`. Flow actions cannot use the clipboard. A `launch-session` flow action needs `repo_template` or `workspace`, and required inputs need defaults.
A manual `launch-session` action with neither fixed target opens a dialog where
you can choose a repository or an agent workspace. `agent` and `post_hook` apply
only to repository sessions. A fixed workspace target cannot use either field.
## Quick terminals
Quick terminals open a tool in the pop-up terminal. Configure them under **Settings ▸ Quick terminals** or in the `launchers` list:
```yaml
launchers:
- id: lazygit
label: lazygit
command: lazygit
```
A launcher without `cwd` uses the active terminal directory. A launcher with `cwd` is available from anywhere. Launchers also appear in the command palette and can have keyboard shortcuts.
!!! tip "Ask the Hive workspace"
The **Hive** workspace in **Chats** can update `actions.yml` with the `hive-actions` skill.
---
# Menu bar
The Hive icon in the menu bar lists the feeds you pin, so you can see what is waiting and act on it without opening the main window.
## Pin feeds
Open **Settings ▸ Menu bar** and choose up to three feeds. Each pinned feed lists its newest items, three by default. You can set the limit per feed, from 1 to 10. Reorder the list with the arrows. The menu shows feeds in the same order.
Each feed's heading shows where it lives, as **Profile › Folder › Feed**. A feed outside a folder shows **Profile › Feed**. Click the heading to open the whole feed. When a feed has more items than its limit, the menu adds a **more** entry that also opens it.
## The dropdown
- Each item row shows the item's title. A dot marks an unread item.
- **Refresh** polls every source now.
- **Profiles** lists your profiles. Click one to open it in Hive.
- The footer shows when Hive last polled your sources.
## Item actions
Each item has a submenu:
- **Open in Browser** and **Copy Link**, when the item has a URL.
- **Open in Hive** selects the item in the main window.
- Your configured [actions](https://hivedesktop.com/desktop/inbox/actions/) that apply to the item.
The menu runs only actions that need nothing more from you. Clipboard actions copy their text straight away. An action that asks for input, or one that opens the New Session dialog, is available only from the item in the main window. If an action already ran for the item and needs confirming, or if it fails, Hive opens the item so you can take it from there.
## settings.yaml
Pins are stored in `settings.yaml`, so they sync with the rest of your settings:
```yaml
menu_bar:
feeds:
- feed: work/reviews # /
limit: 5
- feed: work/mentions # three items, the default
```
A pin that names a feed that no longer exists is skipped.
---
# Terminal mode
Open **Code** with g then c. Select a session to attach to its tmux windows.
## Requirements
Hive needs tmux 3.2 or newer for Code, Chats, and quick terminals.
```sh
brew install tmux
```
Hive searches your login shell's `PATH` and common package manager locations. Set `paths.tmux` in [Settings](https://hivedesktop.com/desktop/configuration/settings/#advanced-configuration) if the binary is elsewhere.
The local HTTP server must also be enabled. It is on by default.
## Hive CLI compatibility
Code uses the same session records, isolated checkouts, and tmux sessions as the [hive CLI](https://hivedesktop.com/cli/getting-started/) when both use the same Hive data root. This is the default. Create, start, recycle, or delete a session from either interface and the other sees the same result.
Use the hive CLI config, commonly `~/.config/hive/config.yaml`, to configure the shared session engine:
- repository search paths and agent profiles;
- repository rules, clone strategies, and recycled checkouts;
- setup commands and the tmux windows or panes created for a new session.
Hive Desktop reads that file when it starts, so restart the app after changing it. Desktop-only settings such as terminal appearance, shortcuts, quick terminals, Inbox flows, and Chats workspaces remain under the Desktop config root, commonly `~/.config/hive/desktop/`.
See the hive CLI documentation for [sessions](https://hivedesktop.com/cli/getting-started/sessions/), the [configuration reference](https://hivedesktop.com/cli/configuration/), and [repository rules](https://hivedesktop.com/cli/configuration/rules/).
## Sessions
Code lists active Hive sessions and their tmux windows. Closing Hive leaves those sessions running. You can attach to the same session from another terminal with `tmux attach`.
If a session has no running terminal, select **Start session**. Hive creates its configured windows and starts the agent. This starts a new agent process and does not resume the previous terminal process.
Startup failures stay in a copyable report with the failed command and available terminal output. If tmux terminates later, Hive keeps a termination notice even when exit details are unavailable. **Restart** starts a new process. It also recovers a session whose launch did not finish, for example after Hive quit during a start. **Reconnect** restores a lost connection to a session that may still be running. Reports survive switching sessions within the app, but not an app restart.
A setup command that exits successfully does not stop healthy panes. If every configured command finishes successfully and no terminal remains, the panel shows **Session completed**.
**Kill terminal** stops the tmux session and its processes while keeping the checkout and Hive session record. **Recycle** and **Delete** also change or remove the checkout.
For repository sessions, the optional status bar shows the branch, changes against the default branch, uncommitted work, and unpushed commits. Connected GitHub, Gitea, and Forgejo repositories also show pull request, review, and check state. Use the status bar to open the checkout in your editor or file manager.
## Scratch terminals
The **Terminals** section holds a scratch tmux session for shells that are not tied to a repository. Use its `+` button or ⌘T to add tabs.
Scratch tabs can be selected, renamed, reordered, and closed. The session keeps running when Hive closes. **Kill terminal** stops every scratch tab.
## Pop-up terminal
Press ⌘` on macOS or Ctrl+` on Linux to open a shell over any area. In Code, it starts in the active pane's directory. Elsewhere, it starts in your home directory.
Hide the panel to keep its shell running, or use **End this terminal** to stop it. Quick terminal launchers use the same panel for tools such as `lazygit`, test watchers, and process monitors. See [Actions](https://hivedesktop.com/desktop/inbox/actions/#quick-terminals).
## Working in Code
### Image input
Drag image files onto the terminal pane, or paste a screenshot from your
clipboard with ⌘V on macOS. This works in Code, Chats, and pop-up
terminals. Hive inserts an image reference; add your instructions and submit
the prompt yourself. The agent must support image input and run on the same
filesystem as Hive.
PNG, JPEG, GIF, and WebP files are supported, up to 20 MiB and 64 megapixels
each. A gesture can include up to 10 images totaling 64 MiB. Unsupported or
oversized images show an error. Switching away during preparation cancels
insertion; a paste already sent can finish in its original pane.
Clipboard images are saved under `desktop/assets/terminal-images/` inside the
data directory shown in **Settings ▸ System**. They survive restarts so resumed
conversations can still read them. Storage is limited to 1 GiB. Remove files
you no longer need from that directory to free space; conversations that still
reference removed files cannot read them again. Dragged files stay at their
original location.
### Images in output
Images that Pi draws with the Kitty graphics protocol show in Chats, Code
panes, and pop-up terminals. Hive Desktop sets `PI_IMAGE_PROTOCOL=kitty` on the
chats, sessions, agent windows, and pop-ups it starts. A session started from
the hive CLI, or from a rule that uses `spawn:` commands instead of `windows:`,
does not get it: set `PI_IMAGE_PROTOCOL=kitty` in that session's environment
yourself.
When you reopen a session or the terminal resyncs, Hive narrows the window by
one column for a moment so Pi redraws its images. A program that does not
redraw on a resize shows its text without the image.
### Navigation
- Select a window from the sidebar to attach to it.
- Use ⌘1 through ⌘9 to switch windows.
- Use ⌘← to focus the sidebar and ⌘→ to return to the terminal.
- Use ⌘B (Windows/Linux: Ctrl+B) to show or hide the left sidebar, including while a terminal has focus.
- Press / while the sidebar is focused to filter sessions.
- Press ⌘F in a terminal to search its recent scrollback.
- Drag windows in the sidebar to reorder them.
Press ? for the current shortcut list. Shortcuts can be changed under **Settings ▸ Keyboard**.
Actions can add commands to session and window menus. Quick terminals can open tools such as `lazygit` in the active checkout. See [Actions](https://hivedesktop.com/desktop/inbox/actions/).
## Panes
A window shows every tmux pane where tmux lays it out, including panes split from another tmux client. The pane with the keyboard is tmux's active pane, so a click in a pane also selects it in tmux.
- ⌘D splits the active pane to the right and ⌘⇧D splits it downward. The new pane opens in the active pane's directory.
- ⌘⌥←, ⌘⌥→, ⌘⌥↑, and ⌘⌥↓ move between panes.
- Drag the border between two panes to resize them.
- ⌘⇧↩ zooms the active pane to fill the window, and again to restore the layout. A `zoomed` badge shows while a pane is zoomed.
- ⌘⇧W closes the active pane. Closing the last pane closes the window. Hive asks first when the pane is running something.
On Linux, Ctrl+Shift+D splits right, Ctrl+Shift+O splits down, Ctrl+Alt with the arrow keys moves between panes, Ctrl+Shift+M zooms, and Ctrl+Shift+Q closes the pane.
## Tasks
Open **Tasks** from the Code status bar, the command palette, or its configured shortcut. It reads the same `hive hc` task tree used by coding agents and the CLI. See the hive CLI [task tracking guide](https://hivedesktop.com/cli/getting-started/task-tracking/) for the shared task model.
Filter by status or repository, search by title or ID, and inspect epics, subtasks, blockers, comments, checkpoints, and linked sessions. You can change task status, follow blocker links, and prune completed work from the Tasks toolbar.
## Drive
An agent in a Code session can publish documents to Drive the same way a chat does. Hive does not change your agent's configuration, so add the server yourself. **Settings ▸ MCP servers** shows the address of the Hive Drive server and the command or config entry for Claude Code, Codex, and other agents. For Claude Code it is:
```bash
claude mcp add --scope user --transport http hive-drive http://127.0.0.1:/mcp/drive
```
The address stays the same across restarts. An agent already set up with `/mcp/canvas` keeps working. The server needs the local HTTP server, which is enabled by default. An empty Drive pane in Code links to the same settings page.
Open the Drive pane beside a session with the right-panel button in the title bar. A session's documents belong to its repository, so every session of that repository shows the same ones, and they remain after the session is deleted. They are in `///` under the hive context directory, which `hive drive init` links into a checkout as `.hive`, so a file you write to `.hive/plans/` shows in the pane within a second.
The pane, the Drive page, search, reorganizing, and the document tools work as they do in [Chats](https://hivedesktop.com/desktop/chats/agent-workspaces/#drive). A scratch terminal has no Drive pane.
An agent outside any chat or Code session, such as one you start in a plain terminal, can still write documents: it passes `global` as its session, and every such agent shares the Shared space. It has no pane. Read it on the Drive page under **Shared**, or find a document by name in the command palette.
## Appearance
**Settings ▸ Terminal** controls the terminal font, size, weight, line height, letter spacing, visible windows, status bar, and session age badges. Age badges are on by default with a five-day threshold and appear once a Hive session reaches the configured number of whole days since creation. Scratch terminals and pinned chats do not get one.
⌘+ and ⌘- step the text size by 2px from a terminal without opening Settings, up to 64px, and ⌘0 puts it back to 13px. On Linux, use Ctrl+Shift with the same keys.
## Shared tmux sizing
All clients attached to a tmux session share one grid size. If the terminal does not fill the available pane, another attached client may be setting the size.
Detach or resize the other client, or add this to `tmux.conf`:
```text
set -g window-size largest
```
## Current limits
- Hive loads up to 2,000 lines of scrollback.
- A large output burst can skip intermediate lines while the view resynchronizes.
---
# Agent workspaces
The **Chats** area runs coding agents in persistent workspaces. Open it with g then a.
A workspace contains its instructions, chats, launch command, skill packages, MCP servers, schedules, and a Drive space for the documents agents write. Chats run in tmux, so they can continue when you switch views or restart Hive.
## Requirements
- tmux 3.2 or newer;
- an agent CLI or custom launch command available on Hive's `PATH`.
Hive includes command presets for Claude Code and Codex. A custom command can start another agent CLI or wrap a preset with model flags, environment variables, or other tools. See [Troubleshooting](https://hivedesktop.com/desktop/getting-started/troubleshooting/#a-coding-agent-is-not-found) if Hive cannot find a command.
## The Hive workspace
Hive creates a built-in workspace named **Hive**. Use it to configure flows, sources, actions, settings, shortcuts, webhook sources, and other workspaces.
Open the workspace and describe the change you want. Its shipped skills know the local config paths and the app's current schemas. Its default command asks before making changes.
## Create a workspace
Use **New workspace** in Chats. A workspace chooses:
- a name and directory;
- a launch command;
- skill packages;
- MCP servers;
- optional schedules.
The command picker includes **Ask**, **Auto**, and **Full** presets for Claude Code and Codex. **Custom** lets you edit the complete command template. Add model or provider flags to the command itself.
Schedules, feed-item launches, and chats started with a prompt need a command
that passes the opening prompt as a shell-quoted argument. Keep this suffix from the shipped presets:
```text
{{ if .Prompt }}-- {{ .Prompt | shq }}{{ end }}
```
Hive refuses a prompted launch if the custom command drops `.Prompt` or
interpolates it without `shq`. For prompts larger than 32 KiB, `.Prompt` is a
short instruction to read and delete a private temporary file containing the
full text.
**Full** presets bypass the agent's approval checks. Use them only when you trust the workspace instructions and every enabled tool.
## Work with chats
Create several named chats inside a workspace and use the sidebar to see whether each agent is working, needs approval, is running, or is stopped.
Stopping an agent keeps its chat record. Restarting a stopped chat resumes the conversation when its command and agent support it. You can also rename or delete a chat, filter the sidebar, and open recent chats from the command palette.
Drag image files or paste clipboard screenshots into a chat's terminal to give
the agent visual context. See [Image input](https://hivedesktop.com/desktop/code/terminal-mode/#image-input)
for supported formats, limits, and saved clipboard images.
Images that Pi draws show in the chat's terminal. Hive sets
`PI_IMAGE_PROTOCOL=kitty` for chats it starts. See
[Images in output](https://hivedesktop.com/desktop/code/terminal-mode/#images-in-output).
An Inbox item's **…** menu offers **Create Session** for Code and **Create Chat**
for Chats. Both open the same dialog on the requested target; use its compact
**Code** / **Chats** switch to change targets. A chat keeps the generated item
prompt, which you can edit before launch. A `launch-session` action with a fixed
`workspace` can do the same from a manual item action or a flow. See
[Actions](https://hivedesktop.com/desktop/inbox/actions/#action-types).
## Scheduled jobs
Add a schedule from the workspace editor to start a chat automatically. Schedules can run hourly, daily, weekly, monthly, or from a five-field cron expression in your local time.
Each schedule has its own prompt and controls to:
- pause or resume future runs;
- run it immediately without changing the next scheduled time;
- launch once after Hive reopens or skip a run missed while the app was closed;
- preview upcoming times and inspect recent launched, skipped, or failed runs.
Scheduled chats run unattended. If the previous scheduled chat is still active, Hive skips the next occurrence instead of starting overlapping work. Ask the agent to save durable output to a canvas or workspace file.
## Workspace files
Workspaces live under `~/.config/hive/desktop/workspaces/` by default. **Settings ▸ Chats** shows the current root. To move it, set `agent_workspaces.dir` in `settings.yaml` and restart Hive.
Each workspace has an `agent-workspace.yaml` manifest and an `AGENTS.md` instruction file. Hive generates agent-specific configuration when the workspace opens. Put lasting instructions in `AGENTS.md` because generated files are replaced.
## Skills
A workspace selects skill packages, such as the built-in `hive` package. Packages can include shipped skills and custom skills from the shared workspace folder.
A skill that only one workspace needs does not have to go in the shared folder. Write it, or ask the workspace's agent to write it, into the workspace's `.claude/skills//SKILL.md` (or `.agents/skills/` for agents that read that folder). Hive keeps it when the workspace opens and only replaces skills that its packages install. A package skill with the same name overwrites it.
The built-in Hive package covers:
- flows and sources;
- actions and quick terminals;
- settings and keybindings;
- agent workspaces;
- the Hive Desktop MCP server.
## MCP servers
Hive includes these MCP entries:
- **Hive Desktop** for reading and configuring the running app. It requires the local HTTP server, which is enabled by default.
- **Hive Drive** for durable Markdown, HTML, and canvas documents beside a chat.
- **Playwright** for browser automation. It requires Node.js and a Playwright browser.
- **Chrome DevTools** for a running Chrome browser. It requires Node.js 20.19 or newer and Chrome.
You can add HTTP, SSE, and stdio servers to the shared MCP library, then enable them per workspace. Secrets in custom server configuration can use `env:`, `file:`, or `op://` references.
## Drive
Drive is the folder tree of documents that agents and you share. It holds Markdown, HTML, and canvas documents in folders, and it outlives any chat. The [hive CLI](https://hivedesktop.com/cli/getting-started/context/) reads the same tree.
### Where it shows
- **The pane.** The right-panel button in the title bar opens the Drive pane beside a chat. It has a header, the workspace's folder tree, and a reader for the selected document.
- **The Drive page.** Open it from the views menu (**Drive**), the command palette, or ⌘⇧P (Windows/Linux: Ctrl+Shift+P) or g then v. It takes the whole window, like Settings, and opens on the document the pane shows when a chat or Code session is on screen. Its picker groups spaces as **Repositories**, **Workspaces**, and **Shared**. Press Esc, ⌘⇧P again, or the close button to return to the view you came from. The page is a place in history, so Back returns to it, and a document on it has a link you can open again.
Search in the pane or on the page looks across every space. Copy a document as Markdown, save it to a file, or open its links from the reader. A Markdown link to another document in the space opens it in place.
### Document kinds
- **Markdown** (`.md`) renders with its front matter shown above it.
- **HTML** (`.html`) runs in a sandbox. Scripts run inside the frame. The page cannot call Hive or send requests to localhost. It can load `https:` content.
- **Canvas** (`.canvas.json`) is a document of blocks that an agent builds: Markdown, Mermaid diagrams, sanitized HTML, and links.
Use a standalone `mermaid` fence inside a Markdown block for a diagram. Mermaid diagrams follow the current theme. Drag a diagram to pan, use its controls to zoom or fit it, or hold Control/Command while scrolling to zoom around the pointer. An invalid diagram shows an error in place without hiding the rest of the canvas.
A Markdown document or a canvas can include front matter such as tags, status, or an owner. Hive displays it above the document. A canvas also shows automatic creation and update times. Collapse **Properties** to hide it; Hive uses that choice for every document. Agents replace a canvas's editable front matter with the `set_frontmatter` tool; `created_at` and `updated_at` are reserved and updated by Hive. Values can be text, numbers, booleans, empty values, or lists of those values. Copy and save include the metadata as YAML front matter and preserve Mermaid source in a fenced `mermaid` block.
**Settings ▸ Drive** changes text size, line spacing, and text width for every document, in Chats and in Code. The text runs at a narrow reading width by default. **Wide** fits HTML laid out in columns, and **Full** runs to the edges of the view.
### Comment on a document
Select text in a Markdown document, in the pane or on the Drive page, and a comment box floats under it with the selection marked; drag it by its top row to move it out of the way. To comment on a whole paragraph, list item, heading, code block, or table, point at it and click the comment button beside it in the margin. While nothing else has focus, the keyboard goes to the box:
- Start typing to write a comment, then press ⌘↵ or **Add Comment**.
- Press 1 to 4 to apply a label: **Clarify this**, **Verify this**, **Needs tests**, or **Looks good**. The icons in the box are the same labels. Text you typed first follows the label. Change them under **Settings ▸ Drive ▸ Comment labels**, or with `review.labels` in [settings](https://hivedesktop.com/desktop/configuration/settings/).
- Press Esc to close the box.
A comment is anchored to the text you selected and the lines it is on, and that text is highlighted. On the Drive page, comments sit in a column beside the document, each on the row of its text; drag the column's edge to resize it. In the pane, the comments button in the pane header shows them over the document. On the Drive page, the title bar's right button shows or hides the column. **Toggle comments** in the command palette, or ⌘⇧M, does the same on either surface. Select a comment to scroll to its text, or highlighted text to find its comment; every comment has **Edit** and **Delete**. Write a note for the agent at the bottom of the column.
- **Copy All** puts the feedback on the clipboard: the document's path, then a numbered entry for the note and for each comment in document order, with its lines and the text it is about. The comments stay.
- **Send to Agent** (⌘↵ in the note) opens a list of the agents running now, in Code sessions and chats, with their status. The agent beside the pane is listed first. Sending pastes the feedback into the agent as one message, submits it, and clears the comments. An agent that is working gets it mid-turn; an agent waiting on a prompt cannot be picked until the prompt is answered.
- **Clear**, the trash button in the comments header, deletes the comments and the note after asking.
Comments are kept in Hive's database, not in the file, and survive a restart. If the document changes after you comment, the panel says the comments are on an earlier version. Send, copy, or discard them before adding new ones. Renaming or moving a document leaves its comments behind.
### Reorganize
You can reorganize the tree without an agent running. Create a folder, rename a document or folder, move it into another folder in the same space, or delete it from a row's menu. You can also drag a document onto a folder. Delete works on a document or an empty folder, and asks for confirmation. Deleting a document removes it for every chat or Code session that shares the space.
### Files on disk
Drive is a folder on disk under the hive context root, `~/.local/share/hive/context/` unless `context.base_dir` moves it:
| Space | Folder |
| --- | --- |
| A repository | `///` |
| A Chats workspace | `/workspaces//` |
| Shared | `/shared/` |
A [Code session's](https://hivedesktop.com/desktop/code/terminal-mode/#drive) checkout links its space as `.hive`. Drive refreshes within a second when a file changes on disk, so a document you write from a terminal or edit in Obsidian appears without a reload. Deleting a workspace or a chat leaves its documents in place.
### Let an agent write
An agent with **Hive Drive** enabled can publish documents beside its chat. The seeded Hive workspace has it on. The MCP server is at `/mcp/drive`; the older address `/mcp/canvas` answers the same server, so existing agent setups keep working. The six document tools are:
- `list_documents`
- `read_document`
- `write_document`
- `move_document`
- `delete_document`
- `open_document`
The ten canvas tools remain. A canvas name can include folders, so `reports/perf` is filed as `reports/perf.canvas.json`, and a bare name is filed under `canvases/`. An agent can only write `.md` and `.html` documents with `write_document`. `read_document` reads markdown, html, and any other text file in the space.
A repository with no documents yet links to the setup in **Settings ▸ MCP servers**.
## Use a chat in Code
Pin a chat to the Code session tree when you want it beside repository terminals. It attaches to the same tmux session from either area. Unpinning it does not stop the agent.
---
# Settings
Open Settings with ⌘, or from the command palette.
## In the app
Settings shows or changes:
- general behavior such as polling and the default editor;
- the theme, interface fonts, and terminal typography;
- terminal spacing, visible windows, the status bar, and session age badges;
- keyboard shortcuts;
- notification delivery and sound;
- the feeds pinned to the menu bar;
- connected source accounts and the local webhook listener;
- actions and quick terminals;
- the agent workspace folder location;
- the addresses of the MCP servers Hive hosts, and how to add one to your own agent;
- the optional Hive CLI compatibility config;
- diagnostics, updates, and release channels.
The app validates changes before saving them.
## Configuration files
Hive Desktop and the hive CLI use separate configuration paths. They share Code sessions and tasks when both use the same Hive data root, which is the default.
| Scope | Common default | Configures |
| --- | --- | --- |
| Hive CLI and Code session engine | `~/.config/hive/config.yaml` | Repositories, agent profiles, clone and recycle rules, setup commands, starting tmux windows, and shared session behavior |
| Hive Desktop | `~/.config/hive/desktop/` | Inbox, Code presentation, Chats, notifications, integrations, shortcuts, and app behavior |
The hive CLI config honors `HIVE_CONFIG` and `XDG_CONFIG_HOME`. The Desktop config honors `HIVE_DESKTOP_CONFIG_DIR` and `XDG_CONFIG_HOME`. Hive Desktop reads the hive CLI configuration at startup, so restart it after editing that file.
Session and task sharing also depends on the data root. The common default is `~/.local/share/hive/`. If you move it, set `HIVE_DATA_DIR` in your shell profile. The hive CLI uses it, and Hive Desktop reads it from your login shell, so it applies even when you open the app from the Dock. Hive Desktop picks the data root in this order:
1. `HIVE_DESKTOP_HIVE_DATA_DIR`, for pointing only Hive Desktop somewhere else
2. `HIVE_DATA_DIR`
3. the Hive Desktop data root (`HIVE_DESKTOP_DATA_DIR`, or `~/.local/share/hive/`)
Hive Desktop logs the data root it picked at startup. If your login shell fails or takes more than a few seconds to start, the app cannot read `HIVE_DATA_DIR` for that run. It falls back to its own data root, so your sessions and tasks look missing until the next launch, and it logs a warning that names the directory it used.
See the hive CLI [configuration reference](https://hivedesktop.com/cli/configuration/) and [repository rules](https://hivedesktop.com/cli/configuration/rules/).
Hive Desktop keeps these files under its config directory by default:
| Content | Path |
| --- | --- |
| Settings | `settings.yaml` |
| Flows | `flows/` |
| Actions | `actions.yml` |
| Agent workspaces | `workspaces/` |
| Desktop application data | `~/.local/share/hive/desktop/` |
| Shared CLI and Desktop log | `/hive.log` |
| Account tokens | OS keychain |
Set `HIVE_DESKTOP_CONFIG_DIR` or `HIVE_DESKTOP_DATA_DIR` to move the config or Desktop data root. You can also move the flow, action, and workspace paths separately. The shared log follows the Hive data root described above, not a separate Desktop data-root override when `HIVE_DATA_DIR` or `HIVE_DESKTOP_HIVE_DATA_DIR` selects another location. Settings ▸ Hive CLI and Settings ▸ System show the effective paths.
A `settings.yaml` key this version does not know, for example one a newer version wrote into a synced config directory, does not stop the app. Startup logs a warning naming the key and ignores it, so the in-app updater stays available. Saving settings from that version drops the key.
!!! tip "Ask the Hive workspace"
The **Hive** workspace in **Chats** can update settings with the `hive-settings` skill. For example, ask it to change the polling interval or terminal font.
## Hive CLI compatibility config
Hive Desktop includes the Hive runtime it needs. A separately installed [Hive CLI](https://hivedesktop.com/cli/getting-started/) is not required.
If you use the Hive CLI, Desktop also reads its optional configuration file at startup. It checks `HIVE_CONFIG` first, then looks for `config.yaml`, `config.yml`, `hive.yaml`, or `hive.yml` under `$XDG_CONFIG_HOME/hive/` with `~/.config/hive/` as the fallback. No file is required. Hive uses built-in defaults when none exists.
First run asks for the two settings Hive Desktop needs from that file — the agents a session can start with, and the parent folders holding your repositories — and writes them; see [Set up your agent and code](https://hivedesktop.com/desktop/getting-started/agent-and-repos/). Everything else in the file is left as written: rules, tmux settings, keybindings, user commands, and any agent profile with a command of its own.
Change any of it later by editing the file yourself, then restarting Hive Desktop. The hive CLI [configuration reference](https://hivedesktop.com/cli/configuration/) describes every key.
**Settings ▸ Hive CLI** shows the exact path selected at startup, and lets you copy it, open or reveal an existing file, or create a missing one and open it. It also tells you when the file no longer parses, which is worth checking after a hand edit.
`HIVE_DEFAULT_AGENT` takes precedence over the default agent you choose, when it names a configured profile. The screen says so when the variable is set.
## Advanced configuration
Most users can use the Settings screens. Edit `settings.yaml` for values that are not exposed there or when you manage configuration with dotfiles.
```yaml
polling:
interval: 5m
http:
enabled: true
host: 127.0.0.1
port: 0
paths:
tmux: ""
editor:
command: ""
agent_workspaces:
dir: ""
appearance:
terminal_show_session_age: true
terminal_session_age_threshold_days: 5
retention:
action_runs: 100
review:
labels:
- title: Clarify this
icon: circle-help
- title: Needs tests
icon: flask-conical
```
- `polling.interval` has a minimum of 60 seconds.
- The local HTTP server provides webhooks, MCP, and terminal connections. It only binds to loopback. Set a fixed port if another local tool needs a stable webhook URL.
- `paths.tmux` accepts an absolute path when Hive cannot find tmux.
- `editor.command` accepts an executable name or absolute path without arguments.
- `agent_workspaces.dir` changes where Chats workspaces are stored.
- `retention.action_runs` is how many finished action runs **Action runs** keeps, each with its full log. It defaults to 100 and accepts 1 through 10,000. A change takes effect the next time Hive starts.
- `review.labels` replaces the labels the comment box on a Drive document offers, up to four. **Settings ▸ Drive ▸ Comment labels** edits the same list. Keys 1 to 4 follow the list order. `icon` is one of `circle-help`, `search-check`, `flask-conical`, `check`, `tag`, `triangle-alert`, `lightbulb`, `scissors`, or `x`; any other value shows a tag. Titles must be unique. Leave the key out for the default four. A change shows the next time the comment box opens.
- `appearance.terminal_show_session_age` shows a whole-day age badge in the Code sidebar after `terminal_session_age_threshold_days` days. It defaults to on with a five-day threshold. The threshold accepts 1 through 365.
Every scalar setting can be overridden for one launch with an environment variable based on its YAML path. For example, `polling.interval` becomes `HIVE_DESKTOP_POLLING_INTERVAL`.
## Updates
**Settings ▸ About** shows the current channel and controls automatic update checks.
To follow a different channel, edit `settings.yaml`:
```yaml
updates:
channel: beta
```
Available channels are Stable, Beta, and Dev. Every release is published to all three, so each channel currently carries the same version. An omitted channel follows the channel used for the current build.
## Telemetry
**Settings ▸ Observability** shows the app's current CPU, memory, process tree, Go runtime, and UI frame behavior. Process data updates while the page is open. UI frame sampling also runs only while this page is open.
The same page reports the status of two independent Grafana Cloud exports:
- **Metrics, logs, and traces** use an OTLP endpoint.
- **Continuous profiles** use a Pyroscope-compatible Grafana Cloud Profiles endpoint.
Each card shows whether the destination is enabled and configured, plus whether it is **Exporting**, **Ready**, waiting for a restart, or failed to start. Exporting means Hive started the local exporter. Check Grafana Cloud or the Hive log for later delivery failures. A change in `settings.yaml` requires a restart.
Grafana Cloud provides different URLs and basic-auth users for OTLP and Profiles. A Cloud Access Policy token can serve both when it includes `profiles:write`, but configure each destination separately in `settings.yaml`:
```yaml
telemetry:
enabled: true
endpoint: https://otlp-gateway-prod-us-central-0.grafana.net/otlp
instance_id: "123456"
host_id: "fdbf79e8af94cb7f9e8df36789187052"
token: op://Private/Grafana Cloud/otlp-token
profiles:
enabled: true
endpoint: https://profiles-prod-us-central-0.grafana.net
user: "123456"
token: op://Private/Grafana Cloud/profiles-token
```
`telemetry.host_id` is optional. Set it to the machine id to add the OpenTelemetry `host.id` resource attribute to metrics, logs, and traces. Profiles use the same value as their `host_id` label. Hive does not read a machine id automatically. Each app launch gets a random OpenTelemetry `service.instance.id`. `telemetry.instance_id` has a different purpose: it is the OTLP endpoint's basic-auth username.
Profile export collects CPU, allocation, and in-use heap profiles. It does not collect goroutine, mutex, or block profiles. OTLP and profile export can run independently.
Tokens must use `env:`, `file:`, or `op://` references. Hive rejects literal telemetry tokens in the settings file. Endpoints and users may also use these references.
A ready-made Grafana dashboard for these signals is in the repository's [`cmd/desktop/grafana/`](https://github.com/colonyops/hive/tree/main/cmd/desktop/grafana) directory. Push it to your stack with [gcx](https://github.com/grafana/gcx). Its README maps each metric, span, and profile to the query that reads it.
---
# Keyboard shortcuts
Press ? to see the current shortcuts. **Settings ▸ Keyboard** shows the same list, reports conflicts, and lets you change each binding.
The command palette at ⌘K can run commands with or without a shortcut.
## Common shortcuts
| Action | Shortcut |
| --- | --- |
| Open command palette | ⌘K |
| Open shortcut list | ? |
| Search the current view | / or ⌘F |
| Find in a Code terminal | ⌘F (Linux: Ctrl+Shift+F) |
| Open Settings | ⌘, or g then s |
| Show or hide the current sidebar | ⌘B (Windows/Linux: Ctrl+B) |
| Show or hide the right panel | ⌘⌥B (Windows/Linux: Ctrl+Alt+B) |
| Show or hide a document's comments | ⌘⇧M (Windows/Linux: Ctrl+Shift+M) |
| Go to Inbox | g then i |
| Go to Code | g then c |
| Go to Chats | g then a |
| Show or hide action runs | g then l |
| Refresh a feed | r |
| Move through feed items | j/k |
| Open an item | o or Enter |
| Archive an item | e |
| Increase or decrease terminal text size | ⌘+/⌘- (Windows/Linux, from a terminal: Ctrl+Shift+=/Ctrl+Shift+-) |
| Reset terminal text size | ⌘0 (Windows/Linux, from a terminal: Ctrl+Shift+0) |
Use ? for the full list because it always matches the installed version.
## Rebinding
You can change shortcuts in the app or in `settings.yaml`:
```yaml
keybindings:
feed.next: [j, arrowdown]
launcher.lazygit: [alt+g]
tasks.toggle: ["g t"]
palette.toggle: []
```
The map only needs entries you want to change. An empty list removes a binding.
Use lower-case key names and join modifiers with `+`, such as `mod+shift+t`. `mod` means Command on macOS and Control on other platforms. Separate keys with a space for a sequence such as `g i`.
## Terminal shortcuts
A focused terminal sends most keys to the running program. A shortcut works from a terminal when it starts with Command on macOS, or with Control on Linux, where you press it with Control+Shift from inside the terminal. Shortcuts without one of those, such as g then i, only work outside a terminal, so typing `git` always reaches the shell.
This applies to shortcuts you add yourself. To switch to the inbox from a terminal, add a binding such as ⌘I or ⌘G then i to **Go to Inbox**. In **Settings ▸ Keyboard**, a terminal icon next to a shortcut shows that it works from a terminal and how to press it there.
On Linux, a shortcut whose first key already uses Shift, such as `mod+shift+b`, cannot be reached from a terminal.
**Find** (`terminal.find`) opens the search bar over a Code terminal. Over the session list and other views, ⌘F searches the current view instead.
**Text size** (`terminal.text-size-increase`, `-decrease`, `-reset`) steps the terminal font by 2px a press, between 8px and 64px, wherever a terminal is on screen (a Code session, Chats, or the pop-up panel) and saves the result to the same setting. On macOS these chords no longer zoom the window, and **Zoom In**, **Zoom Out** and **Actual Size** are gone from the **View** menu, because window zoom scales the window instead of reflowing the terminal grid.
**Toggle sidebar** (`terminal.toggle-sidebar`) shows or hides the sidebar in Inbox, Code, Chats, and the Drive page's folder tree. It uses ⌘B on macOS and Ctrl+B on Windows and Linux, including inside a focused terminal. On macOS, Ctrl+B still reaches the terminal. On Windows and Linux, rebind this command in **Settings ▸ Keyboard** if you need Ctrl+B for tmux.
**Toggle right panel** (`view.toggle-panel`) is the same for the right edge, like the title bar's right button: the preview in Inbox, the Drive pane in Code and Chats, and the comments column on the Drive page. **Toggle comments** (`drive.toggle-comments`) shows or hides the comments of the document on screen, on the Drive page or in the Drive pane.
Check **Settings ▸ Keyboard** before assigning a Control shortcut that your shell or terminal program already uses.
---
# Links
!!! note "Experimental"
The link format can change.
Hive Desktop registers the `hive://` URL scheme. Opening a `hive://` link from a browser, a script, or another app raises the Hive window and goes to the place the link names. Hive starts first if it is not running.
A link only navigates. It never creates a session, runs a command, or changes data.
## Link formats
| Opens | Link |
| --- | --- |
| A tmux session in Code | `hive://code/` |
| A window in that session | `hive://code/?window=@3` |
| A Chats workspace | `hive://chats/` |
| A chat | `hive://chats//` |
| A profile's inbox | `hive://inbox/` |
| A feed | `hive://inbox/?feed=` |
| An inbox item | `hive://inbox//` |
| A Drive document | `hive://drive//` |
| A Drive space | `hive://drive/` |
| A canvas | `hive://canvas/?owner=` |
- `` is the tmux session name, so a link can open a session that another tool started, as long as it runs on the same tmux server as Hive.
- A space key is one of three forms:
- `shared` for the Shared space, as in `hive://drive/shared/notes.md`.
- `workspaces/` for a Chats workspace, as in `hive://drive/workspaces/hive/canvases/release.canvas.json`.
- `/` for a repository, as in `hive://drive/colonyops/hive/plans/2026-10-11-drive.md`.
- The path after the key is the document's path inside the space. A link to a space with no path opens that space.
- Add `canvas=` to a Code or chat link to open the Drive pane beside it on that canvas.
- The older canvas link still opens the canvas. Its owner is a Chats workspace, a repository as `owner/repo`, or `@global`.
- Escape special characters in each part, so a canvas named `release plan` is `hive://canvas/release%20plan?owner=colonyops%2Fhive`.
## Open a link from the CLI
`hive desktop open` (or `hive dt open`) checks a link and opens it. `hive desktop --help` lists the formats above.
```bash
hive dt open 'hive://code/my-session?window=@2'
```
## A link does nothing
Both sides log to the shared `hive.log` (see [Report a problem](https://hivedesktop.com/desktop/getting-started/troubleshooting/#report-a-problem) for its path). Search it for `hive://`:
- `opening hive:// link` and `opener accepted hive:// link` come from the CLI. `opener failed` means the OS has no handler for `hive://`, so install Hive Desktop or reinstall it to register the scheme.
- `received hive:// link` means Hive Desktop got the link, and `frontend took hive:// link` means the window started routing to it. `ignoring hive:// link` names the part that did not parse.
- On Linux, `single-instance lock off` means a link starts a second Hive instead of reaching the running one.
!!! note "Installed builds only"
The packaged macOS app and the Linux install script register the scheme. A build run with `mise run desktop:dev` does not receive links.
---
# Build from source
Use the repository's `CONTRIBUTING.md` and `docs/development.md` if you plan to change the code. This page covers a local build.
## Requirements
- Git
- [mise](https://mise.jdx.dev/)
- Node.js 22 and npm
- Docker for Linux builds
- tmux 3.2 or newer for Code and Chats
Windows is not supported.
## Set up
```sh
git clone https://github.com/colonyops/hive.git
cd hive
mise trust
mise install
mise run desktop:frontend:install
```
## Build
```sh
mise run desktop:build
```
The binary is written to `cmd/desktop/bin/hive-desktop`. On macOS, create a local app bundle with:
```sh
cd cmd/desktop && wails3 package
```
For Linux, Docker must be running:
```sh
mise run desktop:build:linux
ARCH=arm64 mise run desktop:build:linux
```
## Run a development build
```sh
mise run desktop:dev
```
Development runs use isolated config and data directories. See `docs/development.md` in the repository for the devserver, fixtures, tests, and quality checks.
---
# Troubleshooting
Open **Window ▸ Diagnostics** on macOS, or **Open Diagnostics** in the command palette on any platform. Check **Activity** for flow, source, and action errors.
## Investigate a failure
Diagnostics combines the Hive log and recent job outcomes in a searchable timeline. Filter by time or severity, or search for a session name. Expand an entry for its original record, parsed fields, and evidence ID. Desktop and CLI records normally share `hive.log`; the service name distinguishes their entries.
The viewer reads a capped recent portion of the log. **Older entries omitted** means the full retained file did not fit in the viewer; reveal `hive.log` to inspect it. Turn off **Live** to hold the view while reading. View options and export actions are in the menu beside Live.
Describe the incident in the prompt and choose **Investigate** to open your configured default agent beside the logs. You can select another profile. The terminal stacks above the logs in a narrow window, and its divider is resizable. Investigation does not need tmux. Opening Diagnostics never starts an agent, and the logs stay available if the agent fails.
**Copy context** and **Export** collect a bounded incident snapshot from the displayed query, including job errors and source status. You can give that context to an agent outside Hive when the built-in investigation cannot start. Snapshots can contain local paths and command output; review them before sharing.
## Hive does not start on Linux
Hive requires GTK 4 and WebKitGTK 6.0. Install their runtime packages, then start Hive again:
=== "Debian or Ubuntu"
```sh
sudo apt install libgtk-4-1 libwebkitgtk-6.0-4
```
=== "Fedora"
```sh
sudo dnf install gtk4 webkitgtk6.0
```
=== "Arch Linux"
```sh
sudo pacman -S gtk4 webkitgtk-6.0
```
Hive supports Ubuntu 24.04, Debian 13, Fedora 40, and newer releases. See the [Wails Linux documentation](https://v3.wails.io/guides/build/linux/) for details about the GTK and WebKitGTK stack.
The terminal installer also adds Hive to your desktop application menu. If you installed an older version of the script or extracted the tarball manually, run the current [terminal installer](https://hivedesktop.com/desktop/getting-started/#install-from-the-terminal) to create the entry.
## tmux is not installed
Code, Chats, and quick terminals require tmux 3.2 or newer.
```sh
brew install tmux
```
Return to Code after installation. Hive checks again without a restart. If tmux is installed in an unusual location, set `paths.tmux` in [Settings](https://hivedesktop.com/desktop/configuration/settings/#advanced-configuration).
## A coding agent is not found
Hive currently supports the `claude` and `codex` commands. Check the selected workspace agent, then confirm the command is available:
```sh
which claude
which codex
```
Hive reads your login shell environment at launch. Fix the shell's `PATH`, then restart Hive.
## Notifications never appear as banners
Open **Settings ▸ Notifications** and check the master switch, delivery mode, and system permission.
On macOS, select **Allow notifications** if permission has not been requested. If permission is denied, enable Hive under **System Settings ▸ Notifications**.
## The GitHub code expired
Start **Connect GitHub** again and approve the new code. You can also select **Use a token instead** and provide a classic token with `repo` and `notifications` scopes.
## The feed is empty after skipping GitHub
Connecting GitHub after first run does not add the starter feeds automatically. Open the flow editor or ask the **Hive** workspace in Chats to create them.
See [Flows](https://hivedesktop.com/desktop/inbox/flows/) for a minimal source-to-feed example.
## A config change did nothing
Hive keeps the last valid flow or action file active when an edit fails validation. Open Activity, fix the reported error, and save again.
Common errors include unknown fields, invalid durations, duplicate node IDs, and unsupported action targets.
## A webhook does not arrive
Check the sender's result:
- `401` means the `X-Hive-Secret` header is missing or incorrect.
- Connection refused means the local listener is disabled or the port changed.
- `202` with no feed item usually means the path, node state, flow state, or wiring is wrong.
**Settings ▸ Integrations ▸ Webhooks** shows the current URL and lets you set a fixed port. The webhook node editor shows the most recent accepted delivery.
## A feed source reports an error
Open Activity and read the error. The usual cause is a URL that points at a page instead of at its feed document. Look for a `` tag in the page source, or try `/feed`, `/rss`, or `/atom.xml`.
Hive also fails the fetch when the feed asks for credentials, answers a non-2xx status, or is larger than 8 MiB. A failed fetch changes nothing, so the entries already in the feed stay where they are.
## A session was not created
The New Session form closes as soon as Hive accepts it, because the clone runs in the background. If that clone or a session hook fails, Hive raises an error toast that stays until you dismiss it, and keeps the form.
Select **Retry** on the toast, or open the form again with ⌘N. It comes back with the repository, name, prompt, and agent you submitted, and shows the step creation stopped on together with the last lines it printed.
The failure is also recorded in **Activity**, with its own **Retry** button. That row is stored, so it survives a restart: fix the cause first, then come back and retry the same form.
A clone that fails after the checkout is complete leaves the directory behind, and no session list shows it. The failure names the path, so you can delete it:
```sh
rm -rf ~/.local/share/hive/repos/-
```
A global git hook is a common cause. `git clone` returns the exit code of its `post-checkout` hook, so a hook that fails turns a finished clone into a failed session. Run the same clone in a terminal to see the hook's own output.
## The terminal does not fill its pane
Another tmux client may be setting the shared window size. Detach or resize that client, or add this to `tmux.conf`:
```text
set -g window-size largest
```
See [Terminal mode](https://hivedesktop.com/desktop/code/terminal-mode/#shared-tmux-sizing).
## Report a problem
Open **Settings ▸ System** and select **Report a problem**. Hive opens a new issue at [github.com/colonyops/hive/issues](https://github.com/colonyops/hive/issues) with your version and platform filled in. Nothing from your machine is attached. Describe the problem and paste the log lines that show it.
Hive Desktop and the CLI share the default log file. The `service_name` field
identifies `hive-desktop` or `hive-cli` on each line. Open **Settings ▸ System ▸
Shared log file** to see the effective path. By default it is:
```text
~/.local/share/hive/hive.log
```
When the log reaches 10 MB it moves to `hive.log.1`, and older files shift to `hive.log.2` and `hive.log.3`. The oldest is deleted, so the log never takes more than about 40 MB.
The file follows the Hive data directory, including `HIVE_DATA_DIR` and
`HIVE_DESKTOP_HIVE_DATA_DIR` overrides. It does not follow a separate Desktop
data-directory override.
## Save a diagnostic bundle
Use this only when a maintainer asks for one. Open **Settings ▸ System** and select **Save a diagnostic bundle**.
The bundle always holds build and system details. Logs, settings, flows, and actions are separate switches, and all four start off. Switch on what the maintainer asks for.
Tokens, secrets, and API keys are removed from everything the bundle holds. Names are not. The shared log tail can include CLI entries and names your home directory, repositories, and branches. Flows name the orgs and hosts they poll.
**Do not attach a bundle to a GitHub issue.** Issues are public. Send the file through the private channel the maintainer gives you.
Bundles are written to:
```text
~/.local/share/hive/desktop/reports/
```
Read one with `gunzip -c hive-report-.json.gz | jq .`.
---
# Getting Started
Install hive, configure your environment, and launch your first AI agent session in under five minutes.
## Installation
### Prerequisites
- **Git** — available in your PATH
- **tmux** — required for session management and status monitoring
!!! note "tmux is required"
Hive uses tmux for session management, agent monitoring, and preview panes. Install it before proceeding — hive will not function without it.
### Homebrew
```bash
brew install tmux
brew install colonyops/tap/hive
```
### GitHub Release
Pre-built binaries for macOS and Linux are available on the [GitHub Releases](https://github.com/colonyops/hive/releases) page. Download the appropriate archive for your platform, extract it, and place the binary on your PATH.
### Go Install
```bash
go install github.com/colonyops/hive@latest
```
### Mise
Install via [mise](https://mise.jdx.dev/) using the GitHub backend:
```bash
mise use -g github:colonyops/hive
```
### Verify
```bash
hive --version
hive doctor # Check configuration and environment
hive config # Dump resolved configuration as JSON
```
## Quick Start
### 1. Run the setup wizard
```bash
hive init
```
The interactive wizard:
- Detects installed AI agents (Claude, Codex, OpenCode, and others) and writes `~/.config/hive/config.yaml` with your preferred default
- Appends `alias hv='tmux new-session -As hive hive'` to your shell rc. The path defaults to the file for your `$SHELL` (`~/.zshrc`, `~/.bashrc`, or `config.fish`), falling back to `~/.zshrc`. The wizard lets you change it if your shell config lives elsewhere.
- Appends `bind-key h switch-client -t hive` to your `~/.tmux.conf` (or `$XDG_CONFIG_HOME/tmux/tmux.conf`)
Type a workspace path to complete setup (tab or `→` to autocomplete directories), then follow the remaining prompts.
### 2. Launch
```bash
hv
```
Hive auto-detects tmux, bundles its own session management scripts, and registers default keybindings — no other config needed. Press `n` to create sessions, `enter` to open them, and `:` for the command palette.
### Manual setup (alternative)
If you prefer to configure things by hand instead of using the wizard:
**Shell alias** — add to your `.bashrc` / `.zshrc`:
```bash
alias hv='tmux new-session -As hive hive'
```
This runs hive inside a dedicated tmux session called `hive`. If the session already exists, it reattaches.
**tmux keybinding** — add to `~/.tmux.conf`:
```tmux
bind l switch-client -t hive
```
Now ` l` returns you to hive from any agent session.
**Config file** — tell hive where your repos live:
```yaml
# ~/.config/hive/config.yaml
workspaces:
- ~/projects
- ~/work
```
!!! info
Without `workspaces`, you can still create sessions from the CLI by running `hive new` from within a git repository:
```bash
cd ~/projects/my-app
hive new Fix Auth Bug
```
## Next Steps
- [Sessions](https://hivedesktop.com/cli/getting-started/sessions/) — How sessions, agents, and lifecycle work
- [Task Tracking](https://hivedesktop.com/cli/getting-started/task-tracking/) — Built-in epics and tasks for multi-agent coordination
- [Context](https://hivedesktop.com/cli/getting-started/context/) — Shared storage and the review tool
- [Messaging](https://hivedesktop.com/cli/getting-started/messaging/) — Inter-agent pub/sub communication
- [Todos](https://hivedesktop.com/cli/getting-started/todos/) — Operator todo lifecycle and CLI usage
---
# Sessions
A hive session is an isolated git clone paired with a terminal environment for running AI agents. Instead of working directly in your main repository — where multiple agents would step on each other's changes — hive creates separate clones so each agent gets its own workspace. When you create a session, hive clones the repository (or reuses a recycled clone), then spawns a tmux session with windows for your AI tools.
Each project (git remote) can have multiple sessions running in parallel, each working on a different task. Sessions can run multiple agents in separate tmux windows — for example, a primary Claude agent alongside a test runner.
```
colonyops/hive <-- project (git remote)
├── fix-auth (26kj0c) <-- hive session (isolated clone)
│ └── tmux: fix-auth <-- tmux session (spawned by hive)
│ ├── window: claude <-- primary AI agent
│ ├── window: aider <-- secondary agent (optional)
│ └── window: shell <-- regular terminal
├── add-tests (x9m2p)
│ └── tmux: add-tests
│ ├── window: claude
│ └── window: shell
└── refactor-config (m4k8w)
└── tmux: refactor-config
├── window: aider <-- any AI tool works
└── window: shell
acme-corp/backend <-- another project
├── api-migration (p7n3q)
│ └── tmux: api-migration
│ ├── window: claude
│ └── window: shell
└── fix-ci (r2d5t)
└── tmux: fix-ci
├── window: claude
└── window: shell
```
## Hive Session
An isolated git clone in a dedicated directory with its own terminal environment. Each session is a self-contained workspace for one or more AI agents working on a specific task or feature.
**Key characteristics**:
- Unique 6-character ID (e.g., `26kj0c`)
- Display name (e.g., `fix-auth-bug`)
- Isolated git clone at a specific path
- One or more agent windows (configured via [agent profiles](https://hivedesktop.com/cli/configuration/#agents))
- Lifecycle: `active` → `recycled` → `deleted`
**Not to be confused with**: Tmux session (see relationship below)
### Session names
A session has a display name and a slug. You type the name; hive derives the slug from it by lowercasing it, folding accented letters (`é` to `e`), and joining the letters and digits with single hyphens. `Fix Auth Bug` becomes `fix-auth-bug`. The slug names the tmux session and the clone directory.
- A name is 1 to 60 characters of letters, digits, spaces, and `_ . : / -`, and starts with a letter or a digit.
- Two active sessions cannot share a slug, so `Fix Bug` and `fix-bug` count as the same name. `hive new`, `hive batch`, the TUI, and a rename all reject a duplicate.
- A name that hive generates, from a [source](https://hivedesktop.com/cli/configuration/sources/) template or a Hive Desktop launch node, is turned into a slug and cut to 60 characters at a word boundary. When its slug is already taken, hive adds an id from where the name came from (the item id for a source, the command id for a launch node) instead of failing.
[Hive Desktop](https://hivedesktop.com/desktop/code/terminal-mode/) shows the same sessions in its Code area when both use the same Hive data root, which is the default.
## Agent
An AI tool instance (Claude, Aider, Codex) running within a session. Each agent runs in its own tmux window and is independently monitored by the TUI.
Sessions support multiple agents — for example, a primary Claude agent alongside a test runner or code reviewer. Configure agent profiles in your config to define which tools are available. See [agent profiles](https://hivedesktop.com/cli/configuration/#agents) for setup.
## Tmux Session
A terminal multiplexer session that hosts a hive session. When you create a hive session, hive spawns a tmux session with the same name as the session slug.
**Relationship**: Each hive session spawns a tmux session with the same name. The tmux session contains agent windows (matched by `tmux.preview_window_matcher` patterns) and a `shell` window. See the architecture diagram above.
To open a session in Hive Desktop, run `hive desktop open hive://code/`. See [Links](https://hivedesktop.com/desktop/configuration/links/) for the link formats.
## Repository
A git remote URL (e.g., `github.com/colonyops/hive`). Multiple sessions can be created from the same repository.
## Clone Strategies
Hive supports two strategies for isolating session workspaces:
### Full clone (default)
Each session gets its own independent `git clone`. This is the simplest and most compatible option — sessions are entirely self-contained and can be on different branches.
```yaml
rules:
- pattern: "" # matches all repos; omitting clone_strategy also defaults to full
```
### Worktree
Sessions share a single bare clone of the repository. Each session is a [git worktree](https://git-scm.com/docs/git-worktree) pointing into the shared bare clone. This avoids re-downloading the full history for every session and reduces disk usage on large repositories.
Set `clone_strategy: worktree` on a rule. Use a catch-all rule (`pattern: ""`) to apply it globally, or a specific pattern to apply it to matching repos only:
```yaml
rules:
# worktree for all repos
- pattern: ""
clone_strategy: worktree
# override back to full for a specific repo
- pattern: ".*/legacy/.*"
clone_strategy: full
```
!!! note
Recycling a worktree session removes its checkout and session record, just like deleting it. The next session gets a fresh path and branch while continuing to reuse the shared bare clone. This keeps the usual recycle workflow without retaining stale worktree state.
## Session Lifecycle
Sessions move through a managed lifecycle:
1. **Create** — A new session starts as `active`. Hive clones the repository (or reuses a recycled clone) and spawns a tmux session.
2. **Recycle** — When you're done, recycle the session instead of deleting it. Full-clone sessions are reset and retained for reuse. Worktree sessions are removed because the shared bare clone already makes the next worktree inexpensive to create.
3. **Delete** — Permanently removes the session directory and all associated data.
4. **Corrupted** — If hive detects an invalid state (e.g., missing directory, broken git repo), the session is marked corrupted and can only be deleted.
!!! tip "Prefer recycling over deleting"
You can use the same recycle workflow with either clone strategy. Full-clone sessions are retained to avoid another clone; worktree sessions are deleted while their shared bare clone remains available for fast future sessions.
## Status Indicators
The TUI shows real-time agent status:
| Indicator | Color | Meaning |
| --------- | ---------------- | ------------------------------- |
| `[●]` | Green (animated) | Agent actively working |
| `[!]` | Yellow | Agent needs approval/permission |
| `[>]` | Cyan | Agent ready for input |
| `[?]` | Dim | Terminal session not found |
| `[○]` | Gray | Session recycled |
---
# Hive Drive & Review
Hive Drive is the folder tree where plans, research notes, and other documents live. Every session from the same repository reads and writes the same documents. `hive review` lets you annotate them with inline comments.
`hive ctx` is the old name of `hive drive` and still works.
## The Workflow
1. **Research** -- gather information, explore the codebase, and store findings in `.hive/research/`
2. **Plan** -- write implementation plans in `.hive/plans/` that any agent can reference
3. **Iterate** -- review and annotate plans with `hive review`, add comments, refine before coding
4. **Build** -- execute the plan, referencing shared context across sessions
An agent working on authentication can read the plan written by the agent that did the initial research. There is no copy-pasting and no context loss between sessions.
## The Drive
The drive root is `$XDG_DATA_HOME/hive/context/` (`~/.local/share/hive/context/` by default). Set `context.base_dir` in the [configuration](https://hivedesktop.com/cli/configuration/) to move it, for example into a [git repository](https://hivedesktop.com/cli/recipes/git-backed-context/).
A space is a folder under the root:
| Space | Folder |
| --- | --- |
| A repository | `///` |
| A Chats workspace in Hive Desktop | `/workspaces//` |
| Shared across everything | `/shared/` |
```
.hive/ # Symlink (per session)
↓ points to
~/.local/share/hive/context/{owner}/{repo}/
├── plans/ # Implementation plans
│ ├── 2026-01-15-auth-refactor.md
│ └── 2026-01-20-api-redesign.md
├── research/ # Research notes
│ ├── authentication-analysis.md
│ └── performance-profiling.md
└── references/ # Reference material
```
Hive Desktop shows the same tree in its Drive view, so a file you write from a terminal, an editor, or Obsidian appears there, and the reverse. See [Chats](https://hivedesktop.com/desktop/chats/agent-workspaces/#drive) and [Code](https://hivedesktop.com/desktop/code/terminal-mode/#drive).
### Initialization
Initialize the drive folder for your repository:
```bash
# Creates the .hive symlink in the current directory
# and the plans/, research/, and references/ folders
hive drive init
```
!!! warning
`.hive/` must ONLY be a symlink, never a regular directory. Always use `hive drive init` to create it. A regular directory breaks sharing between sessions.
### Listing Documents
!!! tip
Use `hive drive ls` to list documents. Standard `ls` and glob tools do not follow the `.hive` symlink reliably.
`hive drive ls` prints the repository's space with a kind for each entry: `dir`, `markdown`, `html`, `canvas`, or `file`. The kind comes from the file extension. Folders come before files at each level. `.canvas.json` is a canvas, a block document that agents write in Hive Desktop.
```
$ hive drive ls
/Users/you/.local/share/hive/context/my-org/my-repo
dir canvases
canvas canvases/perf.canvas.json
dir plans
markdown plans/2026-01-15-auth-refactor.md
dir research
markdown research/authentication-analysis.md
html research/benchmarks.html
markdown notes.md
```
```bash
hive drive ls --all # every space, each under its key
hive drive ls --json # one JSON entry per line
hive drive spaces # the space keys
hive drive prune --older-than 30d
```
`hive drive spaces` prints each space's kind and key, such as `repository my-org/my-repo`, `workspace workspaces/hive`, and `shared shared`. Another repository or the shared space is `hive drive -r owner/repo ls` or `hive drive -s ls`; `--all` cannot combine with `-r` or `-s`. `prune` removes files older than the given age.
### Finding Documents
```bash
# Review with interactive picker
hive review
# Review every space, with the space shown in the picker
hive review --all
# Review specific document
hive review -f .hive/plans/2026-01-15-auth-refactor.md
# Review most recent document
hive review --latest
```
### Document Types
The picker groups documents by type. A document's type is the `type:` key in its front matter. Without one, the top folder gives the type: `plans` is `plan`, `design-docs` is `design-doc`, `reviews` is `review`, `references` is `reference`, and any other folder is its own type. A document in no folder has the type `other`.
```markdown
---
type: design-doc
---
```
The picker lists these types first, in this order: `plan`, `design-doc`, `research`, `review`, `reference`, `context`. Other types follow alphabetically, and `other` comes last. Within a type, the newest document comes first. Only markdown files are listed.
### Usage Patterns
**Planning workflow:**
```bash
# Create plan document
echo "# Auth Refactor Plan" > .hive/plans/auth-refactor.md
# Review and annotate
hive review --latest
# Later sessions can review the same document
cd ~/another-session
hive review -f .hive/plans/auth-refactor.md
```
**Research workflow:**
```bash
# Store research findings
hive review -f .hive/research/api-analysis.md
# Add comments with findings
# > **Comment:** Found bottleneck in user lookup - missing index on email column
```
## Review Tool
Review and annotate markdown documents stored in the drive. Opens an interactive document picker when run without arguments, or directly reviews a specified file.
```bash
hive review # Interactive picker
hive review -f .hive/plans/auth.md # Review specific file
hive review --latest # Review most recent document
```
### Interactive Features
- **Document Picker** — Fuzzy search through documents (only available when multiple documents exist)
- **Line Selection** — Navigate and select specific lines with visual feedback
- **Inline Comments** — Add multiline comments at any line with automatic indentation
- **Smart Wrapping** — Comments wrap at 80 characters preserving indentation
- **Search** — `/` to search within document, `n/N` to navigate matches
- **Persistence** — Comments are saved directly to the file
### Keyboard Navigation
| Key | Action |
| -------------------- | ------------------------------------ |
| `↑/k` | Move up |
| `↓/j` | Move down |
| `g` | Jump to top |
| `G` | Jump to bottom |
| `enter` | Select line and add comment |
| `/` | Search in document |
| `n/N` | Next/previous search match |
| `esc` | Cancel comment/search, back to picker |
| `q`/`ctrl+c` | Quit |
### Comment Format
Comments are inserted with proper markdown formatting and indentation alignment:
```markdown
│ 42 │ ## Implementation Steps
> **Comment:** This section needs to address the authentication flow.
> The current approach doesn't handle token refresh properly.
│ 43 │ 1. Add OAuth2 client configuration
```
---
# Inter-Agent Messaging
Hive includes a lightweight pub/sub messaging system that enables agents to communicate across repositories. This is useful when work in one microservice depends on information from another.
## Inbox Convention
Each hive session has a conventional inbox topic using the format `agent.{session-id}.inbox`. This convention makes it easy for agents to find each other's inboxes and send direct messages.
**Example**:
- Session ID: `26kj0c`
- Inbox topic: `agent.26kj0c.inbox`
You can find your current session ID and inbox with:
```bash
hive session info
```
!!! info "Why `agent.` not `session.`?"
The `agent.` prefix refers to the AI agent running in the session, not the session itself. Sessions with multiple agents currently share a single inbox. Per-agent addressing (`agent...inbox`) is reserved for future use.
## Example: Cross-Repository Collaboration
```mermaid
sequenceDiagram
participant A as Agent A (auth-service)
participant Bus as Message Bus topic: agent.x7k2
participant B as Agent B (user-service)
Note over A: Working on auth flow, needs User struct format
A->>Bus: pub "What fields are in the User struct?"
Bus-->>B: sub --wait receives message
Note over B: Reads user/model.go
B->>Bus: pub "User{ID, Email, Name, CreatedAt}"
Bus-->>A: sub --last 1 receives response
Note over A: Continues implementation with correct struct
```
This example is simple, but I've used this system at work to debug complex issues across several microservices, pinpointing a bug in a service I didn't own.
## Messaging Commands
```bash
# Generate a unique topic for collaboration
hive msg topic # outputs: agent.x7k2
# Agent A publishes a question
hive msg pub -t agent.x7k2 -m "What fields are in the User struct?"
# Agent B subscribes and waits for messages
hive msg sub -t agent.x7k2 --wait
# Agent B responds
hive msg pub -t agent.x7k2 -m "User struct has: ID, Email, Name, CreatedAt"
# Agent A receives the response
hive msg sub -t agent.x7k2 --tail 1
```
!!! tip "Blocking vs polling"
Use `--wait` to block until a message arrives — useful for agents that need to synchronize. Use `--tail N` to poll for the most recent messages without blocking.
!!! tip "Acknowledgment"
Messages are **not** acknowledged by default. Use `--ack` on `sub` or `inbox` to mark messages as read. This prevents accidentally consuming messages before processing them.
## CLI Reference
Run `hive msg --help` for all flags and options.
---
# Task Tracking
Hive includes a built-in task tracker designed for multi-agent coordination. The `hive hc` command manages epics and tasks that agents can create, claim, and complete — no external issue tracker required.
## Concepts
**Epic** — A top-level grouping of work. Contains tasks.
**Task** — A unit of work under an epic. Agents claim tasks, record progress, and mark them done.
**Auto-detection** — Session ID and repository are detected from the working directory automatically. No configuration needed.
[Hive Desktop](https://hivedesktop.com/desktop/code/terminal-mode/#tasks) reads the same task tree from its Code area.
## Quick Start
### Create an epic with tasks
```bash
echo '{
"title": "Implement Authentication",
"type": "epic",
"children": [
{"title": "Add JWT library", "type": "task"},
{"title": "Implement login endpoint", "type": "task"},
{"title": "Add session middleware", "type": "task"}
]
}' | hive hc create
```
Tasks can be nested under other tasks using `children` to break work into subtrees. `hive hc next` walks the tree and only returns leaf tasks with no incomplete children, so parent tasks act as groupings that resolve automatically when their subtasks are done.
```bash
echo '{
"title": "Launch MVP",
"type": "epic",
"children": [
{"title": "Backend", "type": "task", "children": [
{"title": "Set up database schema", "type": "task"},
{"title": "Implement API endpoints", "type": "task"}
]},
{"title": "Frontend", "type": "task", "children": [
{"title": "Build login page", "type": "task"},
{"title": "Build dashboard", "type": "task"}
]}
]
}' | hive hc create
```
### Express blocker dependencies
Use `ref` and `blockers` to express ordering between sibling tasks in a bulk create. The `ref` field is a local label (not stored) that other tasks can reference in their `blockers` list. `hive hc next` skips tasks that have incomplete blockers.
```bash
echo '{
"title": "Auth System",
"type": "epic",
"children": [
{"ref": "jwt", "title": "JWT middleware", "type": "task"},
{"ref": "db", "title": "User schema migration", "type": "task"},
{"title": "Login endpoint", "type": "task", "blockers": ["jwt", "db"]}
]
}' | hive hc create
```
To add or remove blockers after creation:
```bash
hive hc update --add-blocker # mark task as blocked by another
hive hc update --remove-blocker # remove a blocker
```
Output is JSON lines — one per created item:
```
{"id":"hc-a1b2c3d4","type":"epic","title":"Implement Authentication",...}
{"id":"hc-e5f6g7h8","type":"task","title":"Add JWT library","epic_id":"hc-a1b2c3d4",...}
...
```
### Claim the next task
```bash
hive hc next hc-a1b2c3d4 --assign
```
This finds the next open leaf task, assigns it to the current session, and sets its status to `in_progress`.
### Record progress
```bash
hive hc comment hc-e5f6g7h8 "JWT validation working, added RS256 support"
```
### Complete the task
```bash
hive hc update hc-e5f6g7h8 --status done
```
When an epic is marked `done` or `cancelled`, all non-terminal descendants are automatically cascaded to the same status. Tasks already in a terminal state are not changed.
```bash
hive hc update hc-a1b2c3d4 --status done # cascades to all open/in_progress children
```
### Edit an item's title or description
```bash
hive hc update hc-e5f6g7h8 --title "New title"
hive hc update hc-e5f6g7h8 --desc "Updated description"
hive hc update hc-e5f6g7h8 --title "New title" --status done # combine with other flags
```
### Check epic progress
```bash
hive hc context hc-a1b2c3d4
```
Renders a markdown summary with task counts, your assigned tasks, and open work — designed for AI agent consumption.
Run `hive hc --help` for the full list of subcommands and flags.
---
# Todos
Hive includes an experimental todo workflow for tracking operator actions requested by agents.
!!! warning "Experimental"
Todo behavior and command output are experimental and may change in future releases.
## Open the Todo Panel
In the TUI, press `t` to open the todo panel (or run `:TodoPanel` from the command palette).
When the panel opens:
- all `pending` items are auto-acknowledged to `acknowledged`
- the default filter is `Open` (pending + acknowledged)
- items are sorted with open items first, then completed/dismissed
## Todo Panel Keybindings
| Key | Action |
| --- | --- |
| `j` / `down` | Move down |
| `k` / `up` | Move up |
| `tab` | Toggle filter (`Open` / `All`) |
| `enter` | Run action for selected todo URI |
| `c` | Mark selected item completed |
| `d` | Mark selected item dismissed |
| `esc` / `q` | Close panel |
## What Enter Does
`enter` behavior depends on URI scheme:
| Scheme | Behavior |
| --- | --- |
| `session://...` | Marks todo completed immediately |
| `review://...` | Opens the Review view for the document path |
| `http://...`, `https://...` | Opens in your OS browser/app (`open` on macOS, `xdg-open` elsewhere) |
| custom scheme with `todos.actions` | Runs configured shell template |
| custom scheme without `todos.actions` | Falls back to OS open on the full URI |
Additional behavior:
- if URI is empty, Hive shows `no URI on this todo` and does not update status
- external actions complete the todo only when command execution succeeds
- failed external actions keep todo open and show a warning
- `review://...` todos are auto-completed when review is finalized for the matched document
## Create Todos
Use `hive todo add` to create a todo item:
```bash
hive todo add --title "Review plan" --uri "review://.hive/plans/auth.md"
```
Sources:
- `agent` (default) — requires a detected session ID
- `human`
- `system`
## Instructing Agents to Create Todos
Todo creation is an instruction policy, not an automatic hook.
- Define the behavior in your agent instruction file (for example, `AGENTS.md`) and in any shared skills that run work.
- Put the requirement at the end of the workflow as a final step.
- Use exactly one todo when human follow-up is needed, and avoid duplicate todos for the same request.
Recommended final-step template for skills:
```text
Last step (required):
If work is complete and needs human follow-up (or is blocked on human input), create one todo before your final response:
hive todo add --title "" --uri "review://"
```
Recommended URI choices:
- `review://.hive/...` for plans/research/docs that should be reviewed
- `https://...` for external links
- `session://` only for generic session follow-up when no better URI exists
Example skill footer:
```bash
# Final step: request human follow-up when needed
hive todo add --title "Review auth rollout plan" --uri "review://.hive/plans/auth-rollout.md"
```
## List Todos
List all todos or filter by status:
```bash
hive todo list
hive todo list --status pending
```
## Update Status
Valid update targets:
- `acknowledged`
- `completed`
- `dismissed`
```bash
hive todo update --status acknowledged
hive todo update --status completed
```
You cannot set status back to `pending` from CLI update.
## Status Lifecycle
Allowed transitions are enforced by the todo domain model:
- `pending -> acknowledged`
- `pending -> completed`
- `pending -> dismissed`
- `acknowledged -> completed`
- `acknowledged -> dismissed`
Transitions from `completed` or `dismissed` are rejected.
## Override Enter Actions
Use `todos.actions` to define handlers for custom URI schemes:
```yaml
todos:
actions:
jira: "open https://jira.example.com/browse/{{ .Value | shq }}"
notion: "open {{ .URI | shq }}"
```
Template variables:
- `.Scheme` - URI scheme (`jira`)
- `.Value` - URI value (`PROJ-123` from `jira://PROJ-123`)
- `.URI` - full URI (`jira://PROJ-123`)
Built-in schemes cannot be overridden: `session`, `review`, `http`, `https`.
See [Todo Configuration](https://hivedesktop.com/cli/configuration/todos/) for full settings (actions, limiter, notifications).
---
# Session Picker
!!! warning "Experimental"
Session picker behavior, flags, and output formats are experimental and may change in future releases.
`hive x pick` opens a fuzzy session picker directly in the terminal. It shows all active sessions with live status indicators, lets you filter by name or repository, and switches your tmux client to the selected session.
## Usage
```bash
hive x pick # open picker, switch to selection
hive x pick --print # print selected session ID instead of switching
hive x pick --repo myrepo # pre-filter by repository
hive x pick --hide-current # exclude the session you're currently in
```
## Keybindings
| Key | Action |
| --- | --- |
| `↑` / `ctrl+k` | Move up |
| `↓` / `ctrl+j` | Move down |
| `tab` | Cycle status filter (all → active → approval → ready → missing) |
| `enter` | Switch to selected session |
| `esc` / `ctrl+c` | Cancel |
## Flags
| Flag | Description |
| ---- | ----------- |
| `--status`, `-s` | Pre-set the status filter (`active`, `approval`, `ready`, `missing`) |
| `--repo`, `-r` | Filter by repository remote URL (substring match) |
| `--print`, `-p` | Print selected session info instead of switching tmux |
| `--format`, `-f` | Output format for `--print`: `id` (default), `name`, `path`, `json` |
| `--hide-current` | Hide the session you are currently in |
| `--no-recents` | Don't prioritize recently-used sessions |
## Quick Navigation Popup via Tmux
Bind `hive x pick` to a tmux key to get an instant session switcher from anywhere:
```bash
# ~/.tmux.conf
bind-key f run-shell 'tmux new-window "hive x pick"'
```
Press `prefix + f` from any window. The picker opens in a new window, switches your client to the chosen session, and the picker window closes automatically. Press `esc` to cancel without switching.
---
# Claude Code Plugin
Hive provides a Claude Code plugin that gives your agents messaging, session awareness, and coordination capabilities. There are two plugins — install one or both depending on your needs.
## hive
The core plugin. Adds slash commands and skills for inter-agent messaging and session management.
```bash
claude plugin add github:colonyops/hive/claude-plugin/hive
```
### Commands
| Command | Description |
| --- | --- |
| `/hive:coordinate` | Discover other sessions, send messages, and hand off work between agents |
| `/hive:inbox` | Check inbox for unread inter-agent messages |
### Skills
Skills are loaded automatically when the agent detects relevant context — no slash command needed.
| Skill | What it teaches the agent |
| --- | --- |
| `config` | How to configure hive (rules, spawn commands, keybindings, user commands) |
| `inbox` | Reading messages, acknowledging, waiting, viewing history |
| `publish` | Sending messages to specific agents, broadcasting, topic naming conventions |
| `wait` | Blocking until a message arrives, timeouts, synchronization patterns |
| `session-info` | Retrieving current session ID, inbox topic, and session state |
## hive-hooks
!!! warning "Experimental"
This plugin is experimental and may change in future releases.
Automates session lifecycle events. Currently provides a single hook that checks for unread inbox messages when a Claude session starts, and injects a system message if any are found.
```bash
claude plugin add github:colonyops/hive/claude-plugin/hive-hooks
```
### Hooks
| Event | Behavior |
| --- | --- |
| `SessionStart` | Peeks at the inbox and notifies the agent of unread messages with a preview |
The hook runs silently — if hive isn't installed or the session isn't inside a hive workspace, it exits without error.
---
# Configuration
Config file: `~/.config/hive/config.yaml`
## Example
```yaml
workspaces:
- ~/projects
agents:
default: claude
claude:
command: claude
flags: ["--model", "opus"]
aider:
command: /opt/bin/aider
flags: ["--model", "sonnet"]
tmux:
poll_interval: 1.5s
preview_window_matcher: ["claude", "aider"]
tui:
theme: tokyo-night
rules:
- pattern: ""
max_recycled: 5
windows:
- name: "{{ agentWindow }}"
command: '{{ agentCommand }} {{ agentFlags }}'
focus: true
- name: shell
commands:
- hive drive init
- pattern: ".*/data-team/.*"
agent: aider
```
!!! tip
Run `hive doctor` to validate your configuration and check that all dependencies (git, tmux, plugins) are correctly set up.
Run `hive config` to dump the fully resolved configuration as JSON — useful for debugging which defaults and overrides are in effect.
## General Settings
Hive watches configured workspace directories and rescans them when repositories are added, removed, or renamed. Run `:WorkspaceRefresh` from the command palette to rescan manually.
| Option | Type | Default | Description |
| ----------------------------- | ---------- | -------------------- | ------------------------------------------- |
| `workspaces` | `[]string` | `[]` | Watched directories containing repositories |
| `git_path` | `string` | `git` | Git executable path |
| `copy_command` | `string` | `pbcopy` (macOS) | Command to copy to clipboard |
| `auto_delete_corrupted` | `bool` | `true` | Auto-delete corrupted sessions on prune |
| `history.max_entries` | `int` | `100` | Max command palette history entries |
## Environment Overrides
Use environment overrides for machine-specific paths and defaults without maintaining separate config files. Empty environment variables are ignored. Run `hive config` to inspect the resolved values.
| Environment variable | Overrides | Notes |
| ----------------------- | ------------------- | ------------------------------------------ |
| `HIVE_DEFAULT_AGENT` | `agents.default` | Must match an existing agent profile key |
| `HIVE_CONTEXT_BASE_DIR` | `context.base_dir` | Supports the same path rules as config |
| `HIVE_GIT_PATH` | `git_path` | Git executable path for this machine |
## Agents
Agent profiles define the AI tools available for spawning in sessions. The `default` key selects which profile to use when creating a new session unless a matching rule sets `agent`, the session is created with `--agent`, or `HIVE_DEFAULT_AGENT` is set.
| Option | Type | Default | Description |
| ------------------------- | ---------- | -------------- | ------------------------------------------------------------------------------ |
| `agents.default` | `string` | `"claude"` | Profile name to use by default |
| `agents.agent_selector` | `bool` | `false` | Show an inline agent picker in the new-session form; default profile pre-selected |
| `agents..command` | `string` | profile name | CLI binary to run (defaults to profile name if empty) |
| `agents..flags` | `[]string` | `[]` | Extra CLI args appended to the command on spawn |
Set `HIVE_DEFAULT_AGENT` to override `agents.default` for a single machine or shell session. The value must match an existing profile key in `agents`.
```sh
export HIVE_DEFAULT_AGENT=codex
```
Agent resolution order is: CLI/session agent, then batch `--agent`, then the last matching `rules[].agent`, then `HIVE_DEFAULT_AGENT`, then `agents.default`. Sessions can run multiple agents by opening additional tmux windows — use `tmux.preview_window_matcher` to control which windows the TUI monitors.
## Tmux
| Option | Type | Default | Description |
| ----------------------------- | ---------- | ----------------------------------- | ------------------------------------- |
| `tmux.poll_interval` | `duration` | `1.5s` | Status check frequency |
| `tmux.preview_window_matcher` | `[]string` | `["claude", "aider", "codex", ...]` | Regex patterns for agent window names |
## Terminal
Hive detects agent status in two stages: a stateless per-poll assessment of the visible pane content, then a debounce tracker (`terminal.status`) that turns those assessments into stable, published statuses. Debouncing exists because a single poll can catch a tool mid-redraw; requiring a status to repeat before it's published avoids flickering between `active`/`ready`/`missing` on transient noise.
| Option | Type | Default | Description |
| ---------------------------------------------- | ---------- | ------- | ------------------------------------------------------------------------- |
| `terminal.status.confirm.idle.polls` | `int` | `2` | Consecutive confirming polls required before leaving `active` for `ready` |
| `terminal.status.confirm.idle.min_duration` | `duration` | `2s` | Minimum wall-clock time the idle candidacy must also span |
| `terminal.status.confirm.idle.stable_content` | `bool` | `true` | Require the pane content to stay unchanged for the whole idle candidacy |
| `terminal.status.confirm.missing.polls` | `int` | `2` | See below: governs list-panes failure tolerance, not a debounce policy |
| `terminal.status.confirm.approval.polls` | `int` | `1` | Consecutive confirming polls required before leaving `approval`/`question` |
Entering `active`, `approval`, or `question` is always immediate (a busy indicator or a dialog is trusted the moment it's seen); only *leaving* those states is debounced, since a false positive there is a brief flash rather than a missed prompt.
`terminal.status.confirm.missing.polls` is not a `status.Tracker` debounce policy — it is consumed directly by the tmux transport as a list-panes failure tolerance: N polls tolerates N-1 consecutive `tmux list-panes` failures (serving the last-known cache) before a pane is published as `missing`. This keeps a single transient tmux hiccup from flashing every session missing.
Each `polls`/`min_duration` pair is combined, not alternative: the tracker requires `max(polls, ceil(min_duration / tmux.poll_interval))` consecutive confirming polls. Setting `min_duration` shorter than `tmux.poll_interval` has no effect, since the poll-count floor already dominates — `hive doctor` warns about this combination.
```yaml
terminal:
status:
confirm:
idle:
polls: 2
min_duration: 2s
stable_content: true
missing:
polls: 2
approval:
polls: 1
```
## TUI
| Option | Type | Default | Description |
| ------------------- | -------- | -------------- | -------------------------------------------- |
| `tui.theme` | `string` | `tokyo-night` | Built-in theme name (see [Themes](https://hivedesktop.com/cli/configuration/themes/))|
| `tui.update_checker`| `bool` | `true` | Check for updates on startup |
| `tui.store` | `bool` | `false` | Enable KV store browser tab |
## Messaging
| Option | Type | Default | Description |
| ------------------------ | -------- | -------- | ---------------------------- |
| `messaging.topic_prefix` | `string` | `agent` | Default prefix for topic IDs |
| `messaging.max_messages` | `int` | `100` | Messages kept per topic; older ones are deleted on publish. `0` keeps every message |
## Context
| Option | Type | Default | Description |
| ---------------------- | -------- | -------------------------------- | ------------------------------------------------------------------------------------ |
| `context.symlink_name` | `string` | `.hive` | Symlink name created by `hive drive init` |
| `context.base_dir` | `string` | `$HIVE_DATA_DIR/context/` | Override the base directory for all context storage. Accepts `~` and absolute paths. Can be overridden with `HIVE_CONTEXT_BASE_DIR`. |
By default context documents are stored under hive's data directory (`~/.local/share/hive/context/`). Set `context.base_dir` or `HIVE_CONTEXT_BASE_DIR` to redirect them elsewhere — for example, into a git repository so plans and research are version-controlled alongside your code.
```yaml
context:
base_dir: ~/notes/hive-context # store in a dedicated git repo
```
See [Git-backed Context](https://hivedesktop.com/cli/recipes/git-backed-context/) for a practical guide.
## Todos
| Option | Type | Default | Description |
| ------------------------------------ | ------------------- | ------- | ----------- |
| `todos.actions` | `map[string]string` | `{}` | Custom enter handlers for URI schemes |
| `todos.limiter.max_pending` | `int` | `0` | Global pending-todo cap (`0` disables) |
| `todos.limiter.rate_limit_per_session` | `duration` | `0` | Per-session add cooldown (`0` disables) |
| `todos.notifications.toast` | `bool` | `true` | Show toast on todo creation |
## Views
View-specific settings (keybindings, layout, behavior) are configured per-view under the `views` section.
### Sessions View
| Option | Type | Default | Description |
| ----------------------------------- | ---------- | ------------- | -------------------------------------------- |
| `views.sessions.keybindings` | `map` | | Key-to-command mappings |
| `views.sessions.split_ratio` | `int` | `25` | List/preview split percentage (1-80) |
| `views.sessions.refresh_interval` | `duration` | `15s` | Session list auto-refresh interval (0 to disable) |
| `views.sessions.preview_enabled` | `bool` | `true` | Enable tmux pane preview sidebar on startup |
| `views.sessions.preview_title` | `string` | | Go template for preview panel title |
| `views.sessions.preview_status` | `string` | | Go template for preview status line |
| `views.sessions.group_by` | `string` | `repo` | Tree view grouping: `repo` or `group` |
### Tasks View
| Option | Type | Default | Description |
| ----------------------------- | ----- | ------- | ------------------------------------ |
| `views.tasks.keybindings` | `map` | | Key-to-command mappings |
| `views.tasks.split_ratio` | `int` | `30` | Tree/detail split percentage (1-80) |
### Messages View
| Option | Type | Default | Description |
| ------------------------------- | ----- | ------- | ------------------------------------ |
| `views.messages.keybindings` | `map` | | Key-to-command mappings |
| `views.messages.split_ratio` | `int` | `50` | List/preview split percentage (1-80) |
### Global
| Option | Type | Description |
| ----------------------------- | ----- | ---------------------------------- |
| `views.global.keybindings` | `map` | Keybindings available in all views |
See [Keybindings](https://hivedesktop.com/cli/configuration/keybindings/) for the full per-view configuration format and defaults.
## More Configuration
- **[Rules](https://hivedesktop.com/cli/configuration/rules/)** — Repository-specific spawn, recycle, setup commands, and file copying
- **[User Commands](https://hivedesktop.com/cli/configuration/commands/)** — Custom commands for the vim-style command palette
- **[Keybindings](https://hivedesktop.com/cli/configuration/keybindings/)** — Per-view key mappings and palette commands
- **[Todo Configuration](https://hivedesktop.com/cli/configuration/todos/)** — Todo actions, limiter, notifications, and enter behavior
- **[Plugins](https://hivedesktop.com/cli/configuration/plugins/)** — External service integrations (tmux, Claude, GitHub, etc.)
- **[Themes](https://hivedesktop.com/cli/configuration/themes/)** — Built-in color palettes and custom theme creation
## Data Storage
All data is stored at `~/.local/share/hive/`:
```
~/.local/share/hive/
├── hive.db # SQLite database (sessions, messages)
├── bin/ # Bundled scripts (auto-extracted)
│ ├── hive-tmux # Tmux session launcher
│ └── agent-send # Send text to agent in tmux
├── repos/ # Cloned repositories
│ └── myproject-feature1-abc123/
└── context/ # Per-repo context directories
├── {owner}/{repo}/ # Linked via .hive symlink
└── shared/ # Shared context
```
---
# Rules
Rules match repositories by regex pattern against the remote URL and configure how sessions are created, recycled, and set up. Rules are evaluated in order — the last matching rule with spawn/windows config wins, and the last matching `agent` selects the agent profile. An empty pattern (`""`) matches all repositories.
```yaml
rules:
# Default rule — windows config creates tmux sessions declaratively
- pattern: ""
max_recycled: 5
windows:
- name: "{{ agentWindow }}"
command: '{{ agentCommand }} {{ agentFlags }}'
focus: true
- name: shell
commands:
- hive drive init
# Override for work repos — use the aider profile
- pattern: ".*/my-org/.*"
agent: aider
windows:
- name: "{{ agentWindow }}"
command: "{{ agentCommand }} {{ agentFlags }}"
focus: true
- name: tests
command: "npm run test:watch"
- name: shell
commands:
- npm install
copy:
- .envrc
```
!!! info "Last match wins"
Rules are evaluated in order — the **last** matching rule with spawn/windows config wins, and the **last** matching rule with `agent` selects the agent profile. Place general patterns before specific ones.
## Rule Fields
| Field | Type | Default | Description |
| ------------------ | -------------- | ---------------------------- | ------------------------------------------------- |
| `pattern` | string | `""` | Regex pattern to match remote URL |
| `clone_strategy` | string | — | Override clone strategy for matching repos: `full` or `worktree` |
| `branch_template` | string | `hive/{{ .Slug }}-{{ .ID }}` | Go template for the git branch name (worktree only). Variables: `.Name`, `.Slug`, `.Owner`, `.Repo`, `.ID`. The rendered value must be a valid git branch name (no spaces, colons, `~`, `^`, etc.) — session creation fails with a clear error if it isn't. |
| `agent` | string | — | Agent profile override for matching repos. Must match a key under `agents`. |
| `windows` | []WindowConfig | see below | Declarative tmux window layout (recommended) |
| `spawn` | []string | — | Shell commands run after session creation (legacy) |
| `batch_spawn` | []string | — | Shell commands for batch session creation (legacy) |
| `recycle` | []string | git fetch/checkout/reset/clean | Commands run when recycling a full-clone session; worktree sessions are deleted |
| `commands` | []string | `[]` | Setup commands run after clone |
| `copy` | []string | `[]` | Glob patterns for files to copy from parent repo |
| `max_recycled` | *int | `5` | Maximum recycled full-clone sessions to keep (0 = unlimited) |
!!! warning "`windows` vs `spawn`/`batch_spawn`"
A rule must use either `windows` or `spawn`/`batch_spawn`, not both. If neither is set, the default window layout is used (agent window + shell window). A rule can set `agent` with or without custom `windows`/`spawn` config.
## Agent Overrides
Use `agent` to select a configured agent profile for repositories matching a rule. The value must match a profile under `agents`.
```yaml
agents:
default: claude
claude:
command: claude
flags: ["--model", "opus"]
aider:
command: aider
flags: ["--model", "sonnet"]
rules:
- pattern: ""
max_recycled: 5
# Uses the default window layout, rendered with the aider profile.
- pattern: ".*/data-team/.*"
agent: aider
# Custom windows can still use the selected profile through template functions.
- pattern: ".*/infra/.*"
agent: aider
windows:
- name: "{{ agentWindow }}"
command: "{{ agentCommand }} {{ agentFlags }}"
focus: true
- name: shell
```
Agent resolution order is:
1. CLI/session agent
2. Batch `--agent`
3. Last matching rule with `agent`
4. `HIVE_DEFAULT_AGENT`
5. `agents.default`
## Window Configuration
The `windows` field defines tmux windows declaratively. Each window has:
| Field | Type | Required | Default | Description |
| --------- | ------------ | -------- | ------------- | ---------------------------------------------- |
| `name` | string | yes | — | Window name (supports templates) |
| `command` | string | no | default shell | Command to run in the window (supports templates). Mutually exclusive with `panes`. |
| `dir` | string | no | session path | Working directory override (supports templates) |
| `focus` | bool | no | `false` | Select this window after creation |
| `panes` | []PaneConfig | no | single pane | Panes to create in the window. Mutually exclusive with `command`. |
!!! warning "`command` vs `panes`"
A window must use either `command` or `panes`, not both. Use `command` for a single-pane window. Use `panes` when you need splits inside the window.
**Default window layout** (used when no rule specifies `windows` or `spawn`). The template functions render from the resolved agent profile:
```yaml
windows:
- name: "{{ agentWindow }}"
command: '{{ agentCommand }} {{ agentFlags }}'
focus: true
- name: shell
```
### Window Examples
**Agent + shell (default equivalent):**
```yaml
windows:
- name: "{{ agentWindow }}"
command: "{{ agentCommand }} {{ agentFlags }}"
focus: true
- name: shell
```
**Agent + test watcher + shell:**
```yaml
windows:
- name: "{{ agentWindow }}"
command: "{{ agentCommand }} {{ agentFlags }}"
focus: true
- name: tests
command: "npm run test:watch"
- name: shell
```
**Multiple agents:**
```yaml
windows:
- name: "{{ agentWindow }}"
command: "{{ agentCommand }} {{ agentFlags }}"
focus: true
- name: aider
command: "aider --model sonnet"
- name: shell
```
**Split panes inside a window:**
```yaml
windows:
- name: "{{ agentWindow }}"
focus: true
panes:
- command: "{{ agentCommand }} {{ agentFlags }}"
- command: "npm test -- --watch"
split: horizontal
size: 30%
- name: shell
```
## Pane Configuration
The `panes` field defines tmux panes inside a window. The first pane becomes the initial pane for the window. Additional panes are created with `tmux split-window`.
| Field | Type | Required | Default | Description |
| --------- | ------ | -------- | ------------- | ---------------------------------------------- |
| `command` | string | no | default shell | Command to run in the pane (supports templates) |
| `dir` | string | no | window/session path | Working directory override (supports templates) |
| `size` | string | no | tmux default | Size passed to `tmux split-window -l` (for example `30%`) |
| `split` | string | no | `vertical` | Split direction: `horizontal` or `vertical` |
## Template Variables
Commands support Go templates with `{{ .Variable }}` syntax and `{{ .Variable | shq }}` for shell-safe quoting.
| Context | Variables |
| ---------------------- | ------------------------------------------------------------------- |
| `rules[].windows` / `panes` | `.Path`, `.Name`, `.Slug`, `.ContextDir`, `.Owner`, `.Repo`, `.Prompt` (batch) |
| `rules[].spawn` | `.Path`, `.Name`, `.Slug`, `.ContextDir`, `.Owner`, `.Repo` |
| `rules[].batch_spawn` | Same as spawn, plus `.Prompt` |
| `rules[].commands` | `.Path`, `.Name`, `.Slug`, `.ContextDir`, `.Owner`, `.Repo`, `.ID` |
| `rules[].recycle` | `.DefaultBranch` |
| `rules[].branch_template` | `.Name`, `.Slug`, `.Owner`, `.Repo`, `.ID` |
| `usercommands.*.sh` | `.Path`, `.Name`, `.Remote`, `.ID`, `.Tool`, `.TmuxWindow`, `.Args`, `.Form.*`, `.Doc.Path`, `.Doc.RelPath`, `.Doc.Type` (review scope) |
!!! warning "Always use `shq` for shell quoting"
Template variables like `.Name` and `.Path` may contain spaces or special characters. Always pipe them through `shq` (e.g., `{{ .Name | shq }}`) to prevent shell injection and word-splitting issues.
### `.Name` vs `.Slug` in `branch_template`
These two variables behave very differently as a branch name source:
| | `.Slug` | `.Name` |
| --- | --- | --- |
| Value for session `"dev/fix auth"` | `dev-fix-auth` | `dev/fix auth` |
| Always a valid git branch name | yes | no (spaces, colons, etc. are rejected by git) |
| Preserves `/` namespace separator | no (converted to `-` for safe directory paths) | yes |
**Use `.Slug` when you want a safe, predictable branch name:**
```yaml
branch_template: "dev/{{ .Slug }}" # dev/fix-auth-abc123
```
**Use `.Name` when your session names already follow git branch conventions** (alphanumeric, hyphens, slashes — no spaces or colons):
```yaml
branch_template: "{{ .Name }}" # dev/fix-auth (if that's the session name)
```
If `.Name` renders to an invalid git branch name (e.g. contains a space), hive will fail with a clear error at session creation time rather than passing a bad name to git.
## Template Functions
| Function | Description |
| ----------- | --------------------------------------------- |
| `shq` | Shell-quote a string for safe use in commands |
| `join` | Join string slice with separator |
| `hiveTmux` | Path to bundled `hive-tmux` script |
| `agentSend` | Path to bundled `agent-send` script |
| `agentCommand` | Command from the resolved agent profile |
| `agentWindow` | Resolved agent profile name/window name (use for targets like `session:{{ agentWindow }}`) |
| `agentFlags` | Flags from the resolved agent profile |
---
# User Commands
User commands provide a vim-style command palette accessible by pressing `:` in the TUI. Define custom commands that execute shell scripts, display interactive forms, and integrate with tmux to control agents.
```yaml
usercommands:
review:
sh: "{{ agentSend }} {{ .Name | shq }}:{{ agentWindow }} /review"
help: "Send /review to Claude session"
silent: true
tidy:
sh: "{{ agentSend }} {{ .Name | shq }}:{{ agentWindow }} /tidy"
help: "Send /tidy to Claude session"
confirm: "Commit and push changes?"
open:
sh: "open {{ .Path }}"
help: "Open session in Finder"
silent: true
exit: "true"
```
## Command Palette Features
- **Vim-style interface** — Press `:` to open the palette
- **Fuzzy filtering** — Type to filter commands (prefix and substring matching)
- **Arguments support** — Pass arguments to commands (e.g., `:review pr-123`)
- **Tab completion** — Auto-fill selected command name
- **Keyboard navigation** — `↑/k/ctrl+k`, `↓/j/ctrl+j`, `tab`, `enter`, `esc`
## Command Options
| Field | Type | Description |
| --------- | --------------------- | ------------------------------------------------------------------- |
| `sh` | string | Shell command template (mutually exclusive with `action`) |
| `action` | string | Built-in action name (mutually exclusive with `sh` and `windows`; see [Built-in Actions](#built-in-actions)) |
| `windows` | `[]WindowConfig` | Tmux windows to open after `sh` completes (see [Multi-agent Workflows](#multi-agent-workflows)) |
| `options` | `UserCommandOptions` | Execution options for window-based commands (see below) |
| `help` | string | Description shown in palette |
| `confirm` | string | Confirmation prompt (empty = no confirmation) |
| `silent` | bool | Skip loading popup for fast commands |
| `exit` | string | Exit TUI after command (bool or `$ENV_VAR`) |
| `scope` | `[]string` | Views where command is available (nil = all views). Valid: `global`, `sessions`, `messages`, `review`, `todos`, `tasks` |
| `form` | `[]FormField` | Interactive form fields collected before execution (see below) |
## Built-in Actions
Actions are built-in behaviors that can be assigned to user commands via the `action` field. Names are case-insensitive.
### Session Management
| Action | Description |
| --------------- | ---------------------------------- |
| `Recycle` | Recycle the selected session |
| `Delete` | Delete the selected session |
| `NewSession` | Create a new session |
| `RenameSession` | Rename the selected session |
### Tmux
These actions are provided by the tmux plugin and require tmux to be available.
| Action | Description |
| ----------- | --------------------------------------- |
| `TmuxOpen` | Open/attach the session's tmux session |
| `TmuxStart` | Start a tmux session in the background |
### Filtering
| Action | Description |
| ---------------- | ------------------------------------ |
| `FilterAll` | Show all sessions |
| `FilterActive` | Show sessions with active agents |
| `FilterApproval` | Show sessions needing approval |
| `FilterReady` | Show sessions with idle agents |
### Grouping
| Action | Description |
| ------------- | ------------------------------------------ |
| `GroupSet` | Set/clear the selected session's group |
| `GroupToggle` | Toggle between repo and group tree view |
### Navigation
| Action | Description |
| ------------ | ------------------------------ |
| `NextActive` | Jump to next active session |
| `PrevActive` | Jump to previous active session |
### Tasks
| Action | Description |
| -------------------- | ------------------------------- |
| `TasksRefresh` | Refresh the task list |
| `TasksFilter` | Cycle task status filter |
| `TasksCopyID` | Copy task ID to clipboard |
| `TasksTogglePreview` | Toggle task preview panel |
### Other
| Action | Description |
| ----------- | ---------------------------- |
| `DocReview` | Open the document review view |
| `TodoPanel` | Open the todo panel modal |
| `SetTheme` | Preview and select a theme |
| `Notifications` | Show notification history |
## System Default Commands
Hive registers several built-in actions as default commands that can be overridden in `usercommands`. Additionally, the `SendBatch` command provides a form-based workflow for messaging multiple agents at once.
!!! warning
`action` is mutually exclusive with `sh` and `windows`. A command must have at least one of `action`, `sh`, or `windows`.
## Multi-agent Workflows
The `windows` field opens one or more tmux windows in the current session after `sh` completes. Each window runs an independent agent or process, enabling parallel multi-agent workflows from a single command.
### Window Fields
| Field | Type | Description |
| --------- | ------------ | ------------------------------------------------------- |
| `name` | string | Window name (required, template string) |
| `command` | string | Command to run in a single-pane window (template string). Mutually exclusive with `panes`. |
| `dir` | string | Working directory override (template string) |
| `focus` | bool | Select this window after creation |
| `panes` | []PaneConfig | Panes to create in the window. Mutually exclusive with `command`. |
### Pane Fields
| Field | Type | Description |
| --------- | ------ | ------------------------------------------------------- |
| `command` | string | Command to run in the pane (template string) |
| `dir` | string | Working directory override (template string) |
| `size` | string | Size passed to `tmux split-window -l` (for example `30%`) |
| `split` | string | Split direction: `horizontal` or `vertical` (default `vertical`) |
### Options Fields
The `options` block controls how window-based commands execute:
| Field | Type | Description |
| -------------- | ------ | ------------------------------------------------------------------------ |
| `session_name` | string | Template string — when set, creates a new hive session before opening windows |
| `remote` | string | Remote URL override for new session creation (requires `session_name`) |
| `background` | bool | Open windows without attaching to the tmux session |
```yaml
usercommands:
CodeReview:
help: "parallel review: two specialists coordinated by a leader"
silent: true
windows:
- name: leader
focus: true
command: claude 'coordinate a review...'
- name: specialist-a
command: codex 'review for correctness...'
- name: specialist-b
command: cursor 'review for security...'
```
See the [Recipes](https://hivedesktop.com/cli/recipes/) for full multi-agent workflow examples.
## Document Context (review scope)
When a command runs from the document review view, the focused document is exposed under the `.Doc` namespace:
| Variable | Description |
| -------------- | ---------------------------------------------------------------------------------------------- |
| `.Doc.Path` | Absolute path to the focused document |
| `.Doc.RelPath` | Path relative to the drive space (e.g. `plans/2026-05-06-plan.md`) |
| `.Doc.Type` | Lowercase front matter `type:`, else the top folder name (`plans/` gives `plan`), else `other` |
`.Doc.*` fields render as empty strings outside the review view or when no document is focused. Scope the command to `review` so it only appears where these values are populated.
```yaml
usercommands:
AnnotateDoc:
sh: "send-claude {{ .Name | shq }} /annotate {{ .Doc.RelPath | shq }}"
help: "Send the focused doc to Claude for annotation"
scope: [review]
silent: true
```
## Using Arguments
Arguments passed in the command palette are available via the `.Args` template variable:
```yaml
usercommands:
msg:
sh: |
hive msg pub -t agent.{{ .ID }}.inbox "{{ range .Args }}{{ . }} {{ end }}"
help: "Send message to session inbox"
```
Usage: `:msg hello world` → sends "hello world" to the session inbox
## Exit Conditions
The `exit` field supports environment variables for conditional behavior:
```yaml
usercommands:
attach:
sh: "tmux attach -t {{ .Name }}"
exit: "$HIVE_POPUP" # Only exit if HIVE_POPUP=true
```
This is useful when running hive in a tmux popup vs a dedicated session.
## Form Fields
Commands with `form` fields display an interactive dialog before execution. Form values are available under `.Form.` in the shell template.
| Field | Type | Description |
| ------------- | -------- | --------------------------------------------------------------- |
| `variable` | string | Template variable name (accessed as `.Form.`) |
| `type` | string | `text`, `textarea`, `select`, or `multi-select` (one of type/preset) |
| `preset` | string | `SessionSelector` or `ProjectSelector` (one of type/preset) |
| `label` | string | Display label for the field |
| `placeholder` | string | Placeholder text (text/textarea) |
| `default` | string | Default value (text/textarea/select) |
| `options` | []string | Static options (select/multi-select) |
| `multi` | bool | Enable multi-select (presets only) |
| `filter` | string | `active` (default) or `all` — SessionSelector only |
Preset fields populate from runtime data. `SessionSelector` shows active sessions with running tmux sessions (grouped by project when multiple remotes exist). `ProjectSelector` shows discovered repositories.
!!! info
Form commands don't require a focused session — they collect their own targets via preset fields like `SessionSelector` and `ProjectSelector`.
```yaml
usercommands:
broadcast:
sh: |
{{ range .Form.targets }}
{{ agentSend }} {{ .Name | shq }}:{{ agentWindow }} {{ $.Form.message | shq }}
{{ end }}
form:
- variable: targets
preset: SessionSelector
multi: true
label: "Select recipients"
- variable: message
type: text
label: "Message"
placeholder: "Type your message..."
help: "send message to multiple agents"
silent: true
```
## What You Can Build
User commands combined with tmux integration and messaging create a powerful extensibility layer for AI agent management. Here are real-world patterns:
### Batch Send to Multiple Agents
Send the same instruction to all active agents at once:
```yaml
usercommands:
broadcast:
sh: |
{{ range .Form.targets }}
{{ agentSend }} {{ .Name | shq }}:{{ agentWindow }} {{ $.Form.message | shq }}
{{ end }}
form:
- variable: targets
preset: SessionSelector
multi: true
label: "Select agents"
- variable: message
type: text
label: "Message"
placeholder: "run tests and report results"
help: "Send message to multiple agents"
silent: true
```
### Code Review Agent
Spin up a dedicated reviewer that reviews your branch and sends feedback via inbox:
```yaml
usercommands:
ReviewRequest:
sh: "~/.config/hive/scripts/request-review.sh {{ .Name }}"
help: "Request code review of current branch"
CheckInbox:
sh: "hive msg sub -t agent.{{ .ID }}.inbox"
help: "Check inbox for messages"
```
See the [Recipes](https://hivedesktop.com/cli/recipes/) for full multi-agent workflow examples.
### Quick Actions
Common operations bound to single keys:
```yaml
usercommands:
open:
sh: "open {{ .Path }}"
help: "Open in Finder"
silent: true
exit: "true"
tidy:
sh: "{{ agentSend }} {{ .Name | shq }}:{{ agentWindow }} /tidy"
help: "Send /tidy to agent"
confirm: "Commit and push changes?"
review:
sh: "{{ agentSend }} {{ .Name | shq }}:{{ agentWindow }} /review"
help: "Send /review to agent"
silent: true
views:
sessions:
keybindings:
o:
cmd: open
t:
cmd: tidy
R:
cmd: review
```
### Conditional Exit
Exit hive after opening a session — useful when running hive in a tmux popup:
```yaml
usercommands:
attach:
sh: "tmux attach -t {{ .Name }}"
exit: "$HIVE_POPUP" # Only exit if HIVE_POPUP=true
```
---
# Keybindings
Keybindings map keys to user commands. Keybindings are configured per-view under the `views` section, with a `global` section for bindings available in all views.
```yaml
views:
global:
keybindings:
"?":
cmd: HiveInfo
sessions:
keybindings:
o:
cmd: open # User-defined command
t:
cmd: tidy
confirm: "Run tidy on this session?"
tasks:
keybindings:
r:
cmd: TasksRefresh
```
!!! info
Keybindings reference commands by name. Both system default commands (like `Recycle`) and user-defined commands can be bound. You can override the command's `help` and `confirm` fields per-binding.
!!! warning "Deprecated: top-level keybindings"
The top-level `keybindings` field is deprecated. Move entries to `views.sessions.keybindings` instead. Existing top-level keybindings are automatically migrated to the sessions view.
## Keybinding Options
| Field | Type | Description |
| --------- | ------ | --------------------------------------------- |
| `cmd` | string | Command name to execute (required) |
| `help` | string | Override help text from the command |
| `confirm` | string | Override confirmation prompt from the command |
## Default Keybindings
### Sessions View
| Key | Command | Description |
| ---------- | -------------------- | ------------------------------------ |
| `r` | Recycle | Recycle session |
| `d` | Delete | Delete session (or tmux window) |
| `n` | NewSession | New session (when repos discovered) |
| `enter` | TmuxOpen | Open/attach tmux session |
| `ctrl+d` | TmuxKill | Kill tmux session |
| `A` | AgentSend | Send Enter to agent |
| `R` | RenameSession | Rename session |
| `ctrl+g` | GroupSet | Set session group |
| `J` | NextActive | Jump to next active session |
| `K` | PrevActive | Jump to previous active session |
| `t` | TodoPanel | Open todo panel |
| `o` | TmuxPopUp | Popup tmux session |
| `i` | SourceIssues | Browse GitHub issues |
| `p` | SourcePRs | Browse GitHub pull requests |
### Tasks View
| Key | Command | Description |
| ---- | -------------------- | ------------------------------- |
| `r` | TasksRefresh | Refresh task list |
| `f` | TasksFilter | Cycle status filter |
| `y` | TasksCopyID | Copy task ID to clipboard |
| `v` | TasksTogglePreview | Toggle preview panel |
| `s` | TasksSelectRepo | Select repository scope |
### Hard-coded Keys (all views)
| Key | Description |
| ---------- | ------------------------------------ |
| `:` | Open command palette |
| `tab` | Switch views |
| `q` | Quit |
### Sessions View Navigation
| Key | Description |
| ---- | ------------------------ |
| `v` | Toggle preview sidebar |
| `g` | Refresh git statuses |
### Tasks View Navigation
| Key | Description |
| ------------ | ------------------------ |
| `space` | Expand/collapse item |
| `enter`, `l` | Open detail pane |
| `h`, `esc` | Back to tree |
For todo panel interaction keys (`enter`, `c`, `d`, `tab`, etc.), see [Todos](https://hivedesktop.com/cli/getting-started/todos/) .
## Per-View Keybinding Resolution
When a key is pressed, hive resolves bindings in this order:
1. **View-specific bindings** — checked first (e.g., `views.sessions.keybindings`)
2. **Global bindings** — checked as fallback (e.g., `views.global.keybindings`)
A view-specific binding overrides a global binding for the same key.
## Built-in Palette Commands
These commands are available in the command palette (`:`) but have no default keybinding:
| Command | Description |
| ------------------ | ----------------------------------- |
| `FilterAll` | Show all sessions |
| `FilterActive` | Show sessions with active agents |
| `FilterApproval` | Show sessions needing approval |
| `FilterReady` | Show sessions with idle agents |
| `GroupToggle` | Toggle between repo/group tree view |
| `WorkspaceRefresh` | Rescan workspace repositories |
| `SendBatch` | Send message to multiple agents |
| `TmuxStart` | Start tmux session in background |
---
# Todo Configuration
Configure how todo actions execute in the TUI, how aggressively todo creation is limited, and whether toast notifications are shown.
!!! warning "Experimental"
Todo behavior and settings are experimental and may change in future releases.
## Configuration Shape
```yaml
todos:
actions:
jira: "open https://jira.example.com/browse/{{ .Value | shq }}"
limiter:
max_pending: 50
rate_limit_per_session: 10s
notifications:
toast: true
```
## Options
| Option | Type | Default | Description |
| --- | --- | --- | --- |
| `todos.actions` | `map[string]string` | `{}` | Custom enter-action templates by URI scheme |
| `todos.limiter.max_pending` | `int` | `0` | Max pending todos allowed globally (`0` disables cap) |
| `todos.limiter.rate_limit_per_session` | `duration` | `0` | Min time between new todos per session (`0` disables limit) |
| `todos.notifications.toast` | `bool` | `true` | Show toast notifications when new todos are created |
## Action Templates
Action templates run when you press `enter` on a todo item whose URI scheme matches a key in `todos.actions`.
Template variables:
- `.Scheme` - URI scheme
- `.Value` - URI value portion
- `.URI` - full URI string
Example:
```yaml
todos:
actions:
linear: "open https://linear.app/acme/issue/{{ .Value | shq }}"
docs: "hive review -f {{ .Value | shq }}"
```
Given `linear://ENG-42`, `.Value` resolves to `ENG-42`.
### Built-in Schemes
These schemes have fixed behavior and cannot be overridden:
- `session`
- `review`
- `http`
- `https`
## Enter Behavior Summary
When a todo panel item is activated with `enter`:
- `session://...` -> complete todo directly
- `review://...` -> open review view for that path
- `http(s)://...` -> open via OS handler
- custom scheme with `todos.actions` -> execute rendered template
- custom scheme without `todos.actions` -> fallback to OS open of full URI
For external actions, Hive auto-completes the todo only after a successful command exit.
## Where Todo Creation Is Defined
Hive does not auto-create todos when an agent finishes work.
- Define todo-creation behavior in your instruction layer (`AGENTS.md`, tool prompts, and reusable skills).
- Use `hive todo add` in that instruction text as a required final step when human action is needed.
- Keep `todos.*` config focused on execution behavior (actions, limits, notifications), not creation policy.
## Related Docs
- [Todos](https://hivedesktop.com/cli/getting-started/todos/)
- [Configuration Overview](https://hivedesktop.com/cli/configuration/)
---
# Plugins
Plugins extend hive with custom commands and status providers. Plugins auto-detect their dependencies at startup — if the required CLI tool is installed, the plugin activates automatically.
```yaml
plugins:
tmux:
enabled: true
claude:
enabled: true
github:
enabled: true
results_cache: 8m
```
!!! info "Auto-detection"
Most plugins auto-detect their dependencies at startup. You only need to set `enabled: true` — if the required CLI tool isn't installed, the plugin silently deactivates. No errors, no configuration needed.
## Tmux Plugin
The tmux plugin provides default commands for session management using bundled scripts (`hive-tmux`, `agent-send`) that are auto-extracted to `$HIVE_DATA_DIR/bin/`.
```yaml
plugins:
tmux:
enabled: true # true by default, set false to disable
```
### Commands Provided
| Command | Description | Default Key |
| ---------------- | ------------------------------- | ----------- |
| `TmuxOpen` | Open/attach tmux session | `enter` |
| `TmuxStart` | Start tmux session (background) | — |
| `TmuxKill` | Kill tmux session | `ctrl+d` |
| `TmuxPopUp` | Popup tmux session | `o` |
| `AgentSend` | Send Enter to agent | `A` |
| `AgentSendClear` | Send /clear to agent | — |
## Claude Plugin
The Claude plugin provides Claude Code commands.
```yaml
plugins:
claude:
enabled: true # auto-detected (requires `claude` CLI)
```
### Commands Provided
| Command | Description | Default Key |
| ------------ | --------------------------------- | ----------- |
| `ClaudeFork` | Fork Claude session in new window | — |
### Usage
```yaml
# Add keybinding for fork
keybindings:
f:
cmd: ClaudeFork
# Or invoke via command palette
# :ClaudeFork
```
## GitHub Plugin
The GitHub plugin provides PR status display and GitHub CLI commands. Auto-detected when `gh` CLI is installed.
```yaml
plugins:
github:
enabled: true # auto-detected (requires `gh` CLI)
results_cache: 8m # how often to refresh PR status (default: 8m)
```
### Commands Provided
| Command | Description | Default Key |
| ---------------- | -------------------------- | ----------- |
| `GithubOpenRepo` | Open repo in browser | — |
| `GithubOpenPR` | View current PR in browser | — |
| `GithubPRStatus` | Show PR status (popup) | — |
| `GithubPRCreate` | Create PR in browser | — |
### Status Display
Sessions with an associated PR show a status indicator:
| Label | Color | Meaning |
| ----------- | ------- | ------------- |
| `PR open` | Green | PR is open |
| `PR draft` | Muted | PR is a draft |
| `PR merged` | Primary | PR was merged |
| `PR closed` | Muted | PR was closed |
## LazyGit Plugin
The lazygit plugin provides commands to open lazygit in a tmux popup. Auto-detected when `lazygit` is installed.
```yaml
plugins:
lazygit:
enabled: true # auto-detected (requires `lazygit`)
```
### Commands Provided
| Command | Description | Default Key |
| ---------------- | ------------------------- | ----------- |
| `LazyGitOpen` | Open lazygit (full popup) | — |
| `LazyGitCommits` | Open lazygit commit log | — |
## Neovim Plugin
The neovim plugin provides a command to open neovim in the session's tmux session. Auto-detected when `nvim` is installed.
```yaml
plugins:
neovim:
enabled: true # auto-detected (requires `nvim`)
```
### Commands Provided
| Command | Description | Default Key |
| ------------ | ------------------------------ | ----------- |
| `NeovimOpen` | Open neovim in new tmux window | — |
## Context Directory Plugin
The context directory plugin provides commands to open context directories in the system file browser. Always available on macOS and Linux.
```yaml
plugins:
contextdir:
enabled: true # always available on macOS/Linux
```
### Commands Provided
| Command | Description | Default Key |
| -------------------- | -------------------------------- | ----------- |
| `ContextOpenSession` | Open session's `.hive` directory | — |
| `ContextOpenAll` | Open all context directories | — |
---
# Sources
!!! warning "Experimental"
Sources are experimental — the API and config names may still change.
Sources let hive browse issues/PRs from GitHub **and** Gitea/Forgejo,
search/filter items, and create a session from a selected item using the same
batch-spawn path as `hive batch`. The forge backend is detected from the
repository's git remote host (see [Backends](#backends)).
## Configuration
```yaml
sources:
search_limit: 30 # max items per search (default: 30)
cache_ttl: 30s # search result cache TTL (default: 30s)
hosts: # optional: override backend auto-detection per git remote host
git.example.com: gitea
github.acme.com: github
issues:
enabled: true # nil/omitted = auto, true/false = override
templates:
name: "gh-{{ .Fields.number }}-{{ .Title }}"
prompt: |
Work on {{ .Title }}
{{ .Fields.url }}
{{ .Detail }}
tags: ["github", "issue-{{ .Fields.number }}"]
prs:
enabled: true
templates:
name: "gh-pr-{{ .Fields.number }}-{{ .Title }}"
prompt: |
Review pull request {{ .Title }}
{{ .Fields.url }}
tags: ["github", "pr-{{ .Fields.number }}"]
```
!!! warning "Remote content in templates"
Source items put **remote-authored** text (issue/PR titles and bodies)
into `.Title`, `.Detail`, and the rendered `.Prompt`. Any spawn or
window command template that interpolates `.Prompt` runs through a
shell, so it must quote it with `shq` (the defaults do) — see the
[rules documentation](https://hivedesktop.com/cli/configuration/rules/) for details. Also note the rendered
prompt is handed to your agent verbatim: opening a session from a
public-repo issue feeds that issue's body to the agent, which is a
prompt-injection surface. Prefer scoping sources to repositories you
trust.
Rules:
- `enabled` follows the plugin convention: omitted means auto-detect (the
built-in sources activate only if the backend's CLI — `gh` or `tea` — is on
`PATH`), `true`/`false` explicitly enables/disables registration. The
`enabled` flag applies to a source id across both backends.
- Every source configures `templates.name`, `templates.prompt`, and optional
`templates.tags` — Go templates rendered against the selected item. Templates
are shared across backends, so keep them forge-neutral (all backends populate
`.Fields.number`, `.Fields.url`, and `.Detail`).
- The rendered name becomes a slug of at most 60 characters. When it has no
letters or digits left, hive uses `session-`. When an active session
already holds the slug, hive adds the item id, such as `-42`. See
[session names](https://hivedesktop.com/cli/getting-started/sessions/#session-names).
- Template data:
- `.ID`, `.Title`, `.Subtitle`
- `.Detail` — fetched markdown/detail content when available
- `.Fields` — source-specific data (e.g. `.Fields.number`, `.Fields.url`
for issues; `.Fields.review`, `.Fields.ci`, `.Fields.branch` for PRs)
## Backends
The forge backend for a repository is derived from its git remote host:
- `github.com` and hosts matching `github` → the **GitHub** backend (`gh`).
Unrecognized hosts also default here, so GitHub Enterprise hosts reuse `gh`.
- `codeberg.org` and hosts matching `gitea`/`forgejo` → the **Gitea** backend
(`tea`).
- `sources.hosts` overrides the detection for a specific host (`github` or
`gitea`), for mirrored or ambiguously named self-hosted instances.
The picker only shows the backend that matches the selected session's remote,
and each backend requires its CLI to be installed and authenticated:
- **GitHub** — `gh auth login` (supports GitHub Enterprise via `gh`'s host
config).
- **Gitea/Forgejo** — `tea login add` for the instance. hive runs `tea` in the
session's local checkout so it resolves the matching login from the repo's
remote; without a local checkout `tea` falls back to its default login.
## Built-in sources
| ID | GitHub (`gh`) | Gitea (`tea`) | Detail |
| -------- | --------------------------------- | ------------------ | ------ |
| `issues` | `gh issue list` / `gh issue view` | `tea issues list` | yes¹ |
| `prs` | `gh pr list` | `tea pulls list` | no |
¹ GitHub issues fetch the body via `gh issue view`; Gitea has no single-issue
JSON view, so `tea` returns the body inline and the picker uses it directly.
Each built-in runs the forge's own CLI and parses its JSON output. Gitea's `tea` list output is thinner than
GitHub's — it carries no CI rollup or review decision, so those card cells stay
blank for Gitea PRs.
## Opening a source
In the TUI, run `:SourceIssues [scope]` or `:SourcePRs [scope]` from the
command palette (scope defaults to the selected session's repo), or the
generic `:Sources [scope]`. The default `i`/`p` keybindings in the
sessions view open issues/PRs respectively.
Picker keys: `j/k` or arrows move selection, `/` enters search mode (esc
returns to navigate, keeping the filter), `O` opens the highlighted item in
your browser, and enter creates a session from it using the source's configured
templates.
Space marks items for batch spawning: enter then creates one session per
marked item instead of the highlighted one. Marks survive filtering, tab
switches, and re-searches, and are capped at 10 across all tabs. Session
creation runs on a single background stream; if some items fail (e.g. a
template error), the rest still spawn and the completion notice reports how
many failed.
Custom commands can pin a source id and scope via preset `args`, and keybindings
can reference those commands. This is how the built-in `SourceIssues`/`SourcePRs`
commands are defined:
```yaml
usercommands:
MyRepoIssues:
action: OpenSourcePicker
args: ["issues", "owner/repo"]
scope: ["sessions"]
silent: true
views:
sessions:
keybindings:
I: { cmd: MyRepoIssues }
```
---
# Themes
Hive ships with five built-in color themes. Each theme defines 9 semantic colors that drive all TUI styles.
```yaml
tui:
theme: catppuccin
```
## Available Themes
| Theme | Description |
| ------------- | -------------------------- |
| `tokyo-night` | Default — cool blue/purple |
| `gruvbox` | Warm retro |
| `catppuccin` | Catppuccin Mocha |
| `kanagawa` | Kanagawa Wave |
| `onedark` | One Dark |
## Semantic Color Roles
| Role | Usage |
| ------------ | -------------------------------------------------------- |
| `Primary` | Selections, borders, active elements |
| `Secondary` | IDs, branches, links |
| `Foreground` | Main text |
| `Muted` | De-emphasized text, help text, dividers |
| `Background` | Base background |
| `Surface` | Elevated surfaces (modals, selections, status bar) |
| `Success` | Positive states (active agent, open PRs, clean git) |
| `Warning` | Caution states (needs approval, dirty git) |
| `Error` | Error states, destructive actions, search highlights |
!!! tip "Live preview"
Use the `:ThemePreview` command in the TUI to cycle through available themes and see them applied in real time.
## Adding a Theme
Add a new palette to `cmd/hive/internal/theme/theme.go`:
```go
"my-theme": {
Primary: hex("#rrggbb"),
Secondary: hex("#rrggbb"),
Foreground: hex("#rrggbb"),
Muted: hex("#rrggbb"),
Background: hex("#rrggbb"),
Surface: hex("#rrggbb"),
SurfaceLow: hex("#rrggbb"),
Success: hex("#rrggbb"),
Warning: hex("#rrggbb"),
Error: hex("#rrggbb"),
},
```
All 70+ lipgloss styles are rebuilt from these 10 colors by `SetTheme()`, so adding a palette entry is all that's needed.
---
# Recipes
Practical guides for common hive workflows and integrations.
## Code Review
Two multi-agent review patterns using hive's tmux window spawning and messaging primitives. Both open a dedicated set of windows on the current session — no separate session needed.
### [Sequential Chain Review](https://hivedesktop.com/cli/recipes/sequential-chain-review/)
Serial — each agent reads and challenges the previous. Best for thorough adversarial analysis where you want reviewers to explicitly refute each other; contradictions get resolved rather than buried.
### [Parallel Code Review](https://hivedesktop.com/cli/recipes/parallel-code-review/)
Parallel specialists plus a coordinator. Best for fast feedback with active coordination: both specialists run simultaneously and the leader drives targeted follow-up rounds.
### [Inter-Agent Code Review](https://hivedesktop.com/cli/recipes/inter-agent-code-review/)
Spin up a dedicated reviewer agent via inbox messaging. Your session sends context, the reviewer analyzes the branch, and feedback comes back through pub/sub — no manual coordination needed.
## Context Management
### [Git-backed Context](https://hivedesktop.com/cli/recipes/git-backed-context/)
Store plans and research documents in a git repository by pointing `context.base_dir` at a dedicated repo. Gives you full history, diffs, and cross-machine sharing for all your `.hive/` documents.
## Automation
### [Ralph Loop](https://hivedesktop.com/cli/recipes/ralph-loop/)
Work through an `hive hc` epic backlog autonomously — runs a fresh Claude process per task, retrying until quality gates pass before moving on.
---
# Sequential Chain Review
Three agents review the same diff in strict order — each one reads and challenges the previous reviewer's findings before writing its own report. The final agent produces a verdict that synthesises and stress-tests all prior analysis.
## How it works
```mermaid
sequenceDiagram
participant Co as codex
participant A as agent
participant Cl as claude (final)
Co->>Co: Read diff
Co->>Co: Publish findings
Note right of Co: review-{id}.codex
A-->>Co: Wait for review-{id}.codex
A->>A: Read diff
A->>A: Challenge / deepen codex findings
A->>A: Publish combined analysis
Note right of A: review-{id}.agent
Cl-->>A: Wait for review-{id}.agent
Cl-->>Co: Read review-{id}.codex
Cl->>Cl: Read diff
Cl->>Cl: Challenge both reviewers
Cl->>Cl: Produce final verdict
```
**Key characteristics:**
- **Serial** — each stage blocks on the previous; total time is the sum of all three passes
- **Adversarial** — each reviewer is explicitly instructed to challenge the one before it
- **Accumulating context** — the final reviewer has both earlier reports plus the raw diff
- **Best for:** thorough pre-merge review where you want contradictions surfaced and resolved
Compare with [Parallel Code Review](https://hivedesktop.com/cli/recipes/parallel-code-review/), which runs specialist agents simultaneously and is better suited to faster, iterative feedback.
## Config
Add to `~/.config/hive/config.yaml`:
```yaml
usercommands:
ReviewCodeSync:
help: "sequential chain review: codex → agent → claude"
silent: true
windows:
- name: codex
command: |-
codex 'You are the first reviewer in a sequential code review chain.
Your workflow:
1. Read all changes under review:
git diff main...HEAD (branch commits)
git diff (unstaged changes)
2. Analyse thoroughly for: logic correctness, error handling, edge cases, naming
clarity, test coverage, API design, and any potential bugs.
3. Publish your complete findings:
hive msg pub --topic review-{{ .ID }}.codex "your detailed findings"
Be thorough. The next reviewer will read your report and challenge it.'
- name: agent
command: |-
agent 'You are the second reviewer in a sequential code review chain.
Your workflow:
1. Wait for the first reviewer (codex) to finish:
hive msg sub --topic review-{{ .ID }}.codex --wait --timeout 2h
2. Read all changes under review:
git diff main...HEAD (branch commits)
git diff (unstaged changes)
3. Read codex'"'"'s findings from step 1.
4. Analyse for: security vulnerabilities, architectural concerns, design pattern
misuse, dependency risks, concurrency issues, and anything codex may have
missed or misjudged.
5. For each of codex'"'"'s findings: agree, refute, or deepen it with evidence
from the diff.
6. Publish your combined analysis:
hive msg pub --topic review-{{ .ID }}.agent "your analysis"
Be critical. Do not simply restate what codex said.'
- name: claude
focus: true
command: |-
{{ agentCommand }} {{ agentFlags }} 'You are the final reviewer in a sequential
code review chain. Your job is to be ruthlessly critical.
Your workflow:
1. Wait for the second reviewer (agent) to finish:
hive msg sub --topic review-{{ .ID }}.agent --wait --timeout 2h
2. Read codex'"'"'s findings:
hive msg sub --topic review-{{ .ID }}.codex
3. Read agent'"'"'s findings from step 1.
4. Read all changes under review:
git diff main...HEAD (branch commits)
git diff (unstaged changes)
5. Produce the final verdict. You must:
- Challenge every finding from both reviewers: demand evidence, reject vague claims
- Identify issues NEITHER reviewer caught
- Call out where the two reviewers contradict each other and resolve it
- Rank all issues by severity (critical / major / minor)
- Give a clear ship / do not ship recommendation with specific conditions
Be adversarial. Assume the previous reviewers missed things.'
```
!!! note "Shell quoting"
The `'"'"'` sequences in the commands are the POSIX shell idiom for embedding a literal single quote inside a single-quoted string (end quote → literal `'` → reopen quote). They appear as an apostrophe in the prompt text that codex, agent, and claude receive.
## Template variables
| Variable | Value |
|---|---|
| `{{ .ID }}` | Session ID (6-char alphanumeric) — used as a unique namespace for topics |
| `{{ agentCommand }}` | The configured agent binary (e.g. `claude`) |
| `{{ agentFlags }}` | Any extra flags from the agent profile |
`{{ .ID }}` ensures topic names are shell-safe even when session display names contain spaces or slashes.
## Usage
In the hive TUI, select your working session and press `:`:
```
:ReviewCodeSync
```
Three tmux windows open in the current session: `codex` starts immediately, `agent` and `claude` each block on a messaging subscription until their predecessor publishes. The `claude` window is focused — it will display the final verdict when both earlier stages complete.
## Customisation
**Change the second reviewer tool** — replace `agent` with any CLI tool in the `agent` window command.
**Adjust timeout** — `--timeout 2h` on the `hive msg sub --wait` calls controls how long each stage waits before giving up.
**Add a fourth stage** — publish from the claude window to a new topic and add a fourth window that subscribes to it.
---
# Parallel Code Review
A coordinator agent (claude) directs two specialist agents (codex and cursor) that run concurrently. The coordinator waits for both first-pass reports, identifies gaps, and sends targeted follow-up questions for another round — iterating until satisfied, then producing a final summary.
## How it works
```mermaid
flowchart LR
Co[codex] -->|"review-{id}.codex"| L[leader]
Cu[cursor] -->|"review-{id}.cursor"| L
L -->|"review-{id}.feedback"| Co
L -->|"review-{id}.feedback"| Cu
L --> S[final summary]
```
**Key characteristics:**
- **Parallel** — codex and cursor run simultaneously; total time is dominated by the slower of the two, not their sum
- **Iterative** — the coordinator drives multiple rounds of targeted follow-up questions
- **Specialist split** — codex focuses on correctness/quality, cursor on security/architecture
- **Best for:** fast feedback with active human-like coordination, especially on larger diffs
Compare with [Sequential Chain Review](https://hivedesktop.com/cli/recipes/sequential-chain-review/), which chains three agents in strict order and is better suited to adversarial analysis where you want reviewers to explicitly challenge each other.
## Config
Add to `~/.config/hive/config.yaml`:
```yaml
usercommands:
CodeReview:
help: "parallel multi-agent review: codex + cursor coordinated by claude"
silent: true
windows:
- name: leader
focus: true
command: |-
{{ agentCommand }} {{ agentFlags }} 'You are coordinating a code review of the
current branch changes.
Two specialist agents are running in parallel in this session:
- codex publishes findings to: review-{{ .ID }}.codex
- cursor publishes findings to: review-{{ .ID }}.cursor
Your workflow:
1. Understand the changes under review:
git diff main...HEAD (branch commits)
git diff (unstaged changes)
2. Wait for both agents to complete their first pass:
hive msg sub --topic review-{{ .ID }}.codex --wait
hive msg sub --topic review-{{ .ID }}.cursor --wait
3. Read their findings. Identify gaps, contradictions, and areas needing deeper
investigation.
4. Send targeted follow-up questions to each agent:
hive msg pub --topic review-{{ .ID }}.feedback "your questions"
5. Wait for updated responses and repeat steps 2-4 until satisfied.
6. Produce a final written summary of all findings.'
- name: codex
command: |-
codex 'You are reviewing code changes for correctness and quality.
Your workflow:
1. Read all changes under review:
git diff main...HEAD (branch commits)
git diff (unstaged changes)
2. Analyse for logic correctness, error handling, naming, test coverage, and
API design.
3. Publish your findings:
hive msg pub --topic review-{{ .ID }}.codex "your findings"
4. Wait for follow-up from the leader:
hive msg sub --topic review-{{ .ID }}.feedback --wait
5. Address the follow-up, publish an updated report to the same topic, then wait
again.
Repeat steps 4-5 until no further feedback arrives.'
- name: cursor
command: |-
agent 'You are reviewing code changes for security and architecture.
Your workflow:
1. Read all changes under review:
git diff main...HEAD (branch commits)
git diff (unstaged changes)
2. Analyse for security issues, architectural concerns, dependency risks, and
design patterns.
3. Publish your findings:
hive msg pub --topic review-{{ .ID }}.cursor "your findings"
4. Wait for follow-up from the leader:
hive msg sub --topic review-{{ .ID }}.feedback --wait
5. Address the follow-up, publish an updated report to the same topic, then wait
again.
Repeat steps 4-5 until no further feedback arrives.'
```
!!! note "Shell quoting"
The `'"'"'` sequences in the commands are the POSIX shell idiom for embedding a literal single quote inside a single-quoted string (end quote → literal `'` → reopen quote). They appear as an apostrophe in the prompt text that the agents receive.
## Template variables
| Variable | Value |
|---|---|
| `{{ .ID }}` | Session ID (6-char alphanumeric) — used as a unique namespace for topics |
| `{{ agentCommand }}` | The configured agent binary (e.g. `claude`) |
| `{{ agentFlags }}` | Any extra flags from the agent profile |
`{{ .ID }}` ensures topic names are shell-safe even when session display names contain spaces or slashes.
## Usage
In the hive TUI, select your working session and press `:`:
```
:CodeReview
```
Three tmux windows open in the current session. The `leader` window is focused — it will display coordination activity and the final summary. The `codex` and `cursor` windows each start reviewing immediately in parallel; the `leader` blocks until it receives both first-pass reports on their respective topics.
## Customisation
**Swap the specialist tools** — replace `codex` or `agent` in the window commands with any CLI reviewer.
**Add a third specialist** — add a fourth window, give it a unique topic (e.g. `review-{{ .ID }}.perf`), update the leader prompt to include it in the wait list and feedback loop.
**One-shot mode** — remove steps 4–5 from the specialist prompts and the loop from the leader prompt to do a single pass without follow-up rounds.
---
# Inter-Agent Code Review
Orchestrate code reviews by spinning up a dedicated reviewer agent that receives context via inbox messaging, reviews your branch, and sends feedback back to you.
!!! note "Requirements"
This recipe requires the `agent-send` bundled script (available via `{{ agentSend }}`) and the `/hive-msg` skill for inbox messaging. Both are available out of the box with the tmux plugin enabled.
## Config
Add these user commands to your `~/.config/hive/config.yaml`:
```yaml
usercommands:
ReviewRequest:
sh: "~/.config/hive/scripts/request-review.sh {{ .Name | shq }} {{ agentSend | shq }} {{ agentWindow | shq }}"
help: "Request code review of current branch"
silent: false
CheckInbox:
sh: "hive msg sub -t agent.{{ .ID }}.inbox"
help: "Check inbox for new messages"
silent: false
```
## Scripts
### request-review.sh
Creates a new hive session with a unique ID, sends review context to its inbox, and instructs your current session to send detailed review instructions via the `/hive-msg` skill.
Save to `~/.config/hive/scripts/request-review.sh`:
```bash
#!/bin/bash
# Usage: request-review.sh
# Requests a code review of the current branch
CURRENT_SESSION_NAME="${1:-}"
AGENT_SEND="${2:-}"
AGENT_WINDOW="${3:-claude}"
CURRENT_REPO=$(git remote get-url origin 2>/dev/null)
CURRENT_BRANCH=$(git branch --show-current)
if [ -z "$CURRENT_BRANCH" ]; then
echo "Error: Not on a git branch"
exit 1
fi
if [ -z "$CURRENT_SESSION_NAME" ]; then
echo "Error: Session name required"
exit 1
fi
if [ -z "$AGENT_SEND" ]; then
echo "Error: agent-send path required"
exit 1
fi
# Sanitize branch name for use in session name (replace / with -)
SAFE_BRANCH=$(echo "$CURRENT_BRANCH" | tr '/' '-')
# Generate unique session ID for reviewer
NEW_SESSION=$(hive msg topic --prefix "")
# Create new review session
BATCH_JSON=$(cat <
# Ralph Loop
Work through a task backlog autonomously by running a fresh Claude process per task,
iterating until quality gates pass before moving on.
!!! note "Requirements"
Requires `claude` CLI in PATH with a valid API key. Tasks are managed via
`hive hc` and scoped to the repository. The loop runs in a dedicated tmux
window so the TUI stays responsive.
## How It Works
1. Claim the next open task from an epic (`hive hc next --assign`)
2. Write task details to `.hive/ralph-task.md`
3. Run `claude --dangerously-skip-permissions -p` with the task as the prompt
4. After Claude exits, run your configured check command
5. If checks pass — mark the task done and continue
6. If checks fail — retry up to `MAX_RETRIES` times, then release the task and move on
7. Repeat until no tasks remain
## Setup
### 1. Create an epic with tasks
```bash
echo '{
"title": "Sprint backlog",
"type": "epic",
"children": [
{"title": "Add input validation to API", "type": "task"},
{"title": "Fix pagination bug", "type": "task"},
{"title": "Add rate limiting middleware", "type": "task"}
]
}' | hive hc create
```
Note the epic ID from the output (e.g., `hc-a1b2c3d4`).
### 2. Add the user command
Add to your `~/.config/hive/config.yaml`:
```yaml
usercommands:
RalphLoop:
help: "Run ralph loop on hc epic backlog"
form:
- variable: epic_id
type: text
label: "Epic ID"
placeholder: "hc-a1b2c3d4"
- variable: check_cmd
type: text
label: "Check command"
placeholder: "mise run check"
- variable: max_retries
type: text
label: "Max retries per task"
placeholder: "3"
windows:
- name: ralph
focus: true
command: >-
bash ~/.config/hive/scripts/ralph-loop.sh
{{ .Path | shq }}
{{ .Form.epic_id | shq }}
{{ .Form.check_cmd | shq }}
{{ .Form.max_retries | shq }}
```
The `windows` field opens a tmux window named `ralph` in the current session.
See [User Commands — Multi-agent Workflows](https://hivedesktop.com/cli/configuration/commands/#multi-agent-workflows) for details on the `windows` field.
### 3. Save the script
Save to `~/.config/hive/scripts/ralph-loop.sh` and make it executable:
```bash
#!/usr/bin/env bash
set -euo pipefail
SESSION_PATH="${1:?Usage: ralph-loop.sh [check-cmd] [max-retries]}"
EPIC_ID="${2:?Epic ID required}"
CHECK_CMD="${3:-mise run check}"
MAX_RETRIES="${4:-3}"
cd "$SESSION_PATH"
while true; do
TASK=$(hive hc next "$EPIC_ID" --assign 2>/dev/null) || {
echo "No tasks remaining. Done."
break
}
ID=$(jq -r '.id' <<< "$TASK")
TITLE=$(jq -r '.title' <<< "$TASK")
DESC=$(jq -r '.desc // ""' <<< "$TASK")
echo ""
echo "==> $ID: $TITLE"
cat > .hive/ralph-task.md << EOF
# $TITLE
$DESC
## Definition of Done
All quality gates must pass before you finish: \`$CHECK_CMD\`
Commit and push your changes on a feature branch when complete.
EOF
ATTEMPT=0
SUCCESS=false
while [ "$ATTEMPT" -lt "$MAX_RETRIES" ]; do
ATTEMPT=$((ATTEMPT + 1))
echo " Attempt $ATTEMPT/$MAX_RETRIES"
claude --dangerously-skip-permissions \
-p "$(cat .hive/ralph-task.md)"
if [ -z "$CHECK_CMD" ] || eval "$CHECK_CMD"; then
SUCCESS=true
break
fi
echo " Check failed, retrying..."
done
if $SUCCESS; then
hive hc update "$ID" --status done
echo " Done: $ID"
else
echo " Gave up after $MAX_RETRIES attempts: $ID — releasing"
hive hc update "$ID" --status open --unassign
fi
done
echo ""
echo "Ralph loop complete."
```
```bash
chmod +x ~/.config/hive/scripts/ralph-loop.sh
```
## Usage
Select a session in the TUI and open the command palette:
```
:RalphLoop
```
A form prompts for the epic ID, check command, and max retries, then a `ralph` window opens
in the current tmux session. Switch to it to watch progress. The TUI remains usable
while the loop runs.
**Leave check command empty** to skip quality gate verification and trust Claude's
own judgment on when a task is complete.
## Customization
**Task prompt** — edit the heredoc in the script to give Claude additional context,
coding standards, or constraints that apply to all tasks in the loop.
**Task scope** — each run targets a single epic. Create separate epics to organize
work by feature or priority, then run the loop against each.
---
# Git-backed Context
Store hive's planning and research documents in a git repository so they are version-controlled, searchable, and shareable across machines.
By default, the documents live inside hive's data directory (`~/.local/share/hive/context/`), which is not tracked by git. That directory is the root of [Hive Drive](https://hivedesktop.com/cli/getting-started/context/), so this recipe puts the whole drive under git. Redirecting them into a dedicated repository gives you full history, diffs, and automatic sync across machines.
## Setup
**1. Create (or pick) a git repository for your context documents:**
```bash
mkdir ~/notes/hive-context
cd ~/notes/hive-context
git init
git remote add origin git@github.com:you/hive-context.git
```
**2. Point hive at it via `context.base_dir`:**
```yaml
# ~/.config/hive/config.yaml
context:
base_dir: ~/notes/hive-context
```
**3. Validate the config:**
```bash
hive doctor
```
**4. Initialize the `.hive` symlink in each repository you work on:**
```bash
cd ~/projects/my-repo
hive drive init # creates .hive → ~/notes/hive-context/{owner}/{repo}/
```
Documents written to `.hive/plans/` and `.hive/research/` now land inside `~/notes/hive-context/`.
## Automatic Syncing
Set up a periodic job to commit, pull, and push the context repository automatically. This handles documents written at any point during a session without requiring manual intervention.
=== "macOS (launchd)"
Save to `~/Library/LaunchAgents/hive.context-sync.plist`:
```xml
Labelhive.context-syncProgramArguments/bin/sh-ccd ~/notes/hive-context && git add -A && git diff --cached --quiet || git commit -m "auto: sync context" && git pull --rebase --autostash && git pushStartInterval300RunAtLoad
```
Load it:
```bash
launchctl load ~/Library/LaunchAgents/hive.context-sync.plist
```
=== "Linux (cron)"
```bash
# crontab -e
*/5 * * * * cd ~/notes/hive-context && git add -A && git diff --cached --quiet || git commit -m "auto: sync context" && git pull --rebase --autostash && git push
```
This runs every 5 minutes: commits any new or changed documents, pulls remote changes, and pushes.
## Directory Structure
With `base_dir: ~/notes/hive-context`, the layout is:
```
~/notes/hive-context/
├── my-org/
│ ├── my-repo/
│ │ ├── plans/
│ │ │ └── 2026-01-15-auth-refactor.md
│ │ └── research/
│ │ └── api-analysis.md
│ └── other-repo/
│ └── plans/
└── shared/
└── architecture-decisions.md
```
Each project's `.hive` symlink points to its own subdirectory. A space is a folder under the root: `//` for a repository, `workspaces//` for a Hive Desktop Chats workspace, and `shared/`. All documents live in one repository that you can push, pull, and browse with standard git tools.
Hive Desktop shows the same files in its Drive view, and Obsidian or git sees the same files the desktop does. A document an agent writes, a file you edit in Obsidian, and a commit pulled by the sync job all appear in the drive within a second. Hive Desktop also stores its canvases here, as `.canvas.json` files, so they are committed with the rest.
## Tips
- **Use a private repository** if your plans contain sensitive design details.
- **Add a `.gitignore`** to the context repo to exclude any generated files or large binaries you don't want tracked.
- **Use Obsidian as a GUI** — open `~/notes/hive-context` as an Obsidian vault to get a rich editor, graph view, and search across all your plans and research documents.
- **Add a `CLAUDE.md`** at the root of the context repository and use the repository as a command center for dispatching sessions and managing work.
---
# FAQ
Common questions about hive sessions, terminal integration, and agent management.
### What's the difference between a hive session and a tmux session?
- **Hive session**: A git clone + terminal environment managed by hive
- **Tmux session**: A terminal multiplexer session that hosts the hive session
When you create a hive session with tmux integration, hive spawns a tmux session with the same name. The relationship is:
```
Hive Session "fix-bug" (ID: abc123)
↓ creates
Tmux Session "fix-bug"
↓ contains
Agent (Claude) running in tmux window
```
See [Getting Started](https://hivedesktop.com/cli/getting-started/) for full terminology.
### Can I run multiple agents in one session?
Yes. Each agent runs in its own tmux window within the session. Configure [agent profiles](https://hivedesktop.com/cli/configuration/#agents) to define which tools are available, and use `tmux.preview_window_matcher` to tell hive which windows to monitor. The TUI tracks each agent window independently with its own status indicator.
### Why is the inbox format `agent..inbox` not `session..inbox`?
The inbox belongs to the agent (AI tool), not the session (container). The `agent.` prefix supports future per-agent addressing using `agent...inbox`.
See [Messaging](https://hivedesktop.com/cli/getting-started/messaging/) for full details on inter-agent communication.
### What's a "recycled" session?
When you're done with a session, you can recycle it instead of deleting it. Recycling:
1. Resets the git repository to a clean state
2. Renames the directory to a recycled pattern
3. Makes it available for reuse
When you create a new session, hive will reuse a recycled session if available, avoiding a fresh clone and saving time.
!!! tip
Use `max_recycled` in your [rules](https://hivedesktop.com/cli/configuration/rules/) to control how many recycled sessions are kept per repository. Set to `0` for unlimited.