Skip to content
Automation
Skill

/hermit-evolve

Evolves hermit configuration and templates after a plugin update. Detects version gaps and runs the upgrade (migrations, templates, new settings) in an isolated subagent. Run after updating the plugin.

From plugin
claude-code-hermit
7488 skills11 agents
Install
$ npx -y skills add gtapps/claude-code-hermit --skill hermit-evolve --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/hermit-evolve

Context preview

The summary Claude sees to decide when to auto-load this skill.

Evolves hermit configuration and templates after a plugin update. Detects version gaps and runs the upgrade (migrations, templates, new settings) in an isolated subagent. Run after updating the plugin.

SKILL.md

hermit-evolve.SKILL.md
name: hermit-evolve
description: Evolves hermit configuration and templates after a plugin update. Detects version gaps and runs the upgrade (migrations, templates, new settings) in an isolated subagent. Run after updating the plugin.

Evolve Hermit

Upgrade the project's hermit configuration after a plugin update.

Execution routing

Every run of this skill (interactive or unattended) delegates steps 0–9 to the `claude-code-hermit:evolve-runner` subagent, so the upgrade's transient churn (changelog slice, migration execution, file diffs) never lands in the calling session. The main loop keeps only step 10 (summary + operator notification).

> **Tool note:** `claude-code-hermit:evolve-runner` is a **subagent** — invoke it via the Agent tool, never the Skill tool. The `plugin:name` form it shares with skills does not imply the Skill tool.

  • **If you are running AS the `evolve-runner` subagent**, skip this section and execute steps 0–9 directly (you are the delegate — do not re-dispatch).
  • **Otherwise (main loop, any mode):**

1. **Determine execution and delivery separately** and remember both for step 10:

  • Positional argument `unattended` ⇒ execution *unattended*, delivery *automated-maintainer*.
  • No `unattended` argument + an inbound `<channel source="...">` tag ⇒ execution *unattended*

(never block on `AskUserQuestion`), delivery *direct-channel-reply*.

  • Otherwise ⇒ execution *interactive*, delivery *inline*.

Only the explicit `unattended` argument authorizes a proactive maintainer notification. A direct channel request must answer the channel that invoked it. 2. **Bake the absolute plugin root** to thread to the subagent (it cannot resolve it itself — the bare env var `$CLAUDE_PLUGIN_ROOT` is **not** set at Bash runtime, and the value is empty inside subagents). Derive it from this skill's **Base directory**, which the harness injects in the skill invocation context as `<plugin_root>/skills/hermit-evolve`: strip the trailing `/skills/hermit-evolve` to get `plugin_root`. This works in both installed and `--plugin-dir` modes. (In installed mode this equals the harness's `${CLAUDE_PLUGIN_ROOT}` substitution, which step 1 relies on; the Base-directory derivation is the mode-independent source.) **Guard:** confirm both `test -f "<plugin_root>/skills/hermit-evolve/SKILL.md"` and `test -f "<plugin_root>/skills/hermit-evolve/reference.md"` — the subagent reads `reference.md` for steps 0–9, so a missing reference file is just as fatal as a missing SKILL.md. If either fails, **abort** — log `"hermit-evolve aborted: plugin root unresolved; cannot dispatch evolve-runner."` and stop. Do not dispatch with a broken path. 3. **Dispatch** the `claude-code-hermit:evolve-runner` subagent via the Agent tool. Pass the baked absolute plugin root and the report contract (below). Do **not** execute steps 0–9 yourself. 4. **Go to step 10** with the subagent's returned report.

Delegated mode

Steps 0–9 (in `reference.md`, read only by the `evolve-runner` subagent) are executed with no `AskUserQuestion` — the subagent cannot pause to ask. Each step's **"Delegated mode:"** note states the non-interactive behavior. The rule in every case: never guess on a destructive choice, never block.

  • For any interactive choice with a safe non-destructive default (new settings, file deletions, `## Plan` strip, template conflicts, an `### Upgrade Instructions` step that names a single non-destructive command such as `deny ask-only`), take the default silently and report the outcome.
  • For a genuine either/or with **no safe default** (an `### Upgrade Instructions` migration step in 2b/7 that poses a choice and names no default), **defer**: skip that step and record a verbatim deferred-migration block in the report (see the report contract in step 10). Never guess. Step 10 resolves it — interactive asks the operator; direct-channel and automated-maintainer execution relay it through their respective delivery routes. Never apply a deferred instruction that would write `.claude/settings*.json` from a channel session.

10. Report

After a successful upgrade, arm `/claude-code-hermit:later add 1d "doctor stays green after upgrading to <version>" | .claude-code-hermit/bin/hermit-run doctor-check .claude-code-hermit --gate` (hermit origin, `--timeout-s 120`: the doctor gate probes credentials and docker and gets the same budget as its routine). The resolver form survives the next plugin update; a baked `<plugin_root>` path points at a cache directory that may be gone by the time the claim is checked.

**Step 10 runs in the main loop** (not the subagent), consuming the `evolve-runner`'s returned report. The subagent's report is the single source for what follows.

**Report contract** — the subagent's final message is exactly this; non-deferred runs carry no deferred block, so the common payload is tiny:

Upgrade: vOLD -> vNEW | core current vNEW | blocked: <reason>
Settings added: <keys | none>
Templates: <refreshed/restored/kept-N/conflicts-parked-N | none>
Bin wrappers: <restored/replaced(.bak) | none>
Docker entrypoint: <refreshed | conflict-replaced(<backup path>) | migrated(<N> moved, <M> in <patch path>) | n/a>
Docker templates: <name merged(3-way[; n conflicts resolved]) | kept(bootstrap, upstream not merged: <path>) | conflict(n): upstream copy at <path>; ... | report-only(<names>) | none>
Docker rebuild: <needed + order | base-patched | no>
CLAUDE-APPEND: <updated | unchanged | kept (resident duties duplicated until you accept the shrink)>
RESIDENT: <created | updated | unchanged>
Context reload: <required (comma-separated plugin names) | no>
Sibling hermits: <one or more of the following per sibling, space-separated, or "none">
  <name vOLD->vNEW>           (confirmed by finalizer — only from siblings_confirmed)
  <name current>              (no version gap)
  <name block-drifted>        (no gap but CLAUDE-APPEND differs from template — advisory only, not
Read more
Ships withclaude-code-hermit

If you know Claude Tag, the idea will feel familiar: hand Claude work through a channel, such as Discord, Telegram, or your custom integration, and get results back there.

Get the whole plugin

Other skills on claude-code-hermit.