tachibot-mcp 2.23.3 → 2.26.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 (62) hide show
  1. package/README.md +67 -59
  2. package/dist/src/cli/init.js +125 -0
  3. package/dist/src/config/timeout-config.js +18 -8
  4. package/dist/src/orchestrators/collaborative/services/visualization/VisualizationService.js +32 -59
  5. package/dist/src/profiles/balanced.js +13 -2
  6. package/dist/src/profiles/code_focus.js +13 -2
  7. package/dist/src/profiles/full.js +13 -2
  8. package/dist/src/profiles/heavy_coding.js +13 -2
  9. package/dist/src/profiles/minimal.js +13 -2
  10. package/dist/src/profiles/research_power.js +13 -2
  11. package/dist/src/server-main.js +760 -0
  12. package/dist/src/server.js +11 -753
  13. package/dist/src/tools/debug-triage-tool.js +59 -0
  14. package/dist/src/tools/diff-review-tool.js +120 -0
  15. package/dist/src/tools/doctor-tool.js +143 -0
  16. package/dist/src/tools/jury-tool.js +18 -11
  17. package/dist/src/tools/panel.js +24 -0
  18. package/dist/src/tools/plan-critique-tool.js +117 -0
  19. package/dist/src/tools/prompt-technique-tools.js +129 -34
  20. package/dist/src/tools/provider-catalog.js +148 -0
  21. package/dist/src/tools/refine-prompt-tool.js +57 -0
  22. package/dist/src/tools/registry.js +25 -0
  23. package/dist/src/tools/security-review-tool.js +71 -0
  24. package/dist/src/tools/spec-writer-tool.js +64 -0
  25. package/dist/src/tools/tachi-tool.js +71 -2
  26. package/dist/src/tools/testgen-tool.js +57 -0
  27. package/dist/src/utils/api-keys.js +4 -2
  28. package/dist/src/utils/smart-api-client.js +13 -4
  29. package/dist/src/utils/streaming-helper.js +1 -1
  30. package/dist/src/utils/tool-config.js +17 -0
  31. package/docs/TOOLS_REFERENCE.md +1183 -1068
  32. package/docs/TOOL_PARAMETERS.md +95 -424
  33. package/docs/TOOL_PROFILES.md +139 -140
  34. package/docs/plans/infra-plan-2026-07-research.json +194 -0
  35. package/docs/plans/infra-plan-2026-07.html +292 -0
  36. package/docs/plans/monetization-roadmap/avenues.html +179 -0
  37. package/docs/plans/monetization-roadmap/hosting.html +114 -0
  38. package/docs/plans/monetization-roadmap/index.html +89 -0
  39. package/docs/plans/monetization-roadmap/plan-90.html +94 -0
  40. package/docs/plans/monetization-roadmap/style.css +241 -0
  41. package/docs/superpowers/plans/2026-07-01-gap-tools.md +1147 -0
  42. package/docs/superpowers/plans/2026-07-02-debug-triage-spec-writer.md +417 -0
  43. package/docs/superpowers/plans/2026-07-02-install-wave.md +412 -0
  44. package/docs/superpowers/plans/2026-07-03-refine-prompt.md +197 -0
  45. package/package.json +1 -1
  46. package/profiles/balanced.json +10 -3
  47. package/profiles/code_focus.json +10 -3
  48. package/profiles/full.json +10 -3
  49. package/profiles/heavy_coding.json +10 -3
  50. package/profiles/minimal.json +10 -3
  51. package/profiles/research_power.json +10 -3
  52. package/skills/judge/SKILL.md +1 -1
  53. package/skills/prompt/SKILL.md +40 -124
  54. package/skills/redteam/SKILL.md +21 -0
  55. package/skills/review/SKILL.md +21 -0
  56. package/skills/setup/SKILL.md +13 -0
  57. package/skills/spec/SKILL.md +15 -0
  58. package/skills/tachi/SKILL.md +1 -1
  59. package/skills/triage/SKILL.md +15 -0
  60. package/tools.config.json +6 -12
  61. package/profiles/debug_intensive.json +0 -33
  62. package/profiles/workflow_builder.json +0 -36
package/README.md CHANGED
@@ -4,18 +4,18 @@
4
4
 
5
5
  ### Multi-Model AI Orchestration Platform
6
6
 
