-
Notifications
You must be signed in to change notification settings - Fork 1
Feature: Setup
Installs thatch into Claude Code and Cursor. opencode does not need setup --- it auto-installs skills and injects the system prompt at plugin init. All setup operations are idempotent: re-running updates drifted content without clobbering unrelated config.
For the concrete artifact paths and hook event tables each host writes, see ../setup-and-hooks.md. This doc covers the architecture: how setup commands, the marker system, detection, auto-refresh, and binary resolution fit together.
-
thatch setup --claude--- installs MCP config, CLAUDE.md instructions, hooks, and skills for Claude Code -
thatch setup --cursor--- installs MCP config, AGENTS.md instructions, hooks, and skills for Cursor -
--globalflag --- installs to user-scoped config dirs instead of project-local -
--skills-onlyflag --- refreshes just the skill files (same host and scope rules), skipping MCP config, instructions, hooks, and commands -
Marker system --- idempotent replacement of the thatch instruction block
in
CLAUDE.mdorAGENTS.mdvia start/end markers -
checkSetup--- detects installed, not-installed, or markers-broken at MCP server startup - Auto-refresh --- MCP server re-runs setup on startup if installed, updating drifted content
-
Setup warning surfacing --- first
tools/callresponse prepends a warning if setup was not run -
Binary resolution --- uses bare
thatchif on PATH (survives updates), else the absolute path to the running script
At least one of --claude or --cursor is required. Both can be passed
together. --global applies to whichever host or hosts are selected.
--skills-only narrows the run to the skill install (setupSkillsOnly
in src/setup.ts): it reuses the same path resolution and other-scope
probe as the full setup paths but only calls installSkills, so it is
safe to run in an already-set-up host when only the skill files need
refreshing.
Four artifacts, all idempotent:
-
MCP config --- project-local writes
.mcp.jsonwith a stdio thatch MCP server entry. Global prints aclaude mcp add --scope user thatch -- <bin> mcpcommand for the user to run (does not write a file, because~/.claude.jsonis too complex to write directly). -
Instructions --- appends
claudeInstructions()toCLAUDE.mdbetween start and end markers (THATCH_MARKER/THATCH_END_MARKER). Project-local:<projectDir>/CLAUDE.md. Global:$CLAUDE_CONFIG_DIR/CLAUDE.md. -
Hooks --- writes to
.claude/settings.json(project) or$CLAUDE_CONFIG_DIR/settings.json(global). Three hooks:SessionStart→thatch reminder,PostToolBatch→thatch buffer-batch,UserPromptSubmit→thatch flush-tools. Nested format:{hooks:{Event:{hooks:[{type,command}]}}}. -
Skills --- installs to the scope's skills dir: the repo's
.claude/skills/for project-local,$CLAUDE_CONFIG_DIR/skills/for--global.SHARED_SKILLSonly --- the code-review coordinator requires sub-agent dispatch, which Claude Code does not support.
Four artifacts, same idempotent pattern:
-
MCP config --- writes
.cursor/mcp.json(project) or$CURSOR_CONFIG_DIR/mcp.json(global). Same JSON shape as Claude Code. Noclaude mcp addequivalent needed --- Cursor reads the config file directly. -
Instructions --- appends
cursorInstructions()toAGENTS.mdbetween markers (CURSOR_MARKER/CURSOR_END_MARKER). Project-local:<projectDir>/AGENTS.md. Global:$CURSOR_CONFIG_DIR/AGENTS.md. -
Hooks --- writes to
.cursor/hooks.json(project) or$CURSOR_CONFIG_DIR/hooks.json(global). Flat format:{version:1, hooks:{event:[{command}]}}. Three hooks:sessionStart→thatch reminder --json,postToolUse→thatch buffer-tool,beforeSubmitPrompt→thatch flush-tools --json. -
Skills --- installs to the scope's skills dir: the repo's
.cursor/skills/for project-local,$CURSOR_CONFIG_DIR/skills/for--global(shared only).
appendBlock(path, instructions, startMarker, endMarker) handles three cases:
- Both markers found --- replace content between them. Preserve text before the start marker and after the end marker. This is the normal update path: re-running setup replaces the thatch block without touching user-written content elsewhere in the file.
-
Start marker found but end missing --- leave the file alone. This is a
corrupted state --- someone edited the file and accidentally removed the
end marker. Writing would risk clobbering content that follows the start
marker.
checkSetupreports this asmarkers-broken. - No markers --- append instructions to the end of the file (with a separator). Create the file if it does not exist.
Start markers differ by host (the text says "Claude Code" or "Cursor"). The end marker is shared.
Detects the host from environment variables set by the host process:
-
CURSOR_PROJECT_DIRset → Cursor -
CLAUDE_PROJECT_DIRset (and Cursor not) → Claude Code - Neither set → returns
null(manualthatch mcpinvocation, no check)
Cursor takes priority because Cursor also sets CLAUDE_PROJECT_DIR as an
alias. Without the priority check, Cursor sessions would be misidentified as
Claude Code.
checkSetup looks for start and end markers in the host's instructions file
--- CLAUDE.md for Claude Code, AGENTS.md for Cursor. It checks local first,
then global. Local takes priority.
| Outcome | Condition | Action |
|---|---|---|
| installed | Both markers found (local or global) | No warning |
| not-installed | No instructions file with markers | Warning surfaced on first tools/call
|
| markers-broken | Start marker found, end marker missing | Warning with file path and fix instructions |
If checkSetup returns installed, the MCP server re-runs setupClaudeCode
or setupCursor with the same scope. This updates skills, instructions, and
hooks that drifted since the last thatch setup. All operations are
idempotent --- they only write when content differs. Failure is best-effort
and logged to stderr.
This is how installations stay current without the user manually re-running setup after upgrading thatch. The next MCP session picks up new skill content, updated instructions, and any hook changes automatically.
On the first tools/call response, if a setup warning exists, the server
prepends [thatch] {warning} to the tool's text output. The agent sees it
and can tell the user to run thatch setup. The warning is cleared after one
surfacing so it does not repeat on every tool call.
Setup resolves the thatch binary via Bun.which("thatch"). If thatch is on
PATH (npm global install, opencode plugin install), it uses the bare name.
This survives updates --- the resolved path points to whatever thatch is
current at hook execution time, not a stale absolute path.
If thatch is not on PATH, setup falls back to the absolute path of the
running script. This handles one-off invocations (e.g., bun run bin/thatch setup --claude).
The resolved binary is baked into every installed hook command. Hooks are short-lived processes spawned by the host after the setup session ends, so they cannot rely on the original process's environment. The baked-in path ensures hooks keep working across sessions.
replaceThatchHooks / replaceCursorThatchHooks filter out any existing hook
group whose command contains the string thatch, then add the current
ones. Non-thatch hooks are preserved. This handles legacy hooks --- for
example, an older thatch echo hook is replaced with the current
flush-tools hook without touching hooks from other tools.
- Multi-host --- setup is the installation mechanism for Claude Code and Cursor. opencode auto-installs at plugin init.
- Skills --- setup installs skills as part of the install. Skill content is plugin-owned and overwritten on drift.
- Nudge pipeline --- setup installs the hooks that drive the nudge pipeline for MCP hosts.
-
Extraction --- setup installs the
buffer-batch/buffer-toolhooks that feed the file-backed extraction queue. -
Sideband --- setup installs
flush-tools, which connects to the sideband socket for warm-model access during nudge evaluation.
| File | Role |
|---|---|
src/setup.ts |
setupClaudeCode, setupCursor, checkSetup, appendBlock, marker definitions, hook replacement |
bin/thatch |
setup subcommand --- parses flags, dispatches to setupClaudeCode / setupCursor
|
src/prompts.ts |
claudeInstructions, cursorInstructions --- the instruction text appended to CLAUDE.md / AGENTS.md
|
-
All operations are idempotent. Re-running setup updates drifted content
without clobbering. Instructions use markers, hooks filter by
thatchstring, MCP config preserves existing servers, skills diff before writing. -
Skills follow the setup scope. Project-local installs write skills to
the repo's
.claude/skills//.cursor/skills/(Claude Code and Cursor both discover project skills there);--globalwrites to the user config dirs. Setup reports the directory plus added/updated/removed/unchanged counts, and notes (without touching) any thatch skills found in the opposite scope. -
appendBlockleaves content alone if markers do not parse. A start marker without an end marker means the file was edited externally. Writing would risk clobbering content after the start marker. - Binary path is baked into hook commands. Hooks are short-lived processes that outlive the setup session. The resolved path ensures they keep working.
-
Non-thatch hooks are preserved during hook replacement. Only hooks
whose
commandcontainsthatchare filtered out. - Auto-refresh keeps installations current. The MCP server re-runs setup on startup if markers are present, picking up new skills and updated instructions without manual intervention.
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