thumbgate 1.21.1 → 1.22.0
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 +109 -1
- package/adapters/opencode/opencode.json +1 -1
- package/bin/cli.js +95 -81
- package/config/mcp-allowlists.json +12 -6
- package/package.json +15 -5
- package/public/agent-manager.html +1 -1
- package/public/codex-enterprise.html +123 -0
- package/public/dashboard.html +15 -2
- package/public/index.html +12 -5
- package/public/lessons.html +12 -0
- package/public/numbers.html +2 -2
- package/scripts/audit.js +65 -0
- package/scripts/auto-wire-hooks.js +14 -0
- package/scripts/build-metadata.js +32 -13
- package/scripts/cli-schema.js +8 -0
- package/scripts/gate-stats.js +89 -0
- package/scripts/gates-engine.js +14 -0
- package/scripts/hook-runtime.js +20 -14
- package/scripts/statusline.sh +41 -30
- package/scripts/tool-registry.js +18 -0
- package/src/api/server.js +59 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "thumbgate-marketplace",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.22.0",
|
|
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.
|
|
17
|
+
"version": "1.22.0",
|
|
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.
|
|
4
|
+
"version": "1.22.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Igor Ganapolsky",
|
|
7
7
|
"email": "ig5973700@gmail.com",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "thumbgate",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.22.0",
|
|
4
4
|
"description": "ThumbGate — 👍👎 feedback that teaches your AI agent. Thumbs down a mistake, it never happens again.",
|
|
5
5
|
"homepage": "https://thumbgate-production.up.railway.app",
|
|
6
6
|
"transport": "stdio",
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
"mcpServers": {
|
|
3
3
|
"thumbgate": {
|
|
4
4
|
"command": "npx",
|
|
5
|
-
"args": ["--yes", "--package", "thumbgate@1.
|
|
5
|
+
"args": ["--yes", "--package", "thumbgate@1.22.0", "thumbgate", "serve"]
|
|
6
6
|
}
|
|
7
7
|
},
|
|
8
8
|
"hooks": {
|
|
9
9
|
"preToolUse": {
|
|
10
10
|
"command": "npx",
|
|
11
|
-
"args": ["--yes", "--package", "thumbgate@1.
|
|
11
|
+
"args": ["--yes", "--package", "thumbgate@1.22.0", "thumbgate", "gate-check"]
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
}
|
|
@@ -216,7 +216,7 @@ const {
|
|
|
216
216
|
finalizeSession: finalizeFeedbackSession,
|
|
217
217
|
} = require('../../scripts/feedback-session');
|
|
218
218
|
|
|
219
|
-
const SERVER_INFO = { name: 'thumbgate-mcp', version: '1.
|
|
219
|
+
const SERVER_INFO = { name: 'thumbgate-mcp', version: '1.22.0' };
|
|
220
220
|
const COMMERCE_CATEGORIES = [
|
|
221
221
|
'product_recommendation',
|
|
222
222
|
'brand_compliance',
|
|
@@ -368,6 +368,111 @@ function buildRecallResponse(args = {}) {
|
|
|
368
368
|
return toTextResult(text);
|
|
369
369
|
}
|
|
370
370
|
|
|
371
|
+
function buildSuggestFixResponse(args = {}) {
|
|
372
|
+
const context = String(args.context || '').trim();
|
|
373
|
+
const rawLimit = Number(args.limit);
|
|
374
|
+
const limit = Number.isFinite(rawLimit) && rawLimit > 0 ? Math.min(rawLimit, 5) : 3;
|
|
375
|
+
|
|
376
|
+
// If no context provided, return generic suggestion
|
|
377
|
+
if (!context) {
|
|
378
|
+
return toTextResult({
|
|
379
|
+
suggestions: [
|
|
380
|
+
{
|
|
381
|
+
action: 'Capture feedback about what went wrong so ThumbGate can learn and prevent recurrence.',
|
|
382
|
+
source: 'generic',
|
|
383
|
+
},
|
|
384
|
+
],
|
|
385
|
+
query: '',
|
|
386
|
+
totalFound: 0,
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// Search lessons via lesson-search module
|
|
391
|
+
const lessonModule = loadPrivateMcpModule('lessonSearch');
|
|
392
|
+
let lessonActions = [];
|
|
393
|
+
if (lessonModule) {
|
|
394
|
+
try {
|
|
395
|
+
const searchResult = lessonModule.searchLessons(context, { limit: 10 });
|
|
396
|
+
const results = Array.isArray(searchResult && searchResult.results) ? searchResult.results : [];
|
|
397
|
+
for (const result of results) {
|
|
398
|
+
const correctiveActions = (result.systemResponse && Array.isArray(result.systemResponse.correctiveActions))
|
|
399
|
+
? result.systemResponse.correctiveActions
|
|
400
|
+
: [];
|
|
401
|
+
for (const action of correctiveActions) {
|
|
402
|
+
const text = String(action.text || '').trim();
|
|
403
|
+
if (text) {
|
|
404
|
+
lessonActions.push({
|
|
405
|
+
action: text,
|
|
406
|
+
source: action.source || `lesson:${result.id || 'unknown'}`,
|
|
407
|
+
score: result.score || 0,
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
// Also pick up lesson-level howToAvoid / actionNeeded when no explicit correctiveActions
|
|
412
|
+
if (correctiveActions.length === 0 && result.lesson) {
|
|
413
|
+
const text = result.lesson.howToAvoid || result.lesson.actionNeeded || '';
|
|
414
|
+
if (text) {
|
|
415
|
+
lessonActions.push({
|
|
416
|
+
action: String(text).trim(),
|
|
417
|
+
source: `lesson:${result.id || 'unknown'}`,
|
|
418
|
+
score: result.score || 0,
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
} catch {
|
|
424
|
+
// lesson search failure is non-fatal
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Search prevention rules directly via lesson-search module's helper
|
|
429
|
+
let ruleActions = [];
|
|
430
|
+
try {
|
|
431
|
+
const { readPreventionRuleMatches } = require('../../scripts/lesson-search');
|
|
432
|
+
const ruleMatches = readPreventionRuleMatches(context, limit);
|
|
433
|
+
for (const rule of ruleMatches) {
|
|
434
|
+
const text = rule.summary || rule.title || '';
|
|
435
|
+
if (text) {
|
|
436
|
+
ruleActions.push({
|
|
437
|
+
action: String(text).trim(),
|
|
438
|
+
source: `rule:${String(rule.title || 'prevention_rules').trim()}`,
|
|
439
|
+
score: rule.score || 0,
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
} catch {
|
|
444
|
+
// rule search failure is non-fatal
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// Merge, deduplicate, sort by score, and take top `limit`
|
|
448
|
+
const seen = new Set();
|
|
449
|
+
const all = [...lessonActions, ...ruleActions]
|
|
450
|
+
.filter((item) => {
|
|
451
|
+
if (!item.action) return false;
|
|
452
|
+
const key = item.action.toLowerCase();
|
|
453
|
+
if (seen.has(key)) return false;
|
|
454
|
+
seen.add(key);
|
|
455
|
+
return true;
|
|
456
|
+
})
|
|
457
|
+
.sort((a, b) => (b.score || 0) - (a.score || 0))
|
|
458
|
+
.slice(0, limit)
|
|
459
|
+
.map(({ action, source }) => ({ action, source }));
|
|
460
|
+
|
|
461
|
+
// If nothing matched, add generic fallback
|
|
462
|
+
if (all.length === 0) {
|
|
463
|
+
all.push({
|
|
464
|
+
action: 'No matching lessons or rules found. Capture feedback via capture_feedback so ThumbGate can learn from this failure.',
|
|
465
|
+
source: 'generic',
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
return toTextResult({
|
|
470
|
+
suggestions: all,
|
|
471
|
+
query: context,
|
|
472
|
+
totalFound: all.length,
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
|
|
371
476
|
function buildDiagnoseFailureResponse(args = {}) {
|
|
372
477
|
let intentPlan = null;
|
|
373
478
|
const requestedProfile = args.mcpProfile || getActiveMcpProfile();
|
|
@@ -579,6 +684,8 @@ async function callToolInner(name, args) {
|
|
|
579
684
|
tags: Array.isArray(args.tags) ? args.tags : [],
|
|
580
685
|
}));
|
|
581
686
|
}
|
|
687
|
+
case 'suggest_fix':
|
|
688
|
+
return buildSuggestFixResponse(args);
|
|
582
689
|
case 'retrieve_lessons': {
|
|
583
690
|
// Cross-encoder reranking: retrieve more candidates, then rerank for precision
|
|
584
691
|
const { retrieveWithRerankingSync } = loadOptionalModule(path.join(__dirname, '../../scripts/cross-encoder-reranker'), () => ({
|
|
@@ -1330,6 +1437,7 @@ module.exports = {
|
|
|
1330
1437
|
acquireLock,
|
|
1331
1438
|
toCaptureFeedbackTextResult,
|
|
1332
1439
|
formatCorrectiveActionsReminder,
|
|
1440
|
+
buildSuggestFixResponse,
|
|
1333
1441
|
__test__: {
|
|
1334
1442
|
PRIVATE_MCP_MODULES,
|
|
1335
1443
|
loadPrivateMcpModule,
|
package/bin/cli.js
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
* npx thumbgate background-governance # background-agent run report + risk check
|
|
24
24
|
* npx thumbgate cfo # local operational billing summary
|
|
25
25
|
* npx thumbgate pro # solo dashboard + exports side lane
|
|
26
|
+
* npx thumbgate audit <file> # audit an agent transcript for repeat-mistake token waste
|
|
26
27
|
*/
|
|
27
28
|
|
|
28
29
|
'use strict';
|
|
@@ -40,13 +41,6 @@ const {
|
|
|
40
41
|
resolveMcpEntry,
|
|
41
42
|
} = require(path.join(__dirname, '..', 'scripts', 'mcp-config'));
|
|
42
43
|
const { trackEvent } = require(path.join(__dirname, '..', 'scripts', 'cli-telemetry'));
|
|
43
|
-
const {
|
|
44
|
-
cacheUpdateHookCommand,
|
|
45
|
-
preToolHookCommand,
|
|
46
|
-
sessionStartHookCommand,
|
|
47
|
-
statuslineCommand,
|
|
48
|
-
userPromptHookCommand,
|
|
49
|
-
} = require(path.join(__dirname, '..', 'scripts', 'hook-runtime'));
|
|
50
44
|
const {
|
|
51
45
|
PRO_MONTHLY_PAYMENT_LINK,
|
|
52
46
|
PRO_PRICE_LABEL,
|
|
@@ -395,84 +389,24 @@ function whichExists(cmd) {
|
|
|
395
389
|
|
|
396
390
|
function setupClaude() {
|
|
397
391
|
const mcpChanged = mergeMcpJson(path.join(CWD, '.mcp.json'), 'Claude Code', 'project');
|
|
392
|
+
const { wireHooks } = require(path.join(PKG_ROOT, 'scripts', 'auto-wire-hooks'));
|
|
393
|
+
const hookResult = wireHooks({ agent: 'claude-code' });
|
|
398
394
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
// same hook set. Before this, `install` shipped a Claude config with no
|
|
403
|
-
// PreToolUse gate — the core ThumbGate feature was silently missing.
|
|
404
|
-
let wireChanged = false;
|
|
405
|
-
try {
|
|
406
|
-
const { wireHooks } = require(path.join(PKG_ROOT, 'scripts', 'auto-wire-hooks'));
|
|
407
|
-
const wireResult = wireHooks({ agent: 'claude-code' });
|
|
408
|
-
if (wireResult.error) {
|
|
409
|
-
console.log(` Claude Code: ${wireResult.error}`);
|
|
410
|
-
} else if (wireResult.changed) {
|
|
411
|
-
wireChanged = true;
|
|
412
|
-
const lifecycles = [...new Set(wireResult.added.map((h) => h.lifecycle))].join(', ');
|
|
413
|
-
console.log(` Claude Code: wired gate hooks (${lifecycles})`);
|
|
414
|
-
}
|
|
415
|
-
} catch (err) {
|
|
416
|
-
console.log(` Claude Code: hook wiring skipped (${err.message})`);
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
// Upsert Stop hook into .claude/settings.json for autonomous self-scoring
|
|
420
|
-
const settingsPath = path.join(CWD, '.claude', 'settings.json');
|
|
421
|
-
const stopHookCommand = 'bash scripts/hook-stop-self-score.sh';
|
|
422
|
-
|
|
423
|
-
let settings = { hooks: {} };
|
|
424
|
-
if (fs.existsSync(settingsPath)) {
|
|
425
|
-
try { settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8')); } catch (_) { /* fresh */ }
|
|
426
|
-
}
|
|
427
|
-
settings.hooks = settings.hooks || {};
|
|
428
|
-
|
|
429
|
-
const stopAlreadyPresent = (settings.hooks.Stop || [])
|
|
430
|
-
.some(entry => (entry.hooks || []).some(h => h.command === stopHookCommand));
|
|
431
|
-
|
|
432
|
-
let hooksChanged = false;
|
|
433
|
-
if (!stopAlreadyPresent) {
|
|
434
|
-
settings.hooks.Stop = settings.hooks.Stop || [];
|
|
435
|
-
settings.hooks.Stop.push({ hooks: [{ type: 'command', command: stopHookCommand }] });
|
|
436
|
-
hooksChanged = true;
|
|
437
|
-
console.log(' Claude Code: installed Stop hook');
|
|
395
|
+
if (hookResult.error) {
|
|
396
|
+
console.log(` Claude Code hooks: ${hookResult.error}`);
|
|
397
|
+
return mcpChanged;
|
|
438
398
|
}
|
|
439
399
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
hooksChanged = true;
|
|
448
|
-
}
|
|
449
|
-
const cacheAlreadyPresent = (settings.hooks.PostToolUse || [])
|
|
450
|
-
.some(entry => (entry.hooks || []).some(h => h.command === cacheHookCommand || (h.command && h.command.includes('cache-update'))));
|
|
451
|
-
|
|
452
|
-
if (!cacheAlreadyPresent) {
|
|
453
|
-
settings.hooks.PostToolUse = settings.hooks.PostToolUse || [];
|
|
454
|
-
settings.hooks.PostToolUse.push({
|
|
455
|
-
matcher: 'mcp__thumbgate__feedback_stats|mcp__thumbgate__dashboard',
|
|
456
|
-
hooks: [{ type: 'command', command: cacheHookCommand }]
|
|
457
|
-
});
|
|
458
|
-
hooksChanged = true;
|
|
459
|
-
console.log(' Claude Code: installed ThumbGate cache updater hook');
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
// Upsert statusLine for ThumbGate feedback display
|
|
463
|
-
const statuslineScript = statuslineCommand();
|
|
464
|
-
if (!settings.statusLine || settings.statusLine.command !== statuslineScript) {
|
|
465
|
-
settings.statusLine = { type: 'command', command: statuslineScript };
|
|
466
|
-
hooksChanged = true;
|
|
467
|
-
console.log(' Claude Code: installed ThumbGate status line');
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
if (hooksChanged) {
|
|
471
|
-
fs.mkdirSync(path.dirname(settingsPath), { recursive: true });
|
|
472
|
-
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
|
|
400
|
+
if (!hookResult.changed) {
|
|
401
|
+
console.log(` Claude Code hooks: already configured at ${hookResult.settingsPath}`);
|
|
402
|
+
} else {
|
|
403
|
+
for (const h of hookResult.added) {
|
|
404
|
+
console.log(` Claude Code: wired ${h.lifecycle} hook`);
|
|
405
|
+
}
|
|
406
|
+
console.log(` Claude Code settings: ${hookResult.settingsPath}`);
|
|
473
407
|
}
|
|
474
408
|
|
|
475
|
-
return mcpChanged ||
|
|
409
|
+
return mcpChanged || hookResult.changed;
|
|
476
410
|
}
|
|
477
411
|
|
|
478
412
|
function setupCodex() {
|
|
@@ -744,7 +678,11 @@ function init(cliArgs = parseArgs(process.argv.slice(3))) {
|
|
|
744
678
|
let configured = 0;
|
|
745
679
|
|
|
746
680
|
const platforms = [
|
|
747
|
-
{ name: 'Claude Code', detect: [
|
|
681
|
+
{ name: 'Claude Code', detect: [
|
|
682
|
+
() => whichExists('claude'),
|
|
683
|
+
() => fs.existsSync(path.join(HOME, '.claude')),
|
|
684
|
+
() => fs.existsSync(path.join(CWD, '.claude')),
|
|
685
|
+
], setup: setupClaude },
|
|
748
686
|
{ name: 'Codex', detect: [() => whichExists('codex'), () => fs.existsSync(path.join(HOME, '.codex'))], setup: setupCodex },
|
|
749
687
|
{ name: 'Gemini', detect: [() => whichExists('gemini'), () => fs.existsSync(path.join(HOME, '.gemini'))], setup: setupGemini },
|
|
750
688
|
{ name: 'Amp', detect: [() => whichExists('amp'), () => fs.existsSync(path.join(HOME, '.amp'))], setup: setupAmp },
|
|
@@ -940,7 +878,14 @@ function stats() {
|
|
|
940
878
|
const { analyzeFeedback } = require(path.join(PKG_ROOT, 'scripts', 'feedback-loop'));
|
|
941
879
|
const data = analyzeFeedback();
|
|
942
880
|
|
|
881
|
+
// Gate enforcement stats — runtime intercepts + configured gates
|
|
882
|
+
let gateData = { blocked: 0, warned: 0, passed: 0, byGate: {} };
|
|
883
|
+
try { gateData = require(path.join(PKG_ROOT, 'scripts', 'gates-engine')).loadStats(); } catch {}
|
|
884
|
+
let gateConfigData = { totalGates: 0, autoPromotedGates: 0, estimatedHoursSaved: '0.0', topBlocked: null, firstTimeFixRate: null };
|
|
885
|
+
try { gateConfigData = require(path.join(PKG_ROOT, 'scripts', 'gate-stats')).calculateStats(); } catch {}
|
|
886
|
+
|
|
943
887
|
const avgCostOfMistake = 2.50;
|
|
888
|
+
const totalInterceptions = gateData.blocked + gateData.warned;
|
|
944
889
|
const payload = {
|
|
945
890
|
total: data.total,
|
|
946
891
|
positives: data.totalPositive,
|
|
@@ -950,6 +895,13 @@ function stats() {
|
|
|
950
895
|
revenueAtRisk: Number((data.totalNegative * avgCostOfMistake).toFixed(2)),
|
|
951
896
|
topTags: data.topTags || [],
|
|
952
897
|
recentActivity: data.recentActivity || [],
|
|
898
|
+
gatesBlocked: gateData.blocked,
|
|
899
|
+
gatesWarned: gateData.warned,
|
|
900
|
+
totalGates: gateConfigData.totalGates,
|
|
901
|
+
autoPromotedGates: gateConfigData.autoPromotedGates,
|
|
902
|
+
estimatedHoursSaved: gateConfigData.estimatedHoursSaved,
|
|
903
|
+
topBlockedGate: gateConfigData.topBlocked ? gateConfigData.topBlocked.id : null,
|
|
904
|
+
firstTimeFixRate: gateConfigData.firstTimeFixRate,
|
|
953
905
|
};
|
|
954
906
|
|
|
955
907
|
if (args.json) {
|
|
@@ -963,6 +915,18 @@ function stats() {
|
|
|
963
915
|
console.log(` Approval Rate : ${payload.approvalRate}%`);
|
|
964
916
|
console.log(` Recent Trend : ${payload.recentTrend}%`);
|
|
965
917
|
|
|
918
|
+
// Gate enforcement — the high-ROI section
|
|
919
|
+
if (totalInterceptions > 0 || payload.totalGates > 0) {
|
|
920
|
+
console.log('\n🛡️ PRE-ACTION GATE ENFORCEMENT');
|
|
921
|
+
console.log(` Actions blocked : ${payload.gatesBlocked}`);
|
|
922
|
+
console.log(` Actions warned : ${payload.gatesWarned}`);
|
|
923
|
+
console.log(` Active gates : ${payload.totalGates} (${payload.autoPromotedGates} auto-promoted)`);
|
|
924
|
+
if (payload.topBlockedGate) console.log(` Top blocker : ${payload.topBlockedGate}`);
|
|
925
|
+
console.log(` Est. time saved : ~${payload.estimatedHoursSaved} hours`);
|
|
926
|
+
const { formatFirstTimeFixRate } = require(path.join(PKG_ROOT, 'scripts', 'gate-stats'));
|
|
927
|
+
console.log(` First-time fix : ${formatFirstTimeFixRate(payload.firstTimeFixRate)}`);
|
|
928
|
+
}
|
|
929
|
+
|
|
966
930
|
if (payload.negatives > 0) {
|
|
967
931
|
console.log('\n⚠️ REVENUE-AT-RISK ANALYSIS');
|
|
968
932
|
console.log(` Repeated Failures detected: ${payload.negatives}`);
|
|
@@ -1746,6 +1710,25 @@ function gateStats() {
|
|
|
1746
1710
|
console.log('\n' + formatStats(stats) + '\n');
|
|
1747
1711
|
}
|
|
1748
1712
|
|
|
1713
|
+
function contextPacks() {
|
|
1714
|
+
const args = parseArgs(process.argv.slice(3));
|
|
1715
|
+
const { generateAutoContextPacks } = require(path.join(PKG_ROOT, 'scripts', 'auto-context-packs'));
|
|
1716
|
+
const result = generateAutoContextPacks();
|
|
1717
|
+
if (args.json) {
|
|
1718
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1719
|
+
return;
|
|
1720
|
+
}
|
|
1721
|
+
console.log(`\nGenerated ${result.packCount} context pack(s):`);
|
|
1722
|
+
for (const p of result.packs) {
|
|
1723
|
+
console.log(` [${p.type}] ${p.name}`);
|
|
1724
|
+
console.log(` -> ${p.filePath}`);
|
|
1725
|
+
}
|
|
1726
|
+
if (result.packCount === 0) {
|
|
1727
|
+
console.log(' (No failure patterns found yet — capture some feedback first.)');
|
|
1728
|
+
}
|
|
1729
|
+
console.log('');
|
|
1730
|
+
}
|
|
1731
|
+
|
|
1749
1732
|
function harnessAudit() {
|
|
1750
1733
|
const args = parseArgs(process.argv.slice(3));
|
|
1751
1734
|
const {
|
|
@@ -2548,6 +2531,11 @@ switch (COMMAND) {
|
|
|
2548
2531
|
case 'search-lessons':
|
|
2549
2532
|
lessons();
|
|
2550
2533
|
break;
|
|
2534
|
+
case 'notes': {
|
|
2535
|
+
const { cli: notesCli } = require(path.join(PKG_ROOT, 'scripts', 'implementation-notes'));
|
|
2536
|
+
notesCli(process.argv.slice(3));
|
|
2537
|
+
break;
|
|
2538
|
+
}
|
|
2551
2539
|
case 'lesson-health':
|
|
2552
2540
|
case 'stale': {
|
|
2553
2541
|
const { initDB } = require(path.join(PKG_ROOT, 'scripts', 'lesson-db'));
|
|
@@ -2689,6 +2677,9 @@ switch (COMMAND) {
|
|
|
2689
2677
|
case 'rules':
|
|
2690
2678
|
rules();
|
|
2691
2679
|
break;
|
|
2680
|
+
case 'context-packs':
|
|
2681
|
+
contextPacks();
|
|
2682
|
+
break;
|
|
2692
2683
|
case 'harness-audit':
|
|
2693
2684
|
case 'harness':
|
|
2694
2685
|
harnessAudit();
|
|
@@ -2884,6 +2875,29 @@ switch (COMMAND) {
|
|
|
2884
2875
|
}
|
|
2885
2876
|
break;
|
|
2886
2877
|
}
|
|
2878
|
+
case 'audit': {
|
|
2879
|
+
const auditFile = process.argv[3];
|
|
2880
|
+
if (!auditFile) {
|
|
2881
|
+
console.error('Usage: npx thumbgate audit <path-to-transcript.txt>');
|
|
2882
|
+
process.exit(1);
|
|
2883
|
+
}
|
|
2884
|
+
const { runAudit } = require(path.join(PKG_ROOT, 'scripts', 'audit'));
|
|
2885
|
+
const { results, totalWaste, error } = runAudit(auditFile);
|
|
2886
|
+
if (error) {
|
|
2887
|
+
console.error(error);
|
|
2888
|
+
process.exit(1);
|
|
2889
|
+
}
|
|
2890
|
+
console.log('\n🔍 AI Bill Audit Results\n');
|
|
2891
|
+
if (results.length === 0) {
|
|
2892
|
+
console.log('✅ No repeat-offender patterns found. Your sessions are efficient!');
|
|
2893
|
+
} else {
|
|
2894
|
+
console.table(results);
|
|
2895
|
+
console.log('\n💰 Total estimated monthly waste: $' + totalWaste);
|
|
2896
|
+
console.log('\nBlock these mistakes permanently with ThumbGate Pro:');
|
|
2897
|
+
console.log(PRO_CHECKOUT_URL);
|
|
2898
|
+
}
|
|
2899
|
+
break;
|
|
2900
|
+
}
|
|
2887
2901
|
case 'dashboard':
|
|
2888
2902
|
dashboard();
|
|
2889
2903
|
break;
|
|
@@ -68,7 +68,8 @@
|
|
|
68
68
|
"perplexity_search",
|
|
69
69
|
"perplexity_ask",
|
|
70
70
|
"perplexity_research",
|
|
71
|
-
"perplexity_reason"
|
|
71
|
+
"perplexity_reason",
|
|
72
|
+
"suggest_fix"
|
|
72
73
|
],
|
|
73
74
|
"essential": [
|
|
74
75
|
"capture_feedback",
|
|
@@ -104,7 +105,8 @@
|
|
|
104
105
|
"report_product_issue",
|
|
105
106
|
"require_evidence_for_claim",
|
|
106
107
|
"session_report",
|
|
107
|
-
"generate_operator_artifact"
|
|
108
|
+
"generate_operator_artifact",
|
|
109
|
+
"suggest_fix"
|
|
108
110
|
],
|
|
109
111
|
"commerce": [
|
|
110
112
|
"capture_feedback",
|
|
@@ -123,7 +125,8 @@
|
|
|
123
125
|
"workflow_sentinel",
|
|
124
126
|
"prevention_rules",
|
|
125
127
|
"feedback_stats",
|
|
126
|
-
"feedback_summary"
|
|
128
|
+
"feedback_summary",
|
|
129
|
+
"suggest_fix"
|
|
127
130
|
],
|
|
128
131
|
"readonly": [
|
|
129
132
|
"recall",
|
|
@@ -164,7 +167,8 @@
|
|
|
164
167
|
"session_report",
|
|
165
168
|
"generate_operator_artifact",
|
|
166
169
|
"perplexity_search",
|
|
167
|
-
"perplexity_ask"
|
|
170
|
+
"perplexity_ask",
|
|
171
|
+
"suggest_fix"
|
|
168
172
|
],
|
|
169
173
|
"dispatch": [
|
|
170
174
|
"recall",
|
|
@@ -204,7 +208,8 @@
|
|
|
204
208
|
"session_report",
|
|
205
209
|
"generate_operator_artifact",
|
|
206
210
|
"perplexity_search",
|
|
207
|
-
"perplexity_ask"
|
|
211
|
+
"perplexity_ask",
|
|
212
|
+
"suggest_fix"
|
|
208
213
|
],
|
|
209
214
|
"locked": [
|
|
210
215
|
"feedback_summary",
|
|
@@ -228,7 +233,8 @@
|
|
|
228
233
|
"workflow_sentinel",
|
|
229
234
|
"settings_status",
|
|
230
235
|
"native_messaging_audit",
|
|
231
|
-
"generate_operator_artifact"
|
|
236
|
+
"generate_operator_artifact",
|
|
237
|
+
"suggest_fix"
|
|
232
238
|
]
|
|
233
239
|
}
|
|
234
240
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "thumbgate",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.22.0",
|
|
4
4
|
"description": "ThumbGate self-improving agent governance: thumbs-up/down turns every mistake into a prevention rule and blocks repeat patterns. 33 pre-action checks, budget enforcement, and self-protection for Claude Code, Cursor, Codex, Gemini CLI, and Amp.",
|
|
5
5
|
"homepage": "https://thumbgate-production.up.railway.app",
|
|
6
6
|
"repository": {
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"scripts/analytics-window.js",
|
|
32
32
|
"scripts/async-job-runner.js",
|
|
33
33
|
"scripts/audit-trail.js",
|
|
34
|
+
"scripts/audit.js",
|
|
34
35
|
"scripts/auto-promote-gates.js",
|
|
35
36
|
"scripts/auto-wire-hooks.js",
|
|
36
37
|
"scripts/autoresearch-runner.js",
|
|
@@ -222,6 +223,7 @@
|
|
|
222
223
|
"openapi/",
|
|
223
224
|
"public/agent-manager.html",
|
|
224
225
|
"public/blog.html",
|
|
226
|
+
"public/codex-enterprise.html",
|
|
225
227
|
"public/codex-plugin.html",
|
|
226
228
|
"public/compare.html",
|
|
227
229
|
"public/dashboard.html",
|
|
@@ -332,7 +334,7 @@
|
|
|
332
334
|
"social:prospect:bluesky:dry": "node scripts/social-bluesky-prospecting.js --dry-run",
|
|
333
335
|
"social:reply-publish:bluesky:dry": "node scripts/social-reply-monitor-bluesky.js --publish-approved --dry-run",
|
|
334
336
|
"test:python": "python3 -m pytest tests/*.py",
|
|
335
|
-
"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:cli && npm run test:watcher && npm run test:autoresearch && npm run test:ops && npm run test:session-analyzer && npm run test:tessl && npm run test:gates && npm run test:evoskill && npm run test:gates-hardening && npm run test:workers && npm run test:social-analytics && npm run test:memalign && npm run test:xmemory-lite && npm run test:filesystem-search && npm run test:zernio && npm run test:platform-limits && npm run test:post-video && npm run test:post-everywhere-instagram && npm run test:post-everywhere-channels && npm run test:post-everywhere-zernio-default && npm run test:zernio-canonical-pollers && npm run test:zernio-status && npm run test:obsidian-export && npm run test:lesson-db && npm run test:lesson-rotation && npm run test:memory-dedup && npm run test:feedback-quality && npm run test:sync-version && npm run test:check-congruence && npm run test:tool-registry && npm run test:feedback-to-rules && npm run test:memory-firewall && npm run test: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:plan-gate && npm run test:pulse && npm run test:semantic-layer && npm run test:data-pipeline && npm run test:optimize-context && npm run test:principle-extractor && npm run test:analytics-window && npm run test:funnel-analytics && npm run test:experiment-tracker && npm run test:build-metadata && npm run test:context-engine && npm run test:hf-papers && npm run test:marketing-experiment && npm run test:seo-gsd && npm run test:verify-run && npm run test:export-dpo-pairs && npm run test:export-hf-dataset && npm run test:license && npm run test:bot-detector && npm run test: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:evolution && npm run test:org-dashboard && npm run test:multi-hop-recall && npm run test:synthetic-dpo && npm run test:thumbgate-skill && npm run test:learn-hub && npm run test:feedback-fallback && npm run test:metaclaw && npm run test:server-lock && npm run test:control-tower && npm run test:pii-scanner && npm run test:data-governance && npm run test:lesson-inference && npm run test:semantic-dedup && npm run test:fs-utils && npm run test:cli-schema && npm run test:explore && npm run test:lesson-reranker && npm run test:lesson-retrieval && npm run test:cross-encoder && npm run test:reflector-agent && npm run test:feedback-session && npm run test:feedback-history-distiller && npm run test:hallucination-detector && npm run test:history-distiller && npm run test:predictive-insights && npm run test:prove-predictive-insights && npm run test:statusbar-cli && npm run test:generate-instagram-card && npm run test:instagram-thumbgate-post && npm run test:publish-instagram-thumbgate && npm run test:lesson-synthesis && npm run test: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:community-course-platform-launch-kit && 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:social-dedupe-cleanup && npm run test:sync-launch-assets && npm run test:ai-search-visibility && npm run test:perplexity && npm run test:security-scanner && npm run test:llm-client && npm run test:managed-lesson-agent && npm run test:self-distill && npm run test:meta-agent && npm run test:harness-selector && npm run test:thumbgate-bench && npm run test:seo-guides && npm run test:enforcement-loop && npm run test:cli-agent-experience && npm run test:bot-detection && npm run test:checkout-archived-product-guard && npm run test:postgres-guard && npm run test:checkout-bot-guard && npm run test:checkout-pro-confirmation-gate && 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:demo-voiceover && npm run test:gate-coherence && npm run test:gate-eval && npm run test:high-roi && npm run test:public-static-assets && npm run test:token-savings && npm run test: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: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:stripe-payment-link-update && npm run test:ci-cd-hygiene-audit && npm run test:verify-marketing-pages-deployed && npm run test:install-email-capture",
|
|
337
|
+
"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:cli && npm run test:watcher && npm run test:autoresearch && npm run test:ops && npm run test:session-analyzer && npm run test:tessl && npm run test:gates && npm run test:evoskill && npm run test:gates-hardening && npm run test:workers && npm run test:social-analytics && npm run test:memalign && npm run test:xmemory-lite && npm run test:filesystem-search && npm run test:zernio && npm run test:platform-limits && npm run test:post-video && npm run test:post-everywhere-instagram && npm run test:post-everywhere-channels && npm run test:post-everywhere-zernio-default && npm run test:zernio-canonical-pollers && npm run test:zernio-status && npm run test:obsidian-export && npm run test:lesson-db && npm run test:lesson-rotation && npm run test:memory-dedup && npm run test:feedback-quality && npm run test:sync-version && npm run test:check-congruence && npm run test:tool-registry && npm run test:feedback-to-rules && npm run test:memory-firewall && npm run test: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:plan-gate && npm run test:pulse && npm run test:semantic-layer && npm run test:data-pipeline && npm run test:optimize-context && npm run test:principle-extractor && npm run test:analytics-window && npm run test:funnel-analytics && npm run test:experiment-tracker && npm run test:build-metadata && npm run test:context-engine && npm run test:hf-papers && npm run test:marketing-experiment && npm run test:seo-gsd && npm run test:verify-run && npm run test:export-dpo-pairs && npm run test:export-hf-dataset && npm run test:license && npm run test:bot-detector && npm run test: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:evolution && npm run test:org-dashboard && npm run test:multi-hop-recall && npm run test:synthetic-dpo && npm run test:thumbgate-skill && npm run test:learn-hub && npm run test:feedback-fallback && npm run test:metaclaw && npm run test:server-lock && npm run test:control-tower && npm run test:pii-scanner && npm run test:data-governance && npm run test:lesson-inference && npm run test:semantic-dedup && npm run test:fs-utils && npm run test:cli-schema && npm run test:explore && npm run test:lesson-reranker && npm run test:lesson-retrieval && npm run test:cross-encoder && npm run test:reflector-agent && npm run test:feedback-session && npm run test:feedback-history-distiller && npm run test:hallucination-detector && npm run test:history-distiller && npm run test:predictive-insights && npm run test:prove-predictive-insights && npm run test:statusbar-cli && npm run test:generate-instagram-card && npm run test:instagram-thumbgate-post && npm run test:publish-instagram-thumbgate && npm run test:lesson-synthesis && npm run test: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:community-course-platform-launch-kit && 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:social-dedupe-cleanup && npm run test:sync-launch-assets && npm run test:ai-search-visibility && npm run test:perplexity && npm run test:security-scanner && npm run test:llm-client && npm run test:managed-lesson-agent && npm run test:self-distill && npm run test:meta-agent && npm run test:harness-selector && npm run test:thumbgate-bench && npm run test:seo-guides && npm run test:enforcement-loop && npm run test:cli-agent-experience && npm run test:bot-detection && npm run test:checkout-archived-product-guard && npm run test:postgres-guard && npm run test:checkout-bot-guard && npm run test:checkout-pro-confirmation-gate && 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:demo-voiceover && npm run test:gate-coherence && npm run test:gate-eval && npm run test:high-roi && npm run test:public-static-assets && npm run test:token-savings && npm run test: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: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: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",
|
|
336
338
|
"test:hook-stop-verify-deploy": "node --test tests/hook-stop-verify-deploy.test.js",
|
|
337
339
|
"test:hook-stop-anti-claim": "node --test tests/hook-stop-anti-claim.test.js",
|
|
338
340
|
"test:plausible-server-events": "node --test tests/plausible-server-events.test.js",
|
|
@@ -442,10 +444,10 @@
|
|
|
442
444
|
"test:evolution": "node --test tests/workspace-evolver.test.js",
|
|
443
445
|
"test:watcher": "node --test tests/jsonl-watcher.test.js",
|
|
444
446
|
"test:autoresearch": "node --test tests/autoresearch.test.js",
|
|
445
|
-
"test:ops": "node --test tests/adk-consolidator.test.js tests/anthropic-partner-strategy.test.js tests/auto-promote-gates.test.js tests/auto-wire-hooks.test.js tests/claude-skill.test.js tests/codegraph-context.test.js tests/commercial-signals.test.js tests/decision-journal.test.js tests/delegation-runtime.test.js tests/disagreement-mining.test.js tests/failure-diagnostics.test.js tests/gate-stats.test.js tests/git-hook-installer.test.js tests/github-billing.test.js tests/intervention-policy.test.js tests/markdown-escape.test.js tests/mcp-tools-gates.test.js tests/native-messaging-audit.test.js tests/project-bayes-e2e.test.js tests/project-bayes.test.js tests/rate-limiter.test.js tests/schedule-manager.test.js tests/session-handoff.test.js tests/skill-generator.test.js tests/smart-learning.test.js tests/spike-and-sink.test.js tests/stripe-revenue.test.js tests/stripe-webhook-route.test.js tests/stripe-webhook-rotation.test.js tests/train-from-feedback.test.js tests/workflow-hardening-sprint.test.js tests/workflow-sentinel.test.js tests/test-suite-parity.test.js tests/a2ui-engine.test.js tests/webhook-delivery.test.js",
|
|
447
|
+
"test:ops": "node --test tests/adk-consolidator.test.js tests/anthropic-partner-strategy.test.js tests/auto-promote-gates.test.js tests/auto-wire-hooks.test.js tests/claude-skill.test.js tests/codegraph-context.test.js tests/commercial-signals.test.js tests/decision-journal.test.js tests/delegation-runtime.test.js tests/disagreement-mining.test.js tests/failure-diagnostics.test.js tests/gate-stats.test.js tests/git-hook-installer.test.js tests/github-billing.test.js tests/intervention-policy.test.js tests/markdown-escape.test.js tests/mcp-tools-gates.test.js tests/native-messaging-audit.test.js tests/project-bayes-e2e.test.js tests/project-bayes.test.js tests/rate-limiter.test.js tests/schedule-manager.test.js tests/session-handoff.test.js tests/skill-generator.test.js tests/smart-learning.test.js tests/spike-and-sink.test.js tests/stripe-revenue.test.js tests/stripe-webhook-route.test.js tests/stripe-webhook-rotation.test.js tests/train-from-feedback.test.js tests/workflow-hardening-sprint.test.js tests/workflow-sentinel.test.js tests/test-suite-parity.test.js tests/a2ui-engine.test.js tests/webhook-delivery.test.js tests/auto-context-packs.test.js",
|
|
446
448
|
"test:session-analyzer": "node --test tests/session-analyzer.test.js",
|
|
447
449
|
"test:tessl": "node --test tests/tessl-export.test.js",
|
|
448
|
-
"test:gates": "node --test tests/gate-templates.test.js tests/gates-engine.test.js tests/claim-verification.test.js tests/secret-scanner.test.js tests/secret-fixture-safety.test.js tests/prompt-guard.test.js tests/audit-trail.test.js tests/profile-router.test.js tests/workflow-sentinel.test.js tests/docker-sandbox-planner.test.js",
|
|
450
|
+
"test:gates": "node --test tests/gate-templates.test.js tests/gates-engine.test.js tests/claim-verification.test.js tests/secret-scanner.test.js tests/secret-fixture-safety.test.js tests/prompt-guard.test.js tests/audit-trail.test.js tests/profile-router.test.js tests/workflow-sentinel.test.js tests/docker-sandbox-planner.test.js tests/mcp-tools-suggest-fix.test.js",
|
|
449
451
|
"test:budget": "node --test tests/budget-enforcer.test.js",
|
|
450
452
|
"test:workers": "npm --prefix workers ci && npm --prefix workers test",
|
|
451
453
|
"test:evoskill": "node --test tests/evoskill.test.js",
|
|
@@ -659,7 +661,15 @@
|
|
|
659
661
|
"test:stripe-payment-link-update": "node --test tests/stripe-payment-link-update.test.js",
|
|
660
662
|
"test:verify-marketing-pages-deployed": "node --test tests/verify-marketing-pages-deployed.test.js",
|
|
661
663
|
"verify:marketing-pages": "node scripts/verify-marketing-pages-deployed.js",
|
|
662
|
-
"test:install-email-capture": "node --test tests/install-email-capture.test.js"
|
|
664
|
+
"test:install-email-capture": "node --test tests/install-email-capture.test.js",
|
|
665
|
+
"test:install-shim": "node --test tests/install-shim.test.js",
|
|
666
|
+
"test:hook-runtime-subcommands": "node --test tests/hook-runtime-subcommands.test.js",
|
|
667
|
+
"test:implementation-notes": "node --test tests/implementation-notes.test.js",
|
|
668
|
+
"test:lessons-page-clickability": "playwright test tests/e2e/lessons-page-clickability.spec.js",
|
|
669
|
+
"test:index-page-clickability": "playwright test tests/e2e/index-page-clickability.spec.js",
|
|
670
|
+
"test:dashboard-page-clickability": "playwright test tests/e2e/dashboard-page-clickability.spec.js",
|
|
671
|
+
"test:agent-manager-page-clickability": "playwright test tests/e2e/agent-manager-page-clickability.spec.js",
|
|
672
|
+
"test:pricing-page-clickability": "playwright test tests/e2e/pricing-page-clickability.spec.js"
|
|
663
673
|
},
|
|
664
674
|
"keywords": [
|
|
665
675
|
"mcp",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
</tr>
|
|
77
77
|
<tr>
|
|
78
78
|
<td><strong>Plugin marketplace</strong><br>Deciding which Claude Code / Cursor / Codex plugins are blessed and which are not.</td>
|
|
79
|
-
<td>ThumbGate ships as a Claude Code plugin, a Cursor extension, a Codex plugin, and a Gemini CLI hook. One install, every supported agent. Adapter compatibility matrix kept current as runtimes change.</td>
|
|
79
|
+
<td>ThumbGate ships as a Claude Code plugin, a Cursor extension (Marketplace listing pending Cursor's review since 2026-05-19; runtime install works today via <code>npx thumbgate init --agent cursor</code>), a Codex plugin, and a Gemini CLI hook. One install, every supported agent. Adapter compatibility matrix kept current as runtimes change.</td>
|
|
80
80
|
</tr>
|
|
81
81
|
<tr>
|
|
82
82
|
<td><strong>Permissions policy</strong><br>What an agent is allowed to execute, against which surfaces, with which evidence required.</td>
|