thumbgate 0.9.10

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 (364) hide show
  1. package/.claude-plugin/README.md +134 -0
  2. package/.claude-plugin/bundle/icon.png +0 -0
  3. package/.claude-plugin/bundle/icon.svg +18 -0
  4. package/.claude-plugin/bundle/server/index.js +24 -0
  5. package/.claude-plugin/marketplace.json +36 -0
  6. package/.claude-plugin/plugin.json +21 -0
  7. package/.well-known/mcp/server-card.json +231 -0
  8. package/LICENSE +21 -0
  9. package/README.md +375 -0
  10. package/adapters/README.md +9 -0
  11. package/adapters/amp/skills/thumbgate-feedback/SKILL.md +22 -0
  12. package/adapters/chatgpt/INSTALL.md +83 -0
  13. package/adapters/chatgpt/openapi.yaml +1281 -0
  14. package/adapters/claude/.mcp.json +14 -0
  15. package/adapters/codex/config.toml +9 -0
  16. package/adapters/gemini/function-declarations.json +224 -0
  17. package/adapters/mcp/server-stdio.js +788 -0
  18. package/adapters/opencode/opencode.json +15 -0
  19. package/bin/cli.js +1484 -0
  20. package/bin/memory.sh +64 -0
  21. package/bin/obsidian-sync.sh +20 -0
  22. package/bin/postinstall.js +37 -0
  23. package/config/build-metadata.json +4 -0
  24. package/config/e2e-critical-flows.json +45 -0
  25. package/config/gate-templates.json +77 -0
  26. package/config/gates/claim-verification.json +29 -0
  27. package/config/gates/computer-use.json +39 -0
  28. package/config/gates/default.json +117 -0
  29. package/config/github-about.json +25 -0
  30. package/config/mcp-allowlists.json +135 -0
  31. package/config/model-tiers.json +33 -0
  32. package/config/partner-routing.json +132 -0
  33. package/config/policy-bundles/constrained-v1.json +64 -0
  34. package/config/policy-bundles/default-v1.json +91 -0
  35. package/config/rubrics/default-v1.json +52 -0
  36. package/config/skill-packs/react-testing.json +23 -0
  37. package/config/skill-packs/stripe-integration/references/api-spec.json +1 -0
  38. package/config/skill-packs/stripe-integration/references/webhook-guide.md +3 -0
  39. package/config/skill-specs/pr-reviewer.json +9 -0
  40. package/config/skill-specs/release-status.json +9 -0
  41. package/config/skill-specs/ticket-triage.json +9 -0
  42. package/config/subagent-profiles.json +32 -0
  43. package/config/tessl-tiles.json +29 -0
  44. package/config/thumbgate-settings.managed.json +12 -0
  45. package/openapi/openapi.yaml +1281 -0
  46. package/package.json +283 -0
  47. package/plugins/amp-skill/INSTALL.md +52 -0
  48. package/plugins/amp-skill/SKILL.md +64 -0
  49. package/plugins/claude-codex-bridge/.claude-plugin/plugin.json +22 -0
  50. package/plugins/claude-codex-bridge/.mcp.json +12 -0
  51. package/plugins/claude-codex-bridge/INSTALL.md +43 -0
  52. package/plugins/claude-codex-bridge/README.md +46 -0
  53. package/plugins/claude-codex-bridge/scripts/codex-bridge.js +288 -0
  54. package/plugins/claude-codex-bridge/skills/adversarial-review/SKILL.md +24 -0
  55. package/plugins/claude-codex-bridge/skills/result/SKILL.md +22 -0
  56. package/plugins/claude-codex-bridge/skills/review/SKILL.md +28 -0
  57. package/plugins/claude-codex-bridge/skills/second-pass/SKILL.md +27 -0
  58. package/plugins/claude-codex-bridge/skills/setup/SKILL.md +21 -0
  59. package/plugins/claude-codex-bridge/skills/status/SKILL.md +19 -0
  60. package/plugins/claude-skill/INSTALL.md +55 -0
  61. package/plugins/claude-skill/SKILL.md +46 -0
  62. package/plugins/codex-profile/.codex-plugin/plugin.json +43 -0
  63. package/plugins/codex-profile/.mcp.json +12 -0
  64. package/plugins/codex-profile/AGENTS.md +20 -0
  65. package/plugins/codex-profile/INSTALL.md +66 -0
  66. package/plugins/codex-profile/README.md +37 -0
  67. package/plugins/cursor-marketplace/.cursor-plugin/plugin.json +23 -0
  68. package/plugins/cursor-marketplace/CHANGELOG.md +30 -0
  69. package/plugins/cursor-marketplace/LICENSE +21 -0
  70. package/plugins/cursor-marketplace/README.md +124 -0
  71. package/plugins/cursor-marketplace/agents/reliability-reviewer.md +31 -0
  72. package/plugins/cursor-marketplace/assets/logo-400x400.png +0 -0
  73. package/plugins/cursor-marketplace/commands/capture-feedback.md +33 -0
  74. package/plugins/cursor-marketplace/commands/check-gates.md +25 -0
  75. package/plugins/cursor-marketplace/commands/show-lessons.md +27 -0
  76. package/plugins/cursor-marketplace/hooks/hooks.json +10 -0
  77. package/plugins/cursor-marketplace/mcp.json +12 -0
  78. package/plugins/cursor-marketplace/rules/feedback-capture.mdc +34 -0
  79. package/plugins/cursor-marketplace/rules/pre-action-gates.mdc +30 -0
  80. package/plugins/cursor-marketplace/rules/session-continuity.mdc +28 -0
  81. package/plugins/cursor-marketplace/scripts/gate-check.sh +11 -0
  82. package/plugins/cursor-marketplace/skills/capture-feedback/SKILL.md +47 -0
  83. package/plugins/cursor-marketplace/skills/prevention-rules/SKILL.md +31 -0
  84. package/plugins/cursor-marketplace/skills/recall-context/SKILL.md +30 -0
  85. package/plugins/cursor-marketplace/skills/search-lessons/SKILL.md +33 -0
  86. package/plugins/gemini-extension/INSTALL.md +92 -0
  87. package/plugins/gemini-extension/gemini_prompt.txt +14 -0
  88. package/plugins/gemini-extension/tool_contract.json +45 -0
  89. package/plugins/opencode-profile/INSTALL.md +57 -0
  90. package/public/assets/instagram-card.png +0 -0
  91. package/public/assets/tiktok-agent-memory.mp4 +0 -0
  92. package/public/blog.html +400 -0
  93. package/public/dashboard.html +1093 -0
  94. package/public/guide.html +317 -0
  95. package/public/index.html +1014 -0
  96. package/public/learn/agent-harness-pattern.html +180 -0
  97. package/public/learn/ai-agent-persistent-memory.html +202 -0
  98. package/public/learn/learn.css +45 -0
  99. package/public/learn/mcp-pre-action-gates-explained.html +172 -0
  100. package/public/learn/stop-ai-agent-force-push.html +134 -0
  101. package/public/learn/vibe-coding-safety-net.html +142 -0
  102. package/public/learn.html +213 -0
  103. package/public/lessons.html +650 -0
  104. package/public/vercel.json +8 -0
  105. package/scripts/__pycache__/train_from_feedback.cpython-312.pyc +0 -0
  106. package/scripts/a2ui-engine.js +73 -0
  107. package/scripts/access-anomaly-detector.js +12 -0
  108. package/scripts/adk-consolidator.js +266 -0
  109. package/scripts/agent-readiness.js +220 -0
  110. package/scripts/agent-security-hardening.js +227 -0
  111. package/scripts/agentic-data-pipeline.js +847 -0
  112. package/scripts/analytics-report.js +328 -0
  113. package/scripts/analytics-window.js +158 -0
  114. package/scripts/async-job-runner.js +1001 -0
  115. package/scripts/audit-trail.js +398 -0
  116. package/scripts/auto-promote-gates.js +299 -0
  117. package/scripts/auto-wire-hooks.js +312 -0
  118. package/scripts/autonomous-sales-agent.js +39 -0
  119. package/scripts/autoresearch-runner.js +216 -0
  120. package/scripts/background-agent-governance.js +237 -0
  121. package/scripts/behavioral-extraction.js +97 -0
  122. package/scripts/belief-update.js +84 -0
  123. package/scripts/billing.js +2438 -0
  124. package/scripts/bot-detector.js +50 -0
  125. package/scripts/budget-guard.js +173 -0
  126. package/scripts/build-claude-mcpb.js +189 -0
  127. package/scripts/build-metadata.js +97 -0
  128. package/scripts/check-congruence.js +322 -0
  129. package/scripts/cli-feedback.js +135 -0
  130. package/scripts/cli-telemetry.js +87 -0
  131. package/scripts/cloudflare-dynamic-sandbox.js +315 -0
  132. package/scripts/code-reasoning.js +350 -0
  133. package/scripts/codegraph-context.js +466 -0
  134. package/scripts/commercial-offer.js +56 -0
  135. package/scripts/computer-use-firewall.js +250 -0
  136. package/scripts/context-engine.js +694 -0
  137. package/scripts/contextfs.js +1287 -0
  138. package/scripts/conversation-context.js +119 -0
  139. package/scripts/creator-campaigns.js +239 -0
  140. package/scripts/daemon-manager.js +108 -0
  141. package/scripts/daily-digest.js +11 -0
  142. package/scripts/dashboard-render-spec.js +395 -0
  143. package/scripts/dashboard.js +1058 -0
  144. package/scripts/data-governance.js +173 -0
  145. package/scripts/delegation-runtime.js +900 -0
  146. package/scripts/deploy-gcp.sh +44 -0
  147. package/scripts/deploy-policy.js +263 -0
  148. package/scripts/disagreement-mining.js +315 -0
  149. package/scripts/dispatch-brief.js +159 -0
  150. package/scripts/distribution-surfaces.js +44 -0
  151. package/scripts/dpo-optimizer.js +209 -0
  152. package/scripts/ephemeral-agent-store.js +219 -0
  153. package/scripts/eval-harness.js +56 -0
  154. package/scripts/evolution-state.js +241 -0
  155. package/scripts/experiment-tracker.js +267 -0
  156. package/scripts/export-databricks-bundle.js +242 -0
  157. package/scripts/export-dpo-pairs.js +345 -0
  158. package/scripts/export-kto-pairs.js +310 -0
  159. package/scripts/export-training.js +448 -0
  160. package/scripts/failure-diagnostics.js +558 -0
  161. package/scripts/feedback-attribution.js +313 -0
  162. package/scripts/feedback-fallback.js +111 -0
  163. package/scripts/feedback-history-distiller.js +391 -0
  164. package/scripts/feedback-inbox-read.js +162 -0
  165. package/scripts/feedback-loop.js +1887 -0
  166. package/scripts/feedback-paths.js +145 -0
  167. package/scripts/feedback-quality.js +139 -0
  168. package/scripts/feedback-root-consolidator.js +238 -0
  169. package/scripts/feedback-schema.js +426 -0
  170. package/scripts/feedback-session.js +286 -0
  171. package/scripts/feedback-to-memory.js +185 -0
  172. package/scripts/feedback-to-rules.js +163 -0
  173. package/scripts/filesystem-search.js +404 -0
  174. package/scripts/funnel-analytics.js +35 -0
  175. package/scripts/gate-satisfy.js +42 -0
  176. package/scripts/gate-stats.js +116 -0
  177. package/scripts/gate-templates.js +70 -0
  178. package/scripts/gates-engine.js +816 -0
  179. package/scripts/generate-paperbanana-diagrams.sh +99 -0
  180. package/scripts/generate-pretool-hook.sh +40 -0
  181. package/scripts/github-about.js +350 -0
  182. package/scripts/github-outreach.js +65 -0
  183. package/scripts/gtm-revenue-loop.js +520 -0
  184. package/scripts/hallucination-detector.js +226 -0
  185. package/scripts/hf-papers.js +317 -0
  186. package/scripts/history-distiller.js +200 -0
  187. package/scripts/hook-auto-capture.sh +95 -0
  188. package/scripts/hook-stop-pr-thread-check.sh +68 -0
  189. package/scripts/hook-stop-self-score.sh +51 -0
  190. package/scripts/hook-stop-verify-deploy.sh +31 -0
  191. package/scripts/hook-thumbgate-cache-updater.js +48 -0
  192. package/scripts/hook-verify-before-done.sh +20 -0
  193. package/scripts/hosted-config.js +170 -0
  194. package/scripts/hybrid-feedback-context.js +676 -0
  195. package/scripts/install-mcp.js +159 -0
  196. package/scripts/intent-router.js +392 -0
  197. package/scripts/internal-agent-bootstrap.js +490 -0
  198. package/scripts/jsonl-watcher.js +155 -0
  199. package/scripts/lesson-db.js +613 -0
  200. package/scripts/lesson-inference.js +315 -0
  201. package/scripts/lesson-retrieval.js +95 -0
  202. package/scripts/lesson-rotation.js +137 -0
  203. package/scripts/lesson-search.js +644 -0
  204. package/scripts/lesson-synthesis.js +196 -0
  205. package/scripts/license.js +50 -0
  206. package/scripts/local-model-profile.js +383 -0
  207. package/scripts/markdown-escape.js +12 -0
  208. package/scripts/marketing-experiment.js +671 -0
  209. package/scripts/mcp-config.js +149 -0
  210. package/scripts/mcp-policy.js +99 -0
  211. package/scripts/memalign-recall.js +111 -0
  212. package/scripts/memory-firewall.js +222 -0
  213. package/scripts/memory-migration.js +296 -0
  214. package/scripts/meta-policy.js +194 -0
  215. package/scripts/metered-billing.js +16 -0
  216. package/scripts/model-tier-router.js +301 -0
  217. package/scripts/money-watcher.js +71 -0
  218. package/scripts/multi-hop-recall.js +240 -0
  219. package/scripts/natural-language-harness.js +330 -0
  220. package/scripts/obsidian-export.js +712 -0
  221. package/scripts/operational-dashboard.js +103 -0
  222. package/scripts/operational-summary.js +93 -0
  223. package/scripts/optimize-context.js +17 -0
  224. package/scripts/org-dashboard.js +201 -0
  225. package/scripts/partner-orchestration.js +146 -0
  226. package/scripts/per-step-scoring.js +165 -0
  227. package/scripts/perplexity-marketing.js +466 -0
  228. package/scripts/pii-scanner.js +153 -0
  229. package/scripts/plan-gate.js +154 -0
  230. package/scripts/post-everywhere.js +308 -0
  231. package/scripts/post-to-x-retry.sh +22 -0
  232. package/scripts/post-to-x.js +369 -0
  233. package/scripts/pr-manager.js +236 -0
  234. package/scripts/predictive-insights.js +356 -0
  235. package/scripts/principle-extractor.js +162 -0
  236. package/scripts/pro-features.js +40 -0
  237. package/scripts/pro-local-dashboard.js +174 -0
  238. package/scripts/problem-detail.js +53 -0
  239. package/scripts/product-feedback.js +134 -0
  240. package/scripts/profile-router.js +245 -0
  241. package/scripts/prompt-dlp.js +221 -0
  242. package/scripts/prompt-guard.js +83 -0
  243. package/scripts/prove-adapters.js +863 -0
  244. package/scripts/prove-attribution.js +365 -0
  245. package/scripts/prove-automation.js +653 -0
  246. package/scripts/prove-autoresearch.js +304 -0
  247. package/scripts/prove-claim-verification.js +277 -0
  248. package/scripts/prove-cloudflare-sandbox.js +163 -0
  249. package/scripts/prove-data-pipeline.js +410 -0
  250. package/scripts/prove-data-quality.js +227 -0
  251. package/scripts/prove-evolution.js +352 -0
  252. package/scripts/prove-harnesses.js +287 -0
  253. package/scripts/prove-intelligence.js +259 -0
  254. package/scripts/prove-lancedb.js +371 -0
  255. package/scripts/prove-local-intelligence.js +342 -0
  256. package/scripts/prove-loop-closure.js +263 -0
  257. package/scripts/prove-predictive-insights.js +357 -0
  258. package/scripts/prove-runtime.js +350 -0
  259. package/scripts/prove-seo-gsd.js +234 -0
  260. package/scripts/prove-settings.js +279 -0
  261. package/scripts/prove-subway-upgrades.js +277 -0
  262. package/scripts/prove-tessl.js +229 -0
  263. package/scripts/prove-training-export.js +327 -0
  264. package/scripts/prove-workflow-contract.js +116 -0
  265. package/scripts/prove-xmemory.js +332 -0
  266. package/scripts/publish-decision.js +133 -0
  267. package/scripts/pulse.js +80 -0
  268. package/scripts/rate-limiter.js +125 -0
  269. package/scripts/reddit-dm-outreach.js +182 -0
  270. package/scripts/reddit-monitor-cron.sh +26 -0
  271. package/scripts/reflector-agent.js +221 -0
  272. package/scripts/reminder-engine.js +132 -0
  273. package/scripts/revenue-status.js +472 -0
  274. package/scripts/risk-scorer.js +458 -0
  275. package/scripts/rlaif-self-audit.js +129 -0
  276. package/scripts/rubric-engine.js +230 -0
  277. package/scripts/schedule-manager.js +251 -0
  278. package/scripts/secret-scanner.js +414 -0
  279. package/scripts/self-heal.js +147 -0
  280. package/scripts/self-healing-check.js +188 -0
  281. package/scripts/semantic-layer.js +98 -0
  282. package/scripts/seo-gsd.js +1153 -0
  283. package/scripts/settings-hierarchy.js +214 -0
  284. package/scripts/shieldcortex-memory-firewall-runner.mjs +53 -0
  285. package/scripts/skill-exporter.js +262 -0
  286. package/scripts/skill-generator.js +446 -0
  287. package/scripts/skill-materializer.js +134 -0
  288. package/scripts/skill-packs.js +136 -0
  289. package/scripts/skill-proposer.js +99 -0
  290. package/scripts/skill-quality-tracker.js +284 -0
  291. package/scripts/slo-alert-engine.js +14 -0
  292. package/scripts/slow-loop.js +72 -0
  293. package/scripts/social-analytics/db/schema.sql +32 -0
  294. package/scripts/social-analytics/digest.js +256 -0
  295. package/scripts/social-analytics/generate-instagram-card.js +97 -0
  296. package/scripts/social-analytics/instagram-thumbgate-post.js +73 -0
  297. package/scripts/social-analytics/mcp-server.js +289 -0
  298. package/scripts/social-analytics/normalizer.js +580 -0
  299. package/scripts/social-analytics/notify.js +162 -0
  300. package/scripts/social-analytics/poll-all.js +107 -0
  301. package/scripts/social-analytics/pollers/github.js +195 -0
  302. package/scripts/social-analytics/pollers/instagram.js +253 -0
  303. package/scripts/social-analytics/pollers/linkedin.js +330 -0
  304. package/scripts/social-analytics/pollers/plausible.js +247 -0
  305. package/scripts/social-analytics/pollers/reddit.js +306 -0
  306. package/scripts/social-analytics/pollers/threads.js +233 -0
  307. package/scripts/social-analytics/pollers/tiktok.js +203 -0
  308. package/scripts/social-analytics/pollers/x.js +227 -0
  309. package/scripts/social-analytics/pollers/youtube.js +304 -0
  310. package/scripts/social-analytics/pollers/zernio.js +180 -0
  311. package/scripts/social-analytics/publish-instagram-thumbgate.js +85 -0
  312. package/scripts/social-analytics/publishers/devto.js +122 -0
  313. package/scripts/social-analytics/publishers/instagram.js +317 -0
  314. package/scripts/social-analytics/publishers/linkedin.js +294 -0
  315. package/scripts/social-analytics/publishers/reddit.js +390 -0
  316. package/scripts/social-analytics/publishers/threads.js +275 -0
  317. package/scripts/social-analytics/publishers/tiktok.js +217 -0
  318. package/scripts/social-analytics/publishers/x.js +259 -0
  319. package/scripts/social-analytics/publishers/youtube.js +223 -0
  320. package/scripts/social-analytics/publishers/zernio.js +209 -0
  321. package/scripts/social-analytics/run-digest.js +34 -0
  322. package/scripts/social-analytics/store.js +257 -0
  323. package/scripts/social-analytics/utm.js +143 -0
  324. package/scripts/social-pipeline.js +2628 -0
  325. package/scripts/social-quality-gate.js +18 -0
  326. package/scripts/social-reply-monitor.js +445 -0
  327. package/scripts/status-dashboard.js +155 -0
  328. package/scripts/statusline-lesson.js +16 -0
  329. package/scripts/statusline-tower.js +8 -0
  330. package/scripts/statusline.sh +116 -0
  331. package/scripts/stripe-live-status.js +115 -0
  332. package/scripts/subagent-profiles.js +79 -0
  333. package/scripts/sync-gh-secrets-from-env.sh +70 -0
  334. package/scripts/sync-github-about.js +52 -0
  335. package/scripts/sync-version.js +451 -0
  336. package/scripts/synthetic-dpo.js +234 -0
  337. package/scripts/telemetry-analytics.js +821 -0
  338. package/scripts/tessl-export.js +371 -0
  339. package/scripts/test-coverage.js +120 -0
  340. package/scripts/thompson-sampling.js +417 -0
  341. package/scripts/thumbgate-search.js +189 -0
  342. package/scripts/tool-kpi-tracker.js +12 -0
  343. package/scripts/tool-registry.js +811 -0
  344. package/scripts/train_from_feedback.py +910 -0
  345. package/scripts/user-profile.js +78 -0
  346. package/scripts/validate-feedback.js +580 -0
  347. package/scripts/validate-workflow-contract.js +287 -0
  348. package/scripts/vector-store.js +198 -0
  349. package/scripts/verification-loop.js +291 -0
  350. package/scripts/verify-obsidian-setup.sh +269 -0
  351. package/scripts/verify-run.js +269 -0
  352. package/scripts/webhook-delivery.js +62 -0
  353. package/scripts/weekly-auto-post.js +124 -0
  354. package/scripts/workflow-runs.js +154 -0
  355. package/scripts/workflow-sprint-intake.js +475 -0
  356. package/scripts/workspace-evolver.js +374 -0
  357. package/scripts/x-autonomous-marketing.js +139 -0
  358. package/scripts/xmemory-lite.js +405 -0
  359. package/skills/agent-memory/SKILL.md +97 -0
  360. package/skills/solve-architecture-autonomy/SKILL.md +17 -0
  361. package/skills/solve-architecture-autonomy/tool.js +33 -0
  362. package/skills/thumbgate/SKILL.md +114 -0
  363. package/skills/thumbgate-feedback/SKILL.md +49 -0
  364. package/src/api/server.js +4208 -0
