thumbgate 0.9.13 → 0.9.14
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 +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.well-known/mcp/server-card.json +1 -1
- package/README.md +5 -3
- package/adapters/README.md +1 -1
- package/adapters/claude/.mcp.json +2 -2
- package/adapters/codex/config.toml +2 -2
- package/adapters/mcp/server-stdio.js +1 -1
- package/adapters/opencode/opencode.json +1 -1
- package/bin/cli.js +35 -0
- package/package.json +1 -1
- package/plugins/claude-codex-bridge/.claude-plugin/plugin.json +1 -1
- package/plugins/claude-codex-bridge/.mcp.json +1 -1
- package/plugins/codex-profile/.codex-plugin/plugin.json +1 -1
- package/plugins/codex-profile/.mcp.json +1 -1
- package/plugins/codex-profile/INSTALL.md +1 -1
- package/plugins/codex-profile/README.md +1 -1
- package/plugins/cursor-marketplace/.cursor-plugin/plugin.json +1 -1
- package/plugins/opencode-profile/INSTALL.md +1 -1
- package/public/index.html +27 -3
- package/public/learn.html +61 -0
- package/scripts/__pycache__/train_from_feedback.cpython-312.pyc +0 -0
- package/scripts/feedback-history-distiller.js +7 -1
- package/scripts/feedback-loop.js +10 -4
- package/scripts/feedback-paths.js +142 -10
- package/scripts/feedback-root-consolidator.js +18 -4
- package/scripts/post-everywhere.js +10 -0
- package/scripts/seo-gsd.js +217 -4
- package/scripts/statusline-cache-path.js +9 -6
- package/src/api/server.js +107 -26
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "thumbgate",
|
|
3
3
|
"description": "Pre-action gates that block AI coding agents from repeating known mistakes. Captures feedback, auto-promotes failures into prevention rules, and enforces them via PreToolUse hooks.",
|
|
4
|
-
"version": "0.9.
|
|
4
|
+
"version": "0.9.14",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Igor Ganapolsky"
|
|
7
7
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "thumbgate",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.14",
|
|
4
4
|
"description": "ThumbGate — 👍👎 feedback that teaches your AI agent. Thumbs down a mistake, it never happens again.",
|
|
5
5
|
"homepage": "https://github.com/IgorGanapolsky/thumbgate",
|
|
6
6
|
"transport": "stdio",
|
package/README.md
CHANGED
|
@@ -7,7 +7,9 @@ Make your AI coding agent self-improving. One thumbs-down creates a gate that pe
|
|
|
7
7
|
[](LICENSE)
|
|
8
8
|
[](https://thumbgate-production.up.railway.app/checkout/pro?utm_source=github&utm_medium=readme&utm_campaign=badge_cta)
|
|
9
9
|
|
|
10
|
-
**[Pro Page](https://thumbgate-production.up.railway.app/pro?utm_source=github&utm_medium=readme&utm_campaign=pro_page)** · **[Live Dashboard](https://thumbgate-production.up.railway.app/dashboard?utm_source=github&utm_medium=readme&utm_campaign=top_cta)** · **[Pricing](https://thumbgate-production.up.railway.app
|
|
10
|
+
**[Pro Page](https://thumbgate-production.up.railway.app/pro?utm_source=github&utm_medium=readme&utm_campaign=pro_page)** · **[Live Dashboard](https://thumbgate-production.up.railway.app/dashboard?utm_source=github&utm_medium=readme&utm_campaign=top_cta)** · **[Pricing](https://thumbgate-production.up.railway.app/?utm_source=github&utm_medium=readme&utm_campaign=top_cta#pricing)** · **[Setup Guide](https://thumbgate-production.up.railway.app/guide?utm_source=github&utm_medium=readme&utm_campaign=top_cta)**
|
|
11
|
+
|
|
12
|
+
**Popular buyer questions:** **[How to stop repeated AI agent mistakes](https://thumbgate-production.up.railway.app/guides/stop-repeated-ai-agent-mistakes?utm_source=github&utm_medium=readme&utm_campaign=buyer_questions)** · **[Cursor guardrails](https://thumbgate-production.up.railway.app/guides/cursor-agent-guardrails?utm_source=github&utm_medium=readme&utm_campaign=buyer_questions)** · **[Codex CLI guardrails](https://thumbgate-production.up.railway.app/guides/codex-cli-guardrails?utm_source=github&utm_medium=readme&utm_campaign=buyer_questions)** · **[Gemini CLI memory + enforcement](https://thumbgate-production.up.railway.app/guides/gemini-cli-feedback-memory?utm_source=github&utm_medium=readme&utm_campaign=buyer_questions)**
|
|
11
13
|
|
|
12
14
|
### Get Started
|
|
13
15
|
|
|
@@ -15,7 +17,7 @@ Make your AI coding agent self-improving. One thumbs-down creates a gate that pe
|
|
|
15
17
|
|
|
16
18
|
[](https://thumbgate-production.up.railway.app/checkout/pro?utm_source=github&utm_medium=readme&utm_campaign=get_started)
|
|
17
19
|
|
|
18
|
-
Free for individual developers. Pro adds team dashboards, DPO export, and unlimited lesson search. [See pricing →](https://thumbgate-production.up.railway.app
|
|
20
|
+
Free for individual developers. Pro adds team dashboards, DPO export, and unlimited lesson search. [See pricing →](https://thumbgate-production.up.railway.app/?utm_source=github&utm_medium=readme&utm_campaign=pricing_link#pricing)
|
|
19
21
|
|
|
20
22
|
**Paid path for individual operators:** [ThumbGate Pro](https://thumbgate-production.up.railway.app/pro?utm_source=github&utm_medium=readme&utm_campaign=pro_page) is the buyer-ready page for the personal local dashboard, DPO export, and review-ready evidence. It makes the paid upgrade legible before checkout while the self-hosted path below stays optimized for open source evaluation.
|
|
21
23
|
|
|
@@ -142,7 +144,7 @@ Free includes unlimited feedback captures, 5 daily lesson searches, unlimited re
|
|
|
142
144
|
|
|
143
145
|
It does not update model weights. It's context engineering — enforcement that gets smarter every session.
|
|
144
146
|
|
|
145
|
-
**[Get Pro](https://thumbgate-production.up.railway.app/checkout/pro?utm_source=github&utm_medium=readme&utm_campaign=thumbgate)** | **[Start Team Rollout](https://thumbgate-production.up.railway.app
|
|
147
|
+
**[Get Pro](https://thumbgate-production.up.railway.app/checkout/pro?utm_source=github&utm_medium=readme&utm_campaign=thumbgate)** | **[Start Team Rollout](https://thumbgate-production.up.railway.app/?utm_source=github&utm_medium=readme&utm_campaign=team_rollout#workflow-sprint-intake)** | **[Live Dashboard](https://thumbgate-production.up.railway.app/dashboard?utm_source=github&utm_medium=readme&utm_campaign=thumbgate)**
|
|
146
148
|
|
|
147
149
|
## Tech Stack
|
|
148
150
|
|
package/adapters/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
- `chatgpt/openapi.yaml`: import into GPT Actions.
|
|
4
4
|
- `gemini/function-declarations.json`: Gemini function-calling definitions.
|
|
5
5
|
- `mcp/server-stdio.js`: underlying local MCP stdio server implementation.
|
|
6
|
-
- `claude/.mcp.json`: example Claude Code MCP config using `npx --yes --package thumbgate@0.9.
|
|
6
|
+
- `claude/.mcp.json`: example Claude Code MCP config using `npx --yes --package thumbgate@0.9.14 thumbgate serve`.
|
|
7
7
|
- `codex/config.toml`: example Codex MCP profile section using the same version-pinned portable launcher.
|
|
8
8
|
- `amp/skills/thumbgate-feedback/SKILL.md`: Amp skill template.
|
|
9
9
|
- `opencode/opencode.json`: portable OpenCode MCP profile using the same version-pinned portable launcher.
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
"mcpServers": {
|
|
3
3
|
"thumbgate": {
|
|
4
4
|
"command": "npx",
|
|
5
|
-
"args": ["--yes", "--package", "thumbgate@0.9.
|
|
5
|
+
"args": ["--yes", "--package", "thumbgate@0.9.14", "thumbgate", "serve"]
|
|
6
6
|
}
|
|
7
7
|
},
|
|
8
8
|
"hooks": {
|
|
9
9
|
"preToolUse": {
|
|
10
10
|
"command": "npx",
|
|
11
|
-
"args": ["--yes", "--package", "thumbgate@0.9.
|
|
11
|
+
"args": ["--yes", "--package", "thumbgate@0.9.14", "thumbgate", "gate-check"]
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# Codex MCP profile (copy into ~/.codex/config.toml or merge section)
|
|
2
2
|
[mcp_servers.thumbgate]
|
|
3
3
|
command = "npx"
|
|
4
|
-
args = ["--yes", "--package", "thumbgate@0.9.
|
|
4
|
+
args = ["--yes", "--package", "thumbgate@0.9.14", "thumbgate", "serve"]
|
|
5
5
|
|
|
6
6
|
# Hard PreToolUse hook for Codex
|
|
7
7
|
[hooks.pre_tool_use]
|
|
8
8
|
command = "npx"
|
|
9
|
-
args = ["--yes", "--package", "thumbgate@0.9.
|
|
9
|
+
args = ["--yes", "--package", "thumbgate@0.9.14", "thumbgate", "gate-check"]
|
|
@@ -111,7 +111,7 @@ const {
|
|
|
111
111
|
finalizeSession: finalizeFeedbackSession,
|
|
112
112
|
} = require('../../scripts/feedback-session');
|
|
113
113
|
|
|
114
|
-
const SERVER_INFO = { name: 'thumbgate-mcp', version: '0.9.
|
|
114
|
+
const SERVER_INFO = { name: 'thumbgate-mcp', version: '0.9.14' };
|
|
115
115
|
const COMMERCE_CATEGORIES = [
|
|
116
116
|
'product_recommendation',
|
|
117
117
|
'brand_compliance',
|
package/bin/cli.js
CHANGED
|
@@ -63,6 +63,37 @@ function appendLocalTelemetry(payload) {
|
|
|
63
63
|
} catch (_) { /* telemetry is best-effort */ }
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
function syncActiveProjectContext(options = {}) {
|
|
67
|
+
try {
|
|
68
|
+
// Tests and explicitly scoped CLI calls may pin a feedback root directly.
|
|
69
|
+
// In that case, do not inject a project selection that would cause later
|
|
70
|
+
// reads/writes to escape the requested directory.
|
|
71
|
+
if (
|
|
72
|
+
!options.force &&
|
|
73
|
+
process.env.THUMBGATE_FEEDBACK_DIR &&
|
|
74
|
+
!process.env.THUMBGATE_PROJECT_DIR &&
|
|
75
|
+
!process.env.CLAUDE_PROJECT_DIR
|
|
76
|
+
) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
const {
|
|
80
|
+
resolveProjectDir,
|
|
81
|
+
writeActiveProjectState,
|
|
82
|
+
} = require(path.join(PKG_ROOT, 'scripts', 'feedback-paths'));
|
|
83
|
+
const projectDir = resolveProjectDir({
|
|
84
|
+
cwd: CWD,
|
|
85
|
+
env: process.env,
|
|
86
|
+
includeStored: options.includeStored !== false,
|
|
87
|
+
});
|
|
88
|
+
if (!projectDir) return null;
|
|
89
|
+
process.env.THUMBGATE_PROJECT_DIR = projectDir;
|
|
90
|
+
writeActiveProjectState(projectDir, { env: process.env });
|
|
91
|
+
return projectDir;
|
|
92
|
+
} catch (_) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
66
97
|
function telemetryPing(installId) {
|
|
67
98
|
if (process.env.THUMBGATE_NO_TELEMETRY === '1') return;
|
|
68
99
|
const payloadObject = {
|
|
@@ -1178,12 +1209,14 @@ async function gateCheck() {
|
|
|
1178
1209
|
}
|
|
1179
1210
|
|
|
1180
1211
|
function cacheUpdate() {
|
|
1212
|
+
syncActiveProjectContext();
|
|
1181
1213
|
const payload = readStdinText();
|
|
1182
1214
|
const { updateCacheFromEvent } = require(path.join(PKG_ROOT, 'scripts', 'hook-thumbgate-cache-updater'));
|
|
1183
1215
|
updateCacheFromEvent(payload ? JSON.parse(payload) : {});
|
|
1184
1216
|
}
|
|
1185
1217
|
|
|
1186
1218
|
function statuslineRender() {
|
|
1219
|
+
syncActiveProjectContext();
|
|
1187
1220
|
const payload = readStdinText();
|
|
1188
1221
|
const output = execFileSync('bash', [path.join(PKG_ROOT, 'scripts', 'statusline.sh')], {
|
|
1189
1222
|
encoding: 'utf8',
|
|
@@ -1194,6 +1227,7 @@ function statuslineRender() {
|
|
|
1194
1227
|
}
|
|
1195
1228
|
|
|
1196
1229
|
function hookAutoCapture() {
|
|
1230
|
+
syncActiveProjectContext();
|
|
1197
1231
|
const prompt = process.env.CLAUDE_USER_PROMPT || process.env.THUMBGATE_USER_PROMPT || readStdinText().trim();
|
|
1198
1232
|
const { evaluatePromptGuard } = require(path.join(PKG_ROOT, 'scripts', 'prompt-guard'));
|
|
1199
1233
|
const { processInlineFeedback, formatCliOutput } = require(path.join(PKG_ROOT, 'scripts', 'cli-feedback'));
|
|
@@ -1233,6 +1267,7 @@ function hookAutoCapture() {
|
|
|
1233
1267
|
}
|
|
1234
1268
|
|
|
1235
1269
|
function sessionStart() {
|
|
1270
|
+
syncActiveProjectContext();
|
|
1236
1271
|
const { analyzeFeedback } = require(path.join(PKG_ROOT, 'scripts', 'feedback-loop'));
|
|
1237
1272
|
const { refreshStatuslineCache } = require(path.join(PKG_ROOT, 'scripts', 'hook-thumbgate-cache-updater'));
|
|
1238
1273
|
refreshStatuslineCache(analyzeFeedback());
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "thumbgate",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.14",
|
|
4
4
|
"description": "ThumbGate — 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": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codex-bridge",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.14",
|
|
4
4
|
"description": "Run Codex review, adversarial review, and second-pass handoffs from Claude Code while keeping ThumbGate reliability memory in the loop.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Igor Ganapolsky",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codex-profile",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.14",
|
|
4
4
|
"description": "ThumbGate for Codex: pre-action gates, skill packs, hallucination detection, PII scanning, progressive disclosure (82% token savings), and MCP-backed reliability memory.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Igor Ganapolsky",
|
|
@@ -31,7 +31,7 @@ The following block is appended to `~/.codex/config.toml`:
|
|
|
31
31
|
```toml
|
|
32
32
|
[mcp_servers.thumbgate]
|
|
33
33
|
command = "npx"
|
|
34
|
-
args = ["--yes", "--package", "thumbgate@0.9.
|
|
34
|
+
args = ["--yes", "--package", "thumbgate@0.9.14", "thumbgate", "serve"]
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
The repo-local Codex app plugin ships the same runtime path through `plugins/codex-profile/.mcp.json`, so the manual config and plugin metadata stay aligned.
|
|
@@ -29,7 +29,7 @@ That profile launches:
|
|
|
29
29
|
```toml
|
|
30
30
|
[mcp_servers.thumbgate]
|
|
31
31
|
command = "npx"
|
|
32
|
-
args = ["--yes", "--package", "thumbgate@0.9.
|
|
32
|
+
args = ["--yes", "--package", "thumbgate@0.9.14", "thumbgate", "serve"]
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
## Why this exists
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "thumbgate",
|
|
3
3
|
"displayName": "ThumbGate",
|
|
4
4
|
"description": "👍👎 Thumbs down a mistake — your AI agent won't repeat it. Thumbs up good work — it remembers the pattern.",
|
|
5
|
-
"version": "0.9.
|
|
5
|
+
"version": "0.9.14",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Igor Ganapolsky"
|
|
8
8
|
},
|
|
@@ -25,7 +25,7 @@ The portable profile adds this MCP server entry:
|
|
|
25
25
|
"mcp": {
|
|
26
26
|
"thumbgate": {
|
|
27
27
|
"type": "local",
|
|
28
|
-
"command": ["npx", "--yes", "--package", "thumbgate@0.9.
|
|
28
|
+
"command": ["npx", "--yes", "--package", "thumbgate@0.9.14", "thumbgate", "serve"],
|
|
29
29
|
"enabled": true
|
|
30
30
|
}
|
|
31
31
|
}
|
package/public/index.html
CHANGED
|
@@ -520,8 +520,8 @@ __GA_BOOTSTRAP__
|
|
|
520
520
|
|
|
521
521
|
<section class="seo-pages" id="compare-guides">
|
|
522
522
|
<div class="container">
|
|
523
|
-
<div class="section-label">
|
|
524
|
-
<h2 class="section-title">How ThumbGate
|
|
523
|
+
<div class="section-label">Popular Buyer Questions</div>
|
|
524
|
+
<h2 class="section-title">How buyers discover ThumbGate in search and AI answers</h2>
|
|
525
525
|
<div class="seo-grid">
|
|
526
526
|
<a class="seo-card" href="/compare/speclock">
|
|
527
527
|
<div class="seo-kicker">Comparison</div>
|
|
@@ -547,6 +547,30 @@ __GA_BOOTSTRAP__
|
|
|
547
547
|
<p>Why structured feedback memory matters more when it becomes a live gate that blocks your agent from repeating mistakes.</p>
|
|
548
548
|
<div class="card-arrow">Read the integration guide →</div>
|
|
549
549
|
</a>
|
|
550
|
+
<a class="seo-card" href="/guides/stop-repeated-ai-agent-mistakes">
|
|
551
|
+
<div class="seo-kicker">Problem Guide</div>
|
|
552
|
+
<h3>How to Stop AI Agents From Repeating Mistakes</h3>
|
|
553
|
+
<p>The shortest path from “I already corrected this once” to a pre-action gate that blocks the repeat before the next tool call lands.</p>
|
|
554
|
+
<div class="card-arrow">See the fix →</div>
|
|
555
|
+
</a>
|
|
556
|
+
<a class="seo-card" href="/guides/cursor-agent-guardrails">
|
|
557
|
+
<div class="seo-kicker">Cursor</div>
|
|
558
|
+
<h3>Cursor Guardrails That Block Repeat Failures</h3>
|
|
559
|
+
<p>Why Cursor users need more than prompts when the same risky refactor, shell step, or git action keeps coming back.</p>
|
|
560
|
+
<div class="card-arrow">Read the Cursor guide →</div>
|
|
561
|
+
</a>
|
|
562
|
+
<a class="seo-card" href="/guides/codex-cli-guardrails">
|
|
563
|
+
<div class="seo-kicker">Codex</div>
|
|
564
|
+
<h3>Codex CLI Guardrails That Actually Enforce</h3>
|
|
565
|
+
<p>Turn operator feedback into searchable lessons, linked prevention rules, and a runtime stop before Codex repeats the mistake.</p>
|
|
566
|
+
<div class="card-arrow">Read the Codex guide →</div>
|
|
567
|
+
</a>
|
|
568
|
+
<a class="seo-card" href="/guides/gemini-cli-feedback-memory">
|
|
569
|
+
<div class="seo-kicker">Gemini</div>
|
|
570
|
+
<h3>Gemini CLI Memory That Leads to Enforcement</h3>
|
|
571
|
+
<p>Why Gemini CLI buyers start with memory and convert when they see how memory becomes real pre-action gates.</p>
|
|
572
|
+
<div class="card-arrow">Read the Gemini guide →</div>
|
|
573
|
+
</a>
|
|
550
574
|
</div>
|
|
551
575
|
</div>
|
|
552
576
|
</section>
|
|
@@ -554,7 +578,7 @@ __GA_BOOTSTRAP__
|
|
|
554
578
|
<!-- HOW IT WORKS -->
|
|
555
579
|
<section class="how-it-works" id="how-it-works">
|
|
556
580
|
<div class="container">
|
|
557
|
-
<div class="section-label">New in v0.9.
|
|
581
|
+
<div class="section-label">New in v0.9.14</div>
|
|
558
582
|
<h2 class="section-title">Three steps to stop repeated AI failures</h2>
|
|
559
583
|
<div class="steps">
|
|
560
584
|
<div class="step">
|
package/public/learn.html
CHANGED
|
@@ -57,6 +57,30 @@
|
|
|
57
57
|
"position": 5,
|
|
58
58
|
"url": "https://thumbgate-production.up.railway.app/learn/ai-agent-persistent-memory",
|
|
59
59
|
"name": "How to Give Your AI Coding Agent Persistent Memory Across Sessions"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"@type": "ListItem",
|
|
63
|
+
"position": 6,
|
|
64
|
+
"url": "https://thumbgate-production.up.railway.app/guides/stop-repeated-ai-agent-mistakes",
|
|
65
|
+
"name": "How to Stop AI Coding Agents From Repeating Mistakes"
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"@type": "ListItem",
|
|
69
|
+
"position": 7,
|
|
70
|
+
"url": "https://thumbgate-production.up.railway.app/guides/cursor-agent-guardrails",
|
|
71
|
+
"name": "Cursor Guardrails That Block Repeated Mistakes"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"@type": "ListItem",
|
|
75
|
+
"position": 8,
|
|
76
|
+
"url": "https://thumbgate-production.up.railway.app/guides/codex-cli-guardrails",
|
|
77
|
+
"name": "Codex CLI Guardrails That Actually Enforce"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"@type": "ListItem",
|
|
81
|
+
"position": 9,
|
|
82
|
+
"url": "https://thumbgate-production.up.railway.app/guides/gemini-cli-feedback-memory",
|
|
83
|
+
"name": "Gemini CLI Feedback Memory That Leads to Enforcement"
|
|
60
84
|
}
|
|
61
85
|
]
|
|
62
86
|
}
|
|
@@ -86,6 +110,7 @@
|
|
|
86
110
|
h2 { font-size: 1.5rem; margin: 2.5rem 0 1rem; color: var(--cyan); }
|
|
87
111
|
p { color: var(--text); margin-bottom: 0.75rem; }
|
|
88
112
|
.hero-sub { color: var(--muted); font-size: 1.1rem; max-width: 600px; margin-bottom: 2rem; }
|
|
113
|
+
.section-intro { color: var(--muted); margin-bottom: 1rem; }
|
|
89
114
|
|
|
90
115
|
.article-grid { display: grid; grid-template-columns: 1fr; gap: 24px; margin-top: 2rem; }
|
|
91
116
|
.article-card {
|
|
@@ -202,6 +227,42 @@
|
|
|
202
227
|
</a>
|
|
203
228
|
</div>
|
|
204
229
|
|
|
230
|
+
<h2>Popular buyer questions</h2>
|
|
231
|
+
<p class="section-intro">These are the high-intent guides for buyers who already know the pain and want to understand where ThumbGate fits fast.</p>
|
|
232
|
+
<div class="article-grid">
|
|
233
|
+
<a href="/guides/stop-repeated-ai-agent-mistakes" class="article-card">
|
|
234
|
+
<h3>How to Stop AI Coding Agents From Repeating Mistakes</h3>
|
|
235
|
+
<p>The fastest explanation of why memory alone is not enough when your agent keeps making the same bad move twice.</p>
|
|
236
|
+
<span class="article-tag">Repeat Failures</span>
|
|
237
|
+
<span class="article-tag">Guardrails</span>
|
|
238
|
+
<span class="article-tag">Buyer Guide</span>
|
|
239
|
+
</a>
|
|
240
|
+
|
|
241
|
+
<a href="/guides/cursor-agent-guardrails" class="article-card">
|
|
242
|
+
<h3>Cursor Guardrails That Block Repeated Mistakes</h3>
|
|
243
|
+
<p>For Cursor users who need to keep speed while adding a runtime enforcement layer that does more than prompt politely.</p>
|
|
244
|
+
<span class="article-tag">Cursor</span>
|
|
245
|
+
<span class="article-tag">Guardrails</span>
|
|
246
|
+
<span class="article-tag">Integration</span>
|
|
247
|
+
</a>
|
|
248
|
+
|
|
249
|
+
<a href="/guides/codex-cli-guardrails" class="article-card">
|
|
250
|
+
<h3>Codex CLI Guardrails That Actually Enforce</h3>
|
|
251
|
+
<p>Why operators looking for Codex CLI guardrails are really looking for a feedback-to-enforcement loop they can trust.</p>
|
|
252
|
+
<span class="article-tag">Codex</span>
|
|
253
|
+
<span class="article-tag">CLI</span>
|
|
254
|
+
<span class="article-tag">Reliability</span>
|
|
255
|
+
</a>
|
|
256
|
+
|
|
257
|
+
<a href="/guides/gemini-cli-feedback-memory" class="article-card">
|
|
258
|
+
<h3>Gemini CLI Feedback Memory That Leads to Enforcement</h3>
|
|
259
|
+
<p>A memory-first buyer path for Gemini CLI users who will eventually care about gates, proof, and operational control.</p>
|
|
260
|
+
<span class="article-tag">Gemini</span>
|
|
261
|
+
<span class="article-tag">Memory</span>
|
|
262
|
+
<span class="article-tag">Enforcement</span>
|
|
263
|
+
</a>
|
|
264
|
+
</div>
|
|
265
|
+
|
|
205
266
|
<div class="cta-section">
|
|
206
267
|
<h2 style="color:var(--text);font-size:1.3rem;margin:0 0 8px;">Ready to try it?</h2>
|
|
207
268
|
<p>One command. Works with Claude Code, Cursor, Codex, Gemini, Amp, and any MCP agent.</p>
|
|
Binary file
|
|
@@ -79,7 +79,13 @@ function readJsonlTail(filePath, limit = DEFAULT_HISTORY_LIMIT) {
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
function resolveFeedbackDir(feedbackDir) {
|
|
82
|
-
|
|
82
|
+
if (feedbackDir) {
|
|
83
|
+
return resolveSharedFeedbackDir({ feedbackDir });
|
|
84
|
+
}
|
|
85
|
+
const env = { ...process.env };
|
|
86
|
+
delete env.INIT_CWD;
|
|
87
|
+
delete env.PWD;
|
|
88
|
+
return resolveSharedFeedbackDir({ env });
|
|
83
89
|
}
|
|
84
90
|
|
|
85
91
|
function getConversationPaths(feedbackDir) {
|
package/scripts/feedback-loop.js
CHANGED
|
@@ -146,8 +146,8 @@ function updateStatuslineWithLesson({ accepted, signal, memoryId, feedbackId, le
|
|
|
146
146
|
} catch { /* statusline update is best-effort */ }
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
function getFeedbackPaths() {
|
|
150
|
-
return resolveFeedbackPaths();
|
|
149
|
+
function getFeedbackPaths(options = {}) {
|
|
150
|
+
return resolveFeedbackPaths(options);
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
function getContextFsModule() {
|
|
@@ -1673,8 +1673,8 @@ function writePreventionRules(filePath, minOccurrences = 2) {
|
|
|
1673
1673
|
return { path: outPath, markdown };
|
|
1674
1674
|
}
|
|
1675
1675
|
|
|
1676
|
-
function feedbackSummary(recentN = 20) {
|
|
1677
|
-
const { FEEDBACK_LOG_PATH } = getFeedbackPaths();
|
|
1676
|
+
function feedbackSummary(recentN = 20, options = {}) {
|
|
1677
|
+
const { FEEDBACK_LOG_PATH } = getFeedbackPaths(options);
|
|
1678
1678
|
const entries = readJSONL(FEEDBACK_LOG_PATH);
|
|
1679
1679
|
if (entries.length === 0) {
|
|
1680
1680
|
return '## Feedback Summary\nNo feedback recorded yet.';
|
|
@@ -1794,6 +1794,10 @@ function runTests() {
|
|
|
1794
1794
|
const tmpDir = fs.mkdtempSync(path.join(require('os').tmpdir(), 'thumbgate-loop-test-'));
|
|
1795
1795
|
const localFeedbackLog = path.join(tmpDir, 'feedback-log.jsonl');
|
|
1796
1796
|
process.env.THUMBGATE_FEEDBACK_DIR = tmpDir;
|
|
1797
|
+
const savedInitCwd = process.env.INIT_CWD;
|
|
1798
|
+
process.env.INIT_CWD = savedInitCwd || process.cwd();
|
|
1799
|
+
|
|
1800
|
+
assert(getFeedbackPaths().FEEDBACK_DIR === tmpDir, 'explicit feedback dir wins over npm INIT_CWD');
|
|
1797
1801
|
|
|
1798
1802
|
appendJSONL(localFeedbackLog, { signal: 'positive', tags: ['testing'], skill: 'verify' });
|
|
1799
1803
|
appendJSONL(localFeedbackLog, { signal: 'negative', tags: ['testing'], skill: 'verify' });
|
|
@@ -1845,6 +1849,8 @@ function runTests() {
|
|
|
1845
1849
|
|
|
1846
1850
|
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
1847
1851
|
delete process.env.THUMBGATE_FEEDBACK_DIR;
|
|
1852
|
+
if (savedInitCwd === undefined) delete process.env.INIT_CWD;
|
|
1853
|
+
else process.env.INIT_CWD = savedInitCwd;
|
|
1848
1854
|
console.log(`\nResults: ${passed} passed, ${failed} failed\n`);
|
|
1849
1855
|
process.exit(failed > 0 ? 1 : 0);
|
|
1850
1856
|
}
|