457458437f
CB-527 shipped a Claude Code plugin and a marketplace in this repo. Nothing in
CLAUDE.md or docs/ ever named it, so a later session planned the same feature
from scratch. The wiki Features entry existed and was correct, but wiki/ is a
submodule whose pointer is never advanced, so no session reads it.
Visibility:
- CLAUDE.md addendum now names plugin/ and both structural limits, so every
session sees it. This is the change that stops the rebuild happening again.
- wiki/11-Features.md records the rename and why the entry alone was not enough.
Drift (each measured against the code, not assumed):
- mount name fleetd -> fleet, matching PeerLauncher.MCP_MOUNT_NAME. The old name
gave a lead with both a project .mcp.json and the plugin two mounts of one
daemon and a duplicated fleet_* tool set.
- url is now ${FLEETD_MCP_URL} instead of a hardcoded address, so one plugin can
serve hosts running the daemon on different ports. Plain ${VAR}, the form
kb-alms proves works here; ${VAR:-default} is untested and not used.
- plugin claude-bridge -> fleet, marketplace claude-bridge -> fleetd, version
0.2.0. Breaking for a 0.1.0 install: mcp__fleetd__* becomes mcp__fleet__*.
- README install path ltms/claude-bridge -> the fleet/fleetd remote.
- the setup skill's §5 told operators to pin primary.terminal:. CB-579 replaced
that with fleet.leaders.*.tab. Replaced, with the duplicate-tab warning (#359).
Scope: the plugin is lead-side only, and cannot be otherwise. The launcher adds
--agent only when <worktree>/.claude/agents/<role>.md exists in the member's own
tree (ClaudeCodeLauncher.java:371,391), and a member's CLAUDE_CONFIG_DIR points
at its profile's config dir (ClaudeCodeLauncher.java:285), so a member never
reads the operator's plugin store. On this Mac all four Claude profiles set
configDir, and the four ccs instances hold four separate copies of the plugin
store -- same md5, different inodes. Seeding member skills through the worktree
is #362 scope item 3, implemented separately.
Note for anyone verifying a plugin: `claude plugin validate` does NOT read
.mcp.json. Replacing it with `{ this is not json at all` still passes, exit 0.
Refs #362, #359
81 lines
3.2 KiB
Markdown
81 lines
3.2 KiB
Markdown
# fleet (Claude Code plugin)
|
|
|
|
Makes a project **fleet-ready**: mounts the `fleetd` MCP gateway and applies standard Claude Code
|
|
settings, so the session can orchestrate a fleet of delegated workers.
|
|
|
|
**This plugin ships no credentials.** Every secret is referenced by environment-variable *name*;
|
|
the values stay with the user. Nothing the plugin writes is unsafe to commit.
|
|
|
|
## Scope — lead-side only
|
|
|
|
This plugin configures **the session you are sitting in**: a lead, or any human-started Claude Code
|
|
session that wants to talk to the daemon. It deliberately does **not** carry the worker playbook
|
|
skills or the role agent definitions, and it cannot:
|
|
|
|
- the launcher adds `--agent` only when `<worktree>/.claude/agents/<role>.md` exists in the
|
|
member's own tree (`ClaudeCodeLauncher.java:371,391`), so agent files must live in the repo;
|
|
- a member's `CLAUDE_CONFIG_DIR` points at its profile's config directory
|
|
(`ClaudeCodeLauncher.java:285`), so it never reads the operator's plugin store.
|
|
|
|
Member-facing assets travel in the worktree, not in this plugin. See fleetd #362.
|
|
|
|
## What it is not
|
|
|
|
The plugin is the **client-side setup**, not the bridge. `fleetd` is a separate daemon and `herdr`
|
|
is a separate PTY multiplexer, each with its own lifecycle and install. The plugin mounts an
|
|
already-running daemon and tells you what is missing when one isn't there — it deliberately does
|
|
not try to install system services on your behalf.
|
|
|
|
## Install
|
|
|
|
```shell
|
|
/plugin marketplace add https://git.ltms.dev/fleet/fleetd
|
|
/plugin install fleet@fleetd
|
|
```
|
|
|
|
Export the gateway URL — the plugin mounts `${FLEETD_MCP_URL}`, not a hardcoded address, so one
|
|
plugin serves hosts that run the daemon on different ports:
|
|
|
|
```shell
|
|
export FLEETD_MCP_URL=http://127.0.0.1:8765/mcp
|
|
```
|
|
|
|
Then, in the project you want to onboard:
|
|
|
|
```shell
|
|
/fleet:setup
|
|
```
|
|
|
|
## What you get
|
|
|
|
| Component | Effect |
|
|
|---|---|
|
|
| `.mcp.json` | mounts `fleet` at `${FLEETD_MCP_URL}` for any session with the plugin enabled |
|
|
| `skills/setup` | `/fleet:setup` — preflight, project settings, credential guidance, and verification |
|
|
|
|
The server is named **`fleet`** on purpose: that is `PeerLauncher.MCP_MOUNT_NAME` in the daemon and
|
|
the name a spawned member's own mount carries. Version 0.1.0 named it `fleetd`, which produced two
|
|
mounts of one daemon for anyone who also had a project-level `.mcp.json`. Upgrading from 0.1.0 is a
|
|
**breaking change** — a project that pre-allowed `mcp__fleetd__fleet_whoami` in
|
|
`.claude/settings.json` must be updated to `mcp__fleet__*`.
|
|
|
|
Because the plugin carries its own `.mcp.json`, an installed plugin needs no project-level MCP
|
|
file at all. The setup skill writes one only when you want the mount to work *without* the plugin —
|
|
for teammates who haven't installed it, or for CI.
|
|
|
|
## Verifying a setup
|
|
|
|
The setup skill ends by requiring a **real spawn**, not a health check. `/healthz` only reports
|
|
that the daemon can reach herdr; a protocol mismatch between the daemon's adapter and the herdr
|
|
binary leaves health green while every spawn fails. Only a spawn that reaches `ready` proves the
|
|
fleet.
|
|
|
|
## Local development
|
|
|
|
```shell
|
|
claude --plugin-dir ./plugin
|
|
claude plugin validate ./plugin
|
|
```
|
|
|
|
`/reload-plugins` picks up edits without restarting the session.
|