thumbgate 1.4.2 → 1.4.4
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 +45 -34
- package/.claude-plugin/marketplace.json +3 -3
- package/.claude-plugin/plugin.json +3 -3
- package/.well-known/llms.txt +1 -1
- package/.well-known/mcp/server-card.json +1 -1
- package/README.md +26 -2
- package/adapters/README.md +4 -1
- package/adapters/claude/.mcp.json +2 -2
- package/adapters/codex/config.toml +2 -2
- package/adapters/mcp/server-stdio.js +10 -4
- package/adapters/opencode/opencode.json +1 -1
- package/bin/cli.js +246 -90
- package/config/mcp-allowlists.json +11 -3
- package/package.json +184 -21
- package/scripts/audit-trail.js +25 -15
- package/scripts/auto-wire-hooks.js +127 -0
- package/scripts/cli-demo.js +102 -0
- package/scripts/cli-schema.js +285 -0
- package/scripts/cli-status.js +166 -0
- package/scripts/cross-encoder-reranker.js +235 -0
- package/scripts/explore-subcommands.js +277 -0
- package/scripts/explore.js +569 -0
- package/scripts/feedback-loop.js +20 -6
- package/scripts/lesson-inference.js +7 -1
- package/scripts/lesson-reranker.js +263 -0
- package/scripts/lesson-retrieval.js +34 -17
- package/scripts/lesson-search.js +69 -0
- package/scripts/perplexity-client.js +210 -0
- package/scripts/reflector-agent.js +2 -2
- package/scripts/statusline-local-stats.js +3 -1
- package/scripts/statusline.sh +12 -11
- package/src/api/server.js +178 -17
- package/src/index.js +3 -0
- package/.claude-plugin/bundle/icon.png +0 -0
- package/.claude-plugin/bundle/icon.svg +0 -18
- package/.claude-plugin/bundle/server/index.js +0 -24
- package/adapters/chatgpt/INSTALL.md +0 -138
- package/bin/memory.sh +0 -64
- package/bin/obsidian-sync.sh +0 -20
- package/plugins/amp-skill/INSTALL.md +0 -52
- package/plugins/amp-skill/SKILL.md +0 -64
- package/plugins/claude-codex-bridge/.claude-plugin/plugin.json +0 -22
- package/plugins/claude-codex-bridge/.mcp.json +0 -14
- package/plugins/claude-codex-bridge/INSTALL.md +0 -43
- package/plugins/claude-codex-bridge/README.md +0 -46
- package/plugins/claude-codex-bridge/scripts/codex-bridge.js +0 -286
- package/plugins/claude-codex-bridge/skills/adversarial-review/SKILL.md +0 -24
- package/plugins/claude-codex-bridge/skills/result/SKILL.md +0 -22
- package/plugins/claude-codex-bridge/skills/review/SKILL.md +0 -28
- package/plugins/claude-codex-bridge/skills/second-pass/SKILL.md +0 -27
- package/plugins/claude-codex-bridge/skills/setup/SKILL.md +0 -21
- package/plugins/claude-codex-bridge/skills/status/SKILL.md +0 -19
- package/plugins/claude-skill/INSTALL.md +0 -55
- package/plugins/claude-skill/SKILL.md +0 -46
- package/plugins/codex-profile/.codex-plugin/plugin.json +0 -43
- package/plugins/codex-profile/.mcp.json +0 -14
- package/plugins/codex-profile/AGENTS.md +0 -20
- package/plugins/codex-profile/INSTALL.md +0 -89
- package/plugins/codex-profile/README.md +0 -61
- package/plugins/cursor-marketplace/.cursor-plugin/plugin.json +0 -23
- package/plugins/cursor-marketplace/CHANGELOG.md +0 -30
- package/plugins/cursor-marketplace/LICENSE +0 -21
- package/plugins/cursor-marketplace/README.md +0 -124
- package/plugins/cursor-marketplace/agents/reliability-reviewer.md +0 -31
- package/plugins/cursor-marketplace/assets/logo-400x400.png +0 -0
- package/plugins/cursor-marketplace/commands/capture-feedback.md +0 -33
- package/plugins/cursor-marketplace/commands/check-gates.md +0 -25
- package/plugins/cursor-marketplace/commands/show-lessons.md +0 -27
- package/plugins/cursor-marketplace/hooks/hooks.json +0 -10
- package/plugins/cursor-marketplace/mcp.json +0 -14
- package/plugins/cursor-marketplace/rules/feedback-capture.mdc +0 -34
- package/plugins/cursor-marketplace/rules/pre-action-gates.mdc +0 -30
- package/plugins/cursor-marketplace/rules/session-continuity.mdc +0 -28
- package/plugins/cursor-marketplace/scripts/gate-check.sh +0 -21
- package/plugins/cursor-marketplace/skills/capture-feedback/SKILL.md +0 -48
- package/plugins/cursor-marketplace/skills/prevention-rules/SKILL.md +0 -31
- package/plugins/cursor-marketplace/skills/recall-context/SKILL.md +0 -30
- package/plugins/cursor-marketplace/skills/search-lessons/SKILL.md +0 -33
- package/plugins/gemini-extension/INSTALL.md +0 -92
- package/plugins/gemini-extension/gemini_prompt.txt +0 -14
- package/plugins/gemini-extension/tool_contract.json +0 -45
- package/plugins/opencode-profile/INSTALL.md +0 -57
- package/public/assets/instagram-card.png +0 -0
- package/public/assets/tiktok-agent-memory.mp4 +0 -0
- package/public/blog.html +0 -474
- package/public/compare/mem0.html +0 -189
- package/public/compare/speclock.html +0 -180
- package/public/compare.html +0 -310
- package/public/dashboard.html +0 -1100
- package/public/guide.html +0 -317
- package/public/guides/claude-code-prevent-repeated-mistakes.html +0 -161
- package/public/guides/codex-cli-guardrails.html +0 -158
- package/public/guides/cursor-prevent-repeated-mistakes.html +0 -161
- package/public/guides/pre-action-gates.html +0 -162
- package/public/guides/stop-repeated-ai-agent-mistakes.html +0 -159
- package/public/index.html +0 -1128
- package/public/js/buyer-intent.js +0 -252
- package/public/learn/agent-harness-pattern.html +0 -180
- package/public/learn/ai-agent-persistent-memory.html +0 -203
- package/public/learn/learn.css +0 -45
- package/public/learn/mcp-pre-action-gates-explained.html +0 -172
- package/public/learn/stop-ai-agent-force-push.html +0 -134
- package/public/learn/vibe-coding-safety-net.html +0 -142
- package/public/learn.html +0 -274
- package/public/lessons.html +0 -967
- package/public/llm-context.md +0 -140
- package/public/pro.html +0 -1087
- package/public/vercel.json +0 -8
- package/scripts/a2ui-engine.js +0 -73
- package/scripts/adk-consolidator.js +0 -274
- package/scripts/agent-security-hardening.js +0 -225
- package/scripts/ai-search-visibility.js +0 -142
- package/scripts/autonomous-sales-agent.js +0 -39
- package/scripts/autoresearch-runner.js +0 -216
- package/scripts/background-agent-governance.js +0 -229
- package/scripts/behavioral-extraction.js +0 -93
- package/scripts/budget-enforcer.js +0 -173
- package/scripts/budget-guard.js +0 -173
- package/scripts/build-claude-mcpb.js +0 -255
- package/scripts/build-codex-plugin.js +0 -152
- package/scripts/capture-railway-diagnostics.sh +0 -97
- package/scripts/changeset-check.js +0 -372
- package/scripts/check-congruence.js +0 -443
- package/scripts/computer-use-firewall.js +0 -280
- package/scripts/content-engine/linkedin-content-generator.js +0 -154
- package/scripts/content-engine/output/linkedin-memento-validation.md +0 -17
- package/scripts/content-engine/output/linkedin-posts-2026-04-09.md +0 -175
- package/scripts/content-engine/reddit-thread-finder.js +0 -154
- package/scripts/context-engine.js +0 -710
- package/scripts/daily-digest.js +0 -11
- package/scripts/data-governance.js +0 -173
- package/scripts/deploy-gcp.sh +0 -44
- package/scripts/deploy-policy.js +0 -249
- package/scripts/disagreement-mining.js +0 -315
- package/scripts/dpo-optimizer.js +0 -206
- package/scripts/ensure-repo-bootstrap.js +0 -130
- package/scripts/ephemeral-agent-store.js +0 -212
- package/scripts/eval-harness.js +0 -56
- package/scripts/export-kto-pairs.js +0 -309
- package/scripts/export-training.js +0 -446
- package/scripts/feedback-fallback.js +0 -111
- package/scripts/feedback-inbox-read.js +0 -162
- package/scripts/feedback-root-consolidator.js +0 -233
- package/scripts/feedback-to-memory.js +0 -185
- package/scripts/gate-satisfy.js +0 -42
- package/scripts/generate-paperbanana-diagrams.sh +0 -99
- package/scripts/generate-pretool-hook.sh +0 -40
- package/scripts/github-about.js +0 -430
- package/scripts/github-outreach.js +0 -65
- package/scripts/gtm-revenue-loop.js +0 -535
- package/scripts/hallucination-detector.js +0 -226
- package/scripts/hf-papers.js +0 -317
- package/scripts/hook-auto-capture.sh +0 -100
- package/scripts/hook-stop-pr-thread-check.sh +0 -68
- package/scripts/hook-stop-self-score.sh +0 -51
- package/scripts/hook-stop-verify-deploy.sh +0 -31
- package/scripts/hook-verify-before-done.sh +0 -20
- package/scripts/managed-dpo-export.js +0 -91
- package/scripts/markdown-escape.js +0 -12
- package/scripts/marketing-experiment.js +0 -657
- package/scripts/memalign-recall.js +0 -111
- package/scripts/memory-migration.js +0 -296
- package/scripts/meta-policy.js +0 -190
- package/scripts/metered-billing.js +0 -16
- package/scripts/model-tier-router.js +0 -310
- package/scripts/money-watcher.js +0 -218
- package/scripts/multi-hop-recall.js +0 -240
- package/scripts/per-step-scoring.js +0 -163
- package/scripts/perplexity-marketing.js +0 -466
- package/scripts/pii-scanner.js +0 -153
- package/scripts/plan-gate.js +0 -154
- package/scripts/post-everywhere.js +0 -341
- package/scripts/post-to-x-retry.sh +0 -22
- package/scripts/post-to-x.js +0 -369
- package/scripts/pr-manager.js +0 -421
- package/scripts/principle-extractor.js +0 -162
- package/scripts/pro-features.js +0 -41
- package/scripts/prompt-dlp.js +0 -222
- package/scripts/prove-adapters.js +0 -860
- package/scripts/prove-attribution.js +0 -361
- package/scripts/prove-automation.js +0 -651
- package/scripts/prove-autoresearch.js +0 -304
- package/scripts/prove-claim-verification.js +0 -277
- package/scripts/prove-cloudflare-sandbox.js +0 -161
- package/scripts/prove-data-pipeline.js +0 -408
- package/scripts/prove-data-quality.js +0 -227
- package/scripts/prove-evolution.js +0 -352
- package/scripts/prove-harnesses.js +0 -287
- package/scripts/prove-intelligence.js +0 -257
- package/scripts/prove-lancedb.js +0 -425
- package/scripts/prove-local-intelligence.js +0 -340
- package/scripts/prove-loop-closure.js +0 -263
- package/scripts/prove-packaged-runtime.js +0 -326
- package/scripts/prove-predictive-insights.js +0 -355
- package/scripts/prove-runtime.js +0 -363
- package/scripts/prove-seo-gsd.js +0 -234
- package/scripts/prove-settings.js +0 -279
- package/scripts/prove-subway-upgrades.js +0 -277
- package/scripts/prove-tessl.js +0 -229
- package/scripts/prove-training-export.js +0 -325
- package/scripts/prove-workflow-contract.js +0 -112
- package/scripts/prove-xmemory.js +0 -332
- package/scripts/publish-decision.js +0 -159
- package/scripts/ralph-loop.js +0 -376
- package/scripts/ralph-mode-ci.js +0 -331
- package/scripts/reddit-dm-outreach.js +0 -192
- package/scripts/reddit-monitor-cron.sh +0 -26
- package/scripts/reminder-engine.js +0 -132
- package/scripts/revenue-status.js +0 -472
- package/scripts/rotate-stripe-webhook-secret.js +0 -314
- package/scripts/schedule-manager.js +0 -249
- package/scripts/self-healing-check.js +0 -193
- package/scripts/shieldcortex-memory-firewall-runner.mjs +0 -53
- package/scripts/skill-exporter.js +0 -260
- package/scripts/skill-materializer.js +0 -134
- package/scripts/skill-packs.js +0 -136
- package/scripts/skill-proposer.js +0 -99
- package/scripts/skill-quality-tracker.js +0 -282
- package/scripts/slow-loop.js +0 -72
- package/scripts/social-analytics/db/analytics.sqlite +0 -0
- package/scripts/social-analytics/db/schema.sql +0 -32
- package/scripts/social-analytics/digest.js +0 -256
- package/scripts/social-analytics/engagement-audit.js +0 -185
- package/scripts/social-analytics/generate-instagram-card.js +0 -97
- package/scripts/social-analytics/instagram-thumbgate-post.js +0 -111
- package/scripts/social-analytics/install-growth-automation.js +0 -114
- package/scripts/social-analytics/load-env.js +0 -77
- package/scripts/social-analytics/mcp-server.js +0 -289
- package/scripts/social-analytics/normalizer.js +0 -580
- package/scripts/social-analytics/notify.js +0 -162
- package/scripts/social-analytics/poll-all.js +0 -107
- package/scripts/social-analytics/pollers/github.js +0 -195
- package/scripts/social-analytics/pollers/instagram.js +0 -253
- package/scripts/social-analytics/pollers/linkedin.js +0 -340
- package/scripts/social-analytics/pollers/plausible.js +0 -245
- package/scripts/social-analytics/pollers/reddit.js +0 -306
- package/scripts/social-analytics/pollers/threads.js +0 -233
- package/scripts/social-analytics/pollers/tiktok.js +0 -203
- package/scripts/social-analytics/pollers/x.js +0 -227
- package/scripts/social-analytics/pollers/youtube.js +0 -304
- package/scripts/social-analytics/pollers/zernio.js +0 -183
- package/scripts/social-analytics/publish-instagram-thumbgate.js +0 -104
- package/scripts/social-analytics/publish-thumbgate-launch.js +0 -322
- package/scripts/social-analytics/publishers/devto.js +0 -122
- package/scripts/social-analytics/publishers/instagram.js +0 -317
- package/scripts/social-analytics/publishers/linkedin.js +0 -294
- package/scripts/social-analytics/publishers/reddit.js +0 -385
- package/scripts/social-analytics/publishers/threads.js +0 -275
- package/scripts/social-analytics/publishers/tiktok.js +0 -217
- package/scripts/social-analytics/publishers/x.js +0 -259
- package/scripts/social-analytics/publishers/youtube.js +0 -223
- package/scripts/social-analytics/publishers/zernio.js +0 -539
- package/scripts/social-analytics/reconcile-thumbgate-campaign.js +0 -165
- package/scripts/social-analytics/run-digest.js +0 -34
- package/scripts/social-analytics/schedule-thumbgate-campaign.js +0 -275
- package/scripts/social-analytics/store.js +0 -455
- package/scripts/social-analytics/sync-launch-assets.js +0 -185
- package/scripts/social-analytics/utm.js +0 -143
- package/scripts/social-pipeline.js +0 -2626
- package/scripts/social-post-hourly.js +0 -228
- package/scripts/social-quality-gate.js +0 -134
- package/scripts/social-reply-monitor.js +0 -592
- package/scripts/status-dashboard.js +0 -155
- package/scripts/stripe-live-status.js +0 -115
- package/scripts/subagent-profiles.js +0 -79
- package/scripts/sync-branch-protection.js +0 -340
- package/scripts/sync-gh-secrets-from-env.sh +0 -70
- package/scripts/sync-github-about.js +0 -55
- package/scripts/sync-version.js +0 -479
- package/scripts/synthetic-dpo.js +0 -234
- package/scripts/tessl-export.js +0 -369
- package/scripts/test-coverage.js +0 -128
- package/scripts/thumbgate_session_start.sh +0 -32
- package/scripts/train_from_feedback.py +0 -929
- package/scripts/validate-feedback.js +0 -581
- package/scripts/verify-obsidian-setup.sh +0 -269
- package/scripts/verify-run.js +0 -269
- package/scripts/weekly-auto-post.js +0 -124
- package/scripts/x-autonomous-marketing.js +0 -139
package/scripts/statusline.sh
CHANGED
|
@@ -146,31 +146,32 @@ case "${TREND}" in
|
|
|
146
146
|
improving) ARROW="↗" ;; degrading) ARROW="↘" ;; stable) ARROW="→" ;; *) ARROW="?" ;;
|
|
147
147
|
esac
|
|
148
148
|
|
|
149
|
-
|
|
149
|
+
# OSC 8 hyperlink: \e]8;;URL\a LABEL \e]8;;\a
|
|
150
|
+
# Falls back to plain label when URL is empty or localhost.
|
|
151
|
+
osc_link() {
|
|
150
152
|
local url="$1"
|
|
151
153
|
local label="$2"
|
|
152
|
-
|
|
153
|
-
printf '%s
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
154
|
+
case "$url" in
|
|
155
|
+
*localhost*|*127.0.0.1*|"") printf '%s' "$label" ;;
|
|
156
|
+
*) printf '\033]8;;%s\007%s\033]8;;\007' "$url" "$label" ;;
|
|
157
|
+
esac
|
|
158
|
+
return 0
|
|
157
159
|
}
|
|
158
160
|
|
|
159
161
|
UP_ICON="👍"
|
|
160
162
|
DOWN_ICON="👎"
|
|
161
|
-
DASHBOARD_LINK="$DASHBOARD_LABEL"
|
|
162
|
-
LESSONS_LINK="$LESSONS_LABEL"
|
|
163
|
+
DASHBOARD_LINK="$(osc_link "$DASHBOARD_URL" "$DASHBOARD_LABEL")"
|
|
164
|
+
LESSONS_LINK="$(osc_link "$LESSONS_URL" "$LESSONS_LABEL")"
|
|
163
165
|
LATEST_LESSON_LINK=""
|
|
164
166
|
if [ -n "$LESSON_LABEL" ]; then
|
|
165
|
-
# Only include link if it's a real URL (not localhost)
|
|
166
167
|
_DISPLAY_LINK="$LESSON_LINK"
|
|
167
168
|
case "$_DISPLAY_LINK" in
|
|
168
169
|
*localhost*|*127.0.0.1*) _DISPLAY_LINK="" ;;
|
|
169
170
|
esac
|
|
170
171
|
if [ -n "$LESSON_TEXT" ]; then
|
|
171
|
-
LATEST_LESSON_LINK="$(
|
|
172
|
+
LATEST_LESSON_LINK="$(osc_link "$_DISPLAY_LINK" "${LESSON_LABEL}: ${LESSON_TEXT}")"
|
|
172
173
|
else
|
|
173
|
-
LATEST_LESSON_LINK="$(
|
|
174
|
+
LATEST_LESSON_LINK="$(osc_link "$_DISPLAY_LINK" "$LESSON_LABEL")"
|
|
174
175
|
fi
|
|
175
176
|
fi
|
|
176
177
|
|
package/src/api/server.js
CHANGED
|
@@ -5,6 +5,37 @@ const fs = require('fs');
|
|
|
5
5
|
const path = require('path');
|
|
6
6
|
const pkg = require('../../package.json');
|
|
7
7
|
|
|
8
|
+
const POSTHOG_API_PATHS = new Set(['/capture', '/batch', '/decide', '/e', '/engage']);
|
|
9
|
+
const POSTHOG_INGEST_HOST = 'us.i.posthog.com';
|
|
10
|
+
const POSTHOG_STATIC_PATH_PREFIX = '/static/';
|
|
11
|
+
|
|
12
|
+
function getPosthogProxyPath(pathname) {
|
|
13
|
+
return pathname.slice('/ingest'.length) || '/';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function isExactOrChildPath(pathname, basePath) {
|
|
17
|
+
return pathname === basePath || pathname.startsWith(`${basePath}/`);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function isAllowedPosthogProxyPath(pathname) {
|
|
21
|
+
if (pathname === '/') return true;
|
|
22
|
+
if (pathname.startsWith(POSTHOG_STATIC_PATH_PREFIX)) return true;
|
|
23
|
+
return Array.from(POSTHOG_API_PATHS).some((basePath) => isExactOrChildPath(pathname, basePath));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function buildPosthogProxyRequestOptions(req, posthogPath, search) {
|
|
27
|
+
return {
|
|
28
|
+
protocol: 'https:',
|
|
29
|
+
hostname: POSTHOG_INGEST_HOST,
|
|
30
|
+
path: `${posthogPath}${search || ''}`,
|
|
31
|
+
method: req.method,
|
|
32
|
+
headers: {
|
|
33
|
+
...req.headers,
|
|
34
|
+
host: POSTHOG_INGEST_HOST,
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
8
39
|
const {
|
|
9
40
|
captureFeedback,
|
|
10
41
|
analyzeFeedback,
|
|
@@ -1032,38 +1063,131 @@ function loadProPageHtml(runtimeConfig, pageContext = {}) {
|
|
|
1032
1063
|
return loadPublicMarketingTemplateHtml(PRO_PAGE_PATH, runtimeConfig, pageContext);
|
|
1033
1064
|
}
|
|
1034
1065
|
|
|
1035
|
-
function
|
|
1036
|
-
|
|
1066
|
+
function readOptionalPublicTemplate(filePath) {
|
|
1067
|
+
try {
|
|
1068
|
+
return fs.readFileSync(filePath, 'utf-8');
|
|
1069
|
+
} catch (error) {
|
|
1070
|
+
if (error?.code === 'ENOENT') return null;
|
|
1071
|
+
throw error;
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
function resolveLocalPageBootstrap(req, expectedApiKey) {
|
|
1037
1076
|
const forwardedHost = req.headers['x-forwarded-host'];
|
|
1038
1077
|
const hostHeader = Array.isArray(forwardedHost)
|
|
1039
1078
|
? forwardedHost[0]
|
|
1040
1079
|
: forwardedHost || req.headers.host || '';
|
|
1041
1080
|
const localProBootstrap = process.env.THUMBGATE_PRO_MODE === '1' && Boolean(expectedApiKey) && isLoopbackHost(hostHeader);
|
|
1042
|
-
// Developer override: auth is disabled (expectedApiKey===null), auto-connect with dummy key
|
|
1043
1081
|
const devOverride = expectedApiKey === null && isLoopbackHost(hostHeader);
|
|
1044
1082
|
const bootstrapActive = localProBootstrap || devOverride;
|
|
1045
1083
|
const serializedBootstrapKey = JSON.stringify(localProBootstrap ? expectedApiKey : devOverride ? 'dev-override' : '').replace(/</g, '\\u003c');
|
|
1046
1084
|
|
|
1085
|
+
return {
|
|
1086
|
+
bootstrapActive,
|
|
1087
|
+
serializedBootstrapKey,
|
|
1088
|
+
};
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
function renderPackagedDashboardHtml({ bootstrapActive, serializedBootstrapKey }) {
|
|
1092
|
+
return `<!doctype html>
|
|
1093
|
+
<html lang="en">
|
|
1094
|
+
<head>
|
|
1095
|
+
<meta charset="utf-8">
|
|
1096
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
1097
|
+
<title>ThumbGate Dashboard</title>
|
|
1098
|
+
<style>
|
|
1099
|
+
:root { color-scheme: light dark; --bg:#0f172a; --panel:#111827; --text:#f8fafc; --muted:#94a3b8; --line:#334155; --accent:#22c55e; }
|
|
1100
|
+
body { margin:0; font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; background:linear-gradient(135deg,#020617,#111827); color:var(--text); }
|
|
1101
|
+
main { max-width:920px; margin:0 auto; padding:48px 20px; }
|
|
1102
|
+
.panel { border:1px solid var(--line); border-radius:20px; background:rgba(15,23,42,.86); padding:28px; box-shadow:0 24px 80px rgba(0,0,0,.32); }
|
|
1103
|
+
.eyebrow { color:var(--accent); font-size:13px; font-weight:700; letter-spacing:.12em; text-transform:uppercase; }
|
|
1104
|
+
h1 { font-size:clamp(32px,5vw,54px); line-height:1; margin:14px 0; }
|
|
1105
|
+
p { color:var(--muted); font-size:18px; line-height:1.6; }
|
|
1106
|
+
.grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(220px,1fr)); gap:14px; margin-top:26px; }
|
|
1107
|
+
a { color:var(--text); text-decoration:none; }
|
|
1108
|
+
.card { display:block; border:1px solid var(--line); border-radius:16px; padding:18px; background:rgba(30,41,59,.7); }
|
|
1109
|
+
.card strong { display:block; margin-bottom:8px; }
|
|
1110
|
+
.card span { color:var(--muted); font-size:14px; line-height:1.5; }
|
|
1111
|
+
</style>
|
|
1112
|
+
<script>
|
|
1113
|
+
window.THUMBGATE_DASHBOARD_BOOTSTRAP = { enabled: ${bootstrapActive ? 'true' : 'false'}, apiKey: ${serializedBootstrapKey} };
|
|
1114
|
+
</script>
|
|
1115
|
+
</head>
|
|
1116
|
+
<body>
|
|
1117
|
+
<main>
|
|
1118
|
+
<section class="panel">
|
|
1119
|
+
<div class="eyebrow">Packaged runtime</div>
|
|
1120
|
+
<h1>ThumbGate is running locally.</h1>
|
|
1121
|
+
<p>This lightweight npm dashboard is bundled without marketing assets, so installs stay small while core feedback, lessons, and API routes remain available.</p>
|
|
1122
|
+
<div class="grid">
|
|
1123
|
+
<a class="card" href="/v1/dashboard"><strong>Dashboard JSON</strong><span>Inspect feedback totals, lesson counts, and Reliability Gateway health.</span></a>
|
|
1124
|
+
<a class="card" href="/lessons"><strong>Lessons</strong><span>Review remembered thumbs-up/down lessons and enforcement context.</span></a>
|
|
1125
|
+
<a class="card" href="/health"><strong>Health</strong><span>Verify the installed package version and runtime status.</span></a>
|
|
1126
|
+
</div>
|
|
1127
|
+
</section>
|
|
1128
|
+
</main>
|
|
1129
|
+
</body>
|
|
1130
|
+
</html>`;
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
function renderPackagedLessonsHtml({ bootstrapActive, serializedBootstrapKey }) {
|
|
1134
|
+
return `<!doctype html>
|
|
1135
|
+
<html lang="en">
|
|
1136
|
+
<head>
|
|
1137
|
+
<meta charset="utf-8">
|
|
1138
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
1139
|
+
<title>ThumbGate Lessons</title>
|
|
1140
|
+
<style>
|
|
1141
|
+
:root { color-scheme: light dark; --bg:#0f172a; --panel:#111827; --text:#f8fafc; --muted:#94a3b8; --line:#334155; --accent:#38bdf8; }
|
|
1142
|
+
body { margin:0; font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; background:linear-gradient(135deg,#020617,#0f172a); color:var(--text); }
|
|
1143
|
+
main { max-width:920px; margin:0 auto; padding:48px 20px; }
|
|
1144
|
+
.panel { border:1px solid var(--line); border-radius:20px; background:rgba(15,23,42,.86); padding:28px; box-shadow:0 24px 80px rgba(0,0,0,.32); }
|
|
1145
|
+
.eyebrow { color:var(--accent); font-size:13px; font-weight:700; letter-spacing:.12em; text-transform:uppercase; }
|
|
1146
|
+
h1 { font-size:clamp(32px,5vw,54px); line-height:1; margin:14px 0; }
|
|
1147
|
+
p { color:var(--muted); font-size:18px; line-height:1.6; }
|
|
1148
|
+
.actions { display:flex; flex-wrap:wrap; gap:12px; margin-top:26px; }
|
|
1149
|
+
a { color:var(--text); text-decoration:none; border:1px solid var(--line); border-radius:999px; padding:12px 16px; background:rgba(30,41,59,.7); }
|
|
1150
|
+
</style>
|
|
1151
|
+
<script>
|
|
1152
|
+
window.THUMBGATE_LESSONS_BOOTSTRAP = { enabled: ${bootstrapActive ? 'true' : 'false'}, apiKey: ${serializedBootstrapKey} };
|
|
1153
|
+
</script>
|
|
1154
|
+
</head>
|
|
1155
|
+
<body>
|
|
1156
|
+
<main>
|
|
1157
|
+
<section class="panel">
|
|
1158
|
+
<div class="eyebrow">Packaged runtime</div>
|
|
1159
|
+
<h1>ThumbGate lessons are available.</h1>
|
|
1160
|
+
<p>The full hosted lessons UI is excluded from the npm tarball, but installed packages still expose the lesson APIs and detail pages needed for local agent feedback loops.</p>
|
|
1161
|
+
<div class="actions">
|
|
1162
|
+
<a href="/v1/lessons/search">Search lessons JSON</a>
|
|
1163
|
+
<a href="/v1/feedback/stats">Feedback stats JSON</a>
|
|
1164
|
+
<a href="/dashboard">Back to dashboard</a>
|
|
1165
|
+
</div>
|
|
1166
|
+
</section>
|
|
1167
|
+
</main>
|
|
1168
|
+
</body>
|
|
1169
|
+
</html>`;
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
function loadDashboardPageHtml(req, expectedApiKey) {
|
|
1173
|
+
const bootstrap = resolveLocalPageBootstrap(req, expectedApiKey);
|
|
1174
|
+
const template = readOptionalPublicTemplate(DASHBOARD_PAGE_PATH);
|
|
1175
|
+
if (!template) return renderPackagedDashboardHtml(bootstrap);
|
|
1176
|
+
|
|
1047
1177
|
return fillTemplate(template, {
|
|
1048
|
-
'__DASHBOARD_BOOTSTRAP_KEY__': serializedBootstrapKey,
|
|
1049
|
-
'__DASHBOARD_BOOTSTRAP_ENABLED__': bootstrapActive ? 'true' : 'false',
|
|
1178
|
+
'__DASHBOARD_BOOTSTRAP_KEY__': bootstrap.serializedBootstrapKey,
|
|
1179
|
+
'__DASHBOARD_BOOTSTRAP_ENABLED__': bootstrap.bootstrapActive ? 'true' : 'false',
|
|
1050
1180
|
});
|
|
1051
1181
|
}
|
|
1052
1182
|
|
|
1053
1183
|
function loadLessonsPageHtml(req, expectedApiKey) {
|
|
1054
|
-
const
|
|
1055
|
-
const
|
|
1056
|
-
|
|
1057
|
-
? forwardedHost[0]
|
|
1058
|
-
: forwardedHost || req.headers.host || '';
|
|
1059
|
-
const localProBootstrap = process.env.THUMBGATE_PRO_MODE === '1' && Boolean(expectedApiKey) && isLoopbackHost(hostHeader);
|
|
1060
|
-
const devOverride = expectedApiKey === null && isLoopbackHost(hostHeader);
|
|
1061
|
-
const bootstrapActive = localProBootstrap || devOverride;
|
|
1062
|
-
const serializedBootstrapKey = JSON.stringify(localProBootstrap ? expectedApiKey : devOverride ? 'dev-override' : '').replace(/</g, '\\u003c');
|
|
1184
|
+
const bootstrap = resolveLocalPageBootstrap(req, expectedApiKey);
|
|
1185
|
+
const template = readOptionalPublicTemplate(LESSONS_PAGE_PATH);
|
|
1186
|
+
if (!template) return renderPackagedLessonsHtml(bootstrap);
|
|
1063
1187
|
|
|
1064
1188
|
return fillTemplate(template, {
|
|
1065
|
-
'__LESSONS_BOOTSTRAP_KEY__': serializedBootstrapKey,
|
|
1066
|
-
'__LESSONS_BOOTSTRAP_ENABLED__': bootstrapActive ? 'true' : 'false',
|
|
1189
|
+
'__LESSONS_BOOTSTRAP_KEY__': bootstrap.serializedBootstrapKey,
|
|
1190
|
+
'__LESSONS_BOOTSTRAP_ENABLED__': bootstrap.bootstrapActive ? 'true' : 'false',
|
|
1067
1191
|
});
|
|
1068
1192
|
}
|
|
1069
1193
|
|
|
@@ -2354,6 +2478,29 @@ function createApiServer() {
|
|
|
2354
2478
|
const requestFeedbackDir = requestFeedbackPaths.FEEDBACK_DIR;
|
|
2355
2479
|
const requestSafeDataDir = getSafeDataDir(req, parsed);
|
|
2356
2480
|
|
|
2481
|
+
// PostHog reverse proxy -- bypasses ad blockers.
|
|
2482
|
+
// Only allow known PostHog API paths to prevent SSRF (CodeQL js/request-forgery).
|
|
2483
|
+
if (pathname.startsWith('/ingest')) {
|
|
2484
|
+
const posthogPath = getPosthogProxyPath(pathname);
|
|
2485
|
+
if (!isAllowedPosthogProxyPath(posthogPath)) {
|
|
2486
|
+
res.writeHead(403, { 'Content-Type': 'text/plain' });
|
|
2487
|
+
res.end('Forbidden');
|
|
2488
|
+
return;
|
|
2489
|
+
}
|
|
2490
|
+
let body = '';
|
|
2491
|
+
req.on('data', chunk => { body += chunk; });
|
|
2492
|
+
req.on('end', () => {
|
|
2493
|
+
const proxyReq = https.request(buildPosthogProxyRequestOptions(req, posthogPath, parsed.search), (proxyRes) => {
|
|
2494
|
+
res.writeHead(proxyRes.statusCode, proxyRes.headers);
|
|
2495
|
+
proxyRes.pipe(res);
|
|
2496
|
+
});
|
|
2497
|
+
proxyReq.on('error', () => { res.writeHead(502); res.end(); });
|
|
2498
|
+
if (body) proxyReq.write(body);
|
|
2499
|
+
proxyReq.end();
|
|
2500
|
+
});
|
|
2501
|
+
return;
|
|
2502
|
+
}
|
|
2503
|
+
|
|
2357
2504
|
// Public MCP endpoint — responds to Smithery registry scanning and MCP initialize
|
|
2358
2505
|
// The initialize handshake is unauthenticated; subsequent tool calls require Bearer auth
|
|
2359
2506
|
if (pathname === '/mcp') {
|
|
@@ -3770,7 +3917,14 @@ async function addContext(){
|
|
|
3770
3917
|
return;
|
|
3771
3918
|
}
|
|
3772
3919
|
|
|
3773
|
-
|
|
3920
|
+
// Operator key is allowed to bypass the general admin gate for its dedicated endpoint
|
|
3921
|
+
const _reqToken = extractApiKey(req);
|
|
3922
|
+
const isOperatorBillingRequest = Boolean(expectedOperatorKey)
|
|
3923
|
+
&& _reqToken === expectedOperatorKey
|
|
3924
|
+
&& req.method === 'GET'
|
|
3925
|
+
&& pathname === '/v1/billing/summary';
|
|
3926
|
+
|
|
3927
|
+
if (!isOperatorBillingRequest && !isAuthorized(req, expectedApiKey)) {
|
|
3774
3928
|
sendProblem(res, {
|
|
3775
3929
|
type: PROBLEM_TYPES.UNAUTHORIZED,
|
|
3776
3930
|
title: 'Unauthorized',
|
|
@@ -5014,7 +5168,14 @@ module.exports = {
|
|
|
5014
5168
|
startServer,
|
|
5015
5169
|
__test__: {
|
|
5016
5170
|
buildCheckoutFallbackUrl,
|
|
5171
|
+
buildPosthogProxyRequestOptions,
|
|
5172
|
+
getPosthogProxyPath,
|
|
5173
|
+
isAllowedPosthogProxyPath,
|
|
5017
5174
|
renderSitemapXml,
|
|
5175
|
+
renderPackagedDashboardHtml,
|
|
5176
|
+
renderPackagedLessonsHtml,
|
|
5177
|
+
readOptionalPublicTemplate,
|
|
5178
|
+
resolveLocalPageBootstrap,
|
|
5018
5179
|
},
|
|
5019
5180
|
};
|
|
5020
5181
|
|
package/src/index.js
ADDED
|
Binary file
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" role="img" aria-labelledby="title desc">
|
|
2
|
-
<title>ThumbGate</title>
|
|
3
|
-
<desc>Gateway icon for the Claude Desktop workflow hardening extension.</desc>
|
|
4
|
-
<defs>
|
|
5
|
-
<linearGradient id="bg" x1="0%" x2="100%" y1="0%" y2="100%">
|
|
6
|
-
<stop offset="0%" stop-color="#111827"/>
|
|
7
|
-
<stop offset="100%" stop-color="#1f2937"/>
|
|
8
|
-
</linearGradient>
|
|
9
|
-
<linearGradient id="gate" x1="0%" x2="100%" y1="0%" y2="100%">
|
|
10
|
-
<stop offset="0%" stop-color="#f97316"/>
|
|
11
|
-
<stop offset="100%" stop-color="#fb7185"/>
|
|
12
|
-
</linearGradient>
|
|
13
|
-
</defs>
|
|
14
|
-
<rect width="512" height="512" rx="96" fill="url(#bg)"/>
|
|
15
|
-
<path fill="url(#gate)" d="M152 128h208c17.7 0 32 14.3 32 32v64h-64v-32H184v128h144v-32h64v64c0 17.7-14.3 32-32 32H152c-17.7 0-32-14.3-32-32V160c0-17.7 14.3-32 32-32Z"/>
|
|
16
|
-
<path fill="#fff4ed" d="M248 180h96v48h-48v56h48v48h-96z"/>
|
|
17
|
-
<circle cx="196" cy="256" r="26" fill="#fef3c7"/>
|
|
18
|
-
</svg>
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
const path = require('path');
|
|
5
|
-
const { spawn } = require('child_process');
|
|
6
|
-
|
|
7
|
-
const cliPath = path.join(__dirname, '..', '..', 'bin', 'cli.js');
|
|
8
|
-
const child = spawn(process.execPath, [cliPath, 'serve'], {
|
|
9
|
-
stdio: 'inherit',
|
|
10
|
-
env: process.env,
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
child.on('exit', (code, signal) => {
|
|
14
|
-
if (signal) {
|
|
15
|
-
process.kill(process.pid, signal);
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
18
|
-
process.exit(code ?? 1);
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
child.on('error', (error) => {
|
|
22
|
-
console.error(`[thumbgate] Failed to launch Claude Desktop bundle runtime: ${error.message}`);
|
|
23
|
-
process.exit(1);
|
|
24
|
-
});
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
# ChatGPT GPT Actions: ThumbGate Install
|
|
2
|
-
|
|
3
|
-
Use the published ThumbGate GPT from GPT Store when it is visible for your account, or import the OpenAPI spec into a Custom GPT in under 5 minutes. Regular users use it by replying with 👍/👎 or "thumbs up/down" on ChatGPT answers so ThumbGate remembers lessons, prevents repeated bad answers, and reinforces the answers that worked.
|
|
4
|
-
|
|
5
|
-
## GPT Store path
|
|
6
|
-
|
|
7
|
-
1. Open ChatGPT.
|
|
8
|
-
2. Open **Explore GPTs**.
|
|
9
|
-
3. Search for `ThumbGate`.
|
|
10
|
-
4. Choose the GPT by **Igor Ganapolsky** in the **Programming** category.
|
|
11
|
-
|
|
12
|
-
Direct store URL status: published by the operator on April 13, 2026, but the public `chatgpt.com/g/...` URL has not been captured in this repo yet. Do not invent a URL; add it here once the share link is available.
|
|
13
|
-
|
|
14
|
-
## 30-second regular-user flow
|
|
15
|
-
|
|
16
|
-
1. Ask the ThumbGate GPT any normal question.
|
|
17
|
-
2. If the answer helped, reply with `👍` plus one sentence about what worked.
|
|
18
|
-
3. If the answer missed, reply with `👎` plus one sentence about what to change.
|
|
19
|
-
4. Ask `What do you remember about how I like answers?` to verify the saved lessons.
|
|
20
|
-
|
|
21
|
-
The user should never need to know what MCP, OpenAPI, Actions, DPO, or prevention rules mean. The GPT should explain the loop as: "Reply 👍 or 👎. I remember the lesson for next time."
|
|
22
|
-
|
|
23
|
-
## Regular-user prompts
|
|
24
|
-
|
|
25
|
-
Use these as GPT conversation starters so regular users know how to teach ThumbGate:
|
|
26
|
-
|
|
27
|
-
1. `👎 this answer was too vague. Next time give me exact steps.`
|
|
28
|
-
2. `👍 this format worked. Remember to answer with short numbered steps.`
|
|
29
|
-
3. `Thumbs down: you assumed I know technical terms. Next time explain it for a beginner first.`
|
|
30
|
-
4. `Remember this lesson: I prefer direct answers with examples before theory.`
|
|
31
|
-
5. `Search my ThumbGate lessons before answering this.`
|
|
32
|
-
|
|
33
|
-
Use typed chat replies. ChatGPT's native feedback buttons may send feedback to OpenAI, but they should not be described as the ThumbGate capture path unless OpenAI exposes them to GPT Actions.
|
|
34
|
-
|
|
35
|
-
## Pre-action gate flow
|
|
36
|
-
|
|
37
|
-
Use this when the user asks whether an AI agent should run a proposed action, command, file edit, deployment, merge, or publish step:
|
|
38
|
-
|
|
39
|
-
1. The GPT calls `evaluateDecision` (`POST /v1/decisions/evaluate`) before answering.
|
|
40
|
-
2. If the response has `decisionControl.executionMode: "blocked"`, the GPT says the action is blocked and explains the returned reason.
|
|
41
|
-
3. If the response has `decisionControl.executionMode: "checkpoint_required"`, the GPT asks for explicit confirmation before proceeding.
|
|
42
|
-
4. If the response has `decisionControl.executionMode: "auto_execute"`, the GPT can say the action is allowed and summarize why.
|
|
43
|
-
|
|
44
|
-
Plain thumbs-up/down feedback is the memory loop. The decision endpoint is the gate loop. Do not claim hard blocking unless the decision endpoint, a saved lesson, or a prevention rule was actually applied.
|
|
45
|
-
|
|
46
|
-
## Best first GPT message
|
|
47
|
-
|
|
48
|
-
Use this as the first response for regular users:
|
|
49
|
-
|
|
50
|
-
```text
|
|
51
|
-
Ask me anything. After my answer, reply 👍 if it helped or 👎 plus one sentence if it missed. I will remember the lesson, avoid repeating bad answer patterns, and reuse the formats you like.
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
## Prerequisites
|
|
55
|
-
|
|
56
|
-
- A ChatGPT Plus or Team account (Custom GPTs require a paid plan)
|
|
57
|
-
- ThumbGate API running at `https://thumbgate-production.up.railway.app`
|
|
58
|
-
- Privacy policy URL: `https://thumbgate-production.up.railway.app/privacy`
|
|
59
|
-
- Owner-managed `THUMBGATE_API_KEY` for one-time GPT Builder Actions auth
|
|
60
|
-
|
|
61
|
-
Regular GPT users should not need an API key, JSON payload, OpenAPI knowledge, or developer setup. They should only see the thumbs-up/down memory loop.
|
|
62
|
-
|
|
63
|
-
## Step 1 — Open GPT Builder
|
|
64
|
-
|
|
65
|
-
1. Go to [https://chat.openai.com/gpts/editor](https://chat.openai.com/gpts/editor)
|
|
66
|
-
2. Click **Create a GPT**
|
|
67
|
-
3. Switch to the **Configure** tab
|
|
68
|
-
|
|
69
|
-
## Step 2 — Add Actions
|
|
70
|
-
|
|
71
|
-
1. Scroll to the **Actions** section
|
|
72
|
-
2. Click **Create new action**
|
|
73
|
-
3. Click **Import from URL** — paste your hosted spec URL:
|
|
74
|
-
```
|
|
75
|
-
https://thumbgate-production.up.railway.app/openapi.yaml
|
|
76
|
-
```
|
|
77
|
-
Or click **Upload file** and select:
|
|
78
|
-
```
|
|
79
|
-
adapters/chatgpt/openapi.yaml
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
## Step 3 — Set Authentication
|
|
83
|
-
|
|
84
|
-
In the Actions panel:
|
|
85
|
-
|
|
86
|
-
1. Select **Authentication type: API Key**
|
|
87
|
-
2. **Auth type**: Bearer
|
|
88
|
-
3. **API Key**: paste your `THUMBGATE_API_KEY` value
|
|
89
|
-
|
|
90
|
-
This is an owner setup field. Do not ask regular GPT users to provide an API key.
|
|
91
|
-
|
|
92
|
-
## Step 4 — Update the Server URL
|
|
93
|
-
|
|
94
|
-
In the imported spec, confirm the `servers.url` points to your deployed API:
|
|
95
|
-
|
|
96
|
-
```yaml
|
|
97
|
-
servers:
|
|
98
|
-
- url: https://thumbgate-production.up.railway.app
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
If you uploaded the file, edit the server URL in the GPT Actions editor.
|
|
102
|
-
|
|
103
|
-
## Step 5 — Verify
|
|
104
|
-
|
|
105
|
-
Click **Test** on the `captureFeedback` action:
|
|
106
|
-
|
|
107
|
-
```json
|
|
108
|
-
{
|
|
109
|
-
"signal": "up",
|
|
110
|
-
"context": "GPT Actions install verified with a successful test call",
|
|
111
|
-
"whatWorked": "The hosted action returned accepted=true and a promoted status"
|
|
112
|
-
}
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
Expected response: `200 OK` with `{ "accepted": true, "status": "promoted" }`.
|
|
116
|
-
|
|
117
|
-
If you only send a bare `thumbs up/down` style payload, expect `422` with `status: "clarification_required"` and a follow-up `prompt`.
|
|
118
|
-
|
|
119
|
-
## Available Actions
|
|
120
|
-
|
|
121
|
-
| Action | Method | Path | Description |
|
|
122
|
-
|---|---|---|---|
|
|
123
|
-
| `captureFeedback` | POST | `/v1/feedback/capture` | Capture up/down signal plus one-line why |
|
|
124
|
-
| `getFeedbackStats` | GET | `/v1/feedback/stats` | Aggregated feedback statistics |
|
|
125
|
-
| `getFeedbackSummary` | GET | `/v1/feedback/summary` | Recent feedback summary |
|
|
126
|
-
| `generatePreventionRules` | POST | `/v1/feedback/rules` | Generate prevention rules |
|
|
127
|
-
| `exportDpoPairs` | POST | `/v1/dpo/export` | Export DPO preference pairs |
|
|
128
|
-
| `listIntentCatalog` | GET | `/v1/intents/catalog` | List available intents |
|
|
129
|
-
| `planIntent` | POST | `/v1/intents/plan` | Generate policy-scoped plan |
|
|
130
|
-
| `constructContextPack` | POST | `/v1/context/construct` | Build context pack |
|
|
131
|
-
|
|
132
|
-
Full spec: `adapters/chatgpt/openapi.yaml`
|
|
133
|
-
|
|
134
|
-
## Troubleshooting
|
|
135
|
-
|
|
136
|
-
- **401 Unauthorized**: Verify `THUMBGATE_API_KEY` is set and matches the Bearer token
|
|
137
|
-
- **Connection refused**: Confirm Railway deployment is live (`curl https://<domain>/health`)
|
|
138
|
-
- **Schema errors**: Ensure you are using the latest `openapi.yaml` (version 1.1.0+)
|
package/bin/memory.sh
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# bin/memory.sh - Layer 3 & 4 & 5 Memory Stack Refresher
|
|
3
|
-
|
|
4
|
-
PRIMER_FILE="primer.md"
|
|
5
|
-
|
|
6
|
-
if [ ! -f "$PRIMER_FILE" ]; then
|
|
7
|
-
echo "Error: $PRIMER_FILE not found."
|
|
8
|
-
exit 1
|
|
9
|
-
fi
|
|
10
|
-
|
|
11
|
-
echo "🤖 [Memory Stack] Refreshing context..."
|
|
12
|
-
|
|
13
|
-
# 1. Behavioral Extraction (Layer 4)
|
|
14
|
-
node scripts/behavioral-extraction.js > /dev/null
|
|
15
|
-
TRAITS_FILE="$(node -e "const path = require('path'); const { resolveFeedbackDir } = require('./scripts/feedback-paths'); process.stdout.write(path.join(resolveFeedbackDir(), 'behavioral-traits.json'));" 2>/dev/null)"
|
|
16
|
-
if [ -z "$TRAITS_FILE" ]; then
|
|
17
|
-
TRAITS_FILE=".thumbgate/behavioral-traits.json"
|
|
18
|
-
fi
|
|
19
|
-
|
|
20
|
-
# 2. Capture git context (Layer 3)
|
|
21
|
-
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
|
|
22
|
-
LAST_COMMITS=$(git log -n 5 --oneline 2>/dev/null || echo "No commits found")
|
|
23
|
-
DIRTY_FILES=$(git status --short 2>/dev/null || echo "")
|
|
24
|
-
|
|
25
|
-
# 3. Rebuild Primer
|
|
26
|
-
TEMP_FILE=$(mktemp)
|
|
27
|
-
|
|
28
|
-
# Read primer until "## Behavioral Traits"
|
|
29
|
-
sed -n '1,/## Behavioral Traits/p' "$PRIMER_FILE" > "$TEMP_FILE"
|
|
30
|
-
echo "" >> "$TEMP_FILE"
|
|
31
|
-
|
|
32
|
-
if [ -f "$TRAITS_FILE" ]; then
|
|
33
|
-
# Extract trait descriptions from JSON
|
|
34
|
-
cat "$TRAITS_FILE" | grep "description" | sed 's/.*: "//;s/".*//' | sed 's/^/- /' >> "$TEMP_FILE"
|
|
35
|
-
else
|
|
36
|
-
echo "_No strong behavioral patterns identified yet._" >> "$TEMP_FILE"
|
|
37
|
-
fi
|
|
38
|
-
|
|
39
|
-
echo "" >> "$TEMP_FILE"
|
|
40
|
-
echo "## Live Git Context" >> "$TEMP_FILE"
|
|
41
|
-
echo "" >> "$TEMP_FILE"
|
|
42
|
-
echo "### Branch: $CURRENT_BRANCH" >> "$TEMP_FILE"
|
|
43
|
-
echo "" >> "$TEMP_FILE"
|
|
44
|
-
echo "### Last 5 Commits:" >> "$TEMP_FILE"
|
|
45
|
-
echo '```' >> "$TEMP_FILE"
|
|
46
|
-
echo "$LAST_COMMITS" >> "$TEMP_FILE"
|
|
47
|
-
echo '```' >> "$TEMP_FILE"
|
|
48
|
-
echo "" >> "$TEMP_FILE"
|
|
49
|
-
echo "### Modified Files:" >> "$TEMP_FILE"
|
|
50
|
-
if [ -z "$DIRTY_FILES" ]; then
|
|
51
|
-
echo "_None (Clean working tree)_" >> "$TEMP_FILE"
|
|
52
|
-
else
|
|
53
|
-
echo '```' >> "$TEMP_FILE"
|
|
54
|
-
echo "$DIRTY_FILES" >> "$TEMP_FILE"
|
|
55
|
-
echo '```' >> "$TEMP_FILE"
|
|
56
|
-
fi
|
|
57
|
-
|
|
58
|
-
mv "$TEMP_FILE" "$PRIMER_FILE"
|
|
59
|
-
|
|
60
|
-
# 4. Sync to Obsidian (Layer 5)
|
|
61
|
-
chmod +x bin/obsidian-sync.sh
|
|
62
|
-
./bin/obsidian-sync.sh
|
|
63
|
-
|
|
64
|
-
echo "✅ Context refresh complete."
|
package/bin/obsidian-sync.sh
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
# obsidian-sync.sh
|
|
4
|
-
#
|
|
5
|
-
# Layer 5: Obsidian Knowledge Bridge
|
|
6
|
-
# Exports ThumbGate data as interlinked Obsidian markdown notes to a vault.
|
|
7
|
-
|
|
8
|
-
VAULT_PATH=$THUMBGATE_OBSIDIAN_VAULT_PATH
|
|
9
|
-
PROJECT_NAME=$(basename "$(pwd)")
|
|
10
|
-
|
|
11
|
-
if [ -z "$VAULT_PATH" ]; then
|
|
12
|
-
echo "🤖 [Layer 5] THUMBGATE_OBSIDIAN_VAULT_PATH not set. Skipping sync."
|
|
13
|
-
exit 0
|
|
14
|
-
fi
|
|
15
|
-
|
|
16
|
-
echo "🤖 [Layer 5] Exporting memories to Obsidian vault: $VAULT_PATH/AI-Memories/$PROJECT_NAME"
|
|
17
|
-
|
|
18
|
-
npx thumbgate obsidian-export --vault-path="$VAULT_PATH" --output-dir="AI-Memories/$PROJECT_NAME"
|
|
19
|
-
|
|
20
|
-
echo "✅ Sync complete."
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
# Amp: ThumbGate Feedback Skill Install
|
|
2
|
-
|
|
3
|
-
Install the ThumbGate skill for Amp in under 60 seconds. No manual file editing required.
|
|
4
|
-
|
|
5
|
-
## One-Command Install
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
cp plugins/amp-skill/SKILL.md .amp/skills/thumbgate-feedback.md
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
Or from the npm package:
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
npx thumbgate init
|
|
15
|
-
cp node_modules/thumbgate/plugins/amp-skill/SKILL.md .amp/skills/thumbgate-feedback.md
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## What This Does
|
|
19
|
-
|
|
20
|
-
Copies the skill definition to `.amp/skills/` so Amp loads it automatically on next launch.
|
|
21
|
-
|
|
22
|
-
## Verify
|
|
23
|
-
|
|
24
|
-
After copying, restart Amp. The skill will appear in the active skills list.
|
|
25
|
-
|
|
26
|
-
Then test:
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
npx thumbgate capture --feedback=up --context="amp skill install verified" --tags="install"
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
## Available Commands (via skill)
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
# Positive feedback
|
|
36
|
-
npx thumbgate capture --feedback=up --context="..." --tags="..."
|
|
37
|
-
|
|
38
|
-
# Negative feedback
|
|
39
|
-
npx thumbgate capture --feedback=down --context="..." --what-went-wrong="..." --what-to-change="..." --tags="..."
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## Requirements
|
|
43
|
-
|
|
44
|
-
- Amp (any version with skills support)
|
|
45
|
-
- Node.js 18+ in PATH
|
|
46
|
-
- `.thumbgate/` directory (created by `npx thumbgate init`)
|
|
47
|
-
|
|
48
|
-
## Uninstall
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
rm .amp/skills/thumbgate-feedback.md
|
|
52
|
-
```
|