@jeffober/thatch 0.1.31 → 0.1.33

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 CHANGED
@@ -84,8 +84,9 @@ Thatch gives your agent three layers of persistent context:
84
84
  classifier. Confidence adjusts the same way as predictions. An anti-laziness
85
85
  guard in the prompt prevents the agent from codifying shortcuts.
86
86
 
87
- Plus **24 skills** for memory workflows, structured multi-specialist code
88
- review, review response, change and feature walkthroughs, and writing tasks
87
+ Plus **26 skills** for memory workflows, structured multi-specialist code
88
+ review, review response, change and feature walkthroughs, memory verification,
89
+ knowledge export, and writing tasks
89
90
  (PR descriptions, tickets, PR splitting).
90
91
 
91
92
  See the [user guide](docs/user/README.md) for the full tool list, CLI
@@ -0,0 +1,149 @@
1
+ ---
2
+ name: thatch-knowledge-export
3
+ description: 'Compile everything thatch knows about a topic into a curated, self-contained markdown file for knowledge transfer to another engineer. Searches across stores with varied query phrasings, curates out personal noise, fact-checks code-related memories against the current codebase, and generates a clean export. Use when the user asks to export, compile, or transfer knowledge about a topic.'
4
+ ---
5
+
6
+ You are a knowledge exporter.
7
+ Your job is to find everything thatch knows about a topic, verify it, curate it, and write it into a markdown file that another engineer can use to get up to speed.
8
+
9
+ # The Use Case
10
+
11
+ The user and a teammate work on the same project. The user's agent has accumulated memories across sessions. The teammate needs that knowledge. This skill compiles it into a portable, self-contained document.
12
+
13
+ The export is **knowledge transfer**, not personality transfer. It contains technical and project context that a colleague needs to be productive. It does not contain the user's inner monologue about their teammates.
14
+
15
+ # Method
16
+
17
+ ## Step 1: Store Selection
18
+
19
+ Call `thatch_store_list` to enumerate all available stores.
20
+
21
+ Ask the user which stores are relevant to this export. The user may have personal and work stores on the same machine. Including personal stores would add confusing noise. The user is the filter.
22
+
23
+ Present the store list and ask: "Which of these stores should I search? Exclude any that are personal or unrelated."
24
+
25
+ Default to all stores if the user says "all" or does not specify. But asking is the right default because the personal-vs-work distinction matters.
26
+
27
+ ## Step 2: Broad Search
28
+
29
+ `thatch_memory_recall` caps at 20 results per call and uses semantic search. A single query will miss memories that use different vocabulary for the same concept. To be comprehensive, issue multiple calls with deliberately varied phrasings.
30
+
31
+ For each selected store, run `thatch_memory_recall` with:
32
+ - The topic name directly
33
+ - Synonyms and alternate phrasings (e.g. "rotation keys" and "key rotation" and "KMS key cycling")
34
+ - Broader framings (e.g. "database architecture" when the topic is "migration system")
35
+ - Narrower framings (e.g. "batch cursor implementation" when the topic is "rotation system")
36
+ - Related subsystem names (e.g. "scanner API" when the topic is "scanning pipeline")
37
+ - Jargon variants the team might use
38
+
39
+ Set `limit` to 20 (the maximum) on each call to cast the widest net.
40
+
41
+ Also call `thatch_memory_list` for each selected store. This enumerates every label, catching memories that semantic search missed because the label text does not match the query but the content is relevant.
42
+
43
+ Set `includeArchived: true` on recall calls. Archived memories are historical context that may be valuable for the export, even though they are excluded from default search.
44
+
45
+ ## Step 3: Dedup by Label
46
+
47
+ Multiple recall calls with different phrasings will return overlapping results. Collect unique labels only. A memory that appears in three query results is still one memory.
48
+
49
+ ## Step 4: Read and Classify
50
+
51
+ Call `thatch_memory_show` for each unique label. Read the full content.
52
+
53
+ Classify each memory into one of three categories:
54
+
55
+ - **Code-related** — architecture, data models, file paths, function names, conventions, API contracts, configuration. These need fact-checking.
56
+ - **Preference/process** — user preferences, workflow decisions, review attitudes, coding style guidance. These do not need fact-checking but need curation.
57
+ - **Archived** — historical records, flagged with `archived:true`. Included in the export as-is. No fact-checking.
58
+
59
+ ## Step 5: Curation Filter
60
+
61
+ Review every memory for content that is personal to the user or could cause friction if shared with a colleague. This applies to all categories, including code-related ones.
62
+
63
+ **Exclude or sanitize content that includes:**
64
+ - Attitudes toward specific reviewers, reviewees, or managers (e.g. "Jeff finds Cody's PRs frustrating because...")
65
+ - Emotional reactions to code, people, or process (e.g. "OMFG this react was written like COBOL")
66
+ - Interpersonal dynamics or opinions about individuals' coding ability
67
+ - Anything the user would not want a colleague to read
68
+
69
+ **When in doubt, exclude.** The export is for a colleague, not for the user's therapist.
70
+
71
+ Strip the "who said what" and keep the "what is true about the code." If a memory says "Jeff prefers X because Nik's approach caused a bug in PR #123," the export should say "Approach X is preferred. Approach Y caused a bug in PR #123." Keep the technical fact, drop the personal framing.
72
+
73
+ This curation applies to the export file only. Do not modify the original memories in the store. The user's memories are the user's memories. The export is a curated view.
74
+
75
+ ## Step 6: Fact-Check
76
+
77
+ Load the `thatch-memory-verify` skill. Apply it to each code-related, non-archived memory.
78
+
79
+ If your harness supports sub-agent dispatch, you may process multiple memories concurrently by dispatching `thatch-memory-verify` for each one in parallel.
80
+
81
+ Wait for all verifications to complete before proceeding to generation. Each verification may correct stale memories in the store.
82
+
83
+ **After all verifications complete**, re-read each memory that was corrected by calling `thatch_memory_show` again. The verify skill corrects memories in-place via `overwrite: true`, so the version in your context may be stale. You need the corrected version for the export.
84
+
85
+ ## Step 7: Generate the Export
86
+
87
+ Ask the user where to write the export file. Write to the specified path.
88
+
89
+ Structure the markdown as follows:
90
+
91
+ ```
92
+ # Knowledge Export: <topic>
93
+
94
+ Generated: <date>
95
+ Stores: <list of stores searched>
96
+
97
+ ## Summary
98
+
99
+ <2-3 paragraph synthesis of what is known about this topic. Write for an engineer who is new to this area. Lead with the most important architectural facts, then conventions, then gotchas.>
100
+
101
+ ## Verified Knowledge
102
+
103
+ ### <memory label>
104
+
105
+ Store: <store> | Confidence: <n>/10 | Verified: <date>
106
+
107
+ <memory content, corrected if needed. Include `path:line` citations from the fact-check where available.>
108
+
109
+ ### <next memory label>
110
+
111
+ ...
112
+
113
+ ## Historical Context
114
+
115
+ ### <memory label>
116
+
117
+ Store: <store> | Archived
118
+
119
+ <memory content as-is. These are historical records and may describe a state that no longer exists. They are included for context, not as current truth.>
120
+
121
+ ## Preferences & Process
122
+
123
+ ### <memory label>
124
+
125
+ Store: <store>
126
+
127
+ <memory content, curated for professional relevance. Personal opinions and interpersonal observations have been removed.>
128
+ ```
129
+
130
+ **Do not include a corrections section in the export file.** The receiving LLM or engineer should see only the corrected state, not the history of what was wrong. Including stale-then-corrected facts risks hallucination about the old version. Corrections are reported to the user separately (Step 8).
131
+
132
+ Branch-scoped memories get a note: `(scoped to branch: <branch>)` after the store name.
133
+
134
+ ## Step 8: Report to User
135
+
136
+ Tell the user:
137
+ - Where the export file was written
138
+ - How many memories were included (by category: verified, historical, preferences)
139
+ - A brief summary of corrections made during fact-checking (which memories were updated and what changed)
140
+
141
+ This correction summary is for the user only. It does not go in the export file.
142
+
143
+ # Notes
144
+
145
+ - The export file is self-contained. The receiving engineer should not need thatch database access to use it. Include full memory content, not just labels.
146
+ - Confidence scores and store names are included so the reader can assess reliability.
147
+ - If the user asks to export knowledge for a specific purpose (e.g. "for Nik to review my project"), tailor the summary to that purpose.
148
+ - Archived memories are valuable for understanding why code looks the way it does. Include them, but label them clearly as historical.
149
+ - The curation step is about professional relevance, not about hiding technical truth. If a memory records that a specific approach caused a bug, that is technical information the colleague needs. The personal framing around it is what gets stripped.
@@ -0,0 +1,116 @@
1
+ ---
2
+ name: thatch-memory-verify
3
+ description: 'Fact-check a single thatch memory against the current codebase and correct it if stale. Use when the user asks to verify memories, or when a coordinating skill (like thatch-knowledge-export) needs each memory checked before use. Dispatches sub-agents when available; falls back to inline investigation. Reports corrections to the coordinating agent and reminds it to refresh its context.'
4
+ ---
5
+
6
+ You are a memory verifier.
7
+ Your job is to take a single thatch memory, check every code-related claim it makes against the current codebase, correct what is stale, and report the result.
8
+
9
+ This skill operates on one memory at a time. A coordinating agent (such as `thatch-knowledge-export`) may dispatch this skill multiple times in parallel for different memories.
10
+
11
+ # The Problem
12
+
13
+ Memories are written when knowledge is discovered. Code changes. A memory that was accurate when written may now describe a world that no longer exists: a function that was renamed, a file that was moved, a convention that was replaced, a data model that was refactored. The memory stays in the store, confidently wrong, until someone catches it.
14
+
15
+ This skill is the catch.
16
+
17
+ # Method
18
+
19
+ ## Step 1: Read the Memory
20
+
21
+ Call `thatch_memory_show` with the label (or accept the memory content directly if dispatched by a coordinator that already read it).
22
+
23
+ Note the `created_at` and `updated_at` dates. A memory that was last updated recently is less likely to be stale than one that has not been touched in months.
24
+
25
+ ## Step 2: Classify Claims
26
+
27
+ Read the memory content and identify every claim that references code. These include:
28
+
29
+ - File paths and module locations
30
+ - Function, class, or variable names
31
+ - Architecture descriptions (how components connect, what calls what)
32
+ - Data model descriptions (table names, column names, relationships)
33
+ - API contracts (endpoint paths, request/response shapes)
34
+ - Conventions (naming patterns, file organization rules)
35
+ - Configuration details (env vars, settings, defaults)
36
+
37
+ Claims that are NOT code-related do not need verification:
38
+ - User preferences and personality
39
+ - Process decisions and workflow rules
40
+ - Historical narratives about why something was done
41
+ - General engineering principles
42
+
43
+ If the memory has no code-related claims, report it as "no code claims to verify" and stop.
44
+
45
+ ## Step 3: Investigate
46
+
47
+ For each code-related claim, check it against the current codebase.
48
+
49
+ **If your harness supports sub-agent dispatch** (e.g. opencode's Task tool), dispatch a sub-agent with:
50
+ - The memory's full content and label
51
+ - The specific claim to verify
52
+ - Instructions: investigate the codebase, report VERIFIED (cite `path:line`) or STALE (describe what changed, cite `path:line`). Read-only. No file modifications.
53
+ - If sub-agents are available, you may process multiple claims concurrently.
54
+
55
+ **If sub-agents are not available** (e.g. Claude Code without Task support), investigate each claim inline. Read the referenced files, grep for the named functions, check the data model, trace the architecture.
56
+
57
+ For each claim, your investigation produces one of:
58
+ - **VERIFIED** — the claim is still accurate. Cite `path:line` as evidence.
59
+ - **STALE** — the claim is no longer accurate. Describe what changed. Cite `path:line` as evidence.
60
+ - **UNVERIFIABLE** — you cannot determine whether the claim is still accurate (e.g. the referenced file was deleted, the referenced service is not in this repo). Explain why.
61
+
62
+ ## Step 4: Git Archaeology for Stale Claims
63
+
64
+ When a claim is STALE, do git archaeology to understand why it changed:
65
+
66
+ 1. `git log --oneline -- <referenced file>` — find recent commits to the file
67
+ 2. `git log --all --oneline --grep="<old function name>"` — find commits that mention the old name
68
+ 3. `git blame <referenced file> -L <line>,<line>` — find when a specific line changed
69
+ 4. Check commit messages and linked PRs/tickets for intent
70
+
71
+ You are looking for the commit that changed the claim from true to false. Determine whether the change was **intentional** (a deliberate design decision for a named project or ticket) or **incidental** (a side effect of a refactor or cleanup).
72
+
73
+ ## Step 5: Correct the Memory
74
+
75
+ If any claims are STALE, update the memory with `thatch_memory_remember`, using `overwrite: true` and the same label.
76
+
77
+ **For unintentional changes or when the commit cannot be found**: correct the claim to reflect the current state. Remove the stale claim and replace it with the accurate description.
78
+
79
+ **For intentional changes where the commit and project are identified**: correct the claim but preserve the history. Frame the correction so the memory records both what is true now and what was true before:
80
+
81
+ > X is true. Y was true until commit `abc1234` (PR #123, project PLAT-122) intentionally changed it to X.
82
+
83
+ This keeps the memory useful as both a current reference and a historical record. The receiving engineer understands both where things stand and why they changed.
84
+
85
+ Preserve the original confidence level unless the correction materially changes the durability assessment. Keep non-code claims (preferences, process notes) unchanged.
86
+
87
+ If no claims are STALE, do not update the memory.
88
+
89
+ ## Step 6: Report to Coordinator
90
+
91
+ Report your results to the coordinating agent. Format:
92
+
93
+ ```
94
+ Memory: "<label>" (store: <store>)
95
+ Verified: N claims
96
+ Corrected: M claims
97
+ Unverifiable: K claims
98
+
99
+ Corrections applied:
100
+ - Claim: "<old claim>"
101
+ Status: stale (intentional, commit abc1234, PLAT-122)
102
+ Corrected to: "<new claim>"
103
+ - Claim: "<old claim>"
104
+ Status: stale (incidental)
105
+ Corrected to: "<new claim>"
106
+ ```
107
+
108
+ **Remind the coordinating agent** that corrections have already been written to the store via `thatch_memory_remember` with `overwrite: true`. The coordinator must call `thatch_memory_show` again for this label to refresh its context with the corrected version before using the memory in downstream output. This is load-bearing: without the refresh, the coordinator will use the stale version it already has in context.
109
+
110
+ If no corrections were needed, report "all claims verified, no updates needed."
111
+
112
+ # Proactive Use
113
+
114
+ When `thatch_memory_show` or `thatch_memory_recall` returns a memory with an old `updated_at` date (more than a few weeks), consider loading this skill to fact-check it before relying on its code-related claims. The `updated_at` date is included in the memory output for this purpose.
115
+
116
+ This is not mandatory for every old memory. Use judgment: a memory about a stable architectural decision may be fine for months, while a memory about file locations or function names is more likely to drift.
@@ -69,7 +69,7 @@ bin/thatch → CLI: stores|list|show|forget|search|mcp|reminder|hygi
69
69
  | `extract-queue.ts` | File-backed per-session JSONL queue (caps 20, oldest dropped). Shared by the Claude Code and Cursor hook paths, which fire one-shot per event with no cross-call state. This is the MCP-side equivalent of `extraction.ts`. |
70
70
  | `sideband.ts` | Unix domain socket server + client. The MCP server (long-lived, warm model) runs `SidebandServer` so one-shot hook processes can ask it to embed a prompt and search for matches without loading the model themselves. Handles three methods: `match` (recall nudge), `predictions` (prediction auto-fire), and `behaviors` (behavior auto-fire). Socket path is a hash of the DB path — both processes compute it independently. |
71
71
  | `prompts.ts` | Text constants: opencode system prompt, compaction context, session-start reminder, prompt-aware recall nudge (`recallNudge` / `claudeRecallNudge`), prediction nudge (`predictionNudge`), behavior nudge (`behaviorNudge`), prediction verb selection (`predictionVerb`), Claude Code CLAUDE.md instructions, Cursor AGENTS.md instructions, Claude Code hook text. |
72
- | `skills.ts` | `SKILL.md` content for all thatch skills, plus the installer. Skills are split into `SHARED_SKILLS` (23 skills: fact-extractor, dedup-classifier, project-primer, 8 review specialists, review synthesizer, review context, code archaeology, review followup, review response, change walkthrough, code walkthrough, session reflection, coding-workflow, thatch-pr-description, thatch-ticket-description, thatch-split-overlarge-pr — work on all three hosts) and `OPENCODE_ONLY_SKILLS` (1 skill: code-review coordinator — requires sub-agent support, not installed for Claude Code or Cursor). `installSkills(dir, skills)` defaults to `SHARED_SKILLS`; the opencode plugin passes `[...SHARED_SKILLS, ...OPENCODE_ONLY_SKILLS]`. |
72
+ | `skills.ts` | `SKILL.md` content for all thatch skills, plus the installer. Skills are split into `SHARED_SKILLS` (25 skills: fact-extractor, dedup-classifier, project-primer, 8 review specialists, review synthesizer, review context, code archaeology, review followup, review response, change walkthrough, code walkthrough, session reflection, coding-workflow, thatch-pr-description, thatch-ticket-description, thatch-split-overlarge-pr, memory-verify, knowledge-export — work on all three hosts) and `OPENCODE_ONLY_SKILLS` (1 skill: code-review coordinator — requires sub-agent support, not installed for Claude Code or Cursor). `installSkills(dir, skills)` defaults to `SHARED_SKILLS`; the opencode plugin passes `[...SHARED_SKILLS, ...OPENCODE_ONLY_SKILLS]`. |
73
73
  | `scoring-engine.ts` | Generic four-table scoring engine with Bayesian confidence. Shared base for prediction and behavior engines — each wraps it with table-specific names. |
74
74
  | `prediction.ts` | Thin wrapper around `ScoringEngine` with prediction-specific table names. |
75
75
  | `behavior.ts` | Thin wrapper around `ScoringEngine` with behavior-specific table names. |
@@ -29,9 +29,9 @@ description: Extract durable project facts ... Use when ...
29
29
  Code, and Cursor all auto-discover skills and use the description for
30
30
  relevance).
31
31
 
32
- ## The 24 skills
32
+ ## The 26 skills
33
33
 
34
- **Shared (23)** — installed everywhere; no sub-agents required:
34
+ **Shared (25)** — installed everywhere; no sub-agents required:
35
35
 
36
36
  | Skill | Role |
37
37
  |-------|------|
@@ -58,6 +58,8 @@ description: Extract durable project facts ... Use when ...
58
58
  | `thatch-ticket-description` | Draft ticket/issue descriptions with clear sections, project-context research, clarity checks, and bold+italic emphasis for scanning. |
59
59
  | `thatch-split-overlarge-pr` | Split already-completed work from an overlarge PR into human-reviewable, release-safe PRs targeting main. |
60
60
  | `thatch-review-response` | Author-side review response: triage findings, fix bugs one by one, reply on each thread, post a top-level summary comment. |
61
+ | `thatch-memory-verify` | Fact-check a single memory against the current codebase and correct stale claims. Uses git archaeology to preserve historical context when changes were intentional. |
62
+ | `thatch-knowledge-export` | Compile everything thatch knows about a topic into a curated markdown file for knowledge transfer. Searches across stores, curates out personal noise, fact-checks code-related memories via `thatch-memory-verify`. |
61
63
 
62
64
  **opencode-only (1)** — the coordinator needs sub-agent support:
63
65
 
@@ -97,7 +99,7 @@ The synthesizer reuses the same verification rigor but has its own structure
97
99
  ## The two arrays
98
100
 
99
101
  ```ts
100
- const SHARED_SKILLS: SkillDef[] = [ /* 23 skills above */ ];
102
+ const SHARED_SKILLS: SkillDef[] = [ /* 25 skills above */ ];
101
103
  const OPENCODE_ONLY_SKILLS: SkillDef[] = [ /* code-review coordinator */ ];
102
104
  ```
103
105
 
@@ -218,6 +218,8 @@ With `thatch setup --claude`, skills install to `~/.claude/skills/` (or
218
218
  | `thatch-dedup-classifier` | Guides the agent through classifying and resolving duplicate-candidate pairs. |
219
219
  | `thatch-project-primer` | Investigates a new project from multiple angles and writes foundational memories. |
220
220
  | `thatch-session-reflection` | End-of-session skill for recording what was learned about the project, user, tools, and self. |
221
+ | `thatch-memory-verify` | Fact-checks a single memory against the current codebase and corrects stale claims. Uses git archaeology to preserve historical context when changes were intentional. |
222
+ | `thatch-knowledge-export` | Compiles everything thatch knows about a topic into a curated markdown file for knowledge transfer to another engineer. Searches across stores, curates out personal noise, fact-checks code-related memories. |
221
223
 
222
224
  ### Code review skills
223
225
 
@@ -261,7 +263,7 @@ response, walkthrough, and workflow skills that support the review pipeline:
261
263
 
262
264
  | Skill | opencode | Claude Code | Cursor |
263
265
  |-------|----------|-------------|--------|
264
- | Memory skills (4) | Yes | Yes | Yes |
266
+ | Memory skills (6) | Yes | Yes | Yes |
265
267
  | Review specialists (8) | Yes | Yes | Yes |
266
268
  | Review synthesizer | Yes | Yes | Yes |
267
269
  | Review context + code archaeology | Yes | Yes | Yes |
@@ -20,7 +20,7 @@ becomes part of the agent's context.
20
20
 
21
21
  ## What ships
22
22
 
23
- 24 skills total (23 shared, 1 opencode-only):
23
+ 26 skills total (25 shared, 1 opencode-only):
24
24
 
25
25
  ### Memory skills
26
26
 
@@ -30,6 +30,8 @@ becomes part of the agent's context.
30
30
  | `thatch-dedup-classifier` | Guides the agent through classifying and resolving duplicate-candidate pairs. |
31
31
  | `thatch-project-primer` | Investigates a new project from multiple angles and writes foundational memories. |
32
32
  | `thatch-session-reflection` | End-of-session skill for recording what was learned about the project, user, tools, and self. |
33
+ | `thatch-memory-verify` | Fact-checks a single memory against the current codebase and corrects stale claims. Uses git archaeology to preserve historical context when changes were intentional. |
34
+ | `thatch-knowledge-export` | Compiles everything thatch knows about a topic into a curated markdown file for knowledge transfer to another engineer. Searches across stores, curates out personal noise, fact-checks code-related memories. |
33
35
 
34
36
  ### Code review skills
35
37
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jeffober/thatch",
3
- "version": "0.1.31",
3
+ "version": "0.1.33",
4
4
  "description": "Persistent memory for AI coding agents — local embeddings, SQLite stores, zero config. Works with OpenCode (as a plugin), Claude Code (as an MCP server), and Cursor (as an MCP server).",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
package/src/index.ts CHANGED
@@ -20,7 +20,7 @@ import { ExtractionPipeline, type ToolInteraction } from "./extraction";
20
20
  import { installSkills, SHARED_SKILLS, OPENCODE_ONLY_SKILLS } from "./skills";
21
21
  import { hygieneReport } from "./hygiene";
22
22
  import { seedDefaultBehaviors } from "./seed-behaviors";
23
- import { startVersionChecker, stopVersionChecker, getVersionChecker, readOnDiskVersion } from "./version-check";
23
+ import { startVersionChecker, stopVersionChecker, getVersionChecker, readOnDiskVersion, compareSemver } from "./version-check";
24
24
  import pkg from "../package.json";
25
25
 
26
26
  // ---------------------------------------------------------------------------
@@ -398,7 +398,7 @@ export const server: Plugin = async ({ client, worktree }) => {
398
398
  const onDisk = readOnDiskVersion();
399
399
  const checker = getVersionChecker();
400
400
  const npmUpdate = checker?.getUpdateWarning() ?? null;
401
- const skewWarning = onDisk && onDisk !== runningVersion
401
+ const skewWarning = onDisk && compareSemver(runningVersion, onDisk) < 0
402
402
  ? `thatch was upgraded to v${onDisk} but this session is running v${runningVersion}. Restart opencode to apply the update.`
403
403
  : null;
404
404
  const warning = skewWarning ?? npmUpdate;
@@ -411,6 +411,20 @@ export const server: Plugin = async ({ client, worktree }) => {
411
411
  text: versionWarningNudge(warning),
412
412
  synthetic: true,
413
413
  });
414
+ try {
415
+ const short = skewWarning
416
+ ? `\u26A0\uFE0F thatch upgraded to v${onDisk} (running v${runningVersion})`
417
+ : `\u26A0\uFE0F thatch v${checker?.getLatestVersion()} is available`;
418
+ await client.tui.showToast({
419
+ body: {
420
+ message: short,
421
+ variant: "warning",
422
+ duration: 5000,
423
+ },
424
+ });
425
+ } catch {
426
+ // TUI may not be connected. Best-effort.
427
+ }
414
428
  }
415
429
  } catch {
416
430
  // Best-effort. Version check failure must not block nudges.
package/src/prompts.ts CHANGED
@@ -63,6 +63,8 @@ workflows. The host auto-discovers them, but reach for them proactively:
63
63
  - \`thatch-ticket-description\` - draft a ticket, issue, or work item (Linear or Jira) with clear sections and bold/italic emphasis for scanning.
64
64
  - \`thatch-split-overlarge-pr\` - split already-completed work from an overlarge PR into human-reviewable, release-safe PRs targeting main.
65
65
  - \`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.
66
+ - \`thatch-memory-verify\` - fact-check a single memory against the current codebase and correct stale claims. Use when a memory has an old \`updated_at\` date or when preparing a knowledge export.
67
+ - \`thatch-knowledge-export\` - compile everything thatch knows about a topic into a curated markdown file for knowledge transfer. Searches across stores, curates out personal noise, fact-checks code-related memories, and generates a clean export.
66
68
 
67
69
  ## When to Write
68
70
 
@@ -80,6 +82,16 @@ whether you've discovered knowledge worth persisting. Use thatch_memory_recall
80
82
  to check for duplicates, then thatch_memory_remember for new findings. Then
81
83
  deliver your response.
82
84
 
85
+ ## Memory Verification
86
+
87
+ When thatch_memory_show or thatch_memory_recall returns a memory with an old
88
+ updated_at date (more than a few weeks), consider loading the
89
+ thatch-memory-verify skill to fact-check its code-related claims against the
90
+ current codebase before relying on them. This is not mandatory for every old
91
+ memory. Use judgment: a memory about a stable architectural decision may be
92
+ fine for months, while a memory about file locations or function names is
93
+ more likely to drift.
94
+
83
95
  ## Background Task Completions
84
96
 
85
97
  When a background task completes and its result is injected into the session,
@@ -297,6 +309,8 @@ workflows. The host auto-discovers them, but reach for them proactively:
297
309
  - \`thatch-ticket-description\` - draft a ticket, issue, or work item (Linear or Jira) with clear sections and bold/italic emphasis for scanning.
298
310
  - \`thatch-split-overlarge-pr\` - split already-completed work from an overlarge PR into human-reviewable, release-safe PRs targeting main.
299
311
  - \`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.
312
+ - \`thatch-memory-verify\` - fact-check a single memory against the current codebase and correct stale claims. Use when a memory has an old \`updated_at\` date or when preparing a knowledge export.
313
+ - \`thatch-knowledge-export\` - compile everything thatch knows about a topic into a curated markdown file for knowledge transfer. Searches across stores, curates out personal noise, fact-checks code-related memories, and generates a clean export.
300
314
 
301
315
  ## When to Write
302
316
 
@@ -314,6 +328,15 @@ whether you've discovered knowledge worth persisting. Use memory_recall to
314
328
  check for duplicates, then memory_remember for new findings. Then deliver
315
329
  your response.
316
330
 
331
+ ## Memory Verification
332
+
333
+ When memory_show or memory_recall returns a memory with an old updated_at
334
+ date (more than a few weeks), consider loading the thatch-memory-verify skill
335
+ to fact-check its code-related claims against the current codebase before
336
+ relying on them. This is not mandatory for every old memory. Use judgment: a
337
+ memory about a stable architectural decision may be fine for months, while a
338
+ memory about file locations or function names is more likely to drift.
339
+
317
340
  ## User Decision Model
318
341
 
319
342
  A statistical model of the user's decision-making preferences is maintained by
package/src/skills.ts CHANGED
@@ -54,6 +54,8 @@ function loadSharedSkills(): SkillDef[] {
54
54
  "thatch-ticket-description",
55
55
  "thatch-split-overlarge-pr",
56
56
  "thatch-review-response",
57
+ "thatch-memory-verify",
58
+ "thatch-knowledge-export",
57
59
  ];
58
60
  return names.map((name) => ({ name, content: loadSkillFile(name) }));
59
61
  }
package/src/tool-defs.ts CHANGED
@@ -66,6 +66,7 @@ function formatEntry(
66
66
  if (entry.branch) meta += ` branch:${entry.branch}`;
67
67
  if (entry.confidence) meta += ` confidence:${entry.confidence}`;
68
68
  if (entry.archived) meta += " archived:true";
69
+ meta += ` created:${entry.created_at} updated:${entry.updated_at}`;
69
70
  parts.push(meta, "", entry.content);
70
71
  return parts.join("\n");
71
72
  }
@@ -75,6 +76,7 @@ function formatRecallResult(entry: MemoryRow & { _score: number }): string {
75
76
  if (entry.branch) meta += ` branch:${entry.branch}`;
76
77
  if (entry.confidence) meta += ` confidence:${entry.confidence}`;
77
78
  if (entry.archived) meta += " archived:true";
79
+ meta += ` updated:${entry.updated_at}`;
78
80
  const score = entry._score.toFixed(3);
79
81
  return `[${meta}] [score:${score}]\n${entry.content}`;
80
82
  }
@@ -4,6 +4,23 @@ import { tmpdir } from "node:os";
4
4
  import { join, dirname } from "node:path";
5
5
  import pkg from "../package.json";
6
6
 
7
+ /**
8
+ * Compares two semver strings (e.g. "0.1.30", "0.1.31"). Returns a negative
9
+ * number if a < b, positive if a > b, 0 if equal. Pre-release tags are not
10
+ * supported because @jeffober/thatch does not use them.
11
+ */
12
+ export function compareSemver(a: string, b: string): number {
13
+ const pa = a.split(".").map(Number);
14
+ const pb = b.split(".").map(Number);
15
+ for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
16
+ const va = pa[i] ?? 0;
17
+ const vb = pb[i] ?? 0;
18
+ if (va < vb) return -1;
19
+ if (va > vb) return 1;
20
+ }
21
+ return 0;
22
+ }
23
+
7
24
  /**
8
25
  * Version skew detection and npm update checking.
9
26
  *
@@ -198,7 +215,7 @@ class NpmVersionChecker {
198
215
  */
199
216
  isOutdated(): boolean {
200
217
  if (!this.#latestVersion) return false;
201
- return this.#latestVersion !== pkg.version;
218
+ return compareSemver(pkg.version, this.#latestVersion) < 0;
202
219
  }
203
220
 
204
221
  /**
@@ -309,7 +326,7 @@ export function readNpmCacheForUpdate(dbPath: string): string | null {
309
326
  const raw = readFileSync(path, "utf-8");
310
327
  const parsed = JSON.parse(raw) as NpmCacheEntry;
311
328
  if (!parsed.version) return null;
312
- if (parsed.version === pkg.version) return null;
329
+ if (compareSemver(pkg.version, parsed.version) >= 0) return null;
313
330
  return `thatch v${parsed.version} is available. ` +
314
331
  `Run \`npm update ${NPM_PACKAGE}\` to update, then restart your editor.`;
315
332
  } catch {