Skip to content

Releases: gtapps/hermitd

hermitd-dev--v0.4.25

Choose a tag to compare

@gtapps gtapps released this 23 Oct 08:23

Changed

  • Requires Claude Code 2.1.302 or newer and hermitd 1.4.20.
  • Hatch no longer offers to install context7; docs/RECOMMENDED-PLUGINS.md covers installing it yourself.

hermitd--v1.4.20

Choose a tag to compare

@gtapps gtapps released this 23 Oct 08:22

Changed

  • Nothing unattended types into the resident's tmux pane: watchdog compaction, clear, monitor re-arm, the wedge nudge fallback, pause, the shutdown skill (hermitd-stop, hermitd-docker down, container SIGTERM), live update and /when-done-switch-to go through one durable queue that the core mod runs once the session is idle, never answering an open permission prompt or question.
  • Compaction and clear are recorded only when Claude Code reports them done; a failed or uncertain one stays due, and a manual /clear now records the reset too.
  • hermitd update and hermitd-docker update queue /reload-plugins and hermit-evolve as one batch; evolve runs only after the reload completes.
  • New harness-request and graceful-shutdown verbs.
  • Lapsed logins are detected from the failed turn's authentication_failed error for the resident session, which also catches an invalid API key; pending dialogs come from the session's registry status, and the stall notice names the kind of dialog it waits on (for example permission prompt) instead of quoting the terminal.
  • Watchdog compaction, clear and the other queued commands are skipped and logged as mod-not-loaded when the core mod has not loaded for the resident session, or the loaded one predates the command queue.
  • Chat !effort sets a resident-only effort override that applies to each request and persists across restarts when config.effort is unset; it outranks env.CLAUDE_CODE_EFFORT_LEVEL, the status line keeps the launch level, and !effort auto clears it.
  • Chat requests that expire or are dropped at shutdown get a reply saying they did not run.
  • A /clear or /compact typed at the terminal counts as operator activity.
  • Requires Claude Code 2.1.308 or newer.

Fixed

  • Pairing a Discord or Telegram bot in /hermitd:channel-setup or /hermitd:docker-setup sets an empty home chat to the paired DM, so the first boot's readiness notice is delivered without a prior message.
  • An unreachable channel with no home chat is reported with "send the bot a message" instead of /<channel>:access.
  • hermit-doctor gives the same overlay-hooks, heartbeat and routine-monitor verdicts whether it runs from the marketplace clone or the installed plugin cache at the same version.
  • The watchdog re-arms a stalled heartbeat or routine monitor whose process is still alive instead of reading it as needing a restart.
  • A pause no longer leaves chat harness commands refused until someone types at the terminal.
  • A watchdog compact or update no longer approves a permission prompt or question that is open in the resident session.
  • Chat !effort and /when-done-switch-to effort switches no longer hang on Claude Code's "Change effort level?" confirmation or rewrite the user-level effort default.
  • /hermitd:hatch Advanced no longer gives Docker and tmux operators the interactive next steps, or Docker operators the sandbox note.
  • /hermitd:hatch Advanced's permission question fits the four-option limit; dontAsk is typed via Other.
  • Re-running /hermitd:hatch on a Docker hermit points at hermitd restart instead of /hermitd:docker-setup, then /hermitd:channel-setup when a channel is configured.
  • A Docker hermit honors env.AGENT_HOOK_PROFILE in config.json; docker-compose.hermit.yml no longer sets the hook profile, and with nothing configured the container still launches at strict.
  • An update no longer waits out a hermit-evolve that cannot run on a Claude Code below hermitd's minimum: hermitd-docker update rebuilds the image first and evolve runs at boot (--plugins-only reports the update as blocked), and a host update stops before queuing and points at claude update.
  • The core mod marks itself loaded for a new session even when its SessionStart handler is skipped.
  • A queued /reload-plugins is confirmed from the command's own result, so a live update runs hermit-evolve even when the mod misses the transcript row.

