thumbgate 1.4.3 → 1.4.5

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 (270) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.well-known/llms.txt +12 -8
  4. package/.well-known/mcp/server-card.json +1 -1
  5. package/README.md +18 -8
  6. package/adapters/README.md +1 -1
  7. package/adapters/claude/.mcp.json +2 -2
  8. package/adapters/codex/config.toml +2 -2
  9. package/adapters/mcp/server-stdio.js +1 -1
  10. package/adapters/opencode/opencode.json +1 -1
  11. package/config/github-about.json +2 -2
  12. package/package.json +158 -10
  13. package/scripts/billing.js +5 -2
  14. package/scripts/statusline.sh +1 -0
  15. package/src/api/server.js +113 -16
  16. package/src/index.js +3 -0
  17. package/.claude-plugin/bundle/icon.png +0 -0
  18. package/.claude-plugin/bundle/icon.svg +0 -18
  19. package/.claude-plugin/bundle/server/index.js +0 -24
  20. package/adapters/chatgpt/INSTALL.md +0 -158
  21. package/adapters/perplexity/.mcp.json +0 -36
  22. package/adapters/perplexity/config.toml +0 -16
  23. package/adapters/perplexity/opencode.json +0 -29
  24. package/bin/memory.sh +0 -64
  25. package/bin/obsidian-sync.sh +0 -20
  26. package/plugins/amp-skill/INSTALL.md +0 -52
  27. package/plugins/amp-skill/SKILL.md +0 -64
  28. package/plugins/claude-codex-bridge/.claude-plugin/plugin.json +0 -22
  29. package/plugins/claude-codex-bridge/.mcp.json +0 -14
  30. package/plugins/claude-codex-bridge/INSTALL.md +0 -43
  31. package/plugins/claude-codex-bridge/README.md +0 -46
  32. package/plugins/claude-codex-bridge/scripts/codex-bridge.js +0 -286
  33. package/plugins/claude-codex-bridge/skills/adversarial-review/SKILL.md +0 -24
  34. package/plugins/claude-codex-bridge/skills/result/SKILL.md +0 -22
  35. package/plugins/claude-codex-bridge/skills/review/SKILL.md +0 -28
  36. package/plugins/claude-codex-bridge/skills/second-pass/SKILL.md +0 -27
  37. package/plugins/claude-codex-bridge/skills/setup/SKILL.md +0 -21
  38. package/plugins/claude-codex-bridge/skills/status/SKILL.md +0 -19
  39. package/plugins/claude-skill/INSTALL.md +0 -55
  40. package/plugins/claude-skill/SKILL.md +0 -46
  41. package/plugins/codex-profile/.codex-plugin/plugin.json +0 -43
  42. package/plugins/codex-profile/.mcp.json +0 -14
  43. package/plugins/codex-profile/AGENTS.md +0 -20
  44. package/plugins/codex-profile/INSTALL.md +0 -89
  45. package/plugins/codex-profile/README.md +0 -61
  46. package/plugins/cursor-marketplace/.cursor-plugin/plugin.json +0 -23
  47. package/plugins/cursor-marketplace/CHANGELOG.md +0 -30
  48. package/plugins/cursor-marketplace/LICENSE +0 -21
  49. package/plugins/cursor-marketplace/README.md +0 -124
  50. package/plugins/cursor-marketplace/agents/reliability-reviewer.md +0 -31
  51. package/plugins/cursor-marketplace/assets/logo-400x400.png +0 -0
  52. package/plugins/cursor-marketplace/commands/capture-feedback.md +0 -33
  53. package/plugins/cursor-marketplace/commands/check-gates.md +0 -25
  54. package/plugins/cursor-marketplace/commands/show-lessons.md +0 -27
  55. package/plugins/cursor-marketplace/hooks/hooks.json +0 -10
  56. package/plugins/cursor-marketplace/mcp.json +0 -14
  57. package/plugins/cursor-marketplace/rules/feedback-capture.mdc +0 -34
  58. package/plugins/cursor-marketplace/rules/pre-action-gates.mdc +0 -30
  59. package/plugins/cursor-marketplace/rules/session-continuity.mdc +0 -28
  60. package/plugins/cursor-marketplace/scripts/gate-check.sh +0 -21
  61. package/plugins/cursor-marketplace/skills/capture-feedback/SKILL.md +0 -48
  62. package/plugins/cursor-marketplace/skills/prevention-rules/SKILL.md +0 -31
  63. package/plugins/cursor-marketplace/skills/recall-context/SKILL.md +0 -30
  64. package/plugins/cursor-marketplace/skills/search-lessons/SKILL.md +0 -33
  65. package/plugins/gemini-extension/INSTALL.md +0 -92
  66. package/plugins/gemini-extension/gemini_prompt.txt +0 -14
  67. package/plugins/gemini-extension/tool_contract.json +0 -45
  68. package/plugins/opencode-profile/INSTALL.md +0 -57
  69. package/public/assets/instagram-card.png +0 -0
  70. package/public/assets/tiktok-agent-memory.mp4 +0 -0
  71. package/public/blog.html +0 -474
  72. package/public/compare/mem0.html +0 -189
  73. package/public/compare/speclock.html +0 -180
  74. package/public/compare.html +0 -310
  75. package/public/dashboard.html +0 -1100
  76. package/public/guide.html +0 -317
  77. package/public/guides/claude-code-prevent-repeated-mistakes.html +0 -161
  78. package/public/guides/codex-cli-guardrails.html +0 -158
  79. package/public/guides/cursor-prevent-repeated-mistakes.html +0 -161
  80. package/public/guides/pre-action-gates.html +0 -162
  81. package/public/guides/stop-repeated-ai-agent-mistakes.html +0 -159
  82. package/public/index.html +0 -1225
  83. package/public/js/buyer-intent.js +0 -252
  84. package/public/learn/agent-harness-pattern.html +0 -180
  85. package/public/learn/ai-agent-persistent-memory.html +0 -203
  86. package/public/learn/learn.css +0 -45
  87. package/public/learn/mcp-pre-action-gates-explained.html +0 -172
  88. package/public/learn/stop-ai-agent-force-push.html +0 -134
  89. package/public/learn/vibe-coding-safety-net.html +0 -142
  90. package/public/learn.html +0 -274
  91. package/public/lessons.html +0 -967
  92. package/public/llm-context.md +0 -156
  93. package/public/pro.html +0 -1087
  94. package/public/vercel.json +0 -8
  95. package/scripts/a2ui-engine.js +0 -73
  96. package/scripts/adk-consolidator.js +0 -274
  97. package/scripts/agent-security-hardening.js +0 -225
  98. package/scripts/ai-search-visibility.js +0 -116
  99. package/scripts/autonomous-sales-agent.js +0 -39
  100. package/scripts/autoresearch-runner.js +0 -216
  101. package/scripts/background-agent-governance.js +0 -229
  102. package/scripts/behavioral-extraction.js +0 -93
  103. package/scripts/budget-enforcer.js +0 -173
  104. package/scripts/budget-guard.js +0 -173
  105. package/scripts/build-claude-mcpb.js +0 -255
  106. package/scripts/build-codex-plugin.js +0 -152
  107. package/scripts/capture-railway-diagnostics.sh +0 -97
  108. package/scripts/changeset-check.js +0 -372
  109. package/scripts/check-congruence.js +0 -443
  110. package/scripts/computer-use-firewall.js +0 -280
  111. package/scripts/content-engine/linkedin-content-generator.js +0 -154
  112. package/scripts/content-engine/output/linkedin-memento-validation.md +0 -17
  113. package/scripts/content-engine/output/linkedin-posts-2026-04-09.md +0 -175
  114. package/scripts/content-engine/reddit-thread-finder.js +0 -154
  115. package/scripts/context-engine.js +0 -710
  116. package/scripts/daily-digest.js +0 -11
  117. package/scripts/data-governance.js +0 -173
  118. package/scripts/deploy-gcp.sh +0 -44
  119. package/scripts/deploy-policy.js +0 -249
  120. package/scripts/disagreement-mining.js +0 -315
  121. package/scripts/dpo-optimizer.js +0 -206
  122. package/scripts/ensure-repo-bootstrap.js +0 -130
  123. package/scripts/ephemeral-agent-store.js +0 -212
  124. package/scripts/eval-harness.js +0 -56
  125. package/scripts/export-kto-pairs.js +0 -309
  126. package/scripts/export-training.js +0 -446
  127. package/scripts/feedback-fallback.js +0 -111
  128. package/scripts/feedback-inbox-read.js +0 -162
  129. package/scripts/feedback-root-consolidator.js +0 -233
  130. package/scripts/feedback-to-memory.js +0 -185
  131. package/scripts/gate-satisfy.js +0 -42
  132. package/scripts/generate-paperbanana-diagrams.sh +0 -99
  133. package/scripts/generate-pretool-hook.sh +0 -40
  134. package/scripts/github-about.js +0 -430
  135. package/scripts/github-outreach.js +0 -65
  136. package/scripts/gtm-revenue-loop.js +0 -535
  137. package/scripts/hallucination-detector.js +0 -226
  138. package/scripts/hf-papers.js +0 -317
  139. package/scripts/hook-auto-capture.sh +0 -100
  140. package/scripts/hook-stop-pr-thread-check.sh +0 -68
  141. package/scripts/hook-stop-self-score.sh +0 -51
  142. package/scripts/hook-stop-verify-deploy.sh +0 -31
  143. package/scripts/hook-verify-before-done.sh +0 -20
  144. package/scripts/managed-dpo-export.js +0 -91
  145. package/scripts/markdown-escape.js +0 -12
  146. package/scripts/marketing-experiment.js +0 -657
  147. package/scripts/memalign-recall.js +0 -111
  148. package/scripts/memory-migration.js +0 -296
  149. package/scripts/meta-policy.js +0 -190
  150. package/scripts/metered-billing.js +0 -16
  151. package/scripts/model-tier-router.js +0 -310
  152. package/scripts/money-watcher.js +0 -218
  153. package/scripts/multi-hop-recall.js +0 -240
  154. package/scripts/per-step-scoring.js +0 -163
  155. package/scripts/perplexity-command-center.js +0 -644
  156. package/scripts/perplexity-marketing.js +0 -454
  157. package/scripts/pii-scanner.js +0 -153
  158. package/scripts/plan-gate.js +0 -154
  159. package/scripts/post-everywhere.js +0 -341
  160. package/scripts/post-to-x-retry.sh +0 -22
  161. package/scripts/post-to-x.js +0 -369
  162. package/scripts/pr-manager.js +0 -421
  163. package/scripts/principle-extractor.js +0 -162
  164. package/scripts/pro-features.js +0 -41
  165. package/scripts/prompt-dlp.js +0 -222
  166. package/scripts/prove-adapters.js +0 -860
  167. package/scripts/prove-attribution.js +0 -361
  168. package/scripts/prove-automation.js +0 -651
  169. package/scripts/prove-autoresearch.js +0 -304
  170. package/scripts/prove-claim-verification.js +0 -277
  171. package/scripts/prove-cloudflare-sandbox.js +0 -161
  172. package/scripts/prove-data-pipeline.js +0 -408
  173. package/scripts/prove-data-quality.js +0 -227
  174. package/scripts/prove-evolution.js +0 -352
  175. package/scripts/prove-harnesses.js +0 -287
  176. package/scripts/prove-intelligence.js +0 -257
  177. package/scripts/prove-lancedb.js +0 -425
  178. package/scripts/prove-local-intelligence.js +0 -340
  179. package/scripts/prove-loop-closure.js +0 -263
  180. package/scripts/prove-packaged-runtime.js +0 -327
  181. package/scripts/prove-predictive-insights.js +0 -355
  182. package/scripts/prove-runtime.js +0 -363
  183. package/scripts/prove-seo-gsd.js +0 -234
  184. package/scripts/prove-settings.js +0 -279
  185. package/scripts/prove-subway-upgrades.js +0 -277
  186. package/scripts/prove-tessl.js +0 -229
  187. package/scripts/prove-training-export.js +0 -325
  188. package/scripts/prove-workflow-contract.js +0 -112
  189. package/scripts/prove-xmemory.js +0 -332
  190. package/scripts/publish-decision.js +0 -159
  191. package/scripts/ralph-loop.js +0 -376
  192. package/scripts/ralph-mode-ci.js +0 -434
  193. package/scripts/reddit-dm-outreach.js +0 -192
  194. package/scripts/reddit-monitor-cron.sh +0 -26
  195. package/scripts/reminder-engine.js +0 -132
  196. package/scripts/revenue-status.js +0 -472
  197. package/scripts/rotate-stripe-webhook-secret.js +0 -314
  198. package/scripts/schedule-manager.js +0 -249
  199. package/scripts/self-healing-check.js +0 -193
  200. package/scripts/session-analyzer.js +0 -533
  201. package/scripts/shieldcortex-memory-firewall-runner.mjs +0 -53
  202. package/scripts/skill-exporter.js +0 -260
  203. package/scripts/skill-materializer.js +0 -134
  204. package/scripts/skill-packs.js +0 -136
  205. package/scripts/skill-proposer.js +0 -99
  206. package/scripts/skill-quality-tracker.js +0 -282
  207. package/scripts/slow-loop.js +0 -72
  208. package/scripts/social-analytics/db/marketing-db.js +0 -179
  209. package/scripts/social-analytics/db/schema.sql +0 -55
  210. package/scripts/social-analytics/digest.js +0 -256
  211. package/scripts/social-analytics/engagement-audit.js +0 -185
  212. package/scripts/social-analytics/generate-instagram-card.js +0 -123
  213. package/scripts/social-analytics/generate-slides.js +0 -268
  214. package/scripts/social-analytics/instagram-thumbgate-post.js +0 -111
  215. package/scripts/social-analytics/install-growth-automation.js +0 -114
  216. package/scripts/social-analytics/load-env.js +0 -77
  217. package/scripts/social-analytics/mcp-server.js +0 -289
  218. package/scripts/social-analytics/normalizer.js +0 -580
  219. package/scripts/social-analytics/notify.js +0 -162
  220. package/scripts/social-analytics/poll-all.js +0 -107
  221. package/scripts/social-analytics/pollers/github.js +0 -195
  222. package/scripts/social-analytics/pollers/instagram.js +0 -253
  223. package/scripts/social-analytics/pollers/linkedin.js +0 -340
  224. package/scripts/social-analytics/pollers/plausible.js +0 -245
  225. package/scripts/social-analytics/pollers/reddit.js +0 -306
  226. package/scripts/social-analytics/pollers/threads.js +0 -233
  227. package/scripts/social-analytics/pollers/tiktok.js +0 -203
  228. package/scripts/social-analytics/pollers/x.js +0 -227
  229. package/scripts/social-analytics/pollers/youtube.js +0 -304
  230. package/scripts/social-analytics/pollers/zernio.js +0 -183
  231. package/scripts/social-analytics/post-video.js +0 -316
  232. package/scripts/social-analytics/publish-instagram-thumbgate.js +0 -104
  233. package/scripts/social-analytics/publish-thumbgate-launch.js +0 -322
  234. package/scripts/social-analytics/publishers/devto.js +0 -122
  235. package/scripts/social-analytics/publishers/instagram.js +0 -317
  236. package/scripts/social-analytics/publishers/linkedin.js +0 -294
  237. package/scripts/social-analytics/publishers/reddit.js +0 -385
  238. package/scripts/social-analytics/publishers/threads.js +0 -275
  239. package/scripts/social-analytics/publishers/tiktok.js +0 -217
  240. package/scripts/social-analytics/publishers/x.js +0 -259
  241. package/scripts/social-analytics/publishers/youtube.js +0 -223
  242. package/scripts/social-analytics/publishers/zernio.js +0 -568
  243. package/scripts/social-analytics/reconcile-thumbgate-campaign.js +0 -165
  244. package/scripts/social-analytics/run-digest.js +0 -34
  245. package/scripts/social-analytics/schedule-thumbgate-campaign.js +0 -275
  246. package/scripts/social-analytics/store.js +0 -455
  247. package/scripts/social-analytics/sync-launch-assets.js +0 -185
  248. package/scripts/social-analytics/utm.js +0 -143
  249. package/scripts/social-pipeline.js +0 -2626
  250. package/scripts/social-post-hourly.js +0 -228
  251. package/scripts/social-quality-gate.js +0 -134
  252. package/scripts/social-reply-monitor.js +0 -592
  253. package/scripts/status-dashboard.js +0 -155
  254. package/scripts/stripe-live-status.js +0 -115
  255. package/scripts/subagent-profiles.js +0 -79
  256. package/scripts/sync-branch-protection.js +0 -340
  257. package/scripts/sync-gh-secrets-from-env.sh +0 -70
  258. package/scripts/sync-github-about.js +0 -55
  259. package/scripts/sync-version.js +0 -479
  260. package/scripts/synthetic-dpo.js +0 -234
  261. package/scripts/tessl-export.js +0 -369
  262. package/scripts/test-coverage.js +0 -128
  263. package/scripts/thumbgate-bench.js +0 -494
  264. package/scripts/thumbgate_session_start.sh +0 -32
  265. package/scripts/train_from_feedback.py +0 -929
  266. package/scripts/validate-feedback.js +0 -581
  267. package/scripts/verify-obsidian-setup.sh +0 -269
  268. package/scripts/verify-run.js +0 -269
  269. package/scripts/weekly-auto-post.js +0 -124
  270. package/scripts/x-autonomous-marketing.js +0 -139
