thumbgate 0.9.10 → 0.9.12

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 (115) hide show
  1. package/.claude-plugin/README.md +2 -2
  2. package/.claude-plugin/marketplace.json +4 -2
  3. package/.claude-plugin/plugin.json +1 -1
  4. package/.well-known/mcp/server-card.json +1 -1
  5. package/README.md +115 -312
  6. package/adapters/README.md +1 -1
  7. package/adapters/claude/.mcp.json +2 -2
  8. package/adapters/codex/config.toml +4 -4
  9. package/adapters/mcp/server-stdio.js +61 -1
  10. package/adapters/opencode/opencode.json +4 -2
  11. package/bin/cli.js +156 -8
  12. package/bin/memory.sh +3 -3
  13. package/config/e2e-critical-flows.json +4 -0
  14. package/config/gates/default.json +74 -2
  15. package/config/github-about.json +1 -1
  16. package/config/mcp-allowlists.json +27 -0
  17. package/package.json +22 -5
  18. package/plugins/amp-skill/INSTALL.md +1 -0
  19. package/plugins/amp-skill/SKILL.md +1 -0
  20. package/plugins/claude-codex-bridge/.claude-plugin/plugin.json +1 -1
  21. package/plugins/claude-codex-bridge/.mcp.json +4 -2
  22. package/plugins/claude-skill/INSTALL.md +1 -0
  23. package/plugins/codex-profile/.codex-plugin/plugin.json +1 -1
  24. package/plugins/codex-profile/.mcp.json +4 -2
  25. package/plugins/codex-profile/INSTALL.md +1 -1
  26. package/plugins/codex-profile/README.md +1 -1
  27. package/plugins/cursor-marketplace/.cursor-plugin/plugin.json +1 -1
  28. package/plugins/cursor-marketplace/README.md +3 -3
  29. package/plugins/cursor-marketplace/mcp.json +3 -1
  30. package/plugins/cursor-marketplace/scripts/gate-check.sh +15 -5
  31. package/plugins/gemini-extension/INSTALL.md +3 -3
  32. package/plugins/opencode-profile/INSTALL.md +1 -1
  33. package/public/dashboard.html +15 -8
  34. package/public/index.html +125 -185
  35. package/public/js/buyer-intent.js +252 -0
  36. package/public/pro.html +1085 -0
  37. package/scripts/__pycache__/train_from_feedback.cpython-312.pyc +0 -0
  38. package/scripts/adk-consolidator.js +14 -2
  39. package/scripts/agent-readiness.js +3 -1
  40. package/scripts/agent-security-hardening.js +4 -4
  41. package/scripts/auto-promote-gates.js +2 -0
  42. package/scripts/auto-wire-hooks.js +105 -17
  43. package/scripts/behavioral-extraction.js +2 -6
  44. package/scripts/billing.js +107 -3
  45. package/scripts/budget-guard.js +2 -2
  46. package/scripts/build-metadata.js +14 -0
  47. package/scripts/context-engine.js +1 -0
  48. package/scripts/deploy-policy.js +3 -17
  49. package/scripts/dpo-optimizer.js +3 -6
  50. package/scripts/ensure-repo-bootstrap.js +129 -0
  51. package/scripts/export-dpo-pairs.js +2 -3
  52. package/scripts/export-kto-pairs.js +3 -4
  53. package/scripts/export-training.js +8 -6
  54. package/scripts/feedback-attribution.js +23 -11
  55. package/scripts/feedback-loop.js +40 -2
  56. package/scripts/feedback-to-rules.js +2 -1
  57. package/scripts/filesystem-search.js +3 -2
  58. package/scripts/gates-engine.js +760 -29
  59. package/scripts/generate-pretool-hook.sh +0 -0
  60. package/scripts/gtm-revenue-loop.js +20 -1
  61. package/scripts/hook-auto-capture.sh +8 -3
  62. package/scripts/hook-runtime.js +81 -0
  63. package/scripts/hook-stop-self-score.sh +3 -3
  64. package/scripts/hook-thumbgate-cache-updater.js +99 -38
  65. package/scripts/hosted-config.js +4 -16
  66. package/scripts/hybrid-feedback-context.js +54 -14
  67. package/scripts/install-mcp.js +13 -3
  68. package/scripts/intent-router.js +2 -2
  69. package/scripts/license.js +52 -14
  70. package/scripts/local-model-profile.js +3 -2
  71. package/scripts/mcp-config.js +62 -7
  72. package/scripts/meta-policy.js +4 -8
  73. package/scripts/money-watcher.js +166 -16
  74. package/scripts/obsidian-export.js +1 -0
  75. package/scripts/operational-integrity.js +480 -0
  76. package/scripts/post-everywhere.js +35 -12
  77. package/scripts/pr-manager.js +14 -11
  78. package/scripts/profile-router.js +2 -0
  79. package/scripts/prompt-dlp.js +1 -0
  80. package/scripts/publish-decision.js +10 -0
  81. package/scripts/published-cli.js +61 -0
  82. package/scripts/risk-scorer.js +3 -2
  83. package/scripts/rlhf_session_start.sh +32 -0
  84. package/scripts/skill-quality-tracker.js +3 -5
  85. package/scripts/social-analytics/db/social-analytics.db-shm +0 -0
  86. package/scripts/social-analytics/db/social-analytics.db-wal +0 -0
  87. package/scripts/social-analytics/engagement-audit.js +202 -0
  88. package/scripts/social-analytics/instagram-thumbgate-post.js +45 -7
  89. package/scripts/social-analytics/install-growth-automation.js +114 -0
  90. package/scripts/social-analytics/load-env.js +46 -0
  91. package/scripts/social-analytics/poll-all.js +23 -23
  92. package/scripts/social-analytics/pollers/plausible.js +2 -4
  93. package/scripts/social-analytics/pollers/zernio.js +3 -0
  94. package/scripts/social-analytics/publish-instagram-thumbgate.js +22 -3
  95. package/scripts/social-analytics/publish-thumbgate-launch.js +322 -0
  96. package/scripts/social-analytics/publishers/reddit.js +7 -12
  97. package/scripts/social-analytics/publishers/zernio.js +301 -22
  98. package/scripts/social-analytics/reconcile-thumbgate-campaign.js +165 -0
  99. package/scripts/social-analytics/schedule-thumbgate-campaign.js +275 -0
  100. package/scripts/social-analytics/sync-launch-assets.js +185 -0
  101. package/scripts/social-post-hourly.js +185 -0
  102. package/scripts/social-quality-gate.js +119 -3
  103. package/scripts/social-reply-monitor.js +184 -37
  104. package/scripts/statusline-cache-path.js +27 -0
  105. package/scripts/statusline-local-stats.js +16 -0
  106. package/scripts/statusline-meta.js +22 -0
  107. package/scripts/statusline.sh +40 -33
  108. package/scripts/sync-version.js +24 -3
  109. package/scripts/test-coverage.js +21 -13
  110. package/scripts/tool-registry.js +97 -0
  111. package/scripts/train_from_feedback.py +32 -9
  112. package/scripts/validate-feedback.js +3 -2
  113. package/scripts/vector-store.js +2 -3
  114. package/scripts/verify-obsidian-setup.sh +3 -3
  115. package/src/api/server.js +281 -33
