@jeffober/thatch 0.1.26 → 0.1.28

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.
Files changed (72) hide show
  1. package/README.md +7 -7
  2. package/artifacts/skills/common.md +1 -1
  3. package/artifacts/skills/thatch-change-walkthrough.md +2 -2
  4. package/artifacts/skills/thatch-code-archaeology.md +252 -0
  5. package/artifacts/skills/thatch-code-review.md +4 -4
  6. package/artifacts/skills/thatch-code-walkthrough.md +2 -2
  7. package/artifacts/skills/thatch-coding-workflow.md +79 -0
  8. package/artifacts/skills/thatch-fact-extractor.md +2 -2
  9. package/artifacts/skills/{pr-description.md → thatch-pr-description.md} +1 -1
  10. package/artifacts/skills/thatch-review-context.md +9 -0
  11. package/artifacts/skills/thatch-review-followup.md +29 -1
  12. package/artifacts/skills/thatch-review-pedantic.md +16 -1
  13. package/artifacts/skills/thatch-review-response.md +365 -0
  14. package/artifacts/skills/thatch-review-synthesizer.md +92 -5
  15. package/artifacts/skills/{split-overlarge-pr.md → thatch-split-overlarge-pr.md} +1 -1
  16. package/artifacts/skills/{ticket-description.md → thatch-ticket-description.md} +3 -3
  17. package/bin/release +3 -3
  18. package/bin/thatch +11 -10
  19. package/docs/dev/README.md +7 -6
  20. package/docs/dev/mcp-parity.md +1 -1
  21. package/docs/dev/skills.md +29 -9
  22. package/docs/plans/README.md +9 -6
  23. package/docs/plans/intuition-drives.md +147 -0
  24. package/docs/plans/nomenclater.md +89 -0
  25. package/docs/plans/prediction-consolidation.md +361 -0
  26. package/docs/qa/README.md +20 -3
  27. package/docs/user/README.md +19 -5
  28. package/package.json +1 -1
  29. package/src/db.ts +6 -6
  30. package/src/embeddings.ts +2 -2
  31. package/src/extract-queue.ts +4 -4
  32. package/src/extraction.ts +4 -4
  33. package/src/git.ts +1 -1
  34. package/src/hygiene.ts +1 -1
  35. package/src/index.ts +40 -34
  36. package/src/mcp.ts +34 -6
  37. package/src/prompts.ts +96 -85
  38. package/src/setup.ts +19 -19
  39. package/src/sideband.ts +3 -3
  40. package/src/skills.ts +104 -6
  41. package/src/tool-defs.ts +93 -14
  42. package/src/tools.ts +12 -2
  43. package/artifacts/skills/thatch-workflow-research.md +0 -91
  44. package/docs/in-progress/prediction-engine.md +0 -404
  45. package/docs/plans/001-memory-store.md +0 -106
  46. package/docs/plans/002-agent-driven-pipelines.md +0 -59
  47. package/docs/plans/003-memory-hygiene.md +0 -61
  48. package/docs/qa/use-cases/README.md +0 -51
  49. package/docs/qa/use-cases/UC-001-memory-roundtrip.md +0 -20
  50. package/docs/qa/use-cases/UC-002-dedup-cycle.md +0 -23
  51. package/docs/qa/use-cases/UC-003-extraction-nudge.md +0 -56
  52. package/docs/qa/use-cases/UC-004-cli-inspection.md +0 -22
  53. package/docs/qa/use-cases/UC-005-setup-install.md +0 -34
  54. package/docs/qa/use-cases/UC-006-cursor-hook-lifecycle.md +0 -32
  55. package/docs/qa/use-cases/UC-007-recall-nudge.md +0 -31
  56. package/docs/qa/use-cases/UC-008-hygiene-heartbeat.md +0 -26
  57. package/docs/qa/use-cases/UC-009-flush-tools-tiers.md +0 -33
  58. package/docs/qa/use-cases/UC-010-prime.md +0 -25
  59. package/docs/qa/use-cases/UC-011-write-time-similarity-warning.md +0 -24
  60. package/docs/qa/use-cases/UC-012-model-migration.md +0 -28
  61. package/docs/qa/use-cases/UC-013-compaction-context.md +0 -25
  62. package/docs/qa/use-cases/UC-014-skill-install-drift.md +0 -28
  63. package/docs/qa/use-cases/UC-015-env-override-matrix.md +0 -28
  64. package/docs/qa/use-cases/UC-016-concurrent-session-isolation.md +0 -37
  65. package/docs/qa/use-cases/UC-017-buffer-tool-vs-buffer-batch.md +0 -27
  66. package/docs/qa/use-cases/UC-018-mcp-startup-setup-detection.md +0 -38
  67. package/docs/qa/use-cases/UC-019-archived-memory-lifecycle.md +0 -36
  68. package/docs/qa/use-cases/UC-020-extraction-escalation.md +0 -52
  69. package/docs/qa/use-cases/UC-021-prediction-autofire.md +0 -21
  70. package/docs/qa/use-cases/UC-022-prediction-dedup.md +0 -19
  71. package/docs/qa/use-cases/UC-023-prediction-confidence-model.md +0 -23
  72. package/docs/qa/use-cases/UC-024-prediction-delete.md +0 -20
package/src/prompts.ts CHANGED
@@ -9,7 +9,7 @@ knowledge so future sessions can build on what you've already learned.
9
9
  Tools: thatch_memory_remember, thatch_memory_recall, thatch_memory_list,
10
10
  thatch_memory_show, thatch_memory_forget, thatch_store_list,
11
11
  thatch_find_duplicates, thatch_dedup_mark_checked,
12
- thatch_extraction_done,
12
+ thatch_extraction_done, thatch_get_extraction_payload,
13
13
  thatch_prediction_query, thatch_prediction_update, thatch_prediction_list,
14
14
  thatch_prediction_delete
15
15
 
@@ -37,19 +37,20 @@ you're working in. Prior sessions may have already investigated it.
37
37
  Thatch ships skills for code review, project investigation, and memory
38
38
  workflows. The host auto-discovers them, but reach for them proactively:
39
39
 