Upgrade Instructions

  1. Delete .hermit/state/pending-harness-switch.json if it exists.
  2. In .hermit/state/watchdog-state.json, remove the last_pane_hash_standalone and last_pane_hash_compact keys and set last_nudge_transport to null. Leave every other key unchanged.
  3. Refresh the Docker entrypoint (Docker hermits only). Run hermit-evolve step 5c to refresh docker-entrypoint.hermit.sh, preserving customizations through its backup and sidecar procedure, so SIGTERM runs hermitd-run graceful-shutdown. The update that launched evolve builds and restarts with the refreshed file; for a standalone evolve, apply it with hermitd-docker update.
  4. Hand the hook profile to config.json (Docker hermits only). Hermit-evolve step 5d merges the compose template change, which removes the AGENT_HOOK_PROFILE= line from docker-compose.hermit.yml; until now that line forced strict and outranked config.json. Then read env.AGENT_HOOK_PROFILE in .hermit/config.json:
    • Absent or "strict": nothing to do. The hermit keeps launching at strict.
    • Any other value: compose overrode it, so it applies from the restart that finishes this update. Add to Operator notes: "Docker now applies env.AGENT_HOOK_PROFILE = <value> from config.json, which turns off the dev plugin's push guard. To return to strict, run .hermit/bin/hermitd-run settings-edit .hermit/config.json unset env.AGENT_HOOK_PROFILE, then hermitd restart."
    • After step 5d: if docker-compose.hermit.yml still has an AGENT_HOOK_PROFILE= line, that line keeps outranking config.json. Add to Operator notes: "Delete the AGENT_HOOK_PROFILE= line from docker-compose.hermit.yml so config.json owns the hook profile, then run hermitd-docker update."

hermitd--v1.4.19

Choose a tag to compare

@gtapps gtapps released this 22 Oct 11:15

Changed

  • The hermit edits OPERATOR.md when the operator asks, through the native approval prompt, and proposes a diff only when the edit is denied or no prompt is available.
  • An upgrade notice sent while hermitd update is still running says once that the update restarts the hermit, instead of listing restart and rebuild steps.

Fixed

  • The settings gate no longer asks for a protected-file redirect that appears only inside quoted text or a heredoc body, such as a deny-add 'Bash(*> *.hermit/resident-prompt.md*)' rule. Text a shell would still run keeps asking.
  • hermitd update no longer waits 30 minutes for evolve when a plugin installed from a repository lists its version with a build suffix (1.4.18-467be32f41fc), and no longer sees a version gap on every later update.
  • A chat answer to a deferred upgrade question is recorded only after the chosen option is applied; a denied or failed apply leaves the question open.
  • After a fresh restart, the first chat message carries recent chat history, so a reply to a question asked before the restart is understood.
  • The watchdog no longer reports a stuck session after a quiet context clear.
  • Context compaction waits while the session is busy, showing a prompt or running a worker, instead of typing into it.
  • The end-of-turn reply check accepts a reply already sent on the channel.

