hermes-continuation creates structured continuation handoffs for long-running Hermes agent work. It is a sidecar CLI plus a thin Hermes plugin wrapper. The packet contract is the product: a local Markdown file for humans and a local JSON file for agents/tools.
The MVP is intentionally conservative. doctor recommends, prepare previews, create writes packet files, and watch runs a one-shot read-only advisory check through the existing doctor/prepare helpers. It does not modify Hermes core, auto-restart sessions, parse full Hermes transcripts, launch fresh agents, sync to cloud, provide a dashboard, run a daemon by default, or perform hidden writes.
Use hermes-continuation when:
- a task is too long for one comfortable session;
- context is getting large or compressed;
- you need another Hermes session or teammate to continue safely;
- you want the next agent to see concrete repository state, verification gates, blockers, and boundaries;
- you need a copy-paste resume prompt that is backed by a structured packet.
Do not use it as a secret vault, transcript archive, cloud sync system, background monitor, or automatic session manager.
A handoff packet records:
- current goal;
- repository path, branch, HEAD,
git status --short, and changed files; - completed work and active work;
- known blockers;
- do-not-touch boundaries;
- verified, failing, and not-run gates;
- safety/redaction status;
- a resume prompt for the fresh Hermes session.
Default output:
.hermes/handoffs/<timestamp>-handoff.md
.hermes/handoffs/<timestamp>-handoff.json
Treat .hermes/handoffs/ as runtime output. Do not commit it unless you have deliberately reviewed and sanitized a packet for sharing.
Clone or enter the repo, then install editable into your active Python environment:
cd /path/to/hermes-continuation
python -m pip install -e .Confirm the CLI is visible:
hermes-handoff --help
python -m hermes_continuation.cli --helpIf hermes-handoff is not on PATH, use the module form or check that your shell is using the Python environment where you installed the package.
hermes-handoff create requires --goal and --next.
Minimal create:
hermes-handoff create \
--repo . \
--goal "Finish dashboard QA" \
--next "Run build and browser smoke test"Richer create:
hermes-handoff create \
--repo . \
--goal "Finish dashboard QA" \
--completed "Updated health-card copy" \
--completed "Added unit coverage for health status mapping" \
--in-progress "Preparing release verification" \
--verified "python -m pytest -q passed" \
--failing "browser smoke test still fails on loading state" \
--not-run "production deploy dry run" \
--blocker "Need product sign-off for final copy" \
--do-not-touch "billing migrations" \
--next "Run build and browser smoke test"Equivalent module form:
python -m hermes_continuation.cli create --repo . --goal "Smoke test" --next "Inspect output"Useful options:
--repo: repository path to inspect. Defaults to the current directory.--output-dir: custom output directory. Defaults to<repo>/.hermes/handoffs.--completed,--verified,--failing,--not-run,--blocker,--do-not-touch: repeatable list fields.--in-progress: current active work text.
Use doctor when you want a recommendation without creating anything:
hermes-handoff doctor \
--repo . \
--goal "Finish dashboard QA" \
--next "Run build and browser smoke test"Use prepare when you want a structured preview before deciding to write a packet:
hermes-handoff prepare \
--repo . \
--goal "Finish dashboard QA" \
--next "Run build and browser smoke test"Boundary in plain language:
doctorrecommends whether a handoff is useful.preparepreviews the proposed handoff state and may show a safehermes-handoff create ...command.createis the only CLI command here that writes Markdown/JSON packet files under.hermes/handoffs/by default.prepareis read-only: it never creates.hermes/handoffs/directories or packet files, even when it prints a safe create command.- A safe create command is guidance, not consent. The user must explicitly run
hermes-handoff create ...to write a packet. - Missing
goalornextdegrades toadviserather than fabricating state. - Safety blockers return
block, suppress the safe create command, and do not print secret values.
Both commands support --json when a machine-readable recommendation/preview envelope is needed.
hermes-handoff watch is implemented as a one-shot CLI command for advisory auto-trigger checks. It observes explicit local signals once, calls the existing doctor/prepare helpers, prints advice or a preview, and exits.
Example:
hermes-handoff watch \
--repo . \
--goal "Finish dashboard QA" \
--next "Run build and browser smoke" \
--tool-calls 8 \
--elapsed-minutes 45 \
--dirty-threshold 1 \
--explicit-requestMachine-readable output:
hermes-handoff watch --repo . --goal "Finish QA" --next "Run smoke" --explicit-request --jsonSupported watch flags include --goal, --next, --tool-calls, --elapsed-minutes, --dirty-threshold, --explicit-request, and --json.
Watch boundaries:
- read-only/advisory only: it never writes
.hermes/handoffs/packet files and never creates that directory; - no hidden create path: it never calls
hermes-handoff createor packet-writing helpers on the user's behalf; - no daemon by default: it evaluates once and exits;
- missing
goalornextdegrades toadviseinstead of fabricating preview state; blockresults suppress secret values and safe create commands;- plugin/gateway
/handoff watchis available as a plugin tool; see the plugin documentation for details.
Plain-language side-effect boundary: doctor recommends, prepare previews, create writes, and watch observes/advises/previews through existing doctor/prepare helpers.
Automatic task-state collection is off by default. Enable it explicitly:
hermes-handoff create \
--repo . \
--goal "Finish dashboard QA" \
--auto-task-state \
--completed "Manual note to preserve" \
--next "Run build and browser smoke test"Boundaries of --auto-task-state:
- scans only conservative repo-local Markdown sources:
PROGRESS.mdREADME.md- direct
docs/*.mdfiles
- looks for bullets under task-state headings such as Completed Work, In Progress, Blockers, Do Not Touch, and Next Step;
- skips generated/runtime paths such as
.git,.hermes,graphify-out,_knowledge_base,.pytest_cache,__pycache__, and*.egg-info; - limits the number and size of collected items;
- fails closed if scanned Markdown contains a private-key block;
- does not parse full Hermes transcripts;
- does not infer hidden state from chat history;
- appends manual list values after auto-collected values with de-duplication;
- keeps manual
--nextauthoritative.
Use manual flags for anything important. Treat auto collection as a convenience prefill, not as a source of truth.
Use the generated JSON to print the fresh-session prompt:
hermes-handoff resume .hermes/handoffs/<timestamp>-handoff.jsonBy default, resume prints only the prompt text so it can be pasted or piped into a new Hermes session. If you want a labeled Markdown section:
hermes-handoff resume --markdown .hermes/handoffs/<timestamp>-handoff.jsonresume validates the JSON packet before printing. It does not create a new handoff, mutate the handoff file, or infer missing task state.
For plugin use, install hermes-continuation into the same Python interpreter that runs Hermes. The exact path depends on your Hermes installation.
Example pattern:
cd /path/to/hermes-continuation
/path/to/hermes/python -m pip install -e .This package exposes the entry point:
[project.entry-points."hermes_agent.plugins"]
hermes-continuation = "hermes_continuation.plugin"Enable it through Hermes' normal plugin-management flow, or add it to Hermes config:
plugins:
enabled:
- hermes-continuation
disabled: []Restart the Hermes CLI/gateway after install or config changes. Plugin discovery is cached inside a running Hermes process.
When loaded, the wrapper registers five tools:
hermes_handoff_doctor: return a read-only handoff recommendation.hermes_handoff_prepare: build a read-only prepare preview; it never writes packet files and has no required fields.hermes_handoff_watch: run the same one-shot read-only advisory check exposed byhermes-handoff watch.hermes_handoff_create: create a Markdown + JSON handoff packet.hermes_handoff_resume: extract the resume prompt from a handoff JSON.
The tool schema for create requires:
goalnext_task
A plugin tool and gateway slash command for watch are available (/handoff watch ...). For programmatic use, call the hermes_handoff_watch tool directly.
Auto-watch lets Hermes check whether a handoff is overdue without relying on you to remember /handoff watch. It uses the same conservative watch/doctor/prepare path described above: automatic triggers can advise or prepare a preview, but they do not write handoff packets. If you want a packet, explicitly run /handoff prepare to inspect the preview and then run create yourself.
On compatible Gateway runtimes, the plugin on_turn_complete hook can return a restart advisory after each assistant response. It considers conversation length, elapsed time, tool-call count, and optional task execution completeness. When it fires, the payload includes restart_recommended, handoff_recommended, metrics, task_execution, signals, reasons, and a pasteable handoff_prompt draft. The hook is still read-only: it never starts a new conversation and never writes packet files.
| Mode | How it is triggered | Best for | Notes |
|---|---|---|---|
| Gateway Wrapper | The chat gateway calls evaluate_and_log() or the plugin on_turn_complete hook after each Hermes response. |
Active Feishu/Hermes conversations. | Uses fresh conversation signals such as message count, elapsed time, tool-call count, dirty-file count, and optional task completeness. |
| Cron | A scheduler scans configured watch_repos on an interval, such as every 30 minutes. |
Work you may leave running while away. | Uses repository-local signals only; configure the repo list explicitly. |
| Manual | You run /handoff watch or call hermes_handoff_watch yourself. |
Any time you want an immediate check. | Same read-only advisory behavior as the CLI hermes-handoff watch. |
Feishu notifications are intentionally brief and do not expose repository names, file paths, or file contents:
⚠️ A project in progress may need a handoff
About 45 minutes of work, 80+ tool calls, 12 files changed
→ Return to the conversation and run /handoff prepare to preview the handoff
Add the auto-watch config under the hermes-continuation plugin config. The thresholds below match the README quick-start shape and can be tuned per deployment:
plugins:
enabled:
- hermes-continuation
disabled: []
config:
hermes-continuation:
auto_watch:
enabled: true
tool_calls_threshold: 5 # notify when the active session reaches at least 5 tool calls
elapsed_minutes_threshold: 30 # notify when the active session has run for at least 30 minutes
cooldown_minutes: 20 # wait at least 20 minutes between notifications
notify_levels: ["advise", "prepare", "block"]
watch_repos: # cron mode only: repos to scan explicitly
- /path/to/repoOperational notes:
- Gateway Wrapper mode requires the gateway integration to call
evaluate_and_log()after Hermes responses. - Cron mode only scans paths listed in
watch_repos; keep the list narrow and intentional. - Manual mode works even when automatic gateway/cron integration is not enabled.
- One-click off switch: set
auto_watch.enabled: falseto silence all automatic triggers immediately.
Safety boundaries:
- Notifications never include repo names, file paths, or file contents.
- Auto-watch is read-only/advisory: it does not create
.hermes/handoffs/, does not write packet files, and does not invoke hiddencreatebehavior. - The notification is only a prompt to inspect a preview; packet creation still requires an explicit user action.
On Hermes builds that expose plugin slash commands, the wrapper registers /handoff without modifying Hermes core.
Help:
/handoff help
Prepare a read-only preview with JSON:
/handoff prepare {"repo_path":".","goal":"Finish dashboard QA","next_task":"Run build and browser smoke","auto_task_state":true}
Prepare with shell-style key/value arguments:
/handoff prepare repo_path=. goal="Finish dashboard QA" next_task="Run build and browser smoke" auto_task_state=true
/handoff prepare ... is available only on compatible Hermes runtimes that expose plugin slash-command registration. It calls hermes_handoff_prepare, never writes .hermes/handoffs/ packet files, and may show a safe create command that the user must explicitly run through create to write.
Create with JSON, recommended for predictability:
/handoff create {"repo_path":".","goal":"Finish dashboard QA","next_task":"Run build and browser smoke","auto_task_state":true}
Create with shell-style key/value arguments:
/handoff create repo_path=. goal="Finish dashboard QA" next_task="Run build and browser smoke" auto_task_state=true
Implicit create shortcut:
/handoff {"repo_path":".","goal":"Finish dashboard QA","next_task":"Run build and browser smoke"}
Resume:
/handoff resume .hermes/handoffs/<timestamp>-handoff.json
Resume with Markdown wrapper:
/handoff resume {"handoff_json":".hermes/handoffs/<timestamp>-handoff.json","markdown":true}
Bare /handoff or /handoff help shows help instead of creating an underspecified packet. Plugin auto_task_state is optional and follows the same boundaries as CLI --auto-task-state. Plugin/gateway /handoff watch is available through the hermes_handoff_watch tool on compatible runtimes.
Runtime handoff packets are written to:
.hermes/handoffs/
Do not commit generated/runtime artifacts:
.hermes/handoffs/graphify-out/_knowledge_base/.pytest_cache/__pycache__/*.egg-info
If you run smoke commands, prefer a temporary repository or --output-dir pointing outside your working tree.
tests/test_hermes_runtime_plugin_smoke.py intentionally stays portable for contributors:
- it skips cleanly when Hermes runtime prerequisites are missing;
- default fallback source path is
/home/zycas/.hermes/hermes-agent; - default fallback interpreter path is
/home/zycas/.hermes/hermes-agent/venv/bin/python3.
You can override both defaults with environment variables:
HERMES_AGENT_SOURCE="/path/to/hermes-agent" \
HERMES_AGENT_PYTHON="/path/to/hermes-agent/venv/bin/python3" \
python -m pytest -q tests/test_hermes_runtime_plugin_smoke.pyHandoff content may be copied into another agent or shared with a teammate. Keep it secret-safe.
Rules:
- Never include real API keys, tokens, passwords, private keys, connection strings, chat IDs, message IDs, or customer secrets in examples or handoff notes.
- Use obvious placeholders such as
[REDACTED],sk-test-[REDACTED], orexample-token-[REDACTED]. - The CLI/plugin redacts common token/API-key/password-like patterns to
[REDACTED]. - Private-key blocks fail closed and should prevent handoff output.
doctorrecommends andpreparepreviews; both are read-only and never write.hermes/handoffs/packet files.watchis a one-shot read-only CLI advisory: it never writes.hermes/handoffs/, never invokes hidden create behavior, and does not run as a daemon by default.preparemay show a safe create command, but the user must explicitly runcreatebefore any packet is written.- Safety blockers return
block, suppress the safe create command, and do not print secret values. - The tool does not parse full Hermes transcripts automatically.
- Auto task-state collection is explicit opt-in and limited to conservative repo-local Markdown files.
- Review generated handoff packets before sending them anywhere.
Run these before publishing code or documentation changes.
Full tests:
python -m pytest -qHermes runtime/plugin smoke, if a compatible local Hermes runtime is available:
python -m pytest -q tests/test_hermes_runtime_plugin_smoke.pyCLI help smoke:
python -m hermes_continuation.cli --help
python -m hermes_continuation.cli doctor --help
python -m hermes_continuation.cli prepare --help
python -m hermes_continuation.cli watch --help
python -m hermes_continuation.cli create --help
python -m hermes_continuation.cli resume --helpRuntime create/resume smoke in a temporary repo:
tmpdir="$(mktemp -d)"
git -C "$tmpdir" init
python -m hermes_continuation.cli create \
--repo "$tmpdir" \
--goal "Smoke test" \
--next "Inspect generated handoff"
json_file="$(find "$tmpdir/.hermes/handoffs" -name '*-handoff.json' | sort | tail -n 1)"
python -m hermes_continuation.cli resume "$json_file" >/dev/nullSecret scan concept:
python - <<'PY'
from pathlib import Path
patterns = ['BEGIN PRIVATE KEY', 'api_key=', 'password=', 'bearer ']
for path in [*Path('.').glob('*.md'), *Path('docs').glob('*.md')]:
text = path.read_text(encoding='utf-8', errors='ignore').lower()
hits = [p for p in patterns if p.lower() in text]
if hits:
print(f'{path}: review possible secret-like text {hits}')
PYWhitespace diff check:
git diff --checkGraphify hook, when available in your workspace:
command -v graphify >/dev/null && graphify . || trueIf graph/report output is generated, do not stage graphify-out/ unless a maintainer explicitly asks for it.
Hermes caches plugin discovery in a running process. Restart the Hermes CLI/gateway after installing, enabling, disabling, or editing the plugin. In tests, use forced plugin discovery if the runtime supports it.
Install with the Hermes interpreter, not only your shell's default Python:
/path/to/hermes/python -m pip install -e /path/to/hermes-continuationThen verify:
/path/to/hermes/python - <<'PY'
from importlib.metadata import entry_points
print([ep.name for ep in entry_points(group='hermes_agent.plugins')])
PYYou should see hermes-continuation.
Your Hermes build may not expose plugin slash-command registration. This is expected on older builds. The wrapper still registers plugin tools such as hermes_handoff_prepare, hermes_handoff_watch, hermes_handoff_create, and hermes_handoff_resume.
Watch is available as both the CLI command hermes-handoff watch and the plugin tool hermes_handoff_watch (accessible via /handoff watch on compatible Hermes runtimes).
They are runtime artifacts. Remove or ignore generated files before committing:
git status --shortDo not stage .hermes/handoffs/, graphify-out/, _knowledge_base/, caches, or egg-info directories.
Use the module form:
python -m hermes_continuation.cli --helpOr activate the environment where you installed the package and ensure its script directory is on PATH.
CLI usage does not require Hermes runtime imports. Plugin runtime smoke tests may skip or fail if Hermes is not installed locally. Install into the real Hermes environment and run the runtime smoke only where Hermes is available.
This is intentional fail-closed behavior. Remove the private key block from inputs/docs and replace sensitive material with [REDACTED] before creating a handoff.
Before opening a PR or asking someone to commit:
- Keep changes scoped. Do not modify Hermes core for sidecar/plugin-wrapper work.
- Do not commit runtime/generated artifacts:
.hermes/handoffs/,graphify-out/,_knowledge_base/, caches, or*.egg-info. - Keep examples secret-safe and use obvious fake placeholders only.
- Preserve product truth: this MVP recommends/previews/creates/resumes handoff packets and offers one-shot CLI watch advice; it does not auto-restart sessions, parse full transcripts, run background watch daemons, or perform hidden writes.
- Keep
doctorandprepareread-only; they must not write.hermes/handoffs/packet files. - Keep
watchread-only/advisory; automatic writes remain out of scope unless separately approved. - Keep
createrequiring--goaland--nextin the CLI. - Keep plugin
createrequiringgoalandnext_task. - Keep auto task-state collection opt-in only.
- Run relevant tests and document any skipped checks.
- Run
git diff --checkbefore handing off. - Review
git diffso the commit contains only intended files.
Scoped commit guidance:
git status --short
git diff -- README.md docs/USAGE.md docs/USAGE.zh-TW.md docs/USAGE.zh-CN.md
git diff --checkStage only the intended documentation files when you are ready. Do not stage unrelated local progress files or generated directories.