From claude-code-hermit
Initializes or resumes work sessions by loading OPERATOR.md and SHELL.md context, reading runtime.json state, handling locks, interrupted recoveries, and unclean shutdowns. Invoke at session start.
npx claudepluginhub gtapps/claude-code-hermit --plugin claude-code-homeassistant-hermitThis skill uses the workspace's default tool permissions.
Notify the operator per the channel policy in CLAUDE.md (§ Operator Notification).
Starts or resumes work sessions with full context loading, task planning, progress tracking, blocker handling, execution, and finalization including status, lessons, and changes. Use at work start.
Bootstraps Claude Code sessions by organizing files, generating CLAUDE.md, managing soul purpose lifecycle with completion protocol and context harvesting. Use /start or /init.
Performs internal session startup checks: git status, Plans.md tasks, AGENTS.md roles, file sizes, and harness-mem resume packs. For startup workflows only.
Share bugs, ideas, or general feedback.
Notify the operator per the channel policy in CLAUDE.md (§ Operator Notification).
When starting a new session:
All state lives under .claude-code-hermit/ in the project root.
Read .claude-code-hermit/config.json for agent identity settings (agent_name, language)
If the SessionStart hook output above includes "---Upgrade Available---", mention it to the operator. Do NOT block session start.
Read state/runtime.json for lifecycle state. This is the single source of truth — never parse SHELL.md Status: for decisions.
state/.lifecycle.lock non-blocking. If held by another process (hermit-start.py, hermit-stop.py), tell the operator "A lifecycle operation is in progress — wait for it to complete" and abort.transition is not null, use claude-code-hermit:session-mgr to resume the interrupted operation:
transition == "archiving" + target file missing → re-run archivetransition == "archiving" + target file exists → skip to SHELL.md cleanuptransition == "cleaning" → re-run SHELL.md cleanuplast_error == "unclean_shutdown":
session_state to waiting and waiting_reason to "unclean_shutdown" in runtime.json, notify the operator via channel: "Came back up after unclean shutdown. Previous task: [task from SHELL.md, or 'unknown']. Reply with (1) to archive as partial and start fresh, or (2) to resume where we left off." Then stop — channel-responder handles the reply. If heartbeat.waiting_timeout is set, heartbeat will auto-transition to idle after timeout elapses with no channel activity.partial and start fresh, (b) Resume as-is.last_error after the operator decides.session_state == "dead_process": same flow as unclean shutdown above. Set waiting_reason to "dead_process" in runtime.json. Message: "Process died unexpectedly. Previous task: [task from SHELL.md, or 'unknown']. Reply with (1) to archive as partial and start fresh, or (2) to resume where we left off."session_state is idle → ready for new task. If in_progress or waiting → existing session, offer resume.
3b. Watch registry reset. Read state/monitors.runtime.json and clear all entries unconditionally — watches are session-scoped, so any previous entries are stale. If the file is missing, skip. This runs on every session start (new, resume, or crash recovery) before any watch registration occurs.Session state routing — evaluate the fast-path gate before spawning session-mgr.
Fast path (skip session-mgr) — ALL five must be true:
runtime.json was found and parsed successfully (not missing, not malformed)session_state ∈ {in_progress, idle, waiting}transition is nulllast_error is null.claude-code-hermit/sessions/SHELL.md existsIf all five are true: SHELL.md content is already available from the startup hook injection. Proceed directly to step 4b with the data already in hand. Do not spawn session-mgr. Read session_id from runtime.json — if set and SHELL.md **ID:** still contains the placeholder S-NNN, update it to the actual session ID (e.g., S-009) in-context without spawning session-mgr.
Slow path (spawn session-mgr) — any condition above fails:
runtime.json is missing or malformed → first run or corrupted statesession_state is dead_process or any unrecognized valuetransition is not null → interrupted transition recovery neededlast_error is not null → error recovery neededSHELL.md is missing → session-mgr must create it from templateOn the slow path: use claude-code-hermit:session-mgr to check session state, handle recovery, and create/update SHELL.md as needed.
4b. If runtime.json session_state is idle (session between tasks — SHELL.md exists but no active task):
claude-code-hermit:session-mgr to set Status back to in_progress (cosmetic in SHELL.md) and update runtime.json session_state to in_progress. Fill in Task. After confirming the plan with the operator, create native Tasks (TaskCreate) for each step.Read .claude-code-hermit/OPERATOR.md for project context and constraints
5b. Baseline audit offer (first session only).
Check for .claude-code-hermit/.baseline-pending. If absent, skip this step entirely.
If present:
Notify per channel policy (always-on: channel; interactive: inline). Operator message:
"First session on this project. Want me to run a one-time audit using the plugins you installed at hatch? It'll surface CLAUDE.md gaps and automation opportunities. (yes / no)"
In always-on mode, only this single prompt and the final summary go through the channel. Plugin invocations run in-agent without channel chatter.
Handle response:
.claude-code-hermit/.baseline-pending immediately (before invoking any skill). Marker semantic = "we haven't offered yet." Once consented, the offer is consumed regardless of invocation outcome. If a skill crashes mid-run, the operator re-invokes it manually; we do not re-offer on next session. Then proceed to step 3.Pre-flight: scan config.json scheduled_checks for any entry in the fixed list below with enabled: true. If none qualify, delete the marker silently and continue to step 6.
For each skill in the fixed list below, in order:
/claude-md-management:claude-md-improver/claude-code-setup:claude-automation-recommenderDo NOT invoke /claude-md-management:revise-claude-md — it is a session-trigger skill, not an audit, and runs separately via its own scheduled_checks entry.
For each audit skill:
config.json scheduled_checks for a matching skill field with enabled: true. If absent or disabled, skip silently./claude-code-hermit:proposal-create as one proposal per plugin invocation, passing Evidence Source: operator-request and with source: operator-request in the frontmatter. (Not auto-detected — that routes through reflection-judge expecting cross-session evidence citations the audit cannot provide.) Write the Problem section as a prioritized summary of all findings (top 3 inline, remainder as a bulleted list).Surface a single-line summary to the operator (channel in always-on, inline otherwise):
"Baseline audit done. {N} proposals queued: PROP-XXX[, PROP-YYY]. Review with /claude-code-hermit:proposal-list."
Guard: the marker is the one-shot gate. Absent marker → this step never fires.
Note for maintainers: md-audit and automation-recommender are already scheduled on 7-day intervals via scheduled_checks. This step pulls the first run forward to day 1 with operator consent — it is not an independent execution path.
Check if .claude-code-hermit/sessions/NEXT-TASK.md exists. If it does:
NEXT-TASK.md and proceed with their taskNEXT-TASK.md after it has been presented (whether accepted or not)Scan .claude-code-hermit/proposals/ for files with Source: auto-detected and Status: proposed. If any exist, mention: "There are N unreviewed auto-detected proposal(s). Review with /proposal-list when ready." Do NOT block the session — this is a one-line notification only.
7b. Interactive morning brief. If config.always_on is false AND config.routines contains an enabled entry with skill containing brief --morning: run the morning brief inline — generate a brief emphasizing where things stand, pending proposals, and what's on deck. No dedup needed — interactive sessions are short-lived.
If agent_name is set, use it in the greeting (e.g., "Atlas reporting in." or "{name} a reportar." if language is pt). If language is set, communicate with the operator in that language for the rest of the session.
In always-on mode: if no recovery message was sent in step 3, notify the operator via channel with a startup ping (1 line): "[name or 'Hermit'] online. Reviewing session state." Skip this ping if a recovery question was already sent — the recovery message is the boot signal.
If resuming an existing session (runtime.json session_state is in_progress or waiting):
TaskList to see current plan steps. Present the current task, progress (completed/remaining tasks), and blockers.blocked: suggest running /debug to diagnose tool/hook failures before re-attempting the blocked worksession_state is idle):claude-code-hermit:session-mgr to update SHELL.md: set Status to in_progress (cosmetic), fill Task. Update runtime.json session_state to in_progress. After confirming the plan, create native Tasks for each step.If starting a new session:
claude-code-hermit:session-mgr to create the session with the task. After confirming the plan, create native Tasks (TaskCreate) for each step.Tags: field in SHELL.md. If skipped, leave blank.ask_budget from the config read in step 1. If ask_budget is true:
Budget: $X.XX to SHELL.mdask_budget to false in config.json, leave Budget blankask_budget is false: skip the budget prompt silently.
11b. Watch registration. If config.monitors exists and has enabled entries, invoke
/claude-code-hermit:watch start to register them. (Registry was already cleared in
step 3b.) This is silent — do not prompt the operator about watch registration..claude-code-hermit/OPERATOR.md (always).claude-code-hermit/sessions/SHELL.md (if exists).claude-code-hermit/sessions/S-*-REPORT.md (for continuity — only the latest one).claude-code-hermit/state/runtime.json (always — for lifecycle state)Do NOT load all session reports — only the most recent one.