Upgrade Instructions

  1. Skip this step when this evolve already ran 1.4.18 Upgrade Instructions step 1. Use the settings_file Step 1's preflight resolved. Run bun <plugin_root>/scripts/apply-settings.ts <resolved-settings-file> deny ask-only to merge the Edit(*.hermit/resident-prompt.md), Edit(*.hermit/helper-prompt.md), Bash(hermitd update*), Bash(*/hermitd update*), Bash(*.hermit/bin/hermitd-update*), Bash(*.hermit/bin/hermitd-run hermitd-update*), Bash(hermitd run *hermitd-update*) and Bash(*/hermitd run *hermitd-update*) ask entries. Unless it reports {"status":"skipped","reason":"not_seeded"}, or the same file's permissions.deny already holds Bash(*> *.hermit/resident-prompt.md*) (that rule would refuse a call naming it, and its presence means the deny rules were added), run bun <plugin_root>/scripts/apply-settings.ts <resolved-settings-file> deny-add 'Bash(*> *.hermit/resident-prompt.md*)' 'Bash(*>.hermit/resident-prompt.md*)' 'Bash(*> *.hermit/helper-prompt.md*)' 'Bash(*>.hermit/helper-prompt.md*)', adding 'Edit(*.hermit/resident-prompt.md)' 'Edit(*.hermit/helper-prompt.md)' 'Bash(hermitd update*)' 'Bash(*/hermitd update*)' 'Bash(*.hermit/bin/hermitd-update*)' 'Bash(*.hermit/bin/hermitd-run hermitd-update*)' 'Bash(hermitd run *hermitd-update*)' 'Bash(*/hermitd run *hermitd-update*)' to that call when the same file's permissions.deny already holds Edit(*.hermit/state/resident-system-prompt.md) (Hardened). These operations are additive and idempotent; report added entries, the unseeded skip, or the already-present skip. Never create or edit .hermit/resident-prompt.md or .hermit/helper-prompt.md: they are operator-owned.
  2. Skip this step when this evolve already ran 1.4.18 Upgrade Instructions step 3. If line 1 of .hermit/OPERATOR.md is not # Your Standing Instructions, offer a choice with no default. evolve-runner must defer this step; step 10 asks the operator. Options: Retitle only / Retitle and apply the improvements. Both options replace line 1 only when it is exactly # Operator Context and Instructions or # Operator Context; otherwise insert # Your Standing Instructions above the existing first line. Retitle only preserves the body. Retitle and apply the improvements also rewrites the body to the agent under mission, focus, red lines and ask first, preserving the meaning of every operator rule. Leave sections that another plugin's upgrade manages as they are. Move project facts, CI details and code rules out, never drop them: offer an append to an existing CLAUDE.md or CLAUDE.local.md; otherwise follow target in .hermit/state/hatch-options.json (committed uses CLAUDE.md, local uses CLAUDE.local.md). If only AGENTS.md exists, create that target's CLAUDE file with @AGENTS.md first and append the moved lines. Otherwise create that target's CLAUDE file with a one-line heading (# CLAUDE.md or # CLAUDE.local.md) and append the moved lines under a short heading. Never write or edit AGENTS.md. Apply the OPERATOR.md edit with Edit so the native approval prompt fires; if it is denied, propose the diff for the operator to apply.

hermitd-laravel-forge--v0.0.22

Choose a tag to compare

Fixed

  • Upgrades also list operator scripts and routine checks that still read the old forge.php output.

Upgrade Instructions

  1. Find forge.php invocations that branch on the pre-0.0.20 output shapes listed in 0.0.20 Upgrade Instructions item 1. Look in the project's .claude/skills/, .claude/commands/ and .claude/agents/ (including bundled scripts of any language), routines[].precheck and monitors[].command in .hermit/config.json, hook commands in .claude/settings.json and .claude/settings.local.json, and .hermit/dashboard-render.ts. Skip gitignored files, .claude/worktrees/, nested repositories, backups, plugin directories, and lines already listed by 0.0.20 item 1 in the same run. A line that only checks a real failure's exit code is not a hit. Never edit files here. Skip silently when none remain. Otherwise list the hits with file and line and defer per core's hermit-evolve Step 10 with options: ["Fix them", "Leave them"] and no on_resolve:
    • Fix them: update each line to the shape the Forge skill running the same command describes. Report each file changed.
    • Leave them: change nothing and say those lines misread forge.php output until updated.

hermitd-homeassistant--v0.4.26

Choose a tag to compare

Changed

  • The HA language setting is removed; replies follow the hermit's language, a different automation-naming language goes in a CLAUDE file, and boot store drops --language.

