Skip to content

feat(v3): pin plugin to CLI v3.0+ · SessionStart enforcement hook#183

Merged
kengio merged 2 commits into
mainfrom
feat/plugin-v3-pin
May 22, 2026
Merged

feat(v3): pin plugin to CLI v3.0+ · SessionStart enforcement hook#183
kengio merged 2 commits into
mainfrom
feat/plugin-v3-pin

Conversation

@kengio
Copy link
Copy Markdown
Collaborator

@kengio kengio commented May 22, 2026

Summary

Pairs with the OneBrain CLI v3.0.0 GA released earlier today (2026-05-22):

  1. plugin.json: bump 2.4.143.0.0 (major break) + re-add requires.cli: ">=3.0.0". Restores the pin from PR feat: pin plugin to CLI v3.0 (Rust) #180, which was reverted in PR chore: revert PR #180 (pin plugin to CLI v3.0) — redo after CLI GA #181 pending CLI GA.
  2. hooks/hooks.json + hooks/check-cli-version.sh: new SessionStart hook that blocks any Claude Code session running this plugin alongside an onebrain CLI older than v3.0.0 (or absent entirely). The plugin's requires.cli field is metadata for tooling; this hook is the runtime enforcement.
  3. PLUGIN-CHANGELOG.md: v3.0.0 entry (max 8 bullets per repo style).

What's NOT in this PR

Bundled into the Saturday 2026-05-23 plugin trim PR per single-responsibility:

  • plugin repo README rewrite
  • trim to plugin-only (move CLI legacy CHANGELOG.md out)
  • rename PLUGIN-CHANGELOG.mdCHANGELOG.md

SessionStart hook design

v=$(onebrain --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')   # strips -alpha.X
LOWEST=$(printf '%s\n3.0.0\n' "$v" | sort -V | head -1)
if [ "$LOWEST" != "3.0.0" ]; then emit decision:block JSON ; fi

Practical effect:

  • v3.0.0 (Rust GA) → silent pass
  • v3.0.0-alpha.x (dogfooders) → silent pass (already on Rust)
  • v2.x Bun-era → decision: block with platform-specific update paths
  • onebrain not on PATH → decision: block with install paths

The block reason copy points at the Homebrew tap (onebrain-ai/homebrew-onebrain, shipped earlier today), GitHub Releases, and the onebrain update self-installer.

Local tests

Scenario Result
onebrain 3.0.0-alpha.9 on PATH (current local) silent pass, exit 0, no JSON
onebrain not on PATH (env -i) decision:block with install paths, exit 0
Mock onebrain 2.3.3 shim on PATH decision:block with update paths, exit 0

Hook script also handles the edge case where onebrain --version exists but the output can't be parsed (emits a "could not parse" block).

Test plan

  • Local smoke tests (3 scenarios above)
  • 3-round parallel review (correctness · behavior · security)
  • Post-merge: dogfood by running onebrain vault-sync in this vault to apply the new plugin, then restart Claude Code session and confirm the hook is registered (no block since current CLI is alpha.9 → passes)

kengio added 2 commits May 22, 2026 15:07
- plugin.json: bump 2.4.14 → 3.0.0 (major break) + add requires.cli ">=3.0.0".
  Restores the pin from PR #180 (reverted in #181 pending CLI GA); CLI v3.0.0
  shipped today (2026-05-22).
- hooks/hooks.json + hooks/check-cli-version.sh: SessionStart hook that
  blocks the session when `onebrain --version` is < v3.0.0 or absent.
  Emits decision:block JSON with platform-specific install/update paths
  (brew tap on macOS, GitHub Releases for Linux/Windows, `onebrain update`
  for in-place refresh).
- Version comparison strategy: grep MAJOR.MINOR.PATCH (drops prerelease
  suffixes) then sort -V. Practical effect: v3.0.0-alpha.x users pass
  (they're on the Rust binary already), only v2.x Bun-era is blocked.
- PLUGIN-CHANGELOG: v3.0.0 entry (max 8 bullets per repo style).

NOT in this PR (bundled into the Saturday plugin trim PR): plugin README
rewrite · repo trim to plugin-only · PLUGIN-CHANGELOG.md → CHANGELOG.md
rename. Scoped strictly to the pin + runtime enforcement.

Tested locally:
- alpha.9 (current local CLI) → silent pass, exit 0, no JSON
- missing onebrain on PATH → decision:block with install paths
- mock v2.3.3 CLI → decision:block with update paths
Round-1 review consensus (Reviewer A+B) flagged `sort -V` as a GNU coreutils
extension that may be absent from older macOS BSD `sort` builds — on those
hosts the comparison falls through (LOWEST="") and the hook would block
EVERY session on macOS regardless of installed CLI version.

Live test on macOS Darwin 25.4 showed `sort -V` works there, but the fix
is cheap defensive coding: replace `sort -V` with a pure-bash MAJOR.MINOR.
PATCH integer compare. Works on every POSIX shell, no dependency on GNU
extensions.

Also Reviewer C (MED):
- hooks/hooks.json: add `timeout: 10` so a slow `onebrain --version` (e.g.
  network-mounted binary) can't hang Claude Code session startup
  indefinitely. Matches the `hookify` marketplace pattern.
- PLUGIN-CHANGELOG: softened "blocks any session" claim — script can only
  emit decision:block JSON; actual session refusal depends on Claude Code
  honoring the payload. The CHANGELOG now reflects that contract.
- PLUGIN-CHANGELOG: removed the specific "Saturday 2026-05-23" date from
  the follow-up commitment — references the work generically since
  calendar promises rot if the PR slips.

Tested locally with 4 scenarios:
- alpha.9 (current) → silent pass
- missing CLI → decision:block with install paths
- mock v2.3.3 → decision:block with update paths
- mock v10.0.0 → silent pass (integer compare handles 10 > 3 correctly)
@kengio kengio merged commit 45dc616 into main May 22, 2026
1 check passed
@kengio kengio deleted the feat/plugin-v3-pin branch May 22, 2026 08:16
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