thumbgate 1.22.0 → 1.23.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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thumbgate-marketplace",
3
- "version": "1.22.0",
3
+ "version": "1.23.1",
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.22.0",
17
+ "version": "1.23.1",
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.22.0",
4
+ "version": "1.23.1",
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.22.0",
3
+ "version": "1.23.1",
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",
package/README.md CHANGED
@@ -474,6 +474,7 @@ Pro ($19/mo or $149/yr) removes the rule cap and adds history-aware lesson recal
474
474
  - [Agent Workflow Contract](WORKFLOW.md) — the agent-run contract for all ThumbGate operations
475
475
  - [Ready for Agent Intake](https://github.com/IgorGanapolsky/ThumbGate/issues/new?template=ready-for-agent.yml) — ready-for-agent intake template
476
476
  - [SEO Guide: Claude Code Guardrails](docs/learn/claude-code-guardrails.md)
477
+ - [Unsupervised Learning Signals](docs/UL.md) — silent-failure clustering (experimental, behind `THUMBGATE_SILENT_FAILURE_CLUSTERING=1`; only useful on workspaces with ≥ 50 tool calls/day)
477
478
  - [ThumbGate-Core](https://github.com/IgorGanapolsky/ThumbGate-Core) — private core for hosted overlays, ranking, policy synthesis, billing intelligence, and org/team workflows
478
479
 
479
480
  ---
@@ -72,6 +72,11 @@ components:
72
72
  description: Optional domain tags. If omitted, ThumbGate infers one from the feedback text before promotion.
73
73
  skill:
74
74
  type: string
75
+ source:
76
+ type: string
77
+ enum: [chatgpt_gpt]
78
+ default: chatgpt_gpt
79
+ description: Attribution marker for ThumbGate analytics. The published ThumbGate GPT should send `chatgpt_gpt` so owner dashboards can distinguish GPT Action calls from local API calls.
75
80
  IntentPlanRequest:
76
81
  type: object
77
82
  required: [intentId]
@@ -880,6 +885,11 @@ paths:
880
885
  toolName:
881
886
  type: string
882
887
  description: Tool name is optional when provider-native tool call payload is supplied.
888
+ source:
889
+ type: string
890
+ enum: [chatgpt_gpt]
891
+ default: chatgpt_gpt
892
+ description: Attribution marker for ThumbGate analytics. The published ThumbGate GPT should send `chatgpt_gpt` so owner dashboards can distinguish GPT Action calls from local API calls.
883
893
  provider:
884
894
  type: string
885
895
  model:
@@ -2,13 +2,13 @@
2
2
  "mcpServers": {
3
3
  "thumbgate": {
4
4
  "command": "npx",
5
- "args": ["--yes", "--package", "thumbgate@1.22.0", "thumbgate", "serve"]
5
+ "args": ["--yes", "--package", "thumbgate@1.23.1", "thumbgate", "serve"]
6
6
  }
7
7
  },
8
8
  "hooks": {
9
9
  "preToolUse": {
10
10
  "command": "npx",
11
- "args": ["--yes", "--package", "thumbgate@1.22.0", "thumbgate", "gate-check"]
11
+ "args": ["--yes", "--package", "thumbgate@1.23.1", "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.22.0' };
219
+ const SERVER_INFO = { name: 'thumbgate-mcp', version: '1.23.1' };
220
220
  const COMMERCE_CATEGORIES = [
221
221
  'product_recommendation',
222
222
  'brand_compliance',
@@ -7,7 +7,7 @@
7
7
  "npx",
8
8
  "--yes",
9
9
  "--package",
10
- "thumbgate@1.22.0",
10
+ "thumbgate@1.23.1",
11
11
  "thumbgate",
12
12
  "serve"
13
13
  ],
package/bin/cli.js CHANGED
@@ -52,6 +52,25 @@ const PKG_ROOT = path.join(__dirname, '..');
52
52
 
53
53
  const PRO_URL = 'https://thumbgate-production.up.railway.app';
54
54
  const PRO_CHECKOUT_URL = PRO_MONTHLY_PAYMENT_LINK;
55
+ const TRIAL_DAYS = 14;
56
+
57
+ function checkoutUrlFor(source, content) {
58
+ try {
59
+ const url = new URL(PRO_CHECKOUT_URL);
60
+ url.searchParams.set('utm_source', source || 'cli');
61
+ url.searchParams.set('utm_medium', 'cli');
62
+ url.searchParams.set('utm_campaign', 'pro_conversion');
63
+ if (content) url.searchParams.set('utm_content', content);
64
+ return url.toString();
65
+ } catch (_) {
66
+ return PRO_CHECKOUT_URL;
67
+ }
68
+ }
69
+
70
+ function trialDeadlineLabel(now = new Date()) {
71
+ const deadline = new Date(now.getTime() + (TRIAL_DAYS * 24 * 60 * 60 * 1000));
72
+ return deadline.toISOString().slice(0, 10);
73
+ }
55
74
 
56
75
  function upgradeNudge() {
57
76
  if (process.env.THUMBGATE_NO_NUDGE === '1') return;
@@ -139,25 +158,46 @@ function proNudge(context) {
139
158
  const { isProTier } = require(path.join(PKG_ROOT, 'scripts', 'rate-limiter'));
140
159
  if (isProTier()) return;
141
160
  } catch (_) { /* if rate-limiter is unavailable, fall through and nudge */ }
161
+ const checkoutUrl = checkoutUrlFor('cli_nudge', context || COMMAND || 'general');
142
162
  const messages = [
143
- `\n 💡 Unlock Pro (${PRO_PRICE_LABEL}): searchable dashboard, DPO export, multi-repo sync\n ${PRO_CHECKOUT_URL}\n`,
144
- `\n 💡 Pro tip: export your feedback as DPO training pairs to improve your models.\n Get Pro: ${PRO_CHECKOUT_URL}\n`,
145
- `\n 💡 ThumbGate Pro: search, edit, and sync lessons across repos. ${PRO_PRICE_LABEL}.\n ${PRO_CHECKOUT_URL}\n`,
163
+ `\n 💡 Unlock Pro (${PRO_PRICE_LABEL}): searchable dashboard, DPO export, multi-repo sync\n ${checkoutUrl}\n`,
164
+ `\n 💡 Pro tip: export your feedback as DPO training pairs to improve your models.\n Get Pro: ${checkoutUrl}\n`,
165
+ `\n 💡 ThumbGate Pro: search, edit, and sync lessons across repos. ${PRO_PRICE_LABEL}.\n ${checkoutUrl}\n`,
146
166
  ];
147
167
  // Rotate message daily — no Math.random (security policy)
148
168
  const msg = messages[Math.floor(Date.now() / 86400000) % messages.length];
149
169
  process.stderr.write(msg);
150
170
  }
151
171
 
152
- function limitNudge(action) {
172
+ function limitNudge(action, limitResult = {}) {
153
173
  if (process.env.THUMBGATE_NO_NUDGE === '1') return;
174
+ const checkoutUrl = checkoutUrlFor('cli_limit', action);
175
+ const usageLine = Number.isFinite(limitResult.used) && Number.isFinite(limitResult.limit)
176
+ ? ` Usage: ${limitResult.used}/${limitResult.limit} (${limitResult.limitType || 'limit'}).\n`
177
+ : '';
178
+ const reason = limitResult.message
179
+ ? String(limitResult.message).split('\n')[0]
180
+ : 'Free tier limit reached.';
154
181
  process.stderr.write(
155
- `\n ⚠️ Free tier limit reached. Upgrade to Pro for unlimited: https://thumbgate-production.up.railway.app/pro\n` +
156
- ` ${action} daily limit reached. Upgrade to Pro for unlimited usage — ${PRO_PRICE_LABEL}:\n` +
157
- ` ${PRO_CHECKOUT_URL}\n\n`
182
+ `\n 🔒 ${reason}\n` +
183
+ usageLine +
184
+ ` Upgrade to Pro (${PRO_PRICE_LABEL}) to continue ${action.replace(/_/g, ' ')}:\n` +
185
+ ` ${checkoutUrl}\n\n`
158
186
  );
159
187
  }
160
188
 
189
+ function printInitConversionPrompt(email) {
190
+ if (process.env.THUMBGATE_NO_NUDGE === '1') return;
191
+ const checkoutUrl = checkoutUrlFor('cli_init', email ? 'init_email' : 'init_no_email');
192
+ console.log('');
193
+ console.log(' ┌──────────────────────────────────────────────────────────┐');
194
+ console.log(` │ 14-day Pro trial active through ${trialDeadlineLabel()}. │`);
195
+ console.log(' │ Pro unlocks lesson search, recall, dashboard, exports. │');
196
+ console.log(' │ Add onboarding: npx thumbgate init --email you@company.com │');
197
+ console.log(` │ Upgrade: ${checkoutUrl}`);
198
+ console.log(' └──────────────────────────────────────────────────────────┘');
199
+ }
200
+
161
201
  function parseArgs(argv) {
162
202
  const args = {};
163
203
  argv.forEach((arg, index) => {
@@ -613,6 +653,18 @@ function quickStart() {
613
653
 
614
654
  function init(cliArgs = parseArgs(process.argv.slice(3))) {
615
655
  const args = { ...cliArgs };
656
+ if (args.help || args.h) {
657
+ console.log('Usage: npx thumbgate init [--agent <name>] [--wire-hooks] [--email you@company.com]');
658
+ console.log('');
659
+ console.log('Scaffold ThumbGate in the current project and wire detected agent integrations.');
660
+ console.log('');
661
+ console.log('Options:');
662
+ console.log(' --agent <name> Wire a specific agent: claude-code, codex, gemini, amp, cursor, cline');
663
+ console.log(' --wire-hooks Wire hooks only; do not scaffold project files');
664
+ console.log(' --email <email> Subscribe installer to the setup guide and trial reminders');
665
+ console.log(' --dry-run Show hook changes without writing them');
666
+ return;
667
+ }
616
668
 
617
669
  // --wire-hooks only mode: skip scaffolding, just wire hooks
618
670
  if (args['wire-hooks']) {
@@ -746,16 +798,48 @@ function init(cliArgs = parseArgs(process.argv.slice(3))) {
746
798
  }
747
799
 
748
800
  console.log('');
749
- console.log(`thumbgate v${pkgVersion()} initialized.`);
750
- console.log('Run: npx thumbgate help');
801
+ console.log(`✅ thumbgate v${pkgVersion()} initialized.`);
802
+ const onboardingEmail = typeof args.email === 'string'
803
+ ? args.email.trim()
804
+ : (typeof args['onboarding-email'] === 'string' ? args['onboarding-email'].trim() : '');
805
+ if (onboardingEmail) {
806
+ try {
807
+ execFileSync(process.execPath, [__filename, 'subscribe', onboardingEmail], {
808
+ cwd: CWD,
809
+ env: process.env,
810
+ stdio: 'inherit',
811
+ });
812
+ trackEvent('cli_init_email_subscribed', { command: 'init', source: 'init_email' });
813
+ } catch (_) {
814
+ console.log(` Retry onboarding email: npx thumbgate subscribe ${onboardingEmail}`);
815
+ }
816
+ }
751
817
  trackEvent('cli_init', { command: 'init' });
752
- proNudge();
818
+
819
+ // ---------------------------------------------------------------------------
820
+ // Activation guide: the ONE thing the user should do next.
821
+ // 98.5% of init users never promote their first prevention rule.
822
+ // This is the funnel break — not conversion, not nudges — activation.
823
+ // ---------------------------------------------------------------------------
753
824
  console.log('');
754
- console.log(' ┌──────────────────────────────────────────────────────────┐');
755
- console.log(' │ Teams: shared enforcement, CI gates, audit trails │');
756
- console.log(' │ One correction protects every agent on your team. │');
757
- console.log(' │ https://thumbgate-production.up.railway.app/pro │');
758
- console.log(' └──────────────────────────────────────────────────────────┘');
825
+ console.log(' ╭──────────────────────────────────────────────────────────╮');
826
+ console.log(' │ NEXT: Create your first prevention rule (30 seconds) │');
827
+ console.log(' │ │');
828
+ console.log(' │ When your AI agent makes a mistake, capture it: │');
829
+ console.log(' │ │');
830
+ console.log(' │ npx thumbgate capture --feedback=down \\ │');
831
+ console.log(' │ --context="agent deleted prod config" \\ │');
832
+ console.log(' │ --what-went-wrong="ran rm on .env" \\ │');
833
+ console.log(' │ --what-to-change="never delete .env files" │');
834
+ console.log(' │ │');
835
+ console.log(' │ ThumbGate auto-promotes this to a prevention rule │');
836
+ console.log(' │ that blocks the mistake from happening again. │');
837
+ console.log(' ╰──────────────────────────────────────────────────────────╯');
838
+ console.log('');
839
+ printInitConversionPrompt(onboardingEmail);
840
+ if (!onboardingEmail) {
841
+ console.log(' Get trial reminders: npx thumbgate init --email you@company.com');
842
+ }
759
843
 
760
844
  try {
761
845
  const { appendFunnelEvent } = require(path.join(PKG_ROOT, 'scripts', 'billing'));
@@ -785,7 +869,7 @@ function capture() {
785
869
  const { getUsage } = require(path.join(PKG_ROOT, 'scripts', 'rate-limiter'));
786
870
  const capLimit = checkLimit('capture_feedback');
787
871
  if (!capLimit.allowed) {
788
- limitNudge('capture_feedback');
872
+ limitNudge('capture_feedback', capLimit);
789
873
  process.exit(1);
790
874
  }
791
875
  trackEvent('cli_capture', { command: 'capture' });
@@ -855,6 +939,17 @@ function capture() {
855
939
  }
856
940
  }
857
941
  console.log('');
942
+ try {
943
+ const { buildCaptureReceipt } = require(path.join(PKG_ROOT, 'scripts', 'commercial-offer'));
944
+ console.log(buildCaptureReceipt({
945
+ signal: normalized,
946
+ feedbackId: ev.id,
947
+ memoryId: mem.id,
948
+ actionType: ev.actionType,
949
+ }));
950
+ } catch (_) {
951
+ // Receipt is a conversion aid, not part of feedback persistence.
952
+ }
858
953
  proNudge();
859
954
  } else {
860
955
  if (args.json) {
@@ -938,6 +1033,13 @@ function stats() {
938
1033
  } else {
939
1034
  console.log('\n✅ System is currently high-reliability. No immediate revenue loss detected.');
940
1035
  }
1036
+ try {
1037
+ const { buildStatsReceipt } = require(path.join(PKG_ROOT, 'scripts', 'commercial-offer'));
1038
+ const receipt = buildStatsReceipt(payload);
1039
+ if (receipt) console.log(receipt);
1040
+ } catch (_) {
1041
+ // Keep stats resilient if the receipt helper is unavailable in old installs.
1042
+ }
941
1043
  proNudge();
942
1044
  }
943
1045
 
@@ -1187,6 +1289,13 @@ function lessons() {
1187
1289
  const tags = String(args.tags || '').split(',').map((t) => t.trim()).filter(Boolean);
1188
1290
  const query = args.query || process.argv.slice(3).find((a) => !a.startsWith('--')) || '';
1189
1291
  const limit = Number(args.limit || 10);
1292
+ const { checkLimit } = require(path.join(PKG_ROOT, 'scripts', 'rate-limiter'));
1293
+ const searchLimit = checkLimit('search_lessons');
1294
+ if (!searchLimit.allowed) {
1295
+ trackEvent('cli_upgrade_prompt', { command: 'lessons', action: 'search_lessons', limitType: searchLimit.limitType || null });
1296
+ limitNudge('search_lessons', searchLimit);
1297
+ process.exit(1);
1298
+ }
1190
1299
 
1191
1300
  // --remote: fetch from hosted Railway instance
1192
1301
  if (args.remote) {
@@ -1453,13 +1562,10 @@ function risk() {
1453
1562
  }
1454
1563
 
1455
1564
  function exportDpo() {
1456
- const { isProTier } = require(path.join(PKG_ROOT, 'scripts', 'rate-limiter'));
1457
- if (!isProTier(null)) {
1458
- process.stderr.write(
1459
- `\n 🔒 DPO Export requires Pro (${PRO_PRICE_LABEL}).\n` +
1460
- ` Your feedback would generate valuable training pairs.\n` +
1461
- ` Upgrade: ${PRO_CHECKOUT_URL}\n\n`
1462
- );
1565
+ const { checkLimit } = require(path.join(PKG_ROOT, 'scripts', 'rate-limiter'));
1566
+ const exportLimit = checkLimit('export_dpo');
1567
+ if (!exportLimit.allowed) {
1568
+ limitNudge('export_dpo', exportLimit);
1463
1569
  process.exit(1);
1464
1570
  }
1465
1571
  const extraArgs = process.argv.slice(3).join(' ');
@@ -1476,13 +1582,10 @@ function exportDpo() {
1476
1582
  }
1477
1583
 
1478
1584
  function exportDatabricks() {
1479
- const { isProTier } = require(path.join(PKG_ROOT, 'scripts', 'rate-limiter'));
1480
- if (!isProTier(null)) {
1481
- process.stderr.write(
1482
- `\n 🔒 Databricks Export requires Pro (${PRO_PRICE_LABEL}).\n` +
1483
- ` Export feedback logs + proof artifacts for analytics.\n` +
1484
- ` Upgrade: ${PRO_CHECKOUT_URL}\n\n`
1485
- );
1585
+ const { checkLimit } = require(path.join(PKG_ROOT, 'scripts', 'rate-limiter'));
1586
+ const exportLimit = checkLimit('export_databricks');
1587
+ if (!exportLimit.allowed) {
1588
+ limitNudge('export_databricks', exportLimit);
1486
1589
  process.exit(1);
1487
1590
  }
1488
1591
  const extraArgs = process.argv.slice(3).join(' ');
@@ -2461,6 +2564,39 @@ if (COMMAND === 'daemon' || COMMAND === 'serve-daemon') {
2461
2564
  process.exit(0);
2462
2565
  }
2463
2566
 
2567
+ // ---------------------------------------------------------------------------
2568
+ // Global --help interceptor: `thumbgate <cmd> --help` shows per-command help
2569
+ // instead of running the command. Commands with their own --help guard (init)
2570
+ // handle it internally; everything else falls through here.
2571
+ // ---------------------------------------------------------------------------
2572
+ const _cliSubArgs = process.argv.slice(3);
2573
+ const _wantsHelp = _cliSubArgs.includes('--help') || _cliSubArgs.includes('-h');
2574
+
2575
+ const SUBCOMMAND_HELP = {
2576
+ capture: 'Usage: npx thumbgate capture --feedback=up|down --context="..." [--what-worked="..."] [--what-went-wrong="..."] [--what-to-change="..."] [--tags=a,b]',
2577
+ feedback: 'Usage: npx thumbgate feedback --feedback=up|down --context="..." [--what-worked="..."] [--what-went-wrong="..."] [--what-to-change="..."] [--tags=a,b]',
2578
+ stats: 'Usage: npx thumbgate stats\n\nShow gate enforcement statistics: blocked/warned counts, active gates, time saved.',
2579
+ trial: 'Usage: npx thumbgate trial\n\nShow Pro trial status, remaining days, and upgrade path.',
2580
+ pro: 'Usage: npx thumbgate pro [--activate <key>]\n\nLaunch the local Pro dashboard or activate a Pro license key.',
2581
+ subscribe: 'Usage: npx thumbgate subscribe <email>\n\nSubscribe to the 5-minute setup guide + trial reminders.',
2582
+ lessons: 'Usage: npx thumbgate lessons [--query="..."] [--limit=N]\n\nSearch the lesson database (Pro feature).',
2583
+ search: 'Usage: npx thumbgate search <query>\n\nSearch ThumbGate knowledge base (Pro feature).',
2584
+ 'gate-check': 'Usage: npx thumbgate gate-check\n\nPreToolUse hook interface: reads tool call JSON from stdin, outputs gate verdict.',
2585
+ 'export-dpo': 'Usage: npx thumbgate export-dpo [--format=jsonl|csv]\n\nExport feedback as DPO training pairs (Pro feature).',
2586
+ status: 'Usage: npx thumbgate status\n\nShow ThumbGate system health and active configuration.',
2587
+ watch: 'Usage: npx thumbgate watch\n\nWatch for feedback changes and auto-regenerate prevention rules.',
2588
+ compact: 'Usage: npx thumbgate compact\n\nCompact the lesson database and reclaim disk space.',
2589
+ 'context-packs': 'Usage: npx thumbgate context-packs\n\nGenerate context packs from top failure patterns.',
2590
+ suggest: 'Usage: npx thumbgate suggest <gate-id>\n\nSuggest fixes for a specific gate based on lesson history.',
2591
+ cost: 'Usage: npx thumbgate cost [--json] [--stats <path>] [--mix \'{"claude-sonnet-4-5":0.8,...}\']\n\nShow cumulative $ and tokens saved by PreToolUse gate blocks. Reads ~/.thumbgate/gate-stats.json.',
2592
+ savings: 'Usage: npx thumbgate savings [--json] [--stats <path>] [--mix \'{"claude-sonnet-4-5":0.8,...}\']\n\nAlias for `thumbgate cost`.',
2593
+ };
2594
+
2595
+ if (_wantsHelp && COMMAND && SUBCOMMAND_HELP[COMMAND]) {
2596
+ console.log(SUBCOMMAND_HELP[COMMAND]);
2597
+ process.exit(0);
2598
+ }
2599
+
2464
2600
  switch (COMMAND) {
2465
2601
  case '--version':
2466
2602
  case '-v':
@@ -2515,6 +2651,17 @@ switch (COMMAND) {
2515
2651
  case 'revenue':
2516
2652
  cfo();
2517
2653
  break;
2654
+ case 'cost':
2655
+ case 'savings':
2656
+ case 'costs': {
2657
+ const { main: costMain } = require(path.join(PKG_ROOT, 'scripts', 'cost-cli'));
2658
+ process.exit(costMain(process.argv.slice(3)));
2659
+ // process.exit doesn't return, but keep an explicit break so the switch
2660
+ // cannot accidentally fall through to case 'billing:setup' if a future
2661
+ // refactor wraps costMain in try/finally that intercepts the exit, or
2662
+ // a test runner stubs process.exit (flagged by gitar-bot on PR #2281).
2663
+ break;
2664
+ }
2518
2665
  case 'billing:setup':
2519
2666
  require(path.join(PKG_ROOT, 'scripts', 'billing-setup'));
2520
2667
  break;
@@ -2773,6 +2920,41 @@ switch (COMMAND) {
2773
2920
  case 'self-heal':
2774
2921
  selfHeal();
2775
2922
  break;
2923
+ case 'trial': {
2924
+ // Show trial status — connects the 4K monthly npm installers to checkout
2925
+ const { isProTier, isInTrialPeriod, trialDaysRemaining, getInstallAgeDays } = require(path.join(PKG_ROOT, 'scripts', 'rate-limiter'));
2926
+ const ageDays = getInstallAgeDays();
2927
+ const inTrial = isInTrialPeriod();
2928
+ const remaining = trialDaysRemaining();
2929
+ const isPro = isProTier();
2930
+ console.log('');
2931
+ console.log(' ThumbGate Pro Trial');
2932
+ console.log(' ──────────────────');
2933
+ if (isPro && !inTrial) {
2934
+ console.log(' Status: ✅ Pro (active license or API key)');
2935
+ } else if (inTrial) {
2936
+ const expiryDate = new Date(Date.now() + remaining * 86400000).toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' });
2937
+ console.log(` Status: 🎁 Active (${remaining} day${remaining === 1 ? '' : 's'} remaining)`);
2938
+ console.log(` Expires: ${expiryDate}`);
2939
+ console.log('');
2940
+ console.log(' All Pro features unlocked:');
2941
+ console.log(' • Unlimited prevention rules (free tier: 5)');
2942
+ console.log(' • Recall, lesson search, DPO export');
2943
+ console.log(' • Cross-machine sync via API key');
2944
+ } else {
2945
+ console.log(' Status: ⏰ Expired');
2946
+ if (ageDays !== null) {
2947
+ console.log(` Installed: ${Math.floor(ageDays)} days ago`);
2948
+ }
2949
+ console.log('');
2950
+ console.log(' Free tier: 5 active rules, no recall/search/export');
2951
+ }
2952
+ console.log('');
2953
+ console.log(` Keep Pro: ${PRO_CHECKOUT_URL}`);
2954
+ console.log(` Or set: THUMBGATE_API_KEY=<your-key>`);
2955
+ console.log('');
2956
+ break;
2957
+ }
2776
2958
  case 'pro':
2777
2959
  pro();
2778
2960
  break;
@@ -27,6 +27,11 @@
27
27
  "sentinel": "ThumbGate",
28
28
  "description": "First-party numbers / data transparency page"
29
29
  },
30
+ {
31
+ "route": "/ai-malpractice-prevention",
32
+ "sentinel": "AI Intake Risk Controls for Law Firms",
33
+ "description": "Legal AI intake risk-controls page for law-firm pilot conversations"
34
+ },
30
35
  {
31
36
  "route": "/llm-context.md",
32
37
  "sentinel": "## What ThumbGate Is",
@@ -72,6 +72,11 @@ components:
72
72
  description: Optional domain tags. If omitted, ThumbGate infers one from the feedback text before promotion.
73
73
  skill:
74
74
  type: string
75
+ source:
76
+ type: string
77
+ enum: [chatgpt_gpt]
78
+ default: chatgpt_gpt
79
+ description: Attribution marker for ThumbGate analytics. The published ThumbGate GPT should send `chatgpt_gpt` so owner dashboards can distinguish GPT Action calls from local API calls.
75
80
  IntentPlanRequest:
76
81
  type: object
77
82
  required: [intentId]
@@ -880,6 +885,11 @@ paths:
880
885
  toolName:
881
886
  type: string
882
887
  description: Tool name is optional when provider-native tool call payload is supplied.
888
+ source:
889
+ type: string
890
+ enum: [chatgpt_gpt]
891
+ default: chatgpt_gpt
892
+ description: Attribution marker for ThumbGate analytics. The published ThumbGate GPT should send `chatgpt_gpt` so owner dashboards can distinguish GPT Action calls from local API calls.
883
893
  provider:
884
894
  type: string
885
895
  model:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thumbgate",
3
- "version": "1.22.0",
3
+ "version": "1.23.1",
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": {
@@ -162,10 +162,12 @@
162
162
  "scripts/security-scanner.js",
163
163
  "scripts/self-distill-agent.js",
164
164
  "scripts/self-heal.js",
165
+ "scripts/self-healing-check.js",
165
166
  "scripts/semantic-dedup.js",
166
167
  "scripts/semantic-layer.js",
167
168
  "scripts/seo-gsd.js",
168
169
  "scripts/settings-hierarchy.js",
170
+ "scripts/silent-failure-cluster.js",
169
171
  "scripts/single-use-credential-gate.js",
170
172
  "scripts/skill-generator.js",
171
173
  "scripts/skill-rag-router.js",
@@ -224,6 +226,8 @@
224
226
  "public/agent-manager.html",
225
227
  "public/blog.html",
226
228
  "public/codex-enterprise.html",
229
+ "public/agents-cost-savings.html",
230
+ "public/ai-malpractice-prevention.html",
227
231
  "public/codex-plugin.html",
228
232
  "public/compare.html",
229
233
  "public/dashboard.html",
@@ -334,7 +338,7 @@
334
338
  "social:prospect:bluesky:dry": "node scripts/social-bluesky-prospecting.js --dry-run",
335
339
  "social:reply-publish:bluesky:dry": "node scripts/social-reply-monitor-bluesky.js --publish-approved --dry-run",
336
340
  "test:python": "python3 -m pytest tests/*.py",
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",
341
+ "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 && 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",
338
342
  "test:hook-stop-verify-deploy": "node --test tests/hook-stop-verify-deploy.test.js",
339
343
  "test:hook-stop-anti-claim": "node --test tests/hook-stop-anti-claim.test.js",
340
344
  "test:plausible-server-events": "node --test tests/plausible-server-events.test.js",
@@ -444,7 +448,7 @@
444
448
  "test:evolution": "node --test tests/workspace-evolver.test.js",
445
449
  "test:watcher": "node --test tests/jsonl-watcher.test.js",
446
450
  "test:autoresearch": "node --test tests/autoresearch.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",
451
+ "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/gates-engine-upgrade-cta.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 tests/daily-block-cap.test.js",
448
452
  "test:session-analyzer": "node --test tests/session-analyzer.test.js",
449
453
  "test:tessl": "node --test tests/tessl-export.test.js",
450
454
  "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",
@@ -599,6 +603,7 @@
599
603
  "agent:schedule": "node scripts/schedule-manager.js install --label managed-lesson-agent --spec 'daily 02:00' --command 'npm run agent:run' --workingDirectory .",
600
604
  "feedback:rules:llm": "node scripts/feedback-to-rules.js --llm",
601
605
  "test:self-distill": "node --test tests/self-distill-agent.test.js",
606
+ "test:silent-failure-cluster": "node --test tests/silent-failure-cluster.test.js",
602
607
  "test:seo-guides": "node --test tests/seo-guides.test.js",
603
608
  "self-distill:run": "node scripts/self-distill-agent.js",
604
609
  "self-distill:dry": "node scripts/self-distill-agent.js --dry-run",
@@ -633,6 +638,7 @@
633
638
  "test:high-roi": "node --test tests/high-roi.test.js tests/model-candidates.test.js tests/autonomous-workflow.test.js tests/high-roi-agent-workflows.test.js tests/interaction-model.test.js tests/interaction-model-e2e.test.js tests/code-graph-guardrails.test.js tests/proxy-pointer-rag-guardrails.test.js tests/rag-precision-guardrails.test.js tests/ai-engineering-stack-guardrails.test.js tests/long-running-agent-context-guardrails.test.js tests/reasoning-efficiency-guardrails.test.js tests/deepseek-v4-runtime-guardrails.test.js tests/upstream-contribution-engine.test.js tests/proactive-agent-eval-guardrails.test.js tests/reward-hacking-guardrails.test.js tests/chatgpt-ads-readiness-pack.test.js tests/oss-pr-opportunity-scout.test.js tests/agent-design-governance.test.js tests/gemini-embedding-policy.test.js tests/openclaw-agent-governance-kit.test.js",
634
639
  "test:public-static-assets": "node --test tests/public-static-assets.test.js",
635
640
  "test:token-savings": "node --test tests/token-savings.test.js",
641
+ "test:cost-cli": "node --test tests/cost-cli.test.js tests/conversion-receipt.test.js",
636
642
  "test:numbers-page": "node --test tests/numbers-page.test.js",
637
643
  "test:workflow-gate-checkpoint": "node --test tests/workflow-gate-checkpoint.test.js tests/autonomous-workflow.test.js",
638
644
  "workflow:autonomous": "node scripts/autonomous-workflow.js",
@@ -665,6 +671,10 @@
665
671
  "test:install-shim": "node --test tests/install-shim.test.js",
666
672
  "test:hook-runtime-subcommands": "node --test tests/hook-runtime-subcommands.test.js",
667
673
  "test:implementation-notes": "node --test tests/implementation-notes.test.js",
674
+ "test:daily-block-cap": "node --test tests/daily-block-cap.test.js",
675
+ "test:free-to-paid-conversion-units": "node --test tests/free-to-paid-conversion-units.test.js",
676
+ "test:metrics-real-endpoint": "node --test tests/metrics-real-endpoint.test.js",
677
+ "test:cli-trial-and-help": "node --test tests/cli-trial-and-help.test.js",
668
678
  "test:lessons-page-clickability": "playwright test tests/e2e/lessons-page-clickability.spec.js",
669
679
  "test:index-page-clickability": "playwright test tests/e2e/index-page-clickability.spec.js",
670
680
  "test:dashboard-page-clickability": "playwright test tests/e2e/dashboard-page-clickability.spec.js",