Repository navigation
borgmcp 6.0.2
borgmcp 6.0.2
This release fixes the order of borg representative hermes-plugin install and closes gaps in the Claude wake path. 6.0.1 was prepared but never published, so 6.0.2 is the first release after 6.0.0 and carries both changes. Merged since 6.0.0: #601, #602 (the unpublished 6.0.1 preparation), #603 and #605 (CI only: a manual workflow trigger and a public-source scan in PR CI; no installed behaviour changes).
Fixed: hermes-plugin install asks only after everything that can refuse has been checked
On 6.0.0, with two gateway DMs and three prepared worktrees, install asked the operator to pick a DM and confirm it [y/N]. Only after that did it refuse because several worktrees were prepared, and it printed a bare path list with no command to retry.
- Install now runs as plan, validate, ask, apply.
- Plan: it lists every candidate worktree and conversation, and builds the exact values it would write.
- Validate: it checks every candidate's plan with the same checks the writes apply, before any question. These are the value encoding (for example, a path containing a newline), the gateway DM key and the absolute
borgpath. The same pass also checks, read only, whetherplugins,config.yaml, the backup directories and Borg's state path are usable. - Ask: only then does it ask, at a terminal.
- Apply: it writes. After a question, install can stop only on an invalid or declined answer, a Hermes command's reply, or a write that fails.
- When a selection is needed, install asks at a terminal: for the worktree when several selectable worktrees are prepared, then for the DM, then for the
[y/N]confirmation (default no). A--worktree, or a configured worktree that is still prepared, and a--session-key, or a configured valid DM key, are reused without a question, including without a terminal and onborg update. - Candidates that would fail are not offered. They are shown as not selectable, with the reason. A single selectable worktree is used without a question.
- Without a terminal (including
borg update), a selection that is still needed is refused with exact retry commands. Ambiguous worktrees get oneborg representative hermes-plugin installcommand per selectable worktree, keeping--hermes-homeand a given--session-key. An unconfirmed DM gets one command per candidate with--session-key, keeping--hermes-homeand a given--worktree. Every value in these commands is shell-quoted. - Control, C1 and bidi characters are removed from: displayed worktree and
borgpaths, the planned configuration values, and failure and rollback text (which can quote Hermes config values or replies). Other displayed paths, such as the Hermes home and the backup path, are printed as they are.- Retry commands are printed separately, with their exact bytes, so they round-trip even when a path contains a newline or other control characters.
Fixed: the Claude wake path
- One wake-path text for every Claude surface. The SessionStart hook,
/clear, theborg launchprompt, theborg_regenwake-path warning and theborg_stream-statusself-arm section now render the same wake-path and recovery instructions from one source. - Re-arm before draining. A new Monitor starts at the end of the inbox, so after its exit notification, or when none is armed, a drone now re-arms the Monitor first and then drains
borg_read-log unread_only=true. - A
/loopfallback when the Monitor cannot be armed.- If a permission prompt blocks the Monitor call, or it times out, gets no classifier verdict or errors: the drone does not stop or wait. It invokes
/loopwith no arguments, and on each tick re-arms the Monitor, then drains. With a Monitor armed, the loop is only a fallback. - If a human denies the Monitor call: the drone never requests it again. It invokes
/loopwith no arguments, each tick only drains, and it tells the cube's coordinating role once, throughborg_log, that the Monitor was denied and the seat is polling.
- If a permission prompt blocks the Monitor call, or it times out, gets no classifier verdict or errors: the drone does not stop or wait. It invokes
borg-inbox-monitorreplays entries written while no Monitor was armed. This applies to the supported--state-rootform; the legacy positional form is unchanged.- The monitor keeps a replay cursor,
<state root>/<hash>.monitor.cursor, mode0600. It holds a hash of the last handled entry line, that line's timestamp and an arm boundary, and no message text. - At arm it announces the entries written after the previous monitor for the same inbox stopped. At most the newest 20 are shown; when more are waiting, one notice line says how many were not shown and to drain
borg_read-log unread_only=true. - Delivery is at least once, not exactly once: after a crash or kill, an entry can be announced again at the next arm.
- A state root with no cursor, including the first arm after upgrading, skips history as before.
- A cursor that is unusable is ignored with a warning. A cursor that cannot be written is reported once and never stops delivery.
- Orphan inbox cleanup removes the cursor with the monitor's other state files.
- The monitor keeps a replay cursor,
- The SessionStart and
/clearorientation stays within its preview. The harness shows about 2 KB of hook output. The orientation now puts every fixed instruction first. The cube, drone and role follow, fitted to the remaining bytes. The Monitor command comes last. When the whole text would reach 2048 bytes, the command is replaced by a pointer toborg_stream-status. The orientation's title is now# Borg drone orientation, and the cube, drone and role lines come after the instructions. borg_stream-statusalways shows a Claude seat its exact Monitor command, asinbox Monitor command.- Codex and OpenCode wake-path instructions are unchanged.
- The two stream-owner tests that failed when
TMPDIRis not a canonical path (as on macOS) now use a canonical test root. This only affects development.
Upgrading
- Run
borg update. - Restart each Claude seat: exit it and launch it again. On launch, the SessionStart hook loads the new wake-path instructions, the seat's borg MCP server loads 6.0.2, and the seat arms a 6.0.2 inbox Monitor.
/clearis not enough: it restarts neither the running Monitor process nor the borg MCP server, and a re-armed monitor yields to the pre-update monitor that still holds the inbox. The first 6.0.2 arm has no cursor yet and skips history; later arms replay what they missed. - If a 6.0.0
borg representative hermes-plugin installstopped before it finished, run it again. A 6.0.0 run that refused on the worktrees had not written Borg's plugin files, Hermes configuration or activation record. Hermes's own startup maintenance, which runs with itsconfig getcommands, may still have run. - The shared contract pin is unchanged:
borgmcp-shared2.2.0.