@jeffober/thatch 0.1.22 → 0.1.25

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.
@@ -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 19 skills
24
+ ## The 20 skills
25
25
 
26
- **Shared (18)** — installed everywhere; no sub-agents required:
26
+ **Shared (19)** — installed everywhere; no sub-agents required:
27
27
 
28
28
  | Skill | Role |
29
29
  |-------|------|
@@ -36,6 +36,7 @@ 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-mark-and-sweep` | Mechanical change completeness: whole-repo sweep for stragglers after renames, flag removals, API substitutions. |
39
+ | `thatch-review-highlights` | Positive finding detection: notably clever solutions, cleanup done along the way, documentation that helps. Medium-high bar against generic praise. |
39
40
  | `thatch-review-synthesizer` | Verify specialist findings against code, dedupe, classify, calibrate severity. Starts the final report with a workflow-change preface, then cross-references findings against prior review comments when a follow-up round register is provided. |
40
41
  | `thatch-review-context` | Gather project/feature context (PR descriptions, git archaeology, ticket references, memory) before fan-out. Prevents false positives about intentionally deferred work. Also fetches prior review comments on a connected PR/MR for follow-up-round detection and builds a register with preliminary addressed-check status per comment. |
41
42
  | `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. |
@@ -50,11 +51,11 @@ description: Extract durable project facts ... Use when ...
50
51
 
51
52
  | Skill | Role |
52
53
  |-------|------|
53
- | `thatch-code-review` | Resolve review target (incl. VCS detection and connected PR/MR lookup for follow-up round detection), gather project context, research affected workflows, estimate complexity, partition, dispatch the 6 specialists in parallel, synthesize with a workflow-change preface and prior-comment cross-reference. |
54
+ | `thatch-code-review` | Resolve review target (incl. VCS detection and connected PR/MR lookup for follow-up round detection), gather project context, research affected workflows, estimate complexity, partition, dispatch the 7 specialists in parallel, synthesize with a workflow-change preface and prior-comment cross-reference. |
54
55
 
55
56
  ## REVIEW_COMMON
56
57
 
57
- The six review specialists share a framework interpolated via `${REVIEW_COMMON}`:
58
+ The six problem-finding review specialists share a framework interpolated via `${REVIEW_COMMON}` (the seventh specialist, highlights, finds positive things and uses its own structure):
58
59
 
59
60
  - **Static analysis only** — no running tests/linters/compilers.
60
61
  - **Scope gathering** — resolve the git range, `git diff --stat`, read changed
@@ -84,7 +85,7 @@ The synthesizer reuses the same verification rigor but has its own structure
84
85
  ## The two arrays
85
86
 
86
87
  ```ts
87
- const SHARED_SKILLS: SkillDef[] = [ /* 18 skills above */ ];
88
+ const SHARED_SKILLS: SkillDef[] = [ /* 19 skills above */ ];
88
89
  const OPENCODE_ONLY_SKILLS: SkillDef[] = [ /* code-review coordinator */ ];
89
90
  ```
90
91
 
@@ -107,7 +108,7 @@ and `--cursor` pass only the shared set.
107
108
 
108
109
  ## Adding a skill
109
110
 
110
- 1. Write `artifacts/skills/thatch-<name>.md` with YAML frontmatter. If it's a review specialist, include `${REVIEW_COMMON}` (interpolated from `artifacts/skills/common.md`).
111
+ 1. Write `artifacts/skills/thatch-<name>.md` with YAML frontmatter. If it's a problem-finding review specialist, include `${REVIEW_COMMON}` (interpolated from `artifacts/skills/common.md`). The highlights specialist does not use REVIEW_COMMON — it finds positive things, not problems, so the problem-finding framework does not apply.
111
112
  2. Add the skill name to the `names` array in `loadSharedSkills()` (or `loadOpencodeOnlySkills()` if sub-agents are needed). The loader in `src/skills.ts` reads `.md` files at init.
112
113
  3. If the skill name appears in a tool's workflow (e.g. `thatch-fact-extractor`), update `src/prompts.ts`.
113
114
  4. Run `mise run check` — tests verify counts; `installSkills` picks up new files on next init.
@@ -115,7 +116,7 @@ and `--cursor` pass only the shared set.
115
116
  ## Memory review skills in practice
116
117
 
117
118
  - **Quick single lens**: load any specialist directly and point it at a branch.
