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.
- package/README.md +67 -59
- package/dist/src/cli/init.js +125 -0
- package/dist/src/config/timeout-config.js +18 -8
- package/dist/src/orchestrators/collaborative/services/visualization/VisualizationService.js +32 -59
- package/dist/src/profiles/balanced.js +13 -2
- package/dist/src/profiles/code_focus.js +13 -2
- package/dist/src/profiles/full.js +13 -2
- package/dist/src/profiles/heavy_coding.js +13 -2
- package/dist/src/profiles/minimal.js +13 -2
- package/dist/src/profiles/research_power.js +13 -2
- package/dist/src/server-main.js +760 -0
- package/dist/src/server.js +11 -753
- package/dist/src/tools/debug-triage-tool.js +59 -0
- package/dist/src/tools/diff-review-tool.js +120 -0
- package/dist/src/tools/doctor-tool.js +143 -0
- package/dist/src/tools/jury-tool.js +18 -11
- package/dist/src/tools/panel.js +24 -0
- package/dist/src/tools/plan-critique-tool.js +117 -0
- package/dist/src/tools/prompt-technique-tools.js +129 -34
- package/dist/src/tools/provider-catalog.js +148 -0
- package/dist/src/tools/refine-prompt-tool.js +57 -0
- package/dist/src/tools/registry.js +25 -0
- package/dist/src/tools/security-review-tool.js +71 -0
- package/dist/src/tools/spec-writer-tool.js +64 -0
- package/dist/src/tools/tachi-tool.js +71 -2
- package/dist/src/tools/testgen-tool.js +57 -0
- package/dist/src/utils/api-keys.js +4 -2
- package/dist/src/utils/smart-api-client.js +13 -4
- package/dist/src/utils/streaming-helper.js +1 -1
- package/dist/src/utils/tool-config.js +17 -0
- package/docs/TOOLS_REFERENCE.md +1183 -1068
- package/docs/TOOL_PARAMETERS.md +95 -424
- package/docs/TOOL_PROFILES.md +139 -140
- package/docs/plans/infra-plan-2026-07-research.json +194 -0
- package/docs/plans/infra-plan-2026-07.html +292 -0
- package/docs/plans/monetization-roadmap/avenues.html +179 -0
- package/docs/plans/monetization-roadmap/hosting.html +114 -0
- package/docs/plans/monetization-roadmap/index.html +89 -0
- package/docs/plans/monetization-roadmap/plan-90.html +94 -0
- package/docs/plans/monetization-roadmap/style.css +241 -0
- package/docs/superpowers/plans/2026-07-01-gap-tools.md +1147 -0
- package/docs/superpowers/plans/2026-07-02-debug-triage-spec-writer.md +417 -0
- package/docs/superpowers/plans/2026-07-02-install-wave.md +412 -0
- package/docs/superpowers/plans/2026-07-03-refine-prompt.md +197 -0
- package/package.json +1 -1
- package/profiles/balanced.json +10 -3
- package/profiles/code_focus.json +10 -3
- package/profiles/full.json +10 -3
- package/profiles/heavy_coding.json +10 -3
- package/profiles/minimal.json +10 -3
- package/profiles/research_power.json +10 -3
- package/skills/judge/SKILL.md +1 -1
- package/skills/prompt/SKILL.md +40 -124
- package/skills/redteam/SKILL.md +21 -0
- package/skills/review/SKILL.md +21 -0
- package/skills/setup/SKILL.md +13 -0
- package/skills/spec/SKILL.md +15 -0
- package/skills/tachi/SKILL.md +1 -1
- package/skills/triage/SKILL.md +15 -0
- package/tools.config.json +6 -12
- package/profiles/debug_intensive.json +0 -33
- 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
|
-
[](https://www.npmjs.com/package/tachibot-mcp)
|
|
8
|
+
[](#-tool-ecosystem-64-tools)
|
|
9
9
|
[](LICENSE)
|
|
10
|
-
[](https://nodejs.org)
|
|
11
11
|
[](https://modelcontextprotocol.io)
|
|
12
12
|
|
|
13
|
-
**
|
|
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-
|
|
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.
|
|
31
|
+
## What's New in v2.26.0
|
|
32
32
|
|
|
33
|
-
###
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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) — 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** — `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"`** — `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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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) — 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** — download the `.mcpb` from the latest release and double-click. No JSON editing.
|
|
41
|
+
- **`doctor`** — shows which keys are set, which tools are visible vs hidden and why, and what to try first.
|
|
56
42
|
|
|
57
|
-
|
|
43
|
+
### New tools & skills (64 tools · 17 skills)
|
|
44
|
+
- `debug_triage` — ranked root-cause hypotheses with the cheapest discriminating check for each (Grok 4.3)
|
|
45
|
+
- `spec_writer` — 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` — multi-model diff review, adversarial plan red-team, test generation, OWASP/CWE audit
|
|
47
|
+
- Skills: `/review`, `/redteam`, `/spec`, `/triage`, `/setup`
|
|
58
48
|
|
|
59
|
-
###
|
|
60
|
-
- `
|
|
61
|
-
- `
|
|
62
|
-
|
|
63
|
-
### Enhanced Skills
|
|
64
|
-
- `/breakdown` — now uses `least_to_most` ordering + `pre_mortem` failure analysis
|
|
65
|
-
- `/judge` — first judge now runs pre-mortem ("assume this FAILED")
|
|
66
|
-
- `/decompose` — deep-dives include pre/post contracts per sub-problem
|
|
67
|
-
- `/prompt` — 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
|
|
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
|
-
- **
|
|
89
|
+
- **64 AI Tools** across 12 providers — 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) — Flash/search tier; reasoning default stays `gemini-3.1-pro-preview`
|
|
101
91
|
- **Multi-Model Council** — planner_maker synthesizes plans from 5+ models into bite-sized TDD steps
|
|
102
92
|
- **Smart Routing** — 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** |
|
|
104
|
+
| **Minimal** | 13 | Quick tasks, low token budget |
|
|
115
105
|
| **Research Power** | 35 | Deep investigation, multi-source |
|
|
116
|
-
| **Code Focus** |
|
|
117
|
-
| **Balanced** |
|
|
118
|
-
| **Heavy Coding**
|
|
119
|
-
| **Full** |
|
|
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** — 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)** — 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 (
|
|
189
|
+
## Tool Ecosystem (64 Tools)
|
|
182
190
|
|
|
183
|
-
### Research & Search (
|
|
184
|
-
`perplexity_ask` · `
|
|
191
|
+
### Research & Search (5)
|
|
192
|
+
`perplexity_ask` · `perplexity_reason` · `grok_search` · `openai_search` · `gemini_search`
|
|
185
193
|
|
|
186
|
-
### Reasoning & Planning (
|
|
187
|
-
`grok_reason` · `openai_reason` · `qwen_reason` · `qwq_reason` · `kimi_thinking` · `kimi_decompose` · `deepseek_reason` · `glm_reason` · `stepfun_reason` · `ernie_reason` · `planner_maker` · `planner_runner` · `list_plans`
|
|
194
|
+
### Reasoning & Planning (14)
|
|
195
|
+
`grok_reason` · `openai_reason` · `qwen_reason` · `qwq_reason` · `kimi_thinking` · `kimi_decompose` · `deepseek_reason` · `glm_reason` · `stepfun_reason` · `ernie_reason` · `planner_maker` · `planner_runner` · `list_plans` · `spec_writer`
|
|
188
196
|
|
|
189
|
-
### Code Intelligence (
|
|
190
|
-
`kimi_code` · `grok_code` · `grok_debug` · `qwen_coder` · `qwen_algo` · `qwen_competitive` · `deepseek_algo` · `minimax_code` · `minimax_agent`
|
|
197
|
+
### Code Intelligence (11)
|
|
198
|
+
`kimi_code` · `grok_code` · `grok_debug` · `qwen_coder` · `qwen_algo` · `qwen_competitive` · `deepseek_algo` · `minimax_code` · `minimax_agent` · `testgen` · `debug_triage`
|
|
191
199
|
|
|
192
|
-
### Analysis & Judgment (
|
|
193
|
-
`gemini_analyze_text` · `gemini_analyze_code` · `gemini_judge` · `jury` · `gemini_brainstorm` · `openai_brainstorm` · `openai_code_review` · `openai_explain` · `grok_brainstorm` · `grok_architect` · `kimi_long_context`
|
|
200
|
+
### Analysis & Judgment (14)
|
|
201
|
+
`gemini_analyze_text` · `gemini_analyze_code` · `gemini_judge` · `jury` · `diff_review` · `plan_critique` · `gemini_brainstorm` · `openai_brainstorm` · `openai_code_review` · `openai_explain` · `grok_brainstorm` · `grok_architect` · `security_review` · `kimi_long_context`
|
|
194
202
|
|
|
195
|
-
### Meta & Orchestration (
|
|
196
|
-
`think` · `nextThought` · `focus` · `tachi` · `usage_stats`
|
|
203
|
+
### Meta & Orchestration (6)
|
|
204
|
+
`think` · `nextThought` · `focus` · `tachi` · `doctor` · `usage_stats`
|
|
197
205
|
|
|
198
206
|
### Workflows (9)
|
|
199
207
|
`workflow` · `workflow_start` · `continue_workflow` · `list_workflows` · `create_workflow` · `visualize_workflow` · `workflow_status` · `validate_workflow` · `validate_workflow_file`
|
|
200
208
|
|
|
201
|
-
### Prompt Engineering (
|
|
202
|
-
`list_prompt_techniques` · `preview_prompt_technique` · `execute_prompt_technique`
|
|
209
|
+
### Prompt Engineering (4)
|
|
210
|
+
`list_prompt_techniques` · `preview_prompt_technique` · `execute_prompt_technique` · `refine_prompt`
|
|
203
211
|
|
|
204
212
|
### Local Models (1)
|
|
205
213
|
`local_query` — 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 — e.g. a Nous Hermes build (`ollama pull hermes3`). Note the [Hermes agent](https://hermes-agent.nousresearch.com) itself is model-agnostic — it runs on 300+ backends (GPT, Claude, Gemini, DeepSeek, or self-hosted Ollama/vLLM) — 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
|
-
|
|
84
|
-
|
|
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
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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:
|
|
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
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
-
|
|
57
|
-
lines.push(
|
|
58
|
-
|
|
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
|
-
//
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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
|
|
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 (
|
|
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 (
|
|
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: "
|
|
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
|
};
|