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
31 changes: 31 additions & 0 deletions .changeset/th-claude-driver.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
"@smooai/smooth": patch
---

th claude: tmux-driven Claude Code session supervisor with a shared rate-limit governor

Adds `th claude run / ls / attach` plus a new dependency-light `smooth-tmux`
crate. `th claude run` launches Claude Code inside an isolated tmux session and
supervises it: when the account-wide "temporarily limiting requests" throttle
fires, it backs off with full jitter (via a pool-aware `RateLimitGovernor`) and
resends the last message until it lands — auto-detecting the last user message
from the pane when it didn't send it itself. `th claude attach <id>` hands your
terminal to the session; `th claude ls` lists live sessions and prunes dead
ones.

`th claude mode <id> driving|manual|paused` hands control back and forth between
Big Smooth and a human sharing the same tmux pane: `driving` = the supervisor
sends input and rescues throttles, `manual` = the human drives and the supervisor
only rescues their throttled turns, `paused` = the supervisor stands down. Worker
sessions are launched with `SMOOTH_AGENT_HANDLE` exported so they can register on
the th-mail bus.

This is the 1:1 vertical slice of a broader topology (1→N Big-Smooth-led farm,
N→1 per-session supervisors, and mixed), all built on the same
supervisor + governor + registry primitives. The governor is shared so a 429 on
any session backs off the whole pool rather than thundering the herd.

Also adds the **`smooth` Claude Code plugin marketplace** (`.claude-plugin/
marketplace.json`) with the **`smooth-agent`** plugin — a `/smooth` orchestrator
command plus `agent-comms` / `pearls-flow` worker skills and a SessionStart hook
that registers a worker on th-mail. The recipe layer over the `th claude` engine.
25 changes: 25 additions & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
"name": "smooth",
"owner": {
"name": "SmooAI",
"email": "brent@smoo.ai"
},
"metadata": {
"description": "SmooAI team Claude Code plugins — Big Smooth orchestration (th claude), agent comms (th-mail), and pearls work tracking.",
"pluginRoot": "./claude-plugins"
},
"plugins": [
{
"name": "smooth-agent",
"source": "smooth-agent",
"description": "Run a Big Smooth that drives Claude Code worker sessions over tmux (rate-limit-resilient), coordinate agents over th-mail, and track work in pearls. Provides the /smooth command.",
"version": "0.1.0",
"category": "orchestration",
"keywords": ["orchestration", "tmux", "multi-agent", "th-mail", "pearls", "rate-limit"],
"author": {
"name": "SmooAI"
}
}
]
}
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ smooth-bootstrap-bill = { version = "0.15.7", path = "crates/smooth-bootstrap-bi
smooth-tunnel = { version = "0.15.7", path = "crates/smooth-tunnel", package = "smooai-smooth-tunnel" }
smooth-host-stub = { version = "0.15.7", path = "crates/smooth-host-stub", package = "smooai-smooth-host-stub" }
smooth-bench = { version = "0.15.7", path = "crates/smooth-bench", package = "smooai-smooth-bench" }
smooth-tmux = { version = "0.15.7", path = "crates/smooth-tmux", package = "smooai-smooth-tmux" }
smooth-api-client = { version = "0.15.7", path = "crates/smooth-api-client", package = "smooai-smooth-api-client" }
# Cross-runtime client shared library (github.com/SmooAI/client-shared).
# SMOODEV-1464: switched from a local `path = "../client-shared/rust"` dep to
Expand Down
14 changes: 14 additions & 0 deletions claude-plugins/smooth-agent/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"$schema": "https://anthropic.com/claude-code/plugin.schema.json",
"name": "smooth-agent",
"version": "0.1.0",
"description": "Big Smooth orchestration for Claude Code: tmux-supervised worker sessions that survive the account-wide rate-limit throttle, coordinate over th-mail, and track work in pearls. Provides the /smooth command.",
"author": {
"name": "SmooAI",
"email": "brent@smoo.ai"
},
"homepage": "https://github.com/SmooAI/smooth",
"repository": "https://github.com/SmooAI/smooth",
"license": "MIT",
"keywords": ["orchestration", "tmux", "multi-agent", "th-mail", "pearls", "rate-limit"]
}
53 changes: 53 additions & 0 deletions claude-plugins/smooth-agent/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# smooth-agent

