thumbgate 1.26.1 โ 1.26.2
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/adapters/claude/.mcp.json +2 -2
- package/adapters/mcp/server-stdio.js +1 -1
- package/adapters/opencode/opencode.json +1 -1
- package/package.json +2 -1
- package/public/index.html +2 -2
- package/public/numbers.html +2 -2
- package/scripts/operational-summary.js +178 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "thumbgate-marketplace",
|
|
3
|
-
"version": "1.26.
|
|
3
|
+
"version": "1.26.2",
|
|
4
4
|
"owner": {
|
|
5
5
|
"name": "Igor Ganapolsky",
|
|
6
6
|
"email": "ig5973700@gmail.com"
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"source": "npm",
|
|
15
15
|
"package": "thumbgate"
|
|
16
16
|
},
|
|
17
|
-
"version": "1.26.
|
|
17
|
+
"version": "1.26.2",
|
|
18
18
|
"author": {
|
|
19
19
|
"name": "Igor Ganapolsky",
|
|
20
20
|
"email": "ig5973700@gmail.com",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "thumbgate",
|
|
3
3
|
"description": "One ๐ becomes a hard rule the agent cannot bypass. Captures thumbs-down feedback, distills it into PreToolUse Pre-Action Checks, enforced across every future Claude Code session.",
|
|
4
|
-
"version": "1.26.
|
|
4
|
+
"version": "1.26.2",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Igor Ganapolsky",
|
|
7
7
|
"email": "ig5973700@gmail.com",
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
"mcpServers": {
|
|
3
3
|
"thumbgate": {
|
|
4
4
|
"command": "npx",
|
|
5
|
-
"args": ["--yes", "--package", "thumbgate@1.26.
|
|
5
|
+
"args": ["--yes", "--package", "thumbgate@1.26.2", "thumbgate", "serve"]
|
|
6
6
|
}
|
|
7
7
|
},
|
|
8
8
|
"hooks": {
|
|
9
9
|
"preToolUse": {
|
|
10
10
|
"command": "npx",
|
|
11
|
-
"args": ["--yes", "--package", "thumbgate@1.26.
|
|
11
|
+
"args": ["--yes", "--package", "thumbgate@1.26.2", "thumbgate", "gate-check"]
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
}
|
|
@@ -230,7 +230,7 @@ const {
|
|
|
230
230
|
finalizeSession: finalizeFeedbackSession,
|
|
231
231
|
} = require('../../scripts/feedback-session');
|
|
232
232
|
|
|
233
|
-
const SERVER_INFO = { name: 'thumbgate-mcp', version: '1.26.
|
|
233
|
+
const SERVER_INFO = { name: 'thumbgate-mcp', version: '1.26.2' };
|
|
234
234
|
const COMMERCE_CATEGORIES = [
|
|
235
235
|
'product_recommendation',
|
|
236
236
|
'brand_compliance',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "thumbgate",
|
|
3
|
-
"version": "1.26.
|
|
3
|
+
"version": "1.26.2",
|
|
4
4
|
"description": "ThumbGate self-improving agent governance: thumbs-up/down turns every mistake into a prevention rule and blocks repeat patterns. 36 pre-action checks, budget enforcement, and self-protection for Claude Code, Cursor, Codex, Gemini CLI, and Amp.",
|
|
5
5
|
"homepage": "https://thumbgate.ai",
|
|
6
6
|
"repository": {
|
|
@@ -136,6 +136,7 @@
|
|
|
136
136
|
"scripts/noop-detect.js",
|
|
137
137
|
"scripts/obsidian-export.js",
|
|
138
138
|
"scripts/operational-dashboard.js",
|
|
139
|
+
"scripts/operational-summary.js",
|
|
139
140
|
"scripts/operational-integrity.js",
|
|
140
141
|
"scripts/oss-pr-opportunity-scout.js",
|
|
141
142
|
"scripts/otel-declarative-config.js",
|
package/public/index.html
CHANGED
|
@@ -20,7 +20,7 @@ __GOOGLE_SITE_VERIFICATION_META__
|
|
|
20
20
|
<meta property="og:image" content="https://thumbgate.ai/og.png">
|
|
21
21
|
<meta name="twitter:card" content="summary_large_image">
|
|
22
22
|
<meta name="twitter:image" content="https://thumbgate.ai/og.png">
|
|
23
|
-
<meta name="thumbgate-version" content="1.26.
|
|
23
|
+
<meta name="thumbgate-version" content="1.26.2">
|
|
24
24
|
<meta name="keywords" content="ThumbGate, thumbgate, AI agent orchestration, AI experience orchestration, agentic development cycle, AC/DC framework, Guide Generate Verify Solve, agent enforcement layer, save LLM tokens, reduce Claude API cost, reduce OpenAI cost, AI agent token savings, prevent LLM retries, prevent hallucination retries, stop AI token waste, pre-action checks, agent governance, Claude Code, Cursor, Codex, Gemini, Amp, Cline, OpenCode, workflow hardening, context engineering, AI authenticity, brand authenticity AI">
|
|
25
25
|
<link rel="canonical" href="__APP_ORIGIN__/">
|
|
26
26
|
<link rel="alternate" type="text/markdown" title="ThumbGate LLM context" href="__APP_ORIGIN__/llm-context.md">
|
|
@@ -1594,7 +1594,7 @@ __GA_BOOTSTRAP__
|
|
|
1594
1594
|
<a href="https://www.linkedin.com/in/igorganapolsky" target="_blank" rel="noopener">LinkedIn</a>
|
|
1595
1595
|
<a href="/blog">Blog</a>
|
|
1596
1596
|
</div>
|
|
1597
|
-
<span class="footer-copy">ยฉ 2026 ThumbGate ยท MIT License ยท npm v1.26.
|
|
1597
|
+
<span class="footer-copy">ยฉ 2026 ThumbGate ยท MIT License ยท npm v1.26.2</span>
|
|
1598
1598
|
</div>
|
|
1599
1599
|
</footer>
|
|
1600
1600
|
|
package/public/numbers.html
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"alternateName": "thumbgate",
|
|
26
26
|
"applicationCategory": "DeveloperApplication",
|
|
27
27
|
"operatingSystem": "Cross-platform, Node.js >=18.18.0",
|
|
28
|
-
"softwareVersion": "1.26.
|
|
28
|
+
"softwareVersion": "1.26.2",
|
|
29
29
|
"url": "https://thumbgate.ai/numbers",
|
|
30
30
|
"dateModified": "2026-05-07",
|
|
31
31
|
"creator": {
|
|
@@ -202,7 +202,7 @@
|
|
|
202
202
|
<main class="container">
|
|
203
203
|
<h1>The Numbers</h1>
|
|
204
204
|
<p class="subtitle">Generated first-party operational snapshot from the ThumbGate runtime. This is not customer traction, install volume, revenue, or proof that a configured gate has fired.</p>
|
|
205
|
-
<div class="freshness">Updated: 2026-05-07 ยท Version 1.26.
|
|
205
|
+
<div class="freshness">Updated: 2026-05-07 ยท Version 1.26.2</div>
|
|
206
206
|
<div class="truth-note"><strong>Read this first:</strong> configured checks are inventory. Recorded blocks and warnings are usage evidence. This snapshot currently reports 0 recorded hard-block event(s) and 0 recorded warning event(s).</div>
|
|
207
207
|
|
|
208
208
|
<h2>Gate enforcement</h2>
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('node:fs');
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
const os = require('node:os');
|
|
6
|
+
const { getBillingSummaryLive } = require('./billing');
|
|
7
|
+
const { resolveAnalyticsWindow } = require('./analytics-window');
|
|
8
|
+
const { resolveHostedBillingConfig } = require('./hosted-config');
|
|
9
|
+
|
|
10
|
+
// Configure fetch proxy when running behind a corporate/sandbox proxy
|
|
11
|
+
(function configureProxy() {
|
|
12
|
+
const proxyUrl = process.env.HTTPS_PROXY || process.env.https_proxy
|
|
13
|
+
|| process.env.HTTP_PROXY || process.env.http_proxy;
|
|
14
|
+
if (!proxyUrl) return;
|
|
15
|
+
try {
|
|
16
|
+
const { ProxyAgent, setGlobalDispatcher } = require('undici');
|
|
17
|
+
setGlobalDispatcher(new ProxyAgent(proxyUrl));
|
|
18
|
+
} catch {
|
|
19
|
+
// undici not available โ fetch will use default dispatcher
|
|
20
|
+
}
|
|
21
|
+
}());
|
|
22
|
+
|
|
23
|
+
const OPERATOR_CONFIG_PATH = path.join(os.homedir(), '.config', 'thumbgate', 'operator.json');
|
|
24
|
+
|
|
25
|
+
function normalizeText(value) {
|
|
26
|
+
if (value === undefined || value === null) return null;
|
|
27
|
+
const text = String(value).trim();
|
|
28
|
+
return text || null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function loadOperatorConfig(configPath = OPERATOR_CONFIG_PATH) {
|
|
32
|
+
try {
|
|
33
|
+
const raw = fs.readFileSync(configPath, 'utf8');
|
|
34
|
+
const parsed = JSON.parse(raw);
|
|
35
|
+
return {
|
|
36
|
+
operatorKey: normalizeText(parsed.operatorKey),
|
|
37
|
+
baseUrl: normalizeText(parsed.baseUrl),
|
|
38
|
+
};
|
|
39
|
+
} catch {
|
|
40
|
+
return { operatorKey: null, baseUrl: null };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function shouldPreferHostedSummary() {
|
|
45
|
+
return String(process.env.THUMBGATE_METRICS_SOURCE || '').trim().toLowerCase() !== 'local';
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function resolveHostedSummaryConfig() {
|
|
49
|
+
const runtimeConfig = resolveHostedBillingConfig();
|
|
50
|
+
const operatorConfig = loadOperatorConfig();
|
|
51
|
+
// Priority: env THUMBGATE_OPERATOR_KEY > local config file > env THUMBGATE_API_KEY
|
|
52
|
+
const apiKey = normalizeText(process.env.THUMBGATE_OPERATOR_KEY)
|
|
53
|
+
|| operatorConfig.operatorKey
|
|
54
|
+
|| normalizeText(process.env.THUMBGATE_API_KEY);
|
|
55
|
+
const apiBaseUrl = normalizeText(process.env.THUMBGATE_BILLING_API_BASE_URL)
|
|
56
|
+
|| operatorConfig.baseUrl
|
|
57
|
+
|| runtimeConfig.billingApiBaseUrl;
|
|
58
|
+
return {
|
|
59
|
+
apiBaseUrl,
|
|
60
|
+
apiKey,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async function fetchHostedBillingSummary(options = {}, config = resolveHostedSummaryConfig()) {
|
|
65
|
+
const analyticsWindow = resolveAnalyticsWindow(options);
|
|
66
|
+
if (!shouldPreferHostedSummary()) {
|
|
67
|
+
const err = new Error('Hosted operational summary is disabled.');
|
|
68
|
+
err.code = 'hosted_summary_disabled';
|
|
69
|
+
throw err;
|
|
70
|
+
}
|
|
71
|
+
if (!config.apiBaseUrl || !config.apiKey) {
|
|
72
|
+
const err = new Error('Hosted operational summary is not configured.');
|
|
73
|
+
err.code = 'hosted_summary_unconfigured';
|
|
74
|
+
throw err;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const requestUrl = new URL('/v1/billing/summary', config.apiBaseUrl);
|
|
78
|
+
requestUrl.searchParams.set('window', analyticsWindow.window);
|
|
79
|
+
requestUrl.searchParams.set('timezone', analyticsWindow.timeZone);
|
|
80
|
+
if (options.now !== undefined && options.now !== null && options.now !== '') {
|
|
81
|
+
requestUrl.searchParams.set('now', analyticsWindow.now);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const response = await fetch(requestUrl, {
|
|
85
|
+
method: 'GET',
|
|
86
|
+
headers: {
|
|
87
|
+
authorization: `Bearer ${config.apiKey}`,
|
|
88
|
+
accept: 'application/json',
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
if (!response.ok) {
|
|
93
|
+
const detail = await response.text().catch(() => '');
|
|
94
|
+
const err = new Error(`Hosted operational summary request failed (${response.status}): ${detail || 'unknown error'}`);
|
|
95
|
+
err.code = 'hosted_summary_http_error';
|
|
96
|
+
err.status = response.status;
|
|
97
|
+
throw err;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return response.json();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function getOperationalBillingSummary(options = {}) {
|
|
104
|
+
const analyticsWindow = resolveAnalyticsWindow(options);
|
|
105
|
+
try {
|
|
106
|
+
const summary = await fetchHostedBillingSummary(analyticsWindow);
|
|
107
|
+
return {
|
|
108
|
+
source: 'hosted',
|
|
109
|
+
summary,
|
|
110
|
+
fallbackReason: null,
|
|
111
|
+
hostedStatus: 200,
|
|
112
|
+
summaryWindow: analyticsWindow.window,
|
|
113
|
+
};
|
|
114
|
+
} catch (err) {
|
|
115
|
+
const reason = err && err.message ? err.message : 'hosted_summary_unavailable';
|
|
116
|
+
const status = err && typeof err.status === 'number' ? err.status : null;
|
|
117
|
+
const code = err && err.code ? err.code : null;
|
|
118
|
+
|
|
119
|
+
// Hosted deliberately disabled or never configured โ local fallback is
|
|
120
|
+
// intentional, not a degraded state. Tag as plain 'local'.
|
|
121
|
+
if (code === 'hosted_summary_disabled' || code === 'hosted_summary_unconfigured') {
|
|
122
|
+
return {
|
|
123
|
+
source: 'local',
|
|
124
|
+
summary: await getBillingSummaryLive(analyticsWindow),
|
|
125
|
+
fallbackReason: reason,
|
|
126
|
+
hostedStatus: null,
|
|
127
|
+
summaryWindow: analyticsWindow.window,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Auth failure is the most dangerous case: if hosted Stripe data says
|
|
132
|
+
// we have paid customers and local ledgers are empty, silently returning
|
|
133
|
+
// "$0.00" is a lie that hides actual revenue. Refuse to guess โ surface
|
|
134
|
+
// an actionable error so the operator fixes the key before any
|
|
135
|
+
// downstream report renders wrong numbers.
|
|
136
|
+
if (status === 401 || status === 403) {
|
|
137
|
+
const authErr = new Error(
|
|
138
|
+
`Hosted billing summary rejected credentials (HTTP ${status}). ` +
|
|
139
|
+
`The operator key on this machine does not match the one on the ` +
|
|
140
|
+
`hosted deployment. Fix: set THUMBGATE_OPERATOR_KEY in this shell, ` +
|
|
141
|
+
`or update the operatorKey field in ~/.config/thumbgate/operator.json, ` +
|
|
142
|
+
`to match Railway's THUMBGATE_OPERATOR_KEY. ` +
|
|
143
|
+
`Running this command without hosted auth would report local-only ` +
|
|
144
|
+
`data as ground truth, which may not reflect actual Stripe revenue. ` +
|
|
145
|
+
`Original response: ${reason}`
|
|
146
|
+
);
|
|
147
|
+
authErr.code = 'hosted_summary_unauthorized';
|
|
148
|
+
authErr.status = status;
|
|
149
|
+
throw authErr;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Non-auth failure (network, 5xx, config) โ local fallback is still
|
|
153
|
+
// useful for dev workflows, but tag the source so downstream renderers
|
|
154
|
+
// and agents do not mistake it for verified hosted truth.
|
|
155
|
+
//
|
|
156
|
+
// Log only the status code (trusted) โ the full reason contains upstream
|
|
157
|
+
// response text and is only returned structurally via fallbackReason.
|
|
158
|
+
console.warn(
|
|
159
|
+
`[operational-summary] Hosted billing unreachable (status=${status ?? 'network'}); ` +
|
|
160
|
+
`falling back to LOCAL-UNVERIFIED state. Numbers below may not reflect actual Stripe revenue.`
|
|
161
|
+
);
|
|
162
|
+
return {
|
|
163
|
+
source: 'local-unverified',
|
|
164
|
+
summary: await getBillingSummaryLive(analyticsWindow),
|
|
165
|
+
fallbackReason: reason,
|
|
166
|
+
hostedStatus: status,
|
|
167
|
+
summaryWindow: analyticsWindow.window,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
module.exports = {
|
|
173
|
+
fetchHostedBillingSummary,
|
|
174
|
+
getOperationalBillingSummary,
|
|
175
|
+
resolveHostedSummaryConfig,
|
|
176
|
+
shouldPreferHostedSummary,
|
|
177
|
+
loadOperatorConfig,
|
|
178
|
+
};
|