Files
fleetd/plugin/README.md
Dai Ha 457458437f
CI / contract (pull_request) Successful in 1m12s
CI / build (pull_request) Successful in 1m31s
#362: make the plugin visible, and fix the drift that made it unusable
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
2026-09-05 12:42:20 +07:00

3.2 KiB

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

/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:

export FLEETD_MCP_URL=http://127.0.0.1:8765/mcp

Then, in the project you want to onboard:

/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

claude --plugin-dir ./plugin
claude plugin validate ./plugin

/reload-plugins picks up edits without restarting the session.