A Claude Code plugin for **Big Smooth orchestration** — drive Claude Code worker
sessions that survive the account-wide rate-limit throttle, coordinate them over
**th-mail**, and track work as **pearls**. Part of the `smooth` marketplace
(`SmooAI/smooth`).

## What it gives you

- **`/smooth`** command — the orchestrator surface. `run`, `add-agent`, `drive`/
`manual`, `mail`, `status`, `ls`, `attach`. Drives the `th claude` engine.
- **`agent-comms`** skill — teaches a worker session to report status, answer
pings, and hand off work over `th msg`/`th agent`.
- **`pearls-flow`** skill — teaches a worker to track work as pearls
(`th pearls`).
- **SessionStart hook** — when a session is launched by `th claude run` (which
exports `SMOOTH_AGENT_HANDLE`), auto-registers it on the th-mail bus so Big
Smooth can address it by id.

## Requires

The `th` CLI (built from `SmooAI/smooth`) with the `th claude` engine, plus
`tmux` on `PATH`. The plugin is a thin recipe layer; the supervision, rate-limit
governor, and session control live in `th claude` (the binary).

## Install

```
/plugin marketplace add SmooAI/smooth # or: /plugin marketplace add ./ from a local checkout
/plugin install smooth-agent@smooth
```

Then `th claude run "<task>"` launches a supervised, plugin-active worker, and
`/smooth status` shows the farm.

## How control works

Each worker runs in a tmux session shared between Big Smooth and you. A per-session
**mode** arbitrates who types:

- `driving` — Big Smooth sends input + rescues rate-limits.
- `manual` — you drive (`th claude attach <id>`); the supervisor only rescues
your throttled turns.
- `paused` — the supervisor stands down.

Flip with `/smooth drive <id>` / `/smooth manual <id>` or `th claude mode <id> <mode>`.

## Note on scale (subscription ToS)

This drives Claude Code **subscription** auth. Backoff-and-resume that honors the
limit is fine; a large unattended fleet to maximize a flat-rate plan is the gray
zone — keep the worker count tasteful. True fleet scale belongs on the metered
API + smooth-operator.
64 changes: 64 additions & 0 deletions claude-plugins/smooth-agent/commands/smooth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
description: Big Smooth — orchestrate Claude Code worker sessions via the `th claude` engine (run, add-agent, drive/manual, mail, status)
argument-hint: "[status|run <task>|add-agent <task>|drive <id>|manual <id>|mail <to> <body>|ls|attach <id>] …"
allowed-tools: Bash(th claude:*), Bash(th msg:*), Bash(th agent:*), Bash(th pearls:*)
---

You are **Big Smooth**, the lead orchestrator. You coordinate Claude Code
**worker** sessions through the `th claude` engine — each worker runs in an
isolated tmux session that survives the account-wide rate-limit throttle
("temporarily limiting requests") by backing off with jitter and resending the
last message. You talk to workers two ways: by **driving their pane** (the engine
sends input while a session is in `driving` mode) and over **th-mail**
(`th msg`/`th agent`) for replies, status, and worker↔worker coordination. Track
all work as **pearls**.

Current farm (live now):
!`th claude ls 2>/dev/null || echo "(no sessions; th claude not installed?)"`

Mail waiting:
!`th msg inbox --pull --agent big-smooth 2>/dev/null | head -40 || echo "(none)"`

## Interpret the request

Mode = first word of `$ARGUMENTS`; the rest are its args. Dispatch:

- **(empty) / `status`** — Summarize the farm above (ids, modes, labels) and any
waiting mail. Note which workers are `driving` vs `manual` vs `paused`.

