thumbgate 1.14.1 → 1.16.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.
Files changed (150) 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 +60 -35
  6. package/adapters/chatgpt/openapi.yaml +118 -2
  7. package/adapters/claude/.mcp.json +2 -2
  8. package/adapters/mcp/server-stdio.js +217 -84
  9. package/adapters/opencode/opencode.json +1 -1
  10. package/bench/prompt-eval-suite.json +5 -1
  11. package/bin/cli.js +211 -8
  12. package/config/enforcement.json +59 -7
  13. package/config/evals/agent-safety-eval.json +338 -22
  14. package/config/gates/default.json +33 -0
  15. package/config/gates/routine.json +43 -0
  16. package/config/github-about.json +3 -3
  17. package/config/mcp-allowlists.json +4 -0
  18. package/config/merge-quality-checks.json +2 -1
  19. package/config/model-candidates.json +131 -0
  20. package/openapi/openapi.yaml +118 -2
  21. package/package.json +70 -51
  22. package/public/blog.html +7 -7
  23. package/public/codex-plugin.html +13 -7
  24. package/public/compare.html +29 -23
  25. package/public/dashboard.html +105 -12
  26. package/public/guide.html +28 -28
  27. package/public/index.html +233 -97
  28. package/public/learn.html +87 -20
  29. package/public/lessons.html +26 -2
  30. package/public/numbers.html +271 -0
  31. package/public/pro.html +89 -19
  32. package/scripts/agent-audit-trace.js +55 -0
  33. package/scripts/agent-memory-lifecycle.js +96 -0
  34. package/scripts/agent-readiness-plan.js +118 -0
  35. package/scripts/agentic-data-pipeline.js +21 -1
  36. package/scripts/agents-sdk-sandbox-plan.js +57 -0
  37. package/scripts/ai-org-governance.js +98 -0
  38. package/scripts/ai-search-distribution.js +43 -0
  39. package/scripts/artifact-agent-plan.js +81 -0
  40. package/scripts/billing.js +27 -8
  41. package/scripts/cli-feedback.js +2 -1
  42. package/scripts/cli-schema.js +60 -5
  43. package/scripts/code-mode-mcp-plan.js +71 -0
  44. package/scripts/commercial-offer.js +1 -1
  45. package/scripts/context-engine.js +1 -2
  46. package/scripts/context-manager.js +4 -1
  47. package/scripts/contextfs.js +214 -32
  48. package/scripts/dashboard-render-spec.js +1 -1
  49. package/scripts/dashboard.js +275 -9
  50. package/scripts/decision-journal.js +13 -3
  51. package/scripts/document-workflow-governance.js +62 -0
  52. package/scripts/enterprise-agent-rollout.js +34 -0
  53. package/scripts/experience-replay-governance.js +69 -0
  54. package/scripts/export-hf-dataset.js +1 -1
  55. package/scripts/feedback-loop.js +141 -9
  56. package/scripts/feedback-to-rules.js +17 -23
  57. package/scripts/gates-engine.js +4 -6
  58. package/scripts/growth-campaigns.js +49 -0
  59. package/scripts/harness-selector.js +145 -1
  60. package/scripts/hybrid-supervisor-agent.js +64 -0
  61. package/scripts/inference-cache-policy.js +72 -0
  62. package/scripts/inference-economics.js +53 -0
  63. package/scripts/internal-agent-bootstrap.js +12 -2
  64. package/scripts/knowledge-layer-plan.js +108 -0
  65. package/scripts/lesson-canonical.js +181 -0
  66. package/scripts/lesson-db.js +71 -10
  67. package/scripts/lesson-inference.js +183 -44
  68. package/scripts/lesson-search.js +4 -1
  69. package/scripts/lesson-synthesis.js +23 -2
  70. package/scripts/llm-client.js +157 -26
  71. package/scripts/mailer/resend-mailer.js +112 -1
  72. package/scripts/mcp-transport-strategy.js +66 -0
  73. package/scripts/memory-store-governance.js +60 -0
  74. package/scripts/meta-agent-loop.js +7 -13
  75. package/scripts/model-access-eligibility.js +38 -0
  76. package/scripts/model-migration-readiness.js +55 -0
  77. package/scripts/native-messaging-audit.js +514 -0
  78. package/scripts/operational-integrity.js +96 -3
  79. package/scripts/otel-declarative-config.js +56 -0
  80. package/scripts/perplexity-client.js +1 -1
  81. package/scripts/post-training-governance.js +34 -0
  82. package/scripts/pr-manager.js +47 -7
  83. package/scripts/private-core-boundary.js +72 -0
  84. package/scripts/production-agent-readiness.js +40 -0
  85. package/scripts/profile-router.js +16 -1
  86. package/scripts/prompt-eval.js +564 -32
  87. package/scripts/prompt-programs.js +93 -0
  88. package/scripts/provider-action-normalizer.js +585 -0
  89. package/scripts/rule-validator.js +285 -0
  90. package/scripts/scaling-law-claims.js +60 -0
  91. package/scripts/security-scanner.js +1 -1
  92. package/scripts/self-distill-agent.js +7 -32
  93. package/scripts/seo-gsd.js +400 -43
  94. package/scripts/skill-rag-router.js +53 -0
  95. package/scripts/spec-gate.js +1 -1
  96. package/scripts/student-consistent-training.js +73 -0
  97. package/scripts/synthetic-data-provenance.js +98 -0
  98. package/scripts/task-context-result.js +81 -0
  99. package/scripts/telemetry-analytics.js +149 -0
  100. package/scripts/thompson-sampling.js +2 -2
  101. package/scripts/token-savings.js +7 -6
  102. package/scripts/token-tco.js +46 -0
  103. package/scripts/tool-registry.js +75 -3
  104. package/scripts/verification-loop.js +10 -1
  105. package/scripts/verifier-scoring.js +71 -0
  106. package/scripts/workflow-sentinel.js +284 -28
  107. package/scripts/workspace-agent-routines.js +118 -0
  108. package/skills/thumbgate/SKILL.md +1 -1
  109. package/src/api/server.js +434 -120
  110. package/.claude-plugin/README.md +0 -170
  111. package/adapters/README.md +0 -12
  112. package/scripts/analytics-report.js +0 -328
  113. package/scripts/autonomous-workflow.js +0 -377
  114. package/scripts/billing-setup.js +0 -109
  115. package/scripts/creator-campaigns.js +0 -239
  116. package/scripts/cross-encoder-reranker.js +0 -235
  117. package/scripts/daemon-manager.js +0 -108
  118. package/scripts/decision-trace.js +0 -354
  119. package/scripts/delegation-runtime.js +0 -896
  120. package/scripts/dispatch-brief.js +0 -159
  121. package/scripts/distribution-surfaces.js +0 -110
  122. package/scripts/feedback-history-distiller.js +0 -382
  123. package/scripts/funnel-analytics.js +0 -35
  124. package/scripts/history-distiller.js +0 -200
  125. package/scripts/hosted-job-launcher.js +0 -256
  126. package/scripts/intent-router.js +0 -392
  127. package/scripts/lesson-reranker.js +0 -263
  128. package/scripts/lesson-retrieval.js +0 -148
  129. package/scripts/managed-lesson-agent.js +0 -183
  130. package/scripts/operational-dashboard.js +0 -103
  131. package/scripts/operational-summary.js +0 -129
  132. package/scripts/operator-artifacts.js +0 -608
  133. package/scripts/optimize-context.js +0 -17
  134. package/scripts/org-dashboard.js +0 -206
  135. package/scripts/partner-orchestration.js +0 -146
  136. package/scripts/predictive-insights.js +0 -356
  137. package/scripts/pulse.js +0 -80
  138. package/scripts/reflector-agent.js +0 -221
  139. package/scripts/sales-pipeline.js +0 -681
  140. package/scripts/session-episode-store.js +0 -329
  141. package/scripts/session-health-sensor.js +0 -242
  142. package/scripts/session-report.js +0 -120
  143. package/scripts/swarm-coordinator.js +0 -81
  144. package/scripts/tool-kpi-tracker.js +0 -12
  145. package/scripts/webhook-delivery.js +0 -62
  146. package/scripts/workflow-sprint-intake.js +0 -475
  147. package/skills/agent-memory/SKILL.md +0 -97
  148. package/skills/solve-architecture-autonomy/SKILL.md +0 -17
  149. package/skills/solve-architecture-autonomy/tool.js +0 -33
  150. package/skills/thumbgate-feedback/SKILL.md +0 -49
