Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "biff",
"name": "biff-dev",
"description": "UNIX-style team communication for Claude Code: /who, /finger, /plan, /write, /read, /mesg, /tty, /last, /wall, /talk",
"version": "1.10.0",
"author": {
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Named after the Berkeley dog whose 1980 mail notification program was part of th
## Quick Start

```bash
curl -fsSL https://raw.githubusercontent.com/punt-labs/biff/cbca365/install.sh | sh
curl -fsSL https://raw.githubusercontent.com/punt-labs/biff/677d77a/install.sh | sh
```

Restart Claude Code twice. Type `/who` to see your team.
Expand All @@ -37,7 +37,7 @@ biff doctor
<summary>Verify before running</summary>

```bash
curl -fsSL https://raw.githubusercontent.com/punt-labs/biff/cbca365/install.sh -o install.sh
curl -fsSL https://raw.githubusercontent.com/punt-labs/biff/677d77a/install.sh -o install.sh
shasum -a 256 install.sh
cat install.sh
sh install.sh
Expand Down
16 changes: 16 additions & 0 deletions commands/biff-dev.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
description: Enable or disable biff for this repo
argument-hint: "y | n"
allowed-tools: ["ToolSearch", "mcp__plugin_biff-dev_tty__biff"]
---
<!-- markdownlint-disable MD041 -->

## Input

Arguments: $ARGUMENTS

Parse the argument as `y` or `n`. Map `y` to `enabled=true`, `n` to `enabled=false`.

## Task

Call `mcp__plugin_biff-dev_tty__biff` with `enabled` set to the parsed value. The result is already formatted by a PostToolUse hook and displayed above. Do not repeat or reformat the data. Do not send any text after the tool call.
16 changes: 16 additions & 0 deletions commands/finger-dev.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
description: Check what a teammate is working on and their availability
argument-hint: "@user"
allowed-tools: ["ToolSearch", "mcp__plugin_biff-dev_tty__finger"]
---
<!-- markdownlint-disable MD041 -->

## Input

Arguments: $ARGUMENTS

Parse the username from arguments, stripping any leading `@` if present.

## Task

Call `mcp__plugin_biff-dev_tty__finger` with `user` set to the parsed username. Emit the tool output exactly as returned — character for character, including the leading ▶ unicode character. Do not reformat, add commentary, wrap in code fences, convert to markdown tables, or add boxes around the output.
12 changes: 12 additions & 0 deletions commands/last-dev.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
description: Show session login/logout history
argument-hint: "[@user] [count]"
allowed-tools: ["ToolSearch", "mcp__plugin_biff-dev_tty__last"]
---
<!-- markdownlint-disable MD041 -->

Call `mcp__plugin_biff-dev_tty__last` with optional `user` (e.g. `@kai`) and `count` (default 25) arguments.

If the result says "No session history.", say "No session history available."

Otherwise, emit the tool output exactly as returned — character for character, including the leading ▶ unicode character. Do not reformat, add commentary, wrap in code fences, convert to markdown tables, or add boxes around the output.
16 changes: 16 additions & 0 deletions commands/mesg-dev.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
description: Control message reception
argument-hint: "y | n"
allowed-tools: ["ToolSearch", "mcp__plugin_biff-dev_tty__mesg"]
---
<!-- markdownlint-disable MD041 -->

## Input

Arguments: $ARGUMENTS

Parse the argument as `y` or `n`. Map `y` to `enabled=true`, `n` to `enabled=false`.

## Task

Call `mcp__plugin_biff-dev_tty__mesg` with `enabled` set to the parsed value. The result is already formatted by a PostToolUse hook and displayed above. Do not repeat or reformat the data. Do not send any text after the tool call.
14 changes: 14 additions & 0 deletions commands/plan-dev.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
description: Set what you're currently working on (visible to teammates)
argument-hint: "<message>"
allowed-tools: ["ToolSearch", "mcp__plugin_biff-dev_tty__plan"]
---
<!-- markdownlint-disable MD041 -->

## Input

Arguments: $ARGUMENTS

## Task

Call `mcp__plugin_biff-dev_tty__plan` with `message` set to the full arguments string. The result is already formatted by a PostToolUse hook and displayed above. Do not repeat or reformat the data. Do not send any text after the tool call.
30 changes: 30 additions & 0 deletions commands/poll-dev.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
description: Set the background polling interval
argument-hint: "{N}s | {N}m | n"
allowed-tools: ["ToolSearch", "mcp__plugin_biff-dev_tty__set_poll_interval", "mcp__plugin_biff-dev_tty__get_poll_status", "CronCreate", "CronList", "CronDelete"]
---
<!-- markdownlint-disable MD041 -->

## Input

Arguments: $ARGUMENTS

If no argument provided, call `mcp__plugin_biff-dev_tty__get_poll_status` and report the result. Stop.

Otherwise parse the argument as an interval (`{N}s` or `{N}m`, e.g. `2s`, `30s`, `5m`) or `n` (disable). Sub-minute intervals set the server-side tick rate; the durable cron fires at 1-minute minimum (cron granularity limit).

## Task

1. Call `mcp__plugin_biff-dev_tty__set_poll_interval` with `interval` set to the parsed value.
2. If the interval is `n` (disable):
- Call `CronList` and find any job whose `prompt` field exactly matches `/biff-dev:read-dev`.
- If found, call `CronDelete` with that job's `id` to remove the polling cron.
3. If the interval is NOT `n`:
- Call `CronList` and check if any job has a `prompt` field that exactly matches `/biff-dev:read-dev`.
- If an existing `/biff-dev:read-dev` cron exists, call `CronDelete` on it first.
- Call `CronCreate` with:
- `cron`: convert the interval to a cron expression (e.g. `2s` -> `*/1 * * * *`, `5s` -> `*/1 * * * *`, `1m` -> `*/1 * * * *`, `2m` -> `*/2 * * * *`, `5m` -> `*/5 * * * *`). For intervals under 1 minute, use `*/1 * * * *` (cron minimum is 1 minute).
- `prompt`: `/biff-dev:read-dev`
- `recurring`: true
- `durable`: true
4. Do not mention the cron setup or send any other text to the user beyond the tool result.
11 changes: 11 additions & 0 deletions commands/read-dev.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
description: Check your inbox for new messages
allowed-tools: ["ToolSearch", "mcp__plugin_biff-dev_tty__read_messages"]
---
<!-- markdownlint-disable MD041 -->

Call `mcp__plugin_biff-dev_tty__read_messages` with no arguments.

If the result says "No new messages.", do not emit any text.

Otherwise, emit the tool output exactly as returned — character for character, including the leading ▶ unicode character. Do not reformat, add commentary, wrap in code fences, convert to markdown tables, or add boxes around the output.
28 changes: 28 additions & 0 deletions commands/talk-dev.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
description: Start a real-time conversation with a teammate or agent
argument-hint: "@user [message]"
allowed-tools: ["ToolSearch", "mcp__plugin_biff-dev_tty__talk", "mcp__plugin_biff-dev_tty__talk_end", "mcp__plugin_biff-dev_tty__write"]
---
<!-- markdownlint-disable MD041 -->

## Input

Arguments: $ARGUMENTS

Parse as: first token is the recipient username (strip leading `@` if present), remaining tokens are the opening message (optional).

Examples:

- `@kai` → `to="kai"`
- `@kai hey, got a minute?` → `to="kai"`, `message="hey, got a minute?"`

## Task

1. Call `mcp__plugin_biff-dev_tty__talk` with the parsed values.
2. Incoming messages from the partner appear on the status bar automatically (0-2s). No need to poll or call talk_listen.
3. When the user wants to reply, send with `mcp__plugin_biff-dev_tty__write` to the same user.
4. When the user says to stop, call `mcp__plugin_biff-dev_tty__talk_end`.

If `$ARGUMENTS` is "end", call `mcp__plugin_biff-dev_tty__talk_end` directly.

Do not repeat or reformat tool output — it is already formatted by hooks.
14 changes: 14 additions & 0 deletions commands/tty-dev.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
description: Name the current session (visible in /who and /finger)
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the dev command set, this description references /who and /finger, but the corresponding dev commands are /who-dev and /finger-dev (to avoid collisions with the installed prod plugin). Consider updating the description to point at the dev command names so users of the dev plugin aren’t misled.

Suggested change
description: Name the current session (visible in /who and /finger)
description: Name the current session (visible in /who-dev and /finger-dev)

Copilot uses AI. Check for mistakes.
argument-hint: "[name]"
allowed-tools: ["ToolSearch", "mcp__plugin_biff-dev_tty__tty"]
---
<!-- markdownlint-disable MD041 -->

## Input

Arguments: $ARGUMENTS

## Task

Call `mcp__plugin_biff-dev_tty__tty`. If arguments were provided, pass them as `name`. If no arguments, call with no arguments to auto-assign the next ttyN. The result is already formatted by a PostToolUse hook and displayed above. Do not repeat or reformat the data. Do not send any text after the tool call.
29 changes: 29 additions & 0 deletions commands/wall-dev.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
description: Broadcast a message to all teammates
argument-hint: '"message" [duration] | clear'
allowed-tools: ["ToolSearch", "mcp__plugin_biff-dev_tty__wall"]
---
<!-- markdownlint-disable MD041 -->

## Input

Arguments: $ARGUMENTS

Parse as one of three modes:

1. **Clear**: if arguments are exactly `clear` → call with `clear=True`
2. **Post with duration**: if the last token matches a duration pattern (`30m`, `2h`, `1d`, `3d`), it is the duration and everything before it is the message → `message="...", duration="2h"`
3. **Post with default**: otherwise the entire argument string is the message → `message="..."`

If no arguments are provided, call with no parameters (shows current wall).

Examples:

- `release freeze — do not push to main` → `message="release freeze — do not push to main"`
- `deploy window open 2h` → `message="deploy window open"`, `duration="2h"`
- `clear` → `clear=true`
- (empty) → no parameters

## Task

Call `mcp__plugin_biff-dev_tty__wall` with the parsed values. The result is already formatted by a PostToolUse hook and displayed above. Do not repeat or reformat the data. Do not send any text after the tool call.
11 changes: 11 additions & 0 deletions commands/who-dev.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
description: List active team members and what they're working on
allowed-tools: ["ToolSearch", "mcp__plugin_biff-dev_tty__who"]
---
<!-- markdownlint-disable MD041 -->

Call `mcp__plugin_biff-dev_tty__who` with no arguments.

If the result says "No sessions.", do not emit any text.

Otherwise, emit the tool output exactly as returned — character for character, including the leading ▶ unicode character. Do not reformat, add commentary, wrap in code fences, convert to markdown tables, or add boxes around the output.
30 changes: 30 additions & 0 deletions commands/write-dev.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
description: Send a message to a teammate
argument-hint: "@user <message>"
allowed-tools: ["ToolSearch", "mcp__plugin_biff-dev_tty__write", "CronCreate", "CronList"]
---
<!-- markdownlint-disable MD041 -->

## Input

Arguments: $ARGUMENTS

Parse as: first token is the recipient username (strip leading `@` if present), remaining tokens are the message body.

Example: `@kai hey, ready for code review?` → `to="kai"`, `message="hey, ready for code review?"`

## Task

Call `mcp__plugin_biff-dev_tty__write` with `to` and `message` set to the parsed values. The result is already formatted by a PostToolUse hook and displayed above. Do not repeat or reformat the data.

## Auto-poll for response

After sending the message, ensure a polling loop exists to catch replies:

1. Call `CronList` and check if any listed job has a `prompt` field that exactly matches `/biff-dev:read-dev`.
2. If no existing `/biff-dev:read-dev` cron, call `CronCreate` with:
- `cron`: `*/5 * * * *`
- `prompt`: `/biff-dev:read-dev`
- `recurring`: true
- `durable`: true
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The auto-poll setup created after /write-dev is marked durable: true, which can leave a long-lived recurring cron firing every 5 minutes even after the immediate reply window has passed. If the intent is “temporary auto-poll to catch replies”, consider using a non-durable job (and/or an explicit short TTL) so this automatic action doesn’t persist across restarts.

Suggested change
- `durable`: true
- `durable`: false

Copilot uses AI. Check for mistakes.
3. Do not mention the cron setup or send any other text to the user.
Loading