40
- - \`thatch-code-review\` — full multi-agent code review (dispatches 7 specialists + synthesizer). Requires sub-agent support.
41
- - \`thatch-review-followup\` — alternate entrypoint for follow-up review rounds. Verifies whether the author's responses and code changes since your last review adequately addressed prior findings, offers to reply on resolved items, then optionally re-runs the full structured review.
42
- - \`thatch-workflow-research\` — research code workflows affected by a change or planned change, before reviewing or planning.
43
- - \`thatch-change-walkthrough\` — produces a teaching walkthrough of a diff with a specific format (SYNOPSIS + per-workflow orient/mechanism/numbered-stages + change overlay mirroring the same numbers) and calibrated prose rules. Load the skill for the format and prose rules, not just for the research method.
44
- - \`thatch-code-walkthrough\` — produces a teaching walkthrough for a feature/workflow as it stands today with a specific format (SYNOPSIS + per-workflow orient/mechanism/numbered-stages + Key files) and calibrated prose rules. Also use proactively to draft high-level docs for new or undocumented features (suitable for pkg/README.md or docs/features/<name>.md). Load the skill for the format and prose rules, not just for the research method.
45
- - \`thatch-review-context\` — gather project context (PRs, tickets, TODOs, deferred work) before a review.
46
- - \`thatch-project-primer\` — investigate a new project and write foundational memories.
47
- - \`thatch-session-reflection\` — record what you learned at end of session.
48
- - \`thatch-fact-extractor\` — extract durable facts from recent tool interactions (auto-triggered by the extraction pipeline).
49
- - \`thatch-dedup-classifier\` — resolve duplicate memory pairs from \`thatch_find_duplicates\`.
50
- - \`pr-description\` — draft a PR description with SYNOPSIS / PURPOSE / DESCRIPTION / WALK-THROUGH / NOTES, using bold and italic emphasis on the phrases that carry the meaning.
51
- - \`ticket-description\` — draft a ticket, issue, or work item (Linear or Jira) with clear sections and bold/italic emphasis for scanning.
52
- - \`split-overlarge-pr\` — split already-completed work from an overlarge PR into human-reviewable, release-safe PRs targeting main.
40
+ - \`thatch-code-review\` - full multi-agent code review (dispatches 7 specialists + synthesizer). Requires sub-agent support.
41
+ - \`thatch-review-followup\` - alternate entrypoint for follow-up review rounds. Verifies whether the author's responses and code changes since your last review adequately addressed prior findings, offers to reply on resolved items, then optionally re-runs the full structured review.
42
+ - \`thatch-code-archaeology\` - investigate an existing feature, debug an unfamiliar area, or begin a new ticket. Explores the code base from multiple angles (data model, state flow, git history, sibling features) before proposing changes. The research skill; pair with \`thatch-coding-workflow\`.
43
+ - \`thatch-change-walkthrough\` - produces a teaching walkthrough of a diff with a specific format (SYNOPSIS + per-workflow orient/mechanism/numbered-stages + change overlay mirroring the same numbers) and calibrated prose rules. Load the skill for the format and prose rules, not just for the research method.
44
+ - \`thatch-code-walkthrough\` - produces a teaching walkthrough for a feature/workflow as it stands today with a specific format (SYNOPSIS + per-workflow orient/mechanism/numbered-stages + Key files) and calibrated prose rules. Also use proactively to draft high-level docs for new or undocumented features (suitable for pkg/README.md or docs/features/<name>.md). Load the skill for the format and prose rules, not just for the research method.
45
+ - \`thatch-review-context\` - gather project context (PRs, tickets, TODOs, deferred work) before a review.
46
+ - \`thatch-project-primer\` - investigate a new project and write foundational memories.
47
+ - \`thatch-session-reflection\` - record what you learned at end of session.
48
+ - \`thatch-fact-extractor\` - extract durable facts from recent tool interactions (auto-triggered by the extraction pipeline).
49
+ - \`thatch-dedup-classifier\` - resolve duplicate memory pairs from \`thatch_find_duplicates\`.
50
+ - \`thatch-pr-description\` - draft a PR description with SYNOPSIS / PURPOSE / DESCRIPTION / WALK-THROUGH / NOTES, using bold and italic emphasis on the phrases that carry the meaning.
51
+ - \`thatch-ticket-description\` - draft a ticket, issue, or work item (Linear or Jira) with clear sections and bold/italic emphasis for scanning.
52
+ - \`thatch-split-overlarge-pr\` - split already-completed work from an overlarge PR into human-reviewable, release-safe PRs targeting main.
53
+ - \`thatch-review-response\` - respond to code review on the user's own PR. Triage findings, fix bugs one by one, reply on each thread, then post a top-level summary comment.
53
54
 
54
55
  ## When to Write
55
56
 
@@ -61,8 +62,8 @@ current state of the code).
61
62
 
62
63
  ## Before Responding
63
64
 
64
- Before composing a final response after substantial work this turn — multiple
65
- rounds of tool calls for investigation, debugging, or code-writing — check
65
+ Before composing a final response after substantial work this turn - multiple
66
+ rounds of tool calls for investigation, debugging, or code-writing - check
66
67
  whether you've discovered knowledge worth persisting. Use thatch_memory_recall
67
68
  to check for duplicates, then thatch_memory_remember for new findings. Then
68
69
  deliver your response.
@@ -70,7 +71,7 @@ deliver your response.
70
71
  ## Background Task Completions
71
72
 
72
73
  When a background task completes and its result is injected into the session,
73
- the completion is informational — it is not user input and not approval to
74
+ the completion is informational - it is not user input and not approval to
74
75
  proceed with anything you were discussing. Do not narrate what the task did or
75
76
  summarize its output. If you were mid-conversation with the user, continue
76
77
  that thread. If the user's last message has been fully addressed, stop and
@@ -79,7 +80,7 @@ not greenlit.
79
80
 
80
81
  If a background task was cancelled after timing out, re-dispatch it once with
81
82
  the same prompt. If the re-dispatch also fails or times out, note the gap and
82
- move on. Do not retry more than once — repeated failures indicate an
83
+ move on. Do not retry more than once - repeated failures indicate an
83
84
  intractable prompt, not a transient hang.
84
85
 
85
86
  ## User Decision Model
@@ -147,7 +148,7 @@ do not save it. Do not store:
147
148
 
148
149
  ## Archived Memories
149
150
 
150
- Memories can be marked \`archived\` — a flag for stable, long-term historical
151
+ Memories can be marked \`archived\` - a flag for stable, long-term historical
151
152
  records that should not trigger hygiene nudges (stale, orphaned, duplicate).
152
153
  Archived memories are excluded from search/recall results by default; pass
153
154
  \`includeArchived: true\` to surface them for archaeological dives.
@@ -155,25 +156,25 @@ Archived memories are excluded from search/recall results by default; pass
155
156
  When a branch is merged or about to be deleted, consolidate its branch-scoped
156
157
  memories into a single archived memory scoped to that same branch (preserving
157
158
  provenance). Capture intent, design decisions, review back-and-forth, PR
158
- number, unexpected pivots — the kind of git-archaeology context that explains
159
+ number, unexpected pivots - the kind of git-archaeology context that explains
159
160
  _why_ the code looks the way it does a year from now. Then memory_forget the
160
161
  originals. The archived record outlives the branch. Future sessions searching
161
162
  with \`includeArchived: true\` can pull it up when investigating ambiguous code.
162
163
 
163
- Updating an archived memory requires passing \`archived\` explicitly — omit it
164
+ Updating an archived memory requires passing \`archived\` explicitly - omit it
164
165
  and the tool returns an error. Pass \`archived: true\` to keep it archived,
165
166
  \`archived: false\` to unarchive.
166
167
 
167
168
  ## Explicit Requests
168
169
 
169
- "Remember X" — save immediately.
170
- "Forget X" — thatch_memory_recall to find it, then thatch_memory_forget.`;
170
+ "Remember X" - save immediately.
171
+ "Forget X" - thatch_memory_recall to find it, then thatch_memory_forget.`;
171
172
  }
172
173
 
173
174
  export function compactionContext(repo: string): string {
174
175
  return `Thatch persistent memory is active with stores "${repo}" and "global".