@@ -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,
@@ -93,16 +92,16 @@ const { exportDatabricksBundle } = require('../../scripts/export-databricks-bund
93
92
  const { generateDashboard } = require('../../scripts/dashboard');
94
93
  const { getSettingsStatus } = require('../../scripts/settings-hierarchy');
95
94
  const { generateSkills } = require('../../scripts/skill-generator');
95
+ const { buildNativeMessagingAudit } = require('../../scripts/native-messaging-audit');
96
96
  const {
97
97
  loadModel,
98
98
  getReliability,
99
99
  } = require('../../scripts/thompson-sampling');
100
- const {
101
- searchLessons,
102
- } = require('../../scripts/lesson-search');
103
100
  const {
104
101
  retrieveRelevantLessons,
105
- } = require('../../scripts/lesson-retrieval');
102
+ } = loadOptionalModule(path.join(__dirname, '../../scripts/lesson-retrieval'), () => ({
103
+ retrieveRelevantLessons: () => [],
104
+ }));
106
105
  const {
107
106
  searchThumbgate,
108
107
  } = require('../../scripts/thumbgate-search');
@@ -115,7 +114,17 @@ const {
115
114
  readImportedDocument,
116
115
  } = require('../../scripts/document-intake');
117
116
  const { checkLimit, UPGRADE_MESSAGE } = require('../../scripts/rate-limiter');