- **`run <task>`** — Launch a supervised worker on `<task>`:
`th claude run "<task>" --label <short-role>` in the relevant working dir
(ask, or default to cwd). Tell the user the session id and that it will
self-heal rate-limits. Open a pearl for the task first
(`th pearls create --title=… --type=task`).

- **`add-agent <task>`** — Drop another worker into the pack: another
`th claude run "<task>" --label <role>`. Several supervised workers run in
parallel. Keep the count **tasteful** (subscription ToS — a big unattended
fleet is the gray zone; that scale belongs on the metered API).

- **`drive <id>` / `manual <id>` / `pause <id>`** — Hand control:
`th claude mode <id> driving|manual|paused`. `driving` = Big Smooth sends input
and rescues throttles; `manual` = the human drives (attach with
`th claude attach <id>`) and the supervisor only rescues their throttled turn;
`paused` = supervisor stands down.

- **`mail <to> <body>`** — Steer a worker / broadcast over th-mail:
`th msg send --to <to|all> --from big-smooth --body "<body>"`. Read replies with
`th msg inbox --pull --agent big-smooth`; thread with `th msg thread <id>`.

- **`ls`** — `th claude ls`. **`attach <id>`** — tell the user to run
`th claude attach <id>` themselves (attaching replaces the current process, so
you can't do it for them); `Ctrl-b d` detaches.

## Operating rules

- Prefer `th` over raw curl. Every tracked unit of work gets a pearl; close it
when the worker finishes.
- Workers launched via `th claude run` come up with `SMOOTH_AGENT_HANDLE=<id>` set,
so the `smooth-agent` SessionStart hook auto-registers them on th-mail under
that id — address a worker as `th msg send --to <id>`.
- Don't drive and let the human type at the same time: flip a session to `manual`
before handing it over, back to `driving` to resume.
- If a worker hits a **real usage/quota limit** (not the transient throttle),
backing off won't help — surface it and move on.
15 changes: 15 additions & 0 deletions claude-plugins/smooth-agent/hooks/hooks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"hooks": {
"SessionStart": [
{
"matcher": "startup|resume",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/register-agent.sh"
}
]
}
]
}
}
20 changes: 20 additions & 0 deletions claude-plugins/smooth-agent/hooks/register-agent.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env bash
# smooth-agent SessionStart hook.
#
# Registers this Claude Code session on the th-mail bus so Big Smooth can
# reach it. No-op unless the session was launched by `th claude run`, which
# exports SMOOTH_AGENT_HANDLE=<session-id>. stdout from a SessionStart hook
# is injected into the session as context.
set -euo pipefail

handle="${SMOOTH_AGENT_HANDLE:-}"

# Not a Big Smooth worker (a plain `claude` launch) → nothing to do.
[ -z "$handle" ] && exit 0
command -v th >/dev/null 2>&1 || exit 0

# Idempotent registration; swallow errors so a hiccup never blocks startup.
th agent register --name "$handle" --harness claude-code >/dev/null 2>&1 || true

echo "th-mail: online as agent '$handle'. Report status to Big Smooth and answer pings with the agent-comms skill; check 'th msg inbox --agent $handle'. Track work as pearls (pearls-flow skill)."
exit 0
59 changes: 59 additions & 0 deletions claude-plugins/smooth-agent/skills/agent-comms/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
name: agent-comms
description: Coordinate with Big Smooth and other agents over th-mail (the th msg / th agent bus) — report status, answer pings, and hand off work. Use when this session is a Big Smooth worker (launched via `th claude run`, with SMOOTH_AGENT_HANDLE set) or whenever you need to reach another agent. Invoke for "message the orchestrator", "tell big smooth", "reply to the agent", "who else is working".
---

# agent-comms — talk to Big Smooth and other agents over th-mail

`th` ships a harness-agnostic agent mailbox: `th agent` (registry) + `th msg`
(mail), backed by the pearl Dolt store and synced over `refs/dolt/data`. When
this session was launched by `th claude run`, the `smooth-agent` SessionStart
hook already **registered** it under the handle in `$SMOOTH_AGENT_HANDLE` (your
session id), so Big Smooth can reach you. Your job is to **send** status and
**answer** pings — not to sit in a foreground poll.

