thumbgate 0.9.12 → 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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thumbgate",
3
- "version": "0.9.12",
3
+ "version": "0.9.14",
4
4
  "plugins": [
5
5
  {
6
6
  "name": "thumbgate",
@@ -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.12",
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.12",
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: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
8
8
  [![Try Free](https://img.shields.io/badge/Pro-Try%20Free%20→-635bff?style=for-the-badge&logo=stripe&logoColor=white)](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/#pricing?utm_source=github&utm_medium=readme&utm_campaign=top_cta)** · **[Setup Guide](https://thumbgate-production.up.railway.app/guide?utm_source=github&utm_medium=readme&utm_campaign=top_cta)**
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
  [![Sign up for ThumbGate Pro](https://img.shields.io/badge/>>%20Start%20Free%20→%20ThumbGate%20Pro-635bff?style=for-the-badge)](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/#pricing?utm_source=github&utm_medium=readme&utm_campaign=pricing_link)
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/#workflow-sprint-intake?utm_source=github&utm_medium=readme&utm_campaign=team_rollout)** | **[Live Dashboard](https://thumbgate-production.up.railway.app/dashboard?utm_source=github&utm_medium=readme&utm_campaign=thumbgate)**
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
 
@@ -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.12 thumbgate serve`.
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.12", "thumbgate", "serve"]
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.12", "thumbgate", "gate-check"]
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.12", "thumbgate", "serve"]
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.12", "thumbgate", "gate-check"]
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.12' };
114
+ const SERVER_INFO = { name: 'thumbgate-mcp', version: '0.9.14' };
115
115
  const COMMERCE_CATEGORIES = [
116
116
  'product_recommendation',
117
117
  'brand_compliance',
@@ -7,7 +7,7 @@
7
7
  "npx",
8
8
  "--yes",
9
9
  "--package",
10
- "thumbgate@0.9.12",
10
+ "thumbgate@0.9.14",
11
11
  "thumbgate",
12
12
  "serve"
13
13
  ],
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,7 +1,7 @@
1
1
  {
2
2
  "name": "thumbgate",
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.",
3
+ "version": "0.9.14",
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": {
7
7
  "type": "git",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-bridge",
3
- "version": "0.9.12",
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",
@@ -5,7 +5,7 @@
5
5
  "args": [
6
6
  "--yes",
7
7
  "--package",
8
- "thumbgate@0.9.12",
8
+ "thumbgate@0.9.14",
9
9
  "thumbgate",
10
10
  "serve"
11
11
  ]
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-profile",
3
- "version": "0.9.12",
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",
@@ -5,7 +5,7 @@
5
5
  "args": [
6
6
  "--yes",
7
7
  "--package",
8
- "thumbgate@0.9.12",
8
+ "thumbgate@0.9.14",
9
9
  "thumbgate",
10
10
  "serve"
11
11
  ]
@@ -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.12", "thumbgate", "serve"]
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.12", "thumbgate", "serve"]
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.12",
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.12", "thumbgate", "serve"],
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">Learn More</div>
524
- <h2 class="section-title">How ThumbGate compares and when to use it</h2>
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.12</div>
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>
@@ -79,7 +79,13 @@ function readJsonlTail(filePath, limit = DEFAULT_HISTORY_LIMIT) {
79
79
  }
80
80
 
81
81
  function resolveFeedbackDir(feedbackDir) {
82
- return resolveSharedFeedbackDir({ feedbackDir });
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) {
@@ -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
  }