175
176
  When summarizing, preserve context about what's been learned and decided
176
- this session — conventions, architectural decisions, and prior knowledge
177
+ this session - conventions, architectural decisions, and prior knowledge
177
178
  retrieved from memory. This ensures continuity after compaction.`;
178
179
  }
179
180
 
@@ -199,7 +200,7 @@ When convenient this session (not before addressing the user's request), tend th
199
200
  * start. The repo store name is auto-detected at runtime by the MCP server, so
200
201
  * the instructions don't need it.
201
202
  *
202
- * Tool names use the bare form (memory_remember, memory_recall, etc.) — in
203
+ * Tool names use the bare form (memory_remember, memory_recall, etc.) - in
203
204
  * Claude Code they're prefixed as mcp__thatch__memory_remember, but the bare
204
205
  * names are what the agent searches for and what the instructions reference.
205
206
  */
@@ -213,6 +214,7 @@ Tools are prefixed in Claude Code: \`mcp__thatch__memory_remember\`,
213
214
  \`mcp__thatch__memory_show\`, \`mcp__thatch__memory_forget\`,
214
215
  \`mcp__thatch__store_list\`, \`mcp__thatch__find_duplicates\`,
215
216
  \`mcp__thatch__dedup_mark_checked\`, \`mcp__thatch__extraction_done\`,
217
+ \`mcp__thatch__get_extraction_payload\`,
216
218
  \`mcp__thatch__prediction_query\`, \`mcp__thatch__prediction_update\`,
217
219
  \`mcp__thatch__prediction_list\`, \`mcp__thatch__prediction_delete\`. Bare names used below for readability.
218
220
 
@@ -240,19 +242,20 @@ you're working in. Prior sessions may have already investigated it.
240
242
  Thatch ships skills for code review, project investigation, and memory
241
243
  workflows. The host auto-discovers them, but reach for them proactively:
242
244
 
243
- - \`thatch-workflow-research\` — research code workflows affected by a change or planned change, before reviewing or planning.
244
- - \`thatch-change-walkthrough\` — produces a teaching walkthrough of a diff with a specific format (SYNOPSIS + per-workflow orient/mechanism/numbered-stages + change overlay mirroring the same numbers) and calibrated prose rules. Load the skill for the format and prose rules, not just for the research method.
245
- - \`thatch-code-walkthrough\` — produces a teaching walkthrough for a feature/workflow as it stands today with a specific format (SYNOPSIS + per-workflow orient/mechanism/numbered-stages + Key files) and calibrated prose rules. Also use proactively to draft high-level docs for new or undocumented features (suitable for pkg/README.md or docs/features/<name>.md). Load the skill for the format and prose rules, not just for the research method.
246
- - \`thatch-review-context\` — gather project context (PRs, tickets, TODOs, deferred work) before a review.
247
- - \`thatch-review-followup\` — alternate entrypoint for follow-up review rounds. Verifies whether the author's responses and code changes since your last review adequately addressed prior findings, offers to reply on resolved items, then optionally re-runs the full structured review.
248
- - \`thatch-review-pedantic\` / \`-acceptance\` / \`-state-flow\` / \`-no-slop\` / \`-breadcrumbs\` / \`-mark-and-sweep\` / \`-highlights\` — seven specialist review lenses. Run individually, then \`thatch-review-synthesizer\` to verify and aggregate.
249
- - \`thatch-project-primer\` — investigate a new project and write foundational memories.
250
- - \`thatch-session-reflection\` — record what you learned at end of session.
251
- - \`thatch-fact-extractor\` — extract durable facts from recent tool interactions (auto-triggered by the extraction pipeline).
252
- - \`thatch-dedup-classifier\` — resolve duplicate memory pairs from \`find_duplicates\`.
253
- - \`pr-description\` — draft a PR description with SYNOPSIS / PURPOSE / DESCRIPTION / WALK-THROUGH / NOTES, using bold and italic emphasis on the phrases that carry the meaning.
254
- - \`ticket-description\` — draft a ticket, issue, or work item (Linear or Jira) with clear sections and bold/italic emphasis for scanning.
255
- - \`split-overlarge-pr\` — split already-completed work from an overlarge PR into human-reviewable, release-safe PRs targeting main.
245
+ - \`thatch-code-archaeology\` - investigate an existing feature, debug an unfamiliar area, or begin a new ticket. Explores the code base from multiple angles (data model, state flow, git history, sibling features) before proposing changes. The research skill; pair with \`thatch-coding-workflow\`.
246
+ - \`thatch-change-walkthrough\` - produces a teaching walkthrough of a diff with a specific format (SYNOPSIS + per-workflow orient/mechanism/numbered-stages + change overlay mirroring the same numbers) and calibrated prose rules. Load the skill for the format and prose rules, not just for the research method.
247
+ - \`thatch-code-walkthrough\` - produces a teaching walkthrough for a feature/workflow as it stands today with a specific format (SYNOPSIS + per-workflow orient/mechanism/numbered-stages + Key files) and calibrated prose rules. Also use proactively to draft high-level docs for new or undocumented features (suitable for pkg/README.md or docs/features/<name>.md). Load the skill for the format and prose rules, not just for the research method.
248
+ - \`thatch-review-context\` - gather project context (PRs, tickets, TODOs, deferred work) before a review.
249
+ - \`thatch-review-followup\` - alternate entrypoint for follow-up review rounds. Verifies whether the author's responses and code changes since your last review adequately addressed prior findings, offers to reply on resolved items, then optionally re-runs the full structured review.
250
+ - \`thatch-review-pedantic\` / \`-acceptance\` / \`-state-flow\` / \`-no-slop\` / \`-breadcrumbs\` / \`-mark-and-sweep\` / \`-highlights\` - seven specialist review lenses. Run individually, then \`thatch-review-synthesizer\` to verify and aggregate.
251
+ - \`thatch-project-primer\` - investigate a new project and write foundational memories.
252
+ - \`thatch-session-reflection\` - record what you learned at end of session.
253
+ - \`thatch-fact-extractor\` - extract durable facts from recent tool interactions (auto-triggered by the extraction pipeline).
254
+ - \`thatch-dedup-classifier\` - resolve duplicate memory pairs from \`find_duplicates\`.
255
+ - \`thatch-pr-description\` - draft a PR description with SYNOPSIS / PURPOSE / DESCRIPTION / WALK-THROUGH / NOTES, using bold and italic emphasis on the phrases that carry the meaning.
256
+ - \`thatch-ticket-description\` - draft a ticket, issue, or work item (Linear or Jira) with clear sections and bold/italic emphasis for scanning.
257
+ - \`thatch-split-overlarge-pr\` - split already-completed work from an overlarge PR into human-reviewable, release-safe PRs targeting main.
258
+ - \`thatch-review-response\` - respond to code review on the user's own PR. Triage findings, fix bugs one by one, reply on each thread, then post a top-level summary comment.
256
259
 
257
260
  ## When to Write
258
261
 
@@ -264,8 +267,8 @@ current state of the code).
264
267
 
265
268
  ## Before Responding
266
269
 
267
- Before composing a final response after substantial work this turn — multiple
268
- rounds of tool calls for investigation, debugging, or code-writing — check
270
+ Before composing a final response after substantial work this turn - multiple
271
+ rounds of tool calls for investigation, debugging, or code-writing - check
269
272
  whether you've discovered knowledge worth persisting. Use memory_recall to
270
273
  check for duplicates, then memory_remember for new findings. Then deliver
271
274
  your response.
@@ -335,7 +338,7 @@ do not save it. Do not store:
335
338
 
336
339
  ## Archived Memories
337
340
 
338
- Memories can be marked \`archived\` — a flag for stable, long-term historical
341
+ Memories can be marked \`archived\` - a flag for stable, long-term historical
339
342
  records that should not trigger hygiene nudges (stale, orphaned, duplicate).
340
343
  Archived memories are excluded from search/recall results by default; pass
341
344
  \`includeArchived: true\` to surface them for archaeological dives.
@@ -343,19 +346,19 @@ Archived memories are excluded from search/recall results by default; pass
343
346
  When a branch is merged or about to be deleted, consolidate its branch-scoped
344
347
  memories into a single archived memory scoped to that same branch (preserving
345
348
  provenance). Capture intent, design decisions, review back-and-forth, PR
346
- number, unexpected pivots — the kind of git-archaeology context that explains
349
+ number, unexpected pivots - the kind of git-archaeology context that explains
347
350
  _why_ the code looks the way it does a year from now. Then memory_forget the
348
351
  originals. The archived record outlives the branch. Future sessions searching
349
352
  with \`includeArchived: true\` can pull it up when investigating ambiguous code.
350
353
 
351
- Updating an archived memory requires passing \`archived\` explicitly — omit it
354
+ Updating an archived memory requires passing \`archived\` explicitly - omit it
352
355
  and the tool returns an error. Pass \`archived: true\` to keep it archived,
353
356
  \`archived: false\` to unarchive.
354
357
 
355
358
  ## Explicit Requests
356
359
 
357
- "Remember X" — save immediately.
358
- "Forget X" — \`memory_recall\` to find it, then \`memory_forget\`.`;
360
+ "Remember X" - save immediately.
361
+ "Forget X" - \`memory_recall\` to find it, then \`memory_forget\`.`;
359
362
  }
