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,130 @@
1
+ /**
2
+ * Centralized Timeout Configuration
3
+ *
4
+ * Provides configurable timeouts for all MCP operations to prevent premature
5
+ * termination of long-running AI operations.
6
+ *
7
+ * See docs/ADR-002-timeout-configuration.md for rationale.
8
+ */
9
+ /**
10
+ * Get timeout configuration from environment variables with fallbacks
11
+ */
12
+ export function getTimeoutConfig() {
13
+ return {
14
+ // Global default (90 seconds)
15
+ default: parseInt(process.env.TACHI_DEFAULT_TIMEOUT || '90000'),
16
+ // Per-tool timeouts
17
+ verifier: parseInt(process.env.TACHI_VERIFIER_TIMEOUT || '120000'), // 2 minutes
18
+ challenger: parseInt(process.env.TACHI_CHALLENGER_TIMEOUT || '180000'), // 3 minutes
19
+ scout: parseInt(process.env.TACHI_SCOUT_TIMEOUT || '180000'), // 3 minutes
20
+ focus: parseInt(process.env.TACHI_FOCUS_TIMEOUT || '300000'), // 5 minutes
21
+ workflow: parseInt(process.env.TACHI_WORKFLOW_TIMEOUT || '300000'), // 5 minutes
22
+ pingpong: parseInt(process.env.TACHI_PINGPONG_TIMEOUT || '600000'), // 10 minutes
23
+ // Individual API call timeout (60 seconds)
24
+ api: parseInt(process.env.TACHI_API_TIMEOUT || '60000'),
25
+ // Progress threshold (30 seconds)
26
+ progressThreshold: parseInt(process.env.TACHI_PROGRESS_THRESHOLD || '30000'),
27
+ };
28
+ }
29
+ /**
30
+ * Get timeout for specific tool with fallback to default
31
+ */
32
+ export function getToolTimeout(toolName) {
33
+ const config = getTimeoutConfig();
34
+ const toolKey = toolName.toLowerCase();
35
+ return config[toolKey] || config.default;
36
+ }
37
+ /**
38
+ * Format timeout duration for display
39
+ */
40
+ export function formatTimeout(ms) {
41
+ const seconds = Math.floor(ms / 1000);
42
+ if (seconds < 60) {
43
+ return `${seconds}s`;
44
+ }
45
+ const minutes = Math.floor(seconds / 60);
46
+ const remainingSeconds = seconds % 60;
47
+ if (remainingSeconds === 0) {
48
+ return `${minutes}m`;
49
+ }
50
+ return `${minutes}m ${remainingSeconds}s`;
51
+ }
52
+ /**
53
+ * Create timeout promise for use with Promise.race()
54
+ */
55
+ export function createTimeoutPromise(ms, message) {
56
+ return new Promise((_, reject) => {
57
+ setTimeout(() => {
58
+ reject(new Error(message || `Operation timed out after ${formatTimeout(ms)}`));
59
+ }, ms);
60
+ });
61
+ }
62
+ /**
63
+ * Wrap promise with timeout
64
+ */
65
+ export async function withTimeout(promise, timeoutMs, toolName) {
66
+ const timeoutMessage = toolName
67
+ ? `${toolName} operation timed out after ${formatTimeout(timeoutMs)}`
68
+ : `Operation timed out after ${formatTimeout(timeoutMs)}`;
69
+ return Promise.race([
70
+ promise,
71
+ createTimeoutPromise(timeoutMs, timeoutMessage)
72
+ ]);
73
+ }
74
+ /**
75
+ * Check if we should show progress (operation exceeds threshold)
76
+ */
77
+ export function shouldShowProgress(elapsedMs) {
78
+ const config = getTimeoutConfig();
79
+ return elapsedMs >= config.progressThreshold;
80
+ }
81
+ export const SMART_TIMEOUT_DEFAULTS = {
82
+ interactive: {
83
+ base: 15000, // 15 seconds
84
+ max: 45000, // 45 seconds
85
+ retries: 3
86
+ },
87
+ batch: {
88
+ base: 30000, // 30 seconds
89
+ max: 120000, // 2 minutes
90
+ retries: 5
91
+ },
92
+ providers: {
93
+ perplexity: {
94
+ base: 30000, // 30 seconds - Perplexity can be slow
95
+ max: 90000 // 90 seconds
96
+ },
97
+ grok: {
98
+ base: 30000, // 30 seconds
99
+ max: 90000 // 90 seconds
100
+ },
101
+ openai: {
102
+ base: 20000, // 20 seconds
103
+ max: 60000 // 60 seconds
104
+ },
105
+ anthropic: {
106
+ base: 20000, // 20 seconds
107
+ max: 60000 // 60 seconds
108
+ },
109
+ google: {
110
+ base: 15000, // 15 seconds
111
+ max: 45000 // 45 seconds
112
+ }
113
+ }
114
+ };
115
+ /**
116
+ * Get smart timeout for specific provider and priority
117
+ */
118
+ export function getSmartTimeout(provider, priority) {
119
+ const providerConfig = SMART_TIMEOUT_DEFAULTS.providers[provider];
120
+ const priorityConfig = SMART_TIMEOUT_DEFAULTS[priority];
121
+ return {
122
+ base: providerConfig?.base || priorityConfig.base,
123
+ max: providerConfig?.max || priorityConfig.max,
124
+ retries: priorityConfig.retries
125
+ };
126
+ }
127
+ // Export singleton instance
128
+ export const timeouts = getTimeoutConfig();
129
+ // Re-export for convenience
130
+ export { getTimeoutConfig as default };
@@ -0,0 +1,173 @@
1
+ import { config } from 'dotenv';
2
+ import { TechnicalDomain } from './reasoning-chain.js';
3
+ import * as path from 'path';
4
+ import { fileURLToPath } from 'url';
5
+ // Get the directory of the current module
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = path.dirname(__filename);
8
+ // Load environment variables from the correct path (project root)
9
+ // When built: dist/src/config.js -> need to go up 2 levels to reach .env
10
+ config({ path: path.resolve(__dirname, '../../.env') });
11
+ /**
12
+ * Detect if running in Claude Code environment
13
+ */
14
+ function detectClaudeCode() {
15
+ return !!(process.env.CLAUDE_CODE_SESSION ||
16
+ process.env.ANTHROPIC_SESSION_ID ||
17
+ process.env.CLAUDE_CODE_ACTIVE ||
18
+ process.env.CLAUDE_PROJECT_ROOT ||
19
+ process.env.CLAUDE_WORKSPACE ||
20
+ // Check if we're in Claude Code by looking for specific patterns
21
+ (process.env.USER?.includes('claude') && process.env.HOME?.includes('claude')));
22
+ }
23
+ /**
24
+ * Detect active Claude model
25
+ */
26
+ function detectClaudeModel() {
27
+ const model = process.env.CLAUDE_MODEL ||
28
+ process.env.ANTHROPIC_MODEL ||
29
+ process.env.CLAUDE_CODE_MODEL;
30
+ if (model) {
31
+ if (model.includes('opus'))
32
+ return 'opus-4.1';
33
+ if (model.includes('sonnet'))
34
+ return 'sonnet-4';
35
+ }
36
+ return undefined;
37
+ }
38
+ /**
39
+ * Parse technical domain from string
40
+ */
41
+ function parseDomain(domain) {
42
+ if (!domain)
43
+ return undefined;
44
+ const domainMap = {
45
+ 'architecture': TechnicalDomain.ARCHITECTURE,
46
+ 'algorithms': TechnicalDomain.ALGORITHMS,
47
+ 'debugging': TechnicalDomain.DEBUGGING,
48
+ 'security': TechnicalDomain.SECURITY,
49
+ 'performance': TechnicalDomain.PERFORMANCE,
50
+ 'api_design': TechnicalDomain.API_DESIGN,
51
+ 'database': TechnicalDomain.DATABASE,
52
+ 'frontend': TechnicalDomain.FRONTEND,
53
+ 'backend': TechnicalDomain.BACKEND,
54
+ 'devops': TechnicalDomain.DEVOPS,
55
+ 'testing': TechnicalDomain.TESTING
56
+ };
57
+ return domainMap[domain.toLowerCase()];
58
+ }
59
+ /**
60
+ * Load configuration from environment
61
+ */
62
+ export function loadConfig() {
63
+ const isClaudeCode = detectClaudeCode();
64
+ const claudeModel = detectClaudeModel();
65
+ return {
66
+ isClaudeCode,
67
+ claudeModel,
68
+ apiKeys: {
69
+ anthropic: process.env.ANTHROPIC_API_KEY,
70
+ openai: process.env.OPENAI_API_KEY,
71
+ openrouter: process.env.OPENROUTER_API_KEY,
72
+ gemini: process.env.GOOGLE_API_KEY,
73
+ deepseek: process.env.DEEPSEEK_API_KEY,
74
+ perplexity: process.env.PERPLEXITY_API_KEY,
75
+ grok: process.env.GROK_API_KEY,
76
+ qwen: process.env.QWEN_API_KEY,
77
+ },
78
+ preferences: {
79
+ defaultDomain: parseDomain(process.env.DEFAULT_DOMAIN),
80
+ enableVisuals: process.env.ENABLE_VISUALS !== 'false',
81
+ costOptimization: process.env.COST_OPTIMIZATION !== 'false',
82
+ maxReasoningRounds: parseInt(process.env.MAX_REASONING_ROUNDS || '5', 10),
83
+ maxPingPongRounds: parseInt(process.env.MAX_PINGPONG_ROUNDS || '24', 10), // Default 24 (divisible by 6 models), users can increase if needed
84
+ debug: process.env.DEBUG === 'true'
85
+ },
86
+ session: {
87
+ enableLogging: process.env.ENABLE_SESSION_LOGGING !== 'false',
88
+ autoSave: process.env.SESSION_AUTO_SAVE === 'true',
89
+ defaultVerbose: process.env.SESSION_DEFAULT_VERBOSE === 'true',
90
+ sessionDir: process.env.SESSION_OUTPUT_DIR || './workflow-output/sessions',
91
+ outputFormat: process.env.SESSION_DEFAULT_FORMAT || 'markdown',
92
+ includeMetadata: process.env.SESSION_INCLUDE_METADATA !== 'false',
93
+ maxHistory: parseInt(process.env.SESSION_MAX_HISTORY || '100', 10)
94
+ },
95
+ workflow: {
96
+ outputDir: process.env.WORKFLOW_OUTPUT_DIR || './workflow-output'
97
+ }
98
+ };
99
+ }
100
+ /**
101
+ * Get available models based on configuration
102
+ */
103
+ export function getAvailableModels(config) {
104
+ const models = [];
105
+ // Claude Code mode - always available
106
+ if (config.isClaudeCode && config.claudeModel) {
107
+ models.push(`claude-code-${config.claudeModel}`);
108
+ }
109
+ // API-based models
110
+ if (config.apiKeys.anthropic) {
111
+ models.push('claude-sonnet-4-api', 'claude-opus-4.1-api');
112
+ }
113
+ if (config.apiKeys.openai) {
114
+ // GPT-5 models (require ENABLE_GPT5=true flag)
115
+ if (process.env.ENABLE_GPT5 === 'true') {
116
+ models.push('gpt-5', 'gpt-5-mini', 'gpt-5-nano');
117
+ }
118
+ }
119
+ if (config.apiKeys.gemini) {
120
+ // Use Gemini 2.5 (latest and best)
121
+ models.push('gemini-2.5-flash', 'gemini-2.5-pro', 'gemini-2.5-flash-lite');
122
+ }
123
+ if (config.apiKeys.deepseek) {
124
+ models.push('deepseek-r1');
125
+ }
126
+ if (config.apiKeys.perplexity) {
127
+ models.push('sonar-pro', 'sonar-reasoning-pro', 'sonar-deep-research');
128
+ }
129
+ if (config.apiKeys.grok) {
130
+ models.push('grok-3', 'grok-3-fast', 'grok-4-0709');
131
+ }
132
+ if (config.apiKeys.openrouter) {
133
+ models.push('qwen3-coder', 'qwq-32b', 'qwen3-32b');
134
+ }
135
+ if (config.apiKeys.qwen) {
136
+ models.push('qwen-max');
137
+ }
138
+ return models;
139
+ }
140
+ /**
141
+ * Get configuration status for debugging
142
+ */
143
+ export function getConfigStatus(config) {
144
+ const models = getAvailableModels(config);
145
+ let status = `🔧 Focus MCP Configuration\n\n`;
146
+ status += `**Mode**: ${config.isClaudeCode ? 'Claude Code' : 'Standalone'}\n`;
147
+ if (config.isClaudeCode) {
148
+ status += `**Active Model**: ${config.claudeModel || 'Not detected'}\n`;
149
+ }
150
+ status += `\n**Available Models** (${models.length}):\n`;
151
+ models.forEach(model => {
152
+ status += ` • ${model}\n`;
153
+ });
154
+ status += `\n**Preferences**:\n`;
155
+ status += ` • Default Domain: ${config.preferences.defaultDomain || 'None set'}\n`;
156
+ status += ` • Visuals: ${config.preferences.enableVisuals ? 'Enabled' : 'Disabled'}\n`;
157
+ status += ` • Cost Optimization: ${config.preferences.costOptimization ? 'Enabled' : 'Disabled'}\n`;
158
+ status += ` • Max Reasoning Rounds: ${config.preferences.maxReasoningRounds}\n`;
159
+ status += ` • Max Ping-Pong Rounds: ${config.preferences.maxPingPongRounds} (configurable via MAX_PINGPONG_ROUNDS)\n`;
160
+ status += ` • Debug Mode: ${config.preferences.debug ? 'On' : 'Off'}\n`;
161
+ status += `\n**Session Configuration**:\n`;
162
+ status += ` • Logging: ${config.session.enableLogging ? 'Enabled' : 'Disabled'}\n`;
163
+ status += ` • Auto-save: ${config.session.autoSave ? 'On' : 'Off'}\n`;
164
+ status += ` • Verbose by default: ${config.session.defaultVerbose ? 'Yes' : 'No'}\n`;
165
+ status += ` • Session Directory: ${config.session.sessionDir}\n`;
166
+ status += ` • Output Format: ${config.session.outputFormat}\n`;
167
+ status += ` • Include Metadata: ${config.session.includeMetadata ? 'Yes' : 'No'}\n`;
168
+ status += ` • Max History: ${config.session.maxHistory} sessions\n`;
169
+ if (!config.isClaudeCode && models.length === 0) {
170
+ status += `\n⚠️ **Warning**: No API keys configured. Add keys to .env file for full functionality.\n`;
171
+ }
172
+ return status;
173
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * IFocusMode Interface - Strategy pattern for Focus tool modes
3
+ * Follows Open/Closed Principle (SOLID) - extend via new implementations
4
+ */
5
+ export {};
@@ -0,0 +1,6 @@
1
+ /**
2
+ * IProvider Interface - Abstraction for AI providers
3
+ * Follows Dependency Inversion Principle (SOLID)
4
+ * Allows swapping providers without changing dependent code
5
+ */
6
+ export {};
@@ -0,0 +1,5 @@
1
+ /**
2
+ * ITool Interface - Base abstraction for all MCP tools
3
+ * Follows Interface Segregation Principle (SOLID)
4
+ */
5
+ export {};
@@ -0,0 +1,245 @@
1
+ /**
2
+ * Focus-Deep - Ultimate reasoning combining Sequential Thinking + Multi-Model Orchestration
3
+ * The most powerful reasoning mode in tachibot-mcp
4
+ */
5
+ import { sequentialThinking } from "./sequential-thinking.js";
6
+ import { isGeminiAvailable } from "./tools/gemini-tools.js";
7
+ import { isPerplexityAvailable } from "./tools/perplexity-tools.js";
8
+ import { loadConfig } from "./config.js";
9
+ /**
10
+ * Create a Focus-Deep plan based on available models
11
+ */
12
+ export function createFocusDeepPlan(objective, domain) {
13
+ const config = loadConfig();
14
+ const availableModels = [];
15
+ const steps = [];
16
+ // Check what's available
17
+ if (config.isClaudeCode) {
18
+ availableModels.push(`claude-${config.claudeModel}`);
19
+ }
20
+ if (isGeminiAvailable()) {
21
+ availableModels.push("gemini");
22
+ }
23
+ if (isPerplexityAvailable()) {
24
+ availableModels.push("perplexity");
25
+ }
26
+ // Always have think tool
27
+ availableModels.push("think");
28
+ // Create optimal plan based on available models
29
+ if (availableModels.length >= 4) {
30
+ // Full multi-model Focus-Deep
31
+ steps.push({
32
+ model: availableModels.includes("gemini") ? "gemini" : availableModels[0],
33
+ action: "brainstorm",
34
+ prompt: "Generate innovative approaches and identify key challenges",
35
+ reasoning: "Starting with creative exploration to map the solution space"
36
+ });
37
+ steps.push({
38
+ model: availableModels.includes("claude") ? availableModels[0] : "think",
39
+ action: "analyze",
40
+ prompt: "Critically analyze the proposed approaches, identify gaps",
41
+ reasoning: "Claude excels at systematic analysis and finding edge cases"
42
+ });
43
+ steps.push({
44
+ model: availableModels.includes("perplexity") ? "perplexity" : "think",
45
+ action: "research",
46
+ prompt: "Research evidence, best practices, and similar implementations",
47
+ reasoning: "Grounding our solution in real-world evidence"
48
+ });
49
+ steps.push({
50
+ model: availableModels[0],
51
+ action: "refine",
52
+ prompt: "Refine the approach based on research findings",
53
+ reasoning: "Incorporating evidence to improve the solution"
54
+ });
55
+ steps.push({
56
+ model: "think",
57
+ action: "synthesize",
58
+ prompt: "Synthesize all insights into a final, actionable solution",
59
+ reasoning: "Using think tool for cost-effective synthesis"
60
+ });
61
+ }
62
+ else if (availableModels.length >= 2) {
63
+ // Limited model Focus-Deep
64
+ steps.push({
65
+ model: availableModels[0],
66
+ action: "explore",
67
+ prompt: "Explore the problem space and generate initial solutions",
68
+ reasoning: "Initial exploration with primary model"
69
+ });
70
+ steps.push({
71
+ model: availableModels[1] !== "think" ? availableModels[1] : availableModels[0],
72
+ action: "critique",
73
+ prompt: "Critique and improve the initial solutions",
74
+ reasoning: "Getting a second perspective or self-critique"
75
+ });
76
+ steps.push({
77
+ model: availableModels[0],
78
+ action: "refine",
79
+ prompt: "Refine based on critique and develop final approach",
80
+ reasoning: "Iterative improvement"
81
+ });
82
+ steps.push({
83
+ model: "think",
84
+ action: "synthesize",
85
+ prompt: "Synthesize the final solution",
86
+ reasoning: "Final synthesis"
87
+ });
88
+ }
89
+ else {
90
+ // Single model Focus-Deep (Claude Code only)
91
+ steps.push({
92
+ model: availableModels[0],
93
+ action: "decompose",
94
+ prompt: "Break down the problem into components",
95
+ reasoning: "Problem decomposition"
96
+ });
97
+ steps.push({
98
+ model: availableModels[0],
99
+ action: "explore",
100
+ prompt: "Explore solutions for each component",
101
+ reasoning: "Solution exploration"
102
+ });
103
+ steps.push({
104
+ model: availableModels[0],
105
+ action: "integrate",
106
+ prompt: "Integrate component solutions",
107
+ reasoning: "Solution integration"
108
+ });
109
+ steps.push({
110
+ model: "think",
111
+ action: "finalize",
112
+ prompt: "Finalize and validate the solution",
113
+ reasoning: "Final validation"
114
+ });
115
+ }
116
+ // Start sequential thinking session
117
+ const sessionId = sequentialThinking.startSession(objective, steps.length);
118
+ return {
119
+ sessionId,
120
+ objective,
121
+ steps,
122
+ estimatedThoughts: steps.length,
123
+ availableModels
124
+ };
125
+ }
126
+ /**
127
+ * Generate Focus-Deep visualization
128
+ */
129
+ export function generateFocusDeepVisualization(plan) {
130
+ let viz = `# 🧠⚡ FOCUS-DEEP SESSION\n\n`;
131
+ viz += `**Objective**: ${plan.objective}\n`;
132
+ viz += `**Available Models**: ${plan.availableModels.join(", ")}\n`;
133
+ viz += `**Thoughts Planned**: ${plan.estimatedThoughts}\n\n`;
134
+ // ASCII art for Focus-Deep
135
+ viz += "```\n";
136
+ viz += "@@@@@@@@@@@@@@@@@@@@@\n";
137
+ viz += "@ ◉ ◉ @ 🧠⚡ ULTRATHINKING...\n";
138
+ viz += "@ ≈ @ Maximum reasoning power\n";
139
+ viz += "@ ========= @ Sequential + Multi-Model\n";
140
+ viz += "@@@@@@@@@@@@@@@@@@@@@\n";
141
+ viz += "```\n\n";
142
+ // Model flow diagram
143
+ viz += "## Reasoning Flow\n\n";
144
+ viz += "```\n";
145
+ plan.steps.forEach((step, idx) => {
146
+ const arrow = idx < plan.steps.length - 1 ? " ──► " : "";
147
+ viz += `[${step.model}:${step.action}]${arrow}`;
148
+ if ((idx + 1) % 3 === 0 && idx < plan.steps.length - 1) {
149
+ viz += "\n ⬇\n";
150
+ }
151
+ });
152
+ viz += "\n```\n\n";
153
+ // Detailed steps
154
+ viz += "## Execution Plan\n\n";
155
+ plan.steps.forEach((step, idx) => {
156
+ viz += `### Thought ${idx + 1}: ${step.action.toUpperCase()}\n`;
157
+ viz += `**Model**: ${step.model}\n`;
158
+ viz += `**Task**: ${step.prompt}\n`;
159
+ if (step.reasoning) {
160
+ viz += `**Reasoning**: ${step.reasoning}\n`;
161
+ }
162
+ viz += "\n";
163
+ });
164
+ // Instructions
165
+ viz += "## How Focus-Deep Works\n\n";
166
+ viz += "1. **Sequential Thinking**: Each thought builds on previous insights\n";
167
+ viz += "2. **Multi-Model Orchestration**: Different models handle different aspects\n";
168
+ viz += "3. **Dynamic Adaptation**: Can revise or branch based on discoveries\n";
169
+ viz += "4. **Synthesis**: Final thought combines all insights\n\n";
170
+ viz += "### Unique Features:\n";
171
+ viz += "- 🔄 **Revision**: Can go back and revise earlier thoughts\n";
172
+ viz += "- 🌿 **Branching**: Explore alternative reasoning paths\n";
173
+ viz += "- 🎯 **Focused**: Each model used for its strengths\n";
174
+ viz += "- 💰 **Efficient**: Think tool for synthesis (no API cost)\n\n";
175
+ viz += "**Note**: This is the most powerful reasoning mode in tachibot-mcp, ";
176
+ viz += "combining the best of sequential thinking and multi-model collaboration.\n";
177
+ return viz;
178
+ }
179
+ /**
180
+ * Execute a single Focus-Deep step
181
+ */
182
+ export async function executeFocusDeepStep(sessionId, stepIndex, plan, previousResponse) {
183
+ const step = plan.steps[stepIndex];
184
+ if (!step) {
185
+ throw new Error(`Invalid step index: ${stepIndex}`);
186
+ }
187
+ // Build context from previous responses
188
+ let context = `Objective: ${plan.objective}\n`;
189
+ if (previousResponse) {
190
+ context += `Previous insight: ${previousResponse.substring(0, 500)}...\n`;
191
+ }
192
+ context += `Current task: ${step.prompt}`;
193
+ // Map to actual tool based on model and action
194
+ let tool = "think"; // Default
195
+ let parameters = { thought: context };
196
+ if (step.model === "gemini" && step.action === "brainstorm") {
197
+ tool = "gemini_brainstorm";
198
+ parameters = {
199
+ prompt: plan.objective,
200
+ claudeThoughts: previousResponse
201
+ };
202
+ }
203
+ else if (step.model === "perplexity" && step.action === "research") {
204
+ tool = "perplexity_research";
205
+ parameters = {
206
+ topic: plan.objective,
207
+ depth: "standard"
208
+ };
209
+ }
210
+ else if (step.model.includes("claude")) {
211
+ // Use current Claude session
212
+ tool = "think";
213
+ parameters = { thought: `${step.action}: ${context}` };
214
+ }
215
+ return {
216
+ instruction: `Step ${stepIndex + 1}/${plan.steps.length}: ${step.action}`,
217
+ tool,
218
+ parameters
219
+ };
220
+ }
221
+ /**
222
+ * Check if Focus-Deep can run optimally
223
+ */
224
+ export function canRunFocusDeep() {
225
+ const config = loadConfig();
226
+ const models = [];
227
+ if (config.isClaudeCode) {
228
+ models.push("claude");
229
+ }
230
+ if (isGeminiAvailable()) {
231
+ models.push("gemini");
232
+ }
233
+ if (isPerplexityAvailable()) {
234
+ models.push("perplexity");
235
+ }
236
+ models.push("think"); // Always available
237
+ const quality = models.length >= 4 ? "optimal" :
238
+ models.length >= 3 ? "good" :
239
+ "basic";
240
+ return {
241
+ available: true, // Always available, just varies in quality
242
+ models,
243
+ quality
244
+ };
245
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Robot ASCII Art - Presentation Layer
3
+ * Extracted from server.ts (Phase 1 of SOLID refactoring)
4
+ */
5
+ export const ROBOT_ASCII = {
6
+ tachiBot: {
7
+ exploring: `@@@@@@@@@
8
+ @ ○ ○ @ 🤖🔍 TachiBot: Starting the hunt...
9
+ @ \\_/ @
10
+ @@@@@@@@@`,
11
+ discovery: `@@@@@@@@@
12
+ @ ★ ★ @ 🤖🧠 TachiBot: EUREKA MOMENT!
13
+ @ \\\\o// @
14
+ @@@@@@@@@`
15
+ }
16
+ };
@@ -0,0 +1,90 @@
1
+ // Note: MCP servers cannot directly call other MCP servers.
2
+ // This class generates instructions for the client (Claude) to execute tools.
3
+ export class MCPClient {
4
+ constructor() {
5
+ this.availableTools = new Set();
6
+ }
7
+ async connect() {
8
+ // In a real implementation, this would discover available tools
9
+ // For now, we'll assume these tools are available
10
+ this.availableTools = new Set([
11
+ 'mcp__gemini__gemini-brainstorm',
12
+ 'mcp__perplexity-ask__perplexity_research',
13
+ 'mcp__openai-mcp__openai_gpt5_reason',
14
+ 'mcp__openai-mcp__openai_brainstorm',
15
+ 'mcp__think-mcp-server__think',
16
+ 'mcp__devlog-search__search_devlogs',
17
+ 'mcp__devlog-core__devlog_session_log'
18
+ ]);
19
+ }
20
+ hasTools(tools) {
21
+ return tools.every(tool => this.availableTools.has(tool));
22
+ }
23
+ // Instead of executing directly, return structured instructions
24
+ async executeTool(toolName, parameters) {
25
+ if (!this.availableTools.has(toolName)) {
26
+ throw new Error(`Tool ${toolName} not available`);
27
+ }
28
+ // Return a placeholder that indicates the tool should be called
29
+ // In real usage, this would be replaced by actual tool execution by Claude
30
+ return `[EXECUTE_TOOL: ${toolName}]`;
31
+ }
32
+ // Generate instructions for Claude to execute tools
33
+ generateToolInstructions(toolName, parameters) {
34
+ // Map internal parameters to tool-specific parameters
35
+ const toolParams = this.mapParameters(toolName, parameters);
36
+ return {
37
+ tool: toolName,
38
+ parameters: toolParams,
39
+ description: this.getToolDescription(toolName)
40
+ };
41
+ }
42
+ mapParameters(toolName, params) {
43
+ // Map generic parameters to tool-specific ones
44
+ switch (toolName) {
45
+ case 'mcp__gemini__gemini-brainstorm':
46
+ return {
47
+ prompt: params.prompt || params.query,
48
+ claudeThoughts: params.context || 'Orchestrating brainstorm session'
49
+ };
50
+ case 'mcp__perplexity-ask__perplexity_research':
51
+ case 'mcp__perplexity-ask__perplexity_reason':
52
+ return {
53
+ messages: [{
54
+ role: 'user',
55
+ content: params.prompt || params.query
56
+ }]
57
+ };
58
+ case 'mcp__openai-mcp__openai_gpt5_reason':
59
+ return {
60
+ query: params.prompt || params.query,
61
+ context: params.context
62
+ };
63
+ case 'mcp__openai-mcp__openai_brainstorm':
64
+ return {
65
+ problem: params.prompt || params.query,
66
+ constraints: params.context
67
+ };
68
+ case 'mcp__think-mcp-server__think':
69
+ return {
70
+ thought: params.thought || params.prompt || params.query
71
+ };
72
+ default:
73
+ return params;
74
+ }
75
+ }
76
+ getToolDescription(toolName) {
77
+ const descriptions = {
78
+ 'mcp__gemini__gemini-brainstorm': 'Creative brainstorming with Gemini',
79
+ 'mcp__perplexity-ask__perplexity_research': 'Deep research with citations',
80
+ 'mcp__openai-mcp__openai_gpt5_reason': 'Mathematical/logical reasoning (GPT-5-mini)',
81
+ 'mcp__openai-mcp__openai_brainstorm': 'Alternative perspective generation',
82
+ 'mcp__think-mcp-server__think': 'Reflective thinking scratchpad'
83
+ };
84
+ return descriptions[toolName] || 'Execute tool';
85
+ }
86
+ // Generate a batch of tool instructions for a workflow
87
+ generateWorkflowInstructions(tools) {
88
+ return tools.map(({ name, prompt, context }) => this.generateToolInstructions(name, { prompt, context }));
89
+ }
90
+ }