@@ -0,0 +1,405 @@
1
+ 'use strict';
2
+
3
+ const STOPWORDS = new Set([
4
+ 'a', 'an', 'and', 'are', 'as', 'at', 'be', 'been', 'before', 'but', 'by',
5
+ 'for', 'from', 'had', 'has', 'have', 'into', 'its', 'more', 'not', 'now',
6
+ 'our', 'out', 'that', 'the', 'their', 'them', 'then', 'they', 'this', 'too',
7
+ 'was', 'were', 'what', 'when', 'with', 'without', 'your',
8
+ ]);
9
+
10
+ const GENERIC_THEME_TAGS = new Set([
11
+ 'feedback',
12
+ 'positive',
13
+ 'negative',
14
+ 'rules',
15
+ 'prevention',
16
+ 'memory',
17
+ 'research',
18
+ 'paper',
19
+ 'hf-papers',
20
+ ]);
21
+
22
+ function normalizeKey(input, fallback = 'general') {
23
+ const value = String(input || '')
24
+ .toLowerCase()
25
+ .replace(/[^a-z0-9]+/g, '-')
26
+ .replace(/^-+|-+$/g, '');
27
+ return value || fallback;
28
+ }
29
+
30
+ function uniqueList(values) {
31
+ return Array.from(new Set(values.filter(Boolean)));
32
+ }
33
+
34
+ function tokenizeText(input) {
35
+ return uniqueList(
36
+ String(input || '')
37
+ .toLowerCase()
38
+ .split(/[^a-z0-9]+/)
39
+ .filter((token) => token.length > 2 && !STOPWORDS.has(token))
40
+ );
41
+ }
42
+
43
+ function summarizeText(input, maxChars = 180) {
44
+ return String(input || '')
45
+ .replace(/\s+/g, ' ')
46
+ .trim()
47
+ .slice(0, maxChars);
48
+ }
49
+
50
+ function inferThemeKey(doc = {}) {
51
+ const metadata = doc.metadata || {};
52
+ const directCandidates = [
53
+ metadata.theme,
54
+ metadata.contentPillar,
55
+ metadata.domain,
56
+ ];
57
+
58
+ for (const candidate of directCandidates) {
59
+ if (typeof candidate === 'string' && candidate.trim()) {
60
+ return normalizeKey(candidate);
61
+ }
62
+ }
63
+
64
+ const tags = Array.isArray(doc.tags) ? doc.tags.map((tag) => String(tag).toLowerCase()) : [];
65
+ const meaningfulTag = tags.find((tag) => !GENERIC_THEME_TAGS.has(tag));
66
+ if (meaningfulTag) {
67
+ return normalizeKey(meaningfulTag);
68
+ }
69
+
70
+ if (tags.length > 0) {
71
+ return normalizeKey(tags[0]);
72
+ }
73
+
74
+ if (typeof doc.namespace === 'string' && doc.namespace.includes('memory/error')) return 'mistakes';
75
+ if (typeof doc.namespace === 'string' && doc.namespace.includes('memory/learning')) return 'learnings';
76
+ if (typeof doc.namespace === 'string' && doc.namespace.includes('raw_history')) return 'timeline';
77
+ if (typeof doc.namespace === 'string' && doc.namespace.includes('rules')) return 'rules';
78
+
79
+ const namespaceTail = String(doc.namespace || '').split('/').pop();
80
+ return normalizeKey(namespaceTail, 'general');
81
+ }
82
+
83
+ function collectDocumentTokens(doc = {}) {
84
+ return uniqueList([
85
+ ...tokenizeText(doc.title),
86
+ ...tokenizeText(summarizeText(doc.content, 240)),
87
+ ...(Array.isArray(doc.tags) ? doc.tags.flatMap((tag) => tokenizeText(tag)) : []),
88
+ ]);
89
+ }
90
+
91
+ function buildSemanticFingerprint(doc = {}) {
92
+ const metadata = doc.metadata || {};
93
+ if (typeof metadata.semanticKey === 'string' && metadata.semanticKey.trim()) {
94
+ return normalizeKey(metadata.semanticKey, 'semantic');
95
+ }
96
+
97
+ const tokens = collectDocumentTokens(doc).slice(0, 6);
98
+ if (tokens.length > 0) {
99
+ return normalizeKey(tokens.join('-'), 'semantic');
100
+ }
101
+
102
+ return normalizeKey(doc.title || doc.id || 'semantic', 'semantic');
103
+ }
104
+
105
+ function scoreTokenOverlap(queryTokens = [], candidateTokens = []) {
106
+ if (queryTokens.length === 0) return 0;
107
+ const tokenSet = new Set(candidateTokens);
108
+ let score = 0;
109
+
110
+ for (const token of queryTokens) {
111
+ if (tokenSet.has(token)) {
112
+ score += token.length >= 7 ? 3 : 2;
113
+ }
114
+ }
115
+
116
+ return score;
117
+ }
118
+
119
+ function recencyBoost(createdAt) {
120
+ if (!createdAt) return 0;
121
+ const createdMs = new Date(createdAt).getTime();
122
+ if (!Number.isFinite(createdMs)) return 0;
123
+
124
+ const ageHours = (Date.now() - createdMs) / 3_600_000;
125
+ if (ageHours < 24) return 2;
126
+ if (ageHours < 24 * 7) return 1;
127
+ return 0;
128
+ }
129
+
130
+ function selectRepresentative(members = [], queryTokens = [], scorer = null) {
131
+ return members
132
+ .slice()
133
+ .sort((left, right) => {
134
+ const leftScore = scoreDocumentForSelection(left, queryTokens, scorer);
135
+ const rightScore = scoreDocumentForSelection(right, queryTokens, scorer);
136
+ return rightScore - leftScore;
137
+ })[0] || null;
138
+ }
139
+
140
+ function scoreDocumentForSelection(doc, queryTokens = [], scorer = null) {
141
+ const overlapScore = scoreTokenOverlap(queryTokens, collectDocumentTokens(doc));
142
+ const baseScore = typeof scorer === 'function' ? scorer(doc, queryTokens) : 0;
143
+ return overlapScore + baseScore + recencyBoost(doc.createdAt);
144
+ }
145
+
146
+ function buildSemanticDigest(members = []) {
147
+ if (members.length === 0) return '';
148
+ const titles = uniqueList(members.map((member) => member.title).filter(Boolean)).slice(0, 2);
149
+ const summary = summarizeText(members[0].content, 140);
150
+ return [titles.join(' | '), summary].filter(Boolean).join(' | ');
151
+ }
152
+
153
+ function buildXMemoryHierarchy(documents = [], { query = '', scorer = null } = {}) {
154
+ const queryTokens = tokenizeText(query);
155
+ const themeMap = new Map();
156
+
157
+ for (const doc of documents) {
158
+ const themeKey = inferThemeKey(doc);
159
+ const semanticKey = `${themeKey}::${buildSemanticFingerprint(doc)}`;
160
+ const docTokens = collectDocumentTokens(doc);
161
+
162
+ let theme = themeMap.get(themeKey);
163
+ if (!theme) {
164
+ theme = {
165
+ id: themeKey,
166
+ label: themeKey.replace(/-/g, ' '),
167
+ tokens: [],
168
+ semantics: new Map(),
169
+ documents: [],
170
+ };
171
+ themeMap.set(themeKey, theme);
172
+ }
173
+
174
+ theme.tokens = uniqueList([...theme.tokens, ...docTokens, ...tokenizeText(theme.label)]);
175
+ theme.documents.push(doc);
176
+
177
+ let semantic = theme.semantics.get(semanticKey);
178
+ if (!semantic) {
179
+ semantic = {
180
+ id: semanticKey,
181
+ themeId: themeKey,
182
+ tokens: [],
183
+ members: [],
184
+ };
185
+ theme.semantics.set(semanticKey, semantic);
186
+ }
187
+
188
+ semantic.tokens = uniqueList([...semantic.tokens, ...docTokens]);
189
+ semantic.members.push(doc);
190
+ }
191
+
192
+ const themes = Array.from(themeMap.values()).map((theme) => {
193
+ const semantics = Array.from(theme.semantics.values()).map((semantic) => {
194
+ const representative = selectRepresentative(semantic.members, queryTokens, scorer);
195
+ const score = scoreTokenOverlap(queryTokens, semantic.tokens)
196
+ + recencyBoost(representative && representative.createdAt);
197
+
198
+ return {
199
+ ...semantic,
200
+ memberCount: semantic.members.length,
201
+ digest: buildSemanticDigest(semantic.members),
202
+ representative,
203
+ score,
204
+ };
205
+ }).sort((left, right) => right.score - left.score);
206
+
207
+ const topSemanticScore = semantics[0] ? semantics[0].score : 0;
208
+ const score = scoreTokenOverlap(queryTokens, theme.tokens)
209
+ + topSemanticScore
210
+ + recencyBoost(theme.documents[0] && theme.documents[0].createdAt);
211
+
212
+ return {
213
+ id: theme.id,
214
+ label: theme.label,
215
+ tokens: theme.tokens,
216
+ semanticCount: semantics.length,
217
+ documentCount: theme.documents.length,
218
+ score,
219
+ semantics,
220
+ };
221
+ }).sort((left, right) => right.score - left.score);
222
+
223
+ return {
224
+ query,
225
+ queryTokens,
226
+ themeCount: themes.length,
227
+ semanticCount: themes.reduce((sum, theme) => sum + theme.semanticCount, 0),
228
+ documentCount: documents.length,
229
+ themes,
230
+ };
231
+ }
232
+
233
+ function computeQueryCoverage(queryTokens = [], nodes = []) {
234
+ if (queryTokens.length === 0) return 1;
235
+
236
+ const tokenSet = new Set();
237
+ for (const node of nodes) {
238
+ for (const token of node.tokens || []) {
239
+ tokenSet.add(token);
240
+ }
241
+ }
242
+
243
+ const covered = queryTokens.filter((token) => tokenSet.has(token)).length;
244
+ return Number((covered / queryTokens.length).toFixed(4));
245
+ }
246
+
247
+ function shouldUseHierarchicalRetrieval(namespaces = []) {
248
+ if (!Array.isArray(namespaces) || namespaces.length === 0) return true;
249
+ return !namespaces.every((namespace) => namespace === 'research');
250
+ }
251
+
252
+ function retrieveHierarchicalDocuments({
253
+ documents = [],
254
+ query = '',
255
+ maxItems = 8,
256
+ maxChars = 6000,
257
+ scorer = null,
258
+ measureDocument = null,
259
+ coverageTarget = 0.6,
260
+ } = {}) {
261
+ const hierarchy = buildXMemoryHierarchy(documents, { query, scorer });
262
+ const queryTokens = hierarchy.queryTokens;
263
+ const selectedDocuments = [];
264
+ const selectedSemantics = [];
265
+ const selectedDocumentIds = new Set();
266
+ const selectedSemanticIds = new Set();
267
+ let usedChars = 0;
268
+ let skippedByMaxChars = 0;
269
+
270
+ const semanticBudget = Math.max(1, Math.min(maxItems, Math.ceil(maxItems * 0.6)));
271
+ const rankedThemes = hierarchy.themes.filter((theme) => queryTokens.length === 0 || theme.score > 0);
272
+ const themeCursor = rankedThemes.map(() => 0);
273
+
274
+ function getDocumentChars(doc) {
275
+ if (typeof measureDocument === 'function') {
276
+ return measureDocument(doc);
277
+ }
278
+ return `${doc.title || ''}\n${doc.content || ''}`.length;
279
+ }
280
+
281
+ function trySelectDocument(doc) {
282
+ if (!doc || selectedDocumentIds.has(doc.id) || selectedDocuments.length >= maxItems) {
283
+ return false;
284
+ }
285
+
286
+ const docChars = getDocumentChars(doc);
287
+ if (usedChars + docChars > maxChars) {
288
+ skippedByMaxChars += 1;
289
+ return false;
290
+ }
291
+
292
+ selectedDocuments.push(doc);
293
+ selectedDocumentIds.add(doc.id);
294
+ usedChars += docChars;
295
+ return true;
296
+ }
297
+
298
+ function computeDocumentCoverage(candidateDocs) {
299
+ return computeQueryCoverage(
300
+ queryTokens,
301
+ candidateDocs.map((doc) => ({ tokens: collectDocumentTokens(doc) }))
302
+ );
303
+ }
304
+
305
+ while (selectedSemantics.length < semanticBudget && rankedThemes.length > 0) {
306
+ let progress = false;
307
+
308
+ for (let i = 0; i < rankedThemes.length; i += 1) {
309
+ const theme = rankedThemes[i];
310
+ const semantics = theme.semantics;
311
+ while (themeCursor[i] < semantics.length && selectedSemanticIds.has(semantics[themeCursor[i]].id)) {
312
+ themeCursor[i] += 1;
313
+ }
314
+
315
+ const semantic = semantics[themeCursor[i]];
316
+ if (!semantic) continue;
317
+
318
+ themeCursor[i] += 1;
319
+ if (!trySelectDocument(semantic.representative)) {
320
+ continue;
321
+ }
322
+
323
+ selectedSemanticIds.add(semantic.id);
324
+ selectedSemantics.push(semantic);
325
+ progress = true;
326
+
327
+ if (selectedSemantics.length >= semanticBudget) {
328
+ break;
329
+ }
330
+ }
331
+
332
+ if (!progress) break;
333
+ if (selectedDocuments.length >= maxItems) break;
334
+ }
335
+
336
+ let queryCoverage = computeDocumentCoverage(selectedDocuments);
337
+ const initialCoverage = queryCoverage;
338
+ const expansionCandidates = [];
339
+
340
+ for (const semantic of selectedSemantics) {
341
+ for (const member of semantic.members) {
342
+ if (member.id === (semantic.representative && semantic.representative.id)) continue;
343
+ const memberTokens = collectDocumentTokens(member);
344
+ const newCoverage = computeQueryCoverage(queryTokens, [
345
+ ...selectedDocuments.map((doc) => ({ tokens: collectDocumentTokens(doc) })),
346
+ { tokens: memberTokens },
347
+ ]);
348
+
349
+ expansionCandidates.push({
350
+ doc: member,
351
+ semanticId: semantic.id,
352
+ coverageGain: Number((newCoverage - queryCoverage).toFixed(4)),
353
+ score: scoreDocumentForSelection(member, queryTokens, scorer),
354
+ });
355
+ }
356
+ }
357
+
358
+ expansionCandidates.sort((left, right) => {
359
+ if (right.coverageGain !== left.coverageGain) {
360
+ return right.coverageGain - left.coverageGain;
361
+ }
362
+ return right.score - left.score;
363
+ });
364
+
365
+ let expandedEpisodes = 0;
366
+ for (const candidate of expansionCandidates) {
367
+ if (selectedDocuments.length >= maxItems) break;
368
+ if (queryCoverage >= coverageTarget && candidate.coverageGain <= 0) break;
369
+ if (!trySelectDocument(candidate.doc)) continue;
370
+ queryCoverage = computeDocumentCoverage(selectedDocuments);
371
+ expandedEpisodes += 1;
372
+ }
373
+
374
+ return {
375
+ items: selectedDocuments,
376
+ usedChars,
377
+ skippedByMaxChars,
378
+ hierarchy,
379
+ retrieval: {
380
+ strategy: 'hierarchical',
381
+ themeCount: hierarchy.themeCount,
382
+ semanticCount: hierarchy.semanticCount,
383
+ selectedThemes: uniqueList(selectedSemantics.map((semantic) => semantic.themeId)),
384
+ selectedSemanticGroups: selectedSemantics.map((semantic) => semantic.id),
385
+ representativeCount: Math.min(selectedSemantics.length, selectedDocuments.length),
386
+ expandedEpisodes,
387
+ queryCoverage,
388
+ initialCoverage,
389
+ coverageTarget,
390
+ },
391
+ };
392
+ }
393
+
394
+ module.exports = {
395
+ buildXMemoryHierarchy,
396
+ buildSemanticFingerprint,
397
+ collectDocumentTokens,
398
+ computeQueryCoverage,
399
+ inferThemeKey,
400
+ normalizeKey,
401
+ retrieveHierarchicalDocuments,
402
+ shouldUseHierarchicalRetrieval,
403
+ summarizeText,
404
+ tokenizeText,
405
+ };
@@ -0,0 +1,97 @@
1
+ ---
2
+ name: Agent Memory
3
+ description: Recall past mistakes and capture feedback so your agent stops repeating errors. Works locally via MCP server — no API key needed.
4
+ ---
5
+
6
+ # Agent Memory
7
+
8
+ Give your agent persistent memory across sessions. Before starting any task, recall what went wrong last time. After completing work, capture whether it succeeded or failed. Prevention rules are auto-generated from repeated mistakes.
9
+
10
+ ## Setup
11
+
12
+ Add the MCP server (one-time):
13
+
14
+ ```bash
15
+ claude mcp add thumbgate -- npx -y thumbgate serve
16
+ ```
17
+
18
+ No API key needed. All data stays local.
19
+
20
+ ## When to Use
21
+
22
+ - Starting a new task or session — recall past context first
23
+ - After completing work that succeeded or failed — capture feedback
24
+ - When the agent keeps making the same mistake — check prevention rules
25
+
26
+ ## Workflow
27
+
28
+ ### Step 1: Recall past context (do this FIRST on every task)
29
+
30
+ Call the `recall` MCP tool with a description of your current task. The tool returns:
31
+
32
+ - Past feedback relevant to this task (vector similarity search)
33
+ - Active prevention rules (auto-generated from repeated failures)
34
+ - Recent feedback summary with approval rate
35
+
36
+ Read the prevention rules carefully. These are patterns that failed before — follow them.
37
+
38
+ ### Step 2: Do your work
39
+
40
+ Complete the task as normal. Keep track of what you did and whether it worked.
41
+
42
+ ### Step 3: Capture feedback
43
+
44
+ Call the `capture_feedback` MCP tool:
45
+
46
+ **If succeeded:**
47
+ - signal: `up`
48
+ - context: What worked and why
49
+ - tags: Category labels
50
+
51
+ **If failed:**
52
+ - signal: `down`
53
+ - context: What you were trying to do
54
+ - whatWentWrong: Specific failure description
55
+ - whatToChange: How to avoid this next time
56
+ - tags: Category labels
57
+
58
+ Vague feedback like "it failed" will be rejected. Be specific.
59
+
60
+ ### Step 4: Check improvement (optional)
61
+
62
+ Call the `feedback_stats` MCP tool to see approval rate, top failure domains, and whether the agent is trending better or worse.
63
+
64
+ ## Available MCP Tools
65
+
66
+ | Tool | What it does |
67
+ |------|-------------|
68
+ | `recall` | Search past feedback and prevention rules for current task |
69
+ | `capture_feedback` | Record what worked or failed with structured context |
70
+ | `prevention_rules` | View auto-generated rules from repeated mistakes |
71
+ | `feedback_stats` | Approval rate, trend analysis, top failure domains |
72
+ | `feedback_summary` | Human-readable summary of recent signals |
73
+
74
+ ## MCP Profiles
75
+
76
+ | Profile | Tools | Use case |
77
+ |---------|-------|----------|
78
+ | `essential` | 5 core tools | Default — start here |
79
+ | `commerce` | 6 tools + commerce_recall | Agentic commerce agents |
80
+ | `default` | 12 tools | Full pipeline including DPO export |
81
+
82
+ Set profile: `THUMBGATE_MCP_PROFILE=essential npx thumbgate serve`
83
+
84
+ ## How Prevention Rules Work
85
+
86
+ 1. Agent makes mistake A → you capture `down` feedback
87
+ 2. Agent makes mistake A again → you capture `down` feedback again
88
+ 3. System detects pattern → auto-generates prevention rule: "NEVER do A"
89
+ 4. Next session → `recall` returns the rule → agent follows it
90
+
91
+ This is the core value. The agent doesn't learn — but it reads the rules and follows them.
92
+
93
+ ## Links
94
+
95
+ - [GitHub](https://github.com/IgorGanapolsky/thumbgate)
96
+ - [npm](https://www.npmjs.com/package/thumbgate)
97
+ - [MCP Registry](https://registry.modelcontextprotocol.io)
@@ -0,0 +1,17 @@
1
+ ---
2
+ name: solve-architecture-autonomy
3
+ description: Automated skill to handle architecture, autonomy, crisis, debug, deployment, error, execution, external-assessment, feedback, inefficiency, negative, railway, revenue, roi, simplification, user-frustration patterns efficiently.
4
+ diagnosis: Repeated execution failure in this domain.
5
+ status: materialized
6
+ ---
7
+
8
+ # SOLVE-ARCHITECTURE-AUTONOMY Capability
9
+
10
+ ## Problem
11
+ I provided a plan and research instead of immediately deploy
12
+
13
+ ## Automated Diagnosis
14
+ Repeated execution failure in this domain.
15
+
16
+ ## Usage
17
+ The agent should call the `handle_architecture` tool when tasks involve `architecture, autonomy, crisis, debug, deployment, error, execution, external-assessment, feedback, inefficiency, negative, railway, revenue, roi, simplification, user-frustration`.
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Automated Skill: solve-architecture-autonomy
3
+ * Generated: 2026-03-13T15:50:58.840Z
4
+ *
5
+ * This tool was materialized by the EvoSkill loop to address:
6
+ * "I provided a plan and research instead of immediately deploy"
7
+ */
8
+
9
+ const { execSync } = require('child_process');
10
+
11
+ /**
12
+ * Fixes I provided a plan and research instead of immediately deploy
13
+ */
14
+ async function handle_architecture(args) {
15
+ const { context } = args;
16
+
17
+ // LOGIC: Materialized code should implement the fix derived from the diagnosis.
18
+ // For now, we provide a structured wrapper that logs intent and applies
19
+ // the suggested corrective action.
20
+
21
+ console.log(`[EVOSKILL] Executing handle_architecture to resolve: I provided a plan and research instead of immediately deploy`);
22
+
23
+ // Corrective action placeholder - in a full loop, this would be LLM-generated code
24
+ // derived from the 'how-to-avoid' fields in memory-log.jsonl.
25
+
26
+ return {
27
+ status: 'success',
28
+ appliedFix: `Automated handling of I provided a plan and research instead of immediately deploy pattern.`,
29
+ context: context
30
+ };
31
+ }
32
+
33
+ module.exports = { handle_architecture };
@@ -0,0 +1,114 @@
1
+ ---
2
+ name: thumbgate
3
+ description: >
4
+ ThumbGate provides pre-action gates for AI coding agents. It captures
5
+ thumbs-up/down feedback on agent actions, auto-promotes repeated failures
6
+ into prevention rules, and blocks known-bad tool calls via PreToolUse hooks.
7
+ Trigger when the user wants to add safety guardrails to an AI agent workflow,
8
+ capture structured feedback on agent output, generate prevention rules from
9
+ failure patterns, gate high-risk actions before execution, or export DPO
10
+ training pairs from production feedback. Works with any MCP-compatible agent
11
+ including Cursor, Codex, Gemini CLI, Amp, and OpenCode.
12
+ ---
13
+
14
+ # ThumbGate
15
+
16
+ Pre-action gates that stop AI coding agents from repeating known mistakes.
17
+
18
+ ## Quick Start
19
+
20
+ ```bash
21
+ npx thumbgate init
22
+ ```
23
+
24
+ This installs the MCP server and wires it into your agent's tool configuration. No API keys required for the free tier.
25
+
26
+ Or install globally:
27
+
28
+ ```bash
29
+ npm install -g thumbgate
30
+ thumbgate init
31
+ ```
32
+
33
+ ### MCP Configuration
34
+
35
+ Add to your agent's MCP config (e.g., `claude_desktop_config.json` or `.cursor/mcp.json`):
36
+
37
+ ```json
38
+ {
39
+ "mcpServers": {
40
+ "thumbgate": {
41
+ "command": "npx",
42
+ "args": ["-y", "thumbgate"]
43
+ }
44
+ }
45
+ }
46
+ ```
47
+
48
+ ## How It Works
49
+
50
+ ### Feedback Capture
51
+
52
+ When an agent action succeeds or fails, capture structured feedback:
53
+
54
+ - **Thumbs up**: Records what worked, tags it, and stores it as a reusable pattern.
55
+ - **Thumbs down**: Records the failure context, what went wrong, and what to change. Repeated failures auto-promote into prevention rules.
56
+
57
+ ### Prevention Rules
58
+
59
+ After a failure pattern repeats (default: 2 occurrences), ThumbGate auto-generates a prevention rule. These rules are injected into agent context before every tool call, blocking the known-bad pattern before it executes.
60
+
61
+ ### Pre-Action Gates
62
+
63
+ Gates intercept tool calls via the MCP PreToolUse hook. Each gate checks the proposed action against:
64
+
65
+ 1. Prevention rules generated from past failures
66
+ 2. Thompson Sampling confidence scores (adaptive sensitivity)
67
+ 3. LanceDB vector similarity to known-bad patterns
68
+
69
+ If a match is found, the gate blocks execution and surfaces the prior failure context.
70
+
71
+ ### Context Packs
72
+
73
+ Bounded retrieval of relevant feedback history for the current task. The agent gets exactly the lessons that matter, not the entire history.
74
+
75
+ ## MCP Tools Provided
76
+
77
+ | Tool | Description |
78
+ |------|-------------|
79
+ | `capture_feedback` | Record thumbs-up/down with structured context |
80
+ | `search_lessons` | Query the lesson DB by keyword or semantic similarity |
81
+ | `get_prevention_rules` | Retrieve active prevention rules for the current context |
82
+ | `session_primer` | Get session handoff context (last task, next step, blockers) |
83
+ | `export_dpo` | Export feedback pairs in DPO training format |
84
+
85
+ ## Tiers
86
+
87
+ | | Free | Pro | Team |
88
+ |---|---|---|---|
89
+ | Feedback capture | Unlimited | Unlimited | Unlimited |
90
+ | Lesson search | 5/day | Unlimited | Unlimited |
91
+ | Active gates | 5 | Unlimited | Unlimited |
92
+ | Dashboard | - | Yes | Yes |
93
+ | DPO export | - | Yes | Yes |
94
+ | Seats | 1 | 1 | Per-seat |
95
+ | Price | $0 | $19/mo | $12/seat/mo |
96
+
97
+ Start a 7-day free trial of Pro: <https://buy.stripe.com/fZu9AT3Ug6zcdWh0XN3sI08>
98
+
99
+ ## Compatibility
100
+
101
+ ThumbGate works with any MCP-compatible agent:
102
+
103
+ - Cursor
104
+ - Codex
105
+ - Gemini CLI
106
+ - Amp
107
+ - OpenCode
108
+ - Any agent supporting the Model Context Protocol
109
+
110
+ ## Links
111
+
112
+ - NPM: [thumbgate](https://www.npmjs.com/package/thumbgate)
113
+ - Repository: [IgorGanapolsky/ThumbGate](https://github.com/IgorGanapolsky/ThumbGate)
114
+ - Dashboard: <https://thumbgate-production.up.railway.app/dashboard>