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.
- package/.claude-plugin/README.md +134 -0
- package/.claude-plugin/bundle/icon.png +0 -0
- package/.claude-plugin/bundle/icon.svg +18 -0
- package/.claude-plugin/bundle/server/index.js +24 -0
- package/.claude-plugin/marketplace.json +36 -0
- package/.claude-plugin/plugin.json +21 -0
- package/.well-known/mcp/server-card.json +231 -0
- package/LICENSE +21 -0
- package/README.md +375 -0
- package/adapters/README.md +9 -0
- package/adapters/amp/skills/thumbgate-feedback/SKILL.md +22 -0
- package/adapters/chatgpt/INSTALL.md +83 -0
- package/adapters/chatgpt/openapi.yaml +1281 -0
- package/adapters/claude/.mcp.json +14 -0
- package/adapters/codex/config.toml +9 -0
- package/adapters/gemini/function-declarations.json +224 -0
- package/adapters/mcp/server-stdio.js +788 -0
- package/adapters/opencode/opencode.json +15 -0
- package/bin/cli.js +1484 -0
- package/bin/memory.sh +64 -0
- package/bin/obsidian-sync.sh +20 -0
- package/bin/postinstall.js +37 -0
- package/config/build-metadata.json +4 -0
- package/config/e2e-critical-flows.json +45 -0
- package/config/gate-templates.json +77 -0
- package/config/gates/claim-verification.json +29 -0
- package/config/gates/computer-use.json +39 -0
- package/config/gates/default.json +117 -0
- package/config/github-about.json +25 -0
- package/config/mcp-allowlists.json +135 -0
- package/config/model-tiers.json +33 -0
- package/config/partner-routing.json +132 -0
- package/config/policy-bundles/constrained-v1.json +64 -0
- package/config/policy-bundles/default-v1.json +91 -0
- package/config/rubrics/default-v1.json +52 -0
- package/config/skill-packs/react-testing.json +23 -0
- package/config/skill-packs/stripe-integration/references/api-spec.json +1 -0
- package/config/skill-packs/stripe-integration/references/webhook-guide.md +3 -0
- package/config/skill-specs/pr-reviewer.json +9 -0
- package/config/skill-specs/release-status.json +9 -0
- package/config/skill-specs/ticket-triage.json +9 -0
- package/config/subagent-profiles.json +32 -0
- package/config/tessl-tiles.json +29 -0
- package/config/thumbgate-settings.managed.json +12 -0
- package/openapi/openapi.yaml +1281 -0
- package/package.json +283 -0
- package/plugins/amp-skill/INSTALL.md +52 -0
- package/plugins/amp-skill/SKILL.md +64 -0
- package/plugins/claude-codex-bridge/.claude-plugin/plugin.json +22 -0
- package/plugins/claude-codex-bridge/.mcp.json +12 -0
- package/plugins/claude-codex-bridge/INSTALL.md +43 -0
- package/plugins/claude-codex-bridge/README.md +46 -0
- package/plugins/claude-codex-bridge/scripts/codex-bridge.js +288 -0
- package/plugins/claude-codex-bridge/skills/adversarial-review/SKILL.md +24 -0
- package/plugins/claude-codex-bridge/skills/result/SKILL.md +22 -0
- package/plugins/claude-codex-bridge/skills/review/SKILL.md +28 -0
- package/plugins/claude-codex-bridge/skills/second-pass/SKILL.md +27 -0
- package/plugins/claude-codex-bridge/skills/setup/SKILL.md +21 -0
- package/plugins/claude-codex-bridge/skills/status/SKILL.md +19 -0
- package/plugins/claude-skill/INSTALL.md +55 -0
- package/plugins/claude-skill/SKILL.md +46 -0
- package/plugins/codex-profile/.codex-plugin/plugin.json +43 -0
- package/plugins/codex-profile/.mcp.json +12 -0
- package/plugins/codex-profile/AGENTS.md +20 -0
- package/plugins/codex-profile/INSTALL.md +66 -0
- package/plugins/codex-profile/README.md +37 -0
- package/plugins/cursor-marketplace/.cursor-plugin/plugin.json +23 -0
- package/plugins/cursor-marketplace/CHANGELOG.md +30 -0
- package/plugins/cursor-marketplace/LICENSE +21 -0
- package/plugins/cursor-marketplace/README.md +124 -0
- package/plugins/cursor-marketplace/agents/reliability-reviewer.md +31 -0
- package/plugins/cursor-marketplace/assets/logo-400x400.png +0 -0
- package/plugins/cursor-marketplace/commands/capture-feedback.md +33 -0
- package/plugins/cursor-marketplace/commands/check-gates.md +25 -0
- package/plugins/cursor-marketplace/commands/show-lessons.md +27 -0
- package/plugins/cursor-marketplace/hooks/hooks.json +10 -0
- package/plugins/cursor-marketplace/mcp.json +12 -0
- package/plugins/cursor-marketplace/rules/feedback-capture.mdc +34 -0
- package/plugins/cursor-marketplace/rules/pre-action-gates.mdc +30 -0
- package/plugins/cursor-marketplace/rules/session-continuity.mdc +28 -0
- package/plugins/cursor-marketplace/scripts/gate-check.sh +11 -0
- package/plugins/cursor-marketplace/skills/capture-feedback/SKILL.md +47 -0
- package/plugins/cursor-marketplace/skills/prevention-rules/SKILL.md +31 -0
- package/plugins/cursor-marketplace/skills/recall-context/SKILL.md +30 -0
- package/plugins/cursor-marketplace/skills/search-lessons/SKILL.md +33 -0
- package/plugins/gemini-extension/INSTALL.md +92 -0
- package/plugins/gemini-extension/gemini_prompt.txt +14 -0
- package/plugins/gemini-extension/tool_contract.json +45 -0
- package/plugins/opencode-profile/INSTALL.md +57 -0
- package/public/assets/instagram-card.png +0 -0
- package/public/assets/tiktok-agent-memory.mp4 +0 -0
- package/public/blog.html +400 -0
- package/public/dashboard.html +1093 -0
- package/public/guide.html +317 -0
- package/public/index.html +1014 -0
- package/public/learn/agent-harness-pattern.html +180 -0
- package/public/learn/ai-agent-persistent-memory.html +202 -0
- package/public/learn/learn.css +45 -0
- package/public/learn/mcp-pre-action-gates-explained.html +172 -0
- package/public/learn/stop-ai-agent-force-push.html +134 -0
- package/public/learn/vibe-coding-safety-net.html +142 -0
- package/public/learn.html +213 -0
- package/public/lessons.html +650 -0
- package/public/vercel.json +8 -0
- package/scripts/__pycache__/train_from_feedback.cpython-312.pyc +0 -0
- package/scripts/a2ui-engine.js +73 -0
- package/scripts/access-anomaly-detector.js +12 -0
- package/scripts/adk-consolidator.js +266 -0
- package/scripts/agent-readiness.js +220 -0
- package/scripts/agent-security-hardening.js +227 -0
- package/scripts/agentic-data-pipeline.js +847 -0
- package/scripts/analytics-report.js +328 -0
- package/scripts/analytics-window.js +158 -0
- package/scripts/async-job-runner.js +1001 -0
- package/scripts/audit-trail.js +398 -0
- package/scripts/auto-promote-gates.js +299 -0
- package/scripts/auto-wire-hooks.js +312 -0
- package/scripts/autonomous-sales-agent.js +39 -0
- package/scripts/autoresearch-runner.js +216 -0
- package/scripts/background-agent-governance.js +237 -0
- package/scripts/behavioral-extraction.js +97 -0
- package/scripts/belief-update.js +84 -0
- package/scripts/billing.js +2438 -0
- package/scripts/bot-detector.js +50 -0
- package/scripts/budget-guard.js +173 -0
- package/scripts/build-claude-mcpb.js +189 -0
- package/scripts/build-metadata.js +97 -0
- package/scripts/check-congruence.js +322 -0
- package/scripts/cli-feedback.js +135 -0
- package/scripts/cli-telemetry.js +87 -0
- package/scripts/cloudflare-dynamic-sandbox.js +315 -0
- package/scripts/code-reasoning.js +350 -0
- package/scripts/codegraph-context.js +466 -0
- package/scripts/commercial-offer.js +56 -0
- package/scripts/computer-use-firewall.js +250 -0
- package/scripts/context-engine.js +694 -0
- package/scripts/contextfs.js +1287 -0
- package/scripts/conversation-context.js +119 -0
- package/scripts/creator-campaigns.js +239 -0
- package/scripts/daemon-manager.js +108 -0
- package/scripts/daily-digest.js +11 -0
- package/scripts/dashboard-render-spec.js +395 -0
- package/scripts/dashboard.js +1058 -0
- package/scripts/data-governance.js +173 -0
- package/scripts/delegation-runtime.js +900 -0
- package/scripts/deploy-gcp.sh +44 -0
- package/scripts/deploy-policy.js +263 -0
- package/scripts/disagreement-mining.js +315 -0
- package/scripts/dispatch-brief.js +159 -0
- package/scripts/distribution-surfaces.js +44 -0
- package/scripts/dpo-optimizer.js +209 -0
- package/scripts/ephemeral-agent-store.js +219 -0
- package/scripts/eval-harness.js +56 -0
- package/scripts/evolution-state.js +241 -0
- package/scripts/experiment-tracker.js +267 -0
- package/scripts/export-databricks-bundle.js +242 -0
- package/scripts/export-dpo-pairs.js +345 -0
- package/scripts/export-kto-pairs.js +310 -0
- package/scripts/export-training.js +448 -0
- package/scripts/failure-diagnostics.js +558 -0
- package/scripts/feedback-attribution.js +313 -0
- package/scripts/feedback-fallback.js +111 -0
- package/scripts/feedback-history-distiller.js +391 -0
- package/scripts/feedback-inbox-read.js +162 -0
- package/scripts/feedback-loop.js +1887 -0
- package/scripts/feedback-paths.js +145 -0
- package/scripts/feedback-quality.js +139 -0
- package/scripts/feedback-root-consolidator.js +238 -0
- package/scripts/feedback-schema.js +426 -0
- package/scripts/feedback-session.js +286 -0
- package/scripts/feedback-to-memory.js +185 -0
- package/scripts/feedback-to-rules.js +163 -0
- package/scripts/filesystem-search.js +404 -0
- package/scripts/funnel-analytics.js +35 -0
- package/scripts/gate-satisfy.js +42 -0
- package/scripts/gate-stats.js +116 -0
- package/scripts/gate-templates.js +70 -0
- package/scripts/gates-engine.js +816 -0
- package/scripts/generate-paperbanana-diagrams.sh +99 -0
- package/scripts/generate-pretool-hook.sh +40 -0
- package/scripts/github-about.js +350 -0
- package/scripts/github-outreach.js +65 -0
- package/scripts/gtm-revenue-loop.js +520 -0
- package/scripts/hallucination-detector.js +226 -0
- package/scripts/hf-papers.js +317 -0
- package/scripts/history-distiller.js +200 -0
- package/scripts/hook-auto-capture.sh +95 -0
- package/scripts/hook-stop-pr-thread-check.sh +68 -0
- package/scripts/hook-stop-self-score.sh +51 -0
- package/scripts/hook-stop-verify-deploy.sh +31 -0
- package/scripts/hook-thumbgate-cache-updater.js +48 -0
- package/scripts/hook-verify-before-done.sh +20 -0
- package/scripts/hosted-config.js +170 -0
- package/scripts/hybrid-feedback-context.js +676 -0
- package/scripts/install-mcp.js +159 -0
- package/scripts/intent-router.js +392 -0
- package/scripts/internal-agent-bootstrap.js +490 -0
- package/scripts/jsonl-watcher.js +155 -0
- package/scripts/lesson-db.js +613 -0
- package/scripts/lesson-inference.js +315 -0
- package/scripts/lesson-retrieval.js +95 -0
- package/scripts/lesson-rotation.js +137 -0
- package/scripts/lesson-search.js +644 -0
- package/scripts/lesson-synthesis.js +196 -0
- package/scripts/license.js +50 -0
- package/scripts/local-model-profile.js +383 -0
- package/scripts/markdown-escape.js +12 -0
- package/scripts/marketing-experiment.js +671 -0
- package/scripts/mcp-config.js +149 -0
- package/scripts/mcp-policy.js +99 -0
- package/scripts/memalign-recall.js +111 -0
- package/scripts/memory-firewall.js +222 -0
- package/scripts/memory-migration.js +296 -0
- package/scripts/meta-policy.js +194 -0
- package/scripts/metered-billing.js +16 -0
- package/scripts/model-tier-router.js +301 -0
- package/scripts/money-watcher.js +71 -0
- package/scripts/multi-hop-recall.js +240 -0
- package/scripts/natural-language-harness.js +330 -0
- package/scripts/obsidian-export.js +712 -0
- package/scripts/operational-dashboard.js +103 -0
- package/scripts/operational-summary.js +93 -0
- package/scripts/optimize-context.js +17 -0
- package/scripts/org-dashboard.js +201 -0
- package/scripts/partner-orchestration.js +146 -0
- package/scripts/per-step-scoring.js +165 -0
- package/scripts/perplexity-marketing.js +466 -0
- package/scripts/pii-scanner.js +153 -0
- package/scripts/plan-gate.js +154 -0
- package/scripts/post-everywhere.js +308 -0
- package/scripts/post-to-x-retry.sh +22 -0
- package/scripts/post-to-x.js +369 -0
- package/scripts/pr-manager.js +236 -0
- package/scripts/predictive-insights.js +356 -0
- package/scripts/principle-extractor.js +162 -0
- package/scripts/pro-features.js +40 -0
- package/scripts/pro-local-dashboard.js +174 -0
- package/scripts/problem-detail.js +53 -0
- package/scripts/product-feedback.js +134 -0
- package/scripts/profile-router.js +245 -0
- package/scripts/prompt-dlp.js +221 -0
- package/scripts/prompt-guard.js +83 -0
- package/scripts/prove-adapters.js +863 -0
- package/scripts/prove-attribution.js +365 -0
- package/scripts/prove-automation.js +653 -0
- package/scripts/prove-autoresearch.js +304 -0
- package/scripts/prove-claim-verification.js +277 -0
- package/scripts/prove-cloudflare-sandbox.js +163 -0
- package/scripts/prove-data-pipeline.js +410 -0
- package/scripts/prove-data-quality.js +227 -0
- package/scripts/prove-evolution.js +352 -0
- package/scripts/prove-harnesses.js +287 -0
- package/scripts/prove-intelligence.js +259 -0
- package/scripts/prove-lancedb.js +371 -0
- package/scripts/prove-local-intelligence.js +342 -0
- package/scripts/prove-loop-closure.js +263 -0
- package/scripts/prove-predictive-insights.js +357 -0
- package/scripts/prove-runtime.js +350 -0
- package/scripts/prove-seo-gsd.js +234 -0
- package/scripts/prove-settings.js +279 -0
- package/scripts/prove-subway-upgrades.js +277 -0
- package/scripts/prove-tessl.js +229 -0
- package/scripts/prove-training-export.js +327 -0
- package/scripts/prove-workflow-contract.js +116 -0
- package/scripts/prove-xmemory.js +332 -0
- package/scripts/publish-decision.js +133 -0
- package/scripts/pulse.js +80 -0
- package/scripts/rate-limiter.js +125 -0
- package/scripts/reddit-dm-outreach.js +182 -0
- package/scripts/reddit-monitor-cron.sh +26 -0
- package/scripts/reflector-agent.js +221 -0
- package/scripts/reminder-engine.js +132 -0
- package/scripts/revenue-status.js +472 -0
- package/scripts/risk-scorer.js +458 -0
- package/scripts/rlaif-self-audit.js +129 -0
- package/scripts/rubric-engine.js +230 -0
- package/scripts/schedule-manager.js +251 -0
- package/scripts/secret-scanner.js +414 -0
- package/scripts/self-heal.js +147 -0
- package/scripts/self-healing-check.js +188 -0
- package/scripts/semantic-layer.js +98 -0
- package/scripts/seo-gsd.js +1153 -0
- package/scripts/settings-hierarchy.js +214 -0
- package/scripts/shieldcortex-memory-firewall-runner.mjs +53 -0
- package/scripts/skill-exporter.js +262 -0
- package/scripts/skill-generator.js +446 -0
- package/scripts/skill-materializer.js +134 -0
- package/scripts/skill-packs.js +136 -0
- package/scripts/skill-proposer.js +99 -0
- package/scripts/skill-quality-tracker.js +284 -0
- package/scripts/slo-alert-engine.js +14 -0
- package/scripts/slow-loop.js +72 -0
- package/scripts/social-analytics/db/schema.sql +32 -0
- package/scripts/social-analytics/digest.js +256 -0
- package/scripts/social-analytics/generate-instagram-card.js +97 -0
- package/scripts/social-analytics/instagram-thumbgate-post.js +73 -0
- package/scripts/social-analytics/mcp-server.js +289 -0
- package/scripts/social-analytics/normalizer.js +580 -0
- package/scripts/social-analytics/notify.js +162 -0
- package/scripts/social-analytics/poll-all.js +107 -0
- package/scripts/social-analytics/pollers/github.js +195 -0
- package/scripts/social-analytics/pollers/instagram.js +253 -0
- package/scripts/social-analytics/pollers/linkedin.js +330 -0
- package/scripts/social-analytics/pollers/plausible.js +247 -0
- package/scripts/social-analytics/pollers/reddit.js +306 -0
- package/scripts/social-analytics/pollers/threads.js +233 -0
- package/scripts/social-analytics/pollers/tiktok.js +203 -0
- package/scripts/social-analytics/pollers/x.js +227 -0
- package/scripts/social-analytics/pollers/youtube.js +304 -0
- package/scripts/social-analytics/pollers/zernio.js +180 -0
- package/scripts/social-analytics/publish-instagram-thumbgate.js +85 -0
- package/scripts/social-analytics/publishers/devto.js +122 -0
- package/scripts/social-analytics/publishers/instagram.js +317 -0
- package/scripts/social-analytics/publishers/linkedin.js +294 -0
- package/scripts/social-analytics/publishers/reddit.js +390 -0
- package/scripts/social-analytics/publishers/threads.js +275 -0
- package/scripts/social-analytics/publishers/tiktok.js +217 -0
- package/scripts/social-analytics/publishers/x.js +259 -0
- package/scripts/social-analytics/publishers/youtube.js +223 -0
- package/scripts/social-analytics/publishers/zernio.js +209 -0
- package/scripts/social-analytics/run-digest.js +34 -0
- package/scripts/social-analytics/store.js +257 -0
- package/scripts/social-analytics/utm.js +143 -0
- package/scripts/social-pipeline.js +2628 -0
- package/scripts/social-quality-gate.js +18 -0
- package/scripts/social-reply-monitor.js +445 -0
- package/scripts/status-dashboard.js +155 -0
- package/scripts/statusline-lesson.js +16 -0
- package/scripts/statusline-tower.js +8 -0
- package/scripts/statusline.sh +116 -0
- package/scripts/stripe-live-status.js +115 -0
- package/scripts/subagent-profiles.js +79 -0
- package/scripts/sync-gh-secrets-from-env.sh +70 -0
- package/scripts/sync-github-about.js +52 -0
- package/scripts/sync-version.js +451 -0
- package/scripts/synthetic-dpo.js +234 -0
- package/scripts/telemetry-analytics.js +821 -0
- package/scripts/tessl-export.js +371 -0
- package/scripts/test-coverage.js +120 -0
- package/scripts/thompson-sampling.js +417 -0
- package/scripts/thumbgate-search.js +189 -0
- package/scripts/tool-kpi-tracker.js +12 -0
- package/scripts/tool-registry.js +811 -0
- package/scripts/train_from_feedback.py +910 -0
- package/scripts/user-profile.js +78 -0
- package/scripts/validate-feedback.js +580 -0
- package/scripts/validate-workflow-contract.js +287 -0
- package/scripts/vector-store.js +198 -0
- package/scripts/verification-loop.js +291 -0
- package/scripts/verify-obsidian-setup.sh +269 -0
- package/scripts/verify-run.js +269 -0
- package/scripts/webhook-delivery.js +62 -0
- package/scripts/weekly-auto-post.js +124 -0
- package/scripts/workflow-runs.js +154 -0
- package/scripts/workflow-sprint-intake.js +475 -0
- package/scripts/workspace-evolver.js +374 -0
- package/scripts/x-autonomous-marketing.js +139 -0
- package/scripts/xmemory-lite.js +405 -0
- package/skills/agent-memory/SKILL.md +97 -0
- package/skills/solve-architecture-autonomy/SKILL.md +17 -0
- package/skills/solve-architecture-autonomy/tool.js +33 -0
- package/skills/thumbgate/SKILL.md +114 -0
- package/skills/thumbgate-feedback/SKILL.md +49 -0
- 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>
|