118
- 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
+ }));
119
128
  const {
120
129
  listHarnesses,
121
130
  runHarness,
@@ -123,21 +132,56 @@ const {
123
132
  const { runLoop: runAutoresearchLoop } = require('../../scripts/autoresearch-runner');
124
133
  const { TOOLS } = require('../../scripts/tool-registry');
125
134
  const { buildContextFootprintReport } = require('../../scripts/context-footprint');
126
- const { reflect: reflectOnFeedback } = require('../../scripts/reflector-agent');
135
+ const { reflect: reflectOnFeedback } = loadOptionalModule(path.join(__dirname, '../../scripts/reflector-agent'), () => ({
136
+ reflect: () => createUnavailableReport('Feedback reflection'),
137
+ }));
127
138
  const { submitProductIssue } = require('../../scripts/product-feedback');
128
139
  const {
129
140
  assembleUnifiedContext,
130
141
  formatUnifiedContext,
131
142
  } = require('../../scripts/context-manager');
132
143
  const { exportHfDataset } = require('../../scripts/export-hf-dataset');
133
- const { distributeContextToAgents } = require('../../scripts/swarm-coordinator');
134
- const { buildSessionReport } = require('../../scripts/session-report');
135
- const {
136
- generateOperatorArtifact,
137
- formatArtifactMarkdown,
138
- } = require('../../scripts/operator-artifacts');
139
144
 
140
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
+ }
141
185
 
142
186
  function enforceLimit(action) {
143
187
  const limit = checkLimit(action);
@@ -157,7 +201,7 @@ const {
157
201
  finalizeSession: finalizeFeedbackSession,
158
202
  } = require('../../scripts/feedback-session');
159
203
 
160
- const SERVER_INFO = { name: 'thumbgate-mcp', version: '1.14.1' };
204
+ const SERVER_INFO = { name: 'thumbgate-mcp', version: '1.16.0' };
161
205
  const COMMERCE_CATEGORIES = [
162
206
  'product_recommendation',
163
207
  'brand_compliance',
@@ -315,13 +359,14 @@ function buildDiagnoseFailureResponse(args = {}) {
315
359
 
316
360
  if (args.intentId) {
317
361
  try {
318
- intentPlan = planIntent({
362
+ const module = loadPrivateMcpModule('intentRouter');
363
+ intentPlan = module ? module.planIntent({
319
364
  intentId: args.intentId,
320
365
  context: args.context || '',
321
366
  mcpProfile: requestedProfile,
322
367
  approved: args.approved === true,
323
368
  repoPath: args.repoPath,
324
- });
369
+ }) : null;
325
370
  } catch (_) {
326
371
  intentPlan = null;
327
372
  }
@@ -510,15 +555,24 @@ async function callToolInner(name, args) {
510
555
  return toCaptureFeedbackTextResult(captureFeedback(args));
511
556
  case 'feedback_summary':
512
557
  return toTextResult(feedbackSummary(Number(args.recent || 20)));
513
- case 'search_lessons':
514
- 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 || '', {
515
562
  limit: Number(args.limit || 10),
516
563
  category: args.category,
517
564
  tags: Array.isArray(args.tags) ? args.tags : [],
518
565
  }));
566
+ }
519
567
  case 'retrieve_lessons': {
520
568
  // Cross-encoder reranking: retrieve more candidates, then rerank for precision
521
- 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
+ }));
522
576
  return toTextResult(retrieveWithRerankingSync(
523
577
  args.toolName,
524
578
  args.actionContext || '',
@@ -564,13 +618,17 @@ async function callToolInner(name, args) {
564
618
  case 'diagnose_failure':
565
619
  return buildDiagnoseFailureResponse(args);
566
620
  case 'reflect_on_feedback':
567
- return toTextResult(reflectOnFeedback({
621
+ {
622
+ const module = loadPrivateMcpModule('reflectorAgent');
623
+ if (!module) return unavailablePrivateMcpFeature('reflect_on_feedback');
624
+ return toTextResult(module.reflect({
568
625
  conversationWindow: args.conversationWindow || [],
569
626
  context: args.context || '',
570
627
  whatWentWrong: args.whatWentWrong || '',
571
628
  structuredRule: null,
572
629
  feedbackEvent: args.feedbackEventId ? { id: args.feedbackEventId } : null,
573
- }));
630
+ }));
631
+ }
574
632
  case 'report_product_issue':
575
633
  return toTextResult(await submitProductIssue({
576
634
  title: args.title,
@@ -579,52 +637,69 @@ async function callToolInner(name, args) {
579
637
  source: 'mcp tool',
580
638
  }));
581
639
  case 'list_intents':
582
- return toTextResult(listIntents({
583
- mcpProfile: args.mcpProfile,
584
- bundleId: args.bundleId,
585
- partnerProfile: args.partnerProfile,
586
- }));
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
+ }
587
649
  case 'plan_intent':
588
- return toTextResult(planIntent({
589
- intentId: args.intentId,
590
- context: args.context || '',
591
- mcpProfile: args.mcpProfile,
592
- bundleId: args.bundleId,
593
- partnerProfile: args.partnerProfile,
594
- delegationMode: args.delegationMode,
595
- approved: args.approved === true,
596
- repoPath: args.repoPath,
597
- }));
598
- case 'start_handoff':
599
- return toTextResult(startHandoff({
600
- plan: planIntent({
650
+ {
651
+ const module = loadPrivateMcpModule('intentRouter');
652
+ if (!module) return unavailablePrivateMcpFeature('plan_intent');
653
+ return toTextResult(module.planIntent({
601
654
  intentId: args.intentId,
602
655
  context: args.context || '',
603
656
  mcpProfile: args.mcpProfile,
604
657
  bundleId: args.bundleId,
605
658
  partnerProfile: args.partnerProfile,
606
- delegationMode: 'sequential',
659
+ delegationMode: args.delegationMode,
607
660
  approved: args.approved === true,
608
661
  repoPath: args.repoPath,
609
- }),
610
- context: args.context || '',
611
- mcpProfile: args.mcpProfile || getActiveMcpProfile(),
612
- partnerProfile: args.partnerProfile || null,
613
- repoPath: args.repoPath,
614
- delegateProfile: args.delegateProfile || null,
615
- plannedChecks: Array.isArray(args.plannedChecks) ? args.plannedChecks : [],
616
- }));
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
+ }
617
688
  case 'complete_handoff':
618
- return toTextResult(completeHandoff({
619
- handoffId: args.handoffId,
620
- outcome: args.outcome,
621
- resultContext: args.resultContext || '',
622
- attempts: args.attempts,
623
- violationCount: args.violationCount,
624
- tokenEstimate: args.tokenEstimate,
625
- latencyMs: args.latencyMs,
626
- summary: args.summary || '',
627
- }));
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
+ }
628
703
  case 'enforcement_matrix':
629
704
  return toTextResult(listEnforcementMatrix());
630
705
  case 'security_scan': {
@@ -796,23 +871,33 @@ async function callToolInner(name, args) {
796
871
  });
797
872
  }
798
873
  case 'distribute_context_to_agents':
799
- return toTextResult(distributeContextToAgents({
874
+ {
875
+ const module = loadPrivateMcpModule('swarmCoordinator');
876
+ if (!module) return unavailablePrivateMcpFeature('distribute_context_to_agents');
877
+ return toTextResult(module.distributeContextToAgents({
800
878
  query: args.query || '',
801
879
  agents: args.agents,
802
880
  maxItems: args.maxItems,
803
881
  maxChars: args.maxChars,
804
882
  namespaces: Array.isArray(args.namespaces) ? args.namespaces : [],
805
883
  ttlMs: args.ttlMs,
806
- }));
884
+ }));
885
+ }
807
886
  case 'session_report':
808
- 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
+ }
809
892
  case 'generate_operator_artifact': {
810
- const artifact = await generateOperatorArtifact({
893
+ const module = loadPrivateMcpModule('operatorArtifacts');
894
+ if (!module) return unavailablePrivateMcpFeature('generate_operator_artifact');
895
+ const artifact = await module.generateOperatorArtifact({
811
896
  type: args.type,
812
897
  windowHours: args.windowHours,
813
898
  });
814
899
  if (args.format === 'markdown') {
815
- return toTextResult(formatArtifactMarkdown(artifact));
900
+ return toTextResult(module.formatArtifactMarkdown(artifact));
816
901
  }
817
902
  return toTextResult(artifact);
818
903
  }
@@ -826,20 +911,43 @@ async function callToolInner(name, args) {
826
911
  branchGovernance: getBranchGovernanceState(),
827
912
  }));
828
913
  case 'workflow_sentinel':
829
- 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, {
830
918
  command: args.command,
831
919
  path: args.filePath,
832
- changedFiles: Array.isArray(args.changedFiles) ? args.changedFiles : [],
920
+ changedFiles,
833
921
  repoPath: args.repoPath,
834
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,
835
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,
836
943
  repoPath: args.repoPath,
837
944
  baseBranch: args.baseBranch,
838
- affectedFiles: Array.isArray(args.changedFiles) ? args.changedFiles : undefined,
945
+ affectedFiles: changedFiles.length > 0 ? changedFiles : undefined,
839
946
  requirePrForReleaseSensitive: args.requirePrForReleaseSensitive === true,
840
947
  requireVersionNotBehindBase: args.requireVersionNotBehindBase === true,
841
948
  governanceState: getScopeState(),
842
949
  }));
950
+ }
843
951
  case 'register_claim_gate':
844
952
  return toTextResult(registerClaimGate(args.claimPattern, args.requiredActions, args.message));
845
953
  case 'gate_stats':
@@ -847,20 +955,32 @@ async function callToolInner(name, args) {
847
955
  case 'dashboard':
848
956
  return toTextResult(generateDashboard(getFeedbackPaths().FEEDBACK_DIR));
849
957
  case 'org_dashboard':
850
- 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
+ }
851
963
  case 'settings_status':
852
964
  return toTextResult(getSettingsStatus());
965
+ case 'native_messaging_audit':
966
+ return toTextResult(buildNativeMessagingAudit({
967
+ platform: args.platform,
968
+ homeDir: args.homeDir,
969
+ aiOnly: args.aiOnly === true,
970
+ }));
853
971
  case 'commerce_recall':
854
972
  enforceLimit('commerce_recall');
855
973
  return buildCommerceRecallResponse(args);
856
974
  case 'get_business_metrics': {
857
- const { getBusinessMetrics } = require('../../scripts/semantic-layer');
858
- 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);
859
978
  return toTextResult(metrics);
860
979
  }
