Repository navigation
Feature: Cli
github-actions[bot] edited this page Oct 1, 2026
·
3 revisions
The thatch CLI is a Bun script at bin/thatch. It provides memory inspection, MCP server startup, hook commands for MCP hosts, the setup installer, session archaeology over the opencode database, and a read-only window on the cross-session chat directory.
| Command | Args | Flags | Stdin | Purpose |
|---|---|---|---|---|
stores |
none | none | none | List all store names |
list [store] |
optional store | none | none | List memory labels in a store |
show <label> [store] |
label, optional store | none | none | Display one memory by label |
forget <label> [store] |
label, optional store | none | none | Delete one memory by label |
search <query> [store] |
query, optional store | none | none | Semantic cosine search (limit 10; "all" searches project + global) |
mcp |
none | none | none | Start the stdio MCP server (for Claude Code, Cursor) |
reminder [--json] |
none | --json |
none | Print session-start reminder + hygiene report |
hygiene |
none | none | none | Print the hygiene report standalone |
prime |
none | none | none | Run thatch-project-primer skill via opencode/agent/claude CLI |
buffer-batch |
none | none | JSON | Append PostToolBatch payload to queue (Claude Code hook) |
buffer-tool |
none | none | JSON | Append single postToolUse interaction to queue (Cursor hook) |
flush-tools [--json] |
none | --json |
JSON | Peek queue + extraction/recall/prediction/behavior/write nudge |
flush-predictions [--json] |
none | --json |
JSON | Standalone prediction-only nudge |
setup --claude [--cursor] [--global] |
none |
--claude, --cursor, --global
|
none | Install config + instructions + hooks + skills |
session list/get/transcript/search |
per subcommand |
-s/--session, --id, --after, --before, --regex, --limit
|
none | Read-only archaeology on the opencode session database (JSONL output) |
chat list |
none | none | none | Registered chat sessions: name, human-readable age, project, topic |
chat tail |
none |
--once, --limit N|all, --match RE (repeatable), --from NAME, --to NAME, --since DT, --until DT
|
none | Follow cross-session chat: sent and read events. Backlog defaults to the last 20 messages; filters apply to follow mode too. |
| (unknown) | none | none | none | Print usage, exit 1 |
- No
--version,--help,-h, or short flags. No subcommand aliases. - Unknown command or missing required arg calls
usage()and exits 1. - Args are positional, parsed by hand from
process.argv.slice(2). No arg-parsing library. - DB opened once at startup, closed at end (except
mcpwhich closes early). - Stores default to git remote detected by
detectRepo(); "unknown" (no git repo, or a deleted project directory with no cache entry) degrades to "global". "global" is the shared store. "all" (search only) means project + global.
Runs the thatch-project-primer skill via an external CLI. Searches PATH in order: opencode, agent (Cursor CLI), claude. Uses the first found:
- opencode:
opencode run "<primer prompt>" - agent:
agent -p "<primer prompt>" --approve-mcps - claude:
claude "<primer prompt>"
Inherits stdio, exits with the child's exit code. Errors and exits 1 if none found.
Read-only window on the cross-session chat directory (cross-session-chat.md):
-
chat listrenders the roster as aligned columns under a header row (NAME/AGE/STATUS/PROJECT/TOPIC), colorized only when stdout is a TTY (formatChatRoster()inbin/thatch; pipes and QA runners get plain text). Rows are split into Active and Stale sections bysplitChatRoster(); the status column ischatLiveness()'s verdict (fresh/stalefor opencode rows,active/idlefor MCP rows). -
chat tailfollows the message stream as JSONL: oneChatTailEventper line viaformatChatTailJsonl()(a bareJSON.stringify; no ANSI, no markdown rendering, no local-time conversion - the tail is a log forjqandgrep).sentandreadare separate events linked by the messageid; broadcast fan-out is onesentper recipient withbroadcast: trueand the realto. Event shaping ischatTailDiff()insrc/chat.ts, unit-tested there.--onceprints one snapshot and exits; the snapshot includes areadevent for every shown message whoseread_atis set, sorted by time, so it is the same log a follow would have accumulated. - The backlog prints only the last
CHAT_TAIL_DEFAULT_LIMIT(20) messages;chatTailBacklog()insrc/chat.tsfilters the feed, seeds the diff state from every feed row (so the limit hides lines, not history, and a mid-follow rename or unregister cannot resurface old rows as sent events), and reports the elided count for the CLI's stderr note.filterChatTailRows()ANDs body regexes (--match, repeatable), rendered-name substrings (--from/--to, case-insensitive), and a half-open--since/--untilwindow oncreated_at; the same filter applies to follow polls, so non-matching messages stay invisible (their read events too). A--untilin the past exits after the backlog; one in the future follows until the window closes.parseChatTimeBound()acceptsYYYY-MM-DD [HH:MM]local time.
| Variable | Purpose | Default |
|---|---|---|
XDG_CONFIG_HOME |
Config home base | ~/.config |
THATCH_DB_PATH |
SQLite DB file location | $XDG_CONFIG_HOME/thatch/thatch.db |
THATCH_MODEL |
Embedding model override | Xenova/bge-small-en-v1.5 |
THATCH_RECALL_THRESHOLD |
Cosine cutoff for recall nudge | 0.55 |
THATCH_PREDICTION_THRESHOLD |
Cutoff for prediction auto-fire | 0.60 |
THATCH_BEHAVIOR_THRESHOLD |
Cutoff for behavior auto-fire | 0.60 |
THATCH_CHILD_RECONCILE_MS |
Reload window before a restored extraction child is judged finished (test knob) | 10000 |
CLAUDE_PROJECT_DIR |
Claude Code project dir | process.cwd() |
CURSOR_PROJECT_DIR |
Cursor project dir | falls through |
CLAUDE_CONFIG_DIR |
Claude config dir | ~/.claude |
CURSOR_CONFIG_DIR |
Cursor config dir | ~/.cursor |
OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS |
Enable async extraction | unset |
-
bin/thatch— the CLI (Bun script) -
bin/release— release helper (bash, separate from the main CLI)
- Memory store (memory-store.md):
stores,list,show,forget,searchsubcommands - Setup (setup.md):
setupsubcommand - Nudge pipeline (nudge-pipeline.md):
flush-tools,flush-predictions,remindersubcommands - Extraction (extraction.md):
buffer-batch,buffer-tool,flush-toolssubcommands - Hygiene (hygiene.md):
hygiene,remindersubcommands - Multi-host (multi-host.md):
mcpsubcommand starts the MCP server for Claude Code and Cursor - Session archaeology: the
sessionsubcommand group (see the table above) reads the opencode session database viasrc/session-db.ts - Cross-session chat (cross-session-chat.md): the
chatsubcommand group reads the shared chat directory and inbox
- No arg-parsing library. Args are positional, parsed by hand from
process.argv.slice(2). - No
--version,--help,-h, or short flags. No subcommand aliases. - DB opened once at startup, closed at end (except
mcpwhich closes early). - Store name auto-detected from git remote. "global" is the shared store. "all" (search only) means project + global.
- Unknown command or missing required arg calls
usage()and exits 1. -
primesearches PATH in order:opencode,agent,claude. Uses the first found.
User
- Guide: Behavior Engine
- Guide: Cli
- Guide: Code Review
- Guide: Commands
- Guide: Cross Session Chat
- Guide: Deduplication
- Guide: Default Behaviors
- Guide: Extraction
- Guide: Hygiene
- Guide: Memory
- Guide: Notifications
- Guide: Prediction Engine
- Guide: Overview
- Guide: Setup
- Guide: Skills
- Guide: Watchers
Developer
Dev Feature Guides
- Feature: Behavior Engine
- Feature: Cicd
- Feature: Cli
- Feature: Commands
- Feature: Compaction Recovery
- Feature: Cross Session Chat
- Feature: Database
- Feature: Deduplication
- Feature: Extraction
- Feature: Hygiene
- Feature: Memory Store
- Feature: Multi Host
- Feature: Notifications
- Feature: Nudge Pipeline
- Feature: Opencode Plugin
- Feature: Prediction Engine
- Feature: Qa System
- Feature: Overview
- Feature: Repo Identity
- Feature: Session Lifecycle
- Feature: Setup
- Feature: Sideband
- Feature: Watchers