@@ -1,252 +0,0 @@
1
- (function(global) {
2
- var BUYER_EMAIL_STORAGE_KEY = 'thumbgateBuyerEmail';
3
- var CHECKOUT_LINK_SELECTOR = 'a[href*="/checkout/pro"]';
4
- var BUYER_EMAIL_SELECTOR = '[data-buyer-email]';
5
-
6
- function normalizeBuyerEmail(value) {
7
- return String(value || '').trim().toLowerCase();
8
- }
9
-
10
- function isValidBuyerEmail(value) {
11
- return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(normalizeBuyerEmail(value));
12
- }
13
-
14
- function getStorage() {
15
- return global.localStorage && typeof global.localStorage.getItem === 'function'
16
- ? global.localStorage
17
- : null;
18
- }
19
-
20
- function getStoredBuyerEmail() {
21
- var storage = getStorage();
22
- if (!storage) {
23
- return '';
24
- }
25
- try {
26
- return normalizeBuyerEmail(storage.getItem(BUYER_EMAIL_STORAGE_KEY));
27
- } catch (_error) {
28
- return '';
29
- }
30
- }
31
-
32
- function storeBuyerEmail(email) {
33
- var storage = getStorage();
34
- if (!storage) {
35
- return false;
36
- }
37
- try {
38
- storage.setItem(BUYER_EMAIL_STORAGE_KEY, normalizeBuyerEmail(email));
39
- return true;
40
- } catch (_error) {
41
- return false;
42
- }
43
- }
44
-
45
- function resolveCheckoutUrl(urlValue, email) {
46
- var origin = global.location && global.location.origin
47
- ? global.location.origin
48
- : 'https://thumbgate.invalid';
49
- var checkoutUrl = new URL(String(urlValue || '/checkout/pro'), origin);
50
- if (checkoutUrl.origin !== origin || checkoutUrl.pathname !== '/checkout/pro') {
51
- checkoutUrl = new URL('/checkout/pro', origin);
52
- }
53
- if (isValidBuyerEmail(email)) {
54
- checkoutUrl.searchParams.set('customer_email', normalizeBuyerEmail(email));
55
- } else {
56
- checkoutUrl.searchParams.delete('customer_email');
57
- }
58
- return checkoutUrl;
59
- }
60
-
61
- function getCheckoutLinks(selector) {
62
- if (!global.document || typeof global.document.querySelectorAll !== 'function') {
63
- return [];
64
- }
65
- return Array.from(global.document.querySelectorAll(selector || CHECKOUT_LINK_SELECTOR));
66
- }
67
-
68
- function getBaseCheckoutHref(link) {
69
- if (!link.dataset.baseHref) {
70
- link.dataset.baseHref = link.getAttribute('href') || link.href || '/checkout/pro';
71
- }
72
- return link.dataset.baseHref;
73
- }
74
-
75
- function applyBuyerEmailToCheckoutLinks(email, selector) {
76
- getCheckoutLinks(selector).forEach(function(link) {
77
- link.href = resolveCheckoutUrl(getBaseCheckoutHref(link), email).toString();
78
- });
79
- }
80
-
81
- function hydrateBuyerEmailInputs(email, selector) {
82
- if (!global.document || typeof global.document.querySelectorAll !== 'function') {
83
- return;
84
- }
85
- Array.from(global.document.querySelectorAll(selector || BUYER_EMAIL_SELECTOR)).forEach(function(input) {
86
- if (!input.value) {
87
- input.value = normalizeBuyerEmail(email);
88
- }
89
- });
90
- }
91
-
92
- function getNewsletterStatusElement(form) {
93
- if (!form) {
94
- return null;
95
- }
96
- return form.querySelector('[data-newsletter-status]')
97
- || (form.parentElement ? form.parentElement.querySelector('[data-newsletter-status]') : null);
98
- }
99
-
100
- function setNewsletterStatus(form, message, ok) {
101
- var statusEl = getNewsletterStatusElement(form);
102
- if (!statusEl) {
103
- return;
104
- }
105
- statusEl.textContent = message;
106
- statusEl.style.color = ok ? 'var(--cyan)' : 'var(--red, #f87171)';
107
- }
108
-
109
- async function submitNewsletterSignup(email, form) {
110
- var action = form && form.action ? form.action : '/api/newsletter';
111
- var response = await fetch(action, {
112
- method: 'POST',
113
- headers: {
114
- 'Content-Type': 'application/x-www-form-urlencoded',
115
- Accept: 'application/json',
116
- 'X-Requested-With': 'fetch',
117
- },
118
- body: new URLSearchParams({ email: normalizeBuyerEmail(email) }).toString(),
119
- credentials: 'same-origin',
120
- });
121
- if (!response.ok) {
122
- var errorMessage = 'Unable to save your email right now.';
123
- try {
124
- var errorBody = await response.json();
125
- if (errorBody && errorBody.error) {
126
- errorMessage = errorBody.error;
127
- }
128
- } catch (_error) {
129
- // Keep the default error message when the response is not JSON.
130
- }
131
- throw new Error(errorMessage);
132
- }
133
- try {
134
- return await response.json();
135
- } catch (_error) {
136
- return { accepted: true, duplicate: false };
137
- }
138
- }
139
-
140
- function trackEvent(eventName, props) {
141
- if (typeof global.plausible === 'function') {
142
- global.plausible(eventName, { props: props || {} });
143
- }
144
- }
145
-
146
- function getEmailFromInput(input) {
147
- return normalizeBuyerEmail(input && input.value);
148
- }
149
-
150
- function initializeBuyerIntent(options) {
151
- var settings = options || {};
152
- var storedEmail = getStoredBuyerEmail();
153
- if (storedEmail) {
154
- hydrateBuyerEmailInputs(storedEmail, settings.emailSelector);
155
- applyBuyerEmailToCheckoutLinks(storedEmail, settings.checkoutSelector);
156
- }
157
-
158
- if (!global.document || typeof global.document.querySelectorAll !== 'function') {
159
- return;
160
- }
161
-
162
- Array.from(global.document.querySelectorAll(settings.formSelector || '[data-newsletter-form]')).forEach(function(form) {
163
- form.addEventListener('submit', async function(event) {
164
- event.preventDefault();
165
- var input = form.querySelector(settings.formEmailSelector || 'input[name="email"]');
166
- var email = getEmailFromInput(input);
167
- if (!isValidBuyerEmail(email)) {
168
- setNewsletterStatus(form, settings.invalidEmailMessage || 'Enter a valid work email.', false);
169
- if (input) {
170
- input.focus();
171
- }
172
- return;
173
- }
174
-
175
- storeBuyerEmail(email);
176
- hydrateBuyerEmailInputs(email, settings.emailSelector);
177
- applyBuyerEmailToCheckoutLinks(email, settings.checkoutSelector);
178
-
179
- try {
180
- var result = await submitNewsletterSignup(email, form);
181
- var successMessage = result && result.duplicate
182
- ? (settings.duplicateMessage || 'You are already on the list. Checkout on this device is now prefilled.')
183
- : (settings.successMessage || 'Saved. We will keep checkout prefilled on this device.');
184
- setNewsletterStatus(form, successMessage, true);
185
- trackEvent('newsletter_signup', {
186
- page: form.dataset.page || settings.page || 'homepage',
187
- intent: form.dataset.intent || settings.intent || 'buyer_follow_up',
188
- });
189
- } catch (error) {
190
- setNewsletterStatus(
191
- form,
192
- error && error.message ? error.message : 'Unable to save your email right now.',
193
- false
194
- );
195
- }
196
- });
197
- });
198
- }
199
-
200
- function initializeEmailCheckoutButtons(options) {
201
- var settings = options || {};
202
- if (!global.document || typeof global.document.querySelectorAll !== 'function') {
203
- return;
204
- }
205
-
206
- Array.from(global.document.querySelectorAll(settings.buttonSelector || '.btn-email-checkout')).forEach(function(button) {
207
- button.addEventListener('click', async function() {
208
- var form = button.closest('form');
209
- var input = form ? form.querySelector(settings.formEmailSelector || 'input[name="email"]') : null;
210
- var email = getEmailFromInput(input) || getStoredBuyerEmail();
211
- if (!isValidBuyerEmail(email)) {
212
- setNewsletterStatus(form, settings.invalidCheckoutMessage || 'Enter a valid work email before checkout.', false);
213
- if (input) {
214
- input.focus();
215
- }
216
- return;
217
- }
218
-
219
- storeBuyerEmail(email);
220
- hydrateBuyerEmailInputs(email, settings.emailSelector);
221
- applyBuyerEmailToCheckoutLinks(email, settings.checkoutSelector);
222
- trackEvent(settings.eventName || 'pro_checkout_email_start', settings.eventProps || { page: 'pro', intent: 'checkout' });
223
-
224
- try {
225
- await submitNewsletterSignup(email, form);
226
- } catch (_error) {
227
- // Continue to checkout even if signup persistence fails.
228
- }
229
-
230
- var checkoutLink = global.document.querySelector(settings.checkoutLinkSelector || '.btn-pro-checkout');
231
- if (checkoutLink) {
232
- global.location.assign(checkoutLink.href);
233
- }
234
- });
235
- });
236
- }
237
-
238
- global.ThumbGateBuyerIntent = {
239
- normalizeBuyerEmail: normalizeBuyerEmail,
240
- isValidBuyerEmail: isValidBuyerEmail,
241
- getStoredBuyerEmail: getStoredBuyerEmail,
242
- storeBuyerEmail: storeBuyerEmail,
243
- resolveCheckoutUrl: resolveCheckoutUrl,
244
- applyBuyerEmailToCheckoutLinks: applyBuyerEmailToCheckoutLinks,
245
- hydrateBuyerEmailInputs: hydrateBuyerEmailInputs,
246
- setNewsletterStatus: setNewsletterStatus,
247
- submitNewsletterSignup: submitNewsletterSignup,
248
- initializeBuyerIntent: initializeBuyerIntent,
249
- initializeEmailCheckoutButtons: initializeEmailCheckoutButtons,
250
- trackEvent: trackEvent,
251
- };
252
- })(globalThis);
@@ -1,180 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>The Agent Harness Pattern: Why Your AI Needs a Seatbelt — ThumbGate</title>
7
- <script defer data-domain="thumbgate-production.up.railway.app" src="https://plausible.io/js/script.js"></script>
8
- <meta name="description" content="Tsinghua researchers formalized agent harnesses as first-class objects with contracts, verification gates, and durable state. ThumbGate implements this pattern today.">
9
- <meta name="keywords" content="agent harness pattern, natural language agent harness, NLAH, AI agent safety, pre-action gates, verification gates, agent contracts, ThumbGate, MCP hooks">
10
- <meta property="og:title" content="The Agent Harness Pattern: Why Your AI Needs a Seatbelt">
11
- <meta property="og:description" content="Academic research meets production code. How the natural-language agent harness pattern maps to real pre-action gates.">
12
- <meta property="og:type" content="article">
13
- <meta property="og:url" content="https://thumbgate-production.up.railway.app/learn/agent-harness-pattern">
14
- <link rel="canonical" href="https://thumbgate-production.up.railway.app/learn/agent-harness-pattern">
15
-
16
- <script type="application/ld+json">
17
- {
18
- "@context": "https://schema.org",
19
- "@type": "TechArticle",
20
- "headline": "The Agent Harness Pattern: Why Your AI Needs a Seatbelt",
21
- "description": "How the natural-language agent harness pattern from academic research maps to real pre-action gates you can ship today.",
22
- "author": {
23
- "@type": "Person",
24
- "name": "Igor Ganapolsky",
25
- "url": "https://github.com/IgorGanapolsky"
26
- },
27
- "publisher": {
28
- "@type": "Organization",
29
- "name": "ThumbGate",
30
- "url": "https://thumbgate-production.up.railway.app"
31
- },
32
- "datePublished": "2026-04-02",
33
- "dateModified": "2026-04-02",
34
- "mainEntityOfPage": "https://thumbgate-production.up.railway.app/learn/agent-harness-pattern",
35
- "about": [
36
- {"@type": "Thing", "name": "agent harness pattern"},
37
- {"@type": "Thing", "name": "natural language agent harness"},
38
- {"@type": "Thing", "name": "AI agent verification"}
39
- ]
40
- }
41
- </script>
42
-
43
- <link rel="stylesheet" href="/learn/learn.css">
44
- <style>
45
- table { width: 100%; border-collapse: collapse; margin: 1rem 0; }
46
- th, td { text-align: left; padding: 0.6rem 0.8rem; border-bottom: 1px solid var(--border); font-size: 0.9rem; }
47
- th { color: var(--cyan); font-weight: 600; }
48
- .mapping-row td:first-child { color: var(--green); font-weight: 500; }
49
- </style>
50
- </head>
51
- <body>
52
-
53
- <nav>
54
- <a href="/" class="brand">👍👎 ThumbGate</a>
55
- <a href="/guide">Setup Guide</a>
56
- <a href="/learn">Learn</a>
57
- <a href="/dashboard">Dashboard</a>
58
- <a href="https://github.com/IgorGanapolsky/ThumbGate" target="_blank" rel="noopener">GitHub</a>
59
- </nav>
60
-
61
- <div class="container">
62
- <div class="breadcrumb"><a href="/learn">Learn</a> / Agent Harness Pattern</div>
63
- <h1>The Agent Harness Pattern: Why Your AI Needs a Seatbelt</h1>
64
- <p style="color:var(--muted);">5 min read &middot; Research deep-dive for developers shipping AI agents in production</p>
65
-
66
- <div class="tldr"><strong>TL;DR:</strong> Tsinghua researchers proved that AI agents need harnesses — contracts, verification gates, and durable state. ThumbGate is a production implementation you can ship today.</div>
67
-
68
- <h2>The problem: agents act faster than you can review</h2>
69
- <p>AI coding agents can write, commit, and deploy code in seconds. The gap between "agent decides to act" and "irreversible damage" is measured in milliseconds. Prompt instructions alone cannot close that gap because they live inside the same context the agent can override.</p>
70
- <p>Researchers at Tsinghua University formalized this problem in their work on Natural-Language Agent Harnesses (NLAH). Their key insight: the safety layer must be <strong>external to the agent</strong>, treated as a first-class object with its own contracts, verification logic, and persistent state.</p>
71
-
72
- <div class="callout">
73
- <strong>The core idea:</strong> An agent harness is not a prompt. It is a runtime layer that sits between the agent's intent and the outside world, enforcing contracts that the agent cannot bypass.
74
- </div>
75
-
76
- <h2>Four components of an agent harness</h2>
77
- <p>The NLAH framework defines four components that any production-grade harness needs. Here is how each maps to a concrete implementation in ThumbGate:</p>
78
-
79
- <table>
80
- <thead>
81
- <tr>
82
- <th>NLAH Component</th>
83
- <th>What It Does</th>
84
- <th>ThumbGate Implementation</th>
85
- </tr>
86
- </thead>
87
- <tbody>
88
- <tr class="mapping-row">
89
- <td>Contracts</td>
90
- <td>Formal rules that define what the agent must not do</td>
91
- <td>Prevention rules in <code>prevention-rules.md</code> — auto-generated from thumbs-down feedback</td>
92
- </tr>
93
- <tr class="mapping-row">
94
- <td>Verification Gates</td>
95
- <td>Checkpoints that intercept actions before execution</td>
96
- <td>PreToolUse hooks — intercept every tool call, match against gates, block or allow</td>
97
- </tr>
98
- <tr class="mapping-row">
99
- <td>Durable State</td>
100
- <td>Persistent memory that survives across sessions</td>
101
- <td>SQLite+FTS5 lesson database — feedback, memories, and rules persist and are searchable</td>
102
- </tr>
103
- <tr class="mapping-row">
104
- <td>Adapters</td>
105
- <td>Platform-specific connectors for different agent runtimes</td>
106
- <td>MCP server + adapters for Claude Code, Cursor, Codex, Gemini, Amp, OpenCode</td>
107
- </tr>
108
- </tbody>
109
- </table>
110
-
111
- <h2>Why contracts beat prompt rules</h2>
112
- <p>A prompt rule says: "Do not force-push to main." An agent can reason around that, reinterpret it, or simply lose it in a long context window.</p>
113
- <p>A contract says: if the tool call is <code>Bash</code> and the command matches <code>git push.*--force</code> targeting <code>main</code>, return <code>{"decision": "block"}</code>. The agent never executes the command. There is nothing to reason around.</p>
114
-
115
- <div class="callout callout-red">
116
- <strong>Prompt rules fail silently.</strong> When a prompt rule is violated, you only find out after the damage is done. A verification gate fails loudly — the agent receives a block response and must adapt.
117
- </div>
118
-
119
- <h2>Verification gates in practice</h2>
120
- <p>Every time your AI agent calls a tool — running a shell command, writing a file, making an API call — a PreToolUse hook fires. ThumbGate checks the call against your gates:</p>
121
-
122
- <ol>
123
- <li><strong>Pattern match:</strong> Does the tool name and arguments match any prevention rule?</li>
124
- <li><strong>Thompson Sampling:</strong> For rules with uncertain severity, use multi-armed bandit sampling to decide block vs. warn</li>
125
- <li><strong>Decision:</strong> Block (hard stop), warn (let agent reconsider), or allow (no match)</li>
126
- <li><strong>Feedback loop:</strong> The decision is logged. Thumbs-up/down on outcomes refines future gates.</li>
127
- </ol>
128
-
129
- <p>This is the verification gate pattern from the NLAH framework, running in production today.</p>
130
-
131
- <h2>Durable state: memory that survives sessions</h2>
132
- <p>One of the NLAH paper's strongest arguments is that agent harnesses need persistent state. An agent that forgets its mistakes between sessions will repeat them.</p>
133
- <p>ThumbGate stores every feedback event in a SQLite database with full-text search (FTS5). When a new session starts, the agent's context is assembled from relevant past lessons — not the entire history, but the lessons most similar to the current task.</p>
134
-
135
- <div class="callout callout-green">
136
- <strong>The feedback loop closes itself:</strong> You thumbs-down a mistake → a prevention rule is generated → the gate blocks the mistake next time → the agent adapts → you thumbs-up the adaptation → the rule is reinforced.
137
- </div>
138
-
139
- <h2>Adapters: one harness, many agents</h2>
140
- <p>The NLAH framework emphasizes platform independence. A harness should work across different agent runtimes without rewriting the safety logic.</p>
141
- <p>ThumbGate achieves this through the Model Context Protocol (MCP). Any agent that speaks MCP — Claude Code, Cursor, Codex, Gemini, Amp, OpenCode — connects to the same ThumbGate server and gets the same gates. Write your rules once, enforce everywhere.</p>
142
-
143
- <h2>From research to production in two minutes</h2>
144
- <p>The NLAH framework describes what an agent harness <em>should</em> be. ThumbGate is what it looks like when you ship one:</p>
145
-
146
- <pre><code>npx thumbgate init</code></pre>
147
-
148
- <p>That single command sets up:</p>
149
- <ul>
150
- <li>A PreToolUse hook that intercepts every tool call</li>
151
- <li>A SQLite+FTS5 lesson database for durable state</li>
152
- <li>Prevention rules generated from your feedback</li>
153
- <li>Thompson Sampling for probabilistic gate decisions</li>
154
- <li>MCP server adapters for your agent runtime</li>
155
- </ul>
156
-
157
- <p>You are not writing safety rules from scratch. You are thumbs-downing mistakes and letting the harness learn.</p>
158
-
159
- <div class="cta-box">
160
- <h2 style="color:var(--text);font-size:1.3rem;margin:0 0 8px;">Ship the harness pattern today</h2>
161
- <p>One command. Works with Claude Code, Cursor, Codex, Gemini, Amp, and any MCP agent.</p>
162
- <div class="cta-install">$ npx thumbgate init</div>
163
- </div>
164
-
165
- <div class="related">
166
- <h3>Related articles</h3>
167
- <a href="/learn/mcp-pre-action-gates-explained">MCP Pre-Action Gates Explained →</a>
168
- <a href="/learn/stop-ai-agent-force-push">How to Stop AI Agents From Force-Pushing to Main →</a>
169
- <a href="/learn/vibe-coding-safety-net">The Vibe Coding Safety Net You Are Missing →</a>
170
- </div>
171
- </div>
172
-
173
-
174
- <div class="sticky-cta">
175
- <span style="color:var(--muted)">Try it now:</span>
176
- <code>npx thumbgate init</code>
177
- <a href="https://github.com/IgorGanapolsky/ThumbGate" target="_blank" rel="noopener">GitHub &rarr;</a>
178
- </div>
179
- </body>
180
- </html>
@@ -1,203 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>How to Give Your AI Coding Agent Persistent Memory Across Sessions — ThumbGate</title>
7
- <script defer data-domain="thumbgate-production.up.railway.app" src="https://plausible.io/js/script.js"></script>
8
- <meta name="description" content="AI coding agents forget everything when a session ends. Learn how to give Claude Code, Cursor, Codex, and Gemini persistent memory using an MCP memory server that survives restarts.">
9
- <meta name="keywords" content="ai agent memory, persistent memory, claude code memory, cursor agent memory, MCP memory server, session persistence, agent context, episodic memory, semantic memory">
10
- <meta property="og:title" content="How to Give Your AI Coding Agent Persistent Memory Across Sessions">
11
- <meta property="og:description" content="Context windows are ephemeral. Real memory persists. Here is how to build durable memory for any MCP-compatible AI coding agent.">
12
- <meta property="og:type" content="article">
13
- <meta property="og:url" content="https://thumbgate-production.up.railway.app/learn/ai-agent-persistent-memory">
14
- <link rel="canonical" href="https://thumbgate-production.up.railway.app/learn/ai-agent-persistent-memory">
15
-
16
- <script type="application/ld+json">
17
- {
18
- "@context": "https://schema.org",
19
- "@type": "TechArticle",
20
- "headline": "How to Give Your AI Coding Agent Persistent Memory Across Sessions",
21
- "description": "AI coding agents forget everything when a session ends. Learn how to give Claude Code, Cursor, Codex, and Gemini persistent memory using an MCP memory server that survives restarts.",
22
- "author": {
23
- "@type": "Person",
24
- "name": "Igor Ganapolsky",
25
- "url": "https://github.com/IgorGanapolsky"
26
- },
27
- "publisher": {
28
- "@type": "Organization",
29
- "name": "ThumbGate",
30
- "url": "https://thumbgate-production.up.railway.app"
31
- },
32
- "datePublished": "2026-04-02",
33
- "dateModified": "2026-04-02",
34
- "mainEntityOfPage": "https://thumbgate-production.up.railway.app/learn/ai-agent-persistent-memory",
35
- "about": [
36
- {"@type": "Thing", "name": "ai agent memory"},
37
- {"@type": "Thing", "name": "persistent memory"},
38
- {"@type": "Thing", "name": "MCP memory server"},
39
- {"@type": "Thing", "name": "session persistence"}
40
- ]
41
- }
42
- </script>
43
-
44
- <link rel="stylesheet" href="/learn/learn.css">
45
- <style>
46
- table { width: 100%; border-collapse: collapse; margin: 1rem 0; }
47
- th, td { text-align: left; padding: 0.6rem 0.8rem; border-bottom: 1px solid var(--border); font-size: 0.9rem; }
48
- th { color: var(--cyan); font-weight: 600; }
49
- .memory-row td:first-child { color: var(--green); font-weight: 500; }
50
- </style>
51
- </head>
52
- <body>
53
-
54
- <nav>
55
- <a href="/" class="brand">👍👎 ThumbGate</a>
56
- <a href="/guide">Setup Guide</a>
57
- <a href="/learn">Learn</a>
58
- <a href="/dashboard">Dashboard</a>
59
- <a href="https://github.com/IgorGanapolsky/ThumbGate" target="_blank" rel="noopener">GitHub</a>
60
- </nav>
61
-
62
- <div class="container">
63
- <div class="breadcrumb"><a href="/learn">Learn</a> / AI Agent Persistent Memory</div>
64
- <h1>How to Give Your AI Coding Agent Persistent Memory Across Sessions</h1>
65
- <p style="color:var(--muted);">6 min read &middot; For developers using Claude Code, Cursor, Codex, or Gemini who are tired of re-explaining context every session</p>
66
-
67
- <div class="tldr"><strong>TL;DR:</strong> Your AI agent forgets everything between sessions. Give it a SQLite+FTS5 memory that stores lessons, retrieves relevant context, and blocks known-bad actions automatically.</div>
68
-
69
- <h2>The problem: agents forget everything when you close the tab</h2>
70
- <p>You spend twenty minutes explaining your codebase to your AI coding agent. You tell it about the monorepo structure, the deployment conventions, the one branch it must never force-push to. The session ends. You come back tomorrow and it has no memory of any of it.</p>
71
- <p>You are not doing anything wrong. This is how context windows work. Every session starts with a blank slate. The agent has no continuity of experience — no record of past mistakes, no accumulated knowledge of your project, no recollection of the rules you established last week.</p>
72
- <p>The frustration is real and widespread. Developers using Claude Code, Cursor, Codex, and Gemini all hit the same wall. The agents are capable — they just cannot remember.</p>
73
-
74
- <div class="callout">
75
- <strong>The distinction that matters:</strong> A context window holds information for one session. Memory holds information across sessions. Most agents have the former. Almost none have the latter by default.
76
- </div>
77
-
78
- <h2>Why context windows are not memory</h2>
79
- <p>Context windows are large and getting larger. That solves a different problem. A big context window means the agent can reason over more information at once within a single session. It does not mean that information survives when the session ends.</p>
80
- <p>Think of the difference this way: a context window is RAM — fast, capacious, gone when the power cuts. Memory is disk — slower to query, but persistent. You need both. Right now, AI coding agents only ship with RAM.</p>
81
- <p>The consequences compound over time. An agent with no persistent memory will:</p>
82
- <ul>
83
- <li>Repeat mistakes it made last week because it has no record of them</li>
84
- <li>Re-ask you for project conventions it has already learned once</li>
85
- <li>Ignore prevention rules you painstakingly wrote into a prompt — because that prompt is gone</li>
86
- <li>Treat every session as if it is the first day on the job</li>
87
- </ul>
88
- <p>Stuffing facts into a <code>CLAUDE.md</code> file helps, but it is a manual workaround. You are the memory. You remember what to put in the file. You update it when things change. That is not a solution — it is delegation of a machine problem back to a human.</p>
89
-
90
- <div class="callout callout-red">
91
- <strong>The hidden cost:</strong> Re-explaining context is not just annoying. Every token you spend re-establishing what the agent already knew is a token not spent on the actual task. And re-explained rules are still just prompt rules — the agent can reason around them.
92
- </div>
93
-
94
- <h2>Three types of agent memory</h2>
95
- <p>Cognitive science distinguishes several memory types. The same taxonomy maps cleanly onto what AI coding agents need. Here is how each type works and what it looks like in practice:</p>
96
-
97
- <table>
98
- <thead>
99
- <tr>
100
- <th>Memory Type</th>
101
- <th>What It Stores</th>
102
- <th>Concrete Example</th>
103
- </tr>
104
- </thead>
105
- <tbody>
106
- <tr class="memory-row">
107
- <td>Episodic</td>
108
- <td>Records of specific past events — what happened, when, and what the outcome was</td>
109
- <td>The agent tried to force-push to main. You gave thumbs-down. That event is stored with context, timestamp, and failure description.</td>
110
- </tr>
111
- <tr class="memory-row">
112
- <td>Semantic</td>
113
- <td>Generalised knowledge extracted from episodes — rules, patterns, facts about the world</td>
114
- <td>From multiple thumbs-down events, the system derives: "force-pushing to main causes broken deploys in this repo." That becomes a prevention rule.</td>
115
- </tr>
116
- <tr class="memory-row">
117
- <td>Procedural</td>
118
- <td>Encoded behaviours — gates that fire before actions without requiring the agent to reason about them</td>
119
- <td>A PreToolUse hook that checks every <code>git push</code> command against the prevention rule and blocks the dangerous pattern automatically.</td>
120
- </tr>
121
- </tbody>
122
- </table>
123
-
124
- <p>Most "persistent memory" proposals for AI agents stop at episodic: they store a log of past conversations. That is useful, but insufficient. The signal gets diluted in a sea of raw events. What agents need is the full pipeline: episodes promote to semantic rules, semantic rules compile into procedural gates.</p>
125
-
126
- <h2>How ThumbGate implements persistent memory</h2>
127
- <p>ThumbGate is built around this three-tier memory architecture. Here is each layer in concrete terms.</p>
128
-
129
- <h3>Episodic layer: the feedback log</h3>
130
- <p>Every thumbs-up or thumbs-down you give an agent action is written to a structured feedback log. Each entry captures the tool call that was made, the context at the time, what worked or went wrong, and any tags you add. The log is append-only and survives across sessions.</p>
131
- <p>In the current Claude auto-capture hook, a vague thumbs-down can borrow up to 8 prior recorded entries plus the failed tool call before promotion. Accepted feedback also opens a linked 60-second follow-up session so later corrections stay attached to the same memory trace instead of fragmenting into duplicates.</p>
132
-
133
- <pre><code># Thumbs-down: record a specific failure
134
- node .claude/scripts/feedback/capture-feedback.js \
135
- --feedback=down \
136
- --context="deploying to production" \
137
- --what-went-wrong="agent ran db migration without backup" \
138
- --what-to-change="always checkpoint before schema changes" \
139
- --tags="database,migrations,safety"</code></pre>
140
-
141
- <p>You do not need to write this manually for every interaction. The MCP server captures tool calls automatically. Manual feedback is for adding nuance that the agent could not observe on its own.</p>
142
-
143
- <h3>Semantic layer: the lesson database</h3>
144
- <p>Raw feedback events are processed into a SQLite database with full-text search (FTS5). This is not a flat file — it is a queryable knowledge store. When a new session starts, the system retrieves lessons relevant to the current task by similarity, not by recency.</p>
145
- <p>The FTS5 index means retrieval is fast even as the database grows. You are not loading the entire history into context. You are loading the lessons most likely to matter right now. That is the difference between a knowledge base and a memory dump.</p>
146
-
147
- <h3>Procedural layer: prevention rules and gates</h3>
148
- <p>Promoted lessons generate prevention rules in <code>prevention-rules.md</code>. Rules are not prompt instructions — they are checked by a PreToolUse hook that fires before every tool call. The agent cannot reason around a gate. The gate runs outside the agent's context.</p>
149
-
150
- <div class="callout callout-green">
151
- <strong>The promotion pipeline:</strong> Thumbs-down event &rarr; feedback log entry &rarr; lesson promoted to SQLite &rarr; prevention rule generated &rarr; PreToolUse gate active for every future session, with no additional setup.
152
- </div>
153
-
154
- <h2>Thompson Sampling for memory-informed decisions</h2>
155
- <p>Not every prevention rule has the same confidence level. A rule derived from one thumbs-down event is weaker than a rule reinforced by a dozen. ThumbGate uses Thompson Sampling — a multi-armed bandit algorithm — to handle this uncertainty.</p>
156
- <p>For each gate, the system maintains a Beta distribution over outcomes. As thumbs-up and thumbs-down feedback accumulates, the distribution tightens. A gate with high confidence becomes a hard block. A gate still gathering signal issues a warning and lets the agent reconsider.</p>
157
- <p>This matters for memory because it means the system learns your preferences rather than requiring you to manually tune thresholds. You give feedback. The gate calibrates. The agent adapts.</p>
158
- <p>Thompson Sampling also prevents over-blocking. If a pattern that was once dangerous stops being a problem — because the codebase changed, or you updated your workflow — thumbs-up feedback on future calls will widen the distribution back toward allowing. Memory is not one-way.</p>
159
-
160
- <h2>Setup: persistent memory in two minutes</h2>
161
- <p>ThumbGate ships as an MCP server. Any agent that speaks MCP — Claude Code, Cursor, Codex, Gemini, Amp, OpenCode — can connect to it. You initialize once and the memory layer is active for every subsequent session.</p>
162
-
163
- <pre><code>npx thumbgate init</code></pre>
164
-
165
- <p>That command sets up:</p>
166
- <ul>
167
- <li>The SQLite+FTS5 lesson database in <code>.claude/memory/</code></li>
168
- <li>The feedback log at <code>.claude/memory/feedback/feedback-log.jsonl</code></li>
169
- <li>Prevention rules at <code>.claude/memory/feedback/prevention-rules.md</code></li>
170
- <li>A PreToolUse hook that reads gates on every tool call</li>
171
- <li>The MCP server adapter for your agent runtime</li>
172
- </ul>
173
-
174
- <p>After init, your agent starts each session with context assembled from relevant past lessons. It does not start blank. It starts informed.</p>
175
-
176
- <h3>What memory looks like on day one vs. day thirty</h3>
177
- <p>On day one, the database is empty. The agent behaves the same as it always has. You give feedback on its actions.</p>
178
- <p>By day thirty, the database has accumulated dozens of lessons. The agent's context at session start includes the most relevant ones. Prevention rules have tightened around patterns that caused problems. Patterns that worked have been reinforced. The agent makes fewer mistakes — not because it was retrained, but because the gates learned from your feedback.</p>
179
- <p>That is persistent memory in practice: not a bigger context window, not a longer system prompt, but a feedback loop that accumulates signal and converts it into durable enforcement.</p>
180
-
181
- <div class="cta-box">
182
- <h2 style="color:var(--text);font-size:1.3rem;margin:0 0 8px;">Give your agent memory that survives restarts</h2>
183
- <p>One command. Works with Claude Code, Cursor, Codex, Gemini, Amp, and any MCP-compatible agent.</p>
184
- <div class="cta-install">$ npx thumbgate init</div>
185
- </div>
186
-
187
- <div class="related">
188
- <h3>Related articles</h3>
189
- <a href="/learn/agent-harness-pattern">The Agent Harness Pattern: Why Your AI Needs a Seatbelt &rarr;</a>
190
- <a href="/learn/mcp-pre-action-gates-explained">MCP Pre-Action Gates Explained &rarr;</a>
191
- <a href="/learn/stop-ai-agent-force-push">How to Stop AI Agents From Force-Pushing to Main &rarr;</a>
192
- <a href="/learn/vibe-coding-safety-net">The Vibe Coding Safety Net You Are Missing &rarr;</a>
193
- </div>
194
- </div>
195
-
196
-
197
- <div class="sticky-cta">
198
- <span style="color:var(--muted)">Try it now:</span>
199
- <code>npx thumbgate init</code>
200
- <a href="https://github.com/IgorGanapolsky/ThumbGate" target="_blank" rel="noopener">GitHub &rarr;</a>
201
- </div>
202
- </body>
203
- </html>