118
- - **Full review on opencode**: load `thatch-code-review` — it gathers project context, researches affected workflows, dispatches all 6 specialists in parallel (with both the context brief and workflow guide injected into each briefing), then synthesizes a report that starts with the workflow changes before findings.
119
+ - **Full review on opencode**: load `thatch-code-review` — it gathers project context, researches affected workflows, dispatches all 7 specialists in parallel (with both the context brief and workflow guide injected into each briefing), then synthesizes a report that starts with the workflow changes before findings.
119
120
  - **Full review on Claude Code/Cursor**: run each specialist in sequence, then
120
121
  run `thatch-review-synthesizer` to verify and aggregate.
121
122
 
@@ -22,7 +22,7 @@ file/IPC/CLI contracts ready to graduate into `bun:test` integration tests.
22
22
  | [UC-011](UC-011-write-time-similarity-warning.md) | Write-time warning never blocks; merge or mark-distinct reconciliation |
23
23
  | [UC-012](UC-012-model-migration.md) | `THATCH_MODEL` change: old memories skipped (not corrupted) until re-saved |
24
24
  | [UC-013](UC-013-compaction-context.md) | Compaction context re-familiarization (opencode-only) |
25
- | [UC-014](UC-014-skill-install-drift.md) | Skill install: 18 shared vs 19 opencode; drift overwritten on re-setup |
25
+ | [UC-014](UC-014-skill-install-drift.md) | Skill install: 19 shared vs 20 opencode; drift overwritten on re-setup |
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`) |
@@ -9,26 +9,46 @@ client and a synthetic tool call sequence._
9
9
  **Steps**
10
10
  1. Do some real work: have the agent read files, run commands, edit code —
11
11
  any non-`thatch_*`, non-`skill`, non-`task` tool activity.
12
- 2. Send your next message (anything).
12
+ 2. The agent's turn ends and the session goes idle.
13
13
 
14
- **Expected**
15
- - The agent's context for that message includes a `[thatch]` nudge carrying a
16
- JSON payload summarizing the buffered tool interactions (tool name, title,
17
- truncated args/output).
18
- - The agent loads `thatch-fact-extractor` and saves durable facts via
14
+ **Expected (opencode — direct extraction, primary path)**
15
+ - The plugin's `event` hook catches `session.status` idle with pending tool
16
+ interactions and calls `triggerExtraction`: creates a child session via
17
+ `client.session.create({ parentID })` and prompts it via
18
+ `client.session.promptAsync` (or `client.session.prompt` fire-and-forget
19
+ if the env var is unset).
20
+ - The `extracting` set suppresses the nudge in `chat.message` while the
21
+ child runs — no nudge text appears in the user's conversation.
22
+ - The child loads `thatch-fact-extractor` and saves durable facts via
19
23
  `thatch_memory_remember` — or saves nothing if the activity was routine.
20
- - The buffer is **not** drained on nudge delivery — it persists until the agent
21
- writes a memory or accepts it by calling `thatch_extraction_done`. Accepting
22
- quiets the nudge while holding the entries until the extractor completes; a
23
- child extractor that errors or is deleted requeues them. If the nudge is ignored,
24
- the next message carries a repeat nudge, escalating in urgency:
24
+ - A `thatch_memory_remember` call in the child drains the parent's snapshot
25
+ entries from the buffer (via `consumeSnapshot` with `parentSnapshots`).
26
+ - When the child goes idle, the parent's snapshot entries are drained
27
+ (covering no-save runs where no memory was written), the child session is
28
+ deleted, and a toast notification fires with the extraction metrics
29
+ (`[thatch] new: N, updated: M, deleted: K`, or
30
+ `[thatch] extraction complete — nothing to save`).
31
+ - If `triggerExtraction` throws, the `extracting` set is cleared and the
32
+ nudge fires as a fallback on the next `chat.message` (see below).
33
+
34
+ **Expected (fallback nudge path — opencode when direct extraction fails,
35
+ and all MCP hosts)**
36
+ - The agent's context for the next message includes a `[thatch]` nudge
37
+ carrying a JSON payload summarizing the buffered tool interactions (tool
38
+ name, title, truncated args/output).
39
+ - The buffer is **not** drained on nudge delivery — it persists until the
40
+ agent writes a memory or accepts it by calling `thatch_extraction_done`.
41
+ Accepting quiets the nudge while holding the entries until the extractor
42
+ completes; a child extractor that errors or is deleted requeues them. If
43
+ the nudge is ignored, the next message carries a repeat nudge, escalating
44
+ in urgency:
25
45
  - 1st-2nd miss: polite tone
26
46
  - 3rd consecutive miss (missedCount=2): insistent (directive) tone
27
47
  - 4th+ consecutive miss (missedCount>=3): ALL-CAPS tone
28
48
  The counter resets when the buffer drains (memory write) or is accepted
29
49
  (`thatch_extraction_done`).
30
- - A `thatch_memory_remember` call in a child sub-agent session also drains the
31
- parent's buffer (via the `childToParent` Map), so dispatching the
50
+ - A `thatch_memory_remember` call in a child sub-agent session also drains
51
+ the parent's buffer (via the `childToParent` Map), so dispatching the
32
52
  fact-extractor as a background task clears the parent's queue.
33
53
  - Two concurrent sessions never see each other's interactions in a nudge.
34
54
  - The agent's own `thatch_*` tool calls never appear in a payload (no
@@ -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
- **18 shared skills** (no code-review coordinator) to `$CLAUDE_CONFIG_DIR/skills/` — user-scoped
20
+ **19 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 18 shared skills to `~/.cursor/skills/`.
25
+ `thatch flush-tools --json`; and installs 19 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 **18 shared skills** to the skills
16
+ - Claude Code and Cursor install exactly **19 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** — the 18 shared plus the coordinator.
19
+ - opencode installs **20** — the 19 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 (18 vs 19), content-diff-overwrite, and
26
+ _Automatable: yes — file presence, count (19 vs 20), content-diff-overwrite, and
27
27
  coordinator host-gating are all file assertions (`setup.test.ts` already covers
28
28
  the unit contract)._
@@ -34,7 +34,19 @@ are testable with the mock client and a synthetic tool call sequence._
34
34
  or is deleted first, the entries requeue and the nudge replays.
35
35
  - Step 7: no extraction nudge appears (buffer is accepted). If the user prompt
36
36
  semantically matches existing memories, a recall nudge may appear instead.
37
- - Alternative drain path: if a child sub-agent (dispatched via the `task`
38
- tool) writes a memory via `thatch_memory_remember`, the parent's buffer is
39
- also drained via the `childToParent` Map — the `missedNudges` counter resets
40
- for the parent session.
37
+ - Alternative drain path (opencode direct extraction): when the parent session
38
+ goes idle with pending tool interactions, the plugin calls
39
+ `triggerExtraction` — creates a child session via the SDK client and prompts
40
+ it directly. The `extracting` set suppresses the nudge in `chat.message`
41
+ while the child runs. The child writes memories via
42
+ `thatch_memory_remember`, which drains the parent's snapshot entries via
43
+ `consumeSnapshot`. When the child goes idle, the snapshot is drained
44
+ (covering no-save runs), the child session is deleted, and a toast fires
45
+ with the metrics. This path bypasses the nudge-and-acknowledge cycle
46
+ entirely — no `missedNudges` counter, no escalation. The nudge path is
47
+ fallback only (when `triggerExtraction` throws).
48
+ - Alternative drain path (agent-initiated): if a child sub-agent (dispatched
49
+ via the `task` tool in the fallback nudge path) writes a memory via
50
+ `thatch_memory_remember`, the parent's buffer is also drained via the
51
+ `childToParent` Map — the `missedNudges` counter resets for the parent
52
+ session.
@@ -20,16 +20,15 @@ Publish to npm and add thatch to your opencode config:
20
20
 
21
21
  OpenCode installs the plugin and its dependencies automatically on next start.
22
22
 
23
- Set this environment variable so the extraction nudge can dispatch the
24
- fact-extractor as a **background** sub-agent instead of blocking your turn:
23
+ For async extraction (child sessions run in the background):
25
24
 
26
25
  ```bash
