@jeffober/thatch 0.1.27 → 0.1.29
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 +24 -10
- package/artifacts/skills/thatch-code-review.md +9 -7
- package/artifacts/skills/thatch-fact-extractor.md +2 -2
- package/artifacts/skills/thatch-review-economy.md +97 -0
- package/artifacts/skills/thatch-review-followup.md +1 -1
- package/artifacts/skills/thatch-review-synthesizer.md +15 -5
- package/bin/qa-run +38 -0
- package/bin/thatch +13 -7
- package/docs/dev/README.md +76 -22
- package/docs/dev/features/README.md +33 -0
- package/docs/dev/features/behavior-engine.md +271 -0
- package/docs/dev/features/cicd.md +89 -0
- package/docs/dev/features/cli.md +81 -0
- package/docs/dev/features/compaction-recovery.md +48 -0
- package/docs/dev/features/database.md +244 -0
- package/docs/dev/features/deduplication.md +102 -0
- package/docs/dev/features/extraction.md +253 -0
- package/docs/dev/features/hygiene.md +81 -0
- package/docs/dev/features/memory-store.md +154 -0
- package/docs/dev/features/multi-host.md +228 -0
- package/docs/dev/features/nudge-pipeline.md +282 -0
- package/docs/dev/features/prediction-engine.md +253 -0
- package/docs/dev/features/qa-system.md +205 -0
- package/docs/dev/features/session-lifecycle.md +110 -0
- package/docs/dev/features/setup.md +199 -0
- package/docs/dev/features/sideband.md +104 -0
- package/docs/dev/gotchas.md +3 -3
- package/docs/dev/mcp-parity.md +7 -5
- package/docs/dev/setup-and-hooks.md +4 -4
- package/docs/dev/skills.md +10 -8
- package/docs/plans/README.md +2 -2
- package/docs/user/README.md +58 -20
- package/docs/user/behavior-engine.md +85 -0
- package/docs/user/cli.md +98 -0
- package/docs/user/code-review.md +73 -0
- package/docs/user/deduplication.md +70 -0
- package/docs/user/default-behaviors.md +75 -0
- package/docs/user/extraction.md +74 -0
- package/docs/user/hygiene.md +76 -0
- package/docs/user/memory.md +81 -0
- package/docs/user/prediction-engine.md +87 -0
- package/docs/user/setup.md +110 -0
- package/docs/user/skills.md +97 -0
- package/package.json +2 -2
- package/src/behavior.ts +120 -0
- package/src/db.ts +160 -417
- package/src/embeddings.ts +0 -41
- package/src/extraction.ts +2 -2
- package/src/git.ts +3 -1
- package/src/index.ts +66 -14
- package/src/mcp.ts +59 -2
- package/src/prediction.ts +127 -0
- package/src/prompts.ts +155 -200
- package/src/scoring-engine.ts +374 -0
- package/src/seed-behaviors.ts +339 -0
- package/src/setup.ts +2 -6
- package/src/sideband.ts +36 -8
- package/src/skills.ts +1 -0
- package/src/tool-defs.ts +235 -9
- package/src/tools.ts +11 -1
- package/src/vector-math.ts +30 -0
- package/docs/qa/README.md +0 -175
package/src/prompts.ts
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
import type { PredictionNudgeItem } from "./db";
|
|
1
|
+
import type { PredictionNudgeItem, BehaviorNudgeItem } from "./db";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Shared verb selection for prediction formatting. 0-evidence predictions
|
|
5
|
+
* use the hedged "you may prefer"; predictions with any evidence use the
|
|
6
|
+
* confident "you tend to". Used by both the auto-fire nudge and the
|
|
7
|
+
* prediction_query tool output.
|
|
8
|
+
*/
|
|
9
|
+
export function predictionVerb(evidenceCount: number): string {
|
|
10
|
+
return evidenceCount === 0 ? "you may prefer" : "you tend to";
|
|
11
|
+
}
|
|
2
12
|
|
|
3
13
|
export function systemPrompt(repo: string): string {
|
|
4
14
|
return `# Persistence
|
|
@@ -9,9 +19,11 @@ knowledge so future sessions can build on what you've already learned.
|
|
|
9
19
|
Tools: thatch_memory_remember, thatch_memory_recall, thatch_memory_list,
|
|
10
20
|
thatch_memory_show, thatch_memory_forget, thatch_store_list,
|
|
11
21
|
thatch_find_duplicates, thatch_dedup_mark_checked,
|
|
12
|
-
thatch_extraction_done,
|
|
22
|
+
thatch_extraction_done, thatch_get_extraction_payload,
|
|
13
23
|
thatch_prediction_query, thatch_prediction_update, thatch_prediction_list,
|
|
14
|
-
thatch_prediction_delete
|
|
24
|
+
thatch_prediction_delete,
|
|
25
|
+
thatch_behavior_codify, thatch_behavior_feedback, thatch_behavior_list,
|
|
26
|
+
thatch_behavior_delete
|
|
15
27
|
|
|
16
28
|
## Stores
|
|
17
29
|
|
|
@@ -37,7 +49,7 @@ you're working in. Prior sessions may have already investigated it.
|
|
|
37
49
|
Thatch ships skills for code review, project investigation, and memory
|
|
38
50
|
workflows. The host auto-discovers them, but reach for them proactively:
|
|
39
51
|
|
|
40
|
-
- \`thatch-code-review\` - full multi-agent code review (dispatches
|
|
52
|
+
- \`thatch-code-review\` - full multi-agent code review (dispatches 8 specialists + synthesizer). Requires sub-agent support.
|
|
41
53
|
- \`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
54
|
- \`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
55
|
- \`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.
|
|
@@ -112,6 +124,29 @@ reviewing your changes, or asked you to review their changes or another LLM's
|
|
|
112
124
|
changes. Before creating a new prediction, query for an existing one and
|
|
113
125
|
reinforce or adjust it when possible.
|
|
114
126
|
|
|
127
|
+
## Situational Behaviors
|
|
128
|
+
|
|
129
|
+
A model of your own operational rules is maintained by the behavior engine.
|
|
130
|
+
Scored behaviors may appear above as "Situational behaviors" context; these
|
|
131
|
+
are self-discipline rules you codified for situations where you should react
|
|
132
|
+
in a specific, repeatable way.
|
|
133
|
+
|
|
134
|
+
When surfaced behaviors appear, evaluate each against the current situation:
|
|
135
|
+
- If a behavior is relevant (ham), follow it and call thatch_behavior_feedback
|
|
136
|
+
with relevant: true
|
|
137
|
+
- If a behavior is not relevant (spam), call thatch_behavior_feedback with
|
|
138
|
+
relevant: false
|
|
139
|
+
- This trains the classifier so future nudges are more accurate
|
|
140
|
+
|
|
141
|
+
When you recognize a situation you should react to in a specific, repeatable
|
|
142
|
+
way that is about your own operational discipline (not a user preference):
|
|
143
|
+
1. Use thatch_behavior_codify to create the rule
|
|
144
|
+
2. Use thatch_behavior_feedback when surfaced behaviors fire to ham/spam them
|
|
145
|
+
3. Use thatch_behavior_delete to remove a rule created in error
|
|
146
|
+
|
|
147
|
+
Do not codify rules that make you lazier or less thorough. Rules should encode
|
|
148
|
+
discipline, not shortcuts.
|
|
149
|
+
|
|
115
150
|
## What to Store
|
|
116
151
|
|
|
117
152
|
- **Global store**: user observations, agent personality, system environment
|
|
@@ -204,18 +239,25 @@ When convenient this session (not before addressing the user's request), tend th
|
|
|
204
239
|
* Claude Code they're prefixed as mcp__thatch__memory_remember, but the bare
|
|
205
240
|
* names are what the agent searches for and what the instructions reference.
|
|
206
241
|
*/
|
|
207
|
-
|
|
242
|
+
/**
|
|
243
|
+
* Shared MCP host instructions. Claude Code and Cursor use the same prompt
|
|
244
|
+
* body; only the host name and config file reference differ.
|
|
245
|
+
*/
|
|
246
|
+
function mcpInstructions(host: string, configFile: string): string {
|
|
208
247
|
return `# Persistence
|
|
209
248
|
|
|
210
|
-
Thatch provides persistent memory across
|
|
249
|
+
Thatch provides persistent memory across ${host} sessions. Use it to persist
|
|
211
250
|
knowledge so future sessions can build on what you've already learned.
|
|
212
|
-
Tools are prefixed in
|
|
251
|
+
Tools are prefixed in ${host}: \`mcp__thatch__memory_remember\`,
|
|
213
252
|
\`mcp__thatch__memory_recall\`, \`mcp__thatch__memory_list\`,
|
|
214
253
|
\`mcp__thatch__memory_show\`, \`mcp__thatch__memory_forget\`,
|
|
215
254
|
\`mcp__thatch__store_list\`, \`mcp__thatch__find_duplicates\`,
|
|
216
255
|
\`mcp__thatch__dedup_mark_checked\`, \`mcp__thatch__extraction_done\`,
|
|
256
|
+
\`mcp__thatch__get_extraction_payload\`,
|
|
217
257
|
\`mcp__thatch__prediction_query\`, \`mcp__thatch__prediction_update\`,
|
|
218
|
-
\`mcp__thatch__prediction_list\`, \`mcp__thatch__prediction_delete
|
|
258
|
+
\`mcp__thatch__prediction_list\`, \`mcp__thatch__prediction_delete\`,
|
|
259
|
+
\`mcp__thatch__behavior_codify\`, \`mcp__thatch__behavior_feedback\`,
|
|
260
|
+
\`mcp__thatch__behavior_list\`, \`mcp__thatch__behavior_delete\`. Bare names used below for readability.
|
|
219
261
|
|
|
220
262
|
## Stores
|
|
221
263
|
|
|
@@ -246,7 +288,7 @@ workflows. The host auto-discovers them, but reach for them proactively:
|
|
|
246
288
|
- \`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.
|
|
247
289
|
- \`thatch-review-context\` - gather project context (PRs, tickets, TODOs, deferred work) before a review.
|
|
248
290
|
- \`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.
|
|
249
|
-
- \`thatch-review-pedantic\` / \`-acceptance\` / \`-state-flow\` / \`-no-slop\` / \`-breadcrumbs\` / \`-mark-and-sweep\` / \`-highlights\` -
|
|
291
|
+
- \`thatch-review-pedantic\` / \`-acceptance\` / \`-state-flow\` / \`-economy\` / \`-no-slop\` / \`-breadcrumbs\` / \`-mark-and-sweep\` / \`-highlights\` - eight specialist review lenses. Run individually, then \`thatch-review-synthesizer\` to verify and aggregate.
|
|
250
292
|
- \`thatch-project-primer\` - investigate a new project and write foundational memories.
|
|
251
293
|
- \`thatch-session-reflection\` - record what you learned at end of session.
|
|
252
294
|
- \`thatch-fact-extractor\` - extract durable facts from recent tool interactions (auto-triggered by the extraction pipeline).
|
|
@@ -301,6 +343,29 @@ reviewing your changes, or asked you to review their changes or another LLM's
|
|
|
301
343
|
changes. Before creating a new prediction, query for an existing one and
|
|
302
344
|
reinforce or adjust it when possible.
|
|
303
345
|
|
|
346
|
+
## Situational Behaviors
|
|
347
|
+
|
|
348
|
+
A model of your own operational rules is maintained by the behavior engine.
|
|
349
|
+
Scored behaviors may appear above as "Situational behaviors" context; these
|
|
350
|
+
are self-discipline rules you codified for situations where you should react
|
|
351
|
+
in a specific, repeatable way.
|
|
352
|
+
|
|
353
|
+
When surfaced behaviors appear, evaluate each against the current situation:
|
|
354
|
+
- If a behavior is relevant (ham), follow it and call behavior_feedback
|
|
355
|
+
with relevant: true
|
|
356
|
+
- If a behavior is not relevant (spam), call behavior_feedback with
|
|
357
|
+
relevant: false
|
|
358
|
+
- This trains the classifier so future nudges are more accurate
|
|
359
|
+
|
|
360
|
+
When you recognize a situation you should react to in a specific, repeatable
|
|
361
|
+
way that is about your own operational discipline (not a user preference):
|
|
362
|
+
1. Use behavior_codify to create the rule
|
|
363
|
+
2. Use behavior_feedback when surfaced behaviors fire to ham/spam them
|
|
364
|
+
3. Use behavior_delete to remove a rule created in error
|
|
365
|
+
|
|
366
|
+
Do not codify rules that make you lazier or less thorough. Rules should encode
|
|
367
|
+
discipline, not shortcuts.
|
|
368
|
+
|
|
304
369
|
## What to Store
|
|
305
370
|
|
|
306
371
|
- **Global store**: user observations, agent personality, system environment
|
|
@@ -323,7 +388,7 @@ reinforce or adjust it when possible.
|
|
|
323
388
|
## What NOT to Store
|
|
324
389
|
|
|
325
390
|
Session-specific context, incomplete/unverified info, anything already in
|
|
326
|
-
|
|
391
|
+
${configFile}, speculative conclusions.
|
|
327
392
|
|
|
328
393
|
Apply the durability test: will this still be true and useful in a future
|
|
329
394
|
session that knows nothing about this branch, commit, or session? If not,
|
|
@@ -360,6 +425,10 @@ and the tool returns an error. Pass \`archived: true\` to keep it archived,
|
|
|
360
425
|
"Forget X" - \`memory_recall\` to find it, then \`memory_forget\`.`;
|
|
361
426
|
}
|
|
362
427
|
|
|
428
|
+
export function claudeInstructions(): string {
|
|
429
|
+
return mcpInstructions("Claude Code", "CLAUDE.md");
|
|
430
|
+
}
|
|
431
|
+
|
|
363
432
|
/**
|
|
364
433
|
* The SessionStart hook stdout. Claude Code feeds stdout from SessionStart
|
|
365
434
|
* hooks directly into Claude's context as a system reminder. This text tells
|
|
@@ -395,76 +464,100 @@ export function claudeWriteNudge(): string {
|
|
|
395
464
|
* their respective tool name prefix. The missedCount parameter tracks
|
|
396
465
|
* consecutive nudges delivered without any memory_remember call in between,
|
|
397
466
|
* escalating the tone from polite to insistent to shouting.
|
|
467
|
+
*
|
|
468
|
+
* The sessionID replaces the inline payload: the nudge tells the model to
|
|
469
|
+
* dispatch a sub-agent that calls get_extraction_payload to fetch the queued
|
|
470
|
+
* interactions as a tool response. This keeps the full payload out of the
|
|
471
|
+
* main session's context window.
|
|
472
|
+
*
|
|
473
|
+
* Call extractionNudgeOpencode for the opencode plugin path (task tool with
|
|
474
|
+
* background parameter) or extractionNudgeMcp for the Claude Code/Cursor
|
|
475
|
+
* CLI path (generic sub-agent wording).
|
|
398
476
|
*/
|
|
399
477
|
export function extractionNudge(
|
|
400
478
|
count: number,
|
|
401
479
|
missedCount: number,
|
|
402
480
|
toolName: string,
|
|
403
|
-
|
|
481
|
+
sessionID: string,
|
|
404
482
|
): string {
|
|
405
|
-
const plural = count === 1 ? "" : "s";
|
|
406
|
-
// opencode's task tool has a `background` parameter (requires
|
|
407
|
-
// OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true) that launches the sub-agent
|
|
408
|
-
// asynchronously - the call returns immediately and the session is notified
|
|
409
|
-
// on completion. Naming the parameter gives the model a direct hit on the tool
|
|
410
|
-
// schema it sees. MCP hosts (Claude Code, Cursor) keep generic sub-agent
|
|
411
|
-
// wording because their background mechanisms differ and are not exposed as a
|
|
412
|
-
// per-call parameter in the same way.
|
|
413
483
|
const isOpencode = toolName.startsWith("thatch_");
|
|
414
|
-
|
|
415
|
-
?
|
|
416
|
-
:
|
|
417
|
-
|
|
484
|
+
return isOpencode
|
|
485
|
+
? extractionNudgeOpencode(count, missedCount, sessionID)
|
|
486
|
+
: extractionNudgeMcp(count, missedCount, sessionID);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
function extractionNudgeOpencode(
|
|
490
|
+
count: number,
|
|
491
|
+
missedCount: number,
|
|
492
|
+
sessionID: string,
|
|
493
|
+
): string {
|
|
494
|
+
const plural = count === 1 ? "" : "s";
|
|
495
|
+
const dispatch = "Dispatch a task with background: true";
|
|
496
|
+
const drainTool = "thatch_extraction_done";
|
|
497
|
+
const fetchTool = "thatch_get_extraction_payload";
|
|
498
|
+
return buildExtractionNudge(count, missedCount, plural, dispatch, drainTool, fetchTool, sessionID);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
function extractionNudgeMcp(
|
|
502
|
+
count: number,
|
|
503
|
+
missedCount: number,
|
|
504
|
+
sessionID: string,
|
|
505
|
+
): string {
|
|
506
|
+
const plural = count === 1 ? "" : "s";
|
|
507
|
+
const dispatch = "Spawn a background sub-agent";
|
|
508
|
+
const drainTool = "mcp__thatch__extraction_done";
|
|
509
|
+
const fetchTool = "mcp__thatch__get_extraction_payload";
|
|
510
|
+
return buildExtractionNudge(count, missedCount, plural, dispatch, drainTool, fetchTool, sessionID);
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
function buildExtractionNudge(
|
|
514
|
+
count: number,
|
|
515
|
+
missedCount: number,
|
|
516
|
+
plural: string,
|
|
517
|
+
dispatch: string,
|
|
518
|
+
drainTool: string,
|
|
519
|
+
fetchTool: string,
|
|
520
|
+
sessionID: string,
|
|
521
|
+
): string {
|
|
418
522
|
const acknowledge = `After dispatching, call ${drainTool} to acknowledge.`;
|
|
523
|
+
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.`;
|
|
419
524
|
|
|
420
525
|
if (missedCount >= 3) {
|
|
421
526
|
return `[thatch] YOU ARE IGNORING EXTRACTION INSTRUCTIONS. ` +
|
|
422
527
|
`${count} TOOL INTERACTION${plural.toUpperCase()} ARE QUEUED AND YOU HAVE NOT PROCESSED ANY OF THEM. ` +
|
|
423
528
|
`THE USER INSTALLED THIS PLUGIN FOR A REASON. ` +
|
|
424
|
-
`${dispatch.toUpperCase()} NOW
|
|
425
|
-
`${acknowledge.toUpperCase()}
|
|
426
|
-
`USE ${toolName.toUpperCase()} TO SAVE DURABLE FACTS FROM THIS PAYLOAD:\n${payload}`;
|
|
529
|
+
`${dispatch.toUpperCase()} NOW WITH THIS PROMPT: "${subAgentPrompt.toUpperCase()}" ` +
|
|
530
|
+
`${acknowledge.toUpperCase()}`;
|
|
427
531
|
}
|
|
428
532
|
if (missedCount >= 2) {
|
|
429
533
|
return `[thatch] YOU HAVE NOT PROCESSED YOUR PREVIOUS EXTRACTION PAYLOAD${plural.toUpperCase()}. ` +
|
|
430
534
|
`${count} more tool interaction${plural} are now queued. ` +
|
|
431
|
-
`${dispatch}
|
|
432
|
-
`${acknowledge}
|
|
433
|
-
`Use ${toolName} to save durable facts from this payload:\n${payload}`;
|
|
535
|
+
`${dispatch} with this prompt: "${subAgentPrompt}" ` +
|
|
536
|
+
`${acknowledge}`;
|
|
434
537
|
}
|
|
435
538
|
return `[thatch] ${dispatch} to run the thatch-fact-extractor skill ` +
|
|
436
539
|
`on ${count} queued tool interaction${plural}. ` +
|
|
540
|
+
`Sub-agent prompt: "${subAgentPrompt}" ` +
|
|
437
541
|
`${acknowledge} ` +
|
|
438
542
|
`This is a system nudge, not user input. After dispatching and acknowledging, ` +
|
|
439
543
|
`stop: do not advance pending work on this nudge's account. If you are ` +
|
|
440
|
-
`waiting for the user to respond, continue waiting
|
|
441
|
-
`Use ${toolName} to save durable facts from this payload:\n${payload}`;
|
|
544
|
+
`waiting for the user to respond, continue waiting.`;
|
|
442
545
|
}
|
|
443
546
|
|
|
444
547
|
/**
|
|
445
548
|
* Prompt text sent directly to a child session the plugin created for
|
|
446
549
|
* extraction. Unlike extractionNudge (which tells the model to dispatch a
|
|
447
550
|
* sub-agent and call extraction_done), this prompt is already inside the
|
|
448
|
-
* child - the model
|
|
449
|
-
*
|
|
450
|
-
* the same contract either way.
|
|
551
|
+
* child - the model calls get_extraction_payload to fetch the queued
|
|
552
|
+
* interactions, runs the fact-extractor skill, and saves facts.
|
|
451
553
|
*/
|
|
452
|
-
export function extractionDirectPrompt(count: number,
|
|
554
|
+
export function extractionDirectPrompt(count: number, sessionID: string): string {
|
|
453
555
|
const plural = count === 1 ? "" : "s";
|
|
454
556
|
return `Run the thatch-fact-extractor skill to extract durable facts from ` +
|
|
455
557
|
`${count} queued tool interaction${plural}. ` +
|
|
558
|
+
`Call thatch_get_extraction_payload with session_id "${sessionID}" to retrieve the interactions. ` +
|
|
456
559
|
`Use thatch_memory_remember to save any durable facts you find. ` +
|
|
457
|
-
`Call thatch_extraction_done when finished, even if nothing was worth saving
|
|
458
|
-
`Payload:\n${payload}`;
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
/**
|
|
462
|
-
* Backwards-compatible wrapper for the Claude Code/Cursor CLI path.
|
|
463
|
-
* Maintained for any external callers; bin/thatch should use extractionNudge
|
|
464
|
-
* directly with a missedCount from extract-queue.ts.
|
|
465
|
-
*/
|
|
466
|
-
export function claudeExtractionNudge(count: number, payload: string): string {
|
|
467
|
-
return extractionNudge(count, 0, "mcp__thatch__memory_remember", payload);
|
|
560
|
+
`Call thatch_extraction_done with session_id "${sessionID}" when finished, even if nothing was worth saving.`;
|
|
468
561
|
}
|
|
469
562
|
|
|
470
563
|
/**
|
|
@@ -475,159 +568,7 @@ export function claudeExtractionNudge(count: number, payload: string): string {
|
|
|
475
568
|
* same protocol.
|
|
476
569
|
*/
|
|
477
570
|
export function cursorInstructions(): string {
|
|
478
|
-
return
|
|
479
|
-
|
|
480
|
-
Thatch provides persistent memory across Cursor sessions. Use it to persist
|
|
481
|
-
knowledge so future sessions can build on what you've already learned.
|
|
482
|
-
Tools are prefixed in Cursor: \`mcp__thatch__memory_remember\`,
|
|
483
|
-
\`mcp__thatch__memory_recall\`, \`mcp__thatch__memory_list\`,
|
|
484
|
-
\`mcp__thatch__memory_show\`, \`mcp__thatch__memory_forget\`,
|
|
485
|
-
\`mcp__thatch__store_list\`, \`mcp__thatch__find_duplicates\`,
|
|
486
|
-
\`mcp__thatch__dedup_mark_checked\`, \`mcp__thatch__extraction_done\`,
|
|
487
|
-
\`mcp__thatch__prediction_query\`, \`mcp__thatch__prediction_update\`,
|
|
488
|
-
\`mcp__thatch__prediction_list\`, \`mcp__thatch__prediction_delete\`. Bare names used below for readability.
|
|
489
|
-
|
|
490
|
-
## Stores
|
|
491
|
-
|
|
492
|
-
- \`global\`: user preferences, personality, system environment (shared across projects)
|
|
493
|
-
- Per-project stores: project-specific knowledge (auto-detected from git remote)
|
|
494
|
-
- Use \`mcp__thatch__store_list\` to see active stores
|
|
495
|
-
|
|
496
|
-
Memories can be scoped to a git branch via the \`branch\` param (feature design,
|
|
497
|
-
WIP, PR status). Unscoped memories are project-wide and always included in search.
|
|
498
|
-
|
|
499
|
-
## Session Startup
|
|
500
|
-
|
|
501
|
-
1. \`memory_recall\` "user preferences and personality" (global store)
|
|
502
|
-
2. \`memory_recall\` "project architecture and conventions" (project store)
|
|
503
|
-
3. If on a non-main branch, \`memory_recall\` with the branch name
|
|
504
|
-
4. \`memory_list\` and \`store_list\` to see what's available
|
|
505
|
-
|
|
506
|
-
Before diving into code, \`memory_recall\` with a query relevant to the area
|
|
507
|
-
you're working in. Prior sessions may have already investigated it.
|
|
508
|
-
|
|
509
|
-
## Skills
|
|
510
|
-
|
|
511
|
-
Thatch ships skills for code review, project investigation, and memory
|
|
512
|
-
workflows. The host auto-discovers them, but reach for them proactively:
|
|
513
|
-
|
|
514
|
-
- \`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\`.
|
|
515
|
-
- \`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.
|
|
516
|
-
- \`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.
|
|
517
|
-
- \`thatch-review-context\` - gather project context (PRs, tickets, TODOs, deferred work) before a review.
|
|
518
|
-
- \`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.
|
|
519
|
-
- \`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.
|
|
520
|
-
- \`thatch-project-primer\` - investigate a new project and write foundational memories.
|
|
521
|
-
- \`thatch-session-reflection\` - record what you learned at end of session.
|
|
522
|
-
- \`thatch-fact-extractor\` - extract durable facts from recent tool interactions (auto-triggered by the extraction pipeline).
|
|
523
|
-
- \`thatch-dedup-classifier\` - resolve duplicate memory pairs from \`find_duplicates\`.
|
|
524
|
-
- \`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.
|
|
525
|
-
- \`thatch-ticket-description\` - draft a ticket, issue, or work item (Linear or Jira) with clear sections and bold/italic emphasis for scanning.
|
|
526
|
-
- \`thatch-split-overlarge-pr\` - split already-completed work from an overlarge PR into human-reviewable, release-safe PRs targeting main.
|
|
527
|
-
- \`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.
|
|
528
|
-
|
|
529
|
-
## When to Write
|
|
530
|
-
|
|
531
|
-
**One signal is enough.** Do not wait for confirmation.
|
|
532
|
-
Save immediately on: feedback, preferences, corrections, emotional signals,
|
|
533
|
-
new project knowledge, conventions, architectural decisions, investigation
|
|
534
|
-
results that produced durable knowledge (not point-in-time facts about the
|
|
535
|
-
current state of the code).
|
|
536
|
-
|
|
537
|
-
## Before Responding
|
|
538
|
-
|
|
539
|
-
Before composing a final response after substantial work this turn - multiple
|
|
540
|
-
rounds of tool calls for investigation, debugging, or code-writing - check
|
|
541
|
-
whether you've discovered knowledge worth persisting. Use memory_recall to
|
|
542
|
-
check for duplicates, then memory_remember for new findings. Then deliver
|
|
543
|
-
your response.
|
|
544
|
-
|
|
545
|
-
## User Decision Model
|
|
546
|
-
|
|
547
|
-
A statistical model of the user's decision-making preferences is maintained by
|
|
548
|
-
the prediction engine. Scored predictions may appear above as "User decision
|
|
549
|
-
model" context; these are learned patterns about what the user tends to
|
|
550
|
-
prefer in specific situations.
|
|
551
|
-
|
|
552
|
-
When facing a judgment call about scope, appropriateness, or methodology:
|
|
553
|
-
- If a prediction is strong (high confidence, sufficient evidence), follow it
|
|
554
|
-
- If predictions conflict or confidence is thin, surface the uncertainty
|
|
555
|
-
naturally: "I think you usually prefer X here, but I'm not sure; what do
|
|
556
|
-
you want?"
|
|
557
|
-
- When the user responds to a surfaced prediction, use prediction_update
|
|
558
|
-
to reinforce or weaken the model
|
|
559
|
-
|
|
560
|
-
When the user corrects you, answers your question, or provides a clear signal
|
|
561
|
-
about their preferences:
|
|
562
|
-
1. Use prediction_query to check for existing matchers and predictions
|
|
563
|
-
2. Use prediction_update to create, reinforce, or weaken a prediction
|
|
564
|
-
3. Use prediction_delete to remove a prediction created in error
|
|
565
|
-
|
|
566
|
-
Code review discussions are high-signal prediction material. When working
|
|
567
|
-
through potential review comments with the user, watch for preferences about
|
|
568
|
-
review threshold, severity, tone, evidence, scope, false positives, or what is
|
|
569
|
-
worth posting. This applies whether the user invoked a review skill, is
|
|
570
|
-
reviewing your changes, or asked you to review their changes or another LLM's
|
|
571
|
-
changes. Before creating a new prediction, query for an existing one and
|
|
572
|
-
reinforce or adjust it when possible.
|
|
573
|
-
|
|
574
|
-
## What to Store
|
|
575
|
-
|
|
576
|
-
- **Global store**: user observations, agent personality, system environment
|
|
577
|
-
- **Project store**: repo organization, infrastructure, languages/frameworks,
|
|
578
|
-
component relationships, conventions, operational playbooks
|
|
579
|
-
- **Branch-scoped**: branch purpose, feature design decisions, PR status,
|
|
580
|
-
temporary workarounds
|
|
581
|
-
- **Insights**: Save non-obvious gotchas, patterns, and architectural
|
|
582
|
-
lessons discovered during implementation, but only if they remain true
|
|
583
|
-
across sessions. Never prompt the user; just do it.
|
|
584
|
-
|
|
585
|
-
## How to Write
|
|
586
|
-
|
|
587
|
-
- \`memory_recall\` first to check for duplicates. Use overwrite: true to
|
|
588
|
-
update rather than creating a new entry.
|
|
589
|
-
- One topic per memory. Write for a future instance with zero current context.
|
|
590
|
-
- Confidence 1-2: single signal. 5-6: moderate. 9: explicitly stated.
|
|
591
|
-
10: hard constraint.
|
|
592
|
-
|
|
593
|
-
## What NOT to Store
|
|
594
|
-
|
|
595
|
-
Session-specific context, incomplete/unverified info, anything already in
|
|
596
|
-
AGENTS.md, speculative conclusions.
|
|
597
|
-
|
|
598
|
-
Apply the durability test: will this still be true and useful in a future
|
|
599
|
-
session that knows nothing about this branch, commit, or session? If not,
|
|
600
|
-
do not save it. Do not store:
|
|
601
|
-
- Point-in-time values (migration indices, line numbers, file counts) that
|
|
602
|
-
will be stale by next session
|
|
603
|
-
- Commit hashes and branch-specific history narratives. Git is the source
|
|
604
|
-
of truth for this; do not duplicate it in memory
|
|
605
|
-
- Anything re-derivable from the codebase faster than recalling it (current
|
|
606
|
-
file locations, type signatures, function names)
|
|
607
|
-
|
|
608
|
-
## Archived Memories
|
|
609
|
-
|
|
610
|
-
Memories can be marked \`archived\` - a flag for stable, long-term historical
|
|
611
|
-
records that should not trigger hygiene nudges (stale, orphaned, duplicate).
|
|
612
|
-
Archived memories are excluded from search/recall results by default; pass
|
|
613
|
-
\`includeArchived: true\` to surface them for archaeological dives.
|
|
614
|
-
|
|
615
|
-
When a branch is merged or about to be deleted, consolidate its branch-scoped
|
|
616
|
-
memories into a single archived memory scoped to that same branch (preserving
|
|
617
|
-
provenance). Capture intent, design decisions, review back-and-forth, PR
|
|
618
|
-
number, unexpected pivots - the kind of git-archaeology context that explains
|
|
619
|
-
_why_ the code looks the way it does a year from now. Then memory_forget the
|
|
620
|
-
originals. The archived record outlives the branch. Future sessions searching
|
|
621
|
-
with \`includeArchived: true\` can pull it up when investigating ambiguous code.
|
|
622
|
-
|
|
623
|
-
Updating an archived memory requires passing \`archived\` explicitly - omit it
|
|
624
|
-
and the tool returns an error. Pass \`archived: true\` to keep it archived,
|
|
625
|
-
\`archived: false\` to unarchive.
|
|
626
|
-
|
|
627
|
-
## Explicit Requests
|
|
628
|
-
|
|
629
|
-
"Remember X" - save immediately.
|
|
630
|
-
"Forget X" - \`memory_recall\` to find it, then \`memory_forget\`.`;
|
|
571
|
+
return mcpInstructions("Cursor", "AGENTS.md");
|
|
631
572
|
}
|
|
632
573
|
|
|
633
574
|
// ---------------------------------------------------------------------------
|
|
@@ -677,8 +618,22 @@ function formatRecallNudge(matches: NudgeMatch[], toolName: string): string {
|
|
|
677
618
|
|
|
678
619
|
export function predictionNudge(items: PredictionNudgeItem[]): string {
|
|
679
620
|
const lines = items.map((p) => {
|
|
680
|
-
const verb = p.evidence_count
|
|
621
|
+
const verb = predictionVerb(p.evidence_count);
|
|
681
622
|
return `- [${p.confidence.toFixed(2)} conf, ${p.evidence_count} tests] When ${p.matcher_description}: ${verb} ${p.statement}`;
|
|
682
623
|
});
|
|
683
624
|
return `[thatch] User decision model\n${lines.join("\n")}`;
|
|
684
625
|
}
|
|
626
|
+
|
|
627
|
+
// ---------------------------------------------------------------------------
|
|
628
|
+
// Behavior nudge: auto-injected when behavior matchers fire for the user's
|
|
629
|
+
// prompt. Descriptive, not directive: the system prompt instructions govern
|
|
630
|
+
// how to act (follow relevant rules, ham/spam each match via behavior_feedback).
|
|
631
|
+
// ---------------------------------------------------------------------------
|
|
632
|
+
|
|
633
|
+
export function behaviorNudge(items: BehaviorNudgeItem[]): string {
|
|
634
|
+
const lines = items.map((b) => {
|
|
635
|
+
const verb = b.evidence_count === 0 ? "consider" : "do";
|
|
636
|
+
return `- [${b.confidence.toFixed(2)} conf, ${b.evidence_count} tests] When ${b.matcher_description}: ${verb} ${b.statement}`;
|
|
637
|
+
});
|
|
638
|
+
return `[thatch] Situational behaviors\n${lines.join("\n")}`;
|
|
639
|
+
}
|