7
- [![Version](https://img.shields.io/badge/version-2.23.2-blue.svg)](https://www.npmjs.com/package/tachibot-mcp)
8
- [![Tools](https://img.shields.io/badge/tools-57_active-brightgreen.svg)](#-tool-ecosystem-57-tools)
7
+ [![Version](https://img.shields.io/badge/version-2.26.0-blue.svg)](https://www.npmjs.com/package/tachibot-mcp)
8
+ [![Tools](https://img.shields.io/badge/tools-64_active-brightgreen.svg)](#-tool-ecosystem-64-tools)
9
9
  [![License](https://img.shields.io/badge/license-AGPL--3.0-green.svg)](LICENSE)
10
- [![Node](https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen.svg)](https://nodejs.org)
10
+ [![Node](https://img.shields.io/badge/node-%3E%3D22.0.0-brightgreen.svg)](https://nodejs.org)
11
11
  [![MCP](https://img.shields.io/badge/MCP-Compatible-purple.svg)](https://modelcontextprotocol.io)
12
12
 
13
- **57 AI tools. 12 providers. One protocol.**
13
+ **64 AI tools. 12 providers. One protocol.**
14
14
 
15
15
  Orchestrate Perplexity, Grok, GPT-5.5, Gemini, Qwen, Kimi K2.7-Code, and MiniMax M3
16
16
  from Claude Code, Claude Desktop, Cursor, or any MCP client.
17
17
 
18
- [Get Started](#-quick-start) · [View Tools](#-tool-ecosystem-57-tools) · [Documentation](https://tachibot.com/docs)
18
+ [Get Started](#-quick-start) · [View Tools](#-tool-ecosystem-64-tools) · [Documentation](https://tachibot.com/docs)
19
19
 
20
20
  <br>
21
21
 
@@ -28,52 +28,39 @@ from Claude Code, Claude Desktop, Cursor, or any MCP client.
28
28
 
29
29
  ---
30
30
 
31
- ## What's New in v2.15.0
31
+ ## What's New in v2.26.0
32
32
 
33
- ### `/blueprint` Skill &mdash; Multi-Model Implementation Planning
34
- New skill that creates bite-sized TDD implementation plans using a 7-step multi-model council:
35
- ```
36
- /blueprint add OAuth with refresh tokens
37
- ```
38
- Pipeline: Grok search → Qwen+Kimi analysis → Kimi decompose → GPT pre-mortem critique → Gemini final judgment → **bite-sized TDD output** (exact files, test-first steps, commit points).
39
-
40
- Bridges `planner_maker`'s multi-model intelligence with the `writing-plans` execution format.
41
-
42
- ### 31 Prompt Engineering Techniques (was 22)
43
- Added 9 research-backed techniques for coding and decision-making:
33
+ ### Prompt stack, modernized
34
+ - **`refine_prompt`** (new tool) &mdash; opt-in prompt improver on a cheap/fast model: raw query → goal-first brief + **what changed** + **open questions**. Never auto-fires, never executes anything — you review, then use the brief. In Claude Code, `/prompt refine` presents the open questions as clickable choices and merges your answers into a final brief.
35
+ - **Curated technique list** &mdash; `list_prompt_techniques` now defaults to the ~9 core techniques that still help 2026 reasoning models (output contracts like `scot`, `pre_mortem`, `bdd_spec`); `all=true` for the full 31.
36
+ - **`technique="auto"`** &mdash; `preview_prompt_technique` recommends the right technique for your task, with reasons. Ask `tachi` "improve my prompt" for the symptom-based menu.
44
37
 
45
- | Technique | Source | Category |
46
- |-----------|--------|----------|
47
- | `reflexion` | Shinn et al. 2023 | Engineering |
48
- | `react` (ReAct) | Yao et al. 2022 | Engineering |
49
- | `rubber_duck` | Hunt & Thomas 2008 | Engineering |
50
- | `test_driven` | Beck 2003 | Engineering |
51
- | `scot` (Structured CoT) | Li et al. 2025 (+13.79% HumanEval) | Structured Coding |
52
- | `pre_post` (Contracts) | Empirical SE 2025 | Structured Coding |
53
- | `bdd_spec` (Given/When/Then) | BDD 2025 | Structured Coding |
54
- | `least_to_most` | Zhou et al. 2022 | Research |
55
- | `pre_mortem` | Klein 2007 | Decision |
38
+ ### Setup, de-mystified
39
+ - **`tachibot init`** (new CLI wizard) &mdash; detects your API keys and clients, prints the exact config for Claude Code and Claude Desktop. Never writes or echoes keys.
40
+ - **One-click Claude Desktop install** &mdash; download the `.mcpb` from the latest release and double-click. No JSON editing.
41
+ - **`doctor`** &mdash; shows which keys are set, which tools are visible vs hidden and why, and what to try first.
56
42
 
57
- Techniques are embedded directly in tool system prompts for automatic application.
43
+ ### New tools & skills (64 tools · 17 skills)
44
+ - `debug_triage` &mdash; ranked root-cause hypotheses with the cheapest discriminating check for each (Grok 4.3)
45
+ - `spec_writer` &mdash; loose request → reviewable spec: user stories, Given/When/Then, out-of-scope, open questions (GPT-5.5)
46
+ - `diff_review` / `plan_critique` / `testgen` / `security_review` &mdash; multi-model diff review, adversarial plan red-team, test generation, OWASP/CWE audit
47
+ - Skills: `/review`, `/redteam`, `/spec`, `/triage`, `/setup`
58
48
 
59
- ### MiniMax M2.5 Upgrade
60
- - `minimax_code` &mdash; SWE-Bench **80.2%**, per-task TECHNIQUE tags (SCoT, reflexion, rubber_duck), per-task temperatures
61
- - `minimax_agent` &mdash; ReAct + least-to-most decomposition protocol, HALT criteria
62
-
63
- ### Enhanced Skills
64
- - `/breakdown` &mdash; now uses `least_to_most` ordering + `pre_mortem` failure analysis
65
- - `/judge` &mdash; first judge now runs pre-mortem ("assume this FAILED")
66
- - `/decompose` &mdash; deep-dives include pre/post contracts per sub-problem
67
- - `/prompt` &mdash; auto-recommend flow with 30-intent matching guide, 13 categories
49
+ ### Fixes
50
+ - `focus` orchestration screen: 37 lines of repeated scaffolding 10 focused lines
51
+ - `npm test` exits 0 again (uncancelled race timers leaked past Jest teardown)
52
+ - GPT-5.5 high-effort reasoning no longer cut off at 3 minutes (timeout 180s → 600s)
68
53
 
69
54
  ---
70
55
 
71
56
  ## Skills (Claude Code)
72
57
 
73
- TachiBot ships with 12 slash commands for Claude Code. These orchestrate the tools into powerful workflows:
58
+ TachiBot ships with 17 slash commands for Claude Code. These orchestrate the tools into powerful workflows:
74
59
 
75
60
  | Skill | What it does | Example |
76
61
  |-------|-------------|---------|
62
+ | `/setup` | Guided configuration — runs doctor, walks through keys/profiles | `/setup` |
63
+ | `/spec` | Request → reviewable spec before planning | `/spec add OAuth somehow` |
77
64
  | `/blueprint` | Multi-model planning → bite-sized TDD steps | `/blueprint add OAuth with refresh tokens` |
78
65
  | `/judge` | Multi-model council - parallel analysis with synthesis | `/judge how to implement rate limiting` |
79
66
  | `/think` | Sequential reasoning chain with any model | `/think grok,gemini design a cache layer` |
@@ -85,6 +72,9 @@ TachiBot ships with 12 slash commands for Claude Code. These orchestrate the too
85
72
  | `/lens` | Long-context analysis over Kimi's 256K window | `/lens find inconsistencies in this spec` |
86
73
  | `/reflect` | Grounded reflexion loop — critique vs external evidence | `/reflect harden this auth middleware` |
87
74
  | `/tot` | Tree-of-Thought: branch → jury-prune → synthesize | `/tot design a rate limiter` |
75
+ | `/review` | Multi-model diff review — panel + Gemini judge verdict | `/review` (or paste a diff) |
76
+ | `/redteam` | Adversarial plan red-team — pre-mortem, risks, plan edits | `/redteam <paste plan>` |
77
+ | `/triage` | Ranked root-cause bug triage | `/triage <paste stack trace>` |
88
78
  | `/tachi` | Help - see available skills, tools, key status | `/tachi` |
89
79
 
90
80
  Skills automatically adapt to your configured API keys. Even with just 1-2 providers, all skills work.
@@ -96,7 +86,7 @@ Skills automatically adapt to your configured API keys. Even with just 1-2 provi
96
86
  ## Key Features
97
87
 
98
88
  ### Multi-Model Intelligence
99
- - **57 AI Tools** across 12 providers &mdash; Perplexity, Grok, GPT-5, Gemini, Qwen, Kimi, MiniMax, DeepSeek, GLM (Zhipu), StepFun, ERNIE (Baidu), plus free local models (Ollama / LM Studio / llama.cpp / vLLM)
89
+ - **64 AI Tools** across 12 providers &mdash; Perplexity, Grok, GPT-5, Gemini, Qwen, Kimi, MiniMax, DeepSeek, GLM (Zhipu), StepFun, ERNIE (Baidu), plus free local models (Ollama / LM Studio / llama.cpp / vLLM)
100
90
  - **Gemini 3.5 Flash** (`gemini-3.5-flash`, GA May 19 2026) &mdash; Flash/search tier; reasoning default stays `gemini-3.1-pro-preview`
101
91
  - **Multi-Model Council** &mdash; planner_maker synthesizes plans from 5+ models into bite-sized TDD steps
102
92
  - **Smart Routing** &mdash; Automatic model selection for optimal results
@@ -111,12 +101,12 @@ Skills automatically adapt to your configured API keys. Even with just 1-2 provi
111
101
  ### Tool Profiles
112
102
  | Profile | Tools | Best For |
113
103
  |---------|-------|----------|
114
- | **Minimal** | 12 | Quick tasks, low token budget |
104
+ | **Minimal** | 13 | Quick tasks, low token budget |
115
105
  | **Research Power** | 35 | Deep investigation, multi-source |
116
- | **Code Focus** | 34 | Software development, SWE tasks |
117
- | **Balanced** | 45 | General-purpose, mixed workflows |
118
- | **Heavy Coding** (default) | 50 | Max code tools + agentic workflows |
119
- | **Full** | 57 | Everything enabled |
106
+ | **Code Focus** | 42 | Software development, SWE tasks |
107
+ | **Balanced** | 53 | General-purpose, mixed workflows |
108
+ | **Heavy Coding** | 57 | Max code tools + agentic workflows |
109
+ | **Full** (default) | 64 | Everything enabled |
120
110
 
121
111
  ### Developer Experience
122
112
  - **Claude Code** &mdash; First-class support
@@ -134,7 +124,25 @@ Skills automatically adapt to your configured API keys. Even with just 1-2 provi
134
124
  npm install -g tachibot-mcp
135
125
  ```
136
126
 
137
- ### Setup
127
+ ### Setup wizard
128
+
129
+ ```bash
130
+ npx -y -p tachibot-mcp tachibot init
131
+ ```
132
+
133
+ Detects your keys and clients, then prints the exact config for Claude Code and Claude Desktop.
134
+
135
+ ### Claude Code (one-liner)
136
+
137
+ ```bash
138
+ claude mcp add tachibot -- npx -y -p tachibot-mcp tachibot
139
+ ```
140
+
141
+ Then verify with `/mcp`. Add API keys with `--env`, e.g. `--env OPENROUTER_API_KEY=sk-or-xxx --env PERPLEXITY_API_KEY=pplx-xxx`.
142
+
143
+ ### Setup (Claude Desktop)
144
+
145
+ **One-click (easiest):** download [`tachibot-mcp.mcpb`](https://github.com/byPawel/tachibot-mcp/releases/latest) from the latest release and double-click it — Claude Desktop installs the extension with no JSON editing. Add your API keys when prompted (or later via the extension settings).
138
146
 
139
147
  **Gateway Mode (Recommended)** &mdash; 2 keys, all providers:
140
148
 
@@ -178,28 +186,28 @@ See [Installation Guide](docs/INSTALLATION_BOTH.md) for detailed instructions.
178
186
 
179
187
  ---
180
188
 
181
- ## Tool Ecosystem (57 Tools)
189
+ ## Tool Ecosystem (64 Tools)
182
190
 
183
- ### Research & Search (6)
184
- `perplexity_ask` &#183; `perplexity_research` &#183; `perplexity_reason` &#183; `grok_search` &#183; `openai_search` &#183; `gemini_search`
191
+ ### Research & Search (5)
192
+ `perplexity_ask` &#183; `perplexity_reason` &#183; `grok_search` &#183; `openai_search` &#183; `gemini_search`
185
193
 
186
- ### Reasoning & Planning (13)
187
- `grok_reason` &#183; `openai_reason` &#183; `qwen_reason` &#183; `qwq_reason` &#183; `kimi_thinking` &#183; `kimi_decompose` &#183; `deepseek_reason` &#183; `glm_reason` &#183; `stepfun_reason` &#183; `ernie_reason` &#183; `planner_maker` &#183; `planner_runner` &#183; `list_plans`
194
+ ### Reasoning & Planning (14)
195
+ `grok_reason` &#183; `openai_reason` &#183; `qwen_reason` &#183; `qwq_reason` &#183; `kimi_thinking` &#183; `kimi_decompose` &#183; `deepseek_reason` &#183; `glm_reason` &#183; `stepfun_reason` &#183; `ernie_reason` &#183; `planner_maker` &#183; `planner_runner` &#183; `list_plans` &#183; `spec_writer`
188
196
 
189
- ### Code Intelligence (9)
190
- `kimi_code` &#183; `grok_code` &#183; `grok_debug` &#183; `qwen_coder` &#183; `qwen_algo` &#183; `qwen_competitive` &#183; `deepseek_algo` &#183; `minimax_code` &#183; `minimax_agent`
197
+ ### Code Intelligence (11)
198
+ `kimi_code` &#183; `grok_code` &#183; `grok_debug` &#183; `qwen_coder` &#183; `qwen_algo` &#183; `qwen_competitive` &#183; `deepseek_algo` &#183; `minimax_code` &#183; `minimax_agent` &#183; `testgen` &#183; `debug_triage`
191
199
 
192
- ### Analysis & Judgment (11)
193
- `gemini_analyze_text` &#183; `gemini_analyze_code` &#183; `gemini_judge` &#183; `jury` &#183; `gemini_brainstorm` &#183; `openai_brainstorm` &#183; `openai_code_review` &#183; `openai_explain` &#183; `grok_brainstorm` &#183; `grok_architect` &#183; `kimi_long_context`
200
+ ### Analysis & Judgment (14)
201
+ `gemini_analyze_text` &#183; `gemini_analyze_code` &#183; `gemini_judge` &#183; `jury` &#183; `diff_review` &#183; `plan_critique` &#183; `gemini_brainstorm` &#183; `openai_brainstorm` &#183; `openai_code_review` &#183; `openai_explain` &#183; `grok_brainstorm` &#183; `grok_architect` &#183; `security_review` &#183; `kimi_long_context`
194
202
 
195
- ### Meta & Orchestration (5)
196
- `think` &#183; `nextThought` &#183; `focus` &#183; `tachi` &#183; `usage_stats`
203
+ ### Meta & Orchestration (6)
204
+ `think` &#183; `nextThought` &#183; `focus` &#183; `tachi` &#183; `doctor` &#183; `usage_stats`
197
205
 
198
206
  ### Workflows (9)
199
207
  `workflow` &#183; `workflow_start` &#183; `continue_workflow` &#183; `list_workflows` &#183; `create_workflow` &#183; `visualize_workflow` &#183; `workflow_status` &#183; `validate_workflow` &#183; `validate_workflow_file`
200
208
 
201
- ### Prompt Engineering (3)
202
- `list_prompt_techniques` &#183; `preview_prompt_technique` &#183; `execute_prompt_technique`
209
+ ### Prompt Engineering (4)
210
+ `list_prompt_techniques` &#183; `preview_prompt_technique` &#183; `execute_prompt_technique` &#183; `refine_prompt`
203
211
 
204
212
  ### Local Models (1)
205
213
  `local_query` &mdash; any OpenAI-compatible local server (Ollama / LM Studio / llama.cpp / vLLM). Zero-cost, offline, private; also available as the `local` jury juror (`hermes` is accepted as a legacy alias). Runs whatever `LOCAL_LLM_MODEL` points at &mdash; e.g. a Nous Hermes build (`ollama pull hermes3`). Note the [Hermes agent](https://hermes-agent.nousresearch.com) itself is model-agnostic &mdash; it runs on 300+ backends (GPT, Claude, Gemini, DeepSeek, or self-hosted Ollama/vLLM) &mdash; so "Hermes" was never a guarantee of distinct weights.
@@ -0,0 +1,125 @@
1
+ /**
2
+ * `tachibot init` — setup wizard. Detection + emission first: pure functions
3
+ * detect keys/clients and emit EXACT per-client instructions; a thin
4
+ * readline layer only picks the client. Keys are never written to disk by
5
+ * default and never echoed (masked to 6 chars). Node built-ins only.
6
+ */
7
+ import * as fs from "node:fs";
8
+ import * as os from "node:os";
9
+ import * as path from "node:path";
10
+ import * as readline from "node:readline/promises";
11
+ const KEYS = [
12
+ { name: "OpenRouter", envVar: "OPENROUTER_API_KEY", unlocks: "DeepSeek/GLM/Kimi/Qwen/MiniMax/StepFun/ERNIE + planner (~30 tools)" },
13
+ { name: "Perplexity", envVar: "PERPLEXITY_API_KEY", unlocks: "web research tools" },
14
+ { name: "Gemini / Google", envVar: "GOOGLE_API_KEY", unlocks: "Gemini tools + jury judge + diff_review/plan_critique" },
15
+ { name: "OpenAI", envVar: "OPENAI_API_KEY", unlocks: "GPT-5.5 tools + spec_writer" },
16
+ { name: "Grok / xAI", envVar: "GROK_API_KEY", unlocks: "Grok tools + debug_triage" },
17
+ ];
18
+ function defaultProbe() {
19
+ return {
20
+ // PATH lookup done via fs, not a subprocess: no shell involved, no injection surface.
21
+ which: (bin) => {
22
+ const dirs = (process.env.PATH || "").split(path.delimiter).filter(Boolean);
23
+ const exts = process.platform === "win32" ? [".exe", ".cmd", ".bat", ""] : [""];
24
+ return dirs.some((dir) => exts.some((ext) => {
25
+ try {
26
+ return fs.statSync(path.join(dir, bin + ext)).isFile();
27
+ }
28
+ catch {
29
+ return false;
30
+ }
31
+ }));
32
+ },
33
+ exists: (p) => fs.existsSync(p),
34
+ };
35
+ }
36
+ function desktopConfigPath() {
37
+ if (process.platform === "darwin") {
38
+ return path.join(os.homedir(), "Library", "Application Support", "Claude", "claude_desktop_config.json");
39
+ }
40
+ if (process.platform === "win32") {
41
+ return path.join(process.env.APPDATA || "", "Claude", "claude_desktop_config.json");
42
+ }
43
+ return path.join(os.homedir(), ".config", "Claude", "claude_desktop_config.json");
44
+ }
45
+ export function detectSetup(env = process.env, probe = defaultProbe()) {
46
+ const keys = KEYS.map((k) => ({
47
+ name: k.name,
48
+ envVar: k.envVar,
49
+ present: Boolean(env[k.envVar]?.trim()),
50
+ unlocks: k.unlocks,
51
+ }));
52
+ // Gemini/Grok alternates count as present
53
+ const alt = (primary, alternate) => {
54
+ const row = keys.find((k) => k.envVar === primary);
55
+ if (!row.present && env[alternate]?.trim())
56
+ row.present = true;
57
+ };
58
+ alt("GOOGLE_API_KEY", "GEMINI_API_KEY");
59
+ alt("GROK_API_KEY", "XAI_API_KEY");
60
+ const dcp = desktopConfigPath();
61
+ return {
62
+ keys,
63
+ clients: {
64
+ claudeCode: probe.which("claude"),
65
+ claudeDesktop: probe.exists(dcp),
66
+ desktopConfigPath: probe.exists(dcp) ? dcp : null,
67
+ },
68
+ };
69
+ }
70
+ export function buildClaudeCodeCommand(setup) {
71
+ const envFlags = setup.keys
72
+ .filter((k) => k.present)
73
+ .map((k) => `--env ${k.envVar}=<your-${k.name.toLowerCase().replace(/[^a-z]+/g, "-")}-key>`)
74
+ .join(" \\\n ");
75
+ return [
76
+ "claude mcp add tachibot \\",
77
+ envFlags ? ` ${envFlags} \\` : null,
78
+ " -- npx -y -p tachibot-mcp tachibot",
79
+ ].filter(Boolean).join("\n");
80
+ }
81
+ export function buildDesktopSnippet(setup, profile) {
82
+ const env = {};
83
+ for (const k of setup.keys.filter((k) => k.present))
84
+ env[k.envVar] = `<your-${k.envVar}>`;
85
+ env.TACHIBOT_PROFILE = profile;
86
+ return JSON.stringify({ mcpServers: { tachibot: { command: "tachibot", env } } }, null, 2);
87
+ }
88
+ const mask = (v) => (v ? `${v.slice(0, 6)}…` : "");
89
+ export async function runInitWizard() {
90
+ const setup = detectSetup();
91
+ const out = (s) => process.stdout.write(s + "\n");
92
+ out("\nTACHIBOT INIT\n=============");
93
+ out("\nAPI keys detected in this shell:");
94
+ for (const k of setup.keys) {
95
+ out(` ${k.present ? "✓" : "✗"} ${k.name} (${k.envVar})${k.present ? ` ${mask(process.env[k.envVar])}` : ""} — ${k.unlocks}`);
96
+ }
97
+ if (!setup.keys.some((k) => k.present)) {
98
+ out("\nNo keys found. Get ONE key to start — OPENROUTER_API_KEY unlocks the most tools (openrouter.ai).");
99
+ }
100
+ out("\nClients detected:");
101
+ out(` ${setup.clients.claudeCode ? "✓" : "✗"} Claude Code (claude on PATH)`);
102
+ out(` ${setup.clients.claudeDesktop ? "✓" : "✗"} Claude Desktop${setup.clients.desktopConfigPath ? ` (${setup.clients.desktopConfigPath})` : ""}`);
103
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
104
+ try {
105
+ const choice = (await rl.question("\nSet up for: [1] Claude Code [2] Claude Desktop [3] both [q] quit > ")).trim();
106
+ if (choice === "q")
107
+ return;
108
+ const profile = (await rl.question("Profile [full=all 63 tools | balanced | code_focus] (default: full) > ")).trim() || "full";
109
+ if (choice === "1" || choice === "3") {
110
+ out("\n— Claude Code — run this (fill in your real keys):\n");
111
+ out(buildClaudeCodeCommand(setup));
112
+ out("\nThen verify with /mcp inside Claude Code.");
113
+ }
114
+ if (choice === "2" || choice === "3") {
115
+ out("\n— Claude Desktop — easiest: double-click the tachibot-mcp.mcpb extension package (see GitHub releases).");
116
+ out("Or merge this into " + (setup.clients.desktopConfigPath ?? desktopConfigPath()) + ":\n");
117
+ out(buildDesktopSnippet(setup, profile));
118
+ out("\nThen restart Claude Desktop.");
119
+ }
120
+ out("\nFirst thing to run once connected: the `doctor` tool — it shows which tools your keys unlock.");
121
+ }
122
+ finally {
123
+ rl.close();
124
+ }
125
+ }
@@ -77,14 +77,19 @@ export function formatTimeout(ms) {
77
77
  return `${minutes}m ${remainingSeconds}s`;
78
78
  }
79
79
  /**
80
- * Create timeout promise for use with Promise.race()
80
+ * Create timeout promise for use with Promise.race(), plus a cancel handle.
81
+ * The race's loser leaves its timer scheduled unless the caller cancels it —
82
+ * without that, a fast-resolving `promise` still leaves this setTimeout alive
83
+ * for the full `ms`, holding the event loop open.
81
84
  */
82
85
  export function createTimeoutPromise(ms, message) {
83
- return new Promise((_, reject) => {
84
- setTimeout(() => {
86
+ let timer;
87
+ const promise = new Promise((_, reject) => {
88
+ timer = setTimeout(() => {
85
89
  reject(new Error(message || `Operation timed out after ${formatTimeout(ms)}`));
86
90
  }, ms);
87
91
  });
92
+ return { promise, cancel: () => clearTimeout(timer) };
88
93
  }
89
94
  /**
90
95
  * Wrap promise with timeout
@@ -93,10 +98,13 @@ export async function withTimeout(promise, timeoutMs, toolName) {
93
98
  const timeoutMessage = toolName
94
99
  ? `${toolName} operation timed out after ${formatTimeout(timeoutMs)}`
95
100
  : `Operation timed out after ${formatTimeout(timeoutMs)}`;
96
- return Promise.race([
97
- promise,
98
- createTimeoutPromise(timeoutMs, timeoutMessage)
99
- ]);
101
+ const raceTimeout = createTimeoutPromise(timeoutMs, timeoutMessage);
102
+ try {
103
+ return await Promise.race([promise, raceTimeout.promise]);
104
+ }
105
+ finally {
106
+ raceTimeout.cancel();
107
+ }
100
108
  }
101
109
  /**
102
110
  * Check if we should show progress (operation exceeds threshold)
@@ -127,7 +135,9 @@ export const SMART_TIMEOUT_DEFAULTS = {
127
135
  },
128
136
  openai: {
129
137
  base: 60000, // 60 seconds - GPT-5.4 reasoning needs more time
130
- max: 180000 // 3 minutes - high/xhigh reasoning effort
138
+ max: 600000 // 10 minutes - GPT-5.5 high/xhigh effort can exceed the
139
+ // OpenAI SDK's 900s default; 180s was cutting off real
140
+ // reasoning runs (verified 2026-07 deep-research)
131
141
  },
132
142
  anthropic: {
133
143
  base: 20000, // 20 seconds
@@ -1,14 +1,18 @@
1
- import { ReasoningMode, REASONING_TEMPLATES, MODEL_PERSONAS } from "../../../../reasoning-chain.js";
2
- const renderWorkflowCascade = (steps, title) => {
3
- const lines = [`## ${title}`];
4
- steps.forEach((s, i) => lines.push(`${i + 1}. [${s.status}] ${s.name} (${s.model})`));
5
- return lines.join('\n');
6
- };
7
- const renderProgressReel = (phases, title) => {
8
- const lines = [`## ${title}`];
9
- phases.forEach(p => lines.push(`- [${p.status}] ${p.name}`));
10
- return lines.join('\n');
11
- };
1
+ import { ReasoningMode, REASONING_TEMPLATES } from "../../../../reasoning-chain.js";
2
+ // import {
3
+ // renderWorkflowCascade,
4
+ // renderProgressReel,
5
+ // renderThinkingChainArbor,
6
+ // renderGradientDivider,
7
+ // renderGradientBorderBox,
8
+ // renderTable,
9
+ // renderKeyValueTable,
10
+ // renderQuickFlow,
11
+ // icons,
12
+ // WorkflowStep,
13
+ // ProgressPhase,
14
+ // } from "../../../../utils/ink-renderer.js";
15
+ // Ink disabled — MCP clients render markdown, so these emit plain markdown.
12
16
  const renderThinkingChainArbor = (thoughts, title) => {
13
17
  const lines = [`## ${title}`];
14
18
  thoughts.forEach((t, i) => lines.push(`${i + 1}. (${t.model}) ${t.thought}`));
@@ -30,9 +34,6 @@ const renderTable = (data) => {
30
34
  const renderKeyValueTable = (data) => {
31
35
  return Object.entries(data).map(([k, v]) => `${k}: ${v}`).join('\n');
32
36
  };
33
- const renderQuickFlow = (steps, title) => {
34
- return `## ${title}\n${steps.join(' -> ')}`;
35
- };
36
37
  const icons = {
37
38
  brain: '*',
38
39
  sparkle: '*',
@@ -52,54 +53,26 @@ export class VisualizationService {
52
53
  */
53
54
  generateOrchestrationPlan(session) {
54
55
  const steps = session.chain.steps;
56
+ const done = session.currentStep;
57
+ // One clean header line + a per-step table. The old layout rendered the
58
+ // same step list four times (cascade, flow, progress reel, table) plus a
59
+ // metadata block and faux "gradient" boxes — a wall of duplicated scaffold.
60
+ // MCP clients render markdown, so a single table IS the visualization.
55
61
  const lines = [];
56
- // Header with gradient border box
57
- lines.push(renderGradientBorderBox(`${icons.brain} Collaborative Reasoning\n\n${session.objective}\n\nDomain: ${session.domain} | Session: ${session.id.slice(0, 8)}`, { width: 60, gradient: 'cristal' }));
58
- lines.push('');
59
- // Workflow cascade showing model flow
60
- const cascadeSteps = steps.map((step, idx) => ({
61
- name: `${this.getModeIcon(step.mode)} ${step.mode}`,
62
- model: step.model,
63
- status: idx < session.currentStep ? 'completed' :
64
- idx === session.currentStep ? 'running' : 'pending',
65
- duration: idx < session.currentStep ? 1000 + Math.random() * 2000 : undefined,
66
- }));
67
- lines.push(renderWorkflowCascade(cascadeSteps, 'Reasoning Chain'));
62
+ lines.push(`**Collaborative Reasoning** · ${session.objective}`);
63
+ lines.push(`${session.domain} · ${this.modelTurnTaking ? 'sequential' : 'parallel'} · ` +
64
+ `step ${Math.min(done + 1, steps.length)}/${steps.length} · \`${session.id.slice(0, 8)}\``);
68
65
  lines.push('');
69
- // Quick flow diagram
70
- const flowSteps = steps.map(s => `${s.model}: ${s.mode}`);
71
- lines.push(renderQuickFlow(flowSteps, 'Execution Flow'));
72
- lines.push('');
73
- // Progress reel
74
- const progressSteps = steps.map((step, idx) => ({
75
- name: `${step.model} - ${step.mode}`,
76
- status: idx < session.currentStep ? 'completed' :
77
- idx === session.currentStep ? 'active' : 'pending',
66
+ // One table: status · mode · model, in order. The mode already conveys each
67
+ // step's job, so no "Role" column (its half-filled "AI" fallback is the bit
68
+ // that read as generic). Status marks done (✓) / current (▸) / pending (·).
69
+ const tableData = steps.map((step, idx) => ({
70
+ '#': String(idx + 1),
71
+ '': idx < done ? '✓' : idx === done ? '▸' : '·',
72
+ Step: `${this.getModeIcon(step.mode)} ${step.mode}`,
73
+ Model: step.model,
78
74
  }));
79
- lines.push(renderProgressReel(progressSteps, 'Step Progress'));
80
- lines.push('');
81
- // Detailed steps table
82
- const tableData = steps.map((step, idx) => {
83
- const persona = Object.values(MODEL_PERSONAS).find(p => p.model === step.model);
84
- return {
85
- '#': String(idx + 1),
86
- Mode: `${this.getModeIcon(step.mode)} ${step.mode}`,
87
- Model: step.model,
88
- Role: persona?.role || 'AI',
89
- Status: idx < session.currentStep ? '✓' : idx === session.currentStep ? '⟳' : '○',
90
- };
91
- });
92
75
  lines.push(renderTable(tableData));
93
- lines.push('');
94
- // Session info
95
- lines.push(renderKeyValueTable({
96
- 'Session ID': session.id,
97
- 'Total Steps': String(steps.length),
98
- 'Current Step': String(session.currentStep + 1),
99
- 'Turn Taking': this.modelTurnTaking ? 'Sequential' : 'Parallel',
100
- }));
101
- lines.push('');
102
- lines.push(renderGradientDivider(60, 'rainbow'));
103
76
  return lines.join('\n');
104
77
  }
105
78
  /**
@@ -112,7 +85,7 @@ export class VisualizationService {
112
85
  const currentMode = currentStep?.mode || ReasoningMode.BRAINSTORM;
113
86
  const lines = [];
114
87
  // Thinking chain visualization
115
- const thoughts = session.chain.steps.slice(0, stage + 1).map((step, idx) => ({
88
+ const thoughts = session.chain.steps.slice(0, stage + 1).map((step) => ({
116
89
  thought: `${step.mode}: ${step.prompt.slice(0, 50)}...`,
117
90
  model: step.model,
118
91
  isRevision: step.mode === ReasoningMode.CRITIQUE,
@@ -1,17 +1,18 @@
1
1
  export const balancedProfile = {
2
- description: "Balanced set for general use (~Xk tokens, 18 tools)",
2
+ description: "Balanced set for general use (53 tools)",
3
3
  tools: {
4
4
  think: true,
5
5
  focus: true,
6
6
  tachi: true,
7
+ doctor: true,
7
8
  nextThought: true,
8
9
  usage_stats: true,
9
10
  perplexity_ask: true,
10
11
  perplexity_reason: true,
11
- perplexity_research: false,
12
12
  grok_reason: true,
13
13
  grok_code: true,
14
14
  grok_debug: false,
15
+ debug_triage: true,
15
16
  grok_architect: false,
16
17
  grok_brainstorm: false,
17
18
  grok_search: true,
@@ -20,6 +21,8 @@ export const balancedProfile = {
20
21
  openai_code_review: false,
21
22
  openai_explain: false,
22
23
  openai_search: true,
24
+ spec_writer: true,
25
+ refine_prompt: true,
23
26
  gemini_brainstorm: true,
24
27
  gemini_analyze_code: true,
25
28
  gemini_analyze_text: true,
@@ -59,5 +62,13 @@ export const balancedProfile = {
59
62
  planner_maker: true,
60
63
  planner_runner: true,
61
64
  list_plans: true,
65
+ // Test generation
66
+ testgen: true,
67
+ // Security audit
68
+ security_review: true,
69
+ // Diff-aware code review
70
+ diff_review: true,
71
+ // Adversarial plan red-team
72
+ plan_critique: true,
62
73
  }
63
74
  };
@@ -1,17 +1,18 @@
1
1
  export const codeFocusProfile = {
2
- description: "Code-heavy work with debugging and analysis (~Xk tokens, 15 tools)",
2
+ description: "Code-heavy work with debugging and analysis (42 tools)",
3
3
  tools: {
4
4
  think: true,
5
5
  focus: true,
6
6
  tachi: true,
7
+ doctor: true,
7
8
  nextThought: true,
8
9
  usage_stats: true,
9
10
  perplexity_ask: true,
10
11
  perplexity_reason: false,
11
- perplexity_research: false,
12
12
  grok_reason: true,
13
13
  grok_code: true,
14
14
  grok_debug: true,
15
+ debug_triage: true,
15
16
  grok_architect: false,
16
17
  grok_brainstorm: false,
17
18
  grok_search: false,
@@ -20,6 +21,8 @@ export const codeFocusProfile = {
20
21
  openai_code_review: true,
21
22
  openai_explain: false,
22
23
  openai_search: false,
24
+ spec_writer: true,
25
+ refine_prompt: true,
23
26
  gemini_brainstorm: true,
24
27
  gemini_analyze_code: true,
25
28
  gemini_analyze_text: false,
@@ -59,5 +62,13 @@ export const codeFocusProfile = {
59
62
  planner_maker: true,
60
63
  planner_runner: true,
61
64
  list_plans: true,
65
+ // Test generation
66
+ testgen: true,
67
+ // Security audit
68
+ security_review: true,
69
+ // Diff-aware code review
70
+ diff_review: true,
71
+ // Adversarial plan red-team
72
+ plan_critique: true,
62
73
  }
63
74
  };
@@ -1,17 +1,18 @@
1
1
  export const fullProfile = {
2
- description: "All tools enabled for maximum capability (57 tools)",
2
+ description: "Default profile — all tools enabled for maximum capability (64 tools)",
3
3
  tools: {
4
4
  think: true,
5
5
  focus: true,
6
6
  tachi: true,
7
+ doctor: true,
7
8
  nextThought: true,
8
9
  usage_stats: true,
9
10
  perplexity_ask: true,
10
11
  perplexity_reason: true,
11
- perplexity_research: true,
12
12
  grok_reason: true,
13
13
  grok_code: true,
14
14
  grok_debug: true,
15
+ debug_triage: true,
15
16
  grok_architect: true,
16
17
  grok_brainstorm: true,
17
18
  grok_search: true,
@@ -20,6 +21,8 @@ export const fullProfile = {
20
21
  openai_code_review: true,
21
22
  openai_explain: true,
22
23
  openai_search: true,
24
+ spec_writer: true,
25
+ refine_prompt: true,
23
26
  gemini_brainstorm: true,
24
27
  gemini_analyze_code: true,
25
28
  gemini_analyze_text: true,
@@ -59,5 +62,13 @@ export const fullProfile = {
59
62
  planner_maker: true,
60
63
  planner_runner: true,
61
64
  list_plans: true,
65
+ // Test generation
66
+ testgen: true,
67
+ // Security audit
68
+ security_review: true,
69
+ // Diff-aware code review
70
+ diff_review: true,
71
+ // Adversarial plan red-team
72
+ plan_critique: true,
62
73
  }
63
74
  };