tachibot-mcp 2.0.2

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 (214) hide show
  1. package/.env.example +260 -0
  2. package/CHANGELOG.md +54 -0
  3. package/CODE_OF_CONDUCT.md +56 -0
  4. package/CONTRIBUTING.md +54 -0
  5. package/Dockerfile +36 -0
  6. package/LICENSE +644 -0
  7. package/README.md +201 -0
  8. package/SECURITY.md +95 -0
  9. package/dist/personality/komaai-expressions.js +12 -0
  10. package/dist/profiles/balanced.json +33 -0
  11. package/dist/profiles/code_focus.json +33 -0
  12. package/dist/profiles/full.json +33 -0
  13. package/dist/profiles/minimal.json +33 -0
  14. package/dist/profiles/research_power.json +33 -0
  15. package/dist/scripts/build-profiles.js +46 -0
  16. package/dist/src/application/services/focus/FocusModeRegistry.js +46 -0
  17. package/dist/src/application/services/focus/FocusTool.service.js +109 -0
  18. package/dist/src/application/services/focus/ModeRegistry.js +46 -0
  19. package/dist/src/application/services/focus/modes/focus-deep.mode.js +27 -0
  20. package/dist/src/application/services/focus/modes/status.mode.js +50 -0
  21. package/dist/src/application/services/focus/modes/tachibot-status.mode.js +50 -0
  22. package/dist/src/collaborative-orchestrator.js +391 -0
  23. package/dist/src/config/model-constants.js +188 -0
  24. package/dist/src/config/model-defaults.js +57 -0
  25. package/dist/src/config/model-preferences.js +382 -0
  26. package/dist/src/config/timeout-config.js +130 -0
  27. package/dist/src/config.js +173 -0
  28. package/dist/src/domain/interfaces/IFocusMode.js +5 -0
  29. package/dist/src/domain/interfaces/IProvider.js +6 -0
  30. package/dist/src/domain/interfaces/ITool.js +5 -0
  31. package/dist/src/focus-deep.js +245 -0
  32. package/dist/src/infrastructure/ascii/art/robots.ascii.js +16 -0
  33. package/dist/src/mcp-client.js +90 -0
  34. package/dist/src/memory/index.js +17 -0
  35. package/dist/src/memory/memory-config.js +135 -0
  36. package/dist/src/memory/memory-interface.js +174 -0
  37. package/dist/src/memory/memory-manager.js +383 -0
  38. package/dist/src/memory/providers/devlog-provider.js +385 -0
  39. package/dist/src/memory/providers/hybrid-provider.js +399 -0
  40. package/dist/src/memory/providers/local-provider.js +388 -0
  41. package/dist/src/memory/providers/mem0-provider.js +337 -0
  42. package/dist/src/modes/architect.js +477 -0
  43. package/dist/src/modes/auditor.js +362 -0
  44. package/dist/src/modes/challenger.js +841 -0
  45. package/dist/src/modes/code-reviewer.js +382 -0
  46. package/dist/src/modes/commit-guardian.js +424 -0
  47. package/dist/src/modes/documentation-writer.js +572 -0
  48. package/dist/src/modes/scout.js +587 -0
  49. package/dist/src/modes/shared/helpers/challenger-helpers.js +454 -0
  50. package/dist/src/modes/shared/helpers/index.js +17 -0
  51. package/dist/src/modes/shared/helpers/scout-helpers.js +270 -0
  52. package/dist/src/modes/shared/helpers/verifier-helpers.js +332 -0
  53. package/dist/src/modes/test-architect.js +767 -0
  54. package/dist/src/modes/verifier.js +378 -0
  55. package/dist/src/monitoring/performance-monitor.js +435 -0
  56. package/dist/src/optimization/batch-executor.js +121 -0
  57. package/dist/src/optimization/context-pruner.js +196 -0
  58. package/dist/src/optimization/cost-monitor.js +338 -0
  59. package/dist/src/optimization/index.js +65 -0
  60. package/dist/src/optimization/model-router.js +264 -0
  61. package/dist/src/optimization/result-cache.js +114 -0
  62. package/dist/src/optimization/token-optimizer.js +257 -0
  63. package/dist/src/optimization/token-tracker.js +118 -0
  64. package/dist/src/orchestrator-instructions.js +128 -0
  65. package/dist/src/orchestrator-lite.js +139 -0
  66. package/dist/src/orchestrator.js +191 -0
  67. package/dist/src/orchestrators/collaborative/interfaces/IToolExecutionEngine.js +1 -0
  68. package/dist/src/orchestrators/collaborative/interfaces/IToolExecutionStrategy.js +5 -0
  69. package/dist/src/orchestrators/collaborative/interfaces/IVisualizationRenderer.js +1 -0
  70. package/dist/src/orchestrators/collaborative/registries/ModelProviderRegistry.js +95 -0
  71. package/dist/src/orchestrators/collaborative/registries/ToolAdapterRegistry.js +64 -0
  72. package/dist/src/orchestrators/collaborative/services/tool-execution/ToolExecutionService.js +502 -0
  73. package/dist/src/orchestrators/collaborative/services/visualization/VisualizationService.js +206 -0
  74. package/dist/src/orchestrators/collaborative/types/session-types.js +5 -0
  75. package/dist/src/profiles/balanced.js +37 -0
  76. package/dist/src/profiles/code_focus.js +37 -0
  77. package/dist/src/profiles/debug_intensive.js +59 -0
  78. package/dist/src/profiles/full.js +37 -0
  79. package/dist/src/profiles/minimal.js +37 -0
  80. package/dist/src/profiles/research_code.js +59 -0
  81. package/dist/src/profiles/research_power.js +37 -0
  82. package/dist/src/profiles/types.js +5 -0
  83. package/dist/src/profiles/workflow_builder.js +53 -0
  84. package/dist/src/prompt-engineer-lite.js +78 -0
  85. package/dist/src/prompt-engineer.js +399 -0
  86. package/dist/src/reasoning-chain.js +508 -0
  87. package/dist/src/sequential-thinking.js +291 -0
  88. package/dist/src/server-diagnostic.js +74 -0
  89. package/dist/src/server-raw.js +158 -0
  90. package/dist/src/server-simple.js +58 -0
  91. package/dist/src/server.js +514 -0
  92. package/dist/src/session/session-logger.js +617 -0
  93. package/dist/src/session/session-manager.js +571 -0
  94. package/dist/src/session/session-tools.js +400 -0
  95. package/dist/src/tools/advanced-modes.js +200 -0
  96. package/dist/src/tools/claude-integration.js +356 -0
  97. package/dist/src/tools/consolidated/ai-router.js +174 -0
  98. package/dist/src/tools/consolidated/ai-tool.js +48 -0
  99. package/dist/src/tools/consolidated/brainstorm-tool.js +87 -0
  100. package/dist/src/tools/consolidated/environment-detector.js +80 -0
  101. package/dist/src/tools/consolidated/index.js +50 -0
  102. package/dist/src/tools/consolidated/search-tool.js +110 -0
  103. package/dist/src/tools/consolidated/workflow-tool.js +238 -0
  104. package/dist/src/tools/gemini-tools.js +329 -0
  105. package/dist/src/tools/grok-enhanced.js +376 -0
  106. package/dist/src/tools/grok-tools.js +299 -0
  107. package/dist/src/tools/lmstudio-tools.js +223 -0
  108. package/dist/src/tools/openai-tools.js +498 -0
  109. package/dist/src/tools/openrouter-tools.js +317 -0
  110. package/dist/src/tools/optimized-wrapper.js +204 -0
  111. package/dist/src/tools/perplexity-tools.js +294 -0
  112. package/dist/src/tools/pingpong-tool.js +343 -0
  113. package/dist/src/tools/qwen-wrapper.js +74 -0
  114. package/dist/src/tools/tool-router.js +444 -0
  115. package/dist/src/tools/unified-ai-provider.js +260 -0
  116. package/dist/src/tools/workflow-runner.js +425 -0
  117. package/dist/src/tools/workflow-validator-tool.js +107 -0
  118. package/dist/src/types.js +23 -0
  119. package/dist/src/utils/input-validator.js +130 -0
  120. package/dist/src/utils/model-router.js +91 -0
  121. package/dist/src/utils/progress-stream.js +255 -0
  122. package/dist/src/utils/provider-router.js +88 -0
  123. package/dist/src/utils/smart-api-client.js +146 -0
  124. package/dist/src/utils/table-builder.js +218 -0
  125. package/dist/src/utils/timestamp-formatter.js +134 -0
  126. package/dist/src/utils/tool-compressor.js +257 -0
  127. package/dist/src/utils/tool-config.js +201 -0
  128. package/dist/src/validators/dependency-graph-validator.js +147 -0
  129. package/dist/src/validators/interpolation-validator.js +222 -0
  130. package/dist/src/validators/output-usage-validator.js +151 -0
  131. package/dist/src/validators/syntax-validator.js +102 -0
  132. package/dist/src/validators/tool-registry-validator.js +123 -0
  133. package/dist/src/validators/tool-types.js +97 -0
  134. package/dist/src/validators/types.js +8 -0
  135. package/dist/src/validators/workflow-validator.js +134 -0
  136. package/dist/src/visualizer-lite.js +42 -0
  137. package/dist/src/visualizer.js +179 -0
  138. package/dist/src/workflows/circuit-breaker.js +199 -0
  139. package/dist/src/workflows/custom-workflows.js +451 -0
  140. package/dist/src/workflows/engine/AutoSynthesizer.js +97 -0
  141. package/dist/src/workflows/engine/StepParameterResolver.js +74 -0
  142. package/dist/src/workflows/engine/VariableInterpolator.js +123 -0
  143. package/dist/src/workflows/engine/WorkflowDiscovery.js +125 -0
  144. package/dist/src/workflows/engine/WorkflowExecutionEngine.js +485 -0
  145. package/dist/src/workflows/engine/WorkflowExecutor.js +113 -0
  146. package/dist/src/workflows/engine/WorkflowFileManager.js +244 -0
  147. package/dist/src/workflows/engine/WorkflowHelpers.js +114 -0
  148. package/dist/src/workflows/engine/WorkflowOutputFormatter.js +83 -0
  149. package/dist/src/workflows/engine/events/WorkflowEventBus.js +132 -0
  150. package/dist/src/workflows/engine/events/interfaces/IEventBus.js +5 -0
  151. package/dist/src/workflows/engine/handlers/ErrorRecoveryHandler.js +162 -0
  152. package/dist/src/workflows/engine/handlers/PromptEnhancementHandler.js +115 -0
  153. package/dist/src/workflows/engine/handlers/SessionPersistenceHandler.js +167 -0
  154. package/dist/src/workflows/engine/handlers/StepExecutionHandler.js +231 -0
  155. package/dist/src/workflows/engine/handlers/ToolInvocationHandler.js +46 -0
  156. package/dist/src/workflows/engine/interfaces/IAutoSynthesizer.js +5 -0
  157. package/dist/src/workflows/engine/interfaces/IStepParameterResolver.js +5 -0
  158. package/dist/src/workflows/engine/interfaces/IVariableInterpolator.js +5 -0
  159. package/dist/src/workflows/engine/interfaces/IWorkflowDiscovery.js +4 -0
  160. package/dist/src/workflows/engine/interfaces/IWorkflowFileManager.js +5 -0
  161. package/dist/src/workflows/engine/interfaces/IWorkflowOutputFormatter.js +5 -0
  162. package/dist/src/workflows/engine/state/WorkflowStateMachine.js +194 -0
  163. package/dist/src/workflows/engine/state/interfaces/IStateMachine.js +17 -0
  164. package/dist/src/workflows/fallback-strategies.js +373 -0
  165. package/dist/src/workflows/message-queue.js +455 -0
  166. package/dist/src/workflows/model-router.js +189 -0
  167. package/dist/src/workflows/orchestrator-examples.js +174 -0
  168. package/dist/src/workflows/orchestrator-integration.js +200 -0
  169. package/dist/src/workflows/self-healing.js +524 -0
  170. package/dist/src/workflows/tool-mapper.js +407 -0
  171. package/dist/src/workflows/tool-orchestrator.js +796 -0
  172. package/dist/src/workflows/workflow-engine.js +573 -0
  173. package/dist/src/workflows/workflow-parser.js +283 -0
  174. package/dist/src/workflows/workflow-types.js +95 -0
  175. package/dist/src/workflows.js +568 -0
  176. package/dist/test-workflow-file-output.js +93 -0
  177. package/docs/API_KEYS.md +570 -0
  178. package/docs/CLAUDE_CODE_SETUP.md +181 -0
  179. package/docs/CLAUDE_DESKTOP_MANUAL.md +127 -0
  180. package/docs/CONFIGURATION.md +745 -0
  181. package/docs/FOCUS_MODES.md +240 -0
  182. package/docs/INSTALLATION_BOTH.md +145 -0
  183. package/docs/TERMS.md +352 -0
  184. package/docs/TOOLS_REFERENCE.md +1622 -0
  185. package/docs/TOOL_PARAMETERS.md +496 -0
  186. package/docs/TOOL_PROFILES.md +236 -0
  187. package/docs/WORKFLOWS.md +987 -0
  188. package/docs/WORKFLOW_OUTPUT.md +198 -0
  189. package/docs/WORKFLOW_PROGRESS_TRACKING.md +305 -0
  190. package/docs/workflows/design-brainstorm.md +335 -0
  191. package/package.json +97 -0
  192. package/profiles/balanced.json +37 -0
  193. package/profiles/code_focus.json +37 -0
  194. package/profiles/debug_intensive.json +34 -0
  195. package/profiles/full.json +37 -0
  196. package/profiles/minimal.json +37 -0
  197. package/profiles/research_power.json +37 -0
  198. package/profiles/workflow_builder.json +37 -0
  199. package/smithery.yaml +66 -0
  200. package/start.sh +8 -0
  201. package/tools.config.json +81 -0
  202. package/tsconfig.json +18 -0
  203. package/workflows/accessibility-code-audit.yaml +92 -0
  204. package/workflows/code-architecture-review.yaml +202 -0
  205. package/workflows/code-review.yaml +142 -0
  206. package/workflows/core/iterative-problem-solver.yaml +283 -0
  207. package/workflows/creative-brainstorm-yaml.yaml +215 -0
  208. package/workflows/pingpong.yaml +141 -0
  209. package/workflows/system/README.md +412 -0
  210. package/workflows/system/challenger.yaml +175 -0
  211. package/workflows/system/scout.yaml +164 -0
  212. package/workflows/system/verifier.yaml +133 -0
  213. package/workflows/ultra-creative-brainstorm.yaml +318 -0
  214. package/workflows/ux-research-flow.yaml +92 -0