Upgrade Instructions

  1. If .hermit/OPERATOR.md contains ## HA hermit, offer a choice with no default: Remove (and add the line) / Keep. Defer to the operator through evolve's step 10. Offer to remove only that section, preserving all other content. If language in .hermit/config.json is null, also offer to set it to the section's - Language: value, so replies and automation names keep that language; no naming line is needed then. If its - Language: differs from a non-null language, also offer the line "Name Home Assistant automations and their descriptions in ." with the section's language substituted. Add that line only when the operator chooses removal and accepts the naming instruction. Offer an append to an existing CLAUDE.md or CLAUDE.local.md; otherwise follow target in .hermit/state/hatch-options.json (committed uses CLAUDE.md, local uses CLAUDE.local.md). If only AGENTS.md exists, create the target's CLAUDE file with @AGENTS.md first, then the naming line. Otherwise invoke Skill(init) (local args: Write the result to CLAUDE.local.md instead of CLAUDE.md, titled # CLAUDE.local.md.) and append the line. Never write or edit AGENTS.md. If the languages match, removal needs no naming line or new CLAUDE file. Send the OPERATOR.md edit through the normal approval prompt, proposing the diff for the operator to apply.

hermitd-dev--v0.4.24

Choose a tag to compare

@gtapps gtapps released this 21 Oct 23:40

Changed

  • Hatch no longer appends ## Development Conventions to OPERATOR.md; protected branches and the hook profile stay in config.json.

Upgrade Instructions

  1. If .hermit/OPERATOR.md contains ## Development Conventions, offer a choice with no default: Remove / Keep. Defer to the operator through evolve's step 10. Explain that the section repeats config.json. Remove only that section if chosen, preserving other operator content; propose the diff for the operator to apply through the normal OPERATOR.md approval prompt.

hermitd--v1.4.18

Choose a tag to compare

@gtapps gtapps released this 21 Oct 23:39

Added

  • role-review skill and script for scheduled chat-rule proposals backed by agreeing corrections, with reply approvals and stale checks. Opt-in: it runs only as a routine the operator schedules, and each run spends one subagent.
  • Per-chat instructions (channels.<key>.instructions) that only a permission-prompt approval can change, applied on that chat's turns ahead of standing roles; absent by default since they are operator-written content.
  • Plugin icon at assets/icon.png, declared as icon in plugin.json for plugin directory listings.
  • An operator-owned .hermit/resident-prompt.md replaces the shipped resident prompt and rules at every start, and .hermit/helper-prompt.md does the same for spawned helpers; empty or absent keeps the shipped prompt. A copy misses signals a later release adds to ## Watches or the helper report block until those lines are copied again.