360
363
 
361
364
  /**
@@ -393,17 +396,22 @@ export function claudeWriteNudge(): string {
393
396
  * their respective tool name prefix. The missedCount parameter tracks
394
397
  * consecutive nudges delivered without any memory_remember call in between,
395
398
  * escalating the tone from polite to insistent to shouting.
399
+ *
400
+ * The sessionID replaces the inline payload: the nudge tells the model to
401
+ * dispatch a sub-agent that calls get_extraction_payload to fetch the queued
402
+ * interactions as a tool response. This keeps the full payload out of the
403
+ * main session's context window.
396
404
  */
397
405
  export function extractionNudge(
398
406
  count: number,
399
407
  missedCount: number,
400
408
  toolName: string,
401
- payload: string,
409
+ sessionID: string,
402
410
  ): string {
403
411
  const plural = count === 1 ? "" : "s";
404
412
  // opencode's task tool has a `background` parameter (requires
405
413
  // OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true) that launches the sub-agent
406
- // asynchronously — the call returns immediately and the session is notified
414
+ // asynchronously - the call returns immediately and the session is notified
407
415
  // on completion. Naming the parameter gives the model a direct hit on the tool
408
416
  // schema it sees. MCP hosts (Claude Code, Cursor) keep generic sub-agent
409
417
  // wording because their background mechanisms differ and are not exposed as a
@@ -413,47 +421,48 @@ export function extractionNudge(
413
421
  ? "Dispatch a task with background: true"
414
422
  : "Spawn a background sub-agent";
415
423
  const drainTool = isOpencode ? "thatch_extraction_done" : "mcp__thatch__extraction_done";
424
+ const fetchTool = isOpencode
425
+ ? "thatch_get_extraction_payload"
426
+ : "mcp__thatch__get_extraction_payload";
416
427
  const acknowledge = `After dispatching, call ${drainTool} to acknowledge.`;
428
+ const subAgentPrompt = `Call ${fetchTool} with session_id "${sessionID}" to retrieve the queued tool interactions, then run the thatch-fact-extractor skill to extract durable facts. Call ${drainTool} with session_id "${sessionID}" when finished, even if nothing was worth saving.`;
417
429
 
418
430
  if (missedCount >= 3) {
419
431
  return `[thatch] YOU ARE IGNORING EXTRACTION INSTRUCTIONS. ` +
420
432
  `${count} TOOL INTERACTION${plural.toUpperCase()} ARE QUEUED AND YOU HAVE NOT PROCESSED ANY OF THEM. ` +
421
433
  `THE USER INSTALLED THIS PLUGIN FOR A REASON. ` +
422
- `${dispatch.toUpperCase()} NOW TO RUN THE thatch-fact-extractor SKILL. ` +
423
- `${acknowledge.toUpperCase()} ` +
424
- `USE ${toolName.toUpperCase()} TO SAVE DURABLE FACTS FROM THIS PAYLOAD:\n${payload}`;
434
+ `${dispatch.toUpperCase()} NOW WITH THIS PROMPT: "${subAgentPrompt.toUpperCase()}" ` +
435
+ `${acknowledge.toUpperCase()}`;
425
436
  }
426
437
  if (missedCount >= 2) {
427
438
  return `[thatch] YOU HAVE NOT PROCESSED YOUR PREVIOUS EXTRACTION PAYLOAD${plural.toUpperCase()}. ` +
428
439
  `${count} more tool interaction${plural} are now queued. ` +
429
- `${dispatch} to run the thatch-fact-extractor skill on this payload. ` +
430
- `${acknowledge} ` +
431
- `Use ${toolName} to save durable facts from this payload:\n${payload}`;
440
+ `${dispatch} with this prompt: "${subAgentPrompt}" ` +
441
+ `${acknowledge}`;
432
442
  }
433
443
  return `[thatch] ${dispatch} to run the thatch-fact-extractor skill ` +
434
444
  `on ${count} queued tool interaction${plural}. ` +
445
+ `Sub-agent prompt: "${subAgentPrompt}" ` +
435
446
  `${acknowledge} ` +
436
447
  `This is a system nudge, not user input. After dispatching and acknowledging, ` +
437
448
  `stop: do not advance pending work on this nudge's account. If you are ` +
438
- `waiting for the user to respond, continue waiting. ` +
439
- `Use ${toolName} to save durable facts from this payload:\n${payload}`;
449
+ `waiting for the user to respond, continue waiting.`;
440
450
  }
441
451
 
442
452
  /**
443
453
  * Prompt text sent directly to a child session the plugin created for
444
454
  * extraction. Unlike extractionNudge (which tells the model to dispatch a
445
455
  * sub-agent and call extraction_done), this prompt is already inside the
446
- * child — the model just runs the fact-extractor skill and saves facts.
447
- * The payload format is identical to the nudge path so the skill receives
448
- * the same contract either way.
456
+ * child - the model calls get_extraction_payload to fetch the queued
457
+ * interactions, runs the fact-extractor skill, and saves facts.
449
458
  */
450
- export function extractionDirectPrompt(count: number, payload: string): string {
459
+ export function extractionDirectPrompt(count: number, sessionID: string): string {
451
460
  const plural = count === 1 ? "" : "s";
452
461
  return `Run the thatch-fact-extractor skill to extract durable facts from ` +
453
462
  `${count} queued tool interaction${plural}. ` +
463
+ `Call thatch_get_extraction_payload with session_id "${sessionID}" to retrieve the interactions. ` +
454
464
  `Use thatch_memory_remember to save any durable facts you find. ` +
455
- `Call thatch_extraction_done when finished, even if nothing was worth saving.\n` +
456
- `Payload:\n${payload}`;
465
+ `Call thatch_extraction_done with session_id "${sessionID}" when finished, even if nothing was worth saving.`;
457
466
  }
458
467
 
459
468
  /**
@@ -461,13 +470,13 @@ export function extractionDirectPrompt(count: number, payload: string): string {
461
470
  * Maintained for any external callers; bin/thatch should use extractionNudge
462
471
  * directly with a missedCount from extract-queue.ts.
463
472
  */
464
- export function claudeExtractionNudge(count: number, payload: string): string {
465
- return extractionNudge(count, 0, "mcp__thatch__memory_remember", payload);
473
+ export function claudeExtractionNudge(count: number, sessionID: string): string {
474
+ return extractionNudge(count, 0, "mcp__thatch__memory_remember", sessionID);
466
475
  }
467
476
 
468
477
  /**
469
478
  * Static instructions for Cursor's AGENTS.md. Same contract as
470
- * claudeInstructions() — the host loads this at every session start, and the
479
+ * claudeInstructions() - the host loads this at every session start, and the
471
480
  * repo store name is auto-detected at runtime by the MCP server. Tool names
472
481
  * use the same mcp__thatch__ prefix since Cursor discovers MCP tools via the
473
482
  * same protocol.
@@ -482,6 +491,7 @@ Tools are prefixed in Cursor: \`mcp__thatch__memory_remember\`,
482
491
  \`mcp__thatch__memory_show\`, \`mcp__thatch__memory_forget\`,
483
492
  \`mcp__thatch__store_list\`, \`mcp__thatch__find_duplicates\`,
484
493
  \`mcp__thatch__dedup_mark_checked\`, \`mcp__thatch__extraction_done\`,
494
+ \`mcp__thatch__get_extraction_payload\`,
485
495
  \`mcp__thatch__prediction_query\`, \`mcp__thatch__prediction_update\`,
486
496
  \`mcp__thatch__prediction_list\`, \`mcp__thatch__prediction_delete\`. Bare names used below for readability.
487
497
 
@@ -509,19 +519,20 @@ you're working in. Prior sessions may have already investigated it.
509
519
  Thatch ships skills for code review, project investigation, and memory
510
520
  workflows. The host auto-discovers them, but reach for them proactively:
511
521
 
512
- - \`thatch-workflow-research\` — research code workflows affected by a change or planned change, before reviewing or planning.
513
- - \`thatch-change-walkthrough\` — produces a teaching walkthrough of a diff with a specific format (SYNOPSIS + per-workflow orient/mechanism/numbered-stages + change overlay mirroring the same numbers) and calibrated prose rules. Load the skill for the format and prose rules, not just for the research method.
514
- - \`thatch-code-walkthrough\` — produces a teaching walkthrough for a feature/workflow as it stands today with a specific format (SYNOPSIS + per-workflow orient/mechanism/numbered-stages + Key files) and calibrated prose rules. Also use proactively to draft high-level docs for new or undocumented features (suitable for pkg/README.md or docs/features/<name>.md). Load the skill for the format and prose rules, not just for the research method.
515
- - \`thatch-review-context\` — gather project context (PRs, tickets, TODOs, deferred work) before a review.
516
- - \`thatch-review-followup\` — alternate entrypoint for follow-up review rounds. Verifies whether the author's responses and code changes since your last review adequately addressed prior findings, offers to reply on resolved items, then optionally re-runs the full structured review.
517
- - \`thatch-review-pedantic\` / \`-acceptance\` / \`-state-flow\` / \`-no-slop\` / \`-breadcrumbs\` / \`-mark-and-sweep\` / \`-highlights\` — seven specialist review lenses. Run individually, then \`thatch-review-synthesizer\` to verify and aggregate.
518
- - \`thatch-project-primer\` — investigate a new project and write foundational memories.
519
- - \`thatch-session-reflection\` — record what you learned at end of session.
520
- - \`thatch-fact-extractor\` — extract durable facts from recent tool interactions (auto-triggered by the extraction pipeline).
521
- - \`thatch-dedup-classifier\` — resolve duplicate memory pairs from \`find_duplicates\`.
522
- - \`pr-description\` — draft a PR description with SYNOPSIS / PURPOSE / DESCRIPTION / WALK-THROUGH / NOTES, using bold and italic emphasis on the phrases that carry the meaning.
523
- - \`ticket-description\` — draft a ticket, issue, or work item (Linear or Jira) with clear sections and bold/italic emphasis for scanning.
524
- - \`split-overlarge-pr\` — split already-completed work from an overlarge PR into human-reviewable, release-safe PRs targeting main.
522
+ - \`thatch-code-archaeology\` - investigate an existing feature, debug an unfamiliar area, or begin a new ticket. Explores the code base from multiple angles (data model, state flow, git history, sibling features) before proposing changes. The research skill; pair with \`thatch-coding-workflow\`.
523
+ - \`thatch-change-walkthrough\` - produces a teaching walkthrough of a diff with a specific format (SYNOPSIS + per-workflow orient/mechanism/numbered-stages + change overlay mirroring the same numbers) and calibrated prose rules. Load the skill for the format and prose rules, not just for the research method.
524
+ - \`thatch-code-walkthrough\` - produces a teaching walkthrough for a feature/workflow as it stands today with a specific format (SYNOPSIS + per-workflow orient/mechanism/numbered-stages + Key files) and calibrated prose rules. Also use proactively to draft high-level docs for new or undocumented features (suitable for pkg/README.md or docs/features/<name>.md). Load the skill for the format and prose rules, not just for the research method.
525
+ - \`thatch-review-context\` - gather project context (PRs, tickets, TODOs, deferred work) before a review.
526
+ - \`thatch-review-followup\` - alternate entrypoint for follow-up review rounds. Verifies whether the author's responses and code changes since your last review adequately addressed prior findings, offers to reply on resolved items, then optionally re-runs the full structured review.
527
+ - \`thatch-review-pedantic\` / \`-acceptance\` / \`-state-flow\` / \`-no-slop\` / \`-breadcrumbs\` / \`-mark-and-sweep\` / \`-highlights\` - seven specialist review lenses. Run individually, then \`thatch-review-synthesizer\` to verify and aggregate.
528
+ - \`thatch-project-primer\` - investigate a new project and write foundational memories.
529
+ - \`thatch-session-reflection\` - record what you learned at end of session.
530
+ - \`thatch-fact-extractor\` - extract durable facts from recent tool interactions (auto-triggered by the extraction pipeline).
531
+ - \`thatch-dedup-classifier\` - resolve duplicate memory pairs from \`find_duplicates\`.
532
+ - \`thatch-pr-description\` - draft a PR description with SYNOPSIS / PURPOSE / DESCRIPTION / WALK-THROUGH / NOTES, using bold and italic emphasis on the phrases that carry the meaning.
533
+ - \`thatch-ticket-description\` - draft a ticket, issue, or work item (Linear or Jira) with clear sections and bold/italic emphasis for scanning.
534
+ - \`thatch-split-overlarge-pr\` - split already-completed work from an overlarge PR into human-reviewable, release-safe PRs targeting main.
535
+ - \`thatch-review-response\` - respond to code review on the user's own PR. Triage findings, fix bugs one by one, reply on each thread, then post a top-level summary comment.
525
536
 
526
537
  ## When to Write
527
538
 
@@ -533,8 +544,8 @@ current state of the code).
533
544
 
534
545
  ## Before Responding
535
546
 
536
- Before composing a final response after substantial work this turn — multiple
537
- rounds of tool calls for investigation, debugging, or code-writing — check
547
+ Before composing a final response after substantial work this turn - multiple
548
+ rounds of tool calls for investigation, debugging, or code-writing - check
538
549
  whether you've discovered knowledge worth persisting. Use memory_recall to
539
550
  check for duplicates, then memory_remember for new findings. Then deliver
540
551
  your response.
@@ -604,7 +615,7 @@ do not save it. Do not store:
604
615
 
605
616
  ## Archived Memories
606
617
 
607
- Memories can be marked \`archived\` — a flag for stable, long-term historical
618
+ Memories can be marked \`archived\` - a flag for stable, long-term historical
608
619
  records that should not trigger hygiene nudges (stale, orphaned, duplicate).
609
620
  Archived memories are excluded from search/recall results by default; pass
610
621
  \`includeArchived: true\` to surface them for archaeological dives.
@@ -612,23 +623,23 @@ Archived memories are excluded from search/recall results by default; pass
612
623
  When a branch is merged or about to be deleted, consolidate its branch-scoped
613
624
  memories into a single archived memory scoped to that same branch (preserving
614
625
  provenance). Capture intent, design decisions, review back-and-forth, PR
615
- number, unexpected pivots — the kind of git-archaeology context that explains
626
+ number, unexpected pivots - the kind of git-archaeology context that explains
616
627
  _why_ the code looks the way it does a year from now. Then memory_forget the
617
628
  originals. The archived record outlives the branch. Future sessions searching
618
629
  with \`includeArchived: true\` can pull it up when investigating ambiguous code.
619
630
 
620
- Updating an archived memory requires passing \`archived\` explicitly — omit it
631
+ Updating an archived memory requires passing \`archived\` explicitly - omit it
621
632
  and the tool returns an error. Pass \`archived: true\` to keep it archived,
622
633
  \`archived: false\` to unarchive.
623
634
 
624
635
  ## Explicit Requests
625
636
 
626
- "Remember X" — save immediately.
627
- "Forget X" — \`memory_recall\` to find it, then \`memory_forget\`.`;
637
+ "Remember X" - save immediately.
638
+ "Forget X" - \`memory_recall\` to find it, then \`memory_forget\`.`;
628
639
  }
629
640
 
630
641
  // ---------------------------------------------------------------------------
631
- // Prompt-aware recall nudge — fires when the user's prompt semantically
642
+ // Prompt-aware recall nudge - fires when the user's prompt semantically
632
643
  // matches existing memories. Injected via opencode's chat.message hook
633
644
  // (in-process, warm model) or via the sideband socket for Claude Code/Cursor
634
645
  // (flush-tools CLI subcommand).
package/src/setup.ts CHANGED
@@ -22,7 +22,7 @@ interface SetupPaths {
22
22
 
23
23
  /**
24
24
  * Resolve the Claude config directory. `CLAUDE_CONFIG_DIR` overrides the
25
- * default `~/.claude` location — used by people running multiple accounts
25
+ * default `~/.claude` location - used by people running multiple accounts
26
26
  * side by side (per Claude Code env-vars docs). Settings, CLAUDE.md, and
27
27
  * skills are all stored under this path in global scope. Project-local
28
28
  * installs only use it for skills (which are always user-scoped); the
@@ -41,7 +41,7 @@ function resolvePaths(global: boolean, projectDir: string, homeDir: string): Set
41
41
  mcpConfigPath: null,
42
42
  // Per Claude Code settings docs, user-scope CLAUDE.md lives at
43
43
  // `~/.claude/CLAUDE.md` (or `$CLAUDE_CONFIG_DIR/CLAUDE.md` when the
44
- // env var is set) — NOT `~/CLAUDE.md`. Honoring CLAUDE_CONFIG_DIR
44
+ // env var is set) - NOT `~/CLAUDE.md`. Honoring CLAUDE_CONFIG_DIR
45
45
  // here also fixes a pre-existing bug where we wrote to `~/CLAUDE.md`.
46
46
  claudeMdPath: join(configDir, "CLAUDE.md"),
47
47
  settingsPath: join(configDir, "settings.json"),
@@ -55,14 +55,14 @@ function resolvePaths(global: boolean, projectDir: string, homeDir: string): Set
55
55
  claudeMdPath: join(projectDir, "CLAUDE.md"),
56
56
  settingsPath: join(projectDir, ".claude", "settings.json"),
57
57
  // Skills are always user-scoped, so they always live under the config
58
- // dir — even when settings and CLAUDE.md are project-local.
58
+ // dir - even when settings and CLAUDE.md are project-local.
59
59
  skillsDir,
60
60
  global: false,
61
61
  };
62
62
  }
63
63
 
64
64
  // ---------------------------------------------------------------------------
65
- // .mcp.json — MCP server registration
65
+ // .mcp.json - MCP server registration
66
66
  // ---------------------------------------------------------------------------
67
67
 
68
68
  function writeMcpConfig(path: string, thatchBin: string): void {
@@ -71,7 +71,7 @@ function writeMcpConfig(path: string, thatchBin: string): void {
71
71
  try {
72
72
  config = JSON.parse(readFileSync(path, "utf8"));
73
73
  } catch {
74
- // Corrupt or empty — start fresh.
74
+ // Corrupt or empty - start fresh.
75
75
  }
76
76
  }
77
77
  if (!config.mcpServers) config.mcpServers = {};
@@ -87,11 +87,11 @@ function writeMcpConfig(path: string, thatchBin: string): void {
87
87
  }
88
88
 
89
89
  // ---------------------------------------------------------------------------
90
- // CLAUDE.md — append thatch instructions (idempotent)
90
+ // CLAUDE.md - append thatch instructions (idempotent)
91
91
  // ---------------------------------------------------------------------------
92
92
 
93
93
  const THATCH_MARKER = "# Persistence\n\nThatch provides persistent memory across Claude Code sessions.";
94
- const THATCH_END_MARKER = '"Forget X" — `memory_recall` to find it, then `memory_forget`.';
94
+ const THATCH_END_MARKER = '"Forget X" - `memory_recall` to find it, then `memory_forget`.';
95
95
  const CURSOR_MARKER = "# Persistence\n\nThatch provides persistent memory across Cursor sessions.";
96
96
  const CURSOR_END_MARKER = THATCH_END_MARKER;
97
97
 
@@ -119,7 +119,7 @@ function appendBlock(
119
119
  return;
120
120
  }
121
121
  }
122
- // Marker found but block boundaries didn't parse — leave it alone.
122
+ // Marker found but block boundaries didn't parse - leave it alone.
123
123
  return;
124
124
  }
125
125
  // Append to existing file.
@@ -140,7 +140,7 @@ function appendCursorInstructions(path: string): void {
140
140
  }
141
141
 
142
142
  // ---------------------------------------------------------------------------
143
- // settings.json — hook installation
143
+ // settings.json - hook installation
144
144
  // ---------------------------------------------------------------------------
145
145
 
146
146
  interface HookEntry {
@@ -163,14 +163,14 @@ function writeHooks(path: string, thatchBin: string): void {
163
163
  try {
164
164
  settings = JSON.parse(readFileSync(path, "utf8"));
165
165
  } catch {
166
- // Corrupt — start fresh.
166
+ // Corrupt - start fresh.
167
167
  }
168
168
  }
169
169
  if (!settings.hooks) settings.hooks = {};
170
170
 
171
171
  const sessionStartCmd = `${thatchBin} reminder`;
172
172
  // PostToolBatch silently buffers tool interactions to the file-backed queue
173
- // (see src/extract-queue.ts). No stdout — the next model call must not block
173
+ // (see src/extract-queue.ts). No stdout - the next model call must not block
174
174
  // on a payload that should be invisible to the agent until UserPromptSubmit.
175
175
  const bufferCmd = `${thatchBin} buffer-batch`;
176
176
  // UserPromptSubmit peeks the queue. With buffered interactions, it prints
@@ -209,7 +209,7 @@ function replaceThatchHooks(
209
209
  }
210
210
 
211
211
  // ---------------------------------------------------------------------------
212
- // Skills — install to $CLAUDE_CONFIG_DIR/skills/ (or ~/.claude/skills/ by default)
212
+ // Skills - install to $CLAUDE_CONFIG_DIR/skills/ (or ~/.claude/skills/ by default)
213
213
  // ---------------------------------------------------------------------------
214
214
 
215
215
  function installClaudeSkills(skillsDir: string): SkillFile[] {
@@ -233,7 +233,7 @@ export interface SetupResult {
233
233
  /**
234
234
  * Installs thatch into Claude Code. Writes MCP config, appends instructions to
235
235
  * CLAUDE.md, installs SessionStart + PostToolBatch + UserPromptSubmit hooks,
236
- * and installs skill files. All operations are idempotent — re-running setup
236
+ * and installs skill files. All operations are idempotent - re-running setup
237
237
  * updates content that has drifted without clobbering unrelated configuration.
238
238
  *
239
239
  * Honors `CLAUDE_CONFIG_DIR` for all user-scoped paths (settings, CLAUDE.md,
@@ -276,7 +276,7 @@ export function setupClaudeCode(
276
276
  }
277
277
 
278
278
  // ---------------------------------------------------------------------------
279
- // Cursor setup — .cursor/mcp.json, AGENTS.md, .cursor/hooks.json, skills
279
+ // Cursor setup - .cursor/mcp.json, AGENTS.md, .cursor/hooks.json, skills
280
280
  // ---------------------------------------------------------------------------
281
281
 
282
282
  /**
@@ -303,7 +303,7 @@ function resolveCursorPaths(global: boolean, projectDir: string, homeDir: string
303
303
 
304
304
  if (global) {
305
305
  return {
306
- // Cursor's global MCP config is a simple file — no equivalent of
306
+ // Cursor's global MCP config is a simple file - no equivalent of
307
307
  // `claude mcp add --scope user`. Writing ~/.cursor/mcp.json is enough.
308
308
  mcpConfigPath: join(configDir, "mcp.json"),
309
309
  agentsMdPath: join(configDir, "AGENTS.md"),
@@ -340,7 +340,7 @@ function writeCursorHooks(path: string, thatchBin: string): void {
340
340
  try {
341
341
  config = JSON.parse(readFileSync(path, "utf8"));
342
342
  } catch {
343
- // Corrupt — start fresh.
343
+ // Corrupt - start fresh.
344
344
  }
345
345
  }
346
346
  if (!config.version) config.version = 1;
@@ -351,7 +351,7 @@ function writeCursorHooks(path: string, thatchBin: string): void {
351
351
  // Code style) and Cursor would not parse it.
352
352
  const sessionStartCmd = `${thatchBin} reminder --json`;
353
353
  // postToolUse fires per-tool (Cursor has no PostToolBatch equivalent).
354
- // Silent — no stdout — so the agent loop is not delayed.
354
+ // Silent - no stdout - so the agent loop is not delayed.
355
355
  const bufferCmd = `${thatchBin} buffer-tool`;
356
356
  // beforeSubmitPrompt is Cursor's UserPromptSubmit equivalent. Drains the
357
357
  // queue and prints the extraction nudge as JSON additional_context.
@@ -422,7 +422,7 @@ export function setupCursor(
422
422
  }
423
423
 
424
424
  // ---------------------------------------------------------------------------
425
- // Setup detection — check whether setup was completed for the current host
425
+ // Setup detection - check whether setup was completed for the current host
426
426
  // ---------------------------------------------------------------------------
427
427
 
428
428
  export type HostKind = "claude" | "cursor";
@@ -449,7 +449,7 @@ function checkInstructionsFile(path: string, startMarker: string, endMarker: str
449
449
  * CLAUDE_PROJECT_DIR for Claude Code) and checks whether `thatch setup` was
450
450
  * run for that host. Checks local instructions (in the project dir) first,
451
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).
452
+ * determined (neither env var is set - e.g. manual `thatch mcp` invocation).
453
453
  */
454
454
  export function checkSetup(projectDir: string, homeDir?: string): SetupStatus | null {
455
455
  const home = homeDir ?? process.env.HOME ?? "/tmp";
package/src/sideband.ts CHANGED
@@ -66,7 +66,7 @@ export class SidebandServer {
66
66
  try {
67
67
  unlinkSync(this.#path);
68
68
  } catch {
69
- // No stale socket — expected on first run.
69
+ // No stale socket - expected on first run.
70
70
  }
71
71
 
72
72
  this.#server = createServer((socket) => {
@@ -103,7 +103,7 @@ export class SidebandServer {
103
103
  this.#handleRequest(line, socket);
104
104
  });
105
105
  socket.on("error", () => {
106
- // Client disconnected abruptly — nothing to do.
106
+ // Client disconnected abruptly - nothing to do.
107
107
  });
108
108
  }
109
109
 
@@ -155,7 +155,7 @@ export class SidebandServer {
155
155
 
156
156
  /**
157
157
  * Connect to the sideband server and request semantic matches for a prompt.
158
- * Returns null on any failure (server not running, stale socket, timeout) —
158
+ * Returns null on any failure (server not running, stale socket, timeout) -
159
159
  * callers must treat null as "skip the recall nudge" and fall back gracefully.
160
160
  */
161
161
  export function sidebandMatch(