thumbgate 1.15.0 → 1.16.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.
Files changed (129) hide show
  1. package/.claude-plugin/marketplace.json +6 -6
  2. package/.claude-plugin/plugin.json +3 -3
  3. package/.well-known/llms.txt +5 -5
  4. package/.well-known/mcp/server-card.json +1 -1
  5. package/README.md +59 -35
  6. package/adapters/chatgpt/openapi.yaml +118 -2
  7. package/adapters/claude/.mcp.json +2 -2
  8. package/adapters/mcp/server-stdio.js +210 -84
  9. package/adapters/opencode/opencode.json +1 -1
  10. package/bench/prompt-eval-suite.json +5 -1
  11. package/bin/cli.js +157 -8
  12. package/config/evals/agent-safety-eval.json +338 -22
  13. package/config/gates/routine.json +43 -0
  14. package/config/github-about.json +3 -3
  15. package/config/model-candidates.json +131 -0
  16. package/openapi/openapi.yaml +118 -2
  17. package/package.json +57 -49
  18. package/public/blog.html +7 -7
  19. package/public/codex-plugin.html +6 -6
  20. package/public/compare.html +29 -23
  21. package/public/dashboard.html +82 -10
  22. package/public/guide.html +28 -28
  23. package/public/index.html +216 -98
  24. package/public/learn.html +50 -22
  25. package/public/lessons.html +1 -1
  26. package/public/numbers.html +17 -17
  27. package/public/pro.html +82 -18
  28. package/scripts/agent-audit-trace.js +55 -0
  29. package/scripts/agent-memory-lifecycle.js +96 -0
  30. package/scripts/agent-readiness-plan.js +118 -0
  31. package/scripts/agentic-data-pipeline.js +21 -1
  32. package/scripts/agents-sdk-sandbox-plan.js +57 -0
  33. package/scripts/ai-org-governance.js +98 -0
  34. package/scripts/ai-search-distribution.js +43 -0
  35. package/scripts/artifact-agent-plan.js +81 -0
  36. package/scripts/billing.js +27 -8
  37. package/scripts/cli-schema.js +18 -2
  38. package/scripts/code-mode-mcp-plan.js +71 -0
  39. package/scripts/context-engine.js +1 -2
  40. package/scripts/context-manager.js +4 -1
  41. package/scripts/dashboard-render-spec.js +1 -1
  42. package/scripts/dashboard.js +275 -9
  43. package/scripts/decision-journal.js +13 -3
  44. package/scripts/document-workflow-governance.js +62 -0
  45. package/scripts/enterprise-agent-rollout.js +34 -0
  46. package/scripts/experience-replay-governance.js +69 -0
  47. package/scripts/export-hf-dataset.js +1 -1
  48. package/scripts/feedback-loop.js +92 -4
  49. package/scripts/feedback-to-rules.js +17 -23
  50. package/scripts/gates-engine.js +4 -6
  51. package/scripts/growth-campaigns.js +49 -0
  52. package/scripts/harness-selector.js +16 -4
  53. package/scripts/hybrid-supervisor-agent.js +64 -0
  54. package/scripts/inference-cache-policy.js +72 -0
  55. package/scripts/inference-economics.js +53 -0
  56. package/scripts/internal-agent-bootstrap.js +12 -2
  57. package/scripts/knowledge-layer-plan.js +108 -0
  58. package/scripts/lesson-inference.js +183 -44
  59. package/scripts/lesson-search.js +4 -1
  60. package/scripts/llm-client.js +157 -26
  61. package/scripts/mailer/resend-mailer.js +112 -1
  62. package/scripts/mcp-transport-strategy.js +66 -0
  63. package/scripts/memory-store-governance.js +60 -0
  64. package/scripts/meta-agent-loop.js +7 -13
  65. package/scripts/model-access-eligibility.js +38 -0
  66. package/scripts/model-migration-readiness.js +55 -0
  67. package/scripts/operational-integrity.js +96 -3
  68. package/scripts/otel-declarative-config.js +56 -0
  69. package/scripts/perplexity-client.js +1 -1
  70. package/scripts/post-training-governance.js +34 -0
  71. package/scripts/private-core-boundary.js +72 -0
  72. package/scripts/production-agent-readiness.js +40 -0
  73. package/scripts/prompt-eval.js +564 -32
  74. package/scripts/prompt-programs.js +93 -0
  75. package/scripts/provider-action-normalizer.js +585 -0
  76. package/scripts/scaling-law-claims.js +60 -0
  77. package/scripts/security-scanner.js +1 -1
  78. package/scripts/self-distill-agent.js +7 -32
  79. package/scripts/seo-gsd.js +232 -55
  80. package/scripts/skill-rag-router.js +53 -0
  81. package/scripts/spec-gate.js +1 -1
  82. package/scripts/student-consistent-training.js +73 -0
  83. package/scripts/synthetic-data-provenance.js +98 -0
  84. package/scripts/task-context-result.js +81 -0
  85. package/scripts/telemetry-analytics.js +149 -0
  86. package/scripts/thompson-sampling.js +2 -2
  87. package/scripts/token-savings.js +7 -6
  88. package/scripts/token-tco.js +46 -0
  89. package/scripts/tool-registry.js +63 -3
  90. package/scripts/verification-loop.js +10 -1
  91. package/scripts/verifier-scoring.js +71 -0
  92. package/scripts/workflow-sentinel.js +284 -28
  93. package/scripts/workspace-agent-routines.js +118 -0
  94. package/src/api/server.js +381 -120
  95. package/scripts/analytics-report.js +0 -328
  96. package/scripts/autonomous-workflow.js +0 -377
  97. package/scripts/billing-setup.js +0 -109
  98. package/scripts/creator-campaigns.js +0 -239
  99. package/scripts/cross-encoder-reranker.js +0 -235
  100. package/scripts/daemon-manager.js +0 -108
  101. package/scripts/decision-trace.js +0 -354
  102. package/scripts/delegation-runtime.js +0 -896
  103. package/scripts/dispatch-brief.js +0 -159
  104. package/scripts/distribution-surfaces.js +0 -110
  105. package/scripts/feedback-history-distiller.js +0 -382
  106. package/scripts/funnel-analytics.js +0 -35
  107. package/scripts/history-distiller.js +0 -200
  108. package/scripts/hosted-job-launcher.js +0 -256
  109. package/scripts/intent-router.js +0 -392
  110. package/scripts/lesson-reranker.js +0 -263
  111. package/scripts/lesson-retrieval.js +0 -148
  112. package/scripts/managed-lesson-agent.js +0 -183
  113. package/scripts/operational-dashboard.js +0 -103
  114. package/scripts/operational-summary.js +0 -129
  115. package/scripts/operator-artifacts.js +0 -608
  116. package/scripts/optimize-context.js +0 -17
  117. package/scripts/org-dashboard.js +0 -206
  118. package/scripts/partner-orchestration.js +0 -146
  119. package/scripts/predictive-insights.js +0 -356
  120. package/scripts/pulse.js +0 -80
  121. package/scripts/reflector-agent.js +0 -221
  122. package/scripts/sales-pipeline.js +0 -681
  123. package/scripts/session-episode-store.js +0 -329
  124. package/scripts/session-health-sensor.js +0 -242
  125. package/scripts/session-report.js +0 -120
  126. package/scripts/swarm-coordinator.js +0 -81
  127. package/scripts/tool-kpi-tracker.js +0 -12
  128. package/scripts/webhook-delivery.js +0 -62
  129. package/scripts/workflow-sprint-intake.js +0 -475
