Repository navigation
Tell a session once when the plugin and basecamp command are from different releases - #949
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Snapshot cleanup can delete fallback notice markers, causing repeated notices for unchanged version pairings.
1 open issue
What changed in this PR
Adds a SessionStart notice when the installed Basecamp plugin and CLI come from different releases, complementing the stable-release installation work without adding unconditional session context.
Changes:
- Compares plugin and CLI versions and provides update instructions once per version pairing.
- Adds tests for update guidance, notice suppression, and SessionStart-only behavior.
- Updates skill recovery guidance and hook documentation.
[!TIP]
If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or rungh pr ready --undo.
Click "Ready for review" or rungh pr readyto reengage.
| File | Description |
|---|---|
| skills/basecamp/SKILL.md | Adds upgrade guidance for unknown commands or flags. |
| internal/release/manifests_test.go | Updates comments and assertion messages to include version notices. |
| internal/commands/agent_hook.go | Updates the SessionStart routing comment. |
| internal/commands/agent_hook_version.go | Implements version comparison, notice markers, and update guidance. |
| internal/commands/agent_hook_version_test.go | Tests notices, suppression, and hook routing. |
| internal/commands/agent_hook_rename.go | Integrates version notices and shares agent detection. |
| hooks/hooks.json | Documents the version notice in the hook description. |
Review effort: Balanced
…ferent releases Neither Claude Code nor Codex updates a third-party plugin unless the user turns that on, and a plugin changes only when its version string does, so a plugin installed once can stay put while Homebrew moves the CLI on. Doctor reports the mismatch, but only to someone who runs it. The plugin's SessionStart hook already runs the installed binary at every session start. It now reads the version stamped in this install's manifest, compares it with the CLI's, and once per pairing says which side to update: `basecamp upgrade` when the CLI is behind, the agent's own plugin update when the plugin is. Dev, prerelease and go-install builds, versions that aren't semver, and pre-rename installs (which get the rename notice) stay silent. An old binary can't run this check, so the skill also says that an unknown command means the CLI is older than the skill: run `basecamp upgrade`.
… release; soften the skill line Review findings: - Without a plugin data directory the once-markers fell back to the commit-snapshot directory, whose cleanup removes every file older than an hour, so the version notice (and the rename notice, which shared the fallback) came back. Both now fall back to agent-hook-notices in the CLI's cache. - A prerelease CLI behind the plugin (an rc left installed past its release) was silent; it now gets `basecamp upgrade`. Only a prerelease ahead of the plugin has nothing to update to. - An unknown command doesn't show which side is older: the skill names a removed command in its own triggers. The skill now says to check help first, and to let `basecamp doctor --json`, which compares the versions, name the side to update.
Review finding: doctor's Codex version check said `basecamp setup codex` for every mismatch, but setup can't bring forward a CLI that is behind the plugin; only an upgrade can. It now says `basecamp upgrade` then, as the Claude Code check already does. The skill line no longer leans on doctor's remedy, which an older CLI still gets wrong: it has the agent read both versions from doctor and name the older side itself.
Review finding: without plugin data directories, Claude Code and Codex share the fallback notice directory, so the first agent's notice silenced the other's, whose remedy differs. The marker now names the agent.
924f40b to
1e8b29f
Compare
Review summary: declined findingsAn independent review by Pi
About the loop. Findings across the four rounds were 3, 1, 2 and 2. The later ones were all remedy-text corner cases for particular install shapes: scope, alias, prerelease, which agent. I stopped there instead of chasing the next one. If one of these matters more than I've judged, say so and I'll pick it up.
|
Tested in real Claude Code and Codex sessionsI built Claude Code 2.1.308. Real install:
Codex CLI 0.163.0. Throwaway
Not exercised: whether following each remedy actually clears the mismatch, i.e. |

Why
Pinning the marketplace to
stable(basecamp/plugins#13, with #925) keeps fresh installs on a release. It doesn't reach someone whose plugin or binary is already old:marketplace.jsonhas no field to turn it on (docs). An installed plugin changes only when its version string does (docs). So a plugin installed once can sit still while Homebrew moves the CLI on.basecamp≥ X".basecamp doctorreports a mismatch, but only to someone who runs it.Other vendors handle this with a check on the user's machine and a hint in the skill. Vercel's plugin compares
vercel --versionat SessionStart (source). Railway's skill says an unrecognized command means the CLI may be out of date (source). The research behind this, and the landing order forstable, is in this comment on basecamp/plugins#13.What
SessionStart version notice. The plugin's existing SessionStart hook,
basecamp agent-hook pre-commit-snapshot, already runs the installed binary. It now:.claude-plugin/plugin.jsonor.codex-plugin/plugin.json, and compares it with the CLI's;basecamp upgrade.claude plugin update basecamp-cli@37signals, then restart, plus the auto-update hintbasecamp setupalready prints.basecamp setup codex, the same remedy doctor gives.Updating either side creates a new pairing, so the notice speaks again only when there's something new to say.
It stays silent for:
go installpseudo-versions ahead of the plugin, which have no newer plugin to update to (an rc left installed past its release is behind the plugin, and getsbasecamp upgrade);basecamp setupalso updates them.This keeps the rule from #675 that the plugin doesn't inject context into every session; the manifest test's comment now names this as the third allowed case.
Skill line. An old binary can't run that check, so
skills/basecamp/SKILL.mdnow says, under Errors and recovery: if the CLI rejects a command or flag as unknown, check the group's help first; if the skill names it and the help lacks it, the CLI and skill may be from different releases, andbasecamp doctor --jsoncompares the versions and names the side to update. An unknown command alone doesn't show which side is older, since the skill still names the removedbasecamp campfireamong its triggers.Notice markers. Without a plugin data directory, the once-markers (this notice's, and the existing rename notice's) used to fall back to the commit-snapshot directory, whose cleanup removes every file older than an hour, so the notice came back. Both now fall back to
agent-hook-noticesin the CLI's cache, and the version marker names the agent, so Claude Code and Codex sharing that fallback each get their own notice.Doctor's Codex hint. The Codex plugin version check said
basecamp setup codexfor every mismatch. When the CLI is the side behind, it now saysbasecamp upgrade, as the Claude Code check already did.Not doing
A
commandplugin source (reference), where the binary prints its own plugin directory, would keep the two in step by construction. It's left out because:Worth revisiting if this notice isn't enough.
Tests
internal/commands/agent_hook_version_test.gocovers:v-spelled, dev, prerelease ahead, pseudo-version, non-semver, no version);basecamp upgrade;emitSessionStartNoticesfails the tests that expect a notice. Dropping the prerelease guard fails the prerelease-ahead and pseudo-version cases; making it unconditional fails the rc-behind case; pointing the fallback back at the snapshot directory fails the cleanup case.bin/cipasses on1e8b29f7(exit 0, no failures), in the main checkout.gpt-6.1-sol(thinking high), four rounds. Findings fixed: notice markers lost to the snapshot cleanup, an rc behind its release staying silent, the skill line over-claiming what an unknown command means, doctor's Codex hint naming setup when the CLI is behind, and Claude Code and Codex sharing one fallback marker. Three findings declined; see the summary comment.