Changed

  • Durable chat-behavior corrections save directly as pinned memory roles.
  • Any configured channel can own a routine; script notices still need a direct sender or send_script.
  • Routines added from a chat bind the asking chat, home included.
  • Routine writes from non-primary channel senders or unknown origins raise the native permission prompt, and accepted routine proposals follow the same routine rules.
  • Conversation history includes only allowed inbound senders and all outbound rows.
  • Weekly consolidation leaves role files and [role index lines alone.
  • Reflect reuses an existing observation label for a recurring problem, so repeats under new wording still count toward a proposal.
  • Upgrade questions are queued as micro-proposals at the end of the notice, so a chat reply applies the chosen option even after a restart.
  • hermitd update waits for quiet, updates plugins and runs evolve before building, then restarts once with migrations applied and resumes the conversation unless the resident prompt changed. A wait timeout restarts nothing at once and asks for a rerun; once evolve has applied, the watchdog may finish the restart at a quiet moment, and only the rerun rebuilds the image.
  • hermitd update --plugins-only bounces the container once after the plugin update and is refused while a host tmux session owns the project.
  • Config watches run under a background monitor with no expiry wakes, restart on exit, and apply config edits live.
  • /hermitd:watch stop on a config watch sets enabled: false.
  • Config watch commands no longer see shell-profile functions; PATH and exported variables are unchanged.
  • monitors[] entries drop timeout_ms and persistent; config watches run until stopped or disabled.
  • Closed task threads stay addressed, with !mute and !unmute available after completion.
  • Recent chat history from allowed senders and the hermit accompanies messages after a context reset until the hermit's next logged reply in that chat.
  • Hatch writes OPERATOR.md as standing instructions to the agent and leaves project facts to the CLAUDE files.
  • Hatch creates the project's CLAUDE file with /init when no project instruction file exists.
  • OPERATOR.md is titled # Your Standing Instructions and loads as Operator Instructions.
  • A passing check or held later claim that closes a task record linked to a proposal (key proposal:PROP-NNN) resolves that proposal; task and daily later replies name the resolve or its error. A linked record without a check still needs /proposal-act resolve.
  • hermitd update run by the resident asks for approval, including in auto mode; Hardened installs deny it.
  • proposal-act also activates on requests to implement or go ahead with a proposal or "suggestion #N", opening the linked record through the accept flow.
  • Standing-work answers read config watches from the watch monitor and describe /hermitd:watch stop as disabling that watch.
  • A chat request to schedule a routine whose skill is not installed is declined and filed as a capability proposal.
  • Chat history and the history verb honor a channel's own log_chats: true when global logging is off.
  • Role-review's analysis worker reads the chat snapshot itself, so the chat text stays out of the resident's context.
  • A pending approval question can be answered only in the chat where it was asked; terminal replies still answer any. Briefs and heartbeat alerts in the home chat list only the home chat's questions.
  • A bare YES, LATER or NO on a suggestion acts only in a channel's home chat; elsewhere the hermit asks which suggestion by number.
  • "Implement" or "go ahead with" a named suggestion starts the work in the same turn; a plain accept still asks how to proceed.
  • Capability proposals from a non-primary sender's routine request are marked as external content for triage.
  • Standing-work answers flag a config watch that keeps exiting with an error.

Fixed

  • Settings approval prompts show a single-quoted value in full when it contains an escaped apostrophe ('\''), instead of cutting it off at the first one.
  • Permission rules a release retires are also removed from the hermit's other settings file.
  • Block retirement retires paired blocks and names unpaired markers instead of failing.
  • Planned watchdog restarts avoid crash recovery wording and report the actual resume decision; a changed resident prompt starts fresh.
  • Docker keeps the container alive for up to 60 seconds while a watchdog restart replaces tmux.
  • Doctor reports monitors awaiting a resident restart as failures.
  • .hermit/bin/hermitd-update inside a Docker container points to the Docker host instead of reporting the container as stopped.
  • hermitd update on a macOS host records the running Claude Code version instead of unknown.
  • Dead ad-hoc watches no longer show as active after a restart: hermitd-start empties state/monitors.runtime.json at launch.
  • The harness-mod doctor row clears after the next answered resident turn when the session-start record was missed.
  • The Chrome-on-setup-token warning has its own chrome-auth doctor row, so credential-expiry and the heartbeat no longer read it as a login renewal.
  • The evening brief counts tasks closed today in the configured timezone.
  • Agent names with accented or non-Latin letters ("Inês", "Amélia") keep them in the Remote Control title, peer name and backup commit author instead of losing them.
  • Turn cost rows include API calls made before a mid-turn skill load and, after a session's first billed turn, calls before a mid-turn channel or cross-session message or in a turn whose Stop hook never ran. These calls were previously never billed.

Upgrade Instructions

  1. Use the settings_file Step 1's preflight resolved. Run bun <plugin_root>/scripts/apply-settings.ts <resolved-settings-file> deny ask-only to merge the new Edit(*.hermit/resident-prompt.md), Edit(*.hermit/helper-prompt.md), Bash(hermitd update*), Bash(*/hermitd update*), Bash(*.hermit/bin/hermitd-update*), Bash(*.hermit/bin/hermitd-run hermitd-update*), Bash(hermitd run *hermitd-update*) and Bash(*/hermitd run *hermitd-update*) ask entries. Unless it reports {"status":"skipped","reason":"not_seeded"}, run bun <plugin_root>/scripts/apply-settings.ts <resolved-settings-file> deny-add 'Bash(*> *.hermit/resident-prompt.md*)' 'Bash(*>.hermit/resident-prompt.md*)' 'Bash(*> *.hermit/helper-prompt.md*)' 'Bash(*>.hermit/helper-prompt.md*)', adding 'Edit(*.hermit/resident-prompt.md)' 'Edit(*.hermit/helper-prompt.md)' 'Bash(hermitd update*)' 'Bash(*/hermitd update*)' 'Bash(*.hermit/bin/hermitd-update*)' 'Bash(*.hermit/bin/hermitd-run hermitd-update*)' 'Bash(hermitd run *hermitd-update*)' 'Bash(*/hermitd run *hermitd-update*)' to that call when the same file's permissions.deny already holds Edit(*.hermit/state/resident-system-prompt.md) (Hardened). These operations are additive and idempotent; report added entries or the unseeded skip. Never create or edit .hermit/resident-prompt.md or .hermit/helper-prompt.md: they are operator-owned.
  2. If the project's .gitignore contains the line # .hermit state is tracked here (backup: workspace mode), skip this step. Otherwise add .hermit/resident-prompt.md and .hermit/helper-prompt.md alongside the other .hermit/ entries when absent.
  3. If line 1 of .hermit/OPERATOR.md is not # Your Standing Instructions, offer a choice with no default. evolve-runner must defer this step; step 10 asks the operator. Options: Retitle only / Retitle and apply the improvements. Both options replace line 1 only when it is exactly # Operator Context and Instructions or # Operator Context; otherwise insert # Your Standing Instructions above the existing first line. Retitle only preserves the body. Retitle and apply the improvements also rewrites the body to the agent under mission, focus, red lines and ask first, preserving the meaning of every operator rule. Leave sections that another plugin's upgrade manages as they are. Move project facts, CI details and code rules out, never drop them: offer an append to an existing CLAUDE.md or CLAUDE.local.md; otherwise follow target in .hermit/state/hatch-options.json (committed uses CLAUDE.md, local uses CLAUDE.local.md). If only AGENTS.md exists, create that target's CLAUDE file with @AGENTS.md first and append the moved lines. Otherwise create that target's CLAUDE file with a one-line heading (# CLAUDE.md or # CLAUDE.local.md) and append the moved lines under a short heading. Never write or edit AGENTS.md. Send the OPERATOR.md edit through the normal approval prompt, proposing the diff for the operator to apply.
  4. Remove timeout_ms and persistent from each .hermit/config.json monitors[] entry when present, preserving every other key.
  5. Report restart_required in Operator notes because config watches run under the new monitor only after a restart. Follow the restart_required delivery route; never issue a restart on the operator's behalf....
Read more

hermitd-scribe--v0.1.11

Choose a tag to compare

@gtapps gtapps released this 19 Oct 13:12

Changed

  • Hatch no longer writes an instruction block into CLAUDE.md; the plugin's skills, agents and hooks carry its guidance. Requires hermitd 1.4.17.

Fixed

  • /hatch names existing operator denies that override the publication asks.

hermitd-laravel-forge--v0.0.21

Choose a tag to compare

Changed

  • Hatch no longer writes an instruction block into CLAUDE.md; the plugin's skills, agents and hooks carry its guidance. Requires hermitd 1.4.17.

Fixed

  • forge.php check reports a rejected or forbidden (403) token as invalid instead of unreachable
  • forge.php failed-deploys pauses after a rate-limited deployment fetch

hermitd-homeassistant--v0.4.25

Choose a tag to compare

Changed

  • Hatch no longer writes an instruction block into CLAUDE.md; the plugin's skills, agents and hooks carry its guidance. Requires hermitd 1.4.17.

Fixed

  • The morning brief lists open proposals under Pending:, including update proposals the Updates: section folds into its + N more or HACS lines.