@@ -4,6 +4,10 @@
4
4
  const fs = require('fs');
5
5
  const path = require('path');
6
6
  const promptCache = new Map();
7
+ const {
8
+ createUnavailableReport,
9
+ loadOptionalModule,
10
+ } = require('../../scripts/private-core-boundary');
7
11
 
8
12
  function getCachedPrompt(key) {
9
13
  return promptCache.get(key);
@@ -46,14 +50,6 @@ const {
46
50
  readSessionHandoff,
47
51
  } = require('../../scripts/contextfs');
48
52
  const { buildRubricEvaluation } = require('../../scripts/rubric-engine');
49
- const {
50
- listIntents,
51
- planIntent,
52
- } = require('../../scripts/intent-router');
53
- const {
54
- startHandoff,
55
- completeHandoff,
56
- } = require('../../scripts/delegation-runtime');
57
53
  const {
58
54
  getActiveMcpProfile,
59
55
  getAllowedTools,
@@ -80,6 +76,9 @@ const {
80
76
  const {
81
77
  evaluateWorkflowSentinel,
82
78
  } = require('../../scripts/workflow-sentinel');
79
+ const {
80
+ normalizeProviderAction,
81
+ } = require('../../scripts/provider-action-normalizer');
83
82
  const { diagnoseFailure } = require('../../scripts/failure-diagnostics');
84
83
  const {
85
84
  analyzeCodeGraphImpact,
@@ -98,12 +97,11 @@ const {
98
97
  loadModel,
99
98
  getReliability,
100
99
  } = require('../../scripts/thompson-sampling');
101
- const {
102
- searchLessons,
103
- } = require('../../scripts/lesson-search');
104
100
  const {
105
101
  retrieveRelevantLessons,
106
- } = require('../../scripts/lesson-retrieval');
102
+ } = loadOptionalModule(path.join(__dirname, '../../scripts/lesson-retrieval'), () => ({
103
+ retrieveRelevantLessons: () => [],
104
+ }));
107
105
  const {
108
106
  searchThumbgate,
109
107
  } = require('../../scripts/thumbgate-search');
@@ -116,7 +114,17 @@ const {
116
114
  readImportedDocument,
117
115
  } = require('../../scripts/document-intake');
118
116
  const { checkLimit, UPGRADE_MESSAGE } = require('../../scripts/rate-limiter');
119
- const { generateOrgDashboard } = require('../../scripts/org-dashboard');
117
+ const { generateOrgDashboard } = loadOptionalModule(path.join(__dirname, '../../scripts/org-dashboard'), () => ({
118
+ generateOrgDashboard: () => ({
119
+ activeAgents: 0,
120
+ totalAgents: 0,
121
+ orgAdherenceRate: 0,
122
+ topBlockedGates: [],
123
+ riskAgents: [],
124
+ upgradeMessage: 'Org dashboard requires ThumbGate-Core.',
125
+ ...createUnavailableReport('Org dashboard'),
126
+ }),
127
+ }));
120
128
  const {
121
129
  listHarnesses,
122
130
  runHarness,
@@ -124,21 +132,56 @@ const {
124
132
  const { runLoop: runAutoresearchLoop } = require('../../scripts/autoresearch-runner');
125
133
  const { TOOLS } = require('../../scripts/tool-registry');
126
134
  const { buildContextFootprintReport } = require('../../scripts/context-footprint');
127
- const { reflect: reflectOnFeedback } = require('../../scripts/reflector-agent');
135
+ const { reflect: reflectOnFeedback } = loadOptionalModule(path.join(__dirname, '../../scripts/reflector-agent'), () => ({
136
+ reflect: () => createUnavailableReport('Feedback reflection'),
137
+ }));
128
138
  const { submitProductIssue } = require('../../scripts/product-feedback');
129
139
  const {
130
140
  assembleUnifiedContext,
131
141
  formatUnifiedContext,
132
142
  } = require('../../scripts/context-manager');
133
143
  const { exportHfDataset } = require('../../scripts/export-hf-dataset');
134
- const { distributeContextToAgents } = require('../../scripts/swarm-coordinator');
135
- const { buildSessionReport } = require('../../scripts/session-report');
136
- const {
137
- generateOperatorArtifact,
138
- formatArtifactMarkdown,
139
- } = require('../../scripts/operator-artifacts');
140
144
 
141
145
  const PRO_CHECKOUT_URL = 'https://thumbgate-production.up.railway.app/checkout/pro';
146
+ const PRIVATE_MCP_MODULES = Object.freeze({
147
+ intentRouter: path.resolve(__dirname, '../../scripts/intent-router.js'),
148
+ delegationRuntime: path.resolve(__dirname, '../../scripts/delegation-runtime.js'),
149
+ orgDashboard: path.resolve(__dirname, '../../scripts/org-dashboard.js'),
150
+ reflectorAgent: path.resolve(__dirname, '../../scripts/reflector-agent.js'),
151
+ swarmCoordinator: path.resolve(__dirname, '../../scripts/swarm-coordinator.js'),
152
+ sessionReport: path.resolve(__dirname, '../../scripts/session-report.js'),
153
+ operatorArtifacts: path.resolve(__dirname, '../../scripts/operator-artifacts.js'),
154
+ managedLessonAgent: path.resolve(__dirname, '../../scripts/managed-lesson-agent.js'),
155
+ semanticLayer: path.resolve(__dirname, '../../scripts/semantic-layer.js'),
156
+ lessonInference: path.resolve(__dirname, '../../scripts/lesson-inference.js'),
157
+ lessonSearch: path.resolve(__dirname, '../../scripts/lesson-search.js'),
158
+ });
159
+
160
+ function loadPrivateMcpModule(key) {
161
+ const modulePath = PRIVATE_MCP_MODULES[key];
162
+ if (!modulePath) {
163
+ throw new Error(`Unknown private MCP module: ${key}`);
164
+ }
165
+ try {
166
+ return require(modulePath);
167
+ } catch (error) {
168
+ const message = String(error && error.message || '');
169
+ if ((error && (error.code === 'MODULE_NOT_FOUND' || error.code === 'ERR_MODULE_NOT_FOUND'))
170
+ && (message.includes(modulePath) || message.includes(path.basename(modulePath)))) {
171
+ return null;
172
+ }
173
+ throw error;
174
+ }
175
+ }
176
+
177
+ function unavailablePrivateMcpFeature(toolName) {
178
+ return toTextResult({
179
+ ok: false,
180
+ availability: 'private_core',
181
+ tool: toolName,
182
+ message: `${toolName} is only available in the ThumbGate private core or hosted runtime.`,
183
+ });
184
+ }
142
185
 
143
186
  function enforceLimit(action) {
144
187
  const limit = checkLimit(action);
@@ -158,7 +201,7 @@ const {
158
201
  finalizeSession: finalizeFeedbackSession,
159
202
  } = require('../../scripts/feedback-session');
160
203
 
161
- const SERVER_INFO = { name: 'thumbgate-mcp', version: '1.15.0' };
204
+ const SERVER_INFO = { name: 'thumbgate-mcp', version: '1.16.1' };
162
205
  const COMMERCE_CATEGORIES = [
163
206
  'product_recommendation',
164
207
  'brand_compliance',
@@ -316,13 +359,14 @@ function buildDiagnoseFailureResponse(args = {}) {
316
359
 
317
360
  if (args.intentId) {
318
361
  try {
319
- intentPlan = planIntent({
362
+ const module = loadPrivateMcpModule('intentRouter');
363
+ intentPlan = module ? module.planIntent({
320
364
  intentId: args.intentId,
321
365
  context: args.context || '',
322
366
  mcpProfile: requestedProfile,
323
367
  approved: args.approved === true,
324
368
  repoPath: args.repoPath,
325
- });
369
+ }) : null;
326
370
  } catch (_) {
327
371
  intentPlan = null;
328
372
  }
@@ -511,15 +555,24 @@ async function callToolInner(name, args) {
511
555
  return toCaptureFeedbackTextResult(captureFeedback(args));
512
556
  case 'feedback_summary':
513
557
  return toTextResult(feedbackSummary(Number(args.recent || 20)));
514
- case 'search_lessons':
515
- return toTextResult(searchLessons(args.query || '', {
558
+ case 'search_lessons': {
559
+ const module = loadPrivateMcpModule('lessonSearch');
560
+ if (!module) return unavailablePrivateMcpFeature('search_lessons');
561
+ return toTextResult(module.searchLessons(args.query || '', {
516
562
  limit: Number(args.limit || 10),
517
563
  category: args.category,
518
564
  tags: Array.isArray(args.tags) ? args.tags : [],
519
565
  }));
566
+ }
520
567
  case 'retrieve_lessons': {
521
568
  // Cross-encoder reranking: retrieve more candidates, then rerank for precision
522
- const { retrieveWithRerankingSync } = require('../../scripts/cross-encoder-reranker');
569
+ const { retrieveWithRerankingSync } = loadOptionalModule(path.join(__dirname, '../../scripts/cross-encoder-reranker'), () => ({
570
+ retrieveWithRerankingSync: (toolName, actionContext, options = {}) => retrieveRelevantLessons(
571
+ toolName,
572
+ actionContext,
573
+ { maxResults: options.maxResults || 5 },
574
+ ),
575
+ }));
523
576
  return toTextResult(retrieveWithRerankingSync(
524
577
  args.toolName,
525
578
  args.actionContext || '',
@@ -565,13 +618,17 @@ async function callToolInner(name, args) {
565
618
  case 'diagnose_failure':
566
619
  return buildDiagnoseFailureResponse(args);
567
620
  case 'reflect_on_feedback':
568
- return toTextResult(reflectOnFeedback({
621
+ {
622
+ const module = loadPrivateMcpModule('reflectorAgent');
623
+ if (!module) return unavailablePrivateMcpFeature('reflect_on_feedback');
624
+ return toTextResult(module.reflect({
569
625
  conversationWindow: args.conversationWindow || [],
570
626
  context: args.context || '',
571
627
  whatWentWrong: args.whatWentWrong || '',
572
628
  structuredRule: null,
573
629
  feedbackEvent: args.feedbackEventId ? { id: args.feedbackEventId } : null,
574
- }));
630
+ }));
631
+ }
575
632
  case 'report_product_issue':
576
633
  return toTextResult(await submitProductIssue({
577
634
  title: args.title,
@@ -580,52 +637,69 @@ async function callToolInner(name, args) {
580
637
  source: 'mcp tool',
581
638
  }));
582
639
  case 'list_intents':
583
- return toTextResult(listIntents({
584
- mcpProfile: args.mcpProfile,
585
- bundleId: args.bundleId,
586
- partnerProfile: args.partnerProfile,
587
- }));
640
+ {
641
+ const module = loadPrivateMcpModule('intentRouter');
642
+ if (!module) return unavailablePrivateMcpFeature('list_intents');
643
+ return toTextResult(module.listIntents({
644
+ mcpProfile: args.mcpProfile,
645
+ bundleId: args.bundleId,
646
+ partnerProfile: args.partnerProfile,
647
+ }));
648
+ }
588
649
  case 'plan_intent':
589
- return toTextResult(planIntent({
590
- intentId: args.intentId,
591
- context: args.context || '',
592
- mcpProfile: args.mcpProfile,
593
- bundleId: args.bundleId,
594
- partnerProfile: args.partnerProfile,
595
- delegationMode: args.delegationMode,
596
- approved: args.approved === true,
597
- repoPath: args.repoPath,
598
- }));
599
- case 'start_handoff':
600
- return toTextResult(startHandoff({
601
- plan: planIntent({
650
+ {
651
+ const module = loadPrivateMcpModule('intentRouter');
652
+ if (!module) return unavailablePrivateMcpFeature('plan_intent');
653
+ return toTextResult(module.planIntent({
602
654
  intentId: args.intentId,
603
655
  context: args.context || '',
604
656
  mcpProfile: args.mcpProfile,
605
657
  bundleId: args.bundleId,
606
658
  partnerProfile: args.partnerProfile,
607
- delegationMode: 'sequential',
659
+ delegationMode: args.delegationMode,
608
660
  approved: args.approved === true,
609
661
  repoPath: args.repoPath,
610
- }),
611
- context: args.context || '',
612
- mcpProfile: args.mcpProfile || getActiveMcpProfile(),
613
- partnerProfile: args.partnerProfile || null,
614
- repoPath: args.repoPath,
615
- delegateProfile: args.delegateProfile || null,
616
- plannedChecks: Array.isArray(args.plannedChecks) ? args.plannedChecks : [],
617
- }));
662
+ }));
663
+ }
664
+ case 'start_handoff':
665
+ {
666
+ const intentRouter = loadPrivateMcpModule('intentRouter');
667
+ const delegationRuntime = loadPrivateMcpModule('delegationRuntime');
668
+ if (!intentRouter || !delegationRuntime) return unavailablePrivateMcpFeature('start_handoff');
669
+ return toTextResult(delegationRuntime.startHandoff({
670
+ plan: intentRouter.planIntent({
671
+ intentId: args.intentId,
672
+ context: args.context || '',
673
+ mcpProfile: args.mcpProfile,
674
+ bundleId: args.bundleId,
675
+ partnerProfile: args.partnerProfile,
676
+ delegationMode: 'sequential',
677
+ approved: args.approved === true,
678
+ repoPath: args.repoPath,
679
+ }),
680
+ context: args.context || '',
681
+ mcpProfile: args.mcpProfile || getActiveMcpProfile(),
682
+ partnerProfile: args.partnerProfile || null,
683
+ repoPath: args.repoPath,
684
+ delegateProfile: args.delegateProfile || null,
685
+ plannedChecks: Array.isArray(args.plannedChecks) ? args.plannedChecks : [],
686
+ }));
687
+ }
618
688
  case 'complete_handoff':
619
- return toTextResult(completeHandoff({
620
- handoffId: args.handoffId,
621
- outcome: args.outcome,
622
- resultContext: args.resultContext || '',
623
- attempts: args.attempts,
624
- violationCount: args.violationCount,
625
- tokenEstimate: args.tokenEstimate,
626
- latencyMs: args.latencyMs,
627
- summary: args.summary || '',
628
- }));
689
+ {
690
+ const module = loadPrivateMcpModule('delegationRuntime');
691
+ if (!module) return unavailablePrivateMcpFeature('complete_handoff');
692
+ return toTextResult(module.completeHandoff({
693
+ handoffId: args.handoffId,
694
+ outcome: args.outcome,
695
+ resultContext: args.resultContext || '',
696
+ attempts: args.attempts,
697
+ violationCount: args.violationCount,
698
+ tokenEstimate: args.tokenEstimate,
699
+ latencyMs: args.latencyMs,
700
+ summary: args.summary || '',
701
+ }));
702
+ }
629
703
  case 'enforcement_matrix':
630
704
  return toTextResult(listEnforcementMatrix());
631
705
  case 'security_scan': {
@@ -797,23 +871,33 @@ async function callToolInner(name, args) {
797
871
  });
798
872
  }
799
873
  case 'distribute_context_to_agents':
800
- return toTextResult(distributeContextToAgents({
874
+ {
875
+ const module = loadPrivateMcpModule('swarmCoordinator');
876
+ if (!module) return unavailablePrivateMcpFeature('distribute_context_to_agents');
877
+ return toTextResult(module.distributeContextToAgents({
801
878
  query: args.query || '',
802
879
  agents: args.agents,
803
880
  maxItems: args.maxItems,
804
881
  maxChars: args.maxChars,
805
882
  namespaces: Array.isArray(args.namespaces) ? args.namespaces : [],
806
883
  ttlMs: args.ttlMs,
807
- }));
884
+ }));
885
+ }
808
886
  case 'session_report':
809
- return toTextResult(buildSessionReport({ windowHours: args.windowHours }));
887
+ {
888
+ const module = loadPrivateMcpModule('sessionReport');
889
+ if (!module) return unavailablePrivateMcpFeature('session_report');
890
+ return toTextResult(module.buildSessionReport({ windowHours: args.windowHours }));
891
+ }
810
892
  case 'generate_operator_artifact': {
811
- const artifact = await generateOperatorArtifact({
893
+ const module = loadPrivateMcpModule('operatorArtifacts');
894
+ if (!module) return unavailablePrivateMcpFeature('generate_operator_artifact');
895
+ const artifact = await module.generateOperatorArtifact({
812
896
  type: args.type,
813
897
  windowHours: args.windowHours,
814
898
  });
815
899
  if (args.format === 'markdown') {
816
- return toTextResult(formatArtifactMarkdown(artifact));
900
+ return toTextResult(module.formatArtifactMarkdown(artifact));
817
901
  }
818
902
  return toTextResult(artifact);
819
903
  }
@@ -827,20 +911,43 @@ async function callToolInner(name, args) {
827
911
  branchGovernance: getBranchGovernanceState(),
828
912
  }));
829
913
  case 'workflow_sentinel':
830
- return toTextResult(evaluateWorkflowSentinel(args.toolName, {
914
+ {
915
+ const normalizedAction = normalizeProviderAction(args);
916
+ const changedFiles = Array.isArray(args.changedFiles) ? args.changedFiles : normalizedAction.affectedFiles;
917
+ return toTextResult(evaluateWorkflowSentinel(normalizedAction.toolName || args.toolName, {
831
918
  command: args.command,
832
919
  path: args.filePath,
833
- changedFiles: Array.isArray(args.changedFiles) ? args.changedFiles : [],
920
+ changedFiles,
834
921
  repoPath: args.repoPath,
835
922
  baseBranch: args.baseBranch,
923
+ providerToolCall: args.providerToolCall,
924
+ toolCall: args.toolCall,
925
+ toolUse: args.toolUse,
926
+ content: args.content,
927
+ input: args.input,
928
+ arguments: args.arguments,
929
+ method: args.method,
930
+ params: args.params,
931
+ mcp: args.mcp,
932
+ mcpToolCall: args.mcpToolCall,
933
+ budget: args.budget,
934
+ usage: args.usage,
836
935
  }, {
936
+ provider: args.provider,
937
+ model: args.model,
938
+ normalizedAction,
939
+ usage: args.usage,
940
+ tokenEstimate: args.tokenEstimate,
941
+ costUsd: args.costUsd,
942
+ budget: args.budget,
837
943
  repoPath: args.repoPath,
838
944
  baseBranch: args.baseBranch,
839
- affectedFiles: Array.isArray(args.changedFiles) ? args.changedFiles : undefined,
945
+ affectedFiles: changedFiles.length > 0 ? changedFiles : undefined,
840
946
  requirePrForReleaseSensitive: args.requirePrForReleaseSensitive === true,
841
947
  requireVersionNotBehindBase: args.requireVersionNotBehindBase === true,
842
948
  governanceState: getScopeState(),
843
949
  }));
950
+ }
844
951
  case 'register_claim_gate':
845
952
  return toTextResult(registerClaimGate(args.claimPattern, args.requiredActions, args.message));
846
953
  case 'gate_stats':
@@ -848,7 +955,11 @@ async function callToolInner(name, args) {
848
955
  case 'dashboard':
849
956
  return toTextResult(generateDashboard(getFeedbackPaths().FEEDBACK_DIR));
850
957
  case 'org_dashboard':
851
- return toTextResult(generateOrgDashboard({ windowHours: Number(args.windowHours || 24) }));
958
+ {
959
+ const module = loadPrivateMcpModule('orgDashboard');
960
+ if (!module) return unavailablePrivateMcpFeature('org_dashboard');
961
+ return toTextResult(module.generateOrgDashboard({ windowHours: Number(args.windowHours || 24) }));
962
+ }
852
963
  case 'settings_status':
853
964
  return toTextResult(getSettingsStatus());
854
965
  case 'native_messaging_audit':
@@ -861,13 +972,15 @@ async function callToolInner(name, args) {
861
972
  enforceLimit('commerce_recall');
862
973
  return buildCommerceRecallResponse(args);
863
974
  case 'get_business_metrics': {
864
- const { getBusinessMetrics } = require('../../scripts/semantic-layer');
865
- const metrics = await getBusinessMetrics(args);
975
+ const module = loadPrivateMcpModule('semanticLayer');
976
+ if (!module) return unavailablePrivateMcpFeature('get_business_metrics');
977
+ const metrics = await module.getBusinessMetrics(args);
866
978
  return toTextResult(metrics);
867
979
  }
868
980
  case 'describe_semantic_entity': {
869
- const { describeSemanticSchema } = require('../../scripts/semantic-layer');
870
- const schema = describeSemanticSchema();
981
+ const module = loadPrivateMcpModule('semanticLayer');
982
+ if (!module) return unavailablePrivateMcpFeature('describe_semantic_entity');
983
+ const schema = module.describeSemanticSchema();
871
984
  const entity = schema.entities[args.type] || schema.metrics[args.type];
872
985
  if (!entity) {
873
986
  throw new Error(`Unknown semantic entity: ${args.type}`);
@@ -937,12 +1050,14 @@ async function callToolInner(name, args) {
937
1050
  case 'finalize_feedback_session':
938
1051
  return toTextResult(finalizeFeedbackSession(args.sessionId));
939
1052
  case 'run_managed_lesson_agent': {
940
- const { runManagedAgent } = require('../../scripts/managed-lesson-agent');
941
- return toTextResult(await runManagedAgent({ dryRun: args.dryRun, limit: args.limit, model: args.model }));
1053
+ const module = loadPrivateMcpModule('managedLessonAgent');
1054
+ if (!module) return unavailablePrivateMcpFeature('run_managed_lesson_agent');
1055
+ return toTextResult(await module.runManagedAgent({ dryRun: args.dryRun, limit: args.limit, model: args.model }));
942
1056
  }
943
1057
  case 'managed_agent_status': {
944
- const { getManagedAgentStatus } = require('../../scripts/managed-lesson-agent');
945
- return toTextResult(getManagedAgentStatus() || { message: 'No managed agent runs recorded yet.' });
1058
+ const module = loadPrivateMcpModule('managedLessonAgent');
1059
+ if (!module) return unavailablePrivateMcpFeature('managed_agent_status');
1060
+ return toTextResult(module.getManagedAgentStatus() || { message: 'No managed agent runs recorded yet.' });
946
1061
  }
947
1062
  case 'run_self_distill': {
948
1063
  const { runSelfDistill } = require('../../scripts/self-distill-agent');
@@ -953,8 +1068,13 @@ async function callToolInner(name, args) {
953
1068
  return toTextResult(getSelfDistillStatus() || { message: 'No self-distill runs found.' });
954
1069
  }
955
1070
  case 'context_stuff_lessons': {
956
- const { getAllLessonsForContext } = require('../../scripts/lesson-inference');
957
- return toTextResult(getAllLessonsForContext({ maxTokenBudget: args.maxTokenBudget, signal: args.signal, format: args.format }));
1071
+ const module = loadPrivateMcpModule('lessonInference');
1072
+ if (!module) return unavailablePrivateMcpFeature('context_stuff_lessons');
1073
+ return toTextResult(module.getAllLessonsForContext({
1074
+ maxTokenBudget: args.maxTokenBudget,
1075
+ signal: args.signal,
1076
+ format: args.format,
1077
+ }));
958
1078
  }
959
1079
  default:
960
1080
  throw new Error(`Unsupported tool: ${name}`);
@@ -1175,4 +1295,10 @@ module.exports = {
1175
1295
  acquireLock,
1176
1296
  toCaptureFeedbackTextResult,
1177
1297
  formatCorrectiveActionsReminder,
1298
+ __test__: {
1299
+ PRIVATE_MCP_MODULES,
1300
+ loadPrivateMcpModule,
1301
+ unavailablePrivateMcpFeature,
1302
+ callToolInner,
1303
+ },
1178
1304
  };
@@ -7,7 +7,7 @@
7
7
  "npx",
8
8
  "--yes",
9
9
  "--package",
10
- "thumbgate@1.15.0",
10
+ "thumbgate@1.16.1",
11
11
  "thumbgate",
12
12
  "serve"
13
13
  ],
@@ -2,6 +2,10 @@
2
2
  "version": 1,
3
3
  "name": "ThumbGate Prompt Evaluation",
4
4
  "description": "Tests core ThumbGate prompts against expected outputs. Based on Anthropic prompt evaluation methodology: test against expected answers, compare versions, review outputs for errors.",
5
+ "successCriteria": {
6
+ "minAggregateScore": 80,
7
+ "requireNoRegressions": true
8
+ },
5
9
  "evaluations": [
6
10
  {
7
11
  "id": "lesson-distill-negative-clear",
@@ -81,7 +85,7 @@
81
85
  "hasDomain": true,
82
86
  "domain": "testing",
83
87
  "hasOutcome": true,
84
- "outcomeContains": ["failure", "error"]
88
+ "outcomeContains": ["failure"]
85
89
  }
86
90
  },
87
91
  {