{"id":49141432,"url":"https://github.com/voidborne-d/hermit-agent","last_synced_at":"2026-04-27T07:01:11.702Z","repository":{"id":352926272,"uuid":"1217240042","full_name":"voidborne-d/hermit-agent","owner":"voidborne-d","description":"A Telegram-connected Claude Code agent bootstrap. Borrow the shell, bring your own body. 寄居在 Claude Code 上的 Telegram agent。","archived":false,"fork":false,"pushed_at":"2026-04-24T02:49:34.000Z","size":260,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-25T05:02:40.284Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/voidborne-d.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-21T17:27:34.000Z","updated_at":"2026-04-24T02:49:38.000Z","dependencies_parsed_at":null,"dependency_job_id":"a3e1062f-8e03-42df-a93c-93f61039f643","html_url":"https://github.com/voidborne-d/hermit-agent","commit_stats":null,"previous_names":["voidborne-d/hermit-agent"],"tags_count":25,"template":false,"template_full_name":null,"purl":"pkg:github/voidborne-d/hermit-agent","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voidborne-d%2Fhermit-agent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voidborne-d%2Fhermit-agent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voidborne-d%2Fhermit-agent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voidborne-d%2Fhermit-agent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/voidborne-d","download_url":"https://codeload.github.com/voidborne-d/hermit-agent/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voidborne-d%2Fhermit-agent/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32287398,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-25T18:29:39.964Z","status":"online","status_checked_at":"2026-04-26T02:00:05.962Z","response_time":129,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-22T01:04:44.971Z","updated_at":"2026-04-26T06:01:04.003Z","avatar_url":"https://github.com/voidborne-d.png","language":"JavaScript","readme":"\u003cdiv align=\"center\"\u003e\n\n\u003cimg src=\"assets/logo.png\" width=\"200\" alt=\"Hermit Agent logo\"/\u003e\n\n# Hermit Agent\n\n**Not a standalone agent framework — a hermit crab that lodges inside Claude Code. One command bootstraps a Telegram-connected Claude Code agent with persona, long-term memory, scheduler, and browser automation.**\n\n[English](README.md) · [中文](README.zh-CN.md)\n\n[![npm](https://img.shields.io/npm/v/create-hermit-agent?style=flat-square)](https://www.npmjs.com/package/create-hermit-agent)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow?style=flat-square)](LICENSE)\n[![Node 18+](https://img.shields.io/badge/node-18%2B-green?style=flat-square)](https://nodejs.org)\n[![macOS](https://img.shields.io/badge/platform-macOS-blue?style=flat-square)](https://www.apple.com/macos/)\n[![Claude Code](https://img.shields.io/badge/Claude_Code-required-orange?style=flat-square)](https://docs.claude.com/claude-code)\n\n\u003c/div\u003e\n\n---\n\n## Why a hermit crab?\n\nClaude Code closes its third-party subscription surface, so I built an agent that **lodges inside Claude Code itself** — fusing the best ideas from three agent-harness frameworks.\n\n| Borrowed from | What it contributed |\n|---|---|\n| **[Claude Code](https://docs.claude.com/claude-code)** | The shell. Every agent literally runs inside `claude --dangerously-skip-permissions`. Plugins, MCP, tools, hooks — all native, nothing reimplemented. |\n| **OpenClaw** | Self-managed-browser pattern. Shaped `scripts/chrome-launcher.sh`, `scripts/browser-lock.sh`, per-agent Chrome profile + CDP reuse, stealth-wrapped Playwright. |\n| **Hermas Agent** | Autonomous-evolution pattern and memory-module design. `SOUL.md` + `MEMORY.md` + daily `memory/YYYY-MM-DD.md` logs + dream-style consolidation all inherited. |\n\n---\n\n## 30-second quickstart\n\n```bash\n# Prereqs: Claude Code installed \u0026 logged in, Node 18+, brew install tmux jq, bun installed\nnpx create-hermit-agent\ncd asst \u0026\u0026 ./start.sh\n```\n\nOpen Telegram, DM the bot you just registered with @BotFather. First DM triggers a one-shot orientation — then the agent stays out of your way.\n\n\u003e **You:** remind me at 3pm to call mom  \n\u003e **asst:** scheduled — I'll ping you at 3pm today.\n\n---\n\n## Feature matrix\n\n| Capability | Detail |\n|---|---|\n| **Persona** | `SOUL / IDENTITY / USER / AGENTS / TOOLS / MEMORY.md` loaded every session. Edit the files → edit the agent. |\n| **Long-term memory** | Daily logs at `memory/YYYY-MM-DD.md`, curated long-term at `MEMORY.md`. Survives restarts. |\n| **Telegram I/O** | Native reply / react / edit / attachment download via `@claude-plugins-official/telegram`. Group-chat etiquette built in. Just say it in plain English or Chinese — \"compact the context\" / \"压缩上下文\" / \"switch to opus\" / \"restart\" / \"查状态\" — and the agent routes to the right Claude Code command. No sigil required. |\n| **Lifecycle** | `start.sh` + `restart.sh` wrap the agent in a named `tmux` session. Push alerts when context crosses 100k / 200k / ... / 950k thresholds, or when tool use gets chatty. |\n| **Scheduler** | Three tiers — session-only `cron` skill, cross-restart `HEARTBEAT.md`, OS-durable `launchd` plists. |\n| **Browser** | Dedicated Chrome profile + CDP + Playwright + stealth-init anti-detection. |\n| **Multi-agent** | `provision-agent` skill spawns siblings at `../\u003cname\u003e/` with their own bot tokens. Optional 10-min digest LaunchAgent. |\n| **Safety** | Images forced through `safe-image.sh` resize (≤1800px long edge). Tokens stored at mode 600 outside the repo. Stop hook blocks turn-end if a Telegram DM got no reply. PreToolUse hook strips markdown from outbound Telegram replies so stray `**bold**` / `# headers` don't land as literal noise in the chat. |\n\n---\n\n## Architecture\n\n```\n┌────────────── Your Mac ──────────────┐       ┌─ Telegram ─┐\n│                                       │       │            │\n│  tmux session   claude-asst           │       │  Bot API   │\n│  ┌───────────────────────────────┐   │       │            │\n│  │  claude  (the borrowed shell)  │   │       │            │\n│  │  ┌────────┐  ┌───────────────┐ │   │       │            │\n│  │  │Persona │  │ Skills + Hooks│ │   │◄─────►│ @yourbot   │\n│  │  │*.md    │  │ restart · cron│ │   │       │            │\n│  │  │memory/ │  │ provision ... │ │   │       │            │\n│  │  └────────┘  └───────────────┘ │   │       │            │\n│  │     Telegram plugin (bun)      │   │       │            │\n│  └────────────────────────────────┘   │       │            │\n│                                       │       │            │\n│  ~/.claude/channels/telegram-asst/    │       │            │\n│    (bot token — not in the repo)       │       │            │\n└───────────────────────────────────────┘       └────────────┘\n```\n\nHigher-res SVG: [assets/arch.svg](assets/arch.svg).\n\n---\n\n## Install\n\nPrereqs (macOS):\n\n- [Claude Code](https://docs.claude.com/claude-code) — installed and logged in (`claude login`)\n- Node ≥ 18\n- `brew install tmux jq`\n- `curl -fsSL https://bun.sh/install | bash`\n\nScaffold:\n\n```bash\nnpx create-hermit-agent\n```\n\nThe CLI asks for a Telegram bot token ([@BotFather](https://t.me/BotFather)) and your own Telegram user ID ([@userinfobot](https://t.me/userinfobot)). Then it creates `./asst/`, installs the Telegram plugin at project scope, and writes the token to `~/.claude/channels/telegram-asst/.env` (mode 600).\n\nStart:\n\n```bash\ncd asst \u0026\u0026 ./start.sh\n```\n\nThe agent now runs in a detached `tmux` session named `claude-asst`. DM the bot.\n\n---\n\n## First DM: asst introduces itself\n\nOn first contact, asst sends a one-shot orientation — how to talk to it, which natural-language phrases trigger built-in commands (compact, restart, switch model, status), how to spawn more agents — then deletes its own `FIRST_RUN.md` so it never greets you again.\n\n---\n\n## Spawning more agents\n\n**Don't run `npx create-hermit-agent` a second time.** Tell asst:\n\n\u003e Create a new agent called `github-bot` with token `123:ABC...`. Purpose: triage my GitHub notifications.\n\nasst's `provision-agent` skill scaffolds a sibling at `../github-bot/`, installs its plugin, starts it in a `claude-github-bot` tmux session, and replies with the new bot's `@handle`.\n\nAgents are fully independent: separate bot tokens, separate memory, separate folders.\n\n---\n\n## Customize\n\nEdit these in the agent folder:\n\n| File | What to put there |\n|---|---|\n| `IDENTITY.md` | Name, vibe, one-line purpose |\n| `USER.md` | You — pronouns, timezone, notes |\n| `AGENTS.md` | `\u003c!-- MISSION-START --\u003e` block — this agent's mission |\n| `TOOLS.md` | `\u003c!-- AGENT-SPECIFIC-START --\u003e` block — API keys, repo links, domain notes |\n\n`SOUL.md` is baseline disposition — don't edit unless you want a different personality.\n\n---\n\n## Scheduled tasks\n\nJust tell the agent what you want:\n\n\u003e Every 30 minutes, scan `memory/today.md` and flag urgent items.\n\nasst's `cron` skill handles it. Tasks that must survive restarts go through `launchd`:\n\n1. Drop a plist into your agent's `launchd/` folder — copy `launchd/cron-example.plist.tmpl`, set `Label` to `com.hermit-agent.\u003cagent\u003e.cron-\u003ctask\u003e`, and point `ProgramArguments` at whatever you want run. Wrap the real work in `scripts/with-timeout.sh 1200` — 20 min is the ceiling, not a target.\n2. Sync to the live LaunchAgents dir: `./scripts/launchd-sync.sh .` (idempotent: `LOADED` new, `RELOAD` changed, skip unchanged; `--dry-run` to preview).\n3. Confirm: `launchctl list | grep com.hermit-agent.\u003cagent\u003e`.\n\nWriting the plist alone does NOT activate it — `launchd-sync.sh` is the difference between \"generated\" and \"running\". Re-run it any time you add, edit, or rename a plist. And the timeout wrapper is there for a reason: a cron that drifted off-prompt once wedged for 12h38m and blocked three fire windows. `AGENTS.md` → \"Cron Safety\" documents the discipline.\n\n---\n\n## Multi-agent status digest\n\nThe CLI automatically installs a `launchd` coordinator the first time you run it on a machine. Every 10 minutes it pushes a digest of all hermits on the box to the coordinator's Telegram chat: 🟢 idle · 🟨 running · 🟥 stuck · ⚫ down.\n\n- One coordinator per machine. When `create-hermit-agent` detects an existing `com.hermit-agent.*.status-reporter.plist`, it skips — subsequent hermits don't stack their own jobs.\n- The first agent you install (default `asst`) is the coordinator. Its plist lives at `~/Library/LaunchAgents/com.hermit-agent.asst.status-reporter.plist`.\n- To disable: `launchctl unload ~/Library/LaunchAgents/com.hermit-agent.\u003ccoordinator\u003e.status-reporter.plist`.\n- To hand off to a different coordinator: unload the old plist, delete it, re-run `create-hermit-agent` from a new agent (or manually `cp launchd/status-reporter.plist ~/Library/LaunchAgents/com.hermit-agent.\u003cnew\u003e.status-reporter.plist \u0026\u0026 launchctl load ...`).\n\n---\n\n## Troubleshooting\n\n| Symptom | Fix |\n|---|---|\n| Agent doesn't reply | `tmux attach -t claude-\u003cname\u003e` to see live state. Also check `restart.log`, `claude-agent.log`. |\n| Plugin subprocess missing | `./restart.sh` auto-retries once. Still broken? Check `~/.claude/channels/telegram-\u003cname\u003e/.env` is mode 600 with the token. |\n| `exceeds the dimension limit` image crash | All image Reads MUST go through `scripts/safe-image.sh` first. Recover with restart + `/compact`. |\n| `claude plugin install failed` | Ensure `claude` is on PATH and logged in (`claude login`). |\n| Context bloat | Ask on Telegram — \"compact\" / \"压缩上下文\" / \"精简一下\" — the agent fires `/compact` via tmux. Or type `/compact` directly in the pane. |\n| Bot silent on a fresh Mac | Claude Code may have raised the \"trust this folder\" or \"allow dangerous mode\" TUI dialog — which blocks startup. The CLI pre-acknowledges both, but if something went wrong, `tmux attach -t claude-\u003cname\u003e`, press Enter to dismiss any pending dialog, then detach with Ctrl-b d. |\n\n---\n\n## FAQ\n\n**Do I need to pre-install the Telegram plugin in Claude Code?**  \nNo. `create-hermit-agent` runs `claude plugin install telegram@claude-plugins-official -s project` for every new agent. First install downloads to `~/.claude/plugins/cache/`; subsequent agents register against the cache per-project. Zero manual plugin setup.\n\n**Linux / Windows support?**  \nmacOS only. `launchctl`, `sips`, `tmux` are all macOS-shaped. PRs welcome.\n\n**Can multiple agents share a bot token?**  \nNo. Telegram's Bot API routes each bot's updates to exactly one listener. Sharing causes message hijacking. Each agent needs its own `@BotFather`-issued token.\n\n**Where's the bot token stored?**  \n`~/.claude/channels/telegram-\u003cname\u003e/.env` (mode 600, outside the project). Also echoed into `.claude/settings.local.json` (gitignored).\n\n**Does the first DM trigger a pairing code?**  \nNo. The CLI pre-populates `~/.claude/channels/telegram-\u003cname\u003e/access.json` with your user ID pre-allowlisted, so your own DMs pass through from message one. Strangers who find the bot's `@handle` still get the standard pairing challenge (`dmPolicy: \"pairing\"`), not silent delivery.\n\n**How do I delete an agent cleanly?**\n\n```bash\ntmux kill-session -t claude-\u003cname\u003e\nrm -rf \u003cagent-folder\u003e\nrm -rf ~/.claude/channels/telegram-\u003cname\u003e\n```\n\nAlso revoke the bot via `@BotFather` if you're done with it.\n\n---\n\n## License\n\n[MIT](LICENSE).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoidborne-d%2Fhermit-agent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvoidborne-d%2Fhermit-agent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoidborne-d%2Fhermit-agent/lists"}