@@ -43,10 +43,18 @@ const {
43
43
  evaluateSecretGuard,
44
44
  satisfyCondition,
45
45
  loadStats: loadGateStats,
46
+ setTaskScope,
47
+ setBranchGovernance,
48
+ getScopeState,
49
+ getBranchGovernanceState,
50
+ approveProtectedAction,
46
51
  trackAction,
47
52
  verifyClaimEvidence,
48
53
  registerClaimGate,
49
54
  } = require('../../scripts/gates-engine');
55
+ const {
56
+ evaluateOperationalIntegrity,
57
+ } = require('../../scripts/operational-integrity');
50
58
  const { diagnoseFailure } = require('../../scripts/failure-diagnostics');
51
59
  const {
52
60
  analyzeCodeGraphImpact,
@@ -103,7 +111,7 @@ const {
103
111
  finalizeSession: finalizeFeedbackSession,
104
112
  } = require('../../scripts/feedback-session');
105
113
 
106
- const SERVER_INFO = { name: 'thumbgate-mcp', version: '0.9.10' };
114
+ const SERVER_INFO = { name: 'thumbgate-mcp', version: '0.9.12' };
107
115
  const COMMERCE_CATEGORIES = [
108
116
  'product_recommendation',
109
117
  'brand_compliance',
@@ -519,6 +527,49 @@ async function callToolInner(name, args) {
519
527
  }
520
528
  return toTextResult(result);
521
529
  }
530
+ case 'set_task_scope':
531
+ return toTextResult({
532
+ scope: setTaskScope({
533
+ taskId: args.taskId,
534
+ summary: args.summary,
535
+ allowedPaths: args.allowedPaths,
536
+ protectedPaths: args.protectedPaths,
537
+ repoPath: args.repoPath,
538
+ localOnly: args.localOnly === true,
539
+ clear: args.clear === true,
540
+ }),
541
+ });
542
+ case 'get_scope_state':
543
+ return toTextResult(getScopeState());
544
+ case 'set_branch_governance':
545
+ return toTextResult({
546
+ branchGovernance: setBranchGovernance({
547
+ branchName: args.branchName,
548
+ baseBranch: args.baseBranch,
549
+ prRequired: args.prRequired,
550
+ prNumber: args.prNumber,
551
+ prUrl: args.prUrl,
552
+ queueRequired: args.queueRequired,
553
+ localOnly: args.localOnly === true,
554
+ releaseVersion: args.releaseVersion,
555
+ releaseEvidence: args.releaseEvidence,
556
+ releaseSensitiveGlobs: args.releaseSensitiveGlobs,
557
+ clear: args.clear === true,
558
+ }),
559
+ });
560
+ case 'get_branch_governance':
561
+ return toTextResult(getBranchGovernanceState());
562
+ case 'approve_protected_action':
563
+ return toTextResult({
564
+ approved: true,
565
+ approval: approveProtectedAction({
566
+ pathGlobs: args.pathGlobs,
567
+ reason: args.reason,
568
+ evidence: args.evidence,
569
+ taskId: args.taskId,
570
+ ttlMs: args.ttlMs,
571
+ }),
572
+ });
522
573
  case 'track_action': {
523
574
  const entry = trackAction(args.actionId, args.metadata || {});
524
575
  return toTextResult({
@@ -529,6 +580,15 @@ async function callToolInner(name, args) {
529
580
  }
530
581
  case 'verify_claim':
531
582
  return toTextResult(verifyClaimEvidence(args.claim));
583
+ case 'check_operational_integrity':
584
+ return toTextResult(evaluateOperationalIntegrity({
585
+ repoPath: args.repoPath,
586
+ baseBranch: args.baseBranch,
587
+ command: args.command,
588
+ requirePrForReleaseSensitive: args.requirePrForReleaseSensitive === true,
589
+ requireVersionNotBehindBase: args.requireVersionNotBehindBase === true,
590
+ branchGovernance: getBranchGovernanceState(),
591
+ }));
532
592
  case 'register_claim_gate':
533
593
  return toTextResult(registerClaimGate(args.claimPattern, args.requiredActions, args.message));
534
594
  case 'gate_stats':
@@ -5,8 +5,10 @@
5
5
  "type": "local",
6
6
  "command": [
7
7
  "npx",
8
- "-y",
9
- "thumbgate@0.9.10",
8
+ "--yes",
9
+ "--package",
10
+ "thumbgate@0.9.12",
11
+ "thumbgate",
10
12
  "serve"
11
13
  ],
12
14
  "enabled": true
package/bin/cli.js CHANGED
@@ -6,6 +6,7 @@
6
6
  * npx thumbgate init # scaffold .thumbgate/ config + .mcp.json
7
7
  * npx thumbgate init --wire-hooks # wire hooks only (auto-detect agent)
8
8
  * npx thumbgate init --agent claude-code # scaffold + wire hooks for specific agent
9
+ * npx thumbgate gate-check # PreToolUse hook: pipe tool JSON via stdin, get verdict
9
10
  * npx thumbgate capture # capture feedback
10
11
  * npx thumbgate export-dpo # export DPO training pairs
11
12
  * npx thumbgate export-databricks # export Databricks-ready analytics bundle
@@ -19,9 +20,16 @@
19
20
  const fs = require('fs');
20
21
  const path = require('path');
21
22
  const crypto = require('crypto');
22
- const { execSync } = require('child_process');
23
+ const { execSync, execFileSync } = require('child_process');
23
24
  const { resolveMcpEntry } = require(path.join(__dirname, '..', 'scripts', 'mcp-config'));
24
25
  const { trackEvent } = require(path.join(__dirname, '..', 'scripts', 'cli-telemetry'));
26
+ const {
27
+ cacheUpdateHookCommand,
28
+ preToolHookCommand,
29
+ sessionStartHookCommand,
30
+ statuslineCommand,
31
+ userPromptHookCommand,
32
+ } = require(path.join(__dirname, '..', 'scripts', 'hook-runtime'));
25
33
  const {
26
34
  PRO_MONTHLY_PAYMENT_LINK,
27
35
  PRO_PRICE_LABEL,
@@ -103,14 +111,33 @@ function limitNudge(action) {
103
111
 
104
112
  function parseArgs(argv) {
105
113
  const args = {};
106
- argv.forEach((arg) => {
114
+ argv.forEach((arg, index) => {
107
115
  if (!arg.startsWith('--')) return;
108
116
  const [key, ...rest] = arg.slice(2).split('=');
109
- args[key] = rest.length ? rest.join('=') : true;
117
+ if (rest.length) {
118
+ args[key] = rest.join('=');
119
+ return;
120
+ }
121
+
122
+ const next = argv[index + 1];
123
+ if (next && !next.startsWith('--')) {
124
+ args[key] = next;
125
+ return;
126
+ }
127
+
128
+ args[key] = true;
110
129
  });
111
130
  return args;
112
131
  }
113
132
 
133
+ function readStdinText() {
134
+ try {
135
+ return fs.readFileSync(0, 'utf8');
136
+ } catch {
137
+ return '';
138
+ }
139
+ }
140
+
114
141
  function pkgVersion() {
115
142
  const pkg = JSON.parse(fs.readFileSync(path.join(PKG_ROOT, 'package.json'), 'utf8'));
116
143
  return pkg.version;
@@ -120,7 +147,7 @@ function pkgVersion() {
120
147
 
121
148
  const HOME = process.env.HOME || process.env.USERPROFILE || '';
122
149
  const MCP_SERVER_NAME = 'thumbgate';
123
- const MCP_SERVER_NAMES = ['thumbgate'];
150
+ const MCP_SERVER_NAMES = ['thumbgate', 'mcp-memory-gateway', 'rlhf'];
124
151
 
125
152
  function mcpEntriesMatch(entry, expectedEntry) {
126
153
  return Boolean(
@@ -284,9 +311,16 @@ function setupClaude() {
284
311
  }
285
312
 
286
313
  // Upsert PostToolUse hook for ThumbGate statusline cache updates
287
- const cacheHookCommand = 'node node_modules/thumbgate/scripts/hook-thumbgate-cache-updater.js';
314
+ const cacheHookCommand = cacheUpdateHookCommand();
315
+ const originalPostToolUseCount = (settings.hooks.PostToolUse || []).length;
316
+ settings.hooks.PostToolUse = (settings.hooks.PostToolUse || []).filter(
317
+ (entry) => !(entry.hooks || []).some((h) => h.command && h.command !== cacheHookCommand && /(hook-thumbgate-cache-updater|cache-update\b)/.test(h.command))
318
+ );
319
+ if (settings.hooks.PostToolUse.length !== originalPostToolUseCount) {
320
+ hooksChanged = true;
321
+ }
288
322
  const cacheAlreadyPresent = (settings.hooks.PostToolUse || [])
289
- .some(entry => (entry.hooks || []).some(h => h.command && h.command.includes('hook-thumbgate-cache-updater')));
323
+ .some(entry => (entry.hooks || []).some(h => h.command === cacheHookCommand || (h.command && h.command.includes('cache-update'))));
290
324
 
291
325
  if (!cacheAlreadyPresent) {
292
326
  settings.hooks.PostToolUse = settings.hooks.PostToolUse || [];
@@ -299,8 +333,8 @@ function setupClaude() {
299
333
  }
300
334
 
301
335
  // Upsert statusLine for ThumbGate feedback display
302
- const statuslineScript = path.join('node_modules', 'thumbgate', 'scripts', 'statusline.sh');
303
- if (!settings.statusLine) {
336
+ const statuslineScript = statuslineCommand();
337
+ if (!settings.statusLine || settings.statusLine.command !== statuslineScript) {
304
338
  settings.statusLine = { type: 'command', command: statuslineScript };
305
339
  hooksChanged = true;
306
340
  console.log(' Claude Code: installed ThumbGate status line');
@@ -1135,6 +1169,75 @@ function install() {
1135
1169
  }
1136
1170
  }
1137
1171
 
1172
+ async function gateCheck() {
1173
+ const payload = readStdinText();
1174
+ const input = payload ? JSON.parse(payload) : {};
1175
+ const gatesEngine = require(path.join(PKG_ROOT, 'scripts', 'gates-engine'));
1176
+ const output = await gatesEngine.runAsync(input);
1177
+ process.stdout.write(output + '\n');
1178
+ }
1179
+
1180
+ function cacheUpdate() {
1181
+ const payload = readStdinText();
1182
+ const { updateCacheFromEvent } = require(path.join(PKG_ROOT, 'scripts', 'hook-thumbgate-cache-updater'));
1183
+ updateCacheFromEvent(payload ? JSON.parse(payload) : {});
1184
+ }
1185
+
1186
+ function statuslineRender() {
1187
+ const payload = readStdinText();
1188
+ const output = execFileSync('bash', [path.join(PKG_ROOT, 'scripts', 'statusline.sh')], {
1189
+ encoding: 'utf8',
1190
+ input: payload,
1191
+ env: process.env,
1192
+ });
1193
+ process.stdout.write(output);
1194
+ }
1195
+
1196
+ function hookAutoCapture() {
1197
+ const prompt = process.env.CLAUDE_USER_PROMPT || process.env.THUMBGATE_USER_PROMPT || readStdinText().trim();
1198
+ const { evaluatePromptGuard } = require(path.join(PKG_ROOT, 'scripts', 'prompt-guard'));
1199
+ const { processInlineFeedback, formatCliOutput } = require(path.join(PKG_ROOT, 'scripts', 'cli-feedback'));
1200
+ const { recordConversationEntry, readRecentConversationWindow } = require(path.join(PKG_ROOT, 'scripts', 'feedback-history-distiller'));
1201
+
1202
+ recordConversationEntry({
1203
+ author: 'user',
1204
+ text: prompt,
1205
+ source: 'claude_user_prompt',
1206
+ });
1207
+
1208
+ const guardResult = evaluatePromptGuard(prompt);
1209
+ if (guardResult) {
1210
+ process.stdout.write(`${JSON.stringify(guardResult)}\n`);
1211
+ return;
1212
+ }
1213
+
1214
+ const lower = prompt.toLowerCase();
1215
+ const isUp = /(thumbs?\s*up|that worked|looks good|nice work|perfect|good job)/i.test(lower);
1216
+ const isDown = /(thumbs?\s*down|that failed|that was wrong|fix this)/i.test(lower);
1217
+ if (!isUp && !isDown) {
1218
+ return;
1219
+ }
1220
+
1221
+ const signal = isDown ? 'down' : 'up';
1222
+ const conversationWindow = readRecentConversationWindow({ limit: 8 });
1223
+ const result = processInlineFeedback({
1224
+ signal,
1225
+ context: prompt,
1226
+ chatHistory: signal === 'down'
1227
+ ? conversationWindow.map((entry) => ({ role: entry.author === 'assistant' ? 'assistant' : 'user', content: entry.text || '' }))
1228
+ : undefined,
1229
+ whatWentWrong: signal === 'down' ? prompt : undefined,
1230
+ whatWorked: signal === 'up' ? prompt : undefined,
1231
+ });
1232
+ process.stdout.write(formatCliOutput(result) + '\n');
1233
+ }
1234
+
1235
+ function sessionStart() {
1236
+ const { analyzeFeedback } = require(path.join(PKG_ROOT, 'scripts', 'feedback-loop'));
1237
+ const { refreshStatuslineCache } = require(path.join(PKG_ROOT, 'scripts', 'hook-thumbgate-cache-updater'));
1238
+ refreshStatuslineCache(analyzeFeedback());
1239
+ }
1240
+
1138
1241
  function installMcp() {
1139
1242
  const { installMcp: doInstall, parseFlags } = require(path.join(PKG_ROOT, 'scripts', 'install-mcp'));
1140
1243
  const flags = parseFlags(process.argv.slice(3));
@@ -1187,6 +1290,11 @@ function help() {
1187
1290
  console.log(' --dry-run Preview hook changes without writing');
1188
1291
  console.log(' install-mcp Install ThumbGate MCP server into Claude Code settings (--project for local)');
1189
1292
  console.log(' serve Start MCP server (stdio) — for claude/codex/gemini mcp add');
1293
+ console.log(' gate-check Internal: evaluate a PreToolUse payload from stdin');
1294
+ console.log(' cache-update Internal: refresh the Claude statusline cache from stdin');
1295
+ console.log(' statusline-render Internal: render the ThumbGate Claude status line');
1296
+ console.log(' hook-auto-capture Internal: process Claude UserPromptSubmit feedback');
1297
+ console.log(' session-start Internal: refresh local ThumbGate session cache');
1190
1298
  console.log(' capture [flags] Capture feedback (--feedback=up|down --context="..." --tags="...")');
1191
1299
  console.log(' stats Show feedback analytics + Revenue-at-Risk');
1192
1300
  console.log(' cfo Show hosted billing summary when configured, else local fallback JSON');
@@ -1217,6 +1325,7 @@ function help() {
1217
1325
  console.log(' funnel Show marketing & revenue conversion funnel analytics');
1218
1326
  console.log(' pulse Show real-time GTM velocity and Mission Control summary');
1219
1327
  console.log(' dispatch Dispatch-safe brief — metrics, gates, and read-only prompt templates');
1328
+ console.log(' gate-check PreToolUse hook: reads tool JSON from stdin, outputs gate verdict');
1220
1329
  console.log(' gate-stats Show gate statistics — active gates, blocks, warns, time saved');
1221
1330
  console.log(' analytics Unified ThumbGate analytics snapshot (npm, GitHub, landing page)');
1222
1331
  console.log(' start-api Start the ThumbGate HTTPS API server');
@@ -1256,6 +1365,24 @@ switch (COMMAND) {
1256
1365
  case 'mcp':
1257
1366
  serve();
1258
1367
  break;
1368
+ case 'gate-check':
1369
+ gateCheck().catch((err) => {
1370
+ console.error(err && err.message ? err.message : err);
1371
+ process.exit(1);
1372
+ });
1373
+ break;
1374
+ case 'cache-update':
1375
+ cacheUpdate();
1376
+ break;
1377
+ case 'statusline-render':
1378
+ statuslineRender();
1379
+ break;
1380
+ case 'hook-auto-capture':
1381
+ hookAutoCapture();
1382
+ break;
1383
+ case 'session-start':
1384
+ sessionStart();
1385
+ break;
1259
1386
  case 'capture':
1260
1387
  case 'feedback':
1261
1388
  capture();
@@ -1421,6 +1548,27 @@ switch (COMMAND) {
1421
1548
  case 'dispatch-brief':
1422
1549
  dispatchBrief();
1423
1550
  break;
1551
+ case 'gate-check': {
1552
+ // PreToolUse hook interface: reads tool call JSON from stdin, outputs gate verdict
1553
+ // Used by: generate-pretool-hook.sh → npx thumbgate gate-check
1554
+ const { run: gateRun, runAsync: gateRunAsync } = require(path.join(PKG_ROOT, 'scripts', 'gates-engine'));
1555
+ let stdinData = '';
1556
+ process.stdin.setEncoding('utf8');
1557
+ process.stdin.on('data', (chunk) => { stdinData += chunk; });
1558
+ process.stdin.on('end', async () => {
1559
+ try {
1560
+ const input = JSON.parse(stdinData);
1561
+ const output = await gateRunAsync(input);
1562
+ process.stdout.write(output + '\n');
1563
+ process.exit(0);
1564
+ } catch (err) {
1565
+ process.stderr.write(`gate-check error: ${err.message}\n`);
1566
+ process.stdout.write(JSON.stringify({}) + '\n');
1567
+ process.exit(0);
1568
+ }
1569
+ });
1570
+ break;
1571
+ }
1424
1572
  case 'gate-stats':
1425
1573
  gateStats();
1426
1574
  break;
package/bin/memory.sh CHANGED
@@ -12,9 +12,9 @@ echo "🤖 [Memory Stack] Refreshing context..."
12
12
 
13
13
  # 1. Behavioral Extraction (Layer 4)
14
14
  node scripts/behavioral-extraction.js > /dev/null
15
- TRAITS_FILE=".thumbgate/behavioral-traits.json"
16
- if [ ! -f "$TRAITS_FILE" ]; then
17
- TRAITS_FILE=".claude/memory/feedback/behavioral-traits.json"
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
18
  fi
19
19
 
20
20
  # 2. Capture git context (Layer 3)
@@ -21,6 +21,10 @@
21
21
  "id": "rotated_billing_key_survives_dashboard",
22
22
  "title": "E2E: rotated billing key disables the old key and keeps dashboard access alive"
23
23
  },
24
+ {
25
+ "id": "governance_scope_and_approval_http",
26
+ "title": "E2E: governance task scope and protected approvals persist over the HTTP surface"
27
+ },
24
28
  {
25
29
  "id": "history_aware_feedback_distillation",
26
30
  "title": "E2E: vague thumbs-down distills a lesson and preserves linked follow-up context"
@@ -4,10 +4,54 @@
4
4
  {
5
5
  "id": "local-only-git-writes",
6
6
  "layer": "Identity",
7
- "pattern": "^(git\\s+(add|commit|push)|gh\\s+pr\\s+)",
7
+ "pattern": "^(git\\s+(add|commit|push|tag)|gh\\s+pr\\s+|gh\\s+release\\s+create|npm\\s+publish|yarn\\s+publish|pnpm\\s+publish)",
8
8
  "action": "block",
9
9
  "when": { "constraints": { "local_only": true } },
10
- "message": "User requested local-only work. Git writes and PR operations are blocked.",
10
+ "message": "User requested local-only work. Git writes, PR operations, and release actions are blocked.",
11
+ "severity": "critical"
12
+ },
13
+ {
14
+ "id": "task-scope-required",
15
+ "layer": "Decisions",
16
+ "toolNames": ["Bash"],
17
+ "pattern": "^(git\\s+(add|commit|push)|gh\\s+pr\\s+(create|merge)|gh\\s+release\\s+create|git\\s+tag\\b|npm\\s+publish|yarn\\s+publish|pnpm\\s+publish)",
18
+ "requireTaskScope": true,
19
+ "action": "block",
20
+ "message": "Git write, PR, release, and publish operations require an explicit task scope.",
21
+ "severity": "critical"
22
+ },
23
+ {
24
+ "id": "task-scope-edit-boundary",
25
+ "layer": "Decisions",
26
+ "toolNames": ["Edit", "Write", "MultiEdit"],
27
+ "pattern": ".*",
28
+ "requireTaskScope": true,
29
+ "scopeMode": "declared-only",
30
+ "action": "block",
31
+ "message": "Edits outside the declared task scope are blocked once a task scope is active.",
32
+ "severity": "critical"
33
+ },
34
+ {
35
+ "id": "protected-file-approval-required",
36
+ "layer": "Decisions",
37
+ "toolNames": ["Edit", "Write", "MultiEdit", "Bash"],
38
+ "pattern": ".*",
39
+ "requireProtectedApproval": true,
40
+ "protectedGlobs": [
41
+ "AGENTS.md",
42
+ "CLAUDE.md",
43
+ "CLAUDE.local.md",
44
+ "GEMINI.md",
45
+ "README.md",
46
+ ".gitignore",
47
+ ".husky/**",
48
+ ".claude/**",
49
+ "skills/**",
50
+ "SKILL.md",
51
+ "config/gates/**"
52
+ ],
53
+ "action": "block",
54
+ "message": "Protected files require explicit approval before editing or publishing.",
11
55
  "severity": "critical"
12
56
  },
13
57
  {
@@ -28,6 +72,34 @@
28
72
  "message": "PR merging requires explicit 'pr_merge_allowed' satisfaction with evidence of user permission.",
29
73
  "severity": "high"
30
74
  },
75
+ {
76
+ "id": "branch-governance-required",
77
+ "layer": "Decisions",
78
+ "toolNames": ["Bash"],
79
+ "pattern": "^(gh\\s+pr\\s+(create|merge)|gh\\s+release\\s+create|git\\s+tag\\b|npm\\s+publish|yarn\\s+publish|pnpm\\s+publish)",
80
+ "requireBranchGovernance": true,
81
+ "action": "block",
82
+ "message": "PR, release, and publish actions require explicit branch governance.",
83
+ "severity": "critical"
84
+ },
85
+ {
86
+ "id": "release-readiness-required",
87
+ "layer": "Execution",
88
+ "toolNames": ["Bash"],
89
+ "pattern": "^(gh\\s+release\\s+create|git\\s+tag\\b|npm\\s+publish|yarn\\s+publish|pnpm\\s+publish)",
90
+ "requireReleaseReadiness": true,
91
+ "action": "block",
92
+ "message": "Release and publish actions require a releasable mainline commit and a matching version plan.",
93
+ "severity": "critical"
94
+ },
95
+ {
96
+ "id": "admin-merge-bypass-blocked",
97
+ "layer": "Execution",
98
+ "pattern": "gh\\s+pr\\s+merge.*--admin",
99
+ "action": "block",
100
+ "message": "Admin merge bypass is blocked. Use the merge queue or normal protected-branch flow.",
101
+ "severity": "critical"
102
+ },
31
103
  {
32
104
  "id": "loop-abuse-prevention",
33
105
  "layer": "Decisions",
@@ -2,7 +2,7 @@
2
2
  "repo": "IgorGanapolsky/ThumbGate",
3
3
  "repositoryUrl": "https://github.com/IgorGanapolsky/ThumbGate",
4
4
  "homepageUrl": "https://thumbgate-production.up.railway.app",
5
- "description": "Pre-action gates for AI coding agents. Skill disclosure cuts tokens. Hallucination and PII checks harden outputs. 👍 Thumbs up reinforces good behavior. 👎 Thumbs down blocks repeated mistakes. Free is local. History-aware lessons distill vague feedback. Team adds shared lessons and org visibility, plus generated review views.",
5
+ "description": "Pre-action gates for AI coding agents. 👎 Thumbs down prevention rule mistake permanently blocked. 👍 Thumbs up pattern reinforced. History-aware lessons from your corrections. Team adds shared lessons and org visibility.",
6
6
  "topics": [
7
7
  "thumbgate",
8
8
  "pre-action-gates",
@@ -28,8 +28,14 @@
28
28
  "commerce_recall",
29
29
  "generate_skill",
30
30
  "satisfy_gate",
31
+ "set_task_scope",
32
+ "get_scope_state",
33
+ "set_branch_governance",
34
+ "get_branch_governance",
35
+ "approve_protected_action",
31
36
  "track_action",
32
37
  "verify_claim",
38
+ "check_operational_integrity",
33
39
  "register_claim_gate",
34
40
  "gate_stats",
35
41
  "dashboard",
@@ -55,8 +61,14 @@
55
61
  "search_thumbgate",
56
62
  "reflect_on_feedback",
57
63
  "prevention_rules",
64
+ "set_task_scope",
65
+ "get_scope_state",
66
+ "set_branch_governance",
67
+ "get_branch_governance",
68
+ "approve_protected_action",
58
69
  "track_action",
59
70
  "verify_claim",
71
+ "check_operational_integrity",
60
72
  "feedback_stats",
61
73
  "feedback_summary",
62
74
  "estimate_uncertainty",
@@ -68,8 +80,14 @@
68
80
  "retrieve_lessons",
69
81
  "search_thumbgate",
70
82
  "commerce_recall",
83
+ "set_task_scope",
84
+ "get_scope_state",
85
+ "set_branch_governance",
86
+ "get_branch_governance",
87
+ "approve_protected_action",
71
88
  "track_action",
72
89
  "verify_claim",
90
+ "check_operational_integrity",
73
91
  "prevention_rules",
74
92
  "feedback_stats",
75
93
  "feedback_summary"
@@ -88,7 +106,10 @@
88
106
  "start_handoff",
89
107
  "complete_handoff",
90
108
  "context_provenance",
109
+ "get_scope_state",
110
+ "get_branch_governance",
91
111
  "verify_claim",
112
+ "check_operational_integrity",
92
113
  "gate_stats",
93
114
  "dashboard",
94
115
  "settings_status",
@@ -110,7 +131,10 @@
110
131
  "plan_intent",
111
132
  "run_harness",
112
133
  "context_provenance",
134
+ "get_scope_state",
135
+ "get_branch_governance",
113
136
  "verify_claim",
137
+ "check_operational_integrity",
114
138
  "gate_stats",
115
139
  "dashboard",
116
140
  "settings_status",
@@ -128,7 +152,10 @@
128
152
  "list_intents",
129
153
  "plan_intent",
130
154
  "list_harnesses",
155
+ "get_scope_state",
156
+ "get_branch_governance",
131
157
  "verify_claim",
158
+ "check_operational_integrity",
132
159
  "settings_status"
133
160
  ]
134
161
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "thumbgate",
3
- "version": "0.9.10",
4
- "description": "ThumbGate Pre-action gates that block AI coding agents from repeating known mistakes. SQLite+FTS5 lesson DB with corrective-action inference. MemAlign-inspired dual recall (principles + episodic context). Thompson Sampling for adaptive gate sensitivity. LanceDB vector search. Captures feedback, auto-promotes failures into prevention rules, and enforces them via PreToolUse hooks.",
3
+ "version": "0.9.12",
4
+ "description": "ThumbGate \u2014 Make your AI coding agent self-improving. Every mistake becomes a prevention rule that physically blocks the agent from repeating it. Feedback-driven enforcement via PreToolUse hooks, Thompson Sampling for adaptive gates, SQLite+FTS5 lesson DB, and LanceDB vector search. Your agent gets smarter with every session.",
5
5
  "homepage": "https://thumbgate-production.up.railway.app",
6
6
  "repository": {
7
7
  "type": "git",
@@ -66,7 +66,7 @@
66
66
  "social:post-everywhere:dry": "node scripts/post-everywhere.js --dry-run",
67
67
  "social:reply-monitor": "node scripts/social-reply-monitor.js",
68
68
  "social:reply-monitor:dry": "node scripts/social-reply-monitor.js --dry-run",
69
- "test": "npm run test:schema && npm run test:loop && npm run test:dpo && npm run test:kto && npm run test:api && npm run test:proof && npm run test:e2e && npm run test:rlaif && npm run test:attribution && npm run test:quality && npm run test:intelligence && npm run test:training-export && npm run test:deployment && npm run test:workflow && npm run test:billing && npm run test:cli && npm run test:watcher && npm run test:autoresearch && npm run test:ops && npm run test:tessl && npm run test:gates && npm run test:evoskill && npm run test:gates-hardening && npm run test:workers && npm run test:social-analytics && npm run test:memalign && npm run test:xmemory-lite && npm run test:filesystem-search && npm run test:zernio && npm run test:obsidian-export && npm run test:lesson-db && npm run test:lesson-rotation && npm run test:memory-dedup && npm run test:feedback-quality && npm run test:sync-version && npm run test:check-congruence && npm run test:tool-registry && npm run test:feedback-to-rules && npm run test:memory-firewall && npm run test:belief-update && npm run test:hosted-config && npm run test:cloudflare-sandbox && npm run test:mcp-config && npm run test:plan-gate && npm run test:pulse && npm run test:semantic-layer && npm run test:data-pipeline && npm run test:optimize-context && npm run test:principle-extractor && npm run test:analytics-window && npm run test:funnel-analytics && npm run test:experiment-tracker && npm run test:build-metadata && npm run test:context-engine && npm run test:hf-papers && npm run test:marketing-experiment && npm run test:seo-gsd && npm run test:verify-run && npm run test:export-dpo-pairs && npm run test:license && npm run test:bot-detector && npm run test:postinstall && npm run test:funnel-invariants && npm run test:cli-telemetry && npm run test:pro-parity && npm run test:model-tier-router && npm run test:computer-use-firewall && npm run test:skill-exporter && npm run test:statusline && npm run test:evolution && npm run test:org-dashboard && npm run test:multi-hop-recall && npm run test:synthetic-dpo && npm run test:thumbgate-skill && npm run test:learn-hub && npm run test:feedback-fallback && npm run test:metaclaw && npm run test:server-lock && npm run test:control-tower && npm run test:pii-scanner && npm run test:data-governance && npm run test:lesson-inference && npm run test:lesson-retrieval && npm run test:reflector-agent && npm run test:feedback-session && npm run test:feedback-history-distiller && npm run test:hallucination-detector && npm run test:history-distiller && npm run test:predictive-insights && npm run test:prove-predictive-insights && npm run test:statusbar-cli && npm run test:generate-instagram-card && npm run test:instagram-thumbgate-post && npm run test:publish-instagram-thumbgate && npm run test:lesson-synthesis && npm run test:background-governance && npm run test:memory-migration && npm run test:prompt-dlp && npm run test:ephemeral-store && npm run test:agent-security && npm run test:skill-progressive && npm run test:per-step-scoring && npm run test:weekly-auto-post && npm run test:social-quality-gate && npm run test:a2ui-engine && npm run test:gate-satisfy && npm run test:money-watcher && npm run test:utm && npm run test:product-feedback && npm run test:feedback-root-consolidator",
69
+ "test": "npm run test:schema && npm run test:loop && npm run test:dpo && npm run test:kto && npm run test:api && npm run test:proof && npm run test:e2e && npm run test:rlaif && npm run test:attribution && npm run test:quality && npm run test:intelligence && npm run test:training-export && npm run test:deployment && npm run test:operational-integrity && npm run test:workflow && npm run test:billing && npm run test:cli && npm run test:watcher && npm run test:autoresearch && npm run test:ops && npm run test:tessl && npm run test:gates && npm run test:evoskill && npm run test:gates-hardening && npm run test:workers && npm run test:social-analytics && npm run test:memalign && npm run test:xmemory-lite && npm run test:filesystem-search && npm run test:zernio && npm run test:obsidian-export && npm run test:lesson-db && npm run test:lesson-rotation && npm run test:memory-dedup && npm run test:feedback-quality && npm run test:sync-version && npm run test:check-congruence && npm run test:tool-registry && npm run test:feedback-to-rules && npm run test:memory-firewall && npm run test:belief-update && npm run test:hosted-config && npm run test:cloudflare-sandbox && npm run test:mcp-config && npm run test:plan-gate && npm run test:pulse && npm run test:semantic-layer && npm run test:data-pipeline && npm run test:optimize-context && npm run test:principle-extractor && npm run test:analytics-window && npm run test:funnel-analytics && npm run test:experiment-tracker && npm run test:build-metadata && npm run test:context-engine && npm run test:hf-papers && npm run test:marketing-experiment && npm run test:seo-gsd && npm run test:verify-run && npm run test:export-dpo-pairs && npm run test:license && npm run test:bot-detector && npm run test:postinstall && npm run test:funnel-invariants && npm run test:cli-telemetry && npm run test:pro-parity && npm run test:model-tier-router && npm run test:computer-use-firewall && npm run test:skill-exporter && npm run test:statusline && npm run test:evolution && npm run test:org-dashboard && npm run test:multi-hop-recall && npm run test:synthetic-dpo && npm run test:thumbgate-skill && npm run test:learn-hub && npm run test:feedback-fallback && npm run test:metaclaw && npm run test:server-lock && npm run test:control-tower && npm run test:pii-scanner && npm run test:data-governance && npm run test:lesson-inference && npm run test:lesson-retrieval && npm run test:reflector-agent && npm run test:feedback-session && npm run test:feedback-history-distiller && npm run test:hallucination-detector && npm run test:history-distiller && npm run test:predictive-insights && npm run test:prove-predictive-insights && npm run test:statusbar-cli && npm run test:generate-instagram-card && npm run test:instagram-thumbgate-post && npm run test:publish-instagram-thumbgate && npm run test:lesson-synthesis && npm run test:background-governance && npm run test:memory-migration && npm run test:prompt-dlp && npm run test:ephemeral-store && npm run test:agent-security && npm run test:skill-progressive && npm run test:per-step-scoring && npm run test:weekly-auto-post && npm run test:social-quality-gate && npm run test:a2ui-engine && npm run test:gate-satisfy && npm run test:money-watcher && npm run test:utm && npm run test:product-feedback && npm run test:feedback-root-consolidator && npm run test:engagement-audit && npm run test:install-growth-automation && npm run test:publish-thumbgate-launch && npm run test:reconcile-thumbgate-campaign && npm run test:reddit-publisher && npm run test:schedule-thumbgate-campaign && npm run test:social-reply-monitor && npm run test:sync-launch-assets",
70
70
  "test:feedback-fallback": "node --test tests/feedback-fallback.test.js",
71
71
  "test:metaclaw": "node --test tests/metaclaw-features.test.js",
72
72
  "test:server-lock": "node --test tests/server-stdio-lock.test.js",
@@ -115,7 +115,7 @@
115
115
  "test:loop": "node scripts/feedback-loop.js --test",
116
116
  "test:dpo": "node scripts/export-dpo-pairs.js --test",
117
117
  "test:kto": "node --test tests/export-kto.test.js",
118
- "test:api": "node --test --test-concurrency=1 tests/api-server.test.js tests/api-auth-config.test.js tests/mcp-server.test.js tests/adapters.test.js tests/openapi-parity.test.js tests/budget-guard.test.js tests/contextfs.test.js tests/pack-templates.test.js tests/dashboard.test.js tests/dashboard-render-spec.test.js tests/dashboard-html.test.js tests/agent-readiness.test.js tests/mcp-policy.test.js tests/subagent-profiles.test.js tests/intent-router.test.js tests/internal-agent-bootstrap.test.js tests/lesson-search.test.js tests/thumbgate-search.test.js tests/rubric-engine.test.js tests/self-healing-check.test.js tests/self-heal.test.js tests/feedback-schema.test.js tests/thompson-sampling.test.js tests/feedback-sequences.test.js tests/diversity-tracking.test.js tests/vector-store.test.js tests/feedback-attribution.test.js tests/hybrid-feedback-context.test.js tests/loop-closure.test.js tests/code-reasoning.test.js tests/feedback-loop.test.js tests/feedback-inbox-read.test.js tests/feedback-to-memory.test.js tests/test-coverage.test.js tests/version-metadata.test.js tests/claude-mcpb.test.js tests/claude-codex-bridge.test.js tests/cursor-plugin.test.js tests/codex-plugin.test.js tests/telemetry-analytics.test.js tests/public-landing.test.js tests/local-model-profile.test.js tests/risk-scorer.test.js tests/context-compaction.test.js tests/reminder-engine.test.js tests/post-to-x.test.js tests/verification-loop.test.js tests/async-job-runner.test.js tests/commerce-quality.test.js tests/recall-limit.test.js tests/problem-detail.test.js tests/natural-language-harness.test.js tests/settings-hierarchy.test.js",
118
+ "test:api": "node --test --test-concurrency=1 tests/api-server.test.js tests/api-auth-config.test.js tests/mcp-server.test.js tests/adapters.test.js tests/openapi-parity.test.js tests/budget-guard.test.js tests/contextfs.test.js tests/pack-templates.test.js tests/dashboard.test.js tests/dashboard-render-spec.test.js tests/dashboard-html.test.js tests/agent-readiness.test.js tests/mcp-policy.test.js tests/subagent-profiles.test.js tests/intent-router.test.js tests/internal-agent-bootstrap.test.js tests/lesson-search.test.js tests/thumbgate-search.test.js tests/rubric-engine.test.js tests/self-healing-check.test.js tests/self-heal.test.js tests/feedback-schema.test.js tests/thompson-sampling.test.js tests/feedback-sequences.test.js tests/diversity-tracking.test.js tests/vector-store.test.js tests/feedback-attribution.test.js tests/hybrid-feedback-context.test.js tests/loop-closure.test.js tests/code-reasoning.test.js tests/feedback-loop.test.js tests/feedback-inbox-read.test.js tests/feedback-to-memory.test.js tests/test-coverage.test.js tests/version-metadata.test.js tests/claude-mcpb.test.js tests/claude-codex-bridge.test.js tests/cursor-plugin.test.js tests/codex-plugin.test.js tests/telemetry-analytics.test.js tests/public-landing.test.js tests/pro-landing.test.js tests/local-model-profile.test.js tests/risk-scorer.test.js tests/context-compaction.test.js tests/reminder-engine.test.js tests/post-to-x.test.js tests/verification-loop.test.js tests/async-job-runner.test.js tests/commerce-quality.test.js tests/recall-limit.test.js tests/problem-detail.test.js tests/natural-language-harness.test.js tests/settings-hierarchy.test.js",
119
119
  "test:proof": "node --test tests/prove-adapters.test.js tests/prove-attribution.test.js tests/prove-cloudflare-sandbox.test.js tests/prove-data-quality.test.js tests/prove-intelligence.test.js tests/prove-lancedb.test.js tests/prove-loop-closure.test.js tests/prove-subway-upgrades.test.js tests/prove-training-export.test.js tests/prove-local-intelligence.test.js tests/prove-workflow-contract.test.js tests/prove-autoresearch.test.js tests/prove-claim-verification.test.js tests/prove-data-pipeline.test.js tests/prove-evolution.test.js tests/prove-harnesses.test.js tests/prove-runtime.test.js tests/prove-seo-gsd.test.js tests/prove-settings.test.js tests/prove-xmemory.test.js && node --test tests/prove-automation.test.js",
120
120
  "test:e2e": "node --test tests/e2e-pipeline.test.js tests/e2e-product-flows.test.js tests/e2e-coverage-contract.test.js",
121
121
  "test:rlaif": "node --test tests/rlaif-self-audit.test.js tests/dpo-optimizer.test.js tests/meta-policy.test.js",
@@ -124,6 +124,7 @@
124
124
  "test:intelligence": "node --test tests/intelligence.test.js",
125
125
  "test:training-export": "node --test tests/training-export.test.js tests/databricks-export.test.js",
126
126
  "test:deployment": "node --test tests/deployment.test.js tests/deploy-policy.test.js tests/publish-decision.test.js",
127
+ "test:operational-integrity": "node --test tests/operational-integrity.test.js",
127
128
  "test:workflow": "node --test tests/workflow-contract.test.js tests/social-marketing-assets.test.js tests/social-pipeline.test.js tests/positioning-contract.test.js tests/workflow-runs.test.js tests/workflow-sprint-intake.test.js tests/gtm-revenue-loop.test.js",
128
129
  "test:billing": "node --test tests/billing.test.js",
129
130
  "test:cli": "node --test tests/analytics-report.test.js tests/creator-campaigns.test.js tests/cli.test.js tests/codex-bridge-script.test.js tests/dispatch-brief.test.js tests/feedback-normalize.test.js tests/install-mcp.test.js tests/pr-manager.test.js tests/pro-local-dashboard.test.js tests/revenue-status.test.js",
@@ -156,6 +157,8 @@
156
157
  "tessl:export": "node scripts/tessl-export.js export",
157
158
  "tessl:verify": "node scripts/tessl-export.js verify",
158
159
  "deploy:policy": "node scripts/deploy-policy.js",
160
+ "ops:integrity": "node scripts/operational-integrity.js",
161
+ "ops:integrity:ci": "node scripts/operational-integrity.js --ci",
159
162
  "prove:adapters": "node --test tests/prove-adapters.test.js",
160
163
  "prove:automation": "node --test tests/prove-automation.test.js",
161
164
  "prove:workflow-contract": "node --test tests/prove-workflow-contract.test.js",
@@ -217,7 +220,21 @@
217
220
  "test:money-watcher": "node --test tests/money-watcher.test.js",
218
221
  "test:utm": "node --test tests/utm.test.js",
219
222
  "test:product-feedback": "node --test tests/product-feedback.test.js",
220
- "test:feedback-root-consolidator": "node --test tests/feedback-root-consolidator.test.js"
223
+ "test:feedback-root-consolidator": "node --test tests/feedback-root-consolidator.test.js",
224
+ "social:publish:launch": "node scripts/social-analytics/publish-thumbgate-launch.js",
225
+ "social:schedule:campaign": "node scripts/social-analytics/schedule-thumbgate-campaign.js",
226
+ "social:install:growth": "node scripts/social-analytics/install-growth-automation.js",
227
+ "social:reconcile:campaign": "node scripts/social-analytics/reconcile-thumbgate-campaign.js",
228
+ "social:sync:launch-assets": "node scripts/social-analytics/sync-launch-assets.js",
229
+ "social:engagement:audit": "node scripts/social-analytics/engagement-audit.js",
230
+ "test:install-growth-automation": "node --test tests/install-growth-automation.test.js",
231
+ "test:publish-thumbgate-launch": "node --test tests/publish-thumbgate-launch.test.js",
232
+ "test:reconcile-thumbgate-campaign": "node --test tests/reconcile-thumbgate-campaign.test.js",
233
+ "test:schedule-thumbgate-campaign": "node --test tests/schedule-thumbgate-campaign.test.js",
234
+ "test:social-reply-monitor": "node --test tests/social-reply-monitor.test.js",
235
+ "test:sync-launch-assets": "node --test tests/sync-launch-assets.test.js",
236
+ "test:reddit-publisher": "node --test tests/reddit-publisher.test.js",
237
+ "test:engagement-audit": "node --test tests/engagement-audit.test.js"
221
238
  },
222
239
  "keywords": [
223
240
  "mcp",
@@ -13,6 +13,7 @@ Or from the npm package:
13
13
  ```bash
14
14
  npx thumbgate init
15
15
  cp node_modules/thumbgate/plugins/amp-skill/SKILL.md .amp/skills/thumbgate-feedback.md
16
+ cp node_modules/thumbgate/plugins/amp-skill/SKILL.md .amp/skills/rlhf-feedback.md
16
17
  ```
17
18
 
18
19
  ## What This Does