borgmcp 5.6.0 → 5.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/claude.d.ts.map +1 -1
- package/dist/claude.js +4 -0
- package/dist/claude.js.map +1 -1
- package/dist/cli-help.d.ts.map +1 -1
- package/dist/cli-help.js +9 -2
- package/dist/cli-help.js.map +1 -1
- package/dist/hermes-plugin-install.d.ts +19 -0
- package/dist/hermes-plugin-install.d.ts.map +1 -0
- package/dist/hermes-plugin-install.js +131 -0
- package/dist/hermes-plugin-install.js.map +1 -0
- package/dist/representative-cmd.d.ts +4 -0
- package/dist/representative-cmd.d.ts.map +1 -1
- package/dist/representative-cmd.js +30 -1
- package/dist/representative-cmd.js.map +1 -1
- package/docs/HUMAN_REPRESENTATIVE.md +109 -0
- package/hermes-plugin/borg-representative-push/__init__.py +743 -0
- package/hermes-plugin/borg-representative-push/plugin.yaml +39 -0
- package/package.json +3 -1
- package/src/claude.ts +4 -0
- package/src/cli-help.ts +9 -2
- package/src/hermes-plugin-install.ts +147 -0
- package/src/representative-cmd.ts +28 -2
|
@@ -415,6 +415,115 @@ mapping, and holds unknown correlation for the human. Deduplicate queued hints b
|
|
|
415
415
|
advancing the host's `--replay-after` checkpoint. That hint checkpoint is separate
|
|
416
416
|
from the delivered checkpoint and from `ack`, which remains a server receipt.
|
|
417
417
|
|
|
418
|
+
## Hermes push plugin
|
|
419
|
+
|
|
420
|
+
For Hermes, Borg ships a Hermes user plugin, `borg-representative-push`, that
|
|
421
|
+
supervises the listener for you. When the bound Coordinator replies, the plugin
|
|
422
|
+
wakes one Hermes conversation right away. Hermes source is not changed; the
|
|
423
|
+
plugin is installed and enabled through Hermes's documented plugin mechanism.
|
|
424
|
+
|
|
425
|
+
**Which conversations can be woken.** Only a Hermes *messaging-gateway*
|
|
426
|
+
conversation (Telegram, Discord, Slack and the other gateway platforms), named
|
|
427
|
+
by its gateway `session_key`, for example `agent:main:telegram:dm:<chat id>`.
|
|
428
|
+
A Hermes Desktop chat cannot be woken: Desktop runs its chats in `hermes serve`,
|
|
429
|
+
and Hermes injects plugin messages only into gateway conversations. The
|
|
430
|
+
`session_key` stays the same across `/new` and `/reset` in that chat.
|
|
431
|
+
|
|
432
|
+
### Install
|
|
433
|
+
|
|
434
|
+
```bash
|
|
435
|
+
borg representative hermes-plugin install [--hermes-home <path>] [--force]
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
This copies the plugin's two files into `<Hermes home>/plugins/borg-representative-push/`
|
|
439
|
+
(the Hermes home is `--hermes-home`, else `$HERMES_HOME`, else `~/.hermes`) and
|
|
440
|
+
prints the configuration to add. It refuses to replace an existing install
|
|
441
|
+
without `--force`, refuses a symbolic-link target, never edits Hermes config and
|
|
442
|
+
never starts or restarts Hermes. Rerun it with `--force` after upgrading
|
|
443
|
+
borgmcp to update the plugin.
|
|
444
|
+
|
|
445
|
+
### Configure
|
|
446
|
+
|
|
447
|
+
Add to the Hermes `config.yaml`:
|
|
448
|
+
|
|
449
|
+
```yaml
|
|
450
|
+
plugins:
|
|
451
|
+
enabled:
|
|
452
|
+
- borg-representative-push
|
|
453
|
+
entries:
|
|
454
|
+
borg-representative-push:
|
|
455
|
+
allow_gateway_injection: true
|
|
456
|
+
settings:
|
|
457
|
+
session_key: "agent:main:<platform>:<chat type>:<chat id>"
|
|
458
|
+
worktree: "<absolute path of the prepared representative worktree>"
|
|
459
|
+
# optional: borg_command (default borg), mcp_server (default
|
|
460
|
+
# borg-representative), reinject_after_s (default 600), max_reinjects (default 3)
|
|
461
|
+
mcp_servers:
|
|
462
|
+
borg-representative:
|
|
463
|
+
command: borg
|
|
464
|
+
args: ["representative", "mcp", "--worktree", "<same absolute worktree path>"]
|
|
465
|
+
lazy: true
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
`allow_gateway_injection` is Hermes's per-plugin permission to start gateway
|
|
469
|
+
turns; it is off by default. `mcp_server` must name the `mcp_servers` entry that
|
|
470
|
+
runs `borg representative mcp`, because the plugin recognises the deliver tool
|
|
471
|
+
by that name. Then restart the gateway (`hermes gateway restart`).
|
|
472
|
+
|
|
473
|
+
**One tool owner.** Hermes starts a separate MCP process in every Hermes
|
|
474
|
+
process that uses the server, and only one process may hold the representative
|
|
475
|
+
tools lease. The woken conversation runs in the gateway, so the gateway must be
|
|
476
|
+
the process that uses the tools. With `lazy: true`, a process starts the Borg
|
|
477
|
+
MCP server only when one of its conversations calls a Borg tool. Run `hermes
|
|
478
|
+
tools` and disable the `mcp-borg-representative` toolset on every platform except
|
|
479
|
+
the one in `session_key`, Desktop and CLI included. If another process already
|
|
480
|
+
holds the lease (`borg representative status` shows `owned-by-other-process`),
|
|
481
|
+
restart that process once so it releases the lease.
|
|
482
|
+
|
|
483
|
+
### Behaviour
|
|
484
|
+
|
|
485
|
+
- The listener starts only inside the Hermes messaging gateway, when the platform
|
|
486
|
+
named in `session_key` connects. The CLI, Desktop and worker processes load the
|
|
487
|
+
plugin but start nothing. A platform reconnect does not start a second listener.
|
|
488
|
+
- A burst of hints (about 2 seconds) becomes one injected message with fixed
|
|
489
|
+
text: `Borg: new Coordinator reply. Call borg_representative-read, persist and
|
|
490
|
+
relay, then borg_representative-deliver through the last persisted entry_id.`
|
|
491
|
+
No message body, sender or document ever passes through the plugin. A busy
|
|
492
|
+
conversation queues the message; it does not interrupt the running turn.
|
|
493
|
+
- The plugin watches this gateway's `borg_representative-deliver` results. A
|
|
494
|
+
hinted reply that is still undelivered after `reinject_after_s` wakes the
|
|
495
|
+
conversation again. Each reply gets at most `1 + max_reinjects` wakes in total;
|
|
496
|
+
after that the plugin logs it and wakes no more for that reply until a delivery
|
|
497
|
+
covers it. Every wake is counted on disk before Hermes is asked to start the turn,
|
|
498
|
+
so neither a replayed hint nor a gateway restart renews the count. A wake Hermes
|
|
499
|
+
refuses is not counted. A crash between counting and asking can lose one wake,
|
|
500
|
+
never add one. Hermes reports only that it accepted a message, not that the
|
|
501
|
+
turn ran, so this is how a dropped wake is recovered.
|
|
502
|
+
- One small record (id, timestamp, count) is kept for each reply the plugin has
|
|
503
|
+
woken the conversation for. It is removed only when an observed delivery covers
|
|
504
|
+
that reply; there is no count limit. The records therefore grow only while woken
|
|
505
|
+
replies stay undelivered.
|
|
506
|
+
- Listener exits: 0 stops; 1 restarts with capped backoff; 2 stops and logs
|
|
507
|
+
(fix the binding, then restart the gateway); 3 (another listener owns the
|
|
508
|
+
lease) retries with backoff; 4 restarts after `lease-lost` and otherwise stops
|
|
509
|
+
and logs (evicted, rebound, revoked, trust-changed). A stop ends every wake,
|
|
510
|
+
including queued and repeat wakes, until the gateway restarts.
|
|
511
|
+
- On restart the listener replays retained hints after the last delivered
|
|
512
|
+
checkpoint the plugin observed (`--replay-after`). The delivered checkpoint
|
|
513
|
+
stays the source of truth: `read` returns every reply not yet delivered.
|
|
514
|
+
- On a normal gateway exit the plugin stops the listener. If the gateway is killed,
|
|
515
|
+
the listener it started keeps its lease until its next hint fails to write.
|
|
516
|
+
The next gateway stops that orphan only if it is the recorded listener and its
|
|
517
|
+
parent is gone. Otherwise it retries with backoff until the lease is free. A
|
|
518
|
+
dead owner's lease expires after about 70 seconds; a live orphan releases it
|
|
519
|
+
when its next hint fails to write.
|
|
520
|
+
- State (the recorded listener, the observed delivered checkpoint and the wake
|
|
521
|
+
records) and the
|
|
522
|
+
listener's stderr live under `<Hermes home>/plugin-data/borg-representative-push/`.
|
|
523
|
+
The plugin sets that directory to mode 0700, refuses it if it is a symbolic link,
|
|
524
|
+
creates its files with mode 0600, and never reads or writes through a symbolic
|
|
525
|
+
link planted there.
|
|
526
|
+
|
|
418
527
|
## Recovery
|
|
419
528
|
|
|
420
529
|
Run `borg` with the Node installation that owns the global `borgmcp` install;
|