@jeffober/thatch 0.1.8 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -19
- package/bin/release +21 -0
- package/docs/dev/mcp-parity.md +1 -0
- package/docs/dev/setup-and-hooks.md +36 -0
- package/docs/dev/skills.md +17 -6
- package/docs/qa/use-cases/README.md +1 -0
- package/docs/qa/use-cases/UC-005-setup-install.md +2 -2
- package/docs/qa/use-cases/UC-014-skill-install-drift.md +3 -3
- package/docs/qa/use-cases/UC-018-mcp-startup-setup-detection.md +38 -0
- package/docs/user/README.md +20 -6
- package/package.json +1 -1
- package/src/mcp.ts +23 -0
- package/src/prompts.ts +39 -0
- package/src/setup.ts +115 -3
- package/src/skills.ts +269 -4
package/README.md
CHANGED
|
@@ -2,18 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/sysread/thatch/actions/workflows/ci.yml)
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
## Synopsis
|
|
6
|
+
|
|
7
|
+
Persistent memory and useful dev skills for AI coding agents that requires zero
|
|
8
|
+
manual config.
|
|
7
9
|
|
|
8
10
|
Works with **OpenCode** (as a plugin), **Claude Code** (as an MCP server), and
|
|
9
11
|
**Cursor** (as an MCP server).
|
|
12
|
+
|
|
10
13
|
Each session inherits the accumulated knowledge of every session before it —
|
|
11
14
|
project architecture, conventions, gotchas, user preferences — so your agent
|
|
12
|
-
starts with context instead of a blank slate. Stores are per-repo with a
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
starts with context instead of a blank slate. Stores are per-repo with a shared
|
|
16
|
+
`global` store.
|
|
17
|
+
|
|
18
|
+
On top of the memory layer, thatch ships a suite of skills for managing memories,
|
|
19
|
+
performing in-depth, structured code reviews, and researching your code base.
|
|
20
|
+
|
|
21
|
+
No API keys, no cloud services; everything runs on your machine.
|
|
17
22
|
|
|
18
23
|
## Quick start
|
|
19
24
|
|
|
@@ -118,6 +123,8 @@ agent follows to maintain its own memory and review code systematically.
|
|
|
118
123
|
| `thatch-review-no-slop` | AI writing anti-pattern detection — change narration, fourth wall breaks, hedging |
|
|
119
124
|
| `thatch-review-breadcrumbs` | Comment narrative — do comments form a coherent outline of the code's behavior? |
|
|
120
125
|
| `thatch-review-synthesizer` | Verify specialist findings against actual code, deduplicate, produce severity-grouped report |
|
|
126
|
+
| `thatch-review-context` | Gather project/feature context (PRs, tickets, TODOs, deferred work) before a review |
|
|
127
|
+
| `thatch-workflow-research` | Research code workflows affected by a change or planned change, before reviewing or planning |
|
|
121
128
|
| `thatch-code-review` | Multi-agent review coordinator — triage, partition, dispatch specialists in parallel (opencode only) |
|
|
122
129
|
|
|
123
130
|
The five review specialists run independently and can be used standalone. The
|
|
@@ -142,7 +149,7 @@ thatch prime Prime project memory (runs via opencode or clau
|
|
|
142
149
|
thatch mcp Start the stdio MCP server (for Claude Code)
|
|
143
150
|
thatch reminder Print session-start reminder (for hooks)
|
|
144
151
|
thatch hygiene Print the hygiene report (standalone)
|
|
145
|
-
thatch setup --claude [--global] Install config + instructions + hooks + skills
|
|
152
|
+
thatch setup --claude [--cursor] [--global] Install config + instructions + hooks + skills
|
|
146
153
|
```
|
|
147
154
|
|
|
148
155
|
Stores default to the repo detected from `git remote`. Use `global` for the
|
|
@@ -190,17 +197,18 @@ buffer and flush. On Claude Code, `PostToolBatch` and `UserPromptSubmit`
|
|
|
190
197
|
hooks drive a file-backed queue. Both paths produce the same payload for the
|
|
191
198
|
fact-extractor skill.
|
|
192
199
|
|
|
193
|
-
## OpenCode vs Claude Code parity
|
|
194
|
-
|
|
195
|
-
| Feature | OpenCode (plugin) | Claude Code (MCP + hooks) |
|
|
196
|
-
|
|
197
|
-
| Tools | Plugin tool registration | MCP `tools/list` + `tools/call` |
|
|
198
|
-
| System prompt | Injected at runtime with repo name | Static CLAUDE.md (repo auto-detected by MCP server) |
|
|
199
|
-
| Session-start reminder | `session.created` event | `SessionStart` hook → `thatch reminder` |
|
|
200
|
-
| Compaction context | `experimental.session.compacting` hook | **Gap**: no equivalent (CLAUDE.md persists
|
|
201
|
-
| Extraction nudge | `tool.execute.after` + `chat.message` | `PostToolBatch` + `UserPromptSubmit` (file-backed queue) |
|
|
202
|
-
|
|
|
203
|
-
|
|
|
200
|
+
## OpenCode vs Claude Code vs Cursor parity
|
|
201
|
+
|
|
202
|
+
| Feature | OpenCode (plugin) | Claude Code (MCP + hooks) | Cursor (MCP + hooks) |
|
|
203
|
+
|---------|-------------------|--------------------------|---------------------|
|
|
204
|
+
| Tools | Plugin tool registration | MCP `tools/list` + `tools/call` | MCP `tools/list` + `tools/call` |
|
|
205
|
+
| System prompt | Injected at runtime with repo name | Static CLAUDE.md (repo auto-detected by MCP server) | Static AGENTS.md (repo auto-detected at startup) |
|
|
206
|
+
| Session-start reminder | `session.created` event | `SessionStart` hook → `thatch reminder` | `sessionStart` hook → `thatch reminder --json` |
|
|
207
|
+
| Compaction context | `experimental.session.compacting` hook | **Gap**: no equivalent (CLAUDE.md persists) | **Gap**: no equivalent |
|
|
208
|
+
| Extraction nudge | `tool.execute.after` + `chat.message` | `PostToolBatch` + `UserPromptSubmit` (file-backed queue) | `postToolUse` + `beforeSubmitPrompt` (file-backed queue) |
|
|
209
|
+
| Setup detection at startup | n/a (plugin auto-installs) | `checkSetup` in MCP server: detects missing/broken instructions | Same as Claude Code |
|
|
210
|
+
| Skills | 13 (shared + coordinator) | 12 (shared only) | 12 (shared only) |
|
|
211
|
+
| Store detection | `worktree` param from plugin | `CLAUDE_PROJECT_DIR` env var | `CURSOR_PROJECT_DIR` then `CLAUDE_PROJECT_DIR` |
|
|
204
212
|
|
|
205
213
|
See [docs/dev/mcp-parity.md](docs/dev/mcp-parity.md) for the full analysis.
|
|
206
214
|
|
package/bin/release
CHANGED
|
@@ -22,6 +22,27 @@ echo " bump: $v"
|
|
|
22
22
|
echo " next: $next"
|
|
23
23
|
echo
|
|
24
24
|
|
|
25
|
+
# Pre-flight: verify the current version is published on npm before allowing a
|
|
26
|
+
# new release. A tagged-but-unpublished version means the prior publish failed;
|
|
27
|
+
# stacking another release on top hides the gap and complicates recovery.
|
|
28
|
+
if git rev-parse -q --verify "refs/tags/v$curr" >/dev/null 2>&1; then
|
|
29
|
+
pub_status=$(npm view "@jeffober/thatch@$curr" version 2>&1 || true)
|
|
30
|
+
if ! echo "$pub_status" | grep -q "^$curr$"; then
|
|
31
|
+
if echo "$pub_status" | grep -q "E404"; then
|
|
32
|
+
echo "ERROR: v$curr is tagged but not published to npm."
|
|
33
|
+
echo " The previous release failed. Check: gh run view --workflow=publish.yml"
|
|
34
|
+
echo " Fix the workflow, delete and re-tag v$curr, push, then re-run this release."
|
|
35
|
+
echo " To re-tag: git tag -d v$curr && git tag v$curr <commit> && git push origin :refs/tags/v$curr && git push origin v$curr"
|
|
36
|
+
exit 1
|
|
37
|
+
else
|
|
38
|
+
echo "WARN: npm registry check failed (not a 404 — may be a network issue or npm outage):"
|
|
39
|
+
echo " $pub_status"
|
|
40
|
+
echo " Proceeding anyway. Verify v$curr is published before relying on this."
|
|
41
|
+
echo
|
|
42
|
+
fi
|
|
43
|
+
fi
|
|
44
|
+
fi
|
|
45
|
+
|
|
25
46
|
echo "▸ running checks (typecheck + tests + markdown lint)..."
|
|
26
47
|
mise run check
|
|
27
48
|
echo " ✓ checks passed"
|
package/docs/dev/mcp-parity.md
CHANGED
|
@@ -26,6 +26,7 @@ This document maps the feature parity and documents the remaining gaps.
|
|
|
26
26
|
| **Prompt-aware recall nudge** | `chat.message` hook embeds the prompt with the in-process warm model, searches `db.search()`, pushes a nudge part if matches ≥ threshold | `UserPromptSubmit` hook → `thatch flush-tools` connects to the MCP server's sideband socket; the warm server embeds + searches; hook prints the nudge or falls back to the write nudge | `beforeSubmitPrompt` hook → `thatch flush-tools --json` (same sideband path) | **Full** — sideband socket gives cold hook processes access to the warm MCP server's model |
|
|
27
27
|
| **Skills** | Installed to `$XDG_CONFIG_HOME/opencode/skills` at plugin init (shared **+** opencode-only) | Installed to `$CLAUDE_CONFIG_DIR/skills/` by `thatch setup` (shared only) | Installed to `~/.cursor/skills/` by `thatch setup` (shared only) | **Full** — same SKILL.md format; the code-review coordinator is opencode-only (needs sub-agents) |
|
|
28
28
|
| **Store detection** (repo identity from git remote) | `worktree` parameter from the opencode plugin | `CLAUDE_PROJECT_DIR` env (set by Claude Code for stdio MCP servers) | `CURSOR_PROJECT_DIR` then `CLAUDE_PROJECT_DIR` then cwd | **Full** |
|
|
29
|
+
| **Setup detection at startup** | n/a — plugin auto-installs at init | `checkSetup` in MCP server: detects missing or broken instructions in CLAUDE.md | Same as Claude Code (checks AGENTS.md) | **Full** — warns the agent to tell the user to run `thatch setup` |
|
|
29
30
|
| **Hook config format** | n/a — plugin registers hooks in code | Nested: `.claude/settings.json` `{hooks:{Event:{hooks:[{type,command}]}}}` | Flat: `.cursor/hooks.json` `{version:1,hooks:{event:[{command}]}}` | n/a |
|
|
30
31
|
|
|
31
32
|
## Tool name conventions
|
|
@@ -132,3 +132,39 @@ All setup operations are idempotent:
|
|
|
132
132
|
`thatch setup` resolves `<bin>` from PATH, falling back to the absolute path of
|
|
133
133
|
the running script. This is baked into every installed hook command, so the
|
|
134
134
|
hooks keep working after the session that ran setup ends.
|
|
135
|
+
|
|
136
|
+
## Setup detection at MCP startup
|
|
137
|
+
|
|
138
|
+
When the MCP server starts (`thatch mcp`, spawned by Claude Code or Cursor),
|
|
139
|
+
it calls `checkSetup` (`src/setup.ts`) to verify that `thatch setup` was run
|
|
140
|
+
for the current host. This catches two failure modes that would otherwise leave
|
|
141
|
+
the agent without usage instructions:
|
|
142
|
+
|
|
143
|
+
### Host detection
|
|
144
|
+
|
|
145
|
+
The host is determined from env vars set by the host process:
|
|
146
|
+
|
|
147
|
+
- `CURSOR_PROJECT_DIR` set → Cursor
|
|
148
|
+
- `CLAUDE_PROJECT_DIR` set (and Cursor not) → Claude Code
|
|
149
|
+
- Neither set → returns `null` (no check — manual `thatch mcp` invocation)
|
|
150
|
+
|
|
151
|
+
Cursor takes priority because Cursor also sets `CLAUDE_PROJECT_DIR` as an alias.
|
|
152
|
+
|
|
153
|
+
### What it checks
|
|
154
|
+
|
|
155
|
+
`checkSetup` looks for the instruction markers (start and end) in the host's
|
|
156
|
+
instructions file — `CLAUDE.md` for Claude Code, `AGENTS.md` for Cursor. It
|
|
157
|
+
checks local (in the project directory) first, then global (in the config
|
|
158
|
+
directory). Local takes priority.
|
|
159
|
+
|
|
160
|
+
### Three outcomes
|
|
161
|
+
|
|
162
|
+
| Outcome | Condition | Action |
|
|
163
|
+
|---------|-----------|--------|
|
|
164
|
+
| **installed** | Markers found in local or global instructions file | No warning — setup is complete |
|
|
165
|
+
| **not-installed** | No instructions file with markers found anywhere | Warning to stderr + prepended to first `tools/call` response: "Tell the user to run `thatch setup --<host>`" |
|
|
166
|
+
| **markers-broken** | Start marker found but end marker missing (file edited externally) | Warning with the specific file path and fix instructions: run `thatch setup`, or manually remove the corrupted block and re-run |
|
|
167
|
+
|
|
168
|
+
The warning is cleared after the first `tools/call` response so it surfaces
|
|
169
|
+
once, not on every tool call. The message instructs the LLM to notify the user
|
|
170
|
+
with the specific `thatch setup` command to run.
|
package/docs/dev/skills.md
CHANGED
|
@@ -21,9 +21,9 @@ description: Extract durable project facts ... Use when ...
|
|
|
21
21
|
- `description` drives when the agent loads the skill (both opencode and
|
|
22
22
|
Cursor auto-discover skills and use the description for relevance).
|
|
23
23
|
|
|
24
|
-
## The
|
|
24
|
+
## The 13 skills
|
|
25
25
|
|
|
26
|
-
**Shared (
|
|
26
|
+
**Shared (12)** — installed everywhere; no sub-agents required:
|
|
27
27
|
|
|
28
28
|
| Skill | Role |
|
|
29
29
|
|-------|------|
|
|
@@ -36,13 +36,15 @@ description: Extract durable project facts ... Use when ...
|
|
|
36
36
|
| `thatch-review-no-slop` | AI writing anti-patterns: change narration, fourth-wall breaks, em dashes, filler. |
|
|
37
37
|
| `thatch-review-breadcrumbs` | Comment narrative: do comments form a coherent outline of behavior? |
|
|
38
38
|
| `thatch-review-synthesizer` | Verify specialist findings against code, dedupe, classify, calibrate severity. |
|
|
39
|
+
| `thatch-review-context` | Gather project/feature context (PR descriptions, git archaeology, ticket references, memory) before fan-out. Prevents false positives about intentionally deferred work. |
|
|
40
|
+
| `thatch-workflow-research` | Research code workflows/features affected by a change or planned change. Reads code flows, comments, git history, memories, docs. Produces a guide to the code for reviewers or planners. |
|
|
39
41
|
| `thatch-session-reflection` | End-of-session memory recording (project, user, tools, self). |
|
|
40
42
|
|
|
41
43
|
**opencode-only (1)** — the coordinator needs sub-agent support:
|
|
42
44
|
|
|
43
45
|
| Skill | Role |
|
|
44
46
|
|-------|------|
|
|
45
|
-
| `thatch-code-review` | Resolve review target, estimate complexity, partition, dispatch the 5 specialists in parallel, synthesize. |
|
|
47
|
+
| `thatch-code-review` | Resolve review target, gather project context, research affected workflows, estimate complexity, partition, dispatch the 5 specialists in parallel, synthesize. |
|
|
46
48
|
|
|
47
49
|
## REVIEW_COMMON
|
|
48
50
|
|
|
@@ -57,6 +59,16 @@ The five review specialists share a framework interpolated via `${REVIEW_COMMON}
|
|
|
57
59
|
trigger; "the code allows this" is not enough.
|
|
58
60
|
- **Intent verification** — trace callers, check git history, and `thatch_memory_recall`
|
|
59
61
|
for design rationale before flagging a behavior as a bug.
|
|
62
|
+
- **Project context awareness** — if a context brief is provided (from the
|
|
63
|
+
coordinator or from loading `thatch-review-context`), use it to avoid false
|
|
64
|
+
positives about intentionally deferred work.
|
|
65
|
+
- **Workflow context awareness** — if a workflow guide is provided (from the
|
|
66
|
+
coordinator or from loading `thatch-workflow-research`), use it to understand
|
|
67
|
+
the purpose and evolution of the code, distinguishing intentional behavior
|
|
68
|
+
and long-standing design decisions from new issues.
|
|
69
|
+
- **TODO ($ticket) markers** — recognize `TODO ($TICKET-ID): ...` as legitimate
|
|
70
|
+
breadcrumbs for deferred work, not stale artifacts. Flag only if the referenced
|
|
71
|
+
ticket is closed or merged.
|
|
60
72
|
- **Output format** — `[SEVERITY] [CATEGORY] file:line` with finding, evidence
|
|
61
73
|
(quoted), trigger, reachability, source of truth, producer chain, provenance.
|
|
62
74
|
|
|
@@ -66,7 +78,7 @@ The synthesizer reuses the same verification rigor but has its own structure
|
|
|
66
78
|
## The two arrays
|
|
67
79
|
|
|
68
80
|
```ts
|
|
69
|
-
const SHARED_SKILLS: SkillDef[] = [ /*
|
|
81
|
+
const SHARED_SKILLS: SkillDef[] = [ /* 12 skills above */ ];
|
|
70
82
|
const OPENCODE_ONLY_SKILLS: SkillDef[] = [ /* code-review coordinator */ ];
|
|
71
83
|
```
|
|
72
84
|
|
|
@@ -100,8 +112,7 @@ and `--cursor` pass only the shared set.
|
|
|
100
112
|
## Memory review skills in practice
|
|
101
113
|
|
|
102
114
|
- **Quick single lens**: load any specialist directly and point it at a branch.
|
|
103
|
-
- **Full review on opencode**: load `thatch-code-review` — it dispatches all 5
|
|
104
|
-
specialists in parallel, then synthesizes.
|
|
115
|
+
- **Full review on opencode**: load `thatch-code-review` — it gathers project context, researches affected workflows, dispatches all 5 specialists in parallel (with both the context brief and workflow guide injected into each briefing), then synthesizes.
|
|
105
116
|
- **Full review on Claude Code/Cursor**: run each specialist in sequence, then
|
|
106
117
|
run `thatch-review-synthesizer` to verify and aggregate.
|
|
107
118
|
|
|
@@ -26,6 +26,7 @@ file/IPC/CLI contracts ready to graduate into `bun:test` integration tests.
|
|
|
26
26
|
| [UC-015](UC-015-env-override-matrix.md) | `THATCH_DB_PATH`, `XDG_CONFIG_HOME`, `CLAUDE_CONFIG_DIR`, `THATCH_QUEUE_DIR`, `THATCH_RECALL_THRESHOLD`, `THATCH_MODEL` |
|
|
27
27
|
| [UC-016](UC-016-concurrent-session-isolation.md) | Per-session extraction isolation (in-memory + file queue); shared stateless sideband |
|
|
28
28
|
| [UC-017](UC-017-buffer-tool-vs-buffer-batch.md) | `buffer-batch` (Claude, `tool_calls[]`+`session_id`) vs `buffer-tool` (Cursor, single+`conversation_id`) |
|
|
29
|
+
| [UC-018](UC-018-mcp-startup-setup-detection.md) | MCP startup detects missing/broken setup instructions and warns the agent |
|
|
29
30
|
|
|
30
31
|
## Template
|
|
31
32
|
|
|
@@ -17,12 +17,12 @@
|
|
|
17
17
|
appends a thatch block to `CLAUDE.md` bracketed by start/end markers (replaced, not
|
|
18
18
|
duplicated, on re-run), writes `.claude/settings.json` hooks (`SessionStart` -> `thatch reminder`,
|
|
19
19
|
`PostToolBatch` -> `thatch buffer-batch`, `UserPromptSubmit` -> `thatch flush-tools`), and installs
|
|
20
|
-
**
|
|
20
|
+
**12 shared skills** (no code-review coordinator) to `$CLAUDE_CONFIG_DIR/skills/` — user-scoped
|
|
21
21
|
even in project-local mode.
|
|
22
22
|
- `--cursor` project-local writes `.cursor/mcp.json`, appends to `AGENTS.md`, writes
|
|
23
23
|
`.cursor/hooks.json` in the **flat format** (`{version:1, hooks:{...}}`): `sessionStart` ->
|
|
24
24
|
`thatch reminder --json`, `postToolUse` -> `thatch buffer-tool`, `beforeSubmitPrompt` ->
|
|
25
|
-
`thatch flush-tools --json`; and installs
|
|
25
|
+
`thatch flush-tools --json`; and installs 12 shared skills to `~/.cursor/skills/`.
|
|
26
26
|
- Re-run is idempotent: instructions are not duplicated, thatch hooks are replaced (not appended),
|
|
27
27
|
and non-thatch hooks are preserved. A legacy `thatch echo` hook is replaced with `flush-tools`.
|
|
28
28
|
- `--global` (Claude) writes `~/.claude/CLAUDE.md` + `~/.claude/settings.json` but **no project
|
|
@@ -13,16 +13,16 @@
|
|
|
13
13
|
5. Check whether the `thatch-code-review` coordinator skill is present.
|
|
14
14
|
|
|
15
15
|
**Expected**
|
|
16
|
-
- Claude Code and Cursor install exactly **
|
|
16
|
+
- Claude Code and Cursor install exactly **12 shared skills** to the skills
|
|
17
17
|
dir — the coordinator (`thatch-code-review`) is **absent** (it needs
|
|
18
18
|
sub-agents, which those hosts lack).
|
|
19
|
-
- opencode installs **
|
|
19
|
+
- opencode installs **13** — the 12 shared plus the coordinator.
|
|
20
20
|
- The locally edited `SKILL.md` is **overwritten** with the canonical content
|
|
21
21
|
on the next `setup`/init (drift detection: a file is only rewritten when its
|
|
22
22
|
content differs from the definition). Unrelated skill files are untouched.
|
|
23
23
|
- Skills never land in the worktree — always under the user-scoped config dir
|
|
24
24
|
(`~/.claude/skills`, `~/.cursor/skills`, `$XDG_CONFIG_HOME/opencode/skills`).
|
|
25
25
|
|
|
26
|
-
_Automatable: yes — file presence, count (
|
|
26
|
+
_Automatable: yes — file presence, count (12 vs 13), content-diff-overwrite, and
|
|
27
27
|
coordinator host-gating are all file assertions (`setup.test.ts` already covers
|
|
28
28
|
the unit contract)._
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# UC-018: MCP startup setup detection
|
|
2
|
+
|
|
3
|
+
**Preconditions**
|
|
4
|
+
- Thatch installed and `bun` on PATH
|
|
5
|
+
- MCP server launched by Claude Code (`thatch mcp` with `CLAUDE_PROJECT_DIR` set)
|
|
6
|
+
or Cursor (`thatch mcp` with `CURSOR_PROJECT_DIR` set)
|
|
7
|
+
|
|
8
|
+
**Steps**
|
|
9
|
+
1. Start a Claude Code session in a project where `thatch setup --claude` was
|
|
10
|
+
never run (no `CLAUDE.md` with thatch markers, neither local nor global).
|
|
11
|
+
2. Call any thatch tool (e.g. `mcp__thatch__store_list`).
|
|
12
|
+
3. Repeat in a project where setup was run but `CLAUDE.md` was edited externally
|
|
13
|
+
and the thatch block's end marker was deleted.
|
|
14
|
+
4. Repeat in a project where setup was run correctly.
|
|
15
|
+
5. Repeat all steps for Cursor (substituting `--cursor`, `AGENTS.md`,
|
|
16
|
+
`CURSOR_PROJECT_DIR`).
|
|
17
|
+
|
|
18
|
+
**Expected**
|
|
19
|
+
- **Not-installed**: The first `tools/call` response is prepended with a
|
|
20
|
+
warning: "[thatch] Thatch is running as an MCP server but has not been set
|
|
21
|
+
up for Claude Code. ... Tell the user to run: thatch setup --claude". The
|
|
22
|
+
warning also appears on stderr. Subsequent tool responses are clean (warning
|
|
23
|
+
is one-shot).
|
|
24
|
+
- **Markers-broken**: The first `tools/call` response is prepended with a
|
|
25
|
+
warning naming the corrupted file and instructing the user to run
|
|
26
|
+
`thatch setup` (or manually remove the corrupted block and re-run).
|
|
27
|
+
- **Installed**: No warning. Tool responses are clean from the first call.
|
|
28
|
+
- **Cursor**: Same behavior, with "Cursor" substituted for "Claude Code" and
|
|
29
|
+
`thatch setup --cursor` in the message. When both `CURSOR_PROJECT_DIR` and
|
|
30
|
+
`CLAUDE_PROJECT_DIR` are set, Cursor detection takes priority.
|
|
31
|
+
- **No env var**: When neither `CURSOR_PROJECT_DIR` nor `CLAUDE_PROJECT_DIR` is
|
|
32
|
+
set (manual `thatch mcp` invocation), `checkSetup` returns `null` and no
|
|
33
|
+
warning is emitted.
|
|
34
|
+
|
|
35
|
+
_Automatable: yes — `setup.test.ts` already covers the unit contract (10 tests
|
|
36
|
+
in the `checkSetup` describe block: null, local, global, not-installed,
|
|
37
|
+
markers-broken, local priority, Cursor variants, Cursor priority). This is the
|
|
38
|
+
end-to-end runbook version._
|
package/docs/user/README.md
CHANGED
|
@@ -114,6 +114,17 @@ Beyond the tools, thatch hooks into opencode itself:
|
|
|
114
114
|
- **Compaction context.** When opencode compacts a long session, thatch injects
|
|
115
115
|
a reminder so the summarized session still knows memory tools exist.
|
|
116
116
|
|
|
117
|
+
### Setup detection (Claude Code and Cursor)
|
|
118
|
+
|
|
119
|
+
When the MCP server starts (Claude Code or Cursor), it checks whether
|
|
120
|
+
`thatch setup` was run for the current host by looking for the instruction
|
|
121
|
+
markers in `CLAUDE.md` (Claude Code) or `AGENTS.md` (Cursor). It checks local
|
|
122
|
+
first (in the project directory), then global (in the config directory). If
|
|
123
|
+
setup was never run, or if the instruction markers are broken (e.g. the file
|
|
124
|
+
was edited externally and the thatch block was partially modified), the server
|
|
125
|
+
emits a warning to stderr and prepends it to the first tool response so the
|
|
126
|
+
agent can tell the user to run `thatch setup`.
|
|
127
|
+
|
|
117
128
|
## Skills
|
|
118
129
|
|
|
119
130
|
On startup thatch installs [skills] into your global opencode config
|
|
@@ -143,6 +154,8 @@ Five specialist review lenses, each a self-contained static-analysis pass:
|
|
|
143
154
|
| `thatch-review-no-slop` | AI writing anti-patterns: change narration, fourth wall breaks, em dashes, hedging, filler. |
|
|
144
155
|
| `thatch-review-breadcrumbs` | Comment narrative: do comments form a coherent outline of the code's behavior? |
|
|
145
156
|
| `thatch-review-synthesizer` | Verifies and synthesizes findings from multiple specialists into a single deduplicated, severity-grouped report. |
|
|
157
|
+
| `thatch-review-context` | Gathers project context (PR descriptions, git archaeology, ticket references, memory) before a review. Prevents false positives about intentionally deferred work. |
|
|
158
|
+
| `thatch-workflow-research` | Researches code workflows and features affected by a change or planned change. Reads code flows, comments, git history, and produces a guide for reviewers or planners. |
|
|
146
159
|
|
|
147
160
|
### opencode-only skills
|
|
148
161
|
|
|
@@ -152,12 +165,13 @@ Five specialist review lenses, each a self-contained static-analysis pass:
|
|
|
152
165
|
|
|
153
166
|
### Host availability
|
|
154
167
|
|
|
155
|
-
| Skill | opencode | Claude Code |
|
|
156
|
-
|
|
157
|
-
| Memory skills (4) | Yes | Yes |
|
|
158
|
-
| Review specialists (5) | Yes | Yes |
|
|
159
|
-
| Review synthesizer | Yes | Yes |
|
|
160
|
-
|
|
|
168
|
+
| Skill | opencode | Claude Code | Cursor |
|
|
169
|
+
|-------|----------|-------------|--------|
|
|
170
|
+
| Memory skills (4) | Yes | Yes | Yes |
|
|
171
|
+
| Review specialists (5) | Yes | Yes | Yes |
|
|
172
|
+
| Review synthesizer | Yes | Yes | Yes |
|
|
173
|
+
| Review context + workflow research | Yes | Yes | Yes |
|
|
174
|
+
| Code review coordinator | Yes | No (requires sub-agents) | No (requires sub-agents) |
|
|
161
175
|
|
|
162
176
|
### Using review skills
|
|
163
177
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jeffober/thatch",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"description": "Persistent memory for AI coding agents — local embeddings, SQLite stores, zero config. Works with OpenCode (as a plugin), Claude Code (as an MCP server), and Cursor (as an MCP server).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
package/src/mcp.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { z } from "zod";
|
|
|
2
2
|
import { ThatchDB } from "./db";
|
|
3
3
|
import { BgeEmbeddingModel } from "./embeddings";
|
|
4
4
|
import { detectRepo } from "./git";
|
|
5
|
+
import { checkSetup } from "./setup";
|
|
5
6
|
import { TOOL_DEFS, type CoreContext, type ToolDef } from "./tool-defs";
|
|
6
7
|
import { SidebandServer, sidebandSocketPath } from "./sideband";
|
|
7
8
|
|
|
@@ -99,6 +100,17 @@ export async function runMcpServer(): Promise<void> {
|
|
|
99
100
|
const ctx: CoreContext = { db, model, defaultStore: repo };
|
|
100
101
|
const tools = compileTools();
|
|
101
102
|
|
|
103
|
+
// Check whether `thatch setup` was run for the current host. If not, or if
|
|
104
|
+
// markers are broken, surface a warning on the first tools/call response so
|
|
105
|
+
// the agent can tell the user to run setup. Also emit to stderr for
|
|
106
|
+
// visibility in host debug logs.
|
|
107
|
+
let setupWarning: string | null = null;
|
|
108
|
+
const setupStatus = checkSetup(projectDir);
|
|
109
|
+
if (setupStatus && setupStatus.status !== "installed") {
|
|
110
|
+
setupWarning = setupStatus.message;
|
|
111
|
+
console.error(`[thatch] ${setupWarning}`);
|
|
112
|
+
}
|
|
113
|
+
|
|
102
114
|
// The sideband socket lets one-shot hook processes (flush-tools) ask the
|
|
103
115
|
// warm MCP server to embed a prompt and search for matches — without
|
|
104
116
|
// loading the ~34 MB model themselves. If the socket can't be opened
|
|
@@ -137,6 +149,17 @@ export async function runMcpServer(): Promise<void> {
|
|
|
137
149
|
const isNotification = req.id === null || req.id === undefined;
|
|
138
150
|
const res = await dispatch(req, tools, ctx);
|
|
139
151
|
if (res === null || isNotification) continue;
|
|
152
|
+
|
|
153
|
+
// Surface the setup warning on the first tools/call response so the
|
|
154
|
+
// agent sees it and can notify the user. Cleared after one surfacing.
|
|
155
|
+
if (setupWarning && req.method === "tools/call" && !res.error) {
|
|
156
|
+
const content = res.result?.content;
|
|
157
|
+
if (Array.isArray(content) && content[0]?.text != null) {
|
|
158
|
+
content[0].text = `[thatch] ${setupWarning}\n\n${content[0].text}`;
|
|
159
|
+
}
|
|
160
|
+
setupWarning = null;
|
|
161
|
+
}
|
|
162
|
+
|
|
140
163
|
send(res);
|
|
141
164
|
}
|
|
142
165
|
}
|
package/src/prompts.ts
CHANGED
|
@@ -27,6 +27,19 @@ WIP, PR status). Unscoped memories are project-wide and always included in searc
|
|
|
27
27
|
Before diving into code, thatch_memory_recall with a query relevant to the area
|
|
28
28
|
you're working in. Prior sessions may have already investigated it.
|
|
29
29
|
|
|
30
|
+
## Skills
|
|
31
|
+
|
|
32
|
+
Thatch ships skills for code review, project investigation, and memory
|
|
33
|
+
workflows. The host auto-discovers them, but reach for them proactively:
|
|
34
|
+
|
|
35
|
+
- \`thatch-code-review\` — full multi-agent code review (dispatches 5 specialists + synthesizer). Requires sub-agent support.
|
|
36
|
+
- \`thatch-workflow-research\` — research code workflows affected by a change or planned change, before reviewing or planning.
|
|
37
|
+
- \`thatch-review-context\` — gather project context (PRs, tickets, TODOs, deferred work) before a review.
|
|
38
|
+
- \`thatch-project-primer\` — investigate a new project and write foundational memories.
|
|
39
|
+
- \`thatch-session-reflection\` — record what you learned at end of session.
|
|
40
|
+
- \`thatch-fact-extractor\` — extract durable facts from recent tool interactions (auto-triggered by the extraction pipeline).
|
|
41
|
+
- \`thatch-dedup-classifier\` — resolve duplicate memory pairs from \`thatch_find_duplicates\`.
|
|
42
|
+
|
|
30
43
|
## When to Write
|
|
31
44
|
|
|
32
45
|
**One signal is enough.** Do not wait for confirmation.
|
|
@@ -126,6 +139,19 @@ WIP, PR status). Unscoped memories are project-wide and always included in searc
|
|
|
126
139
|
Before diving into code, \`memory_recall\` with a query relevant to the area
|
|
127
140
|
you're working in. Prior sessions may have already investigated it.
|
|
128
141
|
|
|
142
|
+
## Skills
|
|
143
|
+
|
|
144
|
+
Thatch ships skills for code review, project investigation, and memory
|
|
145
|
+
workflows. The host auto-discovers them, but reach for them proactively:
|
|
146
|
+
|
|
147
|
+
- \`thatch-workflow-research\` — research code workflows affected by a change or planned change, before reviewing or planning.
|
|
148
|
+
- \`thatch-review-context\` — gather project context (PRs, tickets, TODOs, deferred work) before a review.
|
|
149
|
+
- \`thatch-review-pedantic\` / \`-acceptance\` / \`-state-flow\` / \`-no-slop\` / \`-breadcrumbs\` — five specialist review lenses. Run individually, then \`thatch-review-synthesizer\` to verify and aggregate.
|
|
150
|
+
- \`thatch-project-primer\` — investigate a new project and write foundational memories.
|
|
151
|
+
- \`thatch-session-reflection\` — record what you learned at end of session.
|
|
152
|
+
- \`thatch-fact-extractor\` — extract durable facts from recent tool interactions (auto-triggered by the extraction pipeline).
|
|
153
|
+
- \`thatch-dedup-classifier\` — resolve duplicate memory pairs from \`find_duplicates\`.
|
|
154
|
+
|
|
129
155
|
## When to Write
|
|
130
156
|
|
|
131
157
|
**One signal is enough.** Do not wait for confirmation.
|
|
@@ -241,6 +267,19 @@ WIP, PR status). Unscoped memories are project-wide and always included in searc
|
|
|
241
267
|
Before diving into code, \`memory_recall\` with a query relevant to the area
|
|
242
268
|
you're working in. Prior sessions may have already investigated it.
|
|
243
269
|
|
|
270
|
+
## Skills
|
|
271
|
+
|
|
272
|
+
Thatch ships skills for code review, project investigation, and memory
|
|
273
|
+
workflows. The host auto-discovers them, but reach for them proactively:
|
|
274
|
+
|
|
275
|
+
- \`thatch-workflow-research\` — research code workflows affected by a change or planned change, before reviewing or planning.
|
|
276
|
+
- \`thatch-review-context\` — gather project context (PRs, tickets, TODOs, deferred work) before a review.
|
|
277
|
+
- \`thatch-review-pedantic\` / \`-acceptance\` / \`-state-flow\` / \`-no-slop\` / \`-breadcrumbs\` — five specialist review lenses. Run individually, then \`thatch-review-synthesizer\` to verify and aggregate.
|
|
278
|
+
- \`thatch-project-primer\` — investigate a new project and write foundational memories.
|
|
279
|
+
- \`thatch-session-reflection\` — record what you learned at end of session.
|
|
280
|
+
- \`thatch-fact-extractor\` — extract durable facts from recent tool interactions (auto-triggered by the extraction pipeline).
|
|
281
|
+
- \`thatch-dedup-classifier\` — resolve duplicate memory pairs from \`find_duplicates\`.
|
|
282
|
+
|
|
244
283
|
## When to Write
|
|
245
284
|
|
|
246
285
|
**One signal is enough.** Do not wait for confirmation.
|
package/src/setup.ts
CHANGED
|
@@ -415,8 +415,120 @@ export function setupCursor(
|
|
|
415
415
|
return {
|
|
416
416
|
mcpConfig: paths.mcpConfigPath,
|
|
417
417
|
agentsMd: paths.agentsMdPath,
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
418
|
+
hooks: paths.hooksPath,
|
|
419
|
+
skills,
|
|
420
|
+
global,
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// ---------------------------------------------------------------------------
|
|
425
|
+
// Setup detection — check whether setup was completed for the current host
|
|
426
|
+
// ---------------------------------------------------------------------------
|
|
427
|
+
|
|
428
|
+
export type HostKind = "claude" | "cursor";
|
|
429
|
+
|
|
430
|
+
export type SetupStatus =
|
|
431
|
+
| { status: "installed"; scope: "local" | "global"; host: HostKind }
|
|
432
|
+
| { status: "not-installed"; host: HostKind; message: string }
|
|
433
|
+
| { status: "markers-broken"; host: HostKind; file: string; message: string };
|
|
434
|
+
|
|
435
|
+
type FileCheck = "installed" | "absent" | "broken";
|
|
436
|
+
|
|
437
|
+
function checkInstructionsFile(path: string, startMarker: string, endMarker: string): FileCheck {
|
|
438
|
+
if (!existsSync(path)) return "absent";
|
|
439
|
+
const content = readFileSync(path, "utf8");
|
|
440
|
+
const startIdx = content.indexOf(startMarker);
|
|
441
|
+
if (startIdx === -1) return "absent";
|
|
442
|
+
const endIdx = content.indexOf(endMarker, startIdx);
|
|
443
|
+
if (endIdx === -1) return "broken";
|
|
444
|
+
return "installed";
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Detects the host from env vars (CURSOR_PROJECT_DIR for Cursor,
|
|
449
|
+
* CLAUDE_PROJECT_DIR for Claude Code) and checks whether `thatch setup` was
|
|
450
|
+
* run for that host. Checks local instructions (in the project dir) first,
|
|
451
|
+
* then global (in the config dir). Returns null if the host cannot be
|
|
452
|
+
* determined (neither env var is set — e.g. manual `thatch mcp` invocation).
|
|
453
|
+
*/
|
|
454
|
+
export function checkSetup(projectDir: string, homeDir?: string): SetupStatus | null {
|
|
455
|
+
const home = homeDir ?? process.env.HOME ?? "/tmp";
|
|
456
|
+
const isCursor = !!process.env.CURSOR_PROJECT_DIR;
|
|
457
|
+
const isClaude = !!process.env.CLAUDE_PROJECT_DIR && !isCursor;
|
|
458
|
+
if (!isCursor && !isClaude) return null;
|
|
459
|
+
|
|
460
|
+
const host: HostKind = isCursor ? "cursor" : "claude";
|
|
461
|
+
|
|
462
|
+
if (host === "claude") {
|
|
463
|
+
return checkClaudeSetup(projectDir, home);
|
|
464
|
+
}
|
|
465
|
+
return checkCursorSetup(projectDir, home);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
function checkClaudeSetup(projectDir: string, home: string): SetupStatus {
|
|
469
|
+
const configDir = claudeConfigDir(home);
|
|
470
|
+
|
|
471
|
+
const localMd = join(projectDir, "CLAUDE.md");
|
|
472
|
+
const localCheck = checkInstructionsFile(localMd, THATCH_MARKER, THATCH_END_MARKER);
|
|
473
|
+
if (localCheck === "installed") return { status: "installed", scope: "local", host: "claude" };
|
|
474
|
+
if (localCheck === "broken") {
|
|
475
|
+
return {
|
|
476
|
+
status: "markers-broken",
|
|
477
|
+
host: "claude",
|
|
478
|
+
file: localMd,
|
|
479
|
+
message: `Thatch's instructions in ${localMd} have corrupted markers: the start marker was found but the end marker is missing. This usually happens when the file was edited externally and the thatch block was partially modified. Tell the user to fix this by running: thatch setup --claude. If that doesn't resolve it, they may need to manually remove the corrupted thatch block from ${localMd} and re-run setup.`,
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
const globalMd = join(configDir, "CLAUDE.md");
|
|
484
|
+
const globalCheck = checkInstructionsFile(globalMd, THATCH_MARKER, THATCH_END_MARKER);
|
|
485
|
+
if (globalCheck === "installed") return { status: "installed", scope: "global", host: "claude" };
|
|
486
|
+
if (globalCheck === "broken") {
|
|
487
|
+
return {
|
|
488
|
+
status: "markers-broken",
|
|
489
|
+
host: "claude",
|
|
490
|
+
file: globalMd,
|
|
491
|
+
message: `Thatch's instructions in ${globalMd} have corrupted markers: the start marker was found but the end marker is missing. This usually happens when the file was edited externally and the thatch block was partially modified. Tell the user to fix this by running: thatch setup --claude --global. If that doesn't resolve it, they may need to manually remove the corrupted thatch block from ${globalMd} and re-run setup.`,
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
return {
|
|
496
|
+
status: "not-installed",
|
|
497
|
+
host: "claude",
|
|
498
|
+
message: "Thatch is running as an MCP server but has not been set up for Claude Code. The instructions that tell you how to use thatch's memory tools are missing from CLAUDE.md. Tell the user to run: thatch setup --claude",
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
function checkCursorSetup(projectDir: string, home: string): SetupStatus {
|
|
503
|
+
const configDir = cursorConfigDir(home);
|
|
504
|
+
|
|
505
|
+
const localMd = join(projectDir, "AGENTS.md");
|
|
506
|
+
const localCheck = checkInstructionsFile(localMd, CURSOR_MARKER, CURSOR_END_MARKER);
|
|
507
|
+
if (localCheck === "installed") return { status: "installed", scope: "local", host: "cursor" };
|
|
508
|
+
if (localCheck === "broken") {
|
|
509
|
+
return {
|
|
510
|
+
status: "markers-broken",
|
|
511
|
+
host: "cursor",
|
|
512
|
+
file: localMd,
|
|
513
|
+
message: `Thatch's instructions in ${localMd} have corrupted markers: the start marker was found but the end marker is missing. This usually happens when the file was edited externally and the thatch block was partially modified. Tell the user to fix this by running: thatch setup --cursor. If that doesn't resolve it, they may need to manually remove the corrupted thatch block from ${localMd} and re-run setup.`,
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
const globalMd = join(configDir, "AGENTS.md");
|
|
518
|
+
const globalCheck = checkInstructionsFile(globalMd, CURSOR_MARKER, CURSOR_END_MARKER);
|
|
519
|
+
if (globalCheck === "installed") return { status: "installed", scope: "global", host: "cursor" };
|
|
520
|
+
if (globalCheck === "broken") {
|
|
521
|
+
return {
|
|
522
|
+
status: "markers-broken",
|
|
523
|
+
host: "cursor",
|
|
524
|
+
file: globalMd,
|
|
525
|
+
message: `Thatch's instructions in ${globalMd} have corrupted markers: the start marker was found but the end marker is missing. This usually happens when the file was edited externally and the thatch block was partially modified. Tell the user to fix this by running: thatch setup --cursor --global. If that doesn't resolve it, they may need to manually remove the corrupted thatch block from ${globalMd} and re-run setup.`,
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
return {
|
|
530
|
+
status: "not-installed",
|
|
531
|
+
host: "cursor",
|
|
532
|
+
message: "Thatch is running as an MCP server but has not been set up for Cursor. The instructions that tell you how to use thatch's memory tools are missing from AGENTS.md. Tell the user to run: thatch setup --cursor",
|
|
421
533
|
};
|
|
422
534
|
}
|
package/src/skills.ts
CHANGED
|
@@ -82,6 +82,25 @@ Before flagging behavior as a bug, verify intent:
|
|
|
82
82
|
|
|
83
83
|
If any of these reveals the behavior is intentional, it is not a finding. If you cannot determine intent after all three steps, you may report it — but note that you could not confirm whether the behavior is intentional.
|
|
84
84
|
|
|
85
|
+
## Project context awareness
|
|
86
|
+
If your briefing includes a project context brief (from the coordinator or from loading thatch-review-context), use it to calibrate your findings:
|
|
87
|
+
- **Deferred work** listed in the brief is intentionally excluded from this PR. Do not flag the absence of deferred pieces as bugs, inconsistencies, or missing functionality.
|
|
88
|
+
- **Dependencies** in the brief tell you whether base-branch behavior is expected to be present or not. Do not assert that base-branch behavior exists without verifying it landed.
|
|
89
|
+
- **Relevant constraints** may explain why code is structured a certain way. Consider them before flagging design choices.
|
|
90
|
+
|
|
91
|
+
## Workflow context awareness
|
|
92
|
+
If your briefing includes a workflow guide (from the coordinator or from loading thatch-workflow-research), use it to understand the purpose and evolution of the code you are reviewing:
|
|
93
|
+
- **Purpose** sections explain why the workflow exists, which helps distinguish intentional behavior from bugs.
|
|
94
|
+
- **Major evolutions** sections explain how the code reached its current state, which helps distinguish recent changes from long-standing design decisions.
|
|
95
|
+
- **Constraints and design decisions** sections explain tradeoffs and intentional choices, which prevents flagging known design decisions as issues.
|
|
96
|
+
- **Current state** sections list known limitations and incomplete work, which prevents flagging known gaps as new bugs.
|
|
97
|
+
|
|
98
|
+
## TODO ($ticket) markers
|
|
99
|
+
Code may contain \`TODO ($TICKET-ID): description\` comments that mark intentionally deferred work: temporary code, placeholders for future tickets, or planned cleanups. These are legitimate breadcrumbs, not stale artifacts.
|
|
100
|
+
- Do NOT flag a TODO ($ticket) marker as a stale artifact if the ticket it references is still open or future work.
|
|
101
|
+
- DO flag it if you can verify the referenced ticket is closed or merged (the TODO is now stale).
|
|
102
|
+
- If your briefing includes a context brief that lists the deferred work, use it to determine whether the ticket is still pending.
|
|
103
|
+
|
|
85
104
|
## Output format
|
|
86
105
|
Produce findings as markdown. For each finding:
|
|
87
106
|
|
|
@@ -733,6 +752,219 @@ Findings you verified as real but pre-existing, with a one-line note on the issu
|
|
|
733
752
|
Note which files or areas were NOT covered by any specialist.
|
|
734
753
|
`;
|
|
735
754
|
|
|
755
|
+
// ---------------------------------------------------------------------------
|
|
756
|
+
// Review context builder — gathers project/feature context before fan-out
|
|
757
|
+
// ---------------------------------------------------------------------------
|
|
758
|
+
|
|
759
|
+
const REVIEW_CONTEXT = `---
|
|
760
|
+
name: thatch-review-context
|
|
761
|
+
description: Gather project and feature context before a code review. Investigates PR descriptions, git history, ticket references, docs, and memory to build a context brief that prevents false positives about intentionally deferred work. Use before dispatching review specialists or running a solo review.
|
|
762
|
+
---
|
|
763
|
+
|
|
764
|
+
You are a review context builder. Your job is to gather project context that gives reviewers the background they need to avoid false positives about intentionally deferred work, incomplete features, and multi-ticket dependencies.
|
|
765
|
+
|
|
766
|
+
## Why this matters
|
|
767
|
+
|
|
768
|
+
A specialist reviewer without project context will flag missing pieces of a feature as bugs or inconsistencies. If the PR is one ticket in a multi-ticket effort, the "missing" piece may be scheduled for the next ticket. Context prevents these false positives.
|
|
769
|
+
|
|
770
|
+
## Sources to investigate
|
|
771
|
+
|
|
772
|
+
Work through these sources in order. Not every source will yield information for every change. Skip sources that produce nothing rather than forcing a narrative.
|
|
773
|
+
|
|
774
|
+
### 1. PR description
|
|
775
|
+
If reviewing a PR, read the description:
|
|
776
|
+
- \`gh pr view N --json title,body,labels,milestone\` (or the local branch's PR if detected)
|
|
777
|
+
- Extract: stated scope, what is intentionally excluded, ticket references, linked PRs
|
|
778
|
+
|
|
779
|
+
### 2. Branch name
|
|
780
|
+
Branch names often contain ticket identifiers. Look for patterns:
|
|
781
|
+
- \`user/ticket-123\`, \`user/plat-122\`, \`feature/PROJ-456\`
|
|
782
|
+
- Extract the ticket ID and use it to search other sources
|
|
783
|
+
|
|
784
|
+
### 3. Git archaeology
|
|
785
|
+
- \`git log --oneline merge-base..HEAD\` — commit messages may reference tickets, describe scope, or mention future work
|
|
786
|
+
- \`git log --all --oneline --grep="TICKET-ID"\` — find related commits on other branches
|
|
787
|
+
- \`git log -S "TODO (TICKET"\` — find TODO markers that reference this or related tickets
|
|
788
|
+
- \`git branch -a\` — other branches may show planned or in-progress related work
|
|
789
|
+
|
|
790
|
+
### 4. TODO ($ticket) markers in the diff
|
|
791
|
+
Scan the diff for TODO markers that reference ticket identifiers:
|
|
792
|
+
- Pattern: \`TODO ($TICKET-ID): description\`
|
|
793
|
+
- Example: \`// TODO (PLAT-123): replace this temporary flag with the real config loader\`
|
|
794
|
+
- Example: \`// TODO (PLAT-124): this fallback will be removed when the new API lands\`
|
|
795
|
+
- These mark intentionally deferred work: cleanups, temporary code, or pieces to be introduced later
|
|
796
|
+
- Each marker tells a reviewer "this is known and scheduled, not missing"
|
|
797
|
+
- Extract the ticket IDs and note what is deferred
|
|
798
|
+
|
|
799
|
+
### 5. Thatch memories (RAG)
|
|
800
|
+
Call \`thatch_memory_recall\` with queries like:
|
|
801
|
+
- The feature or project name (if known from the PR or branch)
|
|
802
|
+
- The ticket identifier
|
|
803
|
+
- "feature status" or "milestone" or "roadmap"
|
|
804
|
+
- Any architectural decisions or design docs related to the changed area
|
|
805
|
+
|
|
806
|
+
### 6. Project documentation
|
|
807
|
+
- README, docs/, design docs, ADRs
|
|
808
|
+
- CONTRIBUTING.md or equivalent for conventions
|
|
809
|
+
- Any roadmap, milestone, or project plan documents
|
|
810
|
+
|
|
811
|
+
### 7. Issue tracker (if accessible)
|
|
812
|
+
If ticket IDs were found:
|
|
813
|
+
- \`gh issue list --search "TICKET-ID"\` or \`gh issue view N\`
|
|
814
|
+
- Look for milestone assignments, dependencies, and blocking relationships
|
|
815
|
+
- Check for epic or parent issues that describe the overall feature
|
|
816
|
+
|
|
817
|
+
## Context brief format
|
|
818
|
+
|
|
819
|
+
Produce a structured brief:
|
|
820
|
+
|
|
821
|
+
### Project context
|
|
822
|
+
- What larger initiative or feature this change is part of
|
|
823
|
+
- The ticket or milestone this PR implements
|
|
824
|
+
|
|
825
|
+
### This change's scope
|
|
826
|
+
- What this PR is scoped to deliver (from PR description, commit messages, diff analysis)
|
|
827
|
+
- What is explicitly excluded or deferred
|
|
828
|
+
|
|
829
|
+
### Deferred work
|
|
830
|
+
List each deferred piece:
|
|
831
|
+
- What is deferred
|
|
832
|
+
- Which ticket will deliver it (if known)
|
|
833
|
+
- Any TODO ($ticket) markers in the code that annotate it
|
|
834
|
+
|
|
835
|
+
### Dependencies
|
|
836
|
+
- What other tickets or PRs this depends on (must merge first)
|
|
837
|
+
- What tickets or PRs depend on this (are blocked by it)
|
|
838
|
+
- Whether base branches have landed (for stacked PRs)
|
|
839
|
+
|
|
840
|
+
### Relevant constraints
|
|
841
|
+
- Design decisions or architectural constraints from memories or docs
|
|
842
|
+
- Conventions that reviewers should be aware of
|
|
843
|
+
|
|
844
|
+
## If context is sparse
|
|
845
|
+
|
|
846
|
+
Not every PR will have rich context. If you find minimal context:
|
|
847
|
+
- State what you looked for and what you found
|
|
848
|
+
- Note that the change appears to be standalone (no multi-ticket dependencies detected)
|
|
849
|
+
- Flag any TODO ($ticket) markers in the diff even if you could not resolve the ticket
|
|
850
|
+
|
|
851
|
+
## The TODO ($ticket) convention
|
|
852
|
+
|
|
853
|
+
When code is intentionally temporary or incomplete because work is split across tickets, mark it with a TODO that references the ticket that will resolve it:
|
|
854
|
+
|
|
855
|
+
\`\`\`
|
|
856
|
+
// TODO ($TICKET-ID): description of what will be done or removed here
|
|
857
|
+
\`\`\`
|
|
858
|
+
|
|
859
|
+
Examples:
|
|
860
|
+
- \`// TODO (PLAT-123): replace this temporary flag with the real config loader\`
|
|
861
|
+
- \`// TODO (PLAT-124): this fallback will be removed when the new API lands\`
|
|
862
|
+
- \`# TODO (INFRA-456): delete this compatibility shim once all callers migrate\`
|
|
863
|
+
|
|
864
|
+
These markers serve as breadcrumbs for reviewers (human and LLM) who lack project context:
|
|
865
|
+
- They signal "this is known and scheduled, not a bug or oversight"
|
|
866
|
+
- They link the code to the ticket that will resolve it
|
|
867
|
+
- They should NOT be flagged as stale artifacts (the work is not yet completed)
|
|
868
|
+
- They SHOULD be flagged if the referenced ticket is closed or merged (the TODO is now stale)
|
|
869
|
+
`;
|
|
870
|
+
|
|
871
|
+
// ---------------------------------------------------------------------------
|
|
872
|
+
// Workflow research — code archaeology for review or planning
|
|
873
|
+
// ---------------------------------------------------------------------------
|
|
874
|
+
|
|
875
|
+
const WORKFLOW_RESEARCH = `---
|
|
876
|
+
name: thatch-workflow-research
|
|
877
|
+
description: Research the code workflows and features affected by a change or planned change. Identifies affected workflows, reads code flows and comments, traces git history, recalls memories, and produces a guide to the code. Use before reviewing a change or planning new work in an unfamiliar area.
|
|
878
|
+
---
|
|
879
|
+
|
|
880
|
+
You are a code workflow researcher. Your job is to identify the features and logical workflows affected by a change (or a planned change), do deep code archaeology on them, and produce a guide that gives other agents the context they need to review or plan effectively.
|
|
881
|
+
|
|
882
|
+
## Why this matters
|
|
883
|
+
|
|
884
|
+
A specialist reviewer without code-level context will misidentify intentional behavior as bugs, miss known design constraints, and duplicate the same code-tracing work across every specialist lens. A planner without code-level context will propose changes that conflict with existing flows. This skill produces the code guide that prevents both.
|
|
885
|
+
|
|
886
|
+
## Relationship to thatch-review-context
|
|
887
|
+
|
|
888
|
+
These two skills are complementary, not overlapping:
|
|
889
|
+
- **thatch-review-context** gathers project metadata: tickets, PRs, TODO markers, deferred work, issue-tracker context. It answers "what is this change trying to do and what is intentionally left out?"
|
|
890
|
+
- **thatch-workflow-research** (this skill) gathers code-level context: actual code flows, comments, git history, evolutions. It answers "how does the code being changed actually work, and how did it get that way?"
|
|
891
|
+
|
|
892
|
+
Use both before a review. The coordinator runs thatch-review-context in Step 2 and this skill in Step 3.
|
|
893
|
+
|
|
894
|
+
## Two modes
|
|
895
|
+
|
|
896
|
+
### Review mode (existing change)
|
|
897
|
+
Given a git range, branch, or PR:
|
|
898
|
+
1. Run \`git diff --stat\` on the resolved range to identify changed files.
|
|
899
|
+
2. For each changed file, read the diff to understand what is being modified.
|
|
900
|
+
3. From the changes, identify which features and business-logic workflows are touched. A single file may participate in multiple workflows; a single workflow may span multiple files.
|
|
901
|
+
|
|
902
|
+
### Planning mode (new change)
|
|
903
|
+
Given a description of work to be done:
|
|
904
|
+
1. Identify which areas of the codebase the planned change would affect.
|
|
905
|
+
2. Use grep/glob to find the files and modules that implement the relevant features.
|
|
906
|
+
3. From those files, identify which existing workflows the change will interact with or modify.
|
|
907
|
+
|
|
908
|
+
## Research process
|
|
909
|
+
|
|
910
|
+
For each identified workflow or feature, work through these steps. Not every step will yield information for every workflow. Skip steps that produce nothing rather than forcing a narrative.
|
|
911
|
+
|
|
912
|
+
### 1. Retrieve memories
|
|
913
|
+
Call \`thatch_memory_recall\` with queries like:
|
|
914
|
+
- The workflow or feature name
|
|
915
|
+
- The primary files or modules involved
|
|
916
|
+
- "architecture" or "design" or "convention" for the area
|
|
917
|
+
- Any gotchas or known issues in the area
|
|
918
|
+
|
|
919
|
+
### 2. Read documentation
|
|
920
|
+
- README, docs/, design docs, ADRs related to the workflow
|
|
921
|
+
- CLAUDE.md, AGENTS.md, CONTRIBUTING.md for conventions
|
|
922
|
+
- Any inline documentation at the module level
|
|
923
|
+
|
|
924
|
+
### 3. Read the code flow
|
|
925
|
+
Trace each workflow through the codebase. Do not just read the changed lines; read the full flow:
|
|
926
|
+
- Identify the entry point(s) for the workflow
|
|
927
|
+
- Follow the data path through the functions and modules involved
|
|
928
|
+
- Read the comments in the flow. Comments encode intention, rationale, and design decisions that are invisible from the code alone.
|
|
929
|
+
- Note key contracts: what does each function or module assume about its inputs? What does it guarantee about its outputs?
|
|
930
|
+
- Note implicit state machines: what states can the workflow be in? What transitions are guarded?
|
|
931
|
+
|
|
932
|
+
### 4. Read git history
|
|
933
|
+
Trace the evolution of the workflow through git:
|
|
934
|
+
- \`git log --oneline -- <key files>\` for the commit history of the files involved
|
|
935
|
+
- \`git log -S "<function name>"\` to find when key functions were introduced or changed
|
|
936
|
+
- \`git blame\` on critical sections to find when and why they were written
|
|
937
|
+
- \`git log --all --oneline --grep="<feature name>"\` to find related work on other branches
|
|
938
|
+
- Look for commit messages that explain design decisions, refactors, or bug fixes that shaped the workflow
|
|
939
|
+
|
|
940
|
+
Focus on *why* the code evolved, not just *when*. Major evolutions are: creation, significant refactors, behavior changes, bug fixes that changed the flow, and additions of new paths or states.
|
|
941
|
+
|
|
942
|
+
## Output: code guide
|
|
943
|
+
|
|
944
|
+
Produce a guide with one section per affected workflow or feature. Each section should be self-contained enough that a reviewer or planner can understand the workflow without reading the code themselves.
|
|
945
|
+
|
|
946
|
+
### Workflow: <name>
|
|
947
|
+
|
|
948
|
+
- **Purpose**: What this workflow does and why it exists in the system
|
|
949
|
+
- **Key files**: The primary files and entry points, with file:line references
|
|
950
|
+
- **Data flow**: How data moves through the workflow (high-level, not line-by-line)
|
|
951
|
+
- **Major evolutions**: Key changes from git history. When was it created? What refactors or behavior changes shaped it? What drove those changes? Cite commit hashes or dates.
|
|
952
|
+
- **Constraints and design decisions**: From comments, memories, and docs. Known constraints, tradeoffs, intentional design choices, and gotchas.
|
|
953
|
+
- **Current state**: Any open issues, TODOs, known limitations, or incomplete migrations
|
|
954
|
+
|
|
955
|
+
## Scope discipline
|
|
956
|
+
|
|
957
|
+
Only research workflows that the change actually touches. Do not research every workflow in the codebase. If a changed file participates in three workflows but the change only affects one, research only that one.
|
|
958
|
+
|
|
959
|
+
If the change is small and touches a single workflow, the guide may be one section. If the change is cross-cutting, the guide may have several sections. Let the change determine the scope.
|
|
960
|
+
|
|
961
|
+
## What this skill is NOT
|
|
962
|
+
|
|
963
|
+
- It is not a code review. Do not evaluate the quality of the code or flag issues. That is the job of the review specialists.
|
|
964
|
+
- It is not a project context builder. That is the job of thatch-review-context, which gathers project metadata (tickets, PRs, TODOs, deferred work). This skill gathers code-level context (flows, comments, git history, evolutions).
|
|
965
|
+
- It is not a memory writer. Do not call thatch_memory_remember. If you discover durable facts, note them in the guide; the session-reflection or fact-extractor skills will persist them later.
|
|
966
|
+
`;
|
|
967
|
+
|
|
736
968
|
// ---------------------------------------------------------------------------
|
|
737
969
|
// Session reflection — end-of-session memory recording guidance
|
|
738
970
|
// ---------------------------------------------------------------------------
|
|
@@ -833,7 +1065,35 @@ Fetch any refs not locally reachable so branches and PRs that were never checked
|
|
|
833
1065
|
|
|
834
1066
|
Run git diff --stat on the resolved range and git log --oneline to understand the change.
|
|
835
1067
|
|
|
836
|
-
## Step 2:
|
|
1068
|
+
## Step 2: Gather project context
|
|
1069
|
+
|
|
1070
|
+
Load the thatch-review-context skill and follow its methodology to build a context brief for this change. Investigate:
|
|
1071
|
+
- PR description (if a PR was specified or detected via the branch)
|
|
1072
|
+
- Branch name for ticket identifiers
|
|
1073
|
+
- Git log for commit messages referencing tickets or describing scope
|
|
1074
|
+
- TODO ($ticket) markers in the diff
|
|
1075
|
+
- thatch_memory_recall for feature/project status, design decisions, ticket dependencies
|
|
1076
|
+
- Project docs, READMEs, design docs
|
|
1077
|
+
- Issue tracker (gh issue/view) if ticket IDs are found
|
|
1078
|
+
|
|
1079
|
+
Produce the context brief in the format the skill prescribes (project context, this change's scope, deferred work, dependencies, relevant constraints).
|
|
1080
|
+
|
|
1081
|
+
If context is sparse (no PR description, no ticket references, no relevant memories), note that the change appears standalone. Even a sparse brief is valuable: it tells specialists you looked and found nothing, so they do not need to repeat the search.
|
|
1082
|
+
|
|
1083
|
+
## Step 3: Research affected workflows
|
|
1084
|
+
|
|
1085
|
+
Dispatch a sub-agent using the Task tool to research the code workflows affected by this change. Pass the sub-agent:
|
|
1086
|
+
- The git range and changed files (from Step 1)
|
|
1087
|
+
- The project context brief (from Step 2)
|
|
1088
|
+
- Instructions to load the thatch-workflow-research skill and follow its methodology
|
|
1089
|
+
|
|
1090
|
+
The sub-agent produces a code guide with one section per affected workflow or feature. Wait for it to complete and collect the guide.
|
|
1091
|
+
|
|
1092
|
+
This guide gives specialists the code-level context (purpose, data flow, evolutions, constraints) they need to avoid false positives about intentional behavior and long-standing design decisions, and reduces duplicate code-tracing across the five specialist lenses.
|
|
1093
|
+
|
|
1094
|
+
For small changes (a single file or trivial diff), you may do this research inline instead of dispatching a sub-agent. Use your judgment: if the workflow research would require reading more than 3-4 files, dispatch a sub-agent to preserve your context for orchestration.
|
|
1095
|
+
|
|
1096
|
+
## Step 4: Estimate complexity
|
|
837
1097
|
|
|
838
1098
|
Estimate the review effort in scrum points (1-13 scale):
|
|
839
1099
|
- **1**: Trivial — typo fix, config tweak, single-line change.
|
|
@@ -847,7 +1107,7 @@ Points reflect *review complexity*, not implementation effort.
|
|
|
847
1107
|
|
|
848
1108
|
Identify files to exclude from review: vendored dependencies, generated files, lockfiles, compiled assets.
|
|
849
1109
|
|
|
850
|
-
## Step
|
|
1110
|
+
## Step 5: Partition (if > 3 points)
|
|
851
1111
|
|
|
852
1112
|
For changes estimated at more than 3 points, partition into review units of approximately 3 points each:
|
|
853
1113
|
- Group files by logical component or feature, not by directory.
|
|
@@ -857,7 +1117,7 @@ For changes estimated at more than 3 points, partition into review units of appr
|
|
|
857
1117
|
|
|
858
1118
|
For changes estimated at 3 points or fewer, skip partitioning — dispatch one set of specialists covering the full scope. A single 3-point unit is not large enough to warrant decomposition.
|
|
859
1119
|
|
|
860
|
-
## Step
|
|
1120
|
+
## Step 6: Dispatch specialist sub-agents
|
|
861
1121
|
|
|
862
1122
|
For each review unit, dispatch sub-agents using the Task tool. Each sub-agent runs one specialist lens on one review unit. The five specialists are:
|
|
863
1123
|
|
|
@@ -876,7 +1136,7 @@ For the integration review unit (5+ points), dispatch a sub-agent focused on:
|
|
|
876
1136
|
- Boundary correctness — race conditions, ordering dependencies, shared state issues at boundaries.
|
|
877
1137
|
- Top-level coherence — does the overall change make sense as a unit?
|
|
878
1138
|
|
|
879
|
-
## Step
|
|
1139
|
+
## Step 7: Synthesize
|
|
880
1140
|
|
|
881
1141
|
After all sub-agents complete, load the thatch-review-synthesizer skill to verify findings, deduplicate across specialists, classify (CONFIRMED/REJECTED/UNVERIFIABLE), and produce the final severity-grouped report.
|
|
882
1142
|
|
|
@@ -897,10 +1157,13 @@ When dispatching each sub-agent, include in the prompt:
|
|
|
897
1157
|
- The specific files in this unit's scope
|
|
898
1158
|
- The specialist focus (from the five specialists above)
|
|
899
1159
|
- The diff stat for this unit's files
|
|
1160
|
+
- **The project context brief** from Step 2, filtered to what is relevant to this unit's scope. Explicitly list any deferred work that falls within this unit's files, and call out TODO ($ticket) markers the specialists should recognize as intentional.
|
|
1161
|
+
- **The workflow guide** from Step 3, filtered to the workflows relevant to this unit's scope. Use it to understand the purpose and evolution of the code before flagging issues. It provides the code-level context (flows, contracts, history, constraints) that prevents false positives about intentional behavior and long-standing design decisions.
|
|
900
1162
|
- Any design context or specific concerns
|
|
901
1163
|
- Explicit scope boundaries ("your scope is X; do NOT review Y")
|
|
902
1164
|
- Instruction to produce markdown findings with: severity, category, file:line, finding, evidence, trigger scenario, reachability, source of truth, producer chain, provenance
|
|
903
1165
|
- Instruction to apply the reachability gate (including reading and citing governing constraints for data-state claims) and intent verification before reporting
|
|
1166
|
+
- Instruction to respect the project context brief: do not flag deferred work as bugs or inconsistencies, and recognize TODO ($ticket) markers as intentional breadcrumbs
|
|
904
1167
|
`;
|
|
905
1168
|
|
|
906
1169
|
// ---------------------------------------------------------------------------
|
|
@@ -918,6 +1181,8 @@ const SHARED_SKILLS: SkillDef[] = [
|
|
|
918
1181
|
{ name: "thatch-review-no-slop", content: REVIEW_NO_SLOP },
|
|
919
1182
|
{ name: "thatch-review-breadcrumbs", content: REVIEW_BREADCRUMBS },
|
|
920
1183
|
{ name: "thatch-review-synthesizer", content: REVIEW_SYNTHESIZER },
|
|
1184
|
+
{ name: "thatch-review-context", content: REVIEW_CONTEXT },
|
|
1185
|
+
{ name: "thatch-workflow-research", content: WORKFLOW_RESEARCH },
|
|
921
1186
|
{ name: "thatch-session-reflection", content: SESSION_REFLECTION },
|
|
922
1187
|
];
|
|
923
1188
|
|