# biff

<img src="https://raw.githubusercontent.com/punt-labs/biff/main/docs/biff.png" alt="The original biff mail notification app" width="116" align="right">

> Team communication for engineers who never leave the terminal.

[![License](https://img.shields.io/github/license/punt-labs/biff)](LICENSE)
[![CI](https://img.shields.io/github/actions/workflow/status/punt-labs/biff/test.yml?label=CI)](https://github.com/punt-labs/biff/actions/workflows/test.yml)
[![PyPI](https://img.shields.io/pypi/v/punt-biff)](https://pypi.org/project/punt-biff/)

Named after the Berkeley dog whose 1980 mail notification program was part of the same BSD family as `talk`, `wall`, `finger`, `who`, and `mesg`. Biff resurrects the Unix communication vocabulary as MCP-native slash commands inside Claude Code.

**Platforms:** macOS, Linux

## Quick Start

```bash
curl -fsSL https://raw.githubusercontent.com/punt-labs/biff/6ce60b3/install.sh | sh
```

Restart Claude Code twice. Type `/who` to see your team.

<details>
<summary>Manual install (if you already have uv)</summary>

```bash
uv tool install punt-biff
biff install
biff doctor
```

</details>

<details>
<summary>Verify before running</summary>

```bash
curl -fsSL https://raw.githubusercontent.com/punt-labs/biff/6ce60b3/install.sh -o install.sh
shasum -a 256 install.sh
cat install.sh
sh install.sh
```

</details>

## Features

- **MCP-native** --- runs inside Claude Code as slash commands, no separate app
- **BSD vocabulary** --- `/who`, `/write`, `/talk`, `/wall` --- commands engineers already know
- **NATS relay** --- cross-machine presence and messaging over encrypted connections
- **Agent-first** --- agents show up in `/who` alongside humans, coordinate via `/plan` and `/write`
- **Status bar** --- live unread count, wall broadcasts, talk messages --- wraps your existing status line
- **Zero config** --- installs in one command, activates per-repo with `/biff y`

## What It Looks Like

### See who's online

```text
> /who

▶  NAME    TTY   IDLE  S  HOST       DIR                        PLAN
   @kai    tty1  0:03  +  m2-mb-air  /Users/kai/code/myapp      refactoring auth module
   @eric   tty2  1:22  +  m2-mb-air  /Users/eric/code/myapp     reviewing PR #47
   @priya  tty1  0:00  +  priya-mbp  /Users/priya/code/myapp    writing integration tests
```

`S` is message status: `+` means accepting messages, `-` means do not disturb.

### Send a message

```text
> /write @kai "auth module looks good, just one nit on the error handling"

Message sent to @kai.
```

### Check your inbox

```text
> /read

▶  FROM   DATE              MESSAGE
   kai    Sat Feb 15 14:01  hey, ready for review?
   eric   Sat Feb 15 13:45  pushed the fix for the flaky test
   priya  Sat Feb 15 12:30  can you look at the migration script?
```

<details>
<summary>More examples: /finger, /plan, /last, /wall, /talk, /mesg</summary>

### Check what someone is working on

```text
> /finger @kai

▶  Login: kai                              Messages: on
   On since Sat Feb 15 14:01 (UTC) on tty1, idle 0:03
   Host: m2-mb-air  Dir: /Users/kai/code/myapp
   Plan:
    refactoring auth module
```

### Set your status

```text
> /plan "debugging the websocket reconnect logic"

Plan: debugging the websocket reconnect logic
```

Bead IDs auto-expand:

```text
> /plan biff-ka4

Plan: biff-ka4: post-checkout hook: update plan from branch
```

### Session history

```text
> /last

▶  NAME    TTY   HOST       LOGIN             LOGOUT            DURATION
   @kai    tty3  m2-mb-air  Sat Feb 22 14:01  still logged in   -
   @kai    tty2  m2-mb-air  Sat Feb 22 11:30  Sat Feb 22 13:58  2:28
   @eric   tty1  m2-mb-air  Sat Feb 22 09:15  Sat Feb 22 12:45  3:30
```

### Broadcast to the team

```text
> /wall "release freeze --- do not push to main" 2h

Wall posted (2h): release freeze --- do not push to main
```

Every teammate's status bar shows `WALL: release freeze` in bold red. Expires automatically.

### Talk in real time

```text
> /talk @kai "can you review PR #42?"

Talk session started with @kai. Replies appear on the status bar.
```

Incoming messages show on your status bar automatically. Reply with `/write`, close with `/talk end`.

### Go do-not-disturb

```text
> /mesg n

is n
```

Your status bar shows `(n)` instead of the unread count. Messages still accumulate --- `/mesg y` or `/read` reveals them.

</details>

## Commands

| Command | Origin | Purpose |
|---------|--------|---------|
| `/write @user "text"` | BSD `write` | Send a message |
| `/read` | BSD `from` | Check your inbox |
| `/finger @user` | BSD `finger` | Check what someone is working on |
| `/who` | BSD `who` | List active sessions |
| `/last` | BSD `last` | Show session login/logout history |
| `/plan "text"` | BSD `.plan` | Set your status |
| `/tty "name"` | BSD `tty` | Name the current session |
| `/talk @user "msg"` | BSD `talk` | Start a real-time conversation |
| `/wall "text"` | BSD `wall` | Broadcast to the team |
| `/mesg y` \| `/mesg n` | BSD `mesg` | Control message reception |

## Setup

Biff requires a git repo and a GitHub identity. Your username and display name are resolved automatically from `gh auth` --- no manual configuration needed.

### Create a `.biff` file

Commit a `.biff` file in your repo root (TOML format):

```toml
[team]
members = ["kai", "eric", "priya"]

[relay]
url = "tls://connect.ngs.global"
```

Biff ships with a shared demo relay so your team can start immediately. When you're ready for your own relay, see [relay configuration](docs/INSTALLING.md#relay-configuration).

`biff install` registers the MCP server, installs slash commands, and enables the plugin. `biff enable` activates biff in the current repo and deploys git hooks. Run `biff doctor` to verify everything is wired up. See [Installing](docs/INSTALLING.md) for the full guide.

## Status Bar

Biff appends to your existing Claude Code status line --- it never replaces it:

```text
Line 1: your-existing-status | kai:tty1(3)
Line 2: ▶ WALL: release freeze until 5pm
```

Three states: `kai:tty1(0)` when caught up, **`kai:tty1(3)`** (bold yellow) with unreads, `kai:tty1(n)` when messages are off. Line 2 shows active `/talk` messages (bold yellow), wall broadcasts (bold red), or an idle marker.

## Agents Welcome

Because biff speaks MCP, it does not distinguish between human and agent sessions. An autonomous coding agent can `/plan` what it's working on, `/write` a human when it needs a decision, and show up in `/who` alongside everyone else.

Biff coordinates hybrid teams across two planes:

- **Logical plane (cross-machine):** `/plan` shows the task each agent is working on. `/who` shows all plans across all machines. This prevents duplicate work.
- **Physical plane (same-machine):** `/who` shows host and directory per session. When two agents share the same machine and directory, they coordinate via `/write` and create git worktrees to work in isolation.

See [Agent Workflow](docs/AGENT_WORKFLOW.md) for patterns and examples.

## Vision

Biff is built on a simple thesis: the terminal is the new center of gravity for software engineering, and the communication tools haven't caught up. Slack was built for the open-office, always-online workplace. Biff is built for the deep-focus, AI-accelerated one.

Every command implies intent. There are no channels to monitor, no threads to catch up on, no emoji reactions to parse. Communication is pull-based: you decide when to engage.

## Roadmap

### Shipped

- Presence: `/who`, `/finger`, `/plan`, `/tty`, `/last`
- Messaging: `/write`, `/read`, `/mesg`
- Broadcast: `/wall` with duration-based expiry
- Real-time: `/talk` with NATS instant wake-up and status bar display
- NATS relay for cross-machine communication
- Per-project activation (`/biff y`) with lazy connection management
- Status bar with live unread count, wall, and talk display
- Workflow hooks: plan auto-expand, session lifecycle, git integration

### Next

| Phase | What Ships |
|-------|-----------|
| **Security** | E2E encryption (NaCl/libsodium), GitHub identity and auth, per-repo NATS credentials |
| **Real-time** | `/pair` for session sharing with explicit consent |
| **Hosted relay** | Managed service with admin controls, audit logs, team isolation |

## Documentation

[Installing](docs/INSTALLING.md) |
[Agent Workflow](docs/AGENT_WORKFLOW.md) |
[Claude Setup](docs/CLAUDE_SETUP.md) |
[FAQ](docs/FAQ.md) |
[Troubleshooting](docs/TROUBLESHOOTING.md)

[Design Log](DESIGN.md) |
[Installer Design](DESIGN-INSTALLER.md) |
[Changelog](CHANGELOG.md) |
[Contributing](CONTRIBUTING.md)

## Development

```bash
uv sync --extra dev        # Install dependencies
uv run ruff check .        # Lint
uv run ruff format .       # Format
uv run mypy src/ tests/    # Type check
uv run pytest              # Test (unit + integration)
uv run pytest -m nats      # NATS tests (requires local nats-server)
uv run pytest -m hosted    # Hosted NATS tests (see CONTRIBUTING.md)
```

## License

MIT
