thumbgate 1.28.0 → 1.28.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/plugin.json +2 -1
- package/.well-known/mcp/server-card.json +1 -1
- package/README.md +96 -122
- package/adapters/claude/.mcp.json +2 -2
- package/adapters/mcp/server-stdio.js +18 -33
- package/adapters/opencode/opencode.json +1 -1
- package/bin/cli.js +70 -70
- package/config/gates/default.json +2 -2
- package/config/github-about.json +2 -5
- package/config/post-deploy-marketing-pages.json +1 -1
- package/hooks/hooks.json +38 -0
- package/package.json +18 -8
- package/public/chatgpt-app.html +2 -2
- package/public/codex-enterprise.html +1 -1
- package/public/codex-plugin.html +1 -1
- package/public/diagnostic.html +23 -1
- package/public/guide.html +1 -1
- package/public/index.html +172 -201
- package/public/numbers.html +2 -2
- package/public/partner-intake.html +198 -0
- package/public/pricing.html +51 -14
- package/scripts/billing.js +815 -137
- package/scripts/checkout-attribution-reference.js +85 -0
- package/scripts/claude-feedback-sync.js +23 -6
- package/scripts/cli-feedback.js +19 -10
- package/scripts/feedback-loop.js +290 -1
- package/scripts/feedback-quality.js +25 -26
- package/scripts/feedback-sanitizer.js +151 -3
- package/scripts/gates-engine.js +128 -49
- package/scripts/hosted-config.js +9 -2
- package/scripts/mailer/resend-mailer.js +11 -5
- package/scripts/secret-scanner.js +363 -68
- package/scripts/self-protection.js +21 -36
- package/src/api/server.js +121 -12
- package/public/assets/brand/github-social-preview.png +0 -0
|
@@ -231,7 +231,7 @@ const {
|
|
|
231
231
|
finalizeSession: finalizeFeedbackSession,
|
|
232
232
|
} = require('../../scripts/feedback-session');
|
|
233
233
|
|
|
234
|
-
const SERVER_INFO = { name: 'thumbgate-mcp', version: '1.28.
|
|
234
|
+
const SERVER_INFO = { name: 'thumbgate-mcp', version: '1.28.1' };
|
|
235
235
|
const COMMERCE_CATEGORIES = [
|
|
236
236
|
'product_recommendation',
|
|
237
237
|
'brand_compliance',
|
|
@@ -1430,22 +1430,14 @@ function writeNdjsonResponse(id, payload, error = null) {
|
|
|
1430
1430
|
process.stdout.write(`${body}\n`);
|
|
1431
1431
|
}
|
|
1432
1432
|
|
|
1433
|
-
/**
|
|
1434
|
-
* Default staleness threshold: if a lock is older than this (ms), the holder
|
|
1435
|
-
* is considered orphaned even if its PID is still alive — it likely belongs
|
|
1436
|
-
* to a defunct Claude Code session whose process was never reaped.
|
|
1437
|
-
*/
|
|
1438
|
-
const LOCK_STALE_MS = Number(process.env.THUMBGATE_LOCK_STALE_MS) || 2 * 60 * 60 * 1000; // 2 hours
|
|
1439
|
-
|
|
1440
1433
|
/**
|
|
1441
1434
|
* Acquire a file-system lock to prevent duplicate MCP server instances.
|
|
1442
|
-
* Returns { lockFile, cleanupLock } on success
|
|
1443
|
-
* if another live server holds the lock.
|
|
1435
|
+
* Returns { lockFile, cleanupLock } on success.
|
|
1444
1436
|
*
|
|
1445
|
-
*
|
|
1446
|
-
*
|
|
1447
|
-
*
|
|
1448
|
-
*
|
|
1437
|
+
* Every live stdio client needs its own MCP process, and those sessions can
|
|
1438
|
+
* legitimately run for many hours. A lock's age is therefore not evidence that
|
|
1439
|
+
* its owner is orphaned. Live owners coexist through per-session locks; only a
|
|
1440
|
+
* lock whose PID is no longer running is reclaimed.
|
|
1449
1441
|
*/
|
|
1450
1442
|
function acquireLock() {
|
|
1451
1443
|
const feedbackDir = getFeedbackPaths().FEEDBACK_DIR;
|
|
@@ -1458,26 +1450,19 @@ function acquireLock() {
|
|
|
1458
1450
|
try { process.kill(lockData.pid, 0); isRunning = true; } catch { /* process is dead */ }
|
|
1459
1451
|
|
|
1460
1452
|
if (isRunning) {
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
fs.writeFileSync(sessionLockFile, JSON.stringify({ pid: process.pid, startedAt: new Date().toISOString() }));
|
|
1473
|
-
const cleanupSessionLock = () => { try { fs.unlinkSync(sessionLockFile); } catch { /* already removed */ } };
|
|
1474
|
-
process.on('exit', cleanupSessionLock);
|
|
1475
|
-
process.on('SIGTERM', () => { cleanupSessionLock(); process.exit(0); });
|
|
1476
|
-
process.on('SIGINT', () => { cleanupSessionLock(); process.exit(0); });
|
|
1477
|
-
return { lockFile: sessionLockFile, cleanupLock: cleanupSessionLock };
|
|
1478
|
-
}
|
|
1453
|
+
// Another session's MCP server is running — coexist via per-session lock.
|
|
1454
|
+
// Each client communicates via its own stdio pipe and needs its own server.
|
|
1455
|
+
// SQLite WAL mode handles concurrent access safely.
|
|
1456
|
+
process.stderr.write(`[thumbgate] Another MCP server (PID ${lockData.pid}) is running for ${feedbackDir}. Starting concurrent session.\n`);
|
|
1457
|
+
const sessionLockFile = path.join(feedbackDir, `.mcp-server-${process.pid}.lock`);
|
|
1458
|
+
fs.writeFileSync(sessionLockFile, JSON.stringify({ pid: process.pid, startedAt: new Date().toISOString() }));
|
|
1459
|
+
const cleanupSessionLock = () => { try { fs.unlinkSync(sessionLockFile); } catch { /* already removed */ } };
|
|
1460
|
+
process.on('exit', cleanupSessionLock);
|
|
1461
|
+
process.on('SIGTERM', () => { cleanupSessionLock(); process.exit(0); });
|
|
1462
|
+
process.on('SIGINT', () => { cleanupSessionLock(); process.exit(0); });
|
|
1463
|
+
return { lockFile: sessionLockFile, cleanupLock: cleanupSessionLock };
|
|
1479
1464
|
}
|
|
1480
|
-
// Stale lock from a dead
|
|
1465
|
+
// Stale lock from a dead process — remove it.
|
|
1481
1466
|
try { fs.unlinkSync(lockFile); } catch { /* already gone */ }
|
|
1482
1467
|
process.stderr.write(`[thumbgate] Removed stale lock (PID ${lockData.pid} is no longer running).\n`);
|
|
1483
1468
|
}
|
package/bin/cli.js
CHANGED
|
@@ -2695,23 +2695,27 @@ function install() {
|
|
|
2695
2695
|
}
|
|
2696
2696
|
|
|
2697
2697
|
async function gateCheck() {
|
|
2698
|
-
// Explicit emergency escape hatch ONLY. The 2026-06-03 hotfix made this
|
|
2699
|
-
// bypass-by-default, which silently disabled ThumbGate's enforcement entirely
|
|
2700
|
-
// (the firewall approved everything). Restored 2026-06-04: enforcement runs by
|
|
2701
|
-
// default in warn-by-default posture (see gates-engine applyEnforcementPosture);
|
|
2702
|
-
// set THUMBGATE_HOTFIX_BYPASS=1 to disable all checks if a gate ever misfires.
|
|
2703
|
-
if (process.env.THUMBGATE_HOTFIX_BYPASS === '1') {
|
|
2704
|
-
process.stdout.write(JSON.stringify({
|
|
2705
|
-
decision: 'approve',
|
|
2706
|
-
reason: 'hotfix-bypass-opt-in',
|
|
2707
|
-
hookSpecificOutput: { hookEventName: 'PreToolUse', additionalContext: '' }
|
|
2708
|
-
}) + '\n');
|
|
2709
|
-
return;
|
|
2710
|
-
}
|
|
2711
2698
|
try {
|
|
2712
2699
|
const payload = readStdinText();
|
|
2713
2700
|
const input = payload ? JSON.parse(payload) : {};
|
|
2714
2701
|
const gatesEngine = require(path.join(PKG_ROOT, 'scripts', 'gates-engine'));
|
|
2702
|
+
|
|
2703
|
+
// The operator bypass only skips advisory and strict-mode gates. Security and
|
|
2704
|
+
// self-protection floors are evaluated before the early approval path.
|
|
2705
|
+
if (process.env.THUMBGATE_HOTFIX_BYPASS === '1') {
|
|
2706
|
+
const hardFloorOutput = gatesEngine.runHardFloor(input);
|
|
2707
|
+
if (hardFloorOutput) {
|
|
2708
|
+
process.stdout.write(hardFloorOutput + '\n');
|
|
2709
|
+
return;
|
|
2710
|
+
}
|
|
2711
|
+
process.stdout.write(JSON.stringify({
|
|
2712
|
+
decision: 'approve',
|
|
2713
|
+
reason: 'operator-bypass-opt-in',
|
|
2714
|
+
hookSpecificOutput: { hookEventName: 'PreToolUse', additionalContext: '' }
|
|
2715
|
+
}) + '\n');
|
|
2716
|
+
return;
|
|
2717
|
+
}
|
|
2718
|
+
|
|
2715
2719
|
const output = await gatesEngine.runAsync(input);
|
|
2716
2720
|
process.stdout.write(output + '\n');
|
|
2717
2721
|
} catch (err) {
|
|
@@ -2749,11 +2753,18 @@ function statuslineRender() {
|
|
|
2749
2753
|
|
|
2750
2754
|
function hookAutoCapture() {
|
|
2751
2755
|
syncActiveProjectContext();
|
|
2756
|
+
const { extractPromptEnvelope } = require(path.join(PKG_ROOT, 'scripts', 'feedback-sanitizer'));
|
|
2757
|
+
const rawStdin = readStdinText();
|
|
2758
|
+
const promptEnvelope = extractPromptEnvelope(rawStdin);
|
|
2759
|
+
// stdin on a UserPromptSubmit hook is the JSON payload
|
|
2760
|
+
// {session_id, transcript_path, cwd, prompt, ...}. Persist ONLY the human
|
|
2761
|
+
// `.prompt` field — never the whole stdin object — so session metadata blobs
|
|
2762
|
+
// can't be promoted as lessons.
|
|
2752
2763
|
const prompt = process.env.CLAUDE_USER_PROMPT
|
|
2753
2764
|
|| process.env.THUMBGATE_USER_PROMPT
|
|
2754
2765
|
|| process.env.CODEX_USER_PROMPT
|
|
2755
2766
|
|| process.env.USER_PROMPT
|
|
2756
|
-
||
|
|
2767
|
+
|| promptEnvelope.prompt;
|
|
2757
2768
|
const { evaluatePromptGuard } = require(path.join(PKG_ROOT, 'scripts', 'prompt-guard'));
|
|
2758
2769
|
const { processInlineFeedback, formatCliOutput } = require(path.join(PKG_ROOT, 'scripts', 'cli-feedback'));
|
|
2759
2770
|
const { detectFeedbackSignal } = require(path.join(PKG_ROOT, 'scripts', 'feedback-quality'));
|
|
@@ -2766,25 +2777,39 @@ function hookAutoCapture() {
|
|
|
2766
2777
|
})
|
|
2767
2778
|
);
|
|
2768
2779
|
|
|
2769
|
-
recordConversationEntry({
|
|
2770
|
-
author: 'user',
|
|
2771
|
-
text: prompt,
|
|
2772
|
-
source: 'claude_user_prompt',
|
|
2773
|
-
});
|
|
2774
|
-
|
|
2775
2780
|
const guardResult = evaluatePromptGuard(prompt);
|
|
2776
2781
|
if (guardResult) {
|
|
2782
|
+
recordConversationEntry({
|
|
2783
|
+
author: 'user',
|
|
2784
|
+
text: prompt,
|
|
2785
|
+
source: 'claude_user_prompt',
|
|
2786
|
+
});
|
|
2777
2787
|
process.stdout.write(`${JSON.stringify(guardResult)}\n`);
|
|
2778
2788
|
return;
|
|
2779
2789
|
}
|
|
2780
2790
|
|
|
2781
2791
|
const detected = detectFeedbackSignal(prompt);
|
|
2782
2792
|
if (!detected) {
|
|
2793
|
+
recordConversationEntry({
|
|
2794
|
+
author: 'user',
|
|
2795
|
+
text: prompt,
|
|
2796
|
+
source: 'claude_user_prompt',
|
|
2797
|
+
});
|
|
2783
2798
|
return;
|
|
2784
2799
|
}
|
|
2785
2800
|
|
|
2786
2801
|
const signal = detected.signal;
|
|
2787
2802
|
const conversationWindow = readRecentConversationWindow({ limit: 8 });
|
|
2803
|
+
const { buildFeedbackSourceIdentity } = require(path.join(PKG_ROOT, 'scripts', 'feedback-loop'));
|
|
2804
|
+
const sourceEvent = buildFeedbackSourceIdentity({
|
|
2805
|
+
signal,
|
|
2806
|
+
promptText: prompt,
|
|
2807
|
+
sessionId: promptEnvelope.sessionId || process.env.CLAUDE_SESSION_ID,
|
|
2808
|
+
promptId: promptEnvelope.promptId,
|
|
2809
|
+
projectDir: promptEnvelope.projectDir || CWD,
|
|
2810
|
+
timestamp: promptEnvelope.timestamp,
|
|
2811
|
+
source: 'claude-user-prompt',
|
|
2812
|
+
});
|
|
2788
2813
|
const result = processInlineFeedback({
|
|
2789
2814
|
signal,
|
|
2790
2815
|
context: prompt,
|
|
@@ -2793,7 +2818,15 @@ function hookAutoCapture() {
|
|
|
2793
2818
|
: undefined,
|
|
2794
2819
|
whatWentWrong: signal === 'down' ? prompt : undefined,
|
|
2795
2820
|
whatWorked: signal === 'up' ? prompt : undefined,
|
|
2821
|
+
sourceEvent,
|
|
2796
2822
|
});
|
|
2823
|
+
if (!result.feedbackResult || !result.feedbackResult.duplicate) {
|
|
2824
|
+
recordConversationEntry({
|
|
2825
|
+
author: 'user',
|
|
2826
|
+
text: prompt,
|
|
2827
|
+
source: 'claude_user_prompt',
|
|
2828
|
+
});
|
|
2829
|
+
}
|
|
2797
2830
|
process.stdout.write(formatCliOutput(result) + '\n');
|
|
2798
2831
|
}
|
|
2799
2832
|
|
|
@@ -3947,53 +3980,6 @@ switch (COMMAND) {
|
|
|
3947
3980
|
case 'dispatch-brief':
|
|
3948
3981
|
dispatchBrief();
|
|
3949
3982
|
break;
|
|
3950
|
-
case 'gate-check': {
|
|
3951
|
-
// PreToolUse hook interface: reads tool call JSON from stdin, outputs gate verdict
|
|
3952
|
-
// Used by: generate-pretool-hook.sh → npx thumbgate gate-check
|
|
3953
|
-
const { run: gateRun, runAsync: gateRunAsync } = require(path.join(PKG_ROOT, 'scripts', 'gates-engine'));
|
|
3954
|
-
const { evaluateSelfProtection } = require(path.join(PKG_ROOT, 'scripts', 'self-protection'));
|
|
3955
|
-
let stdinData = '';
|
|
3956
|
-
process.stdin.setEncoding('utf8');
|
|
3957
|
-
process.stdin.on('data', (chunk) => { stdinData += chunk; });
|
|
3958
|
-
process.stdin.on('end', async () => {
|
|
3959
|
-
try {
|
|
3960
|
-
const input = JSON.parse(stdinData);
|
|
3961
|
-
const output = await gateRunAsync(input);
|
|
3962
|
-
// Self-protection overlay (2026-07-08): the gate engine only denies edits
|
|
3963
|
-
// to ThumbGate's own governance files under strict enforcement; by default
|
|
3964
|
-
// such edits pass as a clean ALLOW. Surface them (or block in strict) so an
|
|
3965
|
-
// agent can't silently disable the firewall. Only overlays when the engine
|
|
3966
|
-
// did not already produce a hard deny.
|
|
3967
|
-
let verdict = output;
|
|
3968
|
-
try {
|
|
3969
|
-
const parsed = JSON.parse(output || '{}');
|
|
3970
|
-
const alreadyDeny = (parsed.hookSpecificOutput && parsed.hookSpecificOutput.permissionDecision === 'deny')
|
|
3971
|
-
|| parsed.decision === 'block';
|
|
3972
|
-
if (!alreadyDeny) {
|
|
3973
|
-
const sp = evaluateSelfProtection(input.tool_name, input.tool_input);
|
|
3974
|
-
if (sp && sp.action === 'block') {
|
|
3975
|
-
verdict = JSON.stringify({
|
|
3976
|
-
decision: 'block',
|
|
3977
|
-
reason: sp.message,
|
|
3978
|
-
hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'deny', permissionDecisionReason: sp.message },
|
|
3979
|
-
});
|
|
3980
|
-
} else if (sp && sp.action === 'warn') {
|
|
3981
|
-
verdict = JSON.stringify({
|
|
3982
|
-
hookSpecificOutput: { hookEventName: 'PreToolUse', additionalContext: sp.message },
|
|
3983
|
-
});
|
|
3984
|
-
}
|
|
3985
|
-
}
|
|
3986
|
-
} catch (_e) { /* non-JSON engine output: pass through unchanged */ }
|
|
3987
|
-
process.stdout.write(verdict + '\n');
|
|
3988
|
-
process.exit(0);
|
|
3989
|
-
} catch (err) {
|
|
3990
|
-
process.stderr.write(`gate-check error: ${err.message}\n`);
|
|
3991
|
-
process.stdout.write(JSON.stringify({}) + '\n');
|
|
3992
|
-
process.exit(0);
|
|
3993
|
-
}
|
|
3994
|
-
});
|
|
3995
|
-
break;
|
|
3996
|
-
}
|
|
3997
3983
|
case 'hermes-gate': {
|
|
3998
3984
|
// Nous Research Hermes Agent `pre_tool_call` shell hook.
|
|
3999
3985
|
// Hermes pipes each pending tool call as JSON to stdin and reads a decision from stdout;
|
|
@@ -4004,7 +3990,7 @@ switch (COMMAND) {
|
|
|
4004
3990
|
// Hermes `pre_tool_call` is binary (block or allow) with no warn channel, and the whole point
|
|
4005
3991
|
// of wiring it is to gate, so we run STRICT enforcement by default — otherwise ThumbGate's
|
|
4006
3992
|
// warn-by-default posture would pass every deny through and the hook would block nothing.
|
|
4007
|
-
// Opt out with THUMBGATE_HERMES_WARN_ONLY=1;
|
|
3993
|
+
// Opt out with THUMBGATE_HERMES_WARN_ONLY=1; the operator bypass also leaves ordinary gates advisory.
|
|
4008
3994
|
// Wire it in ~/.hermes/config.yaml — see adapters/hermes/config.yaml.
|
|
4009
3995
|
if (process.env.THUMBGATE_HERMES_WARN_ONLY !== '1' && process.env.THUMBGATE_HOTFIX_BYPASS !== '1') {
|
|
4010
3996
|
process.env.THUMBGATE_STRICT_ENFORCEMENT = '1';
|
|
@@ -4016,8 +4002,22 @@ switch (COMMAND) {
|
|
|
4016
4002
|
process.stdin.on('end', async () => {
|
|
4017
4003
|
try {
|
|
4018
4004
|
const payload = JSON.parse(hermesStdin);
|
|
4019
|
-
|
|
4020
|
-
const
|
|
4005
|
+
const hermesToolName = String(payload.tool_name || '');
|
|
4006
|
+
const canonicalToolNames = {
|
|
4007
|
+
terminal: 'Bash',
|
|
4008
|
+
process: 'Bash',
|
|
4009
|
+
execute_code: 'Bash',
|
|
4010
|
+
patch: 'Edit',
|
|
4011
|
+
write_file: 'Write',
|
|
4012
|
+
read_file: 'Read',
|
|
4013
|
+
};
|
|
4014
|
+
const verdict = await hermesGateRun({
|
|
4015
|
+
tool_name: canonicalToolNames[hermesToolName] || hermesToolName,
|
|
4016
|
+
tool_input: {
|
|
4017
|
+
...(payload.tool_input || {}),
|
|
4018
|
+
hermes_tool_name: hermesToolName,
|
|
4019
|
+
},
|
|
4020
|
+
});
|
|
4021
4021
|
let parsed = {};
|
|
4022
4022
|
try { parsed = JSON.parse(verdict); } catch (_e) { parsed = {}; }
|
|
4023
4023
|
const hso = parsed.hookSpecificOutput || {};
|
|
@@ -342,7 +342,7 @@
|
|
|
342
342
|
"id": "self-protect-config",
|
|
343
343
|
"layer": "Execution",
|
|
344
344
|
"toolNames": ["Edit", "Write", "MultiEdit"],
|
|
345
|
-
"pattern": "(?:config/gates/|config/budget\\.json|\\.thumbgate
|
|
345
|
+
"pattern": "(?:config/gates/|config/(?:budget|enforcement|mcp-allowlists)\\.json|\\.thumbgate/config\\.json|thumbgate\\.json)",
|
|
346
346
|
"action": "block",
|
|
347
347
|
"message": "Self-protection: agent cannot modify ThumbGate configuration, gate rules, or budget settings.",
|
|
348
348
|
"severity": "critical",
|
|
@@ -372,7 +372,7 @@
|
|
|
372
372
|
"id": "self-protect-hooks-disable",
|
|
373
373
|
"layer": "Execution",
|
|
374
374
|
"toolNames": ["Edit", "Write", "Bash"],
|
|
375
|
-
"pattern": "(
|
|
375
|
+
"pattern": "(?:\\.claude/settings(?:\\.local)?\\.json|\\.codex/config\\.toml|scripts/hook-[^/]+\\.(?:js|sh))",
|
|
376
376
|
"action": "block",
|
|
377
377
|
"message": "Self-protection: agent cannot modify hook registrations.",
|
|
378
378
|
"severity": "critical",
|
package/config/github-about.json
CHANGED
|
@@ -2,14 +2,11 @@
|
|
|
2
2
|
"repo": "IgorGanapolsky/ThumbGate",
|
|
3
3
|
"repositoryUrl": "https://github.com/IgorGanapolsky/ThumbGate",
|
|
4
4
|
"homepageUrl": "https://thumbgate.ai",
|
|
5
|
-
"githubDescription": "
|
|
6
|
-
"metaDescription": "ThumbGate is the pre-action governance runtime for AI coding agents (Claude Code, Cursor, Codex, Gemini CLI, Amp, Cline, OpenCode): 👍 thumbs
|
|
5
|
+
"githubDescription": "ThumbGate Pre-Action Checks derive rules from repeated failures, flag risky tool calls, hard-block detected secret leaks, and block matches in strict mode.",
|
|
6
|
+
"metaDescription": "ThumbGate is the local pre-action governance runtime for AI coding agents (Claude Code, Cursor, Codex, Gemini CLI, Amp, Cline, OpenCode): accepted 👍 thumbs-up and 👎 thumbs-down feedback becomes history-aware local lessons; repeated failures can become prevention rules. PreToolUse checks flag and log risky tool calls, hard-block detected secret leaks, and block matching actions in strict mode. Pro is for individual operators; Enterprise rollout is scoped after intake.",
|
|
7
7
|
"topics": [
|
|
8
8
|
"thumbgate",
|
|
9
9
|
"pre-action-checks",
|
|
10
|
-
"save-llm-tokens",
|
|
11
|
-
"reduce-llm-cost",
|
|
12
|
-
"ai-cost-optimization",
|
|
13
10
|
"mcp",
|
|
14
11
|
"mcp-server",
|
|
15
12
|
"ai-agents",
|
package/hooks/hooks.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"PreToolUse": [
|
|
4
|
+
{
|
|
5
|
+
"matcher": "Bash|Edit|Write",
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "command",
|
|
9
|
+
"command": "node",
|
|
10
|
+
"args": ["${CLAUDE_PLUGIN_ROOT}/scripts/hook-pre-tool-use.js"]
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"UserPromptSubmit": [
|
|
16
|
+
{
|
|
17
|
+
"hooks": [
|
|
18
|
+
{
|
|
19
|
+
"type": "command",
|
|
20
|
+
"command": "node",
|
|
21
|
+
"args": ["${CLAUDE_PLUGIN_ROOT}/bin/cli.js", "hook-auto-capture"]
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"SessionStart": [
|
|
27
|
+
{
|
|
28
|
+
"hooks": [
|
|
29
|
+
{
|
|
30
|
+
"type": "command",
|
|
31
|
+
"command": "node",
|
|
32
|
+
"args": ["${CLAUDE_PLUGIN_ROOT}/bin/cli.js", "session-start"]
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "thumbgate",
|
|
3
|
-
"version": "1.28.
|
|
4
|
-
"description": "ThumbGate
|
|
3
|
+
"version": "1.28.1",
|
|
4
|
+
"description": "ThumbGate Pre-Action Checks derive rules from repeated failures, flag risky tool calls, hard-block detected secret leaks, and block matches in strict mode.",
|
|
5
5
|
"homepage": "https://thumbgate.ai",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
"scripts/bayes-optimal-gate.js",
|
|
47
47
|
"scripts/belief-update.js",
|
|
48
48
|
"scripts/billing.js",
|
|
49
|
+
"scripts/checkout-attribution-reference.js",
|
|
49
50
|
"scripts/bot-detection.js",
|
|
50
51
|
"scripts/build-metadata.js",
|
|
51
52
|
"scripts/classifier-routing.js",
|
|
@@ -235,6 +236,7 @@
|
|
|
235
236
|
"scripts/workspace-evolver.js",
|
|
236
237
|
"scripts/xmemory-lite.js",
|
|
237
238
|
".claude-plugin/plugin.json",
|
|
239
|
+
"hooks/hooks.json",
|
|
238
240
|
".claude/commands/",
|
|
239
241
|
"commands/",
|
|
240
242
|
".well-known/",
|
|
@@ -280,9 +282,11 @@
|
|
|
280
282
|
"public/learn.html",
|
|
281
283
|
"public/lessons.html",
|
|
282
284
|
"public/numbers.html",
|
|
285
|
+
"public/partner-intake.html",
|
|
283
286
|
"public/pricing.html",
|
|
284
287
|
"public/pro.html",
|
|
285
288
|
"public/assets/brand/",
|
|
289
|
+
"!public/assets/brand/github-social-preview.png",
|
|
286
290
|
"public/assets/claude-thumbgate-statusbar.svg",
|
|
287
291
|
"public/assets/codex-thumbgate-statusbar-test.svg",
|
|
288
292
|
"public/assets/legal-intake-control-flow.svg",
|
|
@@ -383,7 +387,7 @@
|
|
|
383
387
|
"social:prospect:bluesky": "node scripts/social-bluesky-prospecting.js",
|
|
384
388
|
"social:prospect:bluesky:dry": "node scripts/social-bluesky-prospecting.js --dry-run",
|
|
385
389
|
"social:reply-publish:bluesky:dry": "node scripts/social-reply-monitor-bluesky.js --publish-approved --dry-run",
|
|
386
|
-
"test": "npm run test:python && 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:billing-setup && 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:platform-limits && npm run test:post-video && npm run test:post-everywhere-instagram && npm run test:post-everywhere-channels && 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:release-window && npm run test:check-congruence && npm run test:tool-registry && npm run test:repeat-metric && npm run test:noop-detect && npm run test:action-receipts && npm run test:feedback-to-rules && npm run test:memory-firewall && npm run test:memory-scope-readiness && npm run test:belief-update && npm run test:hosted-config && npm run test:operational-summary && npm run test:operational-dashboard && npm run test:operator-artifacts && npm run test:operator-key-auth && npm run test:cloudflare-sandbox && npm run test:mcp-config && npm run test:mcp-tool-annotations && npm run test:mcp-oauth && npm run test:mcp-oauth-flow && npm run test:plan-gate && npm run test:ai-component-inventory && 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:entitlement && npm run test:export-dpo-pairs && npm run test:export-hf-dataset && npm run test:license && npm run test:imperative-detector && npm run test:audit-pr-bot-contamination && npm run test:stripe-bootstrap-saas-catalog && 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:statusline-cache-aggregate && npm run test:public-repo-hygiene && npm run test:no-internal-orchestration-leaks && 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:lesson-semantic-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:predictive-credible-range && 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:lesson-canonical && 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:xss-checkout-escape && 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-archived-product-guard && npm run test:postgres-guard && npm run test:checkout-bot-guard && npm run test:checkout-pro-confirmation-gate && npm run test:pricing-page-telemetry && 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:telemetry-tracked-link-slug && npm run test:prompt-eval && 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:numbers-page && npm run test:workflow-gate-checkpoint && npm run test:lesson-export-import && npm run test:landing-page-claims && npm run test:competitive-positioning-marketing && npm run test:medium-weekly && npm run test:dashboard-deeplink-e2e && npm run test:public-package-parity && npm run test:token-savings-dashboard && npm run test:cursor-wiring && npm run test:pretooluse-injection && npm run test:recent-corrective-context && npm run test:durability-step && npm run test:mailer && npm run test:brand-assets && npm run test:enforcement-teeth && npm run test:bayes-optimal-gate && npm run test:swarm-coordinator && npm run test:session-report && npm run test:agent-reasoning-traces && npm run test:judge-reward && npm run test:llm-behavior-monitor && npm run test:prompting-os && npm run test:single-use-credential-gate && npm run test:structured-prompt-driven && npm run test:require-evidence-gate && npm run test:rule-validator && npm run test:bluesky-atproto && npm run test:social-reply-monitor-bluesky && npm run test:bluesky-delete-replies && npm run test:architect-kit-memory-bridge && npm run test:sonar-review-hotspots && npm run test:actionable-remediations && npm run test:gemini-embedding-policy && npm run test:agent-design-governance && npm run test:public-core-boundary && npm run test:hook-stop-verify-deploy && npm run test:hook-stop-anti-claim && npm run test:plausible-server-events && npm run test:activation-tracker && npm run test:activation-onboarding && npm run test:unified-revenue-rollup && npm run test:conversion-rate-stats && npm run test:external-customer-audit && npm run test:telemetry-export && npm run test:stripe-checkout-diagnostic && npm run test:stripe-business-identity-probe && npm run test:revenue-observability-doctor && npm run test:public-bundle-ratchet && npm run test:pack-runtime-integrity && npm run test:hook-self-protection && npm run test:self-protect-enforcement && npm run test:stripe-payment-link-update && npm run test:ci-cd-hygiene-audit && npm run test:verify-marketing-pages-deployed && npm run test:install-email-capture && npm run test:install-shim && npm run test:hook-runtime-subcommands && npm run test:implementation-notes && npm run test:daily-block-cap && npm run test:free-to-paid-conversion-units && npm run test:metrics-real-endpoint && npm run test:cli-trial-and-help && npm run test:cost-cli && npm run test:silent-failure-cluster && npm run test:proof:truth && node --test tests/adaptive-reliability.test.js && npm run test:mcp-oauth-reviewer && npm run test:dfcx-gate && npm run test:dfcx-gate-server && npm run test:vertex-scorer && npm run test:dashboard-chat && npm run test:gitar-integration && npm run test:secret-redaction && npm run test:discoverable-skills && npm run test:discoverable-skill-skills && npm run test:sync-telemetry && npm run test:leak-scanner && npm run test:team-sync && npm run test:eval-rag && npm run test:async-eval-observability && npm run test:letta-adapter && npm run test:policy-engine-adapter && npm run test:tool-contract-validator && npm run test:check-update && npm run test:hermes-gate && npm run test:memory-provider-enforcement-bridge && npm run test:publisher-credential-guards && npm run test:reddit-browser-notification-watch && npm run test:payment-rails && npm run test:cursor-marketplace-doctor && npm run test:okara-money-promo-automation",
|
|
390
|
+
"test": "npm run test:python && 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:billing-setup && 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:platform-limits && npm run test:post-video && npm run test:post-everywhere-instagram && npm run test:post-everywhere-channels && 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:release-window && npm run test:check-congruence && npm run test:tool-registry && npm run test:repeat-metric && npm run test:noop-detect && npm run test:action-receipts && npm run test:feedback-to-rules && npm run test:memory-firewall && npm run test:memory-scope-readiness && npm run test:belief-update && npm run test:hosted-config && npm run test:operational-summary && npm run test:operational-dashboard && npm run test:operator-artifacts && npm run test:operator-key-auth && npm run test:cloudflare-sandbox && npm run test:mcp-config && npm run test:mcp-tool-annotations && npm run test:mcp-oauth && npm run test:mcp-oauth-flow && npm run test:plan-gate && npm run test:ai-component-inventory && 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:entitlement && npm run test:export-dpo-pairs && npm run test:export-hf-dataset && npm run test:license && npm run test:imperative-detector && npm run test:audit-pr-bot-contamination && npm run test:stripe-bootstrap-saas-catalog && 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:statusline-cache-aggregate && npm run test:public-repo-hygiene && npm run test:no-internal-orchestration-leaks && 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:lesson-semantic-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:predictive-credible-range && 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:lesson-canonical && 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:xss-checkout-escape && 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-archived-product-guard && npm run test:postgres-guard && npm run test:checkout-bot-guard && npm run test:checkout-pro-confirmation-gate && npm run test:pricing-page-telemetry && 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:telemetry-tracked-link-slug && npm run test:prompt-eval && 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:numbers-page && npm run test:workflow-gate-checkpoint && npm run test:lesson-export-import && npm run test:landing-page-claims && npm run test:competitive-positioning-marketing && npm run test:medium-weekly && npm run test:dashboard-deeplink-e2e && npm run test:public-package-parity && npm run test:token-savings-dashboard && npm run test:cursor-wiring && npm run test:pretooluse-injection && npm run test:recent-corrective-context && npm run test:durability-step && npm run test:mailer && npm run test:brand-assets && npm run test:enforcement-teeth && npm run test:bayes-optimal-gate && npm run test:swarm-coordinator && npm run test:session-report && npm run test:agent-reasoning-traces && npm run test:judge-reward && npm run test:llm-behavior-monitor && npm run test:prompting-os && npm run test:single-use-credential-gate && npm run test:structured-prompt-driven && npm run test:require-evidence-gate && npm run test:rule-validator && npm run test:bluesky-atproto && npm run test:social-reply-monitor-bluesky && npm run test:bluesky-delete-replies && npm run test:architect-kit-memory-bridge && npm run test:sonar-review-hotspots && npm run test:actionable-remediations && npm run test:gemini-embedding-policy && npm run test:agent-design-governance && npm run test:public-core-boundary && npm run test:hook-stop-verify-deploy && npm run test:hook-stop-anti-claim && npm run test:plausible-server-events && npm run test:activation-tracker && npm run test:activation-onboarding && npm run test:unified-revenue-rollup && npm run test:conversion-rate-stats && npm run test:external-customer-audit && npm run test:telemetry-export && npm run test:stripe-checkout-diagnostic && npm run test:stripe-business-identity-probe && npm run test:revenue-observability-doctor && npm run test:public-bundle-ratchet && npm run test:pack-runtime-integrity && npm run test:hook-self-protection && npm run test:self-protect-enforcement && npm run test:never-bypass-branch-protection && npm run test:stripe-payment-link-update && npm run test:ci-cd-hygiene-audit && npm run test:verify-marketing-pages-deployed && npm run test:install-email-capture && npm run test:install-shim && npm run test:hook-runtime-subcommands && npm run test:implementation-notes && npm run test:daily-block-cap && npm run test:free-to-paid-conversion-units && npm run test:metrics-real-endpoint && npm run test:cli-trial-and-help && npm run test:cost-cli && npm run test:silent-failure-cluster && npm run test:proof:truth && node --test tests/adaptive-reliability.test.js && npm run test:mcp-oauth-reviewer && npm run test:dfcx-gate && npm run test:dfcx-gate-server && npm run test:vertex-scorer && npm run test:dashboard-chat && npm run test:gitar-integration && npm run test:secret-redaction && npm run test:discoverable-skills && npm run test:discoverable-skill-skills && npm run test:sync-telemetry && npm run test:leak-scanner && npm run test:team-sync && npm run test:eval-rag && npm run test:async-eval-observability && npm run test:letta-adapter && npm run test:policy-engine-adapter && npm run test:tool-contract-validator && npm run test:check-update && npm run test:hermes-gate && npm run test:memory-provider-enforcement-bridge && npm run test:publisher-credential-guards && npm run test:reddit-browser-notification-watch && npm run test:payment-rails && npm run test:service-checkout-price-integrity && npm run test:cursor-marketplace-doctor && npm run test:plugin-hooks-manifest && npm run test:okara-money-promo-automation",
|
|
387
391
|
"test:python": "python3 -m pytest tests/*.py",
|
|
388
392
|
"test:check-update": "node --test tests/check-update.test.js",
|
|
389
393
|
"test:hook-stop-verify-deploy": "node --test tests/hook-stop-verify-deploy.test.js",
|
|
@@ -444,7 +448,7 @@
|
|
|
444
448
|
"test:memory-dedup": "node --test tests/memory-dedup.test.js",
|
|
445
449
|
"test:lesson-db": "node --test tests/lesson-db.test.js",
|
|
446
450
|
"test:lesson-rotation": "node --test tests/lesson-rotation.test.js",
|
|
447
|
-
"test:feedback-quality": "node --test tests/feedback-quality.test.js",
|
|
451
|
+
"test:feedback-quality": "node --test tests/feedback-quality.test.js tests/feedback-event-idempotency.test.js",
|
|
448
452
|
"test:sync-version": "node --test tests/sync-version.test.js",
|
|
449
453
|
"test:release-window": "node --test tests/release-window.test.js",
|
|
450
454
|
"test:team-sync": "node --test tests/team-sync.test.js",
|
|
@@ -512,11 +516,11 @@
|
|
|
512
516
|
"test:training-export": "node --test tests/training-export.test.js tests/databricks-export.test.js",
|
|
513
517
|
"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/public-package-boundary.test.js",
|
|
514
518
|
"test:operational-integrity": "node --test tests/operational-integrity.test.js tests/sync-branch-protection.test.js",
|
|
515
|
-
"test:workflow": "node --test tests/parallel-workflow.test.js tests/workflow-contract.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/revenue-pack-utils.test.js tests/sales-pipeline.test.js tests/github-outreach.test.js tests/enterprise-story.test.js tests/guide-conversion-path.test.js tests/buyer-intent-revenue-assist.test.js",
|
|
519
|
+
"test:workflow": "node --test tests/parallel-workflow.test.js tests/workflow-contract.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/revenue-pack-utils.test.js tests/apollo-acquisition.test.js tests/sales-pipeline.test.js tests/github-outreach.test.js tests/enterprise-story.test.js tests/guide-conversion-path.test.js tests/buyer-intent-revenue-assist.test.js",
|
|
516
520
|
"test:sales-pipeline": "node --test tests/sales-pipeline.test.js",
|
|
517
|
-
"test:billing": "node --test tests/billing.test.js tests/stripe-sync-product-images.test.js",
|
|
521
|
+
"test:billing": "node --test tests/billing.test.js tests/stripe-sync-product-images.test.js tests/checkout-attribution-reference.test.js",
|
|
518
522
|
"test:billing-setup": "node --test tests/billing-setup-redaction.test.js",
|
|
519
|
-
"test:cli": "node --test tests/analytics-report.test.js tests/agent-design-governance.test.js tests/codex-self-heal.test.js tests/creator-campaigns.test.js tests/cli.test.js tests/codex-bridge-script.test.js tests/dependabot-changeset.test.js tests/dispatch-brief.test.js tests/feedback-normalize.test.js tests/install-mcp.test.js tests/install-scope-docs.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 tests/creator-dev-and-prune.test.js",
|
|
523
|
+
"test:cli": "node --test tests/analytics-report.test.js tests/agent-design-governance.test.js tests/codex-self-heal.test.js tests/creator-campaigns.test.js tests/cli.test.js tests/codex-bridge-script.test.js tests/dependabot-changeset.test.js tests/dispatch-brief.test.js tests/feedback-normalize.test.js tests/feedback-lesson-sanitization.test.js tests/install-mcp.test.js tests/install-scope-docs.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 tests/creator-dev-and-prune.test.js",
|
|
520
524
|
"test:evolution": "node --test tests/workspace-evolver.test.js",
|
|
521
525
|
"test:watcher": "node --test tests/jsonl-watcher.test.js",
|
|
522
526
|
"test:autoresearch": "node --test tests/autoresearch.test.js",
|
|
@@ -637,13 +641,16 @@
|
|
|
637
641
|
"test:product-feedback": "node --test tests/product-feedback.test.js",
|
|
638
642
|
"test:feedback-root-consolidator": "node --test tests/feedback-root-consolidator.test.js",
|
|
639
643
|
"social:publish:launch": "node scripts/social-analytics/publish-thumbgate-launch.js",
|
|
644
|
+
"social:publish:latest-release-article": "node scripts/social-analytics/publish-latest-release-article.js",
|
|
645
|
+
"social:publish:latest-release-fallbacks": "node scripts/social-analytics/publish-latest-release-fallbacks.js",
|
|
646
|
+
"social:verify:latest-release": "node scripts/social-analytics/verify-latest-release-posts.js",
|
|
640
647
|
"social:schedule:campaign": "node scripts/social-analytics/schedule-thumbgate-campaign.js",
|
|
641
648
|
"social:install:growth": "node scripts/social-analytics/install-growth-automation.js",
|
|
642
649
|
"social:reconcile:campaign": "node scripts/social-analytics/reconcile-thumbgate-campaign.js",
|
|
643
650
|
"social:sync:launch-assets": "node scripts/social-analytics/sync-launch-assets.js",
|
|
644
651
|
"social:engagement:audit": "node scripts/social-analytics/engagement-audit.js",
|
|
645
652
|
"test:install-growth-automation": "node --test tests/install-growth-automation.test.js",
|
|
646
|
-
"test:publish-thumbgate-launch": "node --test tests/publish-thumbgate-launch.test.js",
|
|
653
|
+
"test:publish-thumbgate-launch": "node --test tests/publish-thumbgate-launch.test.js tests/publish-latest-release-article.test.js tests/latest-release-campaign-ops.test.js",
|
|
647
654
|
"test:reconcile-thumbgate-campaign": "node --test tests/reconcile-thumbgate-campaign.test.js",
|
|
648
655
|
"test:schedule-thumbgate-campaign": "node --test tests/schedule-thumbgate-campaign.test.js",
|
|
649
656
|
"test:social-reply-monitor": "node --test tests/social-reply-monitor.test.js tests/reddit-monitor-launchd.test.js",
|
|
@@ -762,12 +769,15 @@
|
|
|
762
769
|
"eval:observability": "node scripts/async-eval-observability.js",
|
|
763
770
|
"test:memory-provider-enforcement-bridge": "node --test tests/memory-provider-enforcement-bridge.test.js",
|
|
764
771
|
"test:payment-rails": "node --test tests/payment-rails.test.js",
|
|
772
|
+
"test:service-checkout-price-integrity": "node --test tests/service-checkout-price-integrity.test.js",
|
|
765
773
|
"test:publisher-credential-guards": "node --test tests/publisher-credential-guards.test.js",
|
|
766
774
|
"test:reddit-browser-notification-watch": "node --test tests/reddit-browser-notification-watch.test.js",
|
|
767
775
|
"cursor:marketplace:doctor": "node scripts/cursor-marketplace-doctor.js",
|
|
768
776
|
"cursor:marketplace:doctor:json": "node scripts/cursor-marketplace-doctor.js --json",
|
|
769
777
|
"test:cursor-marketplace-doctor": "node --test tests/cursor-marketplace-doctor.test.js",
|
|
778
|
+
"test:plugin-hooks-manifest": "node --test tests/plugin-hooks-manifest.test.js",
|
|
770
779
|
"test:hook-self-protection": "node --test tests/hook-self-protection.test.js",
|
|
780
|
+
"test:never-bypass-branch-protection": "node --test tests/never-bypass-branch-protection.test.js",
|
|
771
781
|
"test:self-protect-enforcement": "node --test tests/self-protect-enforcement.test.js",
|
|
772
782
|
"test:pack-runtime-integrity": "node --test tests/pack-runtime-integrity.test.js",
|
|
773
783
|
"test:entitlement": "node --test tests/entitlement.test.js",
|
package/public/chatgpt-app.html
CHANGED
|
@@ -230,7 +230,7 @@
|
|
|
230
230
|
</div>
|
|
231
231
|
<div class="screen">
|
|
232
232
|
<div class="message">Before I run this migration, check whether this repeats a rejected deploy pattern.</div>
|
|
233
|
-
<div class="message"><strong>ThumbGate:</strong> Require evidence first: test output, rollback path, and the exact affected tables. Then install the local gate so future risky actions are flagged and logged before execution (and hard-blocked for
|
|
233
|
+
<div class="message"><strong>ThumbGate:</strong> Require evidence first: test output, rollback path, and the exact affected tables. Then install the local gate so future risky actions are flagged and logged before execution (and hard-blocked for secret exfiltration and guardrail-tampering by default, or under strict mode).</div>
|
|
234
234
|
<code class="code">thumbs down: agent claimed the release was published before checking npm and CI</code>
|
|
235
235
|
<code class="code">npx thumbgate init --agent codex</code>
|
|
236
236
|
</div>
|
|
@@ -239,7 +239,7 @@
|
|
|
239
239
|
|
|
240
240
|
<section aria-labelledby="what-ships">
|
|
241
241
|
<h2 class="section-title" id="what-ships">What ships today</h2>
|
|
242
|
-
<p class="section-copy">This is the ChatGPT-facing distribution page. It keeps the claim precise: ChatGPT is the discovery, advice, checkpointing, and typed-feedback surface. The enforcement — flag and log by default, hard-block for
|
|
242
|
+
<p class="section-copy">This is the ChatGPT-facing distribution page. It keeps the claim precise: ChatGPT is the discovery, advice, checkpointing, and typed-feedback surface. The enforcement — flag and log by default, hard-block for secret exfiltration and guardrail-tampering by default, or every rule under strict mode — still runs in the local agent or CI lane.</p>
|
|
243
243
|
<div class="grid">
|
|
244
244
|
<article class="card">
|
|
245
245
|
<h3>Live GPT entrypoint</h3>
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
</div>
|
|
79
79
|
<div class="card">
|
|
80
80
|
<h3>Promote repeat failures to PreToolUse gates</h3>
|
|
81
|
-
<p>When the same agent mistake shows up twice, ThumbGate distills it into a prevention rule and flags the next attempt at the tool-call boundary — hard-blocking it for
|
|
81
|
+
<p>When the same agent mistake shows up twice, ThumbGate distills it into a prevention rule and flags the next attempt at the tool-call boundary — hard-blocking it for secret exfiltration and guardrail-tampering by default, or every rule under strict enforcement — with the rule that fired in the agent's reasoning trace, so Codex chooses a safer plan instead of being told to "be more careful."</p>
|
|
82
82
|
</div>
|
|
83
83
|
<div class="card">
|
|
84
84
|
<h3>Audit trail enterprise procurement requires</h3>
|
package/public/codex-plugin.html
CHANGED
|
@@ -256,7 +256,7 @@ $ npx thumbgate feedback-self-test
|
|
|
256
256
|
</div>
|
|
257
257
|
<div class="tile">
|
|
258
258
|
<h3>Checks before action</h3>
|
|
259
|
-
<p>Pre-Action Checks evaluate commands, file edits, publishes, merges, and other high-risk actions before execution. Bad repeats are flagged and logged before they burn time or tokens — and hard-blocked for
|
|
259
|
+
<p>Pre-Action Checks evaluate commands, file edits, publishes, merges, and other high-risk actions before execution. Bad repeats are flagged and logged before they burn time or tokens — and hard-blocked for secret exfiltration and guardrail-tampering by default (destructive deletes, force-push, and supply-chain warn by default) or when strict enforcement is enabled.</p>
|
|
260
260
|
</div>
|
|
261
261
|
</section>
|
|
262
262
|
|
package/public/diagnostic.html
CHANGED
|
@@ -252,7 +252,7 @@ footer { padding: 32px 0 44px; color: var(--muted); }
|
|
|
252
252
|
<option>We need an independent proof checklist first</option>
|
|
253
253
|
</select>
|
|
254
254
|
<button type="submit" data-revenue-cta data-cta-id="diagnostic_page_submit" data-cta-placement="intake">Submit for diagnostic scope</button>
|
|
255
|
-
<p class="hint">Ready to pay now? Use the $499 diagnostic checkout above. If the workflow needs fit review first, submit it here and we will route you to the diagnostic or sprint only when the scope is real.</p>
|
|
255
|
+
<p class="hint" data-diagnostic-payment-hint>Ready to pay now? Use the $499 diagnostic checkout above. If the workflow needs fit review first, submit it here and we will route you to the diagnostic or sprint only when the scope is real.</p>
|
|
256
256
|
</form>
|
|
257
257
|
</div>
|
|
258
258
|
<section>
|
|
@@ -295,6 +295,28 @@ footer { padding: 32px 0 44px; color: var(--muted); }
|
|
|
295
295
|
<script>
|
|
296
296
|
(function () {
|
|
297
297
|
const search = new URLSearchParams(window.location.search);
|
|
298
|
+
const paidCta = document.querySelector('[data-cta-id="diagnostic_hero_paid"]');
|
|
299
|
+
const inboundSource = search.get('utm_source') || search.get('source');
|
|
300
|
+
const isAiventyxTraffic = String(inboundSource || '').trim().toLowerCase() === 'aiventyx';
|
|
301
|
+
if (paidCta && isAiventyxTraffic) {
|
|
302
|
+
paidCta.remove();
|
|
303
|
+
const paymentHint = document.querySelector('[data-diagnostic-payment-hint]');
|
|
304
|
+
if (paymentHint) {
|
|
305
|
+
paymentHint.textContent = 'Submit the workflow here. Aiventyx will collect payment on its checkout once the scope is accepted.';
|
|
306
|
+
}
|
|
307
|
+
} else if (paidCta) {
|
|
308
|
+
const href = new URL(paidCta.getAttribute('href'), window.location.origin);
|
|
309
|
+
const passthrough = /^(utm_(source|medium|campaign|content|term)|source|acquisition_id|visitor_id|session_id|visitor_session_id|install_id|trace_id|creator|community|post_id|comment_id|campaign_variant|offer_code|referrer_host)$/i;
|
|
310
|
+
for (const [key, value] of search.entries()) {
|
|
311
|
+
if (!passthrough.test(key) || !value.trim()) continue;
|
|
312
|
+
href.searchParams.set(key, value.trim());
|
|
313
|
+
}
|
|
314
|
+
if (inboundSource && inboundSource.trim()) {
|
|
315
|
+
href.searchParams.set('utm_source', inboundSource.trim());
|
|
316
|
+
}
|
|
317
|
+
paidCta.setAttribute('href', `${href.pathname}${href.search}${href.hash}`);
|
|
318
|
+
}
|
|
319
|
+
|
|
298
320
|
const form = document.querySelector('[data-diagnostic-intake-form]');
|
|
299
321
|
if (form) {
|
|
300
322
|
for (const [key, value] of search.entries()) {
|