861
980
  case 'describe_semantic_entity': {
862
- const { describeSemanticSchema } = require('../../scripts/semantic-layer');
863
- const schema = describeSemanticSchema();
981
+ const module = loadPrivateMcpModule('semanticLayer');
982
+ if (!module) return unavailablePrivateMcpFeature('describe_semantic_entity');
983
+ const schema = module.describeSemanticSchema();
864
984
  const entity = schema.entities[args.type] || schema.metrics[args.type];
865
985
  if (!entity) {
866
986
  throw new Error(`Unknown semantic entity: ${args.type}`);
@@ -930,12 +1050,14 @@ async function callToolInner(name, args) {
930
1050
  case 'finalize_feedback_session':
931
1051
  return toTextResult(finalizeFeedbackSession(args.sessionId));
932
1052
  case 'run_managed_lesson_agent': {
933
- const { runManagedAgent } = require('../../scripts/managed-lesson-agent');
934
- 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 }));
935
1056
  }
936
1057
  case 'managed_agent_status': {
937
- const { getManagedAgentStatus } = require('../../scripts/managed-lesson-agent');
938
- 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.' });
939
1061
  }
940
1062
  case 'run_self_distill': {
941
1063
  const { runSelfDistill } = require('../../scripts/self-distill-agent');
@@ -946,8 +1068,13 @@ async function callToolInner(name, args) {
946
1068
  return toTextResult(getSelfDistillStatus() || { message: 'No self-distill runs found.' });
947
1069
  }
948
1070
  case 'context_stuff_lessons': {
949
- const { getAllLessonsForContext } = require('../../scripts/lesson-inference');
950
- 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
+ }));
951
1078
  }
952
1079
  default:
953
1080
  throw new Error(`Unsupported tool: ${name}`);
@@ -1168,4 +1295,10 @@ module.exports = {
1168
1295
  acquireLock,
1169
1296
  toCaptureFeedbackTextResult,
1170
1297
  formatCorrectiveActionsReminder,
1298
+ __test__: {
1299
+ PRIVATE_MCP_MODULES,
1300
+ loadPrivateMcpModule,
1301
+ unavailablePrivateMcpFeature,
1302
+ callToolInner,
1303
+ },
1171
1304
  };
@@ -7,7 +7,7 @@
7
7
  "npx",
8
8
  "--yes",
9
9
  "--package",
10
- "thumbgate@1.14.1",
10
+ "thumbgate@1.16.0",
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
  {