feat(plugin): make a missing hub visible and fixable - #97
Merged
Merged
Conversation
obeone
force-pushed
the
feat/plugin-hub-ensure
branch
from
September 17, 2026 22:29
545cc97 to
70377d8
Compare
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
force-pushed
the
feat/plugin-hub-ensure
branch
from
September 17, 2026 22:40
70377d8 to
b0eb3b7
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.hooks/hub-ensure.sh, aSessionStarthook that asks the hub's already installed service to start (the same wayautostart.pydoes for the other connectors, never spawningcaucus-hubdirectly) and waits for the port before the session proceeds. It cannot save the one session where this usually goes wrong, though:SessionStartfires at session start, or after/clearor a compaction, never on a mid-session/plugin install.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./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/versionendpoint, 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-servicewherelaunchdorsystemdexists, a plain detached process where neither does, a container runningtinias 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:setupas 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-pluginsrun twice, and the caucus tools still never showed up in that session, even though a raw MCPinitializeagainst the hub's/mcpendpoint 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/, andmypy src/, all clean.tests/test_plugin_hook.pynow 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.jsonare untouched from the previous version of this PR.Checklist
## [Unreleased]inCHANGELOG.md.PROTOCOL_TEXTchange in this PR.