27
26
  export OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true
28
27
  ```
29
28
 
30
- Without it, opencode hides the task tool's `background` parameter and the
31
- extraction nudge runs synchronously. Put it in your shell rc, `mise.toml`
32
- `[env]`, or `.envrc`.
29
+ Without this env var, extraction still works — the child session runs
30
+ fire-and-forget instead of asynchronously. Put it in your shell rc,
31
+ `mise.toml` `[env]`, or `.envrc`.
33
32
 
34
33
  For local development before publishing, use a file path:
35
34
 
@@ -106,7 +105,7 @@ Stores are created automatically — no setup required.
106
105
 
107
106
  | Tool | What it does |
108
107
  |------|-------------|
109
- | `thatch_extraction_done` | Acknowledge that the extraction nudge was dispatched to a sub-agent. Drains the buffer so the nudge does not replay. Called after dispatching a background task to run the fact-extractor skill. |
108
+ | `thatch_extraction_done` | Acknowledge extraction buffer work. In the nudge fallback path, quiets the nudge while holding entries until the extractor completes. In a child extractor session, marks entries complete. Called by the model after dispatching the fact-extractor skill. |
110
109
 
111
110
  ### Prediction tools
112
111
 
@@ -133,13 +132,21 @@ Beyond the tools, thatch hooks into opencode itself:
133
132
  - **Write-time similarity warning.** Saving a memory that closely resembles an
134
133
  existing one succeeds, but the response warns the agent and lists the
135
134
  similar entries so it can merge them or record that they're distinct.
136
- - **Fact-extraction nudges.** Thatch buffers the session's recent tool calls
137
- (up to 20, per session). On your next message, the agent receives a summary
138
- payload and is prompted to save any durable facts it reveals. The nudge
139
- repeats and escalates (polite to insistent to ALL-CAPS) each turn it's
140
- ignored — the buffer drains only when the agent writes a memory or
141
- acknowledges via `thatch_extraction_done`. The agent does the writing —
142
- thatch never saves memories on its own.
135
+ - **Fact extraction.** Thatch buffers the session's recent tool calls (up
136
+ to 20, per session). When the session goes idle, the plugin creates a
137
+ child session and prompts it to run the fact-extractor skill directly —
138
+ no nudge text in your conversation. The child writes memories via
139
+ `thatch_memory_remember` and is cleaned up when it finishes. A toast
140
+ notification shows the results (`[thatch] new: 2, updated: 1`). If the
141
+ direct path fails, a nudge is injected into the next message as a
142
+ fallback. On Claude Code and Cursor, the nudge-and-acknowledge path is
143
+ the only mechanism (no SDK client to create child sessions). The agent
144
+ does the writing — thatch never saves memories on its own.
145
+ - **Recall and prediction toasts.** When your prompt matches stored
146
+ memories or learned decision patterns, thatch injects a synthetic nudge
147
+ (invisible to you, visible to the agent) and fires a toast notification
148
+ (`[thatch] recalled 3 memories` or `[thatch] 2 predictions surfaced`).
149
+ The toast is ephemeral — it fades after a few seconds.
143
150
  - **Compaction context.** When opencode compacts a long session, thatch injects
144
151
  a reminder so the summarized session still knows memory tools exist.
145
152
  - **Prediction auto-fire.** When a prompt matches learned contexts, thatch
@@ -179,7 +186,7 @@ With `thatch setup --claude`, skills install to `~/.claude/skills/` (or
179
186
 
180
187
  ### Code review skills
181
188
 
182
- Six specialist review lenses, each a self-contained static-analysis pass:
189
+ Seven specialist review lenses, each a self-contained static-analysis pass:
183
190
 
184
191
  | Skill | Focus |
185
192
  |-------|-------|
@@ -189,7 +196,8 @@ Six specialist review lenses, each a self-contained static-analysis pass:
189
196
  | `thatch-review-no-slop` | AI writing anti-patterns: change narration, fourth wall breaks, em dashes, hedging, filler. |
190
197
  | `thatch-review-breadcrumbs` | Comment narrative: do comments form a coherent outline of the code's behavior? |
191
198
  | `thatch-review-mark-and-sweep` | Mechanical change completeness: whole-repo sweep for stragglers after renames, flag removals, API substitutions. |
192
- | `thatch-review-synthesizer` | Verifies and synthesizes findings from multiple specialists into a report that starts with workflow changes, then deduplicated severity-grouped findings. |
199
+ | `thatch-review-highlights` | Positive finding detection: notably clever solutions, cleanup done along the way, documentation that helps. Medium-high bar against generic praise. |
200
+ | `thatch-review-synthesizer` | Verifies and synthesizes findings from multiple specialists into a report that starts with workflow changes, then highlights, then deduplicated severity-grouped findings. |
193
201
  | `thatch-review-context` | Gathers project context (PR descriptions, git archaeology, ticket references, memory) before a review. Prevents false positives about intentionally deferred work. |
194
202
  | `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. |
195
203
  | `thatch-change-walkthrough` | Explains a change to the user as a teaching walkthrough: researches each affected workflow at the merge-base, teaches current behavior, then overlays the modifications with file:line citations. |
@@ -214,7 +222,7 @@ Six specialist review lenses, each a self-contained static-analysis pass:
214
222
  | Skill | opencode | Claude Code | Cursor |
215
223
  |-------|----------|-------------|--------|
216
224
  | Memory skills (4) | Yes | Yes | Yes |
217
- | Review specialists (6) | Yes | Yes | Yes |
225
+ | Review specialists (7) | Yes | Yes | Yes |
218
226
  | Review synthesizer | Yes | Yes | Yes |
219
227
  | Review context + workflow research | Yes | Yes | Yes |
220
228
  | Walkthrough skills (2) | Yes | Yes | Yes |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jeffober/thatch",
3
- "version": "0.1.22",
3
+ "version": "0.1.25",
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",