Skip to content

feat(plugin): make a missing hub visible and fixable - #97

Merged
obeone merged 1 commit into
mainfrom
feat/plugin-hub-ensure
Sep 17, 2026
Merged

obeone merged 1 commit into
mainfrom
feat/plugin-hub-ensure

Conversation

@obeone

@obeone obeone commented Sep 17, 2026 •

Copy link
Copy Markdown
Owner

What changed

The new user path breaks quietly today. Install the plugin, get "Plugin is now active", run /caucus:join, and land on nothing: no hub running, no tools available, and nothing in the session says why. This PR closes that gap in three layers.

  1. hooks/hub-ensure.sh, a SessionStart hook that asks the hub's already installed service to start (the same way autostart.py does for the other connectors, never spawning caucus-hub directly) and waits for the port before the session proceeds. It cannot save the one session where this usually goes wrong, though: SessionStart fires at session start, or after /clear or a compaction, never on a mid-session /plugin install.

  2. The four existing commands, /caucus:join, /caucus:talk, /caucus:status, /caucus:leave, now open with one sentence of diagnosis. With zero caucus tools, they say plainly that the MCP server found no hub instead of guessing or sending the agent off to read the repo, then point at a new fifth command rather than each repeating the whole recovery recipe.

  3. /caucus:setup, the new command. It is prose driving shell commands only, so it works with no caucus tools at all, which is exactly the situation it is for. It probes the hub's /version endpoint, says plainly whether nothing is listening or the session's own client simply dialed too early, and, only with your yes, offers to install the hub and to keep it running (caucus-setup-service where launchd or systemd exists, a plain detached process where neither does, a container running tini as PID 1 for example). It ends on the step nothing else in the plugin said before: once the hub is up, the session that installed it still has no tools, so exit and relaunch Claude Code, then /caucus:join.

.claude-plugin/plugin.json's description and the README's Claude Code quickstart now say the same thing: a hub, then the plugin, then a fresh session, with /caucus:setup as the first command to run in it.

How I verified it

I tested the arrival path on a real machine before writing any of this. Hub started, /reload-plugins run twice, and the caucus tools still never showed up in that session, even though a raw MCP initialize against the hub's /mcp endpoint from the same shell listed the whole toolset. The hub was fine, the plugin's MCP entry was fine, and the session's own client had simply dialed once, failed, and never retried. Only a full exit and relaunch of Claude Code brought the tools back, which is why the four commands, /caucus:setup, and the README all say exit and relaunch rather than /reload-plugins, which reloads plugin configuration but does not reestablish a failed MCP connection.

Claude wrote the hook, the fifth command, and the wiring tests, and ran the checks: pytest (947 passed), ruff check src/ tests/, and mypy src/, all clean. tests/test_plugin_hook.py now also checks that each of the five command files exists with the frontmatter Claude Code needs to register it, a name and a description.

Risk is low: documentation and command text only. No Python source changed outside that test file, and hooks/hub-ensure.sh, hooks/hooks.json, and .claude-plugin/mcp.json are untouched from the previous version of this PR.

Checklist

  • User-visible changes are recorded under ## [Unreleased] in CHANGELOG.md.
  • N/A, no PROTOCOL_TEXT change in this PR.

@obeone
obeone force-pushed the feat/plugin-hub-ensure branch from 545cc97 to 70377d8 Compare September 17, 2026 22:29
The plugin's MCP entry dials the hub over Streamable HTTP as soon as a
session opens, and nothing retried that connection if the hub was not
already listening: a stranger installing the plugin got "Plugin is now
active" and zero caucus tools, with no explanation anywhere.

Add hooks/hub-ensure.sh, a SessionStart hook that asks the hub's
installed service to start (mirroring autostart.py, never spawning
caucus-hub directly) and waits for the port before the session
proceeds. SessionStart never fires on a mid-session plugin install
though, so it cannot rescue the very session where a new user is most
likely to hit this.

Give the four existing commands a one-sentence check for that case:
with no caucus tools at all, they point at a new fifth command,
/caucus:setup, instead of guessing or reading the repo. /caucus:setup
runs with zero caucus tools, since that is exactly the situation it
exists for: it probes the hub, offers to install and start it with the
operator's permission, and states the step nothing else in the plugin
said before, that the installing session still needs to be exited and
relaunched once the hub is up.
@obeone
obeone force-pushed the feat/plugin-hub-ensure branch from 70377d8 to b0eb3b7 Compare September 17, 2026 22:40
@obeone obeone changed the title feat(plugin): wake the hub with a SessionStart hook for /mcp feat(plugin): make a missing hub visible and fixable Sep 17, 2026
@obeone
obeone merged commit 9ace7a8 into main Sep 17, 2026
8 checks passed
@obeone
obeone deleted the feat/plugin-hub-ensure branch September 17, 2026 22:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant