hermes - 💡(How to fix) Fix [i18n] Thai Translation: User Guide Part 3 [1 participants]
ON THIS PAGE
Recommended Tools
×6Utilities matched from this issue’s tags and category — try them while you read without losing context.
GitHub issue graph ai analysis
Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.
The report is written in English Markdown for sharing and archival.
Helpful · Quick feedback
โมเดลความปลอดภัยประกอบด้วยเจ็ดชั้น:
- User authorization - ใครสามารถพูดคุยกับ agent ได้ (allowlists, DM pairing)
- Dangerous command approval - การตรวจสอบคำสั่งอันตรายโดยมนุษย์ (human-in-the-loop) สำหรับการดำเนินการที่ทำลายล้าง
- Container isolation - การแยกส่วนด้วย Docker/Singularity/Modal sandboxing พร้อมการตั้งค่าที่แข็งแกร่ง (hardened settings)
- MCP credential filtering - การแยกส่วนตัวแปรสภาพแวดล้อม (environment variable isolation) สำหรับ MCP subprocesses
- Context file scanning - การตรวจจับ prompt injection ในไฟล์โปรเจกต์
- Cross-session isolation - เซสชันไม่สามารถเข้าถึงข้อมูลหรือสถานะของกันและกันได้; เส้นทางจัดเก็บ cron job ถูกเสริมความแข็งแกร่งเพื่อป้องกัน path traversal attacks
- Input sanitization - พารามิเตอร์ working directory ใน backends ของเครื่องมือ terminal จะถูกตรวจสอบกับ allowlist เพื่อป้องกัน shell injection
Root Cause
โมเดลความปลอดภัยประกอบด้วยเจ็ดชั้น:
- User authorization - ใครสามารถพูดคุยกับ agent ได้ (allowlists, DM pairing)
- Dangerous command approval - การตรวจสอบคำสั่งอันตรายโดยมนุษย์ (human-in-the-loop) สำหรับการดำเนินการที่ทำลายล้าง
- Container isolation - การแยกส่วนด้วย Docker/Singularity/Modal sandboxing พร้อมการตั้งค่าที่แข็งแกร่ง (hardened settings)
- MCP credential filtering - การแยกส่วนตัวแปรสภาพแวดล้อม (environment variable isolation) สำหรับ MCP subprocesses
- Context file scanning - การตรวจจับ prompt injection ในไฟล์โปรเจกต์
- Cross-session isolation - เซสชันไม่สามารถเข้าถึงข้อมูลหรือสถานะของกันและกันได้; เส้นทางจัดเก็บ cron job ถูกเสริมความแข็งแกร่งเพื่อป้องกัน path traversal attacks
- Input sanitization - พารามิเตอร์ working directory ใน backends ของเครื่องมือ terminal จะถูกตรวจสอบกับ allowlist เพื่อป้องกัน shell injection
Fix Action
Fix / Workaround
- Set explicit allowlists - ห้ามใช้
GATEWAY_ALLOW_ALL_USERS=trueใน Production - Use container backend - ตั้งค่า
terminal.backend: dockerใน config.yaml - Restrict resource limits - ตั้งค่า CPU, memory, และ disk limits ให้เหมาะสม
- Store secrets securely - เก็บ API keys ใน
~/.hermes/.envด้วยสิทธิ์ไฟล์ที่เหมาะสม - Enable DM pairing - ใช้ pairing codes แทนการ hardcoding user IDs เมื่อเป็นไปได้
- Review command allowlist - ตรวจสอบ
command_allowlistใน config.yaml เป็นระยะ - Set
MESSAGING_CWD- อย่าปล่อยให้ agent ทำงานจาก directory ที่ละเอียดอ่อน - Run as non-root - ห้ามรัน gateway ในฐานะ root
- Monitor logs - ตรวจสอบ
~/.hermes/logs/สำหรับความพยายามเข้าถึงที่ไม่ได้รับอนุญาต - Keep updated - รัน
hermes updateเป็นประจำเพื่อรับ security patches
- File tools -
write_fileและpatch - Destructive terminal commands -
rm,mv,sed -i,truncate,shred, การเปลี่ยนเส้นทาง output (>) และgit reset/clean/checkout
- 4270a8c 2026-03-16 04:36 before patch (1 file, +1/-0)
- eaf4c1f 2026-03-16 04:35 before write_file
- b3f9d2e 2026-03-16 04:34 before terminal: sed -i s/old/new/ config.py (1 file, +1/-1)
Code Example
# Resume the most recent CLI session
hermes --continue
hermes -c
# Or with the chat subcommand
hermes chat --continue
hermes chat -c
---
# Resume a named session
hermes -c "my project"
# If there are lineage variants (my project, my project #2, my project #3),
# this automatically resumes the most recent one
hermes -c "my project" # → resumes "my project #3"
---
# Resume a specific session by ID
hermes --resume 20250305_091523_a1b2c3d4
hermes -r 20250305_091523_a1b2c3d4
# Resume by title
hermes --resume "refactoring auth"
# Or with the chat subcommand
hermes chat --resume 20250305_091523_a1b2c3d4
---
display:
resume_display: minimal # default: full
---
/title my research project
---
hermes sessions rename 20250305_091523_a1b2c3d4 "refactoring auth module"
---
"my project" → "my project #2" → "my project #3"
---
# List recent sessions (default: last 20)
hermes sessions list
# Filter by platform
hermes sessions list --source telegram
# Show more sessions
hermes sessions list --limit 50
---
Title Preview Last Active ID
────────────────────────────────────────────────────────────────────────────────────────────────
refactoring auth Help me refactor the auth module please 2h ago 20250305_091523_a
my project #3 Can you check the test failures? yesterday 20250304_143022_e
— What's the weather in Las Vegas? 3d ago 20250303_101500_f
---
Preview Last Active Src ID
──────────────────────────────────────────────────────────────────────────────────────
Help me refactor the auth module please 2h ago cli 20250305_091523_a
What's the weather in Las Vegas? 3d ago tele 20250303_101500_f
---
# Export all sessions to a JSONL file
hermes sessions export backup.jsonl
# Export sessions from a specific platform
hermes sessions export telegram-history.jsonl --source telegram
# Export a single session
hermes sessions export session.jsonl --session-id 20250305_091523_a1b2c3d4
---
# Delete a specific session (with confirmation)
hermes sessions delete 20250305_091523_a1b2c3d4
# Delete without confirmation
hermes sessions delete 20250305_091523_a1b2c3d4 --yes
---
# Set or change a session's title
hermes sessions rename 20250305_091523_a1b2c3d4 "debugging auth flow"
# Multi-word titles don't need quotes in the CLI
hermes sessions rename 20250305_091523_a1b2c3d4 debugging auth flow
---
# Delete ended sessions older than 90 days (default)
hermes sessions prune
# Custom age threshold
hermes sessions prune --older-than 30
# Only prune sessions from a specific platform
hermes sessions prune --source telegram --older-than 60
# Skip confirmation
hermes sessions prune --older-than 30 --yes
---
hermes sessions stats
---
Total sessions: 142
Total messages: 3847
cli: 89 sessions
telegram: 38 sessions
discord: 15 sessions
Database size: 12.4 MB
---
group_sessions_per_user: false
---
# Prune sessions older than 90 days
hermes sessions prune
# Delete a specific session
hermes sessions delete <session_id>
# Export before pruning (backup)
hermes sessions export backup.jsonl
hermes sessions prune --older-than 30 --yes
---
approvals:
mode: manual # manual | smart | off
timeout: 60 # seconds to wait for user response (default: 60)
---
> /yolo
⚡ YOLO mode ON — all commands auto-approved. Use with caution.
> /yolo
⚠ YOLO mode OFF — dangerous commands will require approval.
---
approvals:
timeout: 60 # seconds (default: 60)
---
⚠️ DANGEROUS COMMAND: recursive delete
rm -rf /tmp/old-project
[o]nce | [s]ession | [a]lways | [d]eny
Choice [o/s/a/D]:
---
# Permanently allowed dangerous command patterns
command_allowlist:
- rm
- systemctl
---
# Platform-specific allowlists
TELEGRAM_ALLOWED_USERS=123456789,987654321
DISCORD_ALLOWED_USERS=111222333444555666
WHATSAPP_ALLOWED_USERS=15551234567
SLACK_ALLOWED_USERS=U01ABC123
# Cross-platform allowlist (checked for all platforms)
GATEWAY_ALLOWED_USERS=123456789
# Per-platform allow-all (use with caution)
DISCORD_ALLOW_ALL_USERS=true
# Global allow-all (use with extreme caution)
GATEWAY_ALLOW_ALL_USERS=true
---
No user allowlists configured. All unauthorized users will be denied.
Set GATEWAY_ALLOW_ALL_USERS=true in ~/.hermes/.env to allow open access,
or configure platform allowlists (e.g., TELEGRAM_ALLOWED_USERS=your_id).
---
unauthorized_dm_behavior: pair
whatsapp:
unauthorized_dm_behavior: ignore
---
# List pending and approved users
hermes pairing list
# Approve a pairing code
hermes pairing approve telegram ABC12DEF
# Revoke a user's access
hermes pairing revoke telegram 123456789
# Clear all pending codes
hermes pairing clear-pending
---
_SECURITY_ARGS = [
"--cap-drop", "ALL", # Drop ALL Linux capabilities
"--cap-add", "DAC_OVERRIDE", # Root can write to bind-mounted dirs
"--cap-add", "CHOWN", # Package managers need file ownership
"--cap-add", "FOWNER", # Package managers need file ownership
"--security-opt", "no-new-privileges", # Block privilege escalation
"--pids-limit", "256", # Limit process count
"--tmpfs", "/tmp:rw,nosuid,size=512m", # Size-limited /tmp
"--tmpfs", "/var/tmp:rw,noexec,nosuid,size=256m", # No-exec /var/tmp
"--tmpfs", "/run:rw,noexec,nosuid,size=64m", # No-exec /run
]
---
terminal:
backend: docker
docker_image: "nikolaik/python-nodejs:python3.11-nodejs20"
docker_forward_env: [] # Explicit allowlist only; empty keeps secrets out of the container
container_cpu: 1 # CPU cores
container_memory: 5120 # MB (default 5GB)
container_disk: 51200 # MB (default 50GB, requires overlay2 on XFS)
container_persistent: true # Persist filesystem across sessions
---
# In a skill's SKILL.md frontmatter
required_environment_variables:
- name: TENOR_API_KEY
prompt: Tenor API key
help: Get a key from https://developers.google.com/tenor
---
terminal:
env_passthrough:
- MY_CUSTOM_KEY
- ANOTHER_TOKEN
---
required_credential_files:
- path: google_token.json
description: Google OAuth2 token (created by setup script)
- path: google_client_secret.json
description: Google OAuth2 client credentials
---
terminal:
credential_files:
- google_token.json
- my_custom_oauth_token.json
---
PATH, HOME, USER, LANG, LC_ALL, TERM, SHELL, TMPDIR
---
mcp_servers:
github:
command: "npx"
args: ["-y", "@modelcontextprotocol/server-github"]
env:
GITHUB_PERSONAL_ACCESS_TOKEN: "ghp_..." # Only this is passed
---
# In ~/.hermes/config.yaml
security:
website_blocklist:
enabled: true
domains:
- "*.internal.company.com"
- "admin.example.com"
shared_files:
- "/etc/hermes/blocked-sites.txt"
---
# In ~/.hermes/config.yaml
security:
tirith_enabled: true # Enable/disable tirith scanning (default: true)
tirith_path: "tirith" # Path to tirith binary (default: PATH lookup)
tirith_timeout: 5 # Subprocess timeout in seconds
tirith_fail_open: true # Allow execution when tirith is unavailable (default: true)
---
[BLOCKED: AGENTS.md contained potential prompt injection (prompt_injection). Content not loaded.]
---
# Set proper permissions on the .env file
chmod 600 ~/.hermes/.env
# Keep separate keys for different services
# Never commit .env files to version control
---
terminal:
backend: ssh
ssh_host: "agent-worker.local"
ssh_user: "hermes"
ssh_key: "~/.ssh/hermes_agent_key"
---
mkdir -p ~/.hermes
docker run -it --rm \
-v ~/.hermes:/opt/data \
nousresearch/hermes-agent setup
---
docker run -d \
--name hermes \
--restart unless-stopped \
-v ~/.hermes:/opt/data \
-p 8642:8642 \
nousresearch/hermes-agent gateway run
---
docker run -d \
--name hermes-dashboard \
--restart unless-stopped \
-v ~/.hermes:/opt/data \
-p 9119:9119 \
-e GATEWAY_HEALTH_URL=http://$HOST_IP:8642 \
nousresearch/hermes-agent dashboard
---
docker run -it --rm \
-v ~/.hermes:/opt/data \
nousresearch/hermes-agent
---
docker run -it --rm \
-v ~/.hermes:/opt/data \
-e ANTHROPIC_API_KEY="sk-ant-..." \
-e OPENAI_API_KEY="sk-..." \
nousresearch/hermes-agent
---
services:
hermes:
image: nousresearch/hermes-agent:latest
container_name: hermes
restart: unless-stopped
command: gateway run
ports:
- "8642:8642"
volumes:
- ~/.hermes:/opt/data
networks:
- hermes-net
# Uncomment to forward specific env vars instead of using .env file:
# environment:
# - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
# - OPENAI_API_KEY=${OPENAI_API_KEY}
# - TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
deploy:
resources:
limits:
memory: 4G
cpus: "2.0"
dashboard:
image: nousresearch/hermes-agent:latest
container_name: hermes-dashboard
restart: unless-stopped
command: dashboard --host 0.0.0.0
ports:
- "9119:9119"
volumes:
- ~/.hermes:/opt/data
environment:
- GATEWAY_HEALTH_URL=http://hermes:8642
networks:
- hermes-net
depends_on:
- hermes
deploy:
resources:
limits:
memory: 512M
cpus: "0.5"
networks:
hermes-net:
driver: bridge
---
docker run -d \
--name hermes \
--restart unless-stopped \
--memory=4g --cpus=2 \
-v ~/.hermes:/opt/data \
nousresearch/hermes-agent gateway run
---
docker pull nousresearch/hermes-agent:latest
docker rm -f hermes
docker run -d \
--name hermes \
--restart unless-stopped \
-v ~/.hermes:/opt/data \
nousresearch/hermes-agent gateway run
---
docker compose pull
docker compose up -d
---
chmod -R 755 ~/.hermes
---
docker run -d \
--name hermes \
--shm-size=1g \
-v ~/.hermes:/opt/data \
nousresearch/hermes-agent gateway run
---
docker restart hermes
---
docker logs --tail 50 hermes # logs ล่าสุด
docker run -it --rm nousresearch/hermes-agent:latest version # ตรวจสอบเวอร์ชัน
docker stats hermes # การใช้ทรัพยากร
---
# From the main repo root
cd /path/to/your/repo
# Create a new branch and worktree in ../repo-feature
git worktree add ../repo-feature feature/hermes-experiment
---
cd ../repo-feature
# Start Hermes in the worktree
hermes
---
cd /path/to/your/repo
git worktree add ../repo-experiment-a feature/hermes-a
git worktree add ../repo-experiment-b feature/hermes-b
---
# Terminal 1
cd ../repo-experiment-a
hermes
# Terminal 2
cd ../repo-experiment-b
hermes
---
cd /path/to/your/repo
# Remove the worktree directory and its reference
git worktree remove ../repo-feature
---
cd /path/to/your/repo
hermes -w
---
hermes -w -q "Fix issue #123"
---
flowchart LR
user["User command\n(hermes, gateway)"]
agent["AIAgent\n(run_agent.py)"]
tools["File & terminal tools"]
cpMgr["CheckpointManager"]
shadowRepo["Shadow git repo\n~/.hermes/checkpoints/<hash>"]
user --> agent
agent -->|"tool call"| tools
tools -->|"before mutate\nensure_checkpoint()"| cpMgr
cpMgr -->|"git add/commit"| shadowRepo
cpMgr -->|"OK / skipped"| tools
tools -->|"apply changes"| agent
---
checkpoints:
enabled: true # master switch (default: true)
max_snapshots: 50 # max checkpoints per directory
---
checkpoints:
enabled: false
---
/rollback
---
📸 Checkpoints for /path/to/project:
1. 4270a8c 2026-03-16 04:36 before patch (1 file, +1/-0)
2. eaf4c1f 2026-03-16 04:35 before write_file
3. b3f9d2e 2026-03-16 04:34 before terminal: sed -i s/old/new/ config.py (1 file, +1/-1)
/rollback <N> restore to checkpoint N
/rollback diff <N> preview changes since checkpoint N
/rollback <N> <file> restore a single file from checkpoint N
---
/rollback diff 1
---
test.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test.py b/test.py
--- a/test.py
+++ b/test.py
@@ -1 +1 @@
-print('original content')
+print('modified content')
---
/rollback 1
---
✅ Restored to checkpoint 4270a8c5: before patch
A pre-rollback snapshot was saved automatically.
(^_^)b Undid 4 message(s). Removed: "Now update test.py to ..."
4 message(s) remaining in history.
Chat turn undone to match restored file state.
---
/rollback 1 src/broken_file.py
---
~/.hermes/checkpoints/
├── <hash1>/ # shadow git repo for one working directory
├── <hash2>/
└── ...RAW_BUFFERClick to expand / collapse
📄 user-guide/sessions.md
sidebar_position: 7 title: "Sessions" description: "Session persistence, resume, search, management, and per-platform session tracking"
Sessions
Hermes Agent จะบันทึกการสนทนาทุกครั้งเป็นเซสชัน (session) โดยอัตโนมัติ เซสชันช่วยให้สามารถดำเนินการต่อการสนทนา (conversation resume), การค้นหาข้ามเซสชัน (cross-session search), และการจัดการประวัติการสนทนาทั้งหมดได้
How Sessions Work
การสนทนาทุกครั้ง ไม่ว่าจะมาจาก CLI, Telegram, Discord, Slack, WhatsApp, Signal, Matrix, หรือแพลตฟอร์มการส่งข้อความอื่น ๆ จะถูกจัดเก็บเป็นเซสชันพร้อมประวัติข้อความทั้งหมด เซสชันเหล่านี้จะถูกติดตามในระบบเสริมกันสองส่วน:
- SQLite database (
~/.hermes/state.db) - metadata ของเซสชันที่มีโครงสร้าง พร้อมการค้นหาแบบ full-text search ด้วย FTS5 - JSONL transcripts (
~/.hermes/sessions/) - ข้อมูล transcript การสนทนาดิบ รวมถึง tool calls (gateway)
SQLite database จะจัดเก็บข้อมูลดังนี้:
- Session ID, source platform, user ID
- Session title (ชื่อที่เฉพาะเจาะจงและอ่านได้ด้วยมนุษย์)
- ชื่อและ configuration ของ Model
- Snapshot ของ system prompt
- ประวัติข้อความทั้งหมด (role, content, tool calls, tool results)
- Token counts (input/output)
- Timestamps (started_at, ended_at)
- Parent session ID (สำหรับการแยกเซสชันที่เกิดจากการบีบอัดข้อมูล)
Session Sources
แต่ละเซสชันจะถูกติดป้ายกำกับด้วย source platform ของมัน:
| Source | Description |
|---|---|
cli | CLI แบบโต้ตอบ (hermes หรือ hermes chat) |
telegram | Messenger Telegram |
discord | Discord server/DM |
slack | Slack workspace |
whatsapp | Messenger WhatsApp |
signal | Messenger Signal |
matrix | ห้องและ DM ของ Matrix |
mattermost | ช่องของ Mattermost |
email | อีเมล (IMAP/SMTP) |
sms | SMS ผ่าน Twilio |
dingtalk | Messenger DingTalk |
feishu | Messenger Feishu/Lark |
wecom | WeCom (WeChat Work) |
weixin | Weixin (WeChat ส่วนตัว) |
bluebubbles | Apple iMessage ผ่าน BlueBubbles macOS server |
qqbot | QQ Bot (Tencent QQ) ผ่าน Official API v2 |
homeassistant | การสนทนาของ Home Assistant |
webhook | Incoming webhooks |
api-server | คำขอจาก API server |
acp | การรวมระบบ ACP editor |
cron | งาน cron ที่กำหนดเวลา |
batch | การรันงานแบบ batch |
CLI Session Resume
สามารถดำเนินการต่อการสนทนาครั้งก่อนจาก CLI ได้โดยใช้ --continue หรือ --resume:
Continue Last Session
# Resume the most recent CLI session
hermes --continue
hermes -c
# Or with the chat subcommand
hermes chat --continue
hermes chat -cคำสั่งนี้จะค้นหา cli session ล่าสุดจาก SQLite database และโหลดประวัติการสนทนาทั้งหมด
Resume by Name
หากคุณได้ตั้งชื่อให้กับเซสชัน (ดู Session Naming ด้านล่าง) คุณสามารถดำเนินการต่อได้โดยใช้ชื่อ:
# Resume a named session
hermes -c "my project"
# If there are lineage variants (my project, my project #2, my project #3),
# this automatically resumes the most recent one
hermes -c "my project" # → resumes "my project #3"Resume Specific Session
# Resume a specific session by ID
hermes --resume 20250305_091523_a1b2c3d4
hermes -r 20250305_091523_a1b2c3d4
# Resume by title
hermes --resume "refactoring auth"
# Or with the chat subcommand
hermes chat --resume 20250305_091523_a1b2c3d4Session ID จะแสดงเมื่อคุณออกจาก CLI session และสามารถค้นหาได้ด้วย hermes sessions list
Conversation Recap on Resume
เมื่อคุณดำเนินการต่อเซสชัน (resume) Hermes จะแสดงสรุปสั้น ๆ ของการสนทนาครั้งก่อนในแผงสไตล์ (styled panel) ก่อนหน้า prompt สำหรับป้อนข้อมูล:
<img className="docs-terminal-figure" src="/img/docs/session-recap.svg" alt="Stylized preview of the Previous Conversation recap panel shown when resuming a Hermes session." /> <p className="docs-figure-caption">โหมด resume จะแสดงแผงสรุปสั้น ๆ พร้อมการโต้ตอบล่าสุดของผู้ใช้และผู้ช่วย ก่อนที่จะนำคุณกลับไปยัง prompt ที่ใช้งานจริง</p>ส่วนสรุปนี้:
- แสดง ข้อความของผู้ใช้ (● สีทอง) และ การตอบกลับของผู้ช่วย (◆ สีเขียว)
- ตัดทอน ข้อความยาว ๆ (300 ตัวอักษรสำหรับผู้ใช้, 200 ตัวอักษร / 3 บรรทัดสำหรับผู้ช่วย)
- ยุบ tool calls ให้เป็นจำนวนพร้อมชื่อ tool (เช่น
[3 tool calls: terminal, web_search]) - ซ่อน system messages, tool results, และ internal reasoning
- จำกัด ที่ 10 การโต้ตอบล่าสุด พร้อมตัวบ่งชี้ "... N earlier messages ..."
- ใช้ สไตล์ที่จางลง เพื่อแยกความแตกต่างจากการสนทนาที่กำลังใช้งาน
หากต้องการปิดการแสดงสรุปและคงพฤติกรรมแบบ minimal one-liner ให้ตั้งค่าใน ~/.hermes/config.yaml:
display:
resume_display: minimal # default: full:::tip
Session IDs มีรูปแบบเป็น YYYYMMDD_HHMMSS_<8-char-hex> เช่น 20250305_091523_a1b2c3d4 คุณสามารถดำเนินการต่อได้ทั้งด้วย ID หรือด้วยชื่อ - ทั้งสองแบบใช้ได้กับ -c และ -r
:::
Session Naming
กำหนดชื่อที่อ่านได้ด้วยมนุษย์ให้กับเซสชัน เพื่อให้คุณสามารถค้นหาและดำเนินการต่อได้ง่าย
Auto-Generated Titles
Hermes จะสร้างชื่อที่สื่อความหมายสั้น ๆ (3-7 คำ) โดยอัตโนมัติสำหรับแต่ละเซสชันหลังจากมีการโต้ตอบครั้งแรก การทำงานนี้จะเกิดขึ้นใน background thread โดยใช้ auxiliary model ที่รวดเร็ว จึงไม่มีความล่าช้า คุณจะเห็นชื่อที่สร้างโดยอัตโนมัติเมื่อเรียกดูเซสชันด้วย hermes sessions list หรือ hermes sessions browse
การตั้งชื่ออัตโนมัติจะทำงานเพียงครั้งเดียวต่อเซสชัน และจะถูกข้ามหากคุณได้ตั้งชื่อด้วยตนเองแล้ว
Setting a Title Manually
ใช้คำสั่ง slash /title ภายใน chat session ใด ๆ (CLI หรือ gateway):
/title my research projectชื่อจะถูกนำไปใช้ทันที หากเซสชันยังไม่ได้ถูกสร้างใน database (เช่น คุณรัน /title ก่อนส่งข้อความแรก) มันจะถูกจัดคิวและนำไปใช้เมื่อเซสชันเริ่มต้น
คุณยังสามารถเปลี่ยนชื่อเซสชันที่มีอยู่ได้จาก command line:
hermes sessions rename 20250305_091523_a1b2c3d4 "refactoring auth module"Title Rules
- Unique - ไม่มีเซสชันใดสองเซสชันที่สามารถมีชื่อเดียวกันได้
- Max 100 characters - เพื่อให้ output ของรายการดูสะอาดตา
- Sanitized - control characters, zero-width chars, และ RTL overrides จะถูกลบออกโดยอัตโนมัติ
- Normal Unicode is fine - emoji, CJK, accented characters ใช้งานได้ทั้งหมด
Auto-Lineage on Compression
เมื่อ context ของเซสชันถูกบีบอัด (ด้วยตนเองผ่าน /compress หรือโดยอัตโนมัติ) Hermes จะสร้างเซสชัน continuation ใหม่ หากเซสชันเดิมมีชื่อ เซสชันใหม่จะได้รับชื่อที่มีลำดับตัวเลขโดยอัตโนมัติ:
"my project" → "my project #2" → "my project #3"เมื่อคุณดำเนินการต่อด้วยชื่อ (hermes -c "my project") ระบบจะเลือกเซสชันล่าสุดใน lineage ให้โดยอัตโนมัติ
/title in Messaging Platforms
คำสั่ง /title ใช้งานได้ในทุกแพลตฟอร์ม gateway (Telegram, Discord, Slack, WhatsApp):
/title My Research- ตั้งชื่อเซสชัน/title- แสดงชื่อปัจจุบัน
Session Management Commands
Hermes มีชุดคำสั่งจัดการเซสชันที่สมบูรณ์ผ่าน hermes sessions:
List Sessions
# List recent sessions (default: last 20)
hermes sessions list
# Filter by platform
hermes sessions list --source telegram
# Show more sessions
hermes sessions list --limit 50เมื่อเซสชันมีชื่อ จะแสดงชื่อ, ตัวอย่าง, และเวลาที่ใช้งานล่าสุด:
Title Preview Last Active ID
────────────────────────────────────────────────────────────────────────────────────────────────
refactoring auth Help me refactor the auth module please 2h ago 20250305_091523_a
my project #3 Can you check the test failures? yesterday 20250304_143022_e
— What's the weather in Las Vegas? 3d ago 20250303_101500_fเมื่อไม่มีเซสชันใดมีชื่อ จะใช้รูปแบบที่ง่ายกว่า:
Preview Last Active Src ID
──────────────────────────────────────────────────────────────────────────────────────
Help me refactor the auth module please 2h ago cli 20250305_091523_a
What's the weather in Las Vegas? 3d ago tele 20250303_101500_fExport Sessions
# Export all sessions to a JSONL file
hermes sessions export backup.jsonl
# Export sessions from a specific platform
hermes sessions export telegram-history.jsonl --source telegram
# Export a single session
hermes sessions export session.jsonl --session-id 20250305_091523_a1b2c3d4ไฟล์ที่ export จะมี JSON object หนึ่ง object ต่อบรรทัด พร้อม metadata เซสชันทั้งหมดและข้อความทั้งหมด
Delete a Session
# Delete a specific session (with confirmation)
hermes sessions delete 20250305_091523_a1b2c3d4
# Delete without confirmation
hermes sessions delete 20250305_091523_a1b2c3d4 --yesRename a Session
# Set or change a session's title
hermes sessions rename 20250305_091523_a1b2c3d4 "debugging auth flow"
# Multi-word titles don't need quotes in the CLI
hermes sessions rename 20250305_091523_a1b2c3d4 debugging auth flowหากชื่อถูกใช้งานโดยเซสชันอื่นอยู่แล้ว จะแสดงข้อผิดพลาด
Prune Old Sessions
# Delete ended sessions older than 90 days (default)
hermes sessions prune
# Custom age threshold
hermes sessions prune --older-than 30
# Only prune sessions from a specific platform
hermes sessions prune --source telegram --older-than 60
# Skip confirmation
hermes sessions prune --older-than 30 --yes:::info Pruning จะลบเฉพาะเซสชันที่ สิ้นสุดแล้ว (เซสชันที่ถูกยุติอย่างชัดเจนหรือรีเซ็ตอัตโนมัติ) เซสชันที่ใช้งานอยู่จะไม่ถูกลบเด็ดขาด :::
Session Statistics
hermes sessions statsOutput:
Total sessions: 142
Total messages: 3847
cli: 89 sessions
telegram: 38 sessions
discord: 15 sessions
Database size: 12.4 MBสำหรับการวิเคราะห์เชิงลึกยิ่งขึ้น - การใช้ token, การประมาณค่าใช้จ่าย, การแจกแจง tool, และรูปแบบกิจกรรม - ให้ใช้ hermes insights
Session Search Tool
Agent มี tool session_search ในตัวที่ทำการค้นหา full-text search ทั่วทุกการสนทนาที่ผ่านมาโดยใช้ engine FTS5 ของ SQLite
How It Works
- FTS5 ค้นหาข้อความที่ตรงกันและจัดอันดับตามความเกี่ยวข้อง
- จัดกลุ่มผลลัพธ์ตามเซสชัน และเลือก N เซสชันที่ไม่ซ้ำกันที่ดีที่สุด (ค่าเริ่มต้น 3)
- โหลดการสนทนาของแต่ละเซสชัน, ตัดทอนให้เหลือประมาณ 100K ตัวอักษร โดยเน้นบริเวณที่ตรงกับผลลัพธ์
- ส่งไปยัง fast summarization model เพื่อสรุปที่เน้นเฉพาะจุด
- ส่งคืนสรุปต่อเซสชันพร้อม metadata และบริบทโดยรอบ
FTS5 Query Syntax
การค้นหาสนับสนุน syntax ของ FTS5 มาตรฐาน:
- Simple keywords:
docker deployment - Phrases:
"exact phrase" - Boolean:
docker OR kubernetes,python NOT java - Prefix:
deploy*
When It's Used
Agent จะถูกสั่งให้ใช้ session search โดยอัตโนมัติ:
"When the user references something from a past conversation or you suspect relevant prior context exists, use session_search to recall it before asking them to repeat themselves."
Per-Platform Session Tracking
Gateway Sessions
ในแพลตฟอร์มการส่งข้อความ เซสชันจะถูกระบุด้วย session key ที่กำหนดโดย deterministic key ซึ่งสร้างขึ้นจาก source ของข้อความ:
| Chat Type | Default Key Format | Behavior |
|---|---|---|
| Telegram DM | agent:main:telegram:dm:<chat_id> | หนึ่งเซสชันต่อ DM chat |
| Discord DM | agent:main:discord:dm:<chat_id> | หนึ่งเซสชันต่อ DM chat |
| WhatsApp DM | agent:main:whatsapp:dm:<chat_id> | หนึ่งเซสชันต่อ DM chat |
| Group chat | agent:main:<platform>:group:<chat_id>:<user_id> | ต่อผู้ใช้แต่ละคนภายในกลุ่ม เมื่อแพลตฟอร์มเปิดเผย user ID |
| Group thread/topic | agent:main:<platform>:group:<chat_id>:<thread_id> | เซสชันที่ใช้ร่วมกันสำหรับผู้เข้าร่วม thread ทั้งหมด (ค่าเริ่มต้น). ต่อผู้ใช้แต่ละคนเมื่อตั้งค่า thread_sessions_per_user: true |
| Channel | agent:main:<platform>:channel:<chat_id>:<user_id> | ต่อผู้ใช้แต่ละคนภายในช่อง เมื่อแพลตฟอร์มเปิดเผย user ID |
เมื่อ Hermes ไม่สามารถรับ participant identifier สำหรับแชทที่ใช้ร่วมกันได้ มันจะย้อนกลับไปใช้เซสชันที่ใช้ร่วมกันเพียงเซสชันเดียวสำหรับห้องนั้น
Shared vs Isolated Group Sessions
โดยค่าเริ่มต้น Hermes ใช้ group_sessions_per_user: true ใน config.yaml ซึ่งหมายความว่า:
- Alice และ Bob สามารถคุยกับ Hermes ในช่อง Discord เดียวกันได้โดยที่ประวัติ transcript ไม่ถูกแชร์กัน
- งานที่ใช้ tool หนัก ๆ ของผู้ใช้คนหนึ่งจะไม่ทำให้ context window ของผู้ใช้คนอื่นปนเปื้อน
- การจัดการ interrupt ยังคงเป็นแบบต่อผู้ใช้แต่ละคน เนื่องจาก key ของ running-agent ตรงกับ isolated session key
หากคุณต้องการ "room brain" ที่ใช้ร่วมกันแทน ให้ตั้งค่า:
group_sessions_per_user: falseสิ่งนี้จะย้อนกลับกลุ่ม/ช่องให้เป็นเซสชันที่ใช้ร่วมกันเพียงเซสชันเดียวต่อห้อง ซึ่งช่วยรักษาบริบทการสนทนาที่ใช้ร่วมกัน แต่ก็แชร์ token costs, interrupt state, และ context growth ด้วย
Session Reset Policies
Gateway sessions จะถูกรีเซ็ตโดยอัตโนมัติตามนโยบายที่กำหนดค่าได้:
- idle - รีเซ็ตหลังจากไม่มีกิจกรรมเป็นเวลา N นาที
- daily - รีเซ็ตในเวลาที่กำหนดในแต่ละวัน
- both - รีเซ็ตเมื่อถึงเงื่อนไขใดเงื่อนไขหนึ่งก่อน (idle หรือ daily)
- none - ไม่เคยรีเซ็ตอัตโนมัติ
ก่อนที่เซสชันจะถูกรีเซ็ตอัตโนมัติ Agent จะได้รับโอกาสในการบันทึกความทรงจำหรือทักษะที่สำคัญใด ๆ จากการสนทนานั้น
เซสชันที่มี active background processes จะไม่ถูกรีเซ็ตอัตโนมัติ ไม่ว่านโยบายจะเป็นอย่างไร
Storage Locations
| What | Path | Description |
|---|---|---|
| SQLite database | ~/.hermes/state.db | metadata เซสชันทั้งหมด + ข้อความ พร้อม FTS5 |
| Gateway transcripts | ~/.hermes/sessions/ | JSONL transcripts ต่อเซสชัน + index sessions.json |
| Gateway index | ~/.hermes/sessions/sessions.json | แผนที่ key เซสชันไปยัง active session IDs |
SQLite database ใช้ WAL mode สำหรับ concurrent readers และ single writer ซึ่งเหมาะกับสถาปัตยกรรม multi-platform ของ gateway เป็นอย่างดี
Database Schema
ตารางหลักใน state.db:
- sessions - metadata เซสชัน (id, source, user_id, model, title, timestamps, token counts). Titles มี unique index (อนุญาตให้มี NULL title, เฉพาะ non-NULL เท่านั้นที่ต้อง unique).
- messages - ประวัติข้อความทั้งหมด (role, content, tool_calls, tool_name, token_count)
- messages_fts - ตารางเสมือน FTS5 สำหรับ full-text search ทั่ว content ของข้อความ
Session Expiry and Cleanup
Automatic Cleanup
- Gateway sessions จะรีเซ็ตอัตโนมัติตามนโยบายที่กำหนดค่า
- ก่อนรีเซ็ต Agent จะบันทึก memories และ skills จากเซสชันที่กำลังจะหมดอายุ
- เซสชันที่สิ้นสุดแล้วจะยังคงอยู่ใน database จนกว่าจะถูก prune
Manual Cleanup
# Prune sessions older than 90 days
hermes sessions prune
# Delete a specific session
hermes sessions delete <session_id>
# Export before pruning (backup)
hermes sessions export backup.jsonl
hermes sessions prune --older-than 30 --yes:::tip Database จะขยายตัวช้า ๆ (โดยทั่วไป: 10-15 MB สำหรับหลายร้อยเซสชัน) การ prune มีประโยชน์หลักในการลบการสนทนาเก่า ๆ ที่คุณไม่ต้องการสำหรับการเรียกคืนข้อมูล (search recall) :::
📄 user-guide/security.md
sidebar_position: 8 title: "Security" description: "Security model, dangerous command approval, user authorization, container isolation, and production deployment best practices"
Security
Hermes Agent ถูกออกแบบด้วยโมเดลความปลอดภัยแบบลึกหลายชั้น (defense-in-depth security model) หน้านี้ครอบคลุมขอบเขตความปลอดภัยทุกส่วน ตั้งแต่การอนุมัติคำสั่ง การแยกส่วนคอนเทนเนอร์ ไปจนถึงการอนุญาตสิทธิ์ผู้ใช้บนแพลตฟอร์มการส่งข้อความ
Overview
โมเดลความปลอดภัยประกอบด้วยเจ็ดชั้น:
- User authorization - ใครสามารถพูดคุยกับ agent ได้ (allowlists, DM pairing)
- Dangerous command approval - การตรวจสอบคำสั่งอันตรายโดยมนุษย์ (human-in-the-loop) สำหรับการดำเนินการที่ทำลายล้าง
- Container isolation - การแยกส่วนด้วย Docker/Singularity/Modal sandboxing พร้อมการตั้งค่าที่แข็งแกร่ง (hardened settings)
- MCP credential filtering - การแยกส่วนตัวแปรสภาพแวดล้อม (environment variable isolation) สำหรับ MCP subprocesses
- Context file scanning - การตรวจจับ prompt injection ในไฟล์โปรเจกต์
- Cross-session isolation - เซสชันไม่สามารถเข้าถึงข้อมูลหรือสถานะของกันและกันได้; เส้นทางจัดเก็บ cron job ถูกเสริมความแข็งแกร่งเพื่อป้องกัน path traversal attacks
- Input sanitization - พารามิเตอร์ working directory ใน backends ของเครื่องมือ terminal จะถูกตรวจสอบกับ allowlist เพื่อป้องกัน shell injection
Dangerous Command Approval
ก่อนที่จะดำเนินการคำสั่งใดๆ Hermes จะตรวจสอบคำสั่งนั้นกับรายการรูปแบบ (patterns) อันตรายที่รวบรวมมา หากพบการจับคู่ (match) ผู้ใช้จะต้องอนุมัติอย่างชัดเจน
Approval Modes
ระบบการอนุมัติรองรับสามโหมด ซึ่งกำหนดค่าผ่าน approvals.mode ใน ~/.hermes/config.yaml:
approvals:
mode: manual # manual | smart | off
timeout: 60 # seconds to wait for user response (default: 60)| Mode | Behavior |
|---|---|
| manual (default) | จะแจ้งให้ผู้ใช้อนุมัติเสมอเมื่อมีการใช้คำสั่งอันตราย |
| smart | ใช้ LLM ตัวช่วยเพื่อประเมินความเสี่ยง คำสั่งความเสี่ยงต่ำ (เช่น python -c "print('hello')") จะได้รับการอนุมัติอัตโนมัติ คำสั่งอันตรายจริงจะถูกปฏิเสธอัตโนมัติ กรณีที่ไม่แน่ใจจะแจ้งให้ผู้ใช้อนุมัติด้วยตนเอง |
| off | ปิดการตรวจสอบการอนุมัติทั้งหมด - เทียบเท่ากับการรันด้วย --yolo คำสั่งทั้งหมดจะทำงานโดยไม่มีการแจ้งเตือน |
:::warning
การตั้งค่า approvals.mode: off จะปิดการแจ้งเตือนความปลอดภัยทั้งหมด ใช้เฉพาะในสภาพแวดล้อมที่เชื่อถือได้เท่านั้น (CI/CD, containers, ฯลฯ)
:::
YOLO Mode
YOLO mode จะข้ามการแจ้งเตือนการอนุมัติคำสั่งอันตราย ทั้งหมด สำหรับเซสชันปัจจุบัน สามารถเปิดใช้งานได้สามวิธี:
- CLI flag: เริ่มเซสชันด้วย
hermes --yoloหรือhermes chat --yolo - Slash command: พิมพ์
/yoloระหว่างเซสชันเพื่อสลับเปิด/ปิด - Environment variable: ตั้งค่า
HERMES_YOLO_MODE=1
คำสั่ง /yolo เป็นการ สลับ (toggle) - การใช้งานแต่ละครั้งจะสลับโหมดเปิดหรือปิด:
> /yolo
⚡ YOLO mode ON — all commands auto-approved. Use with caution.
> /yolo
⚠ YOLO mode OFF — dangerous commands will require approval.YOLO mode สามารถใช้ได้ทั้งในเซสชัน CLI และ gateway ภายในระบบจะตั้งค่าตัวแปรสภาพแวดล้อม HERMES_YOLO_MODE ซึ่งจะถูกตรวจสอบก่อนการดำเนินการคำสั่งทุกครั้ง
:::danger YOLO mode ปิดการตรวจสอบความปลอดภัยของคำสั่งอันตราย ทั้งหมด สำหรับเซสชัน ใช้เฉพาะเมื่อคุณเชื่อมั่นในคำสั่งที่กำลังถูกสร้างขึ้นอย่างเต็มที่ (เช่น สคริปต์ระบบอัตโนมัติที่ผ่านการทดสอบมาอย่างดีในสภาพแวดล้อมที่ใช้แล้วทิ้ง) :::
Approval Timeout
เมื่อมีการแจ้งเตือนคำสั่งอันตราย ผู้ใช้จะมีเวลาที่กำหนดค่าไว้ในการตอบกลับ หากไม่มีการตอบกลับภายในเวลาที่กำหนด คำสั่งนั้นจะถูก ปฏิเสธ โดยค่าเริ่มต้น (fail-closed)
กำหนดค่า timeout ใน ~/.hermes/config.yaml:
approvals:
timeout: 60 # seconds (default: 60)What Triggers Approval
รูปแบบต่อไปนี้จะกระตุ้นการแจ้งเตือนการอนุมัติ (กำหนดไว้ใน tools/approval.py):
| Pattern | Description |
|---|---|
rm -r / rm --recursive | ลบแบบเรียกซ้ำ (Recursive delete) |
rm ... / | ลบใน root path |
chmod 777/666 / o+w / a+w | สิทธิ์ที่เขียนได้สำหรับโลก/อื่น (World/other-writable permissions) |
chmod --recursive with unsafe perms | ลบแบบเรียกซ้ำด้วยสิทธิ์ที่อันตราย (long flag) |
chown -R root / chown --recursive root | chown แบบเรียกซ้ำเป็น root |
mkfs | ฟอร์แมตไฟล์ซิสเต็ม (Format filesystem) |
dd if= | คัดลอกดิสก์ (Disk copy) |
> /dev/sd | เขียนไปยัง block device |
DROP TABLE/DATABASE | SQL DROP |
DELETE FROM (without WHERE) | SQL DELETE โดยไม่มี WHERE |
TRUNCATE TABLE | SQL TRUNCATE |
> /etc/ | เขียนทับไฟล์ config ระบบ |
systemctl stop/disable/mask | หยุด/ปิดใช้งานระบบบริการ (system services) |
kill -9 -1 | สั่งฆ่าทุก process |
pkill -9 | สั่งฆ่า process โดยบังคับ |
| Fork bomb patterns | รูปแบบ fork bombs |
bash -c / sh -c / zsh -c / ksh -c | การดำเนินการคำสั่ง shell ผ่าน flag -c (รวมถึง combined flags เช่น -lc) |
python -e / perl -e / ruby -e / node -c | การดำเนินการสคริปต์ผ่าน flag -e/-c |
curl ... | sh / wget ... | sh | ส่งเนื้อหาจากระยะไกลผ่าน pipe ไปยัง shell |
bash <(curl ...) / sh <(wget ...) | ดำเนินการสคริปต์ระยะไกลผ่าน process substitution |
tee to /etc/, ~/.ssh/, ~/.hermes/.env | เขียนทับไฟล์ที่ละเอียดอ่อนผ่าน tee |
> / >> to /etc/, ~/.ssh/, ~/.hermes/.env | เขียนทับไฟล์ที่ละเอียดอ่อนผ่าน redirection |
xargs rm | xargs กับ rm |
find -exec rm / find -delete | find ที่มีการดำเนินการทำลายล้าง |
cp/mv/install to /etc/ | คัดลอก/ย้ายไฟล์ไปยัง config ระบบ |
sed -i / sed --in-place on /etc/ | แก้ไขในที่ (In-place edit) config ระบบ |
pkill/killall hermes/gateway | ป้องกันการยุติตัวเอง (Self-termination prevention) |
gateway run with &/disown/nohup/setsid | ป้องกันการเริ่ม gateway นอก service manager |
:::info
Container bypass: เมื่อรันใน docker, singularity, modal, หรือ daytona backends การตรวจสอบคำสั่งอันตรายจะ ถูกข้าม เนื่องจากคอนเทนเนอร์เองคือขอบเขตความปลอดภัย คำสั่งทำลายล้างภายในคอนเทนเนอร์จึงไม่สามารถทำอันตรายต่อ host ได้
:::
Approval Flow (CLI)
ใน CLI แบบโต้ตอบ (interactive CLI) คำสั่งอันตรายจะแสดง prompt การอนุมัติแบบ inline:
⚠️ DANGEROUS COMMAND: recursive delete
rm -rf /tmp/old-project
[o]nce | [s]ession | [a]lways | [d]eny
Choice [o/s/a/D]:สี่ตัวเลือก:
- once - อนุญาตให้ดำเนินการเพียงครั้งเดียวนี้
- session - อนุญาตรูปแบบนี้ตลอดเซสชัน
- always - เพิ่มเข้าใน allowlist ถาวร (บันทึกใน
config.yaml) - deny (default) - บล็อกคำสั่ง
Approval Flow (Gateway/Messaging)
บนแพลตฟอร์มการส่งข้อความ agent จะส่งรายละเอียดคำสั่งอันตรายไปยังแชทและรอให้ผู้ใช้ตอบกลับ:
- ตอบ yes, y, approve, ok, หรือ go เพื่ออนุมัติ
- ตอบ no, n, deny, หรือ cancel เพื่อปฏิเสธ
ตัวแปรสภาพแวดล้อม HERMES_EXEC_ASK=1 จะถูกตั้งค่าโดยอัตโนมัติเมื่อรัน gateway
Permanent Allowlist
คำสั่งที่อนุมัติด้วย "always" จะถูกบันทึกใน ~/.hermes/config.yaml:
# Permanently allowed dangerous command patterns
command_allowlist:
- rm
- systemctlรูปแบบเหล่านี้จะถูกโหลดเมื่อเริ่มต้นระบบและได้รับการอนุมัติโดยอัตโนมัติในทุกเซสชันในอนาคต
:::tip
ใช้ hermes config edit เพื่อตรวจสอบหรือลบรูปแบบออกจาก permanent allowlist ของคุณ
:::
User Authorization (Gateway)
เมื่อรัน messaging gateway, Hermes จะควบคุมว่าใครสามารถโต้ตอบกับบอทได้ผ่านระบบการอนุญาตสิทธิ์แบบหลายชั้น
Authorization Check Order
เมธอด _is_user_authorized() จะตรวจสอบตามลำดับนี้:
- Per-platform allow-all flag (เช่น
DISCORD_ALLOW_ALL_USERS=true) - DM pairing approved list (ผู้ใช้ที่ได้รับการอนุมัติผ่าน pairing codes)
- Platform-specific allowlists (เช่น
TELEGRAM_ALLOWED_USERS=12345,67890) - Global allowlist (
GATEWAY_ALLOWED_USERS=12345,67890) - Global allow-all (
GATEWAY_ALLOW_ALL_USERS=true) - Default: deny
Platform Allowowlists
ตั้งค่า user ID ที่อนุญาตเป็นค่าที่คั่นด้วย comma ใน ~/.hermes/.env:
# Platform-specific allowlists
TELEGRAM_ALLOWED_USERS=123456789,987654321
DISCORD_ALLOWED_USERS=111222333444555666
WHATSAPP_ALLOWED_USERS=15551234567
SLACK_ALLOWED_USERS=U01ABC123
# Cross-platform allowlist (checked for all platforms)
GATEWAY_ALLOWED_USERS=123456789
# Per-platform allow-all (use with caution)
DISCORD_ALLOW_ALL_USERS=true
# Global allow-all (use with extreme caution)
GATEWAY_ALLOW_ALL_USERS=true:::warning
หาก ไม่มีการกำหนด allowlists และไม่ได้ตั้งค่า GATEWAY_ALLOW_ALL_USERS ผู้ใช้ทุกคนจะถูกปฏิเสธ gateway จะบันทึกคำเตือนเมื่อเริ่มต้นระบบ:
No user allowlists configured. All unauthorized users will be denied.
Set GATEWAY_ALLOW_ALL_USERS=true in ~/.hermes/.env to allow open access,
or configure platform allowlists (e.g., TELEGRAM_ALLOWED_USERS=your_id).:::
DM Pairing System
สำหรับการอนุญาตสิทธิ์ที่ยืดหยุ่นยิ่งขึ้น Hermes มีระบบ pairing แบบใช้รหัส (code-based pairing system) แทนที่จะต้องระบุ user ID ตั้งแต่แรก ผู้ใช้ที่ไม่ทราบตัวจะได้รับรหัส pairing ชั่วคราวที่เจ้าของบอทจะอนุมัติผ่าน CLI
วิธีการทำงาน:
- ผู้ใช้ที่ไม่ทราบตัวส่ง DM ไปยังบอท
- บอทตอบกลับด้วยรหัส pairing 8 ตัวอักษร
- เจ้าของบอทรัน
hermes pairing approve <platform> <code>บน CLI - ผู้ใช้จะได้รับการอนุมัติถาวรสำหรับแพลตฟอร์มนั้น
ควบคุมวิธีการจัดการ direct messages ที่ไม่ได้รับอนุญาตใน ~/.hermes/config.yaml:
unauthorized_dm_behavior: pair
whatsapp:
unauthorized_dm_behavior: ignorepairคือค่าเริ่มต้น DMs ที่ไม่ได้รับอนุญาตจะได้รับข้อความตอบกลับพร้อมรหัส pairingignoreจะทิ้ง DMs ที่ไม่ได้รับอนุญาตอย่างเงียบๆ- ส่วนของแพลตฟอร์มจะเขียนทับค่าเริ่มต้นทั่วโลก ดังนั้นคุณสามารถคงการ pairing ไว้สำหรับ Telegram ในขณะที่ทำให้ WhatsApp เงียบได้
Security features (อิงตามแนวทาง OWASP + NIST SP 800-63-4):
| Feature | Details |
|---|---|
| Code format | 8-char from 32-char unambiguous alphabet (no 0/O/1/I) |
| Randomness | Cryptographic (secrets.choice()) |
| Code TTL | 1 hour expiry |
| Rate limiting | 1 request per user per 10 minutes |
| Pending limit | Max 3 pending codes per platform |
| Lockout | 5 failed approval attempts → 1-hour lockout |
| File security | chmod 0600 on all pairing data files |
| Logging | Codes are never logged to stdout |
Pairing CLI commands:
# List pending and approved users
hermes pairing list
# Approve a pairing code
hermes pairing approve telegram ABC12DEF
# Revoke a user's access
hermes pairing revoke telegram 123456789
# Clear all pending codes
hermes pairing clear-pendingStorage: ข้อมูล pairing ถูกจัดเก็บใน ~/.hermes/pairing/ ด้วยไฟล์ JSON แยกตามแพลตฟอร์ม:
{platform}-pending.json- คำขอ pairing ที่รอดำเนินการ{platform}-approved.json- ผู้ใช้ที่ได้รับการอนุมัติ_rate_limits.json- การติดตาม rate limit และ lockout
Container Isolation
เมื่อใช้ terminal backend ของ docker, Hermes จะใช้การเสริมความแข็งแกร่งด้านความปลอดภัยอย่างเคร่งครัดกับทุกคอนเทนเนอร์
Docker Security Flags
ทุกคอนเทนเนอร์จะรันด้วย flag เหล่านี้ (กำหนดไว้ใน tools/environments/docker.py):
_SECURITY_ARGS = [
"--cap-drop", "ALL", # Drop ALL Linux capabilities
"--cap-add", "DAC_OVERRIDE", # Root can write to bind-mounted dirs
"--cap-add", "CHOWN", # Package managers need file ownership
"--cap-add", "FOWNER", # Package managers need file ownership
"--security-opt", "no-new-privileges", # Block privilege escalation
"--pids-limit", "256", # Limit process count
"--tmpfs", "/tmp:rw,nosuid,size=512m", # Size-limited /tmp
"--tmpfs", "/var/tmp:rw,noexec,nosuid,size=256m", # No-exec /var/tmp
"--tmpfs", "/run:rw,noexec,nosuid,size=64m", # No-exec /run
]Resource Limits
ทรัพยากรคอนเทนเนอร์สามารถกำหนดค่าได้ใน ~/.hermes/config.yaml:
terminal:
backend: docker
docker_image: "nikolaik/python-nodejs:python3.11-nodejs20"
docker_forward_env: [] # Explicit allowlist only; empty keeps secrets out of the container
container_cpu: 1 # CPU cores
container_memory: 5120 # MB (default 5GB)
container_disk: 51200 # MB (default 50GB, requires overlay2 on XFS)
container_persistent: true # Persist filesystem across sessionsFilesystem Persistence
- Persistent mode (
container_persistent: true): Bind-mounts/workspaceและ/rootจาก~/.hermes/sandboxes/docker/<task_id>/ - Ephemeral mode (
container_persistent: false): ใช้ tmpfs สำหรับ workspace — ทุกอย่างจะสูญหายเมื่อทำความสะอาด
:::tip
สำหรับการใช้งาน gateway ในสภาพแวดล้อม Production ให้ใช้ backend docker, modal, หรือ daytona เพื่อแยกคำสั่ง agent ออกจากระบบโฮสต์ของคุณ วิธีนี้จะขจัดความจำเป็นในการอนุมัติคำสั่งอันตรายไปโดยสิ้นเชิง
:::
:::warning
หากคุณเพิ่มชื่อใน terminal.docker_forward_env ตัวแปรเหล่านั้นจะถูกฉีดเข้าไปในคอนเทนเนอร์โดยเจตนาสำหรับคำสั่ง terminal ซึ่งมีประโยชน์สำหรับ credentials เฉพาะงาน เช่น GITHUB_TOKEN แต่ก็หมายความว่าโค้ดที่รันในคอนเทนเนอร์สามารถอ่านและส่งออกข้อมูลเหล่านั้นได้
:::
Terminal Backend Security Comparison
| Backend | Isolation | Dangerous Cmd Check | Best For |
|---|---|---|---|
| local | None - runs on host | ✅ Yes | Development, trusted users |
| ssh | Remote machine | ✅ Yes | Running on a separate server |
| docker | Container | ❌ Skipped (container is boundary) | Production gateway |
| singularity | Container | ❌ Skipped | HPC environments |
| modal | Cloud sandbox | ❌ Skipped | Scalable cloud isolation |
| daytona | Cloud sandbox | ❌ Skipped | Persistent cloud workspaces |
Environment Variable Passthrough {#environment-variable-passthrough}
ทั้ง execute_code และ terminal จะลบตัวแปรสภาพแวดล้อมที่ละเอียดอ่อนออกจาก child processes เพื่อป้องกันการส่งออกข้อมูลรับรองโดยโค้ดที่สร้างโดย LLM อย่างไรก็ตาม skills ที่ประกาศ required_environment_variables จำเป็นต้องเข้าถึงตัวแปรเหล่านั้นโดยชอบธรรม
How It Works
กลไกสองอย่างช่วยให้ตัวแปรบางตัวผ่านตัวกรอง sandbox ได้:
1. Skill-scoped passthrough (automatic)
เมื่อมีการโหลด skill (ผ่าน skill_view หรือคำสั่ง /skill) และประกาศ required_environment_variables ตัวแปรเหล่านั้นที่ถูกตั้งค่าอยู่ในสภาพแวดล้อมจริงจะถูกลงทะเบียนเป็น passthrough โดยอัตโนมัติ ตัวแปรที่ขาดหายไป (ยังอยู่ในสถานะ setup-needed) จะ ไม่ ถูกลงทะเบียน
# In a skill's SKILL.md frontmatter
required_environment_variables:
- name: TENOR_API_KEY
prompt: Tenor API key
help: Get a key from https://developers.google.com/tenorหลังจากโหลด skill นี้แล้ว TENOR_API_KEY จะผ่านไปยัง execute_code, terminal (local), และ remote backends (Docker, Modal) - ไม่ต้องกำหนดค่าด้วยตนเอง
:::info Docker & Modal
ก่อน v0.5.1, forward_env ของ Docker เป็นระบบแยกจาก skill passthrough ปัจจุบันทั้งสองถูกรวมเข้าด้วยกัน - ตัวแปร env ที่ประกาศโดย skill จะถูกส่งต่อไปยัง Docker containers และ Modal sandboxes โดยอัตโนมัติโดยไม่จำเป็นต้องเพิ่มใน docker_forward_env ด้วยตนเอง
:::
2. Config-based passthrough (manual)
สำหรับ env vars ที่ไม่ได้ประกาศโดย skill ใดๆ ให้เพิ่มพวกมันใน terminal.env_passthrough ใน config.yaml:
terminal:
env_passthrough:
- MY_CUSTOM_KEY
- ANOTHER_TOKENCredential File Passthrough (OAuth tokens, etc.) {#credential-file-passthrough}
บาง skill ต้องการ ไฟล์ (ไม่ใช่แค่ env vars) ใน sandbox - ตัวอย่างเช่น Google Workspace จัดเก็บ OAuth tokens เป็น google_token.json ภายใต้ HERMES_HOME ของโปรไฟล์ที่ใช้งาน Skills จะประกาศสิ่งเหล่านี้ใน frontmatter:
required_credential_files:
- path: google_token.json
description: Google OAuth2 token (created by setup script)
- path: google_client_secret.json
description: Google OAuth2 client credentialsเมื่อโหลดแล้ว Hermes จะตรวจสอบว่าไฟล์เหล่านี้มีอยู่ใน HERMES_HOME ของโปรไฟล์ที่ใช้งานหรือไม่ และลงทะเบียนเพื่อการ mount:
- Docker: Read-only bind mounts (
-v host:container:ro) - Modal: Mounted เมื่อสร้าง sandbox + sync ก่อนคำสั่งทุกครั้ง (จัดการ setup OAuth กลางเซสชัน)
- Local: ไม่ต้องดำเนินการใดๆ (ไฟล์เข้าถึงได้อยู่แล้ว)
คุณยังสามารถระบุไฟล์ credential ด้วยตนเองใน config.yaml:
terminal:
credential_files:
- google_token.json
- my_custom_oauth_token.jsonPaths เป็น relative to ~/.hermes/. ไฟล์จะถูก mount ไปที่ /root/.hermes/ ภายในคอนเทนเนอร์
What Each Sandbox Filters
| Sandbox | Default Filter | Passthrough Override |
|---|---|---|
| execute_code | Blocks vars containing KEY, TOKEN, SECRET, PASSWORD, CREDENTIAL, PASSWD, AUTH in name; only allows safe-prefix vars through | ✅ Passthrough vars bypass both checks |
| terminal (local) | Blocks explicit Hermes infrastructure vars (provider keys, gateway tokens, tool API keys) | ✅ Passthrough vars bypass the blocklist |
| terminal (Docker) | No host env vars by default | ✅ Passthrough vars + docker_forward_env forwarded via -e |
| terminal (Modal) | No host env/files by default | ✅ Credential files mounted; env passthrough via sync |
| MCP | Blocks everything except safe system vars + explicitly configured env | ❌ Not affected by passthrough (use MCP env config instead) |
Security Considerations
- Passthrough มีผลเฉพาะกับ vars ที่คุณหรือ skills ของคุณประกาศอย่างชัดเจน - ท่าทีด้านความปลอดภัยเริ่มต้นยังคงไม่เปลี่ยนแปลงสำหรับโค้ดที่สร้างโดย LLM แบบสุ่ม
- Credential files ถูก mount เป็น read-only ใน Docker containers
- Skills Guard สแกนเนื้อหา skill เพื่อหา patterns การเข้าถึง env ที่น่าสงสัยก่อนการติดตั้ง
- Vars ที่ขาดหายไป/ไม่ได้ตั้งค่าจะไม่ถูกลงทะเบียน (คุณไม่สามารถรั่วไหลสิ่งที่ไม่มีอยู่ได้)
- Hermes infrastructure secrets (provider API keys, gateway tokens) ไม่ควรถูกเพิ่มใน
env_passthrough- พวกมันมีกลไกเฉพาะ
MCP Credential Handling
MCP (Model Context Protocol) server subprocesses จะได้รับ สภาพแวดล้อมที่ถูกกรอง เพื่อป้องกันการรั่วไหลของข้อมูลรับรองโดยไม่ได้ตั้งใจ
Safe Environment Variables
มีเพียงตัวแปรเหล่านี้เท่านั้นที่ถูกส่งผ่านจาก host ไปยัง MCP stdio subprocesses:
PATH, HOME, USER, LANG, LC_ALL, TERM, SHELL, TMPDIRบวกกับตัวแปร XDG_* อื่นๆ ตัวแปรสภาพแวดล้อมอื่นๆ ทั้งหมด (API keys, tokens, secrets) จะถูก ลบออก
ตัวแปรที่กำหนดอย่างชัดเจนใน env config ของ MCP server จะถูกส่งผ่าน:
mcp_servers:
github:
command: "npx"
args: ["-y", "@modelcontextprotocol/server-github"]
env:
GITHUB_PERSONAL_ACCESS_TOKEN: "ghp_..." # Only this is passedCredential Redaction
ข้อความแสดงข้อผิดพลาดจากเครื่องมือ MCP จะถูกทำความสะอาดก่อนส่งกลับไปยัง LLM รูปแบบต่อไปนี้จะถูกแทนที่ด้วย [REDACTED]:
- GitHub PATs (
ghp_...) - OpenAI-style keys (
sk-...) - Bearer tokens
- พารามิเตอร์
token=,key=,API_KEY=,password=,secret=
Website Access Policy
คุณสามารถจำกัดเว็บไซต์ที่ agent สามารถเข้าถึงได้ผ่าน web และ browser tools ซึ่งมีประโยชน์ในการป้องกันไม่ให้ agent เข้าถึงบริการภายใน, admin panels, หรือ URL ที่ละเอียดอ่อนอื่นๆ
# In ~/.hermes/config.yaml
security:
website_blocklist:
enabled: true
domains:
- "*.internal.company.com"
- "admin.example.com"
shared_files:
- "/etc/hermes/blocked-sites.txt"เมื่อมีการร้องขอ URL ที่ถูกบล็อก เครื่องมือจะส่งคืนข้อผิดพลาดที่อธิบายว่าโดเมนนั้นถูกบล็อกตามนโยบาย blocklist จะถูกบังคับใช้ทั่ว web_search, web_extract, browser_navigate, และเครื่องมือที่รองรับ URL ทั้งหมด
ดู Website Blocklist ในคู่มือการกำหนดค่าสำหรับรายละเอียดทั้งหมด
SSRF Protection
เครื่องมือที่รองรับ URL ทั้งหมด (web search, web extract, vision, browser) จะตรวจสอบ URL ก่อนการดึงข้อมูลเพื่อป้องกันการโจมตี Server-Side Request Forgery (SSRF) ที่อยู่ถูกบล็อกรวมถึง:
- Private networks (RFC 1918):
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 - Loopback:
127.0.0.0/8,::1 - Link-local:
169.254.0.0/16(รวมถึง cloud metadata ที่169.254.169.254) - CGNAT / shared address space (RFC 6598):
100.64.0.0/10(Tailscale, WireGuard VPNs) - Cloud metadata hostnames:
metadata.google.internal,metadata.goog - Reserved, multicast, and unspecified addresses
SSRF protection ทำงานอยู่เสมอและไม่สามารถปิดได้ การล้มเหลวของ DNS จะถูกถือว่าถูกบล็อก (fail-closed) ลำดับการ redirect จะถูกตรวจสอบซ้ำที่แต่ละ hop เพื่อป้องกันการข้ามผ่านด้วยการ redirect
Tirith Pre-Exec Security Scanning
Hermes รวม tirith สำหรับการสแกนคำสั่งระดับเนื้อหาก่อนการดำเนินการ Tirith ตรวจจับภัยคุกคามที่การจับคู่รูปแบบเพียงอย่างเดียวมองข้ามไป:
- Homograph URL spoofing (internationalized domain attacks)
- Pipe-to-interpreter patterns (
curl | bash,wget | sh) - Terminal injection attacks
Tirith ติดตั้งอัตโนมัติจาก GitHub releases ในการใช้งานครั้งแรกพร้อมการตรวจสอบ SHA-256 checksum (และ cosign provenance verification หากมี cosign)
# In ~/.hermes/config.yaml
security:
tirith_enabled: true # Enable/disable tirith scanning (default: true)
tirith_path: "tirith" # Path to tirith binary (default: PATH lookup)
tirith_timeout: 5 # Subprocess timeout in seconds
tirith_fail_open: true # Allow execution when tirith is unavailable (default: true)เมื่อ tirith_fail_open เป็น true (ค่าเริ่มต้น) คำสั่งจะดำเนินการต่อหากไม่มีการติดตั้ง tirith หรือหมดเวลา ตั้งค่าเป็น false ในสภาพแวดล้อมความปลอดภัยสูงเพื่อบล็อกคำสั่งเมื่อ tirith ไม่พร้อมใช้งาน
ผลการตัดสินของ Tirith จะรวมเข้ากับ approval flow: คำสั่งที่ปลอดภัยจะผ่านไปได้ ในขณะที่คำสั่งที่น่าสงสัยและถูกบล็อกจะกระตุ้นให้เกิดการอนุมัติจากผู้ใช้พร้อมผลการค้นพบทั้งหมดของ tirith (severity, title, description, safer alternatives) ผู้ใช้สามารถอนุมัติหรือปฏิเสธได้ - ตัวเลือกเริ่มต้นคือปฏิเสธเพื่อรักษาความปลอดภัยในสถานการณ์ที่ไม่มีผู้ดูแล
Context File Injection Protection
Context files (AGENTS.md, .cursorrules, SOUL.md) จะถูกสแกนเพื่อหา prompt injection ก่อนที่จะถูกรวมเข้าใน system prompt ตัวสแกนจะตรวจสอบสำหรับ:
- คำสั่งให้เพิกเฉย/ไม่สนใจคำสั่งก่อนหน้า
- HTML comments ที่ซ่อนอยู่พร้อม keywords ที่น่าสงสัย
- ความพยายามในการอ่าน secrets (
.env,credentials,.netrc) - การส่งออกข้อมูลรับรองผ่าน
curl - Unicode characters ที่มองไม่เห็น (zero-width spaces, bidirectional overrides)
ไฟล์ที่ถูกบล็อกจะแสดงคำเตือน:
[BLOCKED: AGENTS.md contained potential prompt injection (prompt_injection). Content not loaded.]Best Practices for Production Deployment
Gateway Deployment Checklist
- Set explicit allowlists - ห้ามใช้
GATEWAY_ALLOW_ALL_USERS=trueใน Production - Use container backend - ตั้งค่า
terminal.backend: dockerใน config.yaml - Restrict resource limits - ตั้งค่า CPU, memory, และ disk limits ให้เหมาะสม
- Store secrets securely - เก็บ API keys ใน
~/.hermes/.envด้วยสิทธิ์ไฟล์ที่เหมาะสม - Enable DM pairing - ใช้ pairing codes แทนการ hardcoding user IDs เมื่อเป็นไปได้
- Review command allowlist - ตรวจสอบ
command_allowlistใน config.yaml เป็นระยะ - Set
MESSAGING_CWD- อย่าปล่อยให้ agent ทำงานจาก directory ที่ละเอียดอ่อน - Run as non-root - ห้ามรัน gateway ในฐานะ root
- Monitor logs - ตรวจสอบ
~/.hermes/logs/สำหรับความพยายามเข้าถึงที่ไม่ได้รับอนุญาต - Keep updated - รัน
hermes updateเป็นประจำเพื่อรับ security patches
Securing API Keys
# Set proper permissions on the .env file
chmod 600 ~/.hermes/.env
# Keep separate keys for different services
# Never commit .env files to version controlNetwork Isolation
สำหรับการรักษาความปลอดภัยสูงสุด ให้รัน gateway บนเครื่องหรือ VM แยกต่างหาก:
terminal:
backend: ssh
ssh_host: "agent-worker.local"
ssh_user: "hermes"
ssh_key: "~/.ssh/hermes_agent_key"วิธีนี้จะแยกการเชื่อมต่อ messaging ของ gateway ออกจากการดำเนินการคำสั่งของ agent
📄 user-guide/docker.md
sidebar_position: 7 title: "Docker" description: "การรัน Hermes Agent ใน Docker และการใช้ Docker เป็น terminal backend"
Hermes Agent - Docker
มีสองวิธีหลักที่ Docker เข้ามาเกี่ยวข้องกับ Hermes Agent:
- การรัน Hermes IN Docker - ตัว agent เองจะทำงานภายใน container (เป็นจุดเน้นหลักของหน้านี้)
- Docker เป็น terminal backend - agent ทำงานบน host ของคุณ แต่จะรันคำสั่งภายใน Docker sandbox (ดูที่ Configuration → terminal.backend)
หน้านี้ครอบคลุมตัวเลือกที่ 1 container จะจัดเก็บข้อมูลผู้ใช้ทั้งหมด (config, API keys, sessions, skills, memories) ในไดเรกทอรีเดียวที่ถูก mount มาจาก host ที่ /opt/data ตัว image เองเป็นแบบ stateless และสามารถอัปเกรดได้โดยการดึงเวอร์ชันใหม่โดยไม่สูญเสียการตั้งค่าใดๆ
Quick start
หากนี่เป็นครั้งแรกที่คุณรัน Hermes Agent ให้สร้าง data directory บน host และเริ่ม container แบบ interactive เพื่อรัน setup wizard:
mkdir -p ~/.hermes
docker run -it --rm \
-v ~/.hermes:/opt/data \
nousresearch/hermes-agent setupคำสั่งนี้จะนำคุณเข้าสู่ setup wizard ซึ่งจะแจ้งให้คุณป้อน API keys และเขียนลงใน ~/.hermes/.env คุณต้องทำขั้นตอนนี้เพียงครั้งเดียวเท่านั้น ขอแนะนำอย่างยิ่งให้ตั้งค่า chat system สำหรับ gateway เพื่อให้ทำงานได้ในจุดนี้
Running in gateway mode
เมื่อตั้งค่าเรียบร้อยแล้ว ให้รัน container ใน background เพื่อให้เป็น gateway แบบ persistent (เช่น Telegram, Discord, Slack, WhatsApp, ฯลฯ):
docker run -d \
--name hermes \
--restart unless-stopped \
-v ~/.hermes:/opt/data \
-p 8642:8642 \
nousresearch/hermes-agent gateway runPort 8642 เปิดเผย OpenAI-compatible API server และ health endpoint ของ gateway เป็นทางเลือกหากคุณใช้แค่ chat platforms (Telegram, Discord, ฯลฯ) แต่จำเป็นหากคุณต้องการให้ dashboard หรือ external tools เข้าถึง gateway
การเปิด port ใดๆ บนเครื่องที่เชื่อมต่ออินเทอร์เน็ตถือเป็นความเสี่ยงด้านความปลอดภัย คุณไม่ควรทำเช่นนั้นหากคุณไม่เข้าใจความเสี่ยงที่เกี่ยวข้อง
Running the dashboard
Web dashboard ที่มาพร้อมกับระบบสามารถรันควบคู่ไปกับ gateway ในฐานะ container แยกต่างหากได้
ในการรัน dashboard เป็น container ของตัวเอง ให้ชี้มันไปยัง health endpoint ของ gateway เพื่อให้สามารถตรวจจับสถานะของ gateway ข้าม container ได้:
docker run -d \
--name hermes-dashboard \
--restart unless-stopped \
-v ~/.hermes:/opt/data \
-p 9119:9119 \
-e GATEWAY_HEALTH_URL=http://$HOST_IP:8642 \
nousresearch/hermes-agent dashboardแทนที่ $HOST_IP ด้วย IP address ของเครื่องที่รัน gateway container (เช่น 192.168.1.100) หรือใช้ Docker network hostname หากทั้งสอง container แชร์ network เดียวกัน (ดู Compose example ด้านล่าง)
| Environment variable | Description | Default |
|---|---|---|
GATEWAY_HEALTH_URL | Base URL ของ API server ของ gateway เช่น http://gateway:8642 | (unset — local PID check only) |
GATEWAY_HEALTH_TIMEOUT | Timeout ของ health probe เป็นวินาที | 3 |
หากไม่มี GATEWAY_HEALTH_URL dashboard จะ fallback ไปที่การตรวจจับ process ภายในเครื่อง ซึ่งจะใช้งานได้ก็ต่อเมื่อ gateway รันอยู่ใน container เดียวกันหรือบน host เดียวกันเท่านั้น
Running interactively (CLI chat)
ในการเปิดเซสชัน chat แบบ interactive กับ data directory ที่กำลังรันอยู่:
docker run -it --rm \
-v ~/.hermes:/opt/data \
nousresearch/hermes-agentPersistent volumes
volume /opt/data คือแหล่งข้อมูลความจริง (single source of truth) สำหรับสถานะทั้งหมดของ Hermes มันจะ map ไปยังไดเรกทอรี ~/.hermes/ ของ host และประกอบด้วย:
| Path | Contents |
|---|---|
.env | API keys และ secrets |
config.yaml | การตั้งค่า Hermes ทั้งหมด |
SOUL.md | บุคลิกภาพ/ตัวตนของ Agent |
sessions/ | ประวัติการสนทนา |
memories/ | ที่เก็บหน่วยความจำแบบ persistent |
skills/ | skills ที่ติดตั้ง |
cron/ | คำจำกัดความของงานที่กำหนดเวลา |
hooks/ | Event hooks |
logs/ | logs ขณะรัน |
skins/ | CLI skins แบบกำหนดเอง |
:::warning ห้ามรัน container gateway ของ Hermes สองตัวพร้อมกันกับ data directory เดียวกันโดยเด็ดขาด - ไฟล์เซสชันและ memory stores ไม่ได้ออกแบบมาสำหรับการเข้าถึงแบบเขียนพร้อมกัน (concurrent write access) การรัน dashboard container ควบคู่ไปกับ gateway นั้นปลอดภัย เนื่องจาก dashboard ทำได้เพียงอ่านข้อมูลเท่านั้น :::
Environment variable forwarding
API keys จะถูกอ่านจาก /opt/data/.env ภายใน container คุณยังสามารถส่ง environment variables ได้โดยตรง:
docker run -it --rm \
-v ~/.hermes:/opt/data \
-e ANTHROPIC_API_KEY="sk-ant-..." \
-e OPENAI_API_KEY="sk-..." \
nousresearch/hermes-agentการใช้ flag -e โดยตรงจะเขียนทับค่าจาก .env ซึ่งมีประโยชน์สำหรับการทำ CI/CD หรือการรวมระบบกับ secrets-manager ที่คุณไม่ต้องการให้ keys อยู่บน disk
Docker Compose example
สำหรับการ deploy แบบ persistent ทั้ง gateway และ dashboard การใช้ docker-compose.yaml นั้นสะดวก:
services:
hermes:
image: nousresearch/hermes-agent:latest
container_name: hermes
restart: unless-stopped
command: gateway run
ports:
- "8642:8642"
volumes:
- ~/.hermes:/opt/data
networks:
- hermes-net
# Uncomment to forward specific env vars instead of using .env file:
# environment:
# - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
# - OPENAI_API_KEY=${OPENAI_API_KEY}
# - TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
deploy:
resources:
limits:
memory: 4G
cpus: "2.0"
dashboard:
image: nousresearch/hermes-agent:latest
container_name: hermes-dashboard
restart: unless-stopped
command: dashboard --host 0.0.0.0
ports:
- "9119:9119"
volumes:
- ~/.hermes:/opt/data
environment:
- GATEWAY_HEALTH_URL=http://hermes:8642
networks:
- hermes-net
depends_on:
- hermes
deploy:
resources:
limits:
memory: 512M
cpus: "0.5"
networks:
hermes-net:
driver: bridgeเริ่มด้วย docker compose up -d และดู logs ด้วย docker compose logs -f
Resource limits
container ของ Hermes ต้องการทรัพยากรปานกลาง ค่าต่ำสุดที่แนะนำ:
| Resource | Minimum | Recommended |
|---|---|---|
| Memory | 1 GB | 2–4 GB |
| CPU | 1 core | 2 cores |
| Disk (data volume) | 500 MB | 2+ GB (เพิ่มขึ้นตาม sessions/skills) |
Browser automation (Playwright/Chromium) เป็นฟีเจอร์ที่ใช้หน่วยความจำมากที่สุด หากคุณไม่ต้องการเครื่องมือ browser ก็เพียงพอที่ 1 GB แต่หากเปิดใช้งานเครื่องมือ browser ให้จัดสรรอย่างน้อย 2 GB
การตั้งค่า limits ใน Docker:
docker run -d \
--name hermes \
--restart unless-stopped \
--memory=4g --cpus=2 \
-v ~/.hermes:/opt/data \
nousresearch/hermes-agent gateway runWhat the Dockerfile does
image อย่างเป็นทางการนี้สร้างจาก debian:13.4 และรวมถึง:
- Python 3 พร้อม dependencies ทั้งหมดของ Hermes (
pip install -e ".[all]") - Node.js + npm (สำหรับ browser automation และ WhatsApp bridge)
- Playwright พร้อม Chromium (
npx playwright install --with-deps chromium) - ripgrep และ ffmpeg เป็น system utilities
- WhatsApp bridge (
scripts/whatsapp-bridge/)
entrypoint script (docker/entrypoint.sh) จะทำการ bootstrap data volume ในการรันครั้งแรก:
- สร้างโครงสร้างไดเรกทอรี (
sessions/,memories/,skills/, ฯลฯ) - คัดลอก
.env.example→.envหากไม่มี.env - คัดลอก
config.yamlเริ่มต้นหากขาดหายไป - คัดลอก
SOUL.mdเริ่มต้นหากขาดหายไป - Sync skills ที่ bundle โดยใช้แนวทางแบบ manifest-based (รักษาการแก้ไขของผู้ใช้)
- จากนั้นรัน
hermesด้วย argument ใดๆ ที่คุณส่งมา
Upgrading
ดึง image ล่าสุดและสร้าง container ใหม่ ไดเรกทอรีข้อมูลของคุณจะไม่ถูกแตะต้อง
docker pull nousresearch/hermes-agent:latest
docker rm -f hermes
docker run -d \
--name hermes \
--restart unless-stopped \
-v ~/.hermes:/opt/data \
nousresearch/hermes-agent gateway runหรือด้วย Docker Compose:
docker compose pull
docker compose up -dSkills and credential files
เมื่อใช้ Docker เป็น execution environment (ไม่ใช่ methods ด้านบน แต่เมื่อ agent รันคำสั่งภายใน Docker sandbox) Hermes จะทำการ bind-mount skills directory (~/.hermes/skills/) และไฟล์ credential ใดๆ ที่ประกาศโดย skills เข้าไปใน container ในรูปแบบ read-only volumes นี่หมายความว่า script, template, และ reference ของ skill จะพร้อมใช้งานภายใน sandbox โดยไม่ต้องตั้งค่าด้วยตนเอง
การ sync แบบเดียวกันนี้เกิดขึ้นสำหรับ SSH และ Modal backends - skills และ credential files จะถูกอัปโหลดผ่าน rsync หรือ Modal mount API ก่อนคำสั่งแต่ละครั้ง
Troubleshooting
Container exits immediately
ตรวจสอบ logs: docker logs hermes สาเหตุทั่วไป:
- ไฟล์
.envหายไปหรือไม่ถูกต้อง - ให้รันแบบ interactive ก่อนเพื่อทำ setup ให้เสร็จ - Port conflicts หากรันพร้อมกับการเปิด port
"Permission denied" errors
container จะรันเป็น root โดยค่าเริ่มต้น หาก ~/.hermes/ ของ host ถูกสร้างโดยผู้ใช้ที่ไม่ใช่ root สิทธิ์ควรจะใช้งานได้ หากคุณได้รับข้อผิดพลาด ให้แน่ใจว่า data directory สามารถเขียนได้:
chmod -R 755 ~/.hermesBrowser tools not working
Playwright ต้องการ shared memory ให้เพิ่ม --shm-size=1g เข้าไปในคำสั่ง Docker run ของคุณ:
docker run -d \
--name hermes \
--shm-size=1g \
-v ~/.hermes:/opt/data \
nousresearch/hermes-agent gateway runGateway not reconnecting after network issues
flag --restart unless-stopped จัดการกับความล้มเหลวชั่วคราวส่วนใหญ่ หาก gateway ค้าง ให้รีสตาร์ท container:
docker restart hermesChecking container health
docker logs --tail 50 hermes # logs ล่าสุด
docker run -it --rm nousresearch/hermes-agent:latest version # ตรวจสอบเวอร์ชัน
docker stats hermes # การใช้ทรัพยากร📄 user-guide/git-worktrees.md
sidebar_position: 3 sidebar_label: "Git Worktrees" title: "Git Worktrees" description: "Run multiple Hermes agents safely on the same repository using git worktrees and isolated checkouts"
Git Worktrees
Hermes Agent มักถูกใช้กับ repositories ขนาดใหญ่และมีอายุการใช้งานยาวนาน เมื่อคุณต้องการ:
- รัน multiple agents ในรูปแบบขนาน บน project เดียวกัน หรือ
- ต้องการแยกการ refactor แบบทดลองออกจาก main branch ของคุณ
Git worktrees เป็นวิธีที่ปลอดภัยที่สุดในการให้แต่ละ agent มี checkout ของตัวเอง โดยที่ไม่ต้องทำซ้ำ (duplicate) repository ทั้งหมด
หน้านี้จะแสดงวิธีรวม worktrees เข้ากับ Hermes เพื่อให้แต่ละ session มี working directory ที่สะอาดและแยกส่วนกัน
Why Use Worktrees with Hermes?
Hermes จะถือว่า current working directory เป็น root ของ project:
- CLI: directory ที่คุณรัน
hermesหรือhermes chat - Messaging gateways: directory ที่กำหนดโดย
MESSAGING_CWD
หากคุณรันหลาย agents ใน same checkout การเปลี่ยนแปลงของพวกมันอาจรบกวนกันได้:
- agent ตัวหนึ่งอาจลบหรือเขียนทับไฟล์ที่ agent ตัวอื่นกำลังใช้งานอยู่
- ทำให้ยากต่อการทำความเข้าใจว่าการเปลี่ยนแปลงใดเป็นของ experiment ไหน
ด้วย worktrees, แต่ละ agent จะได้รับ:
- branch และ working directory เป็นของตัวเอง
- Checkpoint Manager history เป็นของตัวเองสำหรับ
/rollback
ดูเพิ่มเติม: Checkpoints and /rollback.
Quick Start: Creating a Worktree
จาก main repository ของคุณ (ที่มี .git/) ให้สร้าง worktree ใหม่สำหรับ feature branch:
# From the main repo root
cd /path/to/your/repo
# Create a new branch and worktree in ../repo-feature
git worktree add ../repo-feature feature/hermes-experimentสิ่งนี้จะสร้าง:
- directory ใหม่:
../repo-feature - branch ใหม่:
feature/hermes-experimentที่ถูก checkout ใน directory นั้น
ตอนนี้คุณสามารถ cd เข้าไปใน worktree ใหม่และรัน Hermes ที่นั่นได้:
cd ../repo-feature
# Start Hermes in the worktree
hermesHermes จะ:
- เห็น
../repo-featureเป็น project root. - ใช้ directory นั้นสำหรับ context files, code edits, และ tools.
- ใช้ separate checkpoint history สำหรับ
/rollbackที่จำกัดขอบเขตเฉพาะ worktree นี้.
Running Multiple Agents in Parallel
คุณสามารถสร้าง worktrees หลายตัว โดยแต่ละตัวมี branch เป็นของตัวเอง:
cd /path/to/your/repo
git worktree add ../repo-experiment-a feature/hermes-a
git worktree add ../repo-experiment-b feature/hermes-bใน terminal แยกกัน:
# Terminal 1
cd ../repo-experiment-a
hermes
# Terminal 2
cd ../repo-experiment-b
hermesแต่ละ process ของ Hermes:
- ทำงานบน branch ของตัวเอง (
feature/hermes-avsfeature/hermes-b). - เขียน checkpoints ภายใต้ shadow repo hash ที่แตกต่างกัน (ได้มาจาก worktree path).
- สามารถใช้
/rollbackได้อย่างอิสระโดยไม่ส่งผลกระทบต่อตัวอื่น.
สิ่งนี้มีประโยชน์อย่างยิ่งเมื่อ:
- รัน batch refactors.
- ทดลองแนวทางที่แตกต่างกันสำหรับงานเดียวกัน.
- จับคู่ session ของ CLI + gateway กับ upstream repo เดียวกัน.
Cleaning Up Worktrees Safely
เมื่อคุณทำ experiment เสร็จแล้ว:
- ตัดสินใจว่าจะเก็บหรือทิ้ง work ที่ทำไป.
- หากคุณต้องการเก็บ:
- Merge branch นั้นเข้ากับ main branch ของคุณตามปกติ.
- ลบ worktree:
cd /path/to/your/repo
# Remove the worktree directory and its reference
git worktree remove ../repo-featureหมายเหตุ:
git worktree removeจะปฏิเสธการลบ worktree ที่มีการเปลี่ยนแปลงที่ยังไม่ได้ commit เว้นแต่คุณจะบังคับ (force) มัน.- การลบ worktree ไม่ได้ ลบ branch โดยอัตโนมัติ; คุณสามารถลบหรือเก็บ branch ได้โดยใช้คำสั่ง
git branchปกติ. - ข้อมูล checkpoint ของ Hermes ภายใต้
~/.hermes/checkpoints/จะไม่ถูกลบโดยอัตโนมัติเมื่อคุณลบ worktree แต่โดยปกติแล้วจะมีขนาดเล็กมาก.
Best Practices
- One worktree per Hermes experiment
- สร้าง branch/worktree เฉพาะสำหรับทุกการเปลี่ยนแปลงที่สำคัญ.
- วิธีนี้ช่วยให้ diffs มีโฟกัสและ PRs มีขนาดเล็กและสามารถตรวจสอบได้.
- Name branches after the experiment
- เช่น
feature/hermes-checkpoints-docs,feature/hermes-refactor-tests.
- เช่น
- Commit frequently
- ใช้ git commits สำหรับ milestones ระดับสูง.
- ใช้ checkpoints and /rollback เป็นตาข่ายนิรภัยสำหรับการแก้ไขที่ขับเคลื่อนด้วย tool ระหว่างนั้น.
- Avoid running Hermes from the bare repo root when using worktrees
- ควรใช้ worktree directories แทน เพื่อให้แต่ละ agent มีขอบเขตที่ชัดเจน.
Using hermes -w (Automatic Worktree Mode)
Hermes มี flag -w ที่สร้างมาให้ ซึ่งจะ สร้าง git worktree ที่ใช้แล้วทิ้งโดยอัตโนมัติ พร้อมกับ branch ของตัวเอง คุณไม่จำเป็นต้องตั้งค่า worktrees ด้วยตนเอง - เพียงแค่ cd เข้าไปใน repo ของคุณแล้วรัน:
cd /path/to/your/repo
hermes -wHermes จะ:
- สร้าง worktree ชั่วคราวภายใต้
.worktrees/ภายใน repo ของคุณ. - Checkout branch ที่แยกส่วน (เช่น
hermes/hermes-<hash>). - รัน full CLI session ภายใน worktree นั้น.
นี่เป็นวิธีที่ง่ายที่สุดในการได้ worktree isolation คุณยังสามารถรวมมันเข้ากับการ query เดียวได้:
hermes -w -q "Fix issue #123"สำหรับ agents แบบขนาน ให้เปิดหลาย terminal และรัน hermes -w ในแต่ละตัว — ทุกการเรียกใช้จะได้รับ worktree และ branch เป็นของตัวเองโดยอัตโนมัติ.
Putting It All Together
- ใช้ git worktrees เพื่อให้แต่ละ session ของ Hermes มี checkout ที่สะอาดเป็นของตัวเอง.
- ใช้ branches เพื่อบันทึก history ระดับสูงของการทดลองของคุณ.
- ใช้ checkpoints +
/rollbackเพื่อกู้คืนจากข้อผิดพลาดภายในแต่ละ worktree.
การรวมกันนี้จะมอบให้คุณ:
- การรับประกันที่แข็งแกร่งว่า agents และ experiments ที่แตกต่างกันจะไม่รบกวนกัน.
- รอบการทำซ้ำที่รวดเร็วพร้อมการกู้คืนที่ง่ายจาก edits ที่ผิดพลาด.
- pull requests ที่สะอาดและสามารถตรวจสอบได้.
📄 user-guide/checkpoints-and-rollback.md
sidebar_position: 8 sidebar_label: "Checkpoints & Rollback" title: "Checkpoints and /rollback" description: "Filesystem safety nets for destructive operations using shadow git repos and automatic snapshots"
Checkpoints and /rollback
Hermes Agent จะทำการ snapshot โปรเจกต์ของคุณโดยอัตโนมัติก่อนการดำเนินการที่อาจทำให้ข้อมูลสูญหาย (destructive operations) และอนุญาตให้คุณกู้คืนด้วยคำสั่งเดียว Checkpoints จะถูกเปิดใช้งานโดยค่าเริ่มต้น (enabled by default) - ไม่มีค่าใช้จ่ายใดๆ เลยแม้ว่าเครื่องมือใดๆ จะไม่ได้ทำการแก้ไขไฟล์ก็ตาม
ระบบป้องกันความปลอดภัยนี้ขับเคลื่อนโดย Checkpoint Manager ภายใน ซึ่งจะเก็บ shadow git repository แยกต่างหากที่ ~/.hermes/checkpoints/ - ทำให้มั่นใจได้ว่า .git ของโปรเจกต์จริงของคุณจะไม่ถูกแตะต้อง
สิ่งที่กระตุ้นการสร้าง Checkpoint
Checkpoints จะถูกสร้างโดยอัตโนมัติก่อนการดำเนินการเหล่านี้:
- File tools -
write_fileและpatch - Destructive terminal commands -
rm,mv,sed -i,truncate,shred, การเปลี่ยนเส้นทาง output (>) และgit reset/clean/checkout
Agent จะสร้าง checkpoint ได้สูงสุดหนึ่งจุดต่อไดเรกทอรีต่อรอบ (per directory per turn) เพื่อป้องกันไม่ให้การเซสชันที่ยาวนานเกิดการ snapshot มากเกินไป
ข้อมูลอ้างอิงด่วน
| Command | Description |
|---|---|
/rollback | แสดงรายการ checkpoint ทั้งหมดพร้อมสถิติการเปลี่ยนแปลง |
/rollback <N> | กู้คืนไปยัง checkpoint N (และยกเลิกการสนทนาครั้งล่าสุดด้วย) |
/rollback diff <N> | แสดงตัวอย่าง diff ระหว่าง checkpoint N กับสถานะปัจจุบัน |
/rollback <N> <file> | กู้คืนไฟล์เดียวจาก checkpoint N |
Checkpoints ทำงานอย่างไร
ในระดับสูง:
- Hermes จะตรวจจับเมื่อเครื่องมือกำลังจะ แก้ไขไฟล์ ใน working tree ของคุณ
- ในแต่ละรอบการสนทนา (ต่อไดเรกทอรี) มันจะ:
- กำหนด root project ที่เหมาะสมสำหรับไฟล์
- เริ่มต้นหรือใช้ซ้ำ shadow git repo ที่ผูกกับไดเรกทอรีนั้น
- ทำการ stage และ commit สถานะปัจจุบันพร้อมเหตุผลสั้นๆ ที่อ่านเข้าใจได้
- commit เหล่านี้จะก่อให้เกิดประวัติ checkpoint ที่คุณสามารถตรวจสอบและกู้คืนได้ผ่าน
/rollback
flowchart LR
user["User command\n(hermes, gateway)"]
agent["AIAgent\n(run_agent.py)"]
tools["File & terminal tools"]
cpMgr["CheckpointManager"]
shadowRepo["Shadow git repo\n~/.hermes/checkpoints/<hash>"]
user --> agent
agent -->|"tool call"| tools
tools -->|"before mutate\nensure_checkpoint()"| cpMgr
cpMgr -->|"git add/commit"| shadowRepo
cpMgr -->|"OK / skipped"| tools
tools -->|"apply changes"| agentการตั้งค่า (Configuration)
Checkpoints เปิดใช้งานโดยค่าเริ่มต้น สามารถกำหนดค่าได้ใน ~/.hermes/config.yaml:
checkpoints:
enabled: true # master switch (default: true)
max_snapshots: 50 # max checkpoints per directoryหากต้องการปิดใช้งาน:
checkpoints:
enabled: falseเมื่อปิดใช้งาน Checkpoint Manager จะเป็น no-op และจะไม่พยายามดำเนินการ git ใดๆ
การแสดงรายการ Checkpoints
จาก CLI session:
/rollbackHermes จะตอบกลับด้วยรายการที่จัดรูปแบบซึ่งแสดงสถิติการเปลี่ยนแปลง:
📸 Checkpoints for /path/to/project:
1. 4270a8c 2026-03-16 04:36 before patch (1 file, +1/-0)
2. eaf4c1f 2026-03-16 04:35 before write_file
3. b3f9d2e 2026-03-16 04:34 before terminal: sed -i s/old/new/ config.py (1 file, +1/-1)
/rollback <N> restore to checkpoint N
/rollback diff <N> preview changes since checkpoint N
/rollback <N> <file> restore a single file from checkpoint Nแต่ละรายการจะแสดง:
- Short hash
- Timestamp
- Reason (สิ่งที่กระตุ้นการ snapshot)
- Change summary (ไฟล์ที่เปลี่ยนแปลง, การเพิ่ม/การลบ)
การดูตัวอย่างการเปลี่ยนแปลงด้วย /rollback diff
ก่อนที่จะ commit ไปสู่การกู้คืน ควรดูตัวอย่างว่าอะไรเปลี่ยนแปลงไปตั้งแต่ checkpoint:
/rollback diff 1สิ่งนี้จะแสดงสรุปสถิติ git diff ตามด้วย diff จริง:
test.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test.py b/test.py
--- a/test.py
+++ b/test.py
@@ -1 +1 @@
-print('original content')
+print('modified content')diff ที่ยาวจะถูกจำกัดไว้ที่ 80 บรรทัดเพื่อป้องกันไม่ให้ terminal ล้น
การกู้คืนด้วย /rollback
กู้คืนไปยัง checkpoint ตามหมายเลข:
/rollback 1เบื้องหลัง Hermes จะ:
- ตรวจสอบว่า commit เป้าหมายมีอยู่ใน shadow repo หรือไม่
- ทำการ snapshot ก่อนการ rollback ของสถานะปัจจุบัน เพื่อให้คุณสามารถ "ยกเลิกการยกเลิก" ได้ในภายหลัง
- กู้คืนไฟล์ที่ถูกติดตาม (tracked files) ใน working directory ของคุณ
- ยกเลิกการสนทนาครั้งล่าสุด เพื่อให้ context ของ agent ตรงกับสถานะ filesystem ที่กู้คืนมา
เมื่อสำเร็จ:
✅ Restored to checkpoint 4270a8c5: before patch
A pre-rollback snapshot was saved automatically.
(^_^)b Undid 4 message(s). Removed: "Now update test.py to ..."
4 message(s) remaining in history.
Chat turn undone to match restored file state.การยกเลิกการสนทนาช่วยให้มั่นใจว่า agent จะไม่ "จดจำ" การเปลี่ยนแปลงที่ถูก rollback ซึ่งช่วยป้องกันความสับสนในรอบถัดไป
การกู้คืนไฟล์เดียว
กู้คืนเพียงไฟล์เดียวจาก checkpoint โดยไม่กระทบต่อส่วนอื่นๆ ของไดเรกทอรี:
/rollback 1 src/broken_file.pyสิ่งนี้มีประโยชน์เมื่อ agent ทำการเปลี่ยนแปลงไฟล์หลายไฟล์ แต่มีเพียงไฟล์เดียวที่ต้องการย้อนกลับ
มาตรการความปลอดภัยและประสิทธิภาพ (Safety and Performance Guards)
เพื่อให้การทำ checkpoint ปลอดภัยและรวดเร็ว Hermes จึงใช้มาตรการป้องกันหลายอย่าง:
- Git availability - หากไม่พบ
gitในPATHการทำ checkpoint จะถูกปิดใช้งานอย่างโปร่งใส - Directory scope - Hermes จะข้ามไดเรกทอรีที่กว้างเกินไป (เช่น root
/, home$HOME) - Repository size - ไดเรกทอรีที่มีไฟล์มากกว่า 50,000 ไฟล์จะถูกข้ามเพื่อหลีกเลี่ยงการดำเนินการ git ที่ช้า
- No-change snapshots - หากไม่มีการเปลี่ยนแปลงใดๆ นับตั้งแต่ snapshot ล่าสุด checkpoint จะถูกข้าม
- Non-fatal errors - ข้อผิดพลาดทั้งหมดภายใน Checkpoint Manager จะถูกบันทึกที่ระดับ debug; เครื่องมือของคุณจะยังคงทำงานต่อไป
Checkpoints อยู่ที่ใด
shadow repo ทั้งหมดจะอยู่ภายใต้:
~/.hermes/checkpoints/
├── <hash1>/ # shadow git repo for one working directory
├── <hash2>/
└── ...แต่ละ <hash> ได้มาจาก absolute path ของ working directory ภายในแต่ละ shadow repo คุณจะพบ:
- Standard git internals (
HEAD,refs/,objects/) - ไฟล์
info/excludeที่มีรายการ ignore ที่คัดสรรมา - ไฟล์
HERMES_WORKDIRที่ชี้กลับไปยัง root project ต้นฉบับ
โดยปกติคุณไม่จำเป็นต้องแตะต้องสิ่งเหล่านี้ด้วยตนเอง
แนวทางปฏิบัติที่ดีที่สุด (Best Practices)
- เปิดใช้งาน checkpoints ไว้ - โดยค่าเริ่มต้นและไม่มีค่าใช้จ่ายใดๆ เมื่อไม่มีการแก้ไขไฟล์
- ใช้
/rollback diffก่อนกู้คืน - เพื่อดูตัวอย่างว่าอะไรจะเปลี่ยนแปลง เพื่อเลือก checkpoint ที่ถูกต้อง - ใช้
/rollbackแทนgit resetเมื่อคุณต้องการยกเลิกเฉพาะการเปลี่ยนแปลงที่เกิดจาก agent เท่านั้น - รวมกับการใช้ Git worktrees เพื่อความปลอดภัยสูงสุด - ให้เก็บแต่ละเซสชัน Hermes ไว้ใน worktree/branch ของตัวเอง พร้อมด้วย checkpoints เป็นชั้นความปลอดภัยเพิ่มเติม
สำหรับการรัน agent หลายตัวแบบขนานบน repo เดียวกัน โปรดดูคู่มือที่ Git worktrees
extent analysis
TL;DR
The issue is related to the Hermes Agent's session management and checkpoint system, which is designed to provide a safety net for destructive operations, but the exact problem is not specified.
Guidance
To resolve the issue, consider the following steps:
- Check the session logs: Review the session logs to identify any errors or warnings related to the checkpoint system.
- Verify checkpoint configuration: Ensure that the checkpoint system is enabled and configured correctly in the
~/.hermes/config.yamlfile. - Use the
/rollbackcommand: If you need to recover from a destructive operation, use the/rollbackcommand to restore the previous checkpoint. - Check for git availability: Make sure that
gitis installed and available in the system'sPATH. - Review the shadow repository: If necessary, inspect the shadow repository located at
~/.hermes/checkpoints/to understand the checkpoint history.
Example
To recover from a destructive operation, you can use the /rollback command followed by the checkpoint number:
/rollback 1This will restore the system to the state of the specified checkpoint.
Notes
The checkpoint system is designed to provide a safety net for destructive operations. If you encounter any issues, ensure that the system is configured correctly and that git is available. Additionally, be cautious when using the /rollback command, as it can potentially overwrite changes made since the last checkpoint.
Vote matrix · Quick signals
Still need to ship something?
×6Another batch ranked right after the header list — different links, same matching logic.
TRENDING
- Feature Request: Configurable per-minute rate limiting (RPM) for models to prevent 429 errors
- Android: Hermes App + Termux install share ~/.hermes and cause silent permission loops
- hermes update emits unicode-animations ANSI demo in non-interactive logs
- hermes update downgrades aiohttp from 3.13.4 to 3.13.3
- npm install warns about deprecated @babel/plugin-proposal-private-methods
- DingTalk inbound media URLs are skipped as unreadable native image paths
- fix(dashboard): ChatPage clears header action buttons on ALL pages, not just Sessions
- [Bug]: check_web_api_key() hardcodes built-in backends — third-party web search plugins silently disabled
- Hermes Web UI 修复经验:GatewayManager 补丁、进程 D 状态、数据库升级问题
- Telegram gateway can silently drop turn after /stop with response=0 chars while internal work continues
- Bug Report: v0.14.0 上下文污染 — 历史回复碎片回注到新请求
- Bug: hermes skills search table truncates Identifier column — install fails with copied value
- [skills-index-watchdog] Skills index is stale or degraded (degraded)
- Discord approval embed not rendering on web/mobile — embed data present in API but invisible
- Idea: Discord voice-channel participation / opt-in auto-join mode
- [Feature]: Claude Code--ultrawork
- build-arm64 job deterministically fails on cold cache (Azure SAS token expires mid-build)
- [Enhancement] computer_use: action=type should fall back to key events for terminal emulators (Ghostty/Terminal.app/iTerm2)
- Feature Request: Session Recovery on Temporary Provider Outage
- [Bug]: Hermes dashboard not working on NixOS (container)
- [Feature]: Add option to ignore @all/@everyone mentions in Feishu group chats
- QQ Bot WebSocket 频繁断开:长时间工具执行阻塞 asyncio 事件循环导致心跳超时
- patch tool: new_string escape sequences (\t) get written literally
- Feature Request: i18n / 多语言支持(国际化)
- Bug: web_crawl schema lets models auto-guess "instructions" instead of asking the user via clarify
- feat: `!command` prefix for direct shell execution (like Claude Code)
- Expose currently-running cron jobs via /api/jobs (or new endpoint)
- [Bug]: Kanban parent-child handoff: scratch workspace GC destroys artifacts before child can read them
- [Bug, Windows] hermes gateway restart loses session context — planned_stop_marker not written before SIGTERM
- [Bug]: Codex→DeepSeek fallback sends assistant turns without reasoning_content → HTTP 400 (require-side cross-provider failover)
- [Bug]: Update got stuck half way, reboot it, then ModuleNotFoundError: No module named 'hermes_cli'
- Kanban dispatcher corrupt-board handling and multi-profile gateway ownership ambiguity
- Gateway can resend a short fallback message when the real final Telegram response was already delivered
- [BUG] Bedrock: Fix 'Invalid API Key format' for presigned URL tokens
- Secret redaction corrupts code syntax in tool output (write_file, execute_code, terminal)
- Unable to connect Ollama Cloud with Pro Subscription to Hermes
- feat: fuzzy substring matching for /skill autocomplete
- PRD: Autonomous market-impact prediction briefing system
- Kanban dashboard should support task/card deep links
- [Feature] Native Feishu CardKit Streaming: consolidate best-in-class implementations
- [Feature]: Inject mental model into context when using Hindsight
- Interactive CLI hides tool output despite display.tool_progress=all, and hermes chat -v does not restore it
- fix(api_server): _handle_responses drops text.format JSON schema — structured output constraints silently ignored
- state.db FTS corruption goes undetected — no integrity check, no repair path
- bug: fallback routing can select text-only models for image requests and hide the primary failure
- feat(kanban): persist worker session_id per run and pass --resume on respawn after unblock
- feat(kanban): support GitHub/OMO lifecycle bridge for Xiyou-style automation
- Expose update-safe TUI/composer hooks for voice transcript and composer events
- Hide or configure voice transcript status rows in editable dictation mode
- [Feature]: Per-Tool / Per-Toolset Approval Policies
- Context compression creates orphan sessions missing from state.db
- messaging platform
- feat: Add read-only / silent monitoring mode for WhatsApp adapter
- double-.hermes path mismatch, the HOME env var leak, and the fallback-notification UX problem
- Bug: Plattform-Bundle name `hermes-yuanbao` in `agent.disabled_toolsets` silently kills ALL tools in gateway path (Telegram + cron), CLI unaffected
- CLI /yolo (in-chat) does not bypass dangerous command approvals — env var freeze + missing enable_session_yolo call
- OpenAI Codex provider crashes with "'NoneType' object is not iterable" (HTTP None)
- DEEPSEEK_API_KEY blocked by env blocklist in gateway process — cron jobs fail with deepseek provider
- fix(feishu): Card action callback routing issues - invalid message_id and unrecognized /card command
- Discord plugin: profiles without explicit `discord:` block silently get `require_mention=true` + `auto_thread=true` (regression in cc8e5ec2a)
- [Bug]: DISCORD_ALLOWED_ROLES ignored by gateway _is_user_authorized — role-authorized users get 'Unauthorized user' rejection
- [Bug]: /new, /clear, and /reset commands freeze the terminal session
- openai-codex subscription backend returns HTTP 200 with response.output=None, causing Slack/cron failures
- RFC: Centralized Model/Provider Registry
- bug: openai-codex provider — TypeError: 'NoneType' object is not iterable on every request (gpt-5.5)
- [Feature]: Source-aware instruction gate — architectural mitigation for indirect prompt injection
- Named custom provider stale_timeout_seconds ignored because runtime provider is normalized to `custom`
- guard test (ignore)
- [Feature]: per-platform LLM request_overrides (extra_body / reasoning_effort / service_tier)
- One-shot smoke: add Flue-backed orchestration fixture
- Gateway should not treat stale Codex app-server progress as final response after post-tool silence
- `docker_run_as_host_user: true` breaks bundled skills: Hermes home is mounted into `/root/.hermes` but the container runs as a non-root user (`HOME=/home/pn`)
- [Bug]: gateway api_server streaming bypasses server-side tool-call loop when chat_template_kwargs.enable_thinking=false (model emits tool name as plain text)
- [Feature]: Pre-install python-telegram-bot in Umbrel Hermes Docker image
- YouTube Shorts filter not working in youtube-content skill
- v0.15.0 PyPI release breaks ALL platforms — plugin.yaml manifests missing from package
- RFC: On-demand tool/skill/MCP discovery — decouple schema registration from process lifecycle
- Pixshelf: local-first stock photo workflow command center
- [Bug]: baoyu infographic skill should not silently bypass image_generate
- Pixshelf v1.5: manual submission tracking for stock agencies
- `hermes config set` silently accepts unknown keys, writing them where the runtime never reads
- Honcho memory prefetch hang on fresh CLI subprocess in v0.15.0 (regression from #27190)
- [Bug] v0.15.0 Docker image: stage2-hook.sh, main-wrapper.sh missing; container_boot module removed
- Feature: Reduce cache-read token overhead for DeepSeek providers — configurable cache_ttl, skills snapshot trimming, memory compaction
- Windows: three bugs from daily use (plugin discovery, gateway exit code, Unicode decode
- holographic memory: HRR silently degrades to FTS5 when numpy is missing
- Make max_tokens configurable for aux vision calls
- Conversation compression desynchronizes session ID between agent context and gateway routing, causing silent message loss
- [Bug]: v0.15.0 Docker image:The TUI cannot be used in the dashboard.
- cron: skip_memory=True blocks fact_store/memory tools from all cron jobs
- TUI: Node.js OOM crash when agent uses browser tools repeatedly
- feat: model_profiles — per-model toolset and memory config
- Automatic background skill patching disrupts active sessions (severe impact on local models)
- ensure_hermes_home() creates root-owned dirs in profile subdirectories when kanban workers are dispatched
- Feature: opt-in webhook bypass for DISCORD_ALLOW_BOTS — allow operator-initiated probes without weakening bot-loop guard
- v0.15.0: Codex requests fail HTTP 400 when participant display_name contains non-ASCII (emoji breaks input[].name pattern)
- Architecture: State Persistence Precedence (Memory vs Skills vs Hooks)
- [Bug]: cronjob tool: create action always fails with "schedule is required for create" even when parameters are provided
- codex-oauth: 'NoneType' object is not iterable in _run_codex_stream (gpt-5.5) — every turn fails non-retryably
- Docs/Config: Plugin local scope enablement ambiguity
- [Bug]: CLI freezes after using /new command (WSL)
- Profile Codex auth can ignore global credential pool when local state is stale
- [workflow-engine] CRITICAL: variable substitution crashes on regex metachars in user input
- [workflow-engine] HIGH: loop and bash nodes leak subprocesses on timeout
- [workflow-engine] HIGH: README documents config env vars the engine never reads
- [workflow-engine] MEDIUM: workflow_run rate limit bypassable via concurrent calls (TOCTOU)
- [workflow-engine] chore: manifest gaps, side-effectful register(), dead code, unauth kanban dispatch
- [mcp_lazy] HIGH: synthetic mcp_server_<name> stub collides with a real MCP server named 'server'
- [mcp_lazy] HIGH: promote_server eager flag documented but never persisted
- [mcp_lazy] MEDIUM: _prev_mode dict leaks and goes stale; not cleared on session evict
- [mcp_lazy] MEDIUM: get_pool has unlocked check-then-set race on pool creation
- [mcp_lazy] MEDIUM: pre_tool_call gives no guidance for unpromoted server-stub calls
- [mcp_lazy] chore: undeclared pre_tool_call hook, nonexistent 'mcp_load_tools' name in docs, missing tests
- [a2a_fleet] CRITICAL: server never auto-starts — register() runs outside an event loop
- [a2a_fleet] CRITICAL: auth_required defaults to false on a cross-machine surface
- [a2a_fleet] HIGH: remove invented disable() hook — loader never calls it, port leaks on reload
- [a2a_fleet] HIGH: plugin.yaml missing kind / provides_tools / requires_env (token env undeclared)
- [a2a_fleet] MEDIUM: tighten wide-open CORS, anonymous /health peer leak, and peer-URL SSRF
- [a2a_fleet] MEDIUM: relocate tests to tests/plugins/ and cover sync-register + auth-default paths
- xai-oauth auxiliary client incorrectly uses Responses API (CodexAuxiliaryClient), causing 403 on compression/vision/web_extract
- [Bug]: Direct Copilot gpt-5.5 large resumes are killed by 12s Codex TTFB watchdog
- [Bug]: `hermes uninstall` does not work on Windows
- TUI: Thinking block leaks raw JSON and Σ character
- Hostinger VPS: migration Hermes Agent → Hermes WebUI impossible (tini + UID mismatch + sessions)
- /goal judge over-continues exploratory goals unless the assistant explicitly says the goal is complete
- /goal auto-continuation can be amplified by preflight compression/session split and resurrect stale task state
- Dashboard infinite reload loop in loopback mode — GET /api/auth/me returns 401 on every page load
- [Bug]: Provider/LLM switch leaves stale encrypted_content causing 400 errors on Telegram sessions
- [Bug]: Infinite reload loop / React state loop on Sessions tab (Firefox + Chrome) — repeated 401 on /api/auth/me (v0.15.0)
- show_reasoning should work independently of streaming in CLI mode
- Feature Request: Strip reasoning/<think> blocks from TTS preprocessing
- mcp add / mcp test raise NameError when mcp package not installed
- v0.14.0 dashboard breaks behind reverse proxies — two regressions
- Skills hub creates empty category directories when no skills installed
- [Bug]: Custom endpoint: ChatCompletions returns content, but Hermes treats response as empty (v0.14.0)
- fix: atomic_replace() fails with EXDEV when HERMES_HOME is a cross-filesystem symlink
- fix(gateway): Feishu session cancellation orphans session guard, permanently blocking messages
- Custom endpoint pricing can overestimate Crof qwen3.5-9b cost by 1,000,000x
- MCP OAuth callback: module-level port global causes port collisions and structural weaknesses vs upstream
- Bug: send_message tool bypasses validate_media_delivery_path security check
- Proposal: Add Mnemosyne to official memory provider documentation
- feat(swarm): support custom verifier/synthesizer body + skills
- Template conversion failed
- Error occurred in the operation of the agent node in the workflow.
- PubSub client overrides Sentinel client when REDIS_USE_SENTINEL is enabled
- Frontend description of the Retrieval node output does not match the actual output
- JSON type input var raise Intenal server error
- cannot extract elements from a scalar
- 负载均衡 为模型配置多组凭据,并自动调用,此功能无法选择
- add models is error
- panic: could not create filter
- Persist partially generated messages when /chat-messages/:task_id/stop is called
- MCP server connection fails with 403 — request never leaves Dify (SSRF proxy suspected)
- Support durable async execution backends for long-running workflow steps
- [Xiaomi MiMo] Credentials validation fails with 400 "Not supported model mimo-v2-flash" when using Token Plan endpoint (v0.0.7)
- After clicking preview on a parent-child segmented knowledge base, it shows 0 chunks
- Retrieval score differs between UI upload (.docx) and API upload (.txt) despite identical chunk content and embedding model
- gemini cli crash again
- Xbox gift card code damage
- Damage caused by the gemini cli crash
- ioctl(2) failed, EBADF (Bad File Descriptor)
- Feat: Support Bun as an alternative runtime/package manager for updates and extensions
- fatal error again!!!!
- ioctl error
- Critical Crash: ioctl(2) failed, EBADF in ShellExecutionService.resizePty
- ioctl(2) failed, EBADF
- v0.44.0 Regression: Critical crash with ioctl(2) failed, EBADF during PTY resize
- Crash on startup: ioctl(2) failed, EBADF in UnixTerminal.resize
- Crash: `ioctl(2) failed, EBADF` in `node-pty` during PTY resize on macOS
- Gemini CLI crashes with `ioctl(2) failed, EBADF` in `node-pty` during `resizePty`
- Remote Role
- ERROR ioctl(2) failed, EBADF /home/mich
- RangeError: Maximum call stack size exceeded
- EBADF Error during folder creationg broke session and terminal glitches
- MAIP / Gargoub Project - Mediterania - North Coast
- Gemini cli crash again in this morning
- ERROR ioctl(2) failed, EBADF
- Verified node install fails — Checksum verification failed (Cloud)
- The extended debugging key did not arrive during registration.
- CollaborationPane unmounts collaboration store on single-user instances, causing permanent "No network connection" state
- Workflow cannot be saved when the name contains "->" (Potentially malicious string)
- automation does not work and does not show an error
- Raj Ai Automation
- Default Data Loader: DOMMatrix is not defined error
- Feature: Per-node execution timestamp overlay on canvas during workflow run
- AI Agent + Vertex `gemini-3.5-flash`: 400 "missing thought_signature" on sequential multi-turn tool calls (post-#24982)
- PDF Loader in Pinecone Vector Store fails due to pdf-parse version conflict (v2 not supported)
- emailReadImap: add UID deduplication, batch size cap, and numeric uid enforcement
- Manual node execution fails with "Could not find a node" when autosave is disabled (N8N_WORKFLOWS_AUTOSAVE_DISABLED)
- Schedule Trigger stopped firing — workflow Published & active, manual executions succeed, no automated fires for 2+ hours
- [MCP SDK] create_workflow_from_code intermittently returns HTTP 500, often as a false negative (workflow persists anyway, causing duplicates on retry)
- Credential-load wedge: workflows using googleApi/jwtAuth credentials silently fail to execute after key rotation
- Google Sheets Trigger every minute is not working manual Execute is working sent email
- [BUG] Plugin marketplace MCP connector remains stuck "still connecting" when mcp-remote requires OAuth
- [redacted at user request]
- Opus 4.7 behavioral regression: loaded instruction-following discipline degraded in recent Claude Code/Cowork updates
- [BUG] Tailscale via Homebrew CLI + Mac App Store GUI, both Macs on macOS, Cowork blocked by VPN detector despite Tailscale being a mesh VPN with no traffic interception
- stopShellPty on tab switch kills active sessions (exit 143) — regression in May 27 build
- [BUG] Long URLs are broken into multiple lines and become unclickable in terminal output
- [BUG] claude rm/stop/reap SIGKILLs background session tree without SIGTERM grace, orphaning git index.lock and similar
- [BUG] Default git workflow in the system prompt was pushed without context or consent
- [MODEL] Inconsistent output quality / Ignoring instructions (overfitting and inappropriate repetition of Korean vocabulary)
- You've hit your weekly limit · resets May 31 at 5pm (Asia/Shanghai)
- Paid yearly subscription silently downgraded to Free with no user action
- [Regression v2.1.153] Plugin bash hooks fail with "echo: write error: Permission denied" on Windows (claude-mem, shell: "bash")
- [BUG] Connector toggles in conversation are not clickable — must click text label instead
- [remote-control] Input from mobile app/browser not reaching host session — output works fine
- Model fails to read/reference CLAUDE.md contents despite being loaded in context
- [BUG] Claude Desktop reinstall destroys Code chat history (transcripts + Recents) while regular Chat history, project files, and memory all survive
- Bypass mode clamps to Accept Edits even with the toggle ON (Claude Code Desktop 1.9255.2 / CC 2.1.149)
- [BUG] TUI input freezes randomly mid-typing — entire prompt becomes unresponsive for minutes
- [BUG] Cowork downloads Linux ELF binary instead of macOS binary on macOS Sonoma 14.8.7 — exit code 132 (SIGILL) on every session
- [Feature Request] Persistent project memory — sessions forget everything on close, forcing users to keep many sessions open
- [Bug] Thread context stale after sleep/resume, returns outdated date and calendar data
- [FEATURE] Add context window usage indicator and warning before auto-compaction
- [BUG] Dictation error: Invalid character in header content ["x-config-keyterms"] on Windows
- [Bug] Anthropic API Error: Server rate limiting despite normal usage
- Does delegating work to `claude -p` subprocesses reduce context accumulation in the parent session?
- [BUG] Claude Code hangs on M1 Mac when terminal says "opening browser to sign in" and browser opens
- [BUG] Claude_Preview MCP preview_start spawns dev server with main-repo cwd instead of session's worktree cwd
- [Bug] Anthropic API Error: Server rate limiting during request execution
- [Bug] Anthropic API Error: Server rate limiting on concurrent requests
- [Bug] Ultraplan ready notification fires before cloud agent completes execution
- [BUG] API 500 ERROR ALL THROUGHOUT THE DAY
- [BUG] Cowork: Live Artifacts folder path changed in 1.9255.2, no automatic migration from Documents\Claude\Artifacts
- [Bug] Auto-compact never triggers despite statusline reporting "100% context used" (v2.1.153, Max sub, 200K mode)
- [BUG] [Desktop / macOS] 'Open in → New Window' detached session: font renders smaller than main, no per-window controls, Cmd+/Cmd- keystrokes routed to main window instead
- Feature request: option to switch between classic and new minimal UI
- [Feature Request] Show timestamps for each message
- [BUG] Terminal corruption when permission prompt appears while navigating Agent Teams agent selection menu
- [FEATURE] Allow users to customize the background color of the Claude desktop app beyond the current light/dark theme presets.
- [BUG] Statusline not displaying on Windows [fixed]
- Background agent UI Stop button is a no-op for stuck agents — process keeps consuming tokens
- Background agents silently die on session pause/resume — no completion notification, no work recovery
- Add option to hide email address from welcome banner
- [BUG] SSH Remote: `projects` field in remote ~/.claude.json becomes null after desktop restart — jsonl files intact, UI shows 'No messages yet' for every session
- [Bug] Claude Code not applying fixes despite claiming to complete tasks
- billing is unfair and poorly documented
- [BUG] Claude Code on the web: declared plugins inactive on first session, require restart to fully load
- [BUG] Restore from archive deleted sessions instead of restoring them
- [BUG] M365 connector fails with AADSTS50011 in Cowork — localhost vs 127.0.0.1 redirect URI mismatch
- claude agents: workflow slash-commands missing from dispatch-input completion (regression-adjacent to #61424)
- Claude Desktop's Info.plist missing TCC usage strings, blocks all EventKit-based MCP servers
- False-positive safety blocks on self-administered governance amendments — request for owner-authority mode for verified professional users
- [BUG] Stop pushing "AUTO"-mode
- [DOCS] Plugin marketplace guide omits `skipLfs` option for git-based sources
- [DOCS] MCP docs omit combined startup notification for MCP server and connector authentication
- [DOCS] Agent view docs omit macOS Privacy & Security identity for background agents
- [DOCS] Npm update docs do not explain release-channel behavior for `claude update`
- [DOCS] Agent SDK docs omit `subagent_type: "claude"` worktree and output persistence behavior
- [DOCS] Background session docs omit `$CLAUDE_JOB_DIR` temp-file behavior
- [FR] mask env-var values in 'claude mcp get <server>' output
- [FR] subagent worktrees should not inherit stale local 'user.email' from prior dispatches
- [BUG] Windows: Grep tool leaks rg.exe + conhost.exe processes (~2000 zombies / 14 GB RAM in long sessions)
- [BUG] Stats dashboard "Peak hour" appears off by one hour
- [BUG] Diff highlight (teal SGR background) bleeds past changed text in 2.1.150–2.1.153
- [FEATURE] confirm before deleting session
- Plugin PostToolUse hooks still silently skip in Claude Desktop / Cowork (re-filing closed #51904)
- /code-review skill: silent fallback to main...HEAD reviews other people's commits, and JSON-only output is hard to read
- Monitor tool doesn't source the shell snapshot like Bash does; PATH-dependent tools (jq, sleep, etc.) fail in Monitor commands on macOS/Nix
- [Bug] Long input lines truncated with ellipsis while typing instead of wrapping in terminal UI
- [FEATURE] VS Code extension: Render submitted user messages as Markdown in chat
- OSC 52 copy from Claude TUI doesn't reach clipboard inside tmux (regression in 2.1.146–2.1.153)
- [BUG] RemoteTrigger create/update returns HTTP 400 with circular error: "event_type is required" / "unknown field event_type"
- [BUG] Option to hide or minimize the built-in "status footer" (multi-line debug/cost panel) [re-raise of #31475]
- [Bug] Feedback submissions being closed without review or action
- [FEATURE] Word-jump cursor navigation in Chat input (option+arrow / bindable actions)
- [FEATURE] ! shell mode: filesystem tab completion
- [BUG] API Error: Usage credits required for 1M context
- claude agents: OSC 52 clipboard emission broken in tmux (regression in 2.1.146–2.1.153)
- CLI crashes on macOS 15 M3 - exit code 1
- [FEATURE] Support Cmd+V image paste from clipboard
- [FEATURE] Enhance claude.ai M365 connector to support MS Planner
- [BUG] Slash command autocomplete hijacks pasted absolute file paths starting with /
- PreToolUse hook `if` filter false-positives on complex Bash commands
- [BUG] Diff panel hangs/whites out
- Feature Request: Support drag-and-drop for binary documents (.wps, .doc, .docx, .xlsx, .pdf) in VS Code extension
- [BUG] activation of 1M context in VSCode
- [FEATURE] Support i18n / language localization for built-in slash command outputs
- Ctrl+V para colar imagens deixou de funcionar no CLI (Windows, PowerShell)
- [FEATURE] Please add Norwegian (Bokmål/Nynorsk) language support to the Claude Code interface
- [BUG] OTel log events (claude_code.user_prompt, api_request_body, tool_decision, hook_execution_complete) emitted with empty trace_id/span_id while sibling spans correlate correctly
- [BUG] Cowork crashes on every message, no VM logs generated, missing AppData\Roaming\Claude
- [FEATURE] first-class session handoff + per-session token budgets for unattended runs
- [FEATURE] Smart paste: convert clipboard code to file reference chips (like Cursor)
- [Feature Request] Restore chat pin functionality to title chat submenu
- [BUG] SIGILL issues with version 2.1.153
- [BUG] Cowork plugin upload fails with generic "Plugin validation failed" when a `description` field in any SKILL.md frontmatter contains angle brackets (`<…>`)
- [BUG] Desktop App 2.1.144+: startup scanner deletes cliSessionId from claude-code-sessions local files on every launch — session not found on disk
- [Feature Request] Add keyboard shortcut to copy last message with proper formatting
- [MODEL] Opus 4.7 not 1M
- Allow naming/renaming background agents in `claude agents` view
- Stale worktrees in .claude/worktrees/ are never cleaned up, consuming massive disk space
- Agent worktrees are never cleaned up, silently consuming disk space
- Subagent worktrees not auto-cleaned when reviewer writes scratch files
- [Bug] Skill initialization hangs for extended duration in Plan Mode
- Claude Desktop writes malformed registry Run entry (nested escaped quotes) - crashes Windows Task Manager and other Run-key parsers
- IME candidate window shows at bottom-right corner instead of caret position (Windows CMD)
- [BUG] Pressing 'Escape' doesn't close the /BTW conversation when the main conversation is asking for approval
- [BUG] Opus 4.7 (1M) intermittently emits empty-string values for tool_use.input fields, killing the session
- FleetView agent UI shows "running" with incrementing elapsed time after agent has returned
- /doctor flags context-scoped cmd+c binding as macOS conflict (false positive)
- [BUG] Text Rendering in Elvish
- Desktop app: Bypass Permissions mode flips to Accept Edits on first prompt (M5 / macOS 26.5)
- [Workaround] Date-Weekday Verification Hook — Prevents Claude from writing wrong weekdays
- [BUG] Claude Code create c:/memfs directory without asking me.
- [BUG] Claude Code's Bash execution waits forever with no processes running
- [BUG] usage stays stuck waiting for 5 hr limit after upgrading to premium seat in team plan
- [Workflow tool] resume cache is unreachable for nontrivial workflows because LLM dispatchers can't transcribe args byte-exactly
- Code review (Preview): "Add a repository" shows no results for private GitHub org repos
- [BUG] /context commands blows up context
- [Feature Request] Add precache expiry hook to enable proactive compaction before token eviction
- [BUG] Context indicator shows 0% at session start despite ~20K+ tokens already loaded
- [Feature Request] Add semantic search for --resume session history
- [Feature Request] Add session search, tagging, and filtering capabilities
- [BUG] Cowork Dispatch reports "desktop not available" on Windows 11 while standard Cowork works normally
- [Bug] Claude Code provides incorrect suggestions with high confidence despite errors
- defaultMode: acceptEdits silently overrides per-path permissions.ask rules for Write/Edit
- [FEATUR configurable tip interval (e.g. tipIntervalSeconds: 30 in settings)E]
- Plugin marketplace fails to load: schema rejects 'displayName' key (v2.1.153)
- claude agents: in-session copy uses broken OSC 52 path while overview correctly uses tmux buffer
- [BUG] Plugin agent descriptions (and custom agents) load unconditionally into context — no parity with disable-model-invocation for skills
- Crashed ultrareview consumed a free credit despite producing zero findings
- [Bug] Character rendering issue - invisible or missing text display
- [BUG] Cowork: processo Claude Code encerra com código 3 — .claude.json não contém token de autenticação (Windows 11 25H2)
- [BUG] 2.1.153 silently discards tools/list response from rmcp 0.12.0 HTTP MCP server (works in 2.1.152, wire-identical handshake)
- VS Code extension: option to auto-resume last session when reopening a workspace folder
- [Bug] Conversation continuation failure
- [BUG] Cowork crashes every time I start a new chat or attempt to continue an existing one in any project. The error displayed is: "Claude Code è andato in crash
- [Bug] Unannounced quota changes
- Native update/install fails with 'socket connection was closed unexpectedly' behind proxy — undici TLS incompatibility
- [BUG] Session name reverting after manual change
- [BUG] 非正常思考,上下文过长时,一直显示思考,点击interrupt按钮失效
- Honor `tools:` frontmatter when an agent is invoked via `@mention` — strip `Task` only when the agent did not declare it
- macOS TCC popup still recurring on v2.1.153 — "2.1.153" would like to access data from other apps
- Claude Code leaks pty handles — exhausts pseudo-terminals on macOS after long session
- [Bug] Agent fails to execute or respond to user input
- [BUG] Persistent "Expecting value: line 1 column 1 (char 0)" JSON parse error after tool execution
- [Feature Request] Implement proactive unit test coverage recommendations for recurring bugs
- VS Code panel lacks status line + terminal lacks image paste in Codespaces, forcing a tradeoff
- `/powerup` only shows ~10 lessons — allow viewing the full catalog
- [Bug] Context contamination after auto-compact with unrelated email draft of Tejo/Sado Basin
- [Bug] VSCode terminal output displays corrupted text with garbled symbols
- [Feature Request] Add LaTeX/KaTeX math rendering to TUI
- [Bug] Sub-agent PR review results not validated by orchestrating agent
- Subagents on Pro 1M tier: trivial probes pass, real workloads fail at first tool call (probe-vs-workload divergence)
- Path-scoped rules and subdirectory CLAUDE.md not loaded when creating new files matching the pattern
- AskUserQuestion: cancelling during extended thinking poisons the whole session with 400 'thinking blocks cannot be modified' (2.1.153); concurrent prompts overwrite each other
- Ideas Missing from Claude Cowork Menu (Windows)
- [BUG_BOUNTY_SAFE_POC_2026] Prompt Injection RCE Test - Command Execution Proof
- [BUG] Cowork scheduled task: execution history row not showing after successful run
- Resuming an extended-thinking session fails permanently with 400 "thinking blocks cannot be modified" (transcript stores thinking text as empty but keeps signature)
- [Bug] Plugin-registered CwdChanged and FileChanged hooks don't fire (settings.json works) — v2.1.153
- Auto-archive on PR merge / branch delete — clarify autoArchiveSessions semantics or add dedicated opt-out
- `claude mcp add` echoes Authorization header value verbatim to stdout, leaks bearer tokens to terminal and session transcripts
- [BUG] Bug report — /insights skill, Claude Code The /insights skill outputs a malformed file path.
- Plugin slash commands render with '*'-inline format instead of two-column, despite matching official plugin shape
- [Bug] Unexpected long text generation without user input or goal
- [Bug] Thinking blocks causing task progression blocked without user modification
- [BUG] (Critical!) contamination by an unknown session simirlar to the report => [Bug] Context contamination after auto-compact with unrelated email draft of Tejo/Sado Basin #63137
- [Critical] Opus 4.7 Korean output degeneration — Korean grammar itself collapses in long contexts
- [BUG] Title: Autocompact buffer persists across /clear — wastes tokens for irrelevant old context
- [Bug] Auto-Compact loses user input before processing in conversation history
- Feature: per-invocation effort parameter + runtime session-config introspection for skills
- Auto-mode classifier mislabels Azure DevOps vote -5 as "Reject" when denying PR vote actions
- [BUG] Claude Desktop and Claude Code CLI never re-register MCP tools after OAuth 2.1 handshake on a remote HTTP server
- [BUG] Workspace file tags leak across sessions
- [BUG] Ink renderer crashes on Windows 11 build 26200 (Canary) duplicate banners, terminal mode leaks, mid-operation aborts
- [BUG] Claude Code Desktop issue
- PTY master fd leak in Claude desktop app exhausts macOS kern.tty.ptmx_max after ~2-3 days
- [BUG] Claude Code — Session Management after Unexpected Interruption
- [Windows] Cowork OpenTelemetry exporter does not initialize - zero events emitted to any destination, including loopback
- [Bug] Opus 4.7: 400 `thinking blocks ... cannot be modified` on long extended-thinking sessions, triggered by history-altering events (scheduled prompts / parallel tool-call cancellation)
- [BUG] API Error: Server is temporarily limiting requests (not your usage limit) · Rate limited
- Multi-plugin custom marketplace: only first plugin registered in installed_plugins.json, skills don't load
- [BUG] Git push through the SDK's git proxy fan-outs into ~500 GitHub REST API calls, exhausting the 5,000/hour budget after a handful of pushes
- [BUG] Claude took liberties it really shouldn't with my global config
- [BUG] Agent window focus lost after navigating with arrow keys, causing scroll deadlock
- [BUG] `--model` flag silently ignored in interactive sessions (works in `--print` only)
- [BUG] Dispatch permanently shows "desktop appears offline" on Windows 11 - never worked on first use
- feat: support per-command enableWeakerNetworkIsolation as safer alternative to dangerouslyDisableSandbox
- /code-review outputs a raw JSON array instead of readable findings
- [BUG] Cowork — Additional allowed domains ignored on Team plan; same domain works on Pro plan
- Haiku
- [Bug] False positive blocking beneficial outcomes in tool execution
- 3P Bedrock SSO: credentials silently expire without triggering re-auth on day 2+
- CLAUDE_AUTOCOMPACT_PCT_OVERRIDE in settings.json env block silently ignored by autocompact logic
- Auto-compaction deletes main session JSONL before verifying summary completion, causing data loss
- [Bug] Claude Code not executing stated actions or producing expected results
- [FEATURE] Deferred Messages — Queue Input for End of Turn
- [BUG] Up/Down arrows in input box navigate history instead of moving cursor — regression in 2.1.149+
- Cancelling a parallel tool-call batch corrupts thinking blocks -> 400 "thinking blocks cannot be modified" permanently wedges the session
- Claude Code caused data loss, then contradicted itself about recovery (two incidents, one session)
- [Bug] Unclear error messages from Claude Code CLI
- [Bug] Agent tool rejecting due to context size limit exceeded
- claude agents: daemon and bg-spare processes spin at ~100% CPU when idle
- [BUG] Compaction fails with "context window limit" error even when context usage is low (e.g., 20%) — regression in v2.1.153
- Remote Control entitlement lost after May 27-28 incident — `Error: Remote Control is not yet enabled for your account` on active Max subscription
- PreToolUse hook exit code 2 does not block Write tool
- [Bug] Thinking blocks in latest assistant message are immutable
- GUI: dispatch file:// and custom-scheme clicks to OS shell handler
- Show current model in statusLine by default
- [Bug] Agent console becomes unresponsive to keyboard input after multiple agents initialized
- [FEATURE] PreToolUse hooks should have a way of updating the environment
- [Bug] Unable to start or use Claude Code CLI
- [BUG] Repository not visible in Claude Code web repo picker
- Session permanently wedged on 400 "thinking blocks cannot be modified" after parallel tool_results
- [Bug] @ autocomplete loses sibling repos after a file edit in multi-repo workspace
- Unclear error message when creating sub-agent without authentication
- [Bug] Anthropic API errors causing frequent failures and high token usage
- [BUG] @ mention file picker only shows packages, not individual files (desktop app - Code tab)
- [Bug] TUI panel footer remains sticky and consumes excessive terminal space
- PR-status polling exhausts GitHub GraphQL rate limit on repos with many open PRs
- [BUG] Windows: welcome panel not shown in some project folders (2.1.153)
- [Bug] Anthropic API Error: thinking blocks corrupted during context compaction with extended thinking enabled
- API 400 "thinking blocks cannot be modified" permanently bricks session during agent activation (interleaved thinking + tool use)
- Right-click Copy copies the whole message instead of the selection; pasted text retains dark background
- Mid-session model switch corrupts conversation when extended thinking is enabled (API 400: 'thinking blocks cannot be modified')
- [BUG] Markdown file links in chat output do not open files when clicked (VS Code extension)
- Stuck retry loop: `400 thinking blocks cannot be modified` on large interleaved-thinking turns using AskUserQuestion
- [FEATURE] Prompt user for approval before auto-compaction proceeds
- Custom MCP connectors not attachable to scheduled routines — no UUID discovery path
- [BUG] Claude in Chrome — Navigation blocked for teams.cloud.microsoft and outlook.cloud.microsoft after Microsoft domain migration**
- [BUG] Claude Desktop — Personal plugins panel renders list but is entirely non-interactive (macOS, v1.9255.2)
- [Bug] error when using Workflows
- [BUG] Persistent "update available" notification despite being on latest version
- [BUG] Sweep Agent from /code-review never completes
- [Bug] Tool calls not executing or returning results
- [FEATURE] Cloud-synced memory and settings across machines
- [Bug] Terminal UI freezes when Ctrl+O view exits during interactive prompt in plan mode
- Continuous api errors when using claude code with Opus 4.7 with thinking on low
- [Feature Request] Add support for installing and using previous Claude Code versions
- [Bug] Extended Thinking: Summarized thinking blocks fail signature validation when resent to API
- [Bug] Anthropic API Error: 'thinking' blocks cannot be modified
- [Bug] Anthropic API Error: Thinking blocks cannot be modified with extended thinking mode
- Feature request: Lazy/on-demand MCP server connections
- [Bug] Tool Arguments Parsed as String Instead of Object
- [Bug] Anthropic API Error: Insufficient context provided
- [Bug] Claude Opus occasionally uses moskovian(russian) orthography instead of Ukrainian in system-prompted responses
- Opus 4.8: backgrounded task completions (subagents AND Bash) crash with 400 "thinking blocks cannot be modified"
- [Bug] Opus 4.7 fabricates stable preferences ("my default") to rationalize arbitrary choices when challenged
- [Bug] Unable to update Claude Code CLI
- [BUG] Desktop app: /remote-control mints link + connects bridge (main.log) but in-chat link/QR panel never renders
- Feature: sessionColor and sessionName in .claude/settings.json
- [BUG] Anthropic API error: thinking blocks
- [FEATURE] Support Remote MCPs in Cowork as in Claude Code
- [Bug] Anthropic API Error: 400 Bad Request with Redacted Thinking - 0 4.7 & 4.8
- [Bug] Anthropic API Error: Cannot modify thinking blocks from different model versions
- Interleaved thinking + multi-tool turn corrupts thinking block (text blanked, signature kept) → permanent 400 'blocks must remain as they were'
- [BUG] Mode/permission changes mid-tool-loop (effortLevel: xhigh) poisons entire session
- Session failure log: Opus 4.6 ignores its own rules for an entire session
- [BUG] "400 Guardrail was enabled" error when using Claude Opus 4.8 with AWS Bedrock
- [Feature Request] Add subagent approach selection option to avoid accidental feedback
- Persistent 400 'thinking blocks in the latest assistant message cannot be modified' — interleaved thinking persisted with empty text + signature bricks sessions
- [BUG] DesktopvsApp
- [BUG] Opus 4.7 cache hit rate collapse after May 27 incident — Messages 1.1k→88.9k in 9 minutes, $630/session
- [Bug] Anthropic API Error: Invalid thinking block format
- [BUG] FUCK CLAUDE
- Opus 4.8 extended thinking: Stop hook block re-entry corrupts thinking blocks → 400
- [Bug] 4.8 Fails when accessing previous model history
- [Bug] Unintended File Modifications During Execution
- [DOCS] Model configuration docs omit lean system prompt default scope and model exceptions
- Add "Always allow globally" option to permission prompts
- Server-side model upgrade (Opus 4.7→4.8) wedges in-flight sessions with `thinking blocks cannot be modified` 400
- [DOCS] AskUserQuestion docs missing multiple-choice prompt decision threshold
- [DOCS] Agent view docs omit shell-command background session launch syntax
- [DOCS] Agent view dispatch input docs incorrectly imply `/logout` dispatches as a prompt
- [DOCS] Claude in Chrome docs omit connected-browser selection behavior
- [DOCS] Plugin docs omit `defaultEnabled: false` for opt-in plugins
- Feature Request: Customizable chat text colors for user and assistant messages
- [DOCS] `/plugin` Discover tab docs omit directory-based suggested plugin pins
- VSCode Chrome integration silently fails: 3 distinct bugs
- [DOCS] MCP stdio docs omit session environment variables
- [Bug] Anthropic API error on second request within session with Claude Opus 4.8
- Cowork emits a blank session "index" handoff on focus when a CLI session is paused awaiting input
- [DOCS] MCP docs omit `claude mcp list/get` pending-approval output for unapproved project servers
- [BUG] /compact fails with 400 error when last assistant turn contains thinking blocks
- [DOCS] `/claude-api` docs omit Opus 4.8 migration guidance
- [DOCS] Fast mode docs still recommend deprecated Opus 4.6 override variable
- [DOCS] Bash tool docs omit `$TMPDIR` consistency across sandboxed and unsandboxed commands
- [Bug] Anthropic API Error: 400 Bad Request on Extended Thinking
- [DOCS] Background session docs omit worktree-isolation behavior for spawned subagents
- Built-in mechanistic self-verification of verifiable claims (symmetric to the auto permission gate)
- [DOCS] Worktree docs do not clarify `worktree.baseRef: "head"` inside linked worktrees
- [BUG] Excessive RAM usage with multiple parallel chats (~10 sessions → 30 GB memory pressure, macOS OOM)
- [DOCS] Managed MCP policy docs omit invalid `allowedMcpServers`/`deniedMcpServers` entry behavior
- [DOCS] Effort docs omit `CLAUDE_CODE_ALWAYS_ENABLE_EFFORT` unsupported-model behavior
- Regression (2.1.147–2.1.150?): resuming an extended-thinking session after a CC update/model-switch → unrecoverable 400, session bricked
- [DOCS] Windows updater docs omit `claude.exe` in-use recovery guidance
- [DOCS] VS Code auto mode docs still tie mode-picker visibility to bypass-permissions setting
- [DOCS] MCP docs omit `/mcp` tool list and detail rendering behavior
- [DOCS] Fine-grained tool streaming docs still describe provider opt-in behavior
- bypassPermissions: session startup reads flat pref, GUI toggle writes per-account pref — they never sync
- [BUG] Claude Desktop Code tab causes disk write limit violation — 8.5GB in 11 min, macOS kills app (M5, v1.9659.1)
- Ultrareview v2.1.96: docs describe /tasks command + claude ultrareview --json subcommand that don't exist; findings hard to read after completion
- I'd be happy to help create a GitHub issue title, but I don't see the error message in your message. Could you please share the specific error you're encountering? That way I can generate an accurate and descriptive issue title for you.
- [BUG] Claude in Chrome `file_upload` rejects all scheduled-task sessions with misleading error (real cause: INVALID_SESSION)
- Extended thinking: signed thinking block 'cannot be modified' (400) permanently wedges session
- RTL text support for Hebrew (and Arabic) in Claude Code
- [Bug] Random errors occurring across multiple operations