Your handle: `$SMOOTH_AGENT_HANDLE` (fall back to a name you pick if unset).
**Pass `--agent`/`--from <handle>` on every command** — shell env doesn't persist
between Bash calls in this harness, and the default handle is `user@host`, not
yours.

## Report status / hand off to the orchestrator

```bash
th msg send --to big-smooth --from "$SMOOTH_AGENT_HANDLE" --body "done: <what>; pearl <id> closed"
th msg send --to big-smooth --from "$SMOOTH_AGENT_HANDLE" --body "blocked: <why>; need <decision>"
```

Broadcast to everyone with `--to all`. Reply within a thread with `--re <id>`.

## Check for and answer pings

```bash
th msg inbox --agent "$SMOOTH_AGENT_HANDLE" # local read (no lock contention)
th msg thread <id> # full conversation if needed
th msg reply <msg-id> --from "$SMOOTH_AGENT_HANDLE" --body "…"
th msg inbox --unread --mark-read --agent "$SMOOTH_AGENT_HANDLE" # mark consumed
```

Check the inbox at natural breakpoints (finishing a step, before going idle).
Answer anything you can from context — a status request, an ack, a coordination
ping. Surface decisions that aren't yours to make to the user instead of
committing on their behalf.

## See who's around

```bash
th agent list # registered agents, most-recent first
```

## Footguns

- **`--pull` writes to the shared Dolt store** and contends on its lock —
polling with `--pull` every few seconds once wedged *every* agent's mailbox
(`Error 1105: database is read only`). For same-machine agents the store is
local, so plain `th msg inbox` already sees new mail with **no** pull. Only
`--pull` occasionally, for genuinely cross-machine setups.
- **`th msg` (agent mail) ≠ `th inbox`** (operative review gates). Different
thing.
- One identity: always the same `--agent <handle>`, or you'll watch the wrong
mailbox.
39 changes: 39 additions & 0 deletions claude-plugins/smooth-agent/skills/pearls-flow/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
name: pearls-flow
description: Track work as pearls (th pearls) — the dependency-graph work tracker shared across smooth/smooai. Create a pearl before starting work, claim it, close it when pushed. Use whenever you start a unit of work, are asked what to work on, or finish a task. Invoke for "track this", "what's ready", "file a pearl", "close it out".
---

# pearls-flow — track work as pearls

`th pearls` is the work tracker (Dolt-backed, dependency-aware) used across the
SmooAI repos. As a Big Smooth worker, wrap each unit of work in a pearl so the
orchestrator and teammates can see what's in flight and what's done.

## The loop

```bash
th pearls ready # what's ready (open, no blockers)
th pearls show <id> # details + dependencies + history
th pearls update <id> --status=in_progress # claim it before you start
# … do the work …
th pearls close <id> # when the work is committed/pushed
```

## Create work

```bash
th pearls create --title="<summary>" --description="<why + what>" --type=task|bug|feature --priority=2
```

Priority is **0–4** (0 = critical, 2 = medium, 4 = backlog) — not "high"/"low".
Add dependencies with `th pearls dep add <issue> <depends-on>`.

## Rules

- **Create the pearl before writing code**; mark `in_progress` when you start;
close when pushed. Work isn't done until it's committed and pushed.
- Don't use ad-hoc TODO lists for multi-step work — pearls are the tracker.
- When you finish, report to the orchestrator over th-mail (see the
`agent-comms` skill): `th msg send --to big-smooth --from "$SMOOTH_AGENT_HANDLE"
--body "closed pearl <id>: <what>"`.
- Avoid interactive editor flows (`th pearls edit`) — they block on `$EDITOR`.
1 change: 1 addition & 0 deletions crates/smooth-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ admin = []

[dependencies]
smooth-bench.workspace = true
smooth-tmux.workspace = true
smooth-bigsmooth.workspace = true
smooth-bootstrap-bill = { workspace = true, default-features = false, features = ["server"] }
smooth-code.workspace = true
Expand Down
Loading
Loading