@@ -0,0 +1,454 @@
1
+ /**
2
+ * Challenger Helper Functions
3
+ *
4
+ * Pure, composable functions for devil's advocate analysis.
5
+ * Used by workflows/system/challenger.yaml
6
+ *
7
+ * Purpose: Expand perspectives, not find faults
8
+ * - Challenge assumptions and basic truths
9
+ * - Find counter-evidence and alternatives
10
+ * - Explore opposite thinking ("what if we're backwards?")
11
+ * - Discover third-way solutions beyond binary choices
12
+ *
13
+ * SOLID Principles:
14
+ * - Single Responsibility: Each function does ONE transformation
15
+ * - Open/Closed: Functions are closed for modification, open for extension
16
+ * - Liskov Substitution: All functions are predictable pure functions
17
+ * - Interface Segregation: Small, focused function signatures
18
+ * - Dependency Inversion: Functions depend on types, not concrete implementations
19
+ */
20
+ // ============================================================================
21
+ // Tone Detection
22
+ // ============================================================================
23
+ /**
24
+ * Flag uncontested tone - authoritarian language that shuts down dissent
25
+ *
26
+ * Detects phrases like:
27
+ * - "obviously", "clearly", "everyone knows"
28
+ * - "the only way", "undeniably", "without question"
29
+ * - "unanimous", "no disagreement", "settled science"
30
+ *
31
+ * Severity:
32
+ * - high: 3+ phrases (strong groupthink indicators)
33
+ * - medium: 2 phrases
34
+ * - low: 1 phrase
35
+ */
36
+ export const flagUncontestedTone = (config) => {
37
+ const uncontestedPhrases = [
38
+ 'obviously',
39
+ 'clearly',
40
+ 'everyone knows',
41
+ 'everyone agrees',
42
+ 'the only way',
43
+ 'undeniably',
44
+ 'without question',
45
+ 'unanimous',
46
+ 'no disagreement',
47
+ 'settled science',
48
+ 'beyond doubt',
49
+ 'no alternative',
50
+ 'must',
51
+ 'always',
52
+ 'never'
53
+ ];
54
+ const foundPhrases = uncontestedPhrases.filter(phrase => config.text.toLowerCase().includes(phrase));
55
+ const severity = foundPhrases.length >= 3 ? 'high'
56
+ : foundPhrases.length >= 2 ? 'medium'
57
+ : 'low';
58
+ const message = foundPhrases.length === 0
59
+ ? 'No uncontested tone detected - healthy room for debate'
60
+ : `Detected ${foundPhrases.length} authoritarian phrase(s) that may shut down dissent`;
61
+ return {
62
+ detected: foundPhrases.length > 0,
63
+ phrases: foundPhrases,
64
+ severity,
65
+ message
66
+ };
67
+ };
68
+ // ============================================================================
69
+ // Claim Extraction
70
+ // ============================================================================
71
+ /**
72
+ * Extract testable claims from text
73
+ *
74
+ * Claims are statements that can be verified or challenged:
75
+ * - Factual assertions
76
+ * - Predictions
77
+ * - Causal relationships
78
+ * - Generalizations
79
+ */
80
+ export const extractClaims = (config) => {
81
+ const sentences = config.text.split(/[.!?]+/)
82
+ .map(s => s.trim())
83
+ .filter(s => s.length > 10);
84
+ const claims = [];
85
+ for (const sentence of sentences) {
86
+ const testable = isTestable(sentence);
87
+ const priority = calculateClaimPriority(sentence);
88
+ if (testable && (priority > 0.3 || config.thoroughness === 'deep')) {
89
+ claims.push({
90
+ claim: sentence,
91
+ context: extractContext(sentence, config.text),
92
+ testable,
93
+ priority
94
+ });
95
+ }
96
+ }
97
+ return claims;
98
+ };
99
+ /**
100
+ * Prioritize claims for fact-checking
101
+ *
102
+ * Returns top N claims by priority score
103
+ */
104
+ export const prioritizeClaims = (config) => {
105
+ return [...config.claims]
106
+ .sort((a, b) => b.priority - a.priority)
107
+ .slice(0, config.max_claims);
108
+ };
109
+ // ============================================================================
110
+ // Opposite Thinking
111
+ // ============================================================================
112
+ /**
113
+ * Explore "what if we're backwards?" perspective
114
+ *
115
+ * For each claim, explore the opposite view and assess plausibility
116
+ */
117
+ export const exploreOppositeThinking = (config) => {
118
+ return config.claims.map(claim => {
119
+ const oppositeView = generateOppositeView(claim.claim);
120
+ const evidence = extractRelevantEvidence(claim.claim, config.counter_evidence || '');
121
+ const plausibility = assessOppositeViewPlausibility(claim.claim, oppositeView, config.fact_check || '', config.counter_evidence || '');
122
+ return {
123
+ original_claim: claim.claim,
124
+ opposite_view: oppositeView,
125
+ plausibility,
126
+ evidence,
127
+ source: 'research'
128
+ };
129
+ });
130
+ };
131
+ /**
132
+ * Find "third way" alternatives beyond binary thinking
133
+ *
134
+ * When everyone sees only A vs B, find option C, D, E
135
+ */
136
+ export const findThirdWay = (config) => {
137
+ const binaryClaims = config.claims.filter(claim => isBinaryChoice(claim.claim));
138
+ return binaryClaims.map(claim => {
139
+ const alternatives = generateThirdWayAlternatives(claim.claim, config.fact_check || '', config.counter_evidence || '');
140
+ const confidence = calculateAlternativeConfidence(alternatives, config.fact_check || '', config.counter_evidence || '');
141
+ return {
142
+ original_claim: claim.claim,
143
+ alternatives,
144
+ confidence,
145
+ source: 'research'
146
+ };
147
+ });
148
+ };
149
+ // ============================================================================
150
+ // Synthesis
151
+ // ============================================================================
152
+ /**
153
+ * Synthesize all challenges into coherent report
154
+ */
155
+ export const synthesizeChallengerReport = (config) => {
156
+ let synthesis = `## 🎯 Devil's Advocate Analysis\n\n`;
157
+ // Tone Analysis Section
158
+ synthesis += `### 📢 Tone Analysis\n\n`;
159
+ synthesis += `**Status:** ${config.tone_analysis.detected ? '⚠️ Uncontested Tone Detected' : '✅ Healthy Debate Room'}\n`;
160
+ synthesis += `**Severity:** ${config.tone_analysis.severity.toUpperCase()}\n`;
161
+ synthesis += `**Message:** ${config.tone_analysis.message}\n\n`;
162
+ if (config.tone_analysis.phrases.length > 0) {
163
+ synthesis += `**Authoritarian phrases found:**\n`;
164
+ config.tone_analysis.phrases.forEach(phrase => {
165
+ synthesis += `- "${phrase}"\n`;
166
+ });
167
+ synthesis += `\n`;
168
+ }
169
+ // Claims Analysis
170
+ synthesis += `### 🔍 Claims Analyzed: ${config.claims.length}\n\n`;
171
+ if (config.claims.length > 0) {
172
+ synthesis += buildClaimsTable(config.claims.slice(0, 5));
173
+ synthesis += `\n`;
174
+ }
175
+ // Fact-Check Results
176
+ if (config.fact_check) {
177
+ synthesis += `### ✓ Fact-Check Results\n\n`;
178
+ synthesis += formatFactCheckResults(config.fact_check);
179
+ synthesis += `\n`;
180
+ }
181
+ // Counter-Evidence
182
+ if (config.counter_evidence) {
183
+ synthesis += `### ⚡ Counter-Evidence\n\n`;
184
+ synthesis += formatCounterEvidence(config.counter_evidence);
185
+ synthesis += `\n`;
186
+ }
187
+ // Opposite Views
188
+ if (config.opposite_views && config.opposite_views.length > 0) {
189
+ synthesis += `### 🔄 Opposite Thinking ("What if we're backwards?")\n\n`;
190
+ config.opposite_views.forEach(view => {
191
+ synthesis += `**Original:** ${view.original_claim}\n`;
192
+ synthesis += `**Opposite:** ${view.opposite_view}\n`;
193
+ synthesis += `**Plausibility:** ${(view.plausibility * 100).toFixed(0)}%\n\n`;
194
+ });
195
+ }
196
+ // Third-Way Alternatives
197
+ if (config.third_way && config.third_way.length > 0) {
198
+ synthesis += `### 🌟 Third-Way Alternatives (Beyond Binary Thinking)\n\n`;
199
+ config.third_way.forEach(alt => {
200
+ synthesis += `**Original:** ${alt.original_claim}\n`;
201
+ synthesis += `**Alternatives:**\n`;
202
+ alt.alternatives.forEach(a => synthesis += `- ${a}\n`);
203
+ synthesis += `**Confidence:** ${(alt.confidence * 100).toFixed(0)}%\n\n`;
204
+ });
205
+ }
206
+ // Summary
207
+ synthesis += `### 📋 Summary\n\n`;
208
+ synthesis += `\`\`\`\n`;
209
+ synthesis += `Thoroughness: ${config.thoroughness}\n`;
210
+ synthesis += `Claims Analyzed: ${config.claims.length}\n`;
211
+ synthesis += `Tone Detected: ${config.tone_analysis.detected ? 'YES ⚠️' : 'NO ✅'}\n`;
212
+ synthesis += `Fact-Checked: ${config.fact_check ? 'YES ✓' : 'NO'}\n`;
213
+ synthesis += `Counter-Evidence: ${config.counter_evidence ? 'YES ✓' : 'NO'}\n`;
214
+ synthesis += `Opposite Views: ${config.opposite_views?.length || 0}\n`;
215
+ synthesis += `Third-Way Options: ${config.third_way?.length || 0}\n`;
216
+ synthesis += `\`\`\`\n`;
217
+ return synthesis;
218
+ };
219
+ /**
220
+ * Calculate overall challenge score (strength of counter-arguments)
221
+ *
222
+ * Score based on:
223
+ * - Fact-check contradictions (40%)
224
+ * - Counter-evidence strength (30%)
225
+ * - Opposite view plausibility (15%)
226
+ * - Third-way alternatives (15%)
227
+ */
228
+ export const calculateChallengeScore = (config) => {
229
+ let score = 0;
230
+ // Fact-check contradictions (40%)
231
+ if (config.fact_check) {
232
+ const contradictions = (config.fact_check.match(/refuted|false|incorrect/gi) || []).length;
233
+ score += Math.min(contradictions * 0.1, 0.4);
234
+ }
235
+ // Counter-evidence strength (30%)
236
+ if (config.counter_evidence) {
237
+ const counterArgs = (config.counter_evidence.match(/however|but|alternative|dissent/gi) || []).length;
238
+ score += Math.min(counterArgs * 0.05, 0.3);
239
+ }
240
+ // Opposite view plausibility (15%)
241
+ if (config.opposite_views && config.opposite_views.length > 0) {
242
+ const avgPlausibility = config.opposite_views.reduce((sum, v) => sum + v.plausibility, 0) / config.opposite_views.length;
243
+ score += avgPlausibility * 0.15;
244
+ }
245
+ // Third-way alternatives (15%)
246
+ if (config.third_way && config.third_way.length > 0) {
247
+ const avgConfidence = config.third_way.reduce((sum, t) => sum + t.confidence, 0) / config.third_way.length;
248
+ score += avgConfidence * 0.15;
249
+ }
250
+ return Math.min(score, 1.0);
251
+ };
252
+ /**
253
+ * Format final challenger result
254
+ */
255
+ export const formatChallengerResult = (config) => {
256
+ return {
257
+ synthesis: config.synthesis,
258
+ tone_analysis: config.tone_analysis,
259
+ claims_analyzed: config.claims_analyzed,
260
+ challenge_score: config.challenge_score,
261
+ fact_check_results: config.fact_check_results ? parseFactCheckResults(config.fact_check_results) : undefined,
262
+ counter_evidence_results: config.counter_evidence_results ? parseCounterEvidenceResults(config.counter_evidence_results) : undefined,
263
+ opposite_views: config.opposite_views || undefined,
264
+ third_way_alternatives: config.third_way_alternatives || undefined
265
+ };
266
+ };
267
+ // ============================================================================
268
+ // Internal Utilities
269
+ // ============================================================================
270
+ /**
271
+ * Check if sentence is testable (can be verified or challenged)
272
+ */
273
+ const isTestable = (sentence) => {
274
+ const testableIndicators = [
275
+ /\b(is|are|was|were|will|would|can|could|should|must)\b/i,
276
+ /\b(all|every|always|never|most|many|some|few)\b/i,
277
+ /\b(cause|result|lead|increase|decrease|improve|reduce)\b/i,
278
+ /\b(better|worse|faster|slower|more|less)\b/i
279
+ ];
280
+ return testableIndicators.some(pattern => pattern.test(sentence));
281
+ };
282
+ /**
283
+ * Calculate claim priority score (0-1)
284
+ *
285
+ * Higher priority for:
286
+ * - Causal claims ("X causes Y")
287
+ * - Generalizations ("all", "never", "always")
288
+ * - Comparative claims ("better than", "more effective")
289
+ * - Predictions ("will", "going to")
290
+ */
291
+ const calculateClaimPriority = (sentence) => {
292
+ let priority = 0;
293
+ // Causal language (+0.4)
294
+ if (/\b(cause|result|lead|due to|because of)\b/i.test(sentence)) {
295
+ priority += 0.4;
296
+ }
297
+ // Generalizations (+0.3)
298
+ if (/\b(all|every|always|never|none)\b/i.test(sentence)) {
299
+ priority += 0.3;
300
+ }
301
+ // Comparatives (+0.2)
302
+ if (/\b(better|worse|more|less|faster|slower|superior|inferior)\b/i.test(sentence)) {
303
+ priority += 0.2;
304
+ }
305
+ // Predictions (+0.2)
306
+ if (/\b(will|going to|predict|forecast|expect)\b/i.test(sentence)) {
307
+ priority += 0.2;
308
+ }
309
+ return Math.min(priority, 1.0);
310
+ };
311
+ /**
312
+ * Extract context around a claim
313
+ */
314
+ const extractContext = (claim, fullText) => {
315
+ const index = fullText.indexOf(claim);
316
+ if (index === -1)
317
+ return claim;
318
+ const start = Math.max(0, index - 100);
319
+ const end = Math.min(fullText.length, index + claim.length + 100);
320
+ return fullText.substring(start, end);
321
+ };
322
+ /**
323
+ * Generate opposite view for a claim
324
+ */
325
+ const generateOppositeView = (claim) => {
326
+ // Simple negation (in real implementation, this would be more sophisticated)
327
+ if (claim.toLowerCase().includes('should')) {
328
+ return claim.replace(/should/i, 'should not');
329
+ }
330
+ if (claim.toLowerCase().includes('must')) {
331
+ return claim.replace(/must/i, 'must not');
332
+ }
333
+ if (claim.toLowerCase().includes('always')) {
334
+ return claim.replace(/always/i, 'never');
335
+ }
336
+ if (claim.toLowerCase().includes('never')) {
337
+ return claim.replace(/never/i, 'always');
338
+ }
339
+ return `The opposite view: ${claim} may not be true`;
340
+ };
341
+ /**
342
+ * Extract relevant evidence from counter-evidence text
343
+ */
344
+ const extractRelevantEvidence = (claim, counterEvidence) => {
345
+ if (!counterEvidence)
346
+ return [];
347
+ const keywords = claim.toLowerCase().split(/\s+/).filter(w => w.length > 3);
348
+ const sentences = counterEvidence.split(/[.!?]+/);
349
+ const relevant = sentences.filter(sentence => keywords.some(keyword => sentence.toLowerCase().includes(keyword)));
350
+ return relevant.slice(0, 3);
351
+ };
352
+ /**
353
+ * Assess plausibility of opposite view
354
+ */
355
+ const assessOppositeViewPlausibility = (claim, oppositeView, factCheck, counterEvidence) => {
356
+ let plausibility = 0.3; // Base plausibility
357
+ // Check if counter-evidence supports opposite view
358
+ const keywords = oppositeView.toLowerCase().split(/\s+/).filter(w => w.length > 3);
359
+ const matches = keywords.filter(keyword => counterEvidence.toLowerCase().includes(keyword)).length;
360
+ plausibility += Math.min(matches * 0.1, 0.4);
361
+ // Check fact-check contradictions
362
+ if (factCheck.toLowerCase().includes('refuted') || factCheck.toLowerCase().includes('false')) {
363
+ plausibility += 0.3;
364
+ }
365
+ return Math.min(plausibility, 1.0);
366
+ };
367
+ /**
368
+ * Check if claim represents binary choice
369
+ */
370
+ const isBinaryChoice = (claim) => {
371
+ return /\b(or|versus|vs|either|choice|alternative)\b/i.test(claim);
372
+ };
373
+ /**
374
+ * Generate third-way alternatives
375
+ */
376
+ const generateThirdWayAlternatives = (claim, factCheck, counterEvidence) => {
377
+ const alternatives = [];
378
+ // Extract alternative approaches from evidence
379
+ const altPattern = /alternative|another way|instead|different approach/gi;
380
+ const sentences = (factCheck + ' ' + counterEvidence).split(/[.!?]+/);
381
+ sentences.forEach(sentence => {
382
+ if (altPattern.test(sentence) && sentence.length > 20) {
383
+ alternatives.push(sentence.trim());
384
+ }
385
+ });
386
+ // Add synthetic alternatives if needed
387
+ if (alternatives.length === 0) {
388
+ alternatives.push(`Hybrid approach combining elements of both perspectives`);
389
+ alternatives.push(`Context-dependent solution varying by situation`);
390
+ alternatives.push(`Gradual transition rather than binary switch`);
391
+ }
392
+ return alternatives.slice(0, 5);
393
+ };
394
+ /**
395
+ * Calculate confidence in alternatives
396
+ */
397
+ const calculateAlternativeConfidence = (alternatives, factCheck, counterEvidence) => {
398
+ // Higher confidence if alternatives are derived from evidence
399
+ const evidenceBased = alternatives.filter(alt => factCheck.includes(alt.substring(0, 20)) || counterEvidence.includes(alt.substring(0, 20))).length;
400
+ return Math.min(0.5 + (evidenceBased * 0.15), 0.95);
401
+ };
402
+ /**
403
+ * Build claims table
404
+ */
405
+ const buildClaimsTable = (claims) => {
406
+ let table = '| Priority | Claim | Testable |\n';
407
+ table += '|---------:|:------|:--------:|\n';
408
+ claims.forEach(claim => {
409
+ const priority = (claim.priority * 100).toFixed(0) + '%';
410
+ const claimText = claim.claim.length > 80 ? claim.claim.substring(0, 77) + '...' : claim.claim;
411
+ const testable = claim.testable ? '✓' : '✗';
412
+ table += `| ${priority} | ${claimText} | ${testable} |\n`;
413
+ });
414
+ return table;
415
+ };
416
+ /**
417
+ * Format fact-check results
418
+ */
419
+ const formatFactCheckResults = (factCheck) => {
420
+ return factCheck.substring(0, 500) + (factCheck.length > 500 ? '...' : '');
421
+ };
422
+ /**
423
+ * Format counter-evidence
424
+ */
425
+ const formatCounterEvidence = (counterEvidence) => {
426
+ return counterEvidence.substring(0, 500) + (counterEvidence.length > 500 ? '...' : '');
427
+ };
428
+ /**
429
+ * Parse fact-check results into structured format
430
+ */
431
+ const parseFactCheckResults = (factCheck) => {
432
+ // Simplified parsing (real implementation would be more sophisticated)
433
+ return [{
434
+ claim: 'Sample claim',
435
+ status: 'uncertain',
436
+ supporting_evidence: [],
437
+ contradicting_evidence: [],
438
+ sources: [],
439
+ reliability: 0.5
440
+ }];
441
+ };
442
+ /**
443
+ * Parse counter-evidence into structured format
444
+ */
445
+ const parseCounterEvidenceResults = (counterEvidence) => {
446
+ // Simplified parsing
447
+ return [{
448
+ claim: 'Sample claim',
449
+ counter_arguments: [],
450
+ dissenting_experts: [],
451
+ alternative_interpretations: [],
452
+ edge_cases: []
453
+ }];
454
+ };
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Shared Helper Functions for System Workflows
3
+ *
4
+ * This module exports pure, composable helper functions used by
5
+ * system workflows (scout, verifier, challenger).
6
+ *
7
+ * SOLID Principles Applied:
8
+ * - Single Responsibility: Each helper module focuses on one mode
9
+ * - Open/Closed: Helpers are closed for modification, open for extension
10
+ * - Dependency Inversion: Workflows depend on these abstractions
11
+ */
12
+ // Scout helpers
13
+ export * from './scout-helpers.js';
14
+ // Verifier helpers
15
+ export * from './verifier-helpers.js';
16
+ // Challenger helpers
17
+ export * from './challenger-helpers.js';