stravinsky 0.2.52__py3-none-any.whl → 0.2.67__py3-none-any.whl
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.
Potentially problematic release.
This version of stravinsky might be problematic. Click here for more details.
- mcp_bridge/__init__.py +1 -1
- mcp_bridge/cli/__init__.py +6 -0
- mcp_bridge/cli/install_hooks.py +1265 -0
- mcp_bridge/cli/session_report.py +585 -0
- mcp_bridge/hooks/HOOKS_SETTINGS.json +175 -0
- mcp_bridge/hooks/README.md +215 -0
- mcp_bridge/hooks/__init__.py +117 -63
- mcp_bridge/hooks/edit_recovery.py +42 -37
- mcp_bridge/hooks/git_noninteractive.py +89 -0
- mcp_bridge/hooks/keyword_detector.py +30 -0
- mcp_bridge/hooks/notification_hook.py +103 -0
- mcp_bridge/hooks/parallel_execution.py +111 -0
- mcp_bridge/hooks/pre_compact.py +82 -183
- mcp_bridge/hooks/rules_injector.py +507 -0
- mcp_bridge/hooks/session_notifier.py +125 -0
- mcp_bridge/{native_hooks → hooks}/stravinsky_mode.py +51 -16
- mcp_bridge/hooks/subagent_stop.py +98 -0
- mcp_bridge/hooks/task_validator.py +73 -0
- mcp_bridge/hooks/tmux_manager.py +141 -0
- mcp_bridge/hooks/todo_continuation.py +90 -0
- mcp_bridge/hooks/todo_delegation.py +88 -0
- mcp_bridge/hooks/tool_messaging.py +164 -0
- mcp_bridge/hooks/truncator.py +21 -17
- mcp_bridge/prompts/multimodal.py +24 -3
- mcp_bridge/server.py +12 -1
- mcp_bridge/server_tools.py +5 -0
- mcp_bridge/tools/agent_manager.py +30 -11
- mcp_bridge/tools/code_search.py +81 -9
- mcp_bridge/tools/lsp/tools.py +6 -2
- mcp_bridge/tools/model_invoke.py +76 -1
- mcp_bridge/tools/templates.py +32 -18
- stravinsky-0.2.67.dist-info/METADATA +284 -0
- {stravinsky-0.2.52.dist-info → stravinsky-0.2.67.dist-info}/RECORD +36 -23
- stravinsky-0.2.67.dist-info/entry_points.txt +5 -0
- mcp_bridge/native_hooks/edit_recovery.py +0 -46
- mcp_bridge/native_hooks/todo_delegation.py +0 -54
- mcp_bridge/native_hooks/truncator.py +0 -23
- stravinsky-0.2.52.dist-info/METADATA +0 -204
- stravinsky-0.2.52.dist-info/entry_points.txt +0 -3
- /mcp_bridge/{native_hooks → hooks}/context.py +0 -0
- {stravinsky-0.2.52.dist-info → stravinsky-0.2.67.dist-info}/WHEEL +0 -0
mcp_bridge/tools/model_invoke.py
CHANGED
|
@@ -305,11 +305,13 @@ async def invoke_gemini(
|
|
|
305
305
|
temperature: float = 0.7,
|
|
306
306
|
max_tokens: int = 4096,
|
|
307
307
|
thinking_budget: int = 0,
|
|
308
|
+
image_path: str | None = None,
|
|
308
309
|
) -> str:
|
|
309
310
|
"""
|
|
310
311
|
Invoke a Gemini model with the given prompt.
|
|
311
312
|
|
|
312
313
|
Uses OAuth authentication with Antigravity credentials.
|
|
314
|
+
Supports vision API for image/PDF analysis when image_path is provided.
|
|
313
315
|
|
|
314
316
|
Args:
|
|
315
317
|
token_store: Token store for OAuth credentials
|
|
@@ -317,6 +319,8 @@ async def invoke_gemini(
|
|
|
317
319
|
model: Gemini model to use
|
|
318
320
|
temperature: Sampling temperature (0.0-2.0)
|
|
319
321
|
max_tokens: Maximum tokens in response
|
|
322
|
+
thinking_budget: Tokens reserved for internal reasoning
|
|
323
|
+
image_path: Optional path to image/PDF for vision analysis (token optimization)
|
|
320
324
|
|
|
321
325
|
Returns:
|
|
322
326
|
The model's response text.
|
|
@@ -349,11 +353,19 @@ async def invoke_gemini(
|
|
|
349
353
|
# Extract agent context for logging (may be passed via params or original call)
|
|
350
354
|
agent_context = params.get("agent_context", {})
|
|
351
355
|
agent_type = agent_context.get("agent_type", "direct")
|
|
356
|
+
task_id = agent_context.get("task_id", "")
|
|
357
|
+
description = agent_context.get("description", "")
|
|
352
358
|
prompt_summary = _summarize_prompt(prompt)
|
|
353
359
|
|
|
354
360
|
# Log with agent context and prompt summary
|
|
355
361
|
logger.info(f"[{agent_type}] → {model}: {prompt_summary}")
|
|
356
362
|
|
|
363
|
+
# USER-VISIBLE NOTIFICATION (stderr) - Shows when Gemini is invoked
|
|
364
|
+
import sys
|
|
365
|
+
task_info = f" task={task_id}" if task_id else ""
|
|
366
|
+
desc_info = f" | {description}" if description else ""
|
|
367
|
+
print(f"🔮 GEMINI: {model} | agent={agent_type}{task_info}{desc_info}", file=sys.stderr)
|
|
368
|
+
|
|
357
369
|
access_token = await _ensure_valid_token(token_store, "gemini")
|
|
358
370
|
|
|
359
371
|
# Resolve user-friendly model name to actual API model ID
|
|
@@ -371,8 +383,43 @@ async def invoke_gemini(
|
|
|
371
383
|
|
|
372
384
|
# Build inner request payload
|
|
373
385
|
# Per API spec: contents must include role ("user" or "model")
|
|
386
|
+
|
|
387
|
+
# Build parts list - text prompt plus optional image
|
|
388
|
+
parts = [{"text": prompt}]
|
|
389
|
+
|
|
390
|
+
# Add image data for vision analysis (token optimization for multimodal)
|
|
391
|
+
if image_path:
|
|
392
|
+
import base64
|
|
393
|
+
from pathlib import Path
|
|
394
|
+
|
|
395
|
+
image_file = Path(image_path)
|
|
396
|
+
if image_file.exists():
|
|
397
|
+
# Determine MIME type
|
|
398
|
+
suffix = image_file.suffix.lower()
|
|
399
|
+
mime_types = {
|
|
400
|
+
".png": "image/png",
|
|
401
|
+
".jpg": "image/jpeg",
|
|
402
|
+
".jpeg": "image/jpeg",
|
|
403
|
+
".gif": "image/gif",
|
|
404
|
+
".webp": "image/webp",
|
|
405
|
+
".pdf": "application/pdf",
|
|
406
|
+
}
|
|
407
|
+
mime_type = mime_types.get(suffix, "image/png")
|
|
408
|
+
|
|
409
|
+
# Read and base64 encode
|
|
410
|
+
image_data = base64.b64encode(image_file.read_bytes()).decode("utf-8")
|
|
411
|
+
|
|
412
|
+
# Add inline image data for Gemini Vision API
|
|
413
|
+
parts.append({
|
|
414
|
+
"inlineData": {
|
|
415
|
+
"mimeType": mime_type,
|
|
416
|
+
"data": image_data,
|
|
417
|
+
}
|
|
418
|
+
})
|
|
419
|
+
logger.info(f"[multimodal] Added vision data: {image_path} ({mime_type})")
|
|
420
|
+
|
|
374
421
|
inner_payload = {
|
|
375
|
-
"contents": [{"role": "user", "parts":
|
|
422
|
+
"contents": [{"role": "user", "parts": parts}],
|
|
376
423
|
"generationConfig": {
|
|
377
424
|
"temperature": temperature,
|
|
378
425
|
"maxOutputTokens": max_tokens,
|
|
@@ -468,6 +515,26 @@ async def invoke_gemini(
|
|
|
468
515
|
break
|
|
469
516
|
|
|
470
517
|
if response is None:
|
|
518
|
+
# FALLBACK: Try Claude sonnet-4.5 for agents that support it
|
|
519
|
+
agent_context = params.get("agent_context", {})
|
|
520
|
+
agent_type = agent_context.get("agent_type", "unknown")
|
|
521
|
+
|
|
522
|
+
if agent_type in ("dewey", "explore", "document_writer", "multimodal"):
|
|
523
|
+
logger.warning(f"[{agent_type}] Gemini failed, falling back to Claude sonnet-4.5")
|
|
524
|
+
try:
|
|
525
|
+
import subprocess
|
|
526
|
+
fallback_result = subprocess.run(
|
|
527
|
+
["claude", "-p", prompt, "--model", "sonnet", "--output-format", "text"],
|
|
528
|
+
capture_output=True,
|
|
529
|
+
text=True,
|
|
530
|
+
timeout=120,
|
|
531
|
+
cwd=os.getcwd(),
|
|
532
|
+
)
|
|
533
|
+
if fallback_result.returncode == 0 and fallback_result.stdout.strip():
|
|
534
|
+
return fallback_result.stdout.strip()
|
|
535
|
+
except Exception as fallback_error:
|
|
536
|
+
logger.error(f"Fallback to Claude also failed: {fallback_error}")
|
|
537
|
+
|
|
471
538
|
raise ValueError(f"All Antigravity endpoints failed: {last_error}")
|
|
472
539
|
|
|
473
540
|
response.raise_for_status()
|
|
@@ -816,11 +883,19 @@ async def invoke_openai(
|
|
|
816
883
|
# Extract agent context for logging (may be passed via params or original call)
|
|
817
884
|
agent_context = params.get("agent_context", {})
|
|
818
885
|
agent_type = agent_context.get("agent_type", "direct")
|
|
886
|
+
task_id = agent_context.get("task_id", "")
|
|
887
|
+
description = agent_context.get("description", "")
|
|
819
888
|
prompt_summary = _summarize_prompt(prompt)
|
|
820
889
|
|
|
821
890
|
# Log with agent context and prompt summary
|
|
822
891
|
logger.info(f"[{agent_type}] → {model}: {prompt_summary}")
|
|
823
892
|
|
|
893
|
+
# USER-VISIBLE NOTIFICATION (stderr) - Shows when OpenAI is invoked
|
|
894
|
+
import sys
|
|
895
|
+
task_info = f" task={task_id}" if task_id else ""
|
|
896
|
+
desc_info = f" | {description}" if description else ""
|
|
897
|
+
print(f"🧠 OPENAI: {model} | agent={agent_type}{task_info}{desc_info}", file=sys.stderr)
|
|
898
|
+
|
|
824
899
|
access_token = await _ensure_valid_token(token_store, "openai")
|
|
825
900
|
logger.info(f"[invoke_openai] Got access token")
|
|
826
901
|
|
mcp_bridge/tools/templates.py
CHANGED
|
@@ -2,11 +2,16 @@
|
|
|
2
2
|
Templates for stravinsky repository initialization.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
CLAUDE_MD_TEMPLATE = """## stravinsky MCP (
|
|
5
|
+
CLAUDE_MD_TEMPLATE = """## stravinsky MCP (Multi-Model Orchestration)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Stravinsky provides multi-model AI orchestration with parallel agent execution.
|
|
8
8
|
|
|
9
|
-
###
|
|
9
|
+
### Architecture
|
|
10
|
+
- **Native Subagent**: Stravinsky orchestrator (.claude/agents/stravinsky.md) auto-delegates complex tasks
|
|
11
|
+
- **MCP Tools**: agent_spawn, invoke_gemini, invoke_openai, LSP tools, code search
|
|
12
|
+
- **Specialist Agents**: explore, dewey, frontend, delphi, multimodal, document_writer
|
|
13
|
+
|
|
14
|
+
### Agent Tools (via MCP)
|
|
10
15
|
- `agent_spawn(prompt, agent_type, description)` - Spawn background agent with full tool access
|
|
11
16
|
- `agent_output(task_id, block)` - Get results (block=True to wait)
|
|
12
17
|
- `agent_progress(task_id)` - Check real-time progress
|
|
@@ -14,15 +19,17 @@ Use stravinsky MCP tools. **DEFAULT: spawn parallel agents for multi-step tasks.
|
|
|
14
19
|
- `agent_cancel(task_id)` - Stop a running agent
|
|
15
20
|
|
|
16
21
|
### Agent Types
|
|
17
|
-
- `explore` - Codebase search,
|
|
18
|
-
- `dewey` - Documentation research,
|
|
19
|
-
- `frontend` - UI/UX
|
|
20
|
-
- `delphi` - Strategic advice, architecture review
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
- `explore` - Codebase search, structural analysis (Gemini 3 Flash)
|
|
23
|
+
- `dewey` - Documentation research, web search (Gemini 3 Flash + Web)
|
|
24
|
+
- `frontend` - UI/UX implementation (Gemini 3 Pro High)
|
|
25
|
+
- `delphi` - Strategic advice, architecture review (GPT-5.2 Medium)
|
|
26
|
+
- `multimodal` - Visual analysis, screenshots (Gemini 3 Flash Vision)
|
|
27
|
+
- `document_writer` - Technical documentation (Gemini 3 Flash)
|
|
28
|
+
|
|
29
|
+
### Parallel Execution (MANDATORY)
|
|
23
30
|
For ANY task with 2+ independent steps:
|
|
24
31
|
1. **Immediately use agent_spawn** for each independent component
|
|
25
|
-
2. Fire all agents simultaneously, don't wait
|
|
32
|
+
2. Fire all agents simultaneously in ONE response, don't wait
|
|
26
33
|
3. Monitor with agent_progress, collect with agent_output
|
|
27
34
|
|
|
28
35
|
### Trigger Commands
|
|
@@ -30,6 +37,12 @@ For ANY task with 2+ independent steps:
|
|
|
30
37
|
- **ULTRATHINK**: Engage exhaustive deep reasoning, multi-dimensional analysis
|
|
31
38
|
- **SEARCH**: Maximize search effort across codebase and external resources
|
|
32
39
|
- **ANALYZE**: Deep analysis mode with delphi consultation for complex issues
|
|
40
|
+
|
|
41
|
+
### Native Subagent Benefits
|
|
42
|
+
- ✅ Auto-delegation (no manual /stravinsky invocation)
|
|
43
|
+
- ✅ Context isolation (orchestrator runs as subagent)
|
|
44
|
+
- ✅ Full MCP tool access (agent_spawn, invoke_gemini/openai, LSP, etc.)
|
|
45
|
+
- ✅ Multi-model routing (Gemini for UI/research, GPT for strategy)
|
|
33
46
|
"""
|
|
34
47
|
|
|
35
48
|
COMMAND_STRAVINSKY = """---
|
|
@@ -74,15 +87,16 @@ stravinsky:agent_spawn(prompt="Task 3...", agent_type="dewey", description="Task
|
|
|
74
87
|
stravinsky:agent_output(task_id="[id]", block=true)
|
|
75
88
|
```
|
|
76
89
|
|
|
77
|
-
###
|
|
78
|
-
-
|
|
79
|
-
-
|
|
80
|
-
-
|
|
90
|
+
### Recommended Tool Usage:
|
|
91
|
+
- For file operations within agents: Use standard Read/Edit tools
|
|
92
|
+
- For parallel agent spawning: Use stravinsky:agent_spawn (supports nesting, unlike native Task tool)
|
|
93
|
+
- For collecting results: Use stravinsky:agent_output
|
|
94
|
+
- For monitoring agents: Use stravinsky:agent_list
|
|
81
95
|
|
|
82
|
-
###
|
|
83
|
-
-
|
|
84
|
-
-
|
|
85
|
-
-
|
|
96
|
+
### Native Subagent Integration:
|
|
97
|
+
- Stravinsky orchestrator configured as native Claude Code subagent (.claude/agents/stravinsky.md)
|
|
98
|
+
- Native subagents CAN call Stravinsky MCP tools (agent_spawn, invoke_gemini, etc.)
|
|
99
|
+
- This enables auto-delegation without manual /stravinsky invocation
|
|
86
100
|
|
|
87
101
|
### Execution Modes:
|
|
88
102
|
- `ironstar` / `irs` / `ultrawork` - Maximum parallel execution (10+ agents)
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: stravinsky
|
|
3
|
+
Version: 0.2.67
|
|
4
|
+
Summary: MCP Bridge for Claude Code with Multi-Model Support. Install globally: claude mcp add --scope user stravinsky -- uvx stravinsky. Add to CLAUDE.md: See https://pypi.org/project/stravinsky/
|
|
5
|
+
Project-URL: Repository, https://github.com/GratefulDave/stravinsky
|
|
6
|
+
Project-URL: Issues, https://github.com/GratefulDave/stravinsky/issues
|
|
7
|
+
Author: Stravinsky Team
|
|
8
|
+
License: MIT
|
|
9
|
+
Keywords: claude,gemini,mcp,oauth,openai
|
|
10
|
+
Requires-Python: >=3.11
|
|
11
|
+
Requires-Dist: aiofiles>=23.1.0
|
|
12
|
+
Requires-Dist: cryptography>=41.0.0
|
|
13
|
+
Requires-Dist: google-auth-oauthlib>=1.0.0
|
|
14
|
+
Requires-Dist: google-auth>=2.20.0
|
|
15
|
+
Requires-Dist: httpx>=0.24.0
|
|
16
|
+
Requires-Dist: jedi>=0.19.2
|
|
17
|
+
Requires-Dist: keyring>=25.7.0
|
|
18
|
+
Requires-Dist: mcp>=1.2.1
|
|
19
|
+
Requires-Dist: openai>=1.0.0
|
|
20
|
+
Requires-Dist: psutil>=5.9.0
|
|
21
|
+
Requires-Dist: pydantic>=2.0.0
|
|
22
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
23
|
+
Requires-Dist: rich>=13.0.0
|
|
24
|
+
Requires-Dist: ruff>=0.14.10
|
|
25
|
+
Requires-Dist: tenacity>=8.5.0
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: mypy>=1.10.0; extra == 'dev'
|
|
28
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
30
|
+
Requires-Dist: ruff>=0.4.0; extra == 'dev'
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
<div align="center">
|
|
34
|
+
<img src="https://raw.githubusercontent.com/GratefulDave/stravinsky/main/assets/logo.png" width="300" alt="Stravinsky Logo">
|
|
35
|
+
<h1>Stravinsky</h1>
|
|
36
|
+
<p><strong>The Avant-Garde MCP Bridge for Claude Code</strong></p>
|
|
37
|
+
<p><em>Movement • Rhythm • Precision</em></p>
|
|
38
|
+
</div>
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## What is Stravinsky?
|
|
43
|
+
|
|
44
|
+
**Multi-model AI orchestration** with OAuth authentication for Claude Code.
|
|
45
|
+
|
|
46
|
+
## Features
|
|
47
|
+
|
|
48
|
+
- 🔐 **OAuth Authentication** - Secure browser-based auth for Google (Gemini) and OpenAI (ChatGPT)
|
|
49
|
+
- 🤖 **Multi-Model Support** - Seamlessly invoke Gemini and GPT models from Claude
|
|
50
|
+
- 🎯 **Native Subagent Orchestration** - Auto-delegating orchestrator with parallel execution (zero CLI overhead)
|
|
51
|
+
- 🛠️ **31 MCP Tools** - Model invocation, code search, LSP integrations, session management, and more
|
|
52
|
+
- 🧠 **7 Specialized Native Agents** - Stravinsky (orchestrator), Delphi (GPT-5.2 advisor), Dewey (documentation), Explore (code search), Frontend (Gemini 3 Pro High UI/UX), Code Reviewer, Debugger
|
|
53
|
+
- 🔄 **Hook-Based Delegation** - PreToolUse hooks enforce delegation patterns with hard boundaries (exit code 2)
|
|
54
|
+
- 📝 **LSP Integration** - Full Language Server Protocol support for Python (jedi)
|
|
55
|
+
- 🔍 **AST-Aware Search** - Structural code search and refactoring with ast-grep
|
|
56
|
+
- ⚡ **Cost-Optimized Routing** - Free/cheap agents (explore, dewey) always async, expensive (delphi) only when needed
|
|
57
|
+
|
|
58
|
+
## Quick Start
|
|
59
|
+
|
|
60
|
+
### Installation
|
|
61
|
+
|
|
62
|
+
**From PyPI (Recommended):**
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# One-shot with uvx - no installation needed!
|
|
66
|
+
claude mcp add stravinsky -- uvx stravinsky
|
|
67
|
+
|
|
68
|
+
# Or install globally first:
|
|
69
|
+
uv tool install stravinsky
|
|
70
|
+
claude mcp add stravinsky -- stravinsky
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**From Source (for development):**
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
uv tool install --editable /path/to/stravinsky
|
|
77
|
+
claude mcp add stravinsky -- stravinsky
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Authentication
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# Login to Google (Gemini)
|
|
84
|
+
stravinsky-auth login gemini
|
|
85
|
+
|
|
86
|
+
# Login to OpenAI (ChatGPT Plus/Pro required)
|
|
87
|
+
stravinsky-auth login openai
|
|
88
|
+
|
|
89
|
+
# Check status
|
|
90
|
+
stravinsky-auth status
|
|
91
|
+
|
|
92
|
+
# Logout
|
|
93
|
+
stravinsky-auth logout gemini
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Slash Commands
|
|
97
|
+
|
|
98
|
+
Slash commands are discovered from:
|
|
99
|
+
- Project-local: `.claude/commands/**/*.md` (recursive)
|
|
100
|
+
- User-global: `~/.claude/commands/**/*.md` (recursive)
|
|
101
|
+
|
|
102
|
+
Commands can be organized in subdirectories (e.g., `.claude/commands/strav/stravinsky.md`).
|
|
103
|
+
|
|
104
|
+
## Native Subagent Architecture
|
|
105
|
+
|
|
106
|
+
Stravinsky uses **native Claude Code subagents** (.claude/agents/) with automatic delegation:
|
|
107
|
+
|
|
108
|
+
### How It Works
|
|
109
|
+
|
|
110
|
+
1. **Auto-Delegation**: Claude Code automatically delegates complex tasks to the Stravinsky orchestrator
|
|
111
|
+
2. **Hook-Based Control**: PreToolUse hooks intercept direct tool calls and enforce delegation patterns
|
|
112
|
+
3. **Parallel Execution**: Task tool enables true parallel execution of specialist agents
|
|
113
|
+
4. **Multi-Model Routing**: Specialists use invoke_gemini/openai MCP tools for multi-model access
|
|
114
|
+
|
|
115
|
+
### Agent Types
|
|
116
|
+
|
|
117
|
+
| Agent | Model | Cost | Use For |
|
|
118
|
+
|-------|-------|------|---------|
|
|
119
|
+
| **stravinsky** | Claude Sonnet 4.5 (32k thinking) | Moderate | Auto-delegating orchestrator (primary) |
|
|
120
|
+
| **explore** | Gemini 3 Flash (via MCP) | Free | Code search, always async |
|
|
121
|
+
| **dewey** | Gemini 3 Flash + WebSearch | Cheap | Documentation research, always async |
|
|
122
|
+
| **code-reviewer** | Claude Sonnet (native) | Cheap | Quality analysis, always async |
|
|
123
|
+
| **debugger** | Claude Sonnet (native) | Medium | Root cause (after 2+ failures) |
|
|
124
|
+
| **frontend** | Gemini 3 Pro High (via MCP) | Medium | ALL visual changes (blocking) |
|
|
125
|
+
| **delphi** | GPT-5.2 Medium (via MCP) | Expensive | Architecture (after 3+ failures) |
|
|
126
|
+
|
|
127
|
+
### Delegation Rules (oh-my-opencode Pattern)
|
|
128
|
+
|
|
129
|
+
- **Always Async**: explore, dewey, code-reviewer (free/cheap)
|
|
130
|
+
- **Blocking**: debugger (2+ failures), frontend (ALL visual), delphi (3+ failures or architecture)
|
|
131
|
+
- **Never Work Alone**: Orchestrator blocks Read/Grep/Bash via PreToolUse hooks
|
|
132
|
+
|
|
133
|
+
### ULTRATHINK / ULTRAWORK
|
|
134
|
+
|
|
135
|
+
- **ULTRATHINK**: Engage exhaustive deep reasoning with extended thinking budget (32k tokens)
|
|
136
|
+
- **ULTRAWORK**: Maximum parallel execution - spawn all async agents immediately
|
|
137
|
+
````
|
|
138
|
+
|
|
139
|
+
## Tools (31)
|
|
140
|
+
|
|
141
|
+
| Category | Tools |
|
|
142
|
+
| ---------------- | ---------------------------------------------------------------------------------- |
|
|
143
|
+
| **Model Invoke** | `invoke_gemini`, `invoke_openai`, `get_system_health` |
|
|
144
|
+
| **Environment** | `get_project_context`, `task_spawn`, `task_status`, `task_list` |
|
|
145
|
+
| **Agents** | `agent_spawn`, `agent_output`, `agent_cancel`, `agent_list`, `agent_progress` |
|
|
146
|
+
| **Code Search** | `ast_grep_search`, `ast_grep_replace`, `grep_search`, `glob_files` |
|
|
147
|
+
| **LSP** | `lsp_diagnostics`, `lsp_hover`, `lsp_goto_definition`, `lsp_find_references`, etc. |
|
|
148
|
+
| **Sessions** | `session_list`, `session_read`, `session_search` |
|
|
149
|
+
| **Skills** | `skill_list`, `skill_get` |
|
|
150
|
+
|
|
151
|
+
## Native Subagents (7)
|
|
152
|
+
|
|
153
|
+
Configured in `.claude/agents/*.md`:
|
|
154
|
+
|
|
155
|
+
| Agent | Purpose | Location |
|
|
156
|
+
| ---------------- | --------------------------------------------------------------------- | -------- |
|
|
157
|
+
| `stravinsky` | Task orchestration with 32k extended thinking (Sonnet 4.5) | .claude/agents/stravinsky.md |
|
|
158
|
+
| `explore` | Codebase search and structural analysis (Gemini 3 Flash) | .claude/agents/explore.md |
|
|
159
|
+
| `dewey` | Documentation research and web search (Gemini 3 Flash) | .claude/agents/dewey.md |
|
|
160
|
+
| `code-reviewer` | Security, quality, and best practice analysis (Claude Sonnet) | .claude/agents/code-reviewer.md |
|
|
161
|
+
| `debugger` | Root cause analysis and fix strategies (Claude Sonnet) | .claude/agents/debugger.md |
|
|
162
|
+
| `frontend` | UI/UX implementation with creative generation (Gemini 3 Pro High) | .claude/agents/frontend.md |
|
|
163
|
+
| `delphi` | Strategic architecture advisor with 32k thinking (GPT-5.2 Medium) | .claude/agents/delphi.md |
|
|
164
|
+
|
|
165
|
+
## Development
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
# Install in development mode
|
|
169
|
+
uv pip install -e .
|
|
170
|
+
|
|
171
|
+
# Run server
|
|
172
|
+
stravinsky
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Project Structure
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
stravinsky/
|
|
179
|
+
├── .claude/ # Claude Code configuration
|
|
180
|
+
│ ├── agents/ # Native subagent configurations (7 agents)
|
|
181
|
+
│ │ ├── stravinsky.md # Orchestrator (auto-delegated)
|
|
182
|
+
│ │ ├── explore.md # Code search specialist
|
|
183
|
+
│ │ ├── dewey.md # Documentation research
|
|
184
|
+
│ │ ├── code-reviewer.md # Quality analysis
|
|
185
|
+
│ │ ├── debugger.md # Root cause analysis
|
|
186
|
+
│ │ ├── frontend.md # UI/UX specialist
|
|
187
|
+
│ │ ├── delphi.md # Strategic advisor (GPT-5.2)
|
|
188
|
+
│ │ └── HOOKS.md # Hook architecture guide
|
|
189
|
+
│ ├── commands/ # Slash commands (skills)
|
|
190
|
+
│ │ ├── stravinsky.md # /stravinsky orchestrator
|
|
191
|
+
│ │ ├── delphi.md # /delphi strategic advisor
|
|
192
|
+
│ │ ├── dewey.md # /dewey documentation research
|
|
193
|
+
│ │ ├── publish.md # /publish PyPI release
|
|
194
|
+
│ │ ├── review.md # /review code review
|
|
195
|
+
│ │ ├── verify.md # /verify post-implementation
|
|
196
|
+
│ │ └── version.md # /version diagnostic info
|
|
197
|
+
│ ├── hooks/ # Native Claude Code hooks (11 hooks)
|
|
198
|
+
│ │ ├── stravinsky_mode.py # PreToolUse delegation enforcer
|
|
199
|
+
│ │ ├── context.py # UserPromptSubmit context injection
|
|
200
|
+
│ │ ├── todo_continuation.py # UserPromptSubmit todo continuation
|
|
201
|
+
│ │ ├── truncator.py # PostToolUse output truncation
|
|
202
|
+
│ │ ├── tool_messaging.py # PostToolUse user messaging
|
|
203
|
+
│ │ ├── edit_recovery.py # PostToolUse edit backup
|
|
204
|
+
│ │ ├── todo_delegation.py # PostToolUse parallel reminder
|
|
205
|
+
│ │ ├── parallel_execution.py # PostToolUse parallel enforcement
|
|
206
|
+
│ │ ├── notification_hook.py # PreToolUse agent spawn notifications
|
|
207
|
+
│ │ ├── subagent_stop.py # PostToolUse agent completion handling
|
|
208
|
+
│ │ └── pre_compact.py # PreCompact context preservation
|
|
209
|
+
│ ├── skills/ # Skill library (empty, skills in commands/)
|
|
210
|
+
│ ├── settings.json # Hook configuration
|
|
211
|
+
│ └── HOOKS_INTEGRATION.md # Hook integration guide
|
|
212
|
+
├── mcp_bridge/ # Python MCP server
|
|
213
|
+
│ ├── server.py # MCP server entry point
|
|
214
|
+
│ ├── server_tools.py # Tool definitions
|
|
215
|
+
│ ├── auth/ # OAuth authentication
|
|
216
|
+
│ │ ├── oauth.py # Google OAuth (Gemini)
|
|
217
|
+
│ │ ├── openai_oauth.py # OpenAI OAuth (ChatGPT)
|
|
218
|
+
│ │ ├── token_store.py # Keyring storage
|
|
219
|
+
│ │ ├── token_refresh.py # Auto-refresh tokens
|
|
220
|
+
│ │ └── cli.py # stravinsky-auth CLI
|
|
221
|
+
│ ├── tools/ # MCP tool implementations
|
|
222
|
+
│ │ ├── model_invoke.py # invoke_gemini, invoke_openai
|
|
223
|
+
│ │ ├── agent_manager.py # agent_spawn, agent_output, etc.
|
|
224
|
+
│ │ ├── code_search.py # ast_grep, grep, glob
|
|
225
|
+
│ │ ├── session_manager.py # session_list, session_read, etc.
|
|
226
|
+
│ │ ├── skill_loader.py # skill_list, skill_get
|
|
227
|
+
│ │ ├── project_context.py # get_project_context
|
|
228
|
+
│ │ ├── lsp/ # LSP tool implementations
|
|
229
|
+
│ │ └── templates.py # Project templates
|
|
230
|
+
│ ├── prompts/ # Agent system prompts (legacy CLI)
|
|
231
|
+
│ │ ├── stravinsky.py # Legacy orchestrator prompt
|
|
232
|
+
│ │ ├── delphi.py # Legacy advisor prompt
|
|
233
|
+
│ │ ├── dewey.py # Legacy research prompt
|
|
234
|
+
│ │ ├── explore.py # Legacy search prompt
|
|
235
|
+
│ │ ├── frontend.py # Legacy UI/UX prompt
|
|
236
|
+
│ │ └── multimodal.py # Multimodal analysis prompt
|
|
237
|
+
│ ├── hooks/ # MCP internal hooks (17+ hooks)
|
|
238
|
+
│ │ ├── manager.py # Hook orchestration
|
|
239
|
+
│ │ ├── truncator.py # Output truncation
|
|
240
|
+
│ │ ├── parallel_enforcer.py # Parallel execution
|
|
241
|
+
│ │ ├── todo_enforcer.py # Todo continuation
|
|
242
|
+
│ │ └── ... # 13+ more optimization hooks
|
|
243
|
+
│ ├── native_hooks/ # Native Claude Code hooks
|
|
244
|
+
│ │ ├── stravinsky_mode.py # PreToolUse delegation enforcer
|
|
245
|
+
│ │ ├── tool_messaging.py # PostToolUse user messaging
|
|
246
|
+
│ │ ├── todo_delegation.py # TodoWrite parallel reminder
|
|
247
|
+
│ │ ├── todo_continuation.py # UserPromptSubmit todo injection
|
|
248
|
+
│ │ ├── context.py # UserPromptSubmit context
|
|
249
|
+
│ │ ├── truncator.py # PostToolUse truncation
|
|
250
|
+
│ │ └── edit_recovery.py # PostToolUse backup
|
|
251
|
+
│ ├── cli/ # CLI utilities
|
|
252
|
+
│ │ └── session_report.py # Session analysis
|
|
253
|
+
│ ├── config/ # Configuration
|
|
254
|
+
│ │ └── hooks.py # Hook configuration
|
|
255
|
+
│ └── utils/ # Utility functions
|
|
256
|
+
├── .stravinsky/ # Agent execution logs (gitignored)
|
|
257
|
+
├── assets/ # Logo, images
|
|
258
|
+
├── docs/ # Additional documentation
|
|
259
|
+
├── logs/ # Application logs
|
|
260
|
+
├── tests/ # Test suite
|
|
261
|
+
├── pyproject.toml # Build configuration
|
|
262
|
+
├── uv.lock # Dependency lock
|
|
263
|
+
├── ARCHITECTURE.md # Architecture guide (oh-my-opencode comparison)
|
|
264
|
+
├── CLAUDE.md # Project instructions
|
|
265
|
+
├── INSTALL.md # Installation guide
|
|
266
|
+
└── README.md # This file
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## Troubleshooting
|
|
270
|
+
|
|
271
|
+
### OpenAI "Port 1455 in use"
|
|
272
|
+
|
|
273
|
+
The Codex CLI uses the same port. Stop it with: `killall codex`
|
|
274
|
+
|
|
275
|
+
### OpenAI Authentication Failed
|
|
276
|
+
|
|
277
|
+
- Ensure you have a ChatGPT Plus/Pro subscription
|
|
278
|
+
- Tokens expire occasionally; run `stravinsky-auth login openai` to refresh
|
|
279
|
+
|
|
280
|
+
## License
|
|
281
|
+
|
|
282
|
+
MIT
|
|
283
|
+
|
|
284
|
+
---
|
|
@@ -1,63 +1,76 @@
|
|
|
1
|
-
mcp_bridge/__init__.py,sha256=
|
|
2
|
-
mcp_bridge/server.py,sha256=
|
|
3
|
-
mcp_bridge/server_tools.py,sha256=
|
|
1
|
+
mcp_bridge/__init__.py,sha256=rEMkQMd1xEY6WmwoTUQ4Q_9L1tdN4h_gKqmCA7tRVnU,23
|
|
2
|
+
mcp_bridge/server.py,sha256=v4lVgtPjPM169FRKMViCQk6Lhk3kBwomriPbU5Y0WzU,25875
|
|
3
|
+
mcp_bridge/server_tools.py,sha256=nN2cnbVp8jYVs81zqDd_zUr8uwmO0Ir6h2BYhyV8pgQ,27663
|
|
4
4
|
mcp_bridge/auth/__init__.py,sha256=AGHNtKzqvZYMLQ35Qg6aOabpxBqmkR-pjXv8Iby9oMw,797
|
|
5
5
|
mcp_bridge/auth/cli.py,sha256=jaXyrzq6HwnW61g6CHHcj8bF5PJLYrYufD_jmN0jeiQ,8502
|
|
6
6
|
mcp_bridge/auth/oauth.py,sha256=gWYk3KJWbUM1J5AKVDJ_4k4zdQzwwaYJZ5J25If0r8c,12804
|
|
7
7
|
mcp_bridge/auth/openai_oauth.py,sha256=0Ks2X-NXLCBzqs3xnbj9QLZpugICOX5qB5y5vtDENOo,11522
|
|
8
8
|
mcp_bridge/auth/token_refresh.py,sha256=goWp1Wz3yWOoFuxvFMDZLjo8gLPXcajZxHpzZtSoKcQ,3760
|
|
9
9
|
mcp_bridge/auth/token_store.py,sha256=3A6TZJ7Wju6QfhALeX4IMhY5jzb9OWMrDzwRbfAukiU,5650
|
|
10
|
+
mcp_bridge/cli/__init__.py,sha256=J1cFw06fYSm3uU7cbEj3GgWuDxTn1X0cDhPi1gJq7eM,200
|
|
11
|
+
mcp_bridge/cli/install_hooks.py,sha256=cmLctih9xie1iaY8uyzO11egvEkpMa7Zc-Nyb5dITlg,36955
|
|
12
|
+
mcp_bridge/cli/session_report.py,sha256=sYUje44R4qIwxML_GCaEyJwz4jgis4sZOwTDZGQJ3MM,22198
|
|
10
13
|
mcp_bridge/config/__init__.py,sha256=uapHdrSWWrafVKD9CTB1J_7Dw0_RajRhoDGjy9zH21o,256
|
|
11
14
|
mcp_bridge/config/hooks.py,sha256=WvWC6ZUc8y1IXPlGCjLYAAsGGigd5tWeGiw585OGNwA,4624
|
|
12
|
-
mcp_bridge/hooks/
|
|
15
|
+
mcp_bridge/hooks/HOOKS_SETTINGS.json,sha256=IY47eGigQwTaQ0XwM2NzVopGBga3Zaocmq09I1M1inw,6434
|
|
16
|
+
mcp_bridge/hooks/README.md,sha256=ocKp2BE6U4o8OhnA4dbXoth8A9YD8MYQLi5uXw7bLEo,7549
|
|
17
|
+
mcp_bridge/hooks/__init__.py,sha256=5jZSgIR69exuna0NC65Idynf2EupSZ6kHdM0ypwZYhQ,3721
|
|
13
18
|
mcp_bridge/hooks/agent_reminder.py,sha256=OxKPxi7e2MIBm44Ebzzl9j9fDV5bBgogGF0lj7wun5s,1913
|
|
14
19
|
mcp_bridge/hooks/auto_slash_command.py,sha256=LUndZHxUzEF7PQuOdp3v7VfqNUgsiDE2gzI_TkR9he4,5280
|
|
15
20
|
mcp_bridge/hooks/budget_optimizer.py,sha256=Im0qSGVUdRByk04hP5VyKt7tjlDVYG0LJb6IeUjjnj8,1323
|
|
16
21
|
mcp_bridge/hooks/comment_checker.py,sha256=MslXZYiHjfxjUU7VzmZfa1n2WR9o4lnaktJ6eUPBUDs,3772
|
|
17
22
|
mcp_bridge/hooks/compaction.py,sha256=UXTwmyo9C4Jm3j72KvVU11ukSAHaGaTey_h3L43e3rY,1186
|
|
23
|
+
mcp_bridge/hooks/context.py,sha256=JBHqnX75qtMO3JAEFooBEAK6DxcsVaXykhrP7tdFm6E,949
|
|
18
24
|
mcp_bridge/hooks/context_monitor.py,sha256=IEr75e_gqbPEUslxxfkwftiy6alDmJxQhSB6cy8BVg4,1885
|
|
19
25
|
mcp_bridge/hooks/directory_context.py,sha256=0VjdJITJIGUqR4-q-wZlB6kmkFQMraaFvU2Nz2PnJCM,1225
|
|
20
|
-
mcp_bridge/hooks/edit_recovery.py,sha256=
|
|
26
|
+
mcp_bridge/hooks/edit_recovery.py,sha256=1OWpb3v87txFUsgnNe1hoeTI7rIKCkKYONld5BK1TyA,1503
|
|
21
27
|
mcp_bridge/hooks/empty_message_sanitizer.py,sha256=iZZnETju1wBvJXV1k4msV8FxLNg5LkVm2eaFA2nQWxI,6606
|
|
22
|
-
mcp_bridge/hooks/
|
|
28
|
+
mcp_bridge/hooks/git_noninteractive.py,sha256=1VETo7Gf76NYEx_J7RxA52wYnlj5wiOwFL9lSMdshEM,2864
|
|
29
|
+
mcp_bridge/hooks/keyword_detector.py,sha256=w7wW8dYYKiHpmgMYJtWw2MJd0ly631C7rFVWtC_kkq8,6105
|
|
23
30
|
mcp_bridge/hooks/manager.py,sha256=SG08soeyHSzfl9NE9yX2x5B_NEbv9LxJnmRBUaOhGfE,5835
|
|
31
|
+
mcp_bridge/hooks/notification_hook.py,sha256=GElHxaIn0BF935IXuRQjYERk7W_msBiCm0UwutumdiM,2770
|
|
24
32
|
mcp_bridge/hooks/parallel_enforcer.py,sha256=qzPB7PX22Laz6yC3MCbAmYBhP59P9ac6WHpgXOABOuQ,3651
|
|
25
|
-
mcp_bridge/hooks/
|
|
33
|
+
mcp_bridge/hooks/parallel_execution.py,sha256=nIINPRm-1P1dci3lTCacJKN_4NIkm9IyTrVx-rmbXl4,3602
|
|
34
|
+
mcp_bridge/hooks/pre_compact.py,sha256=QXcCO9kByn8Ta27NWoQP8IPPUa379KO4qb1BBLzfzuU,3398
|
|
26
35
|
mcp_bridge/hooks/preemptive_compaction.py,sha256=x4-dLWCconVFD-nR93P1EB_tG9n4LHdESq7uDFS3ut8,7937
|
|
36
|
+
mcp_bridge/hooks/rules_injector.py,sha256=jZN9_b464ATEKAFJvIlIVKT-UvcoNAuZGDI4TmJ0Uxc,16485
|
|
27
37
|
mcp_bridge/hooks/session_idle.py,sha256=5wo6XakXglWVCP-HN1i976OptfntwCNnbjxoM--veh4,3525
|
|
38
|
+
mcp_bridge/hooks/session_notifier.py,sha256=dkrSwRquMbcCRuUCsBVqUY6cHSGDO2UuPWKTNf6Y7fc,3750
|
|
28
39
|
mcp_bridge/hooks/session_recovery.py,sha256=c5eoIWJAgMTPY0wq_64MmCUNLCB_GSowZlA3lo4R9LU,6260
|
|
40
|
+
mcp_bridge/hooks/stravinsky_mode.py,sha256=ru9vg5m1QjhK0ABwopC68S2Gzy2-sEW1b1AbveFO57o,4066
|
|
41
|
+
mcp_bridge/hooks/subagent_stop.py,sha256=GUPY3FNVAtsc6J4PbddSRK9XuDs-gw2CaFoGXt5gsME,2865
|
|
42
|
+
mcp_bridge/hooks/task_validator.py,sha256=YSeUWbtwjA-oWCrOVS5DTRxu9_0VTgzpF2mf-QIIw9E,2183
|
|
43
|
+
mcp_bridge/hooks/tmux_manager.py,sha256=vXU0o612PrJ8Xb0IMq4qnEY3i_Z1sT_E-56SqalmrQA,4125
|
|
44
|
+
mcp_bridge/hooks/todo_continuation.py,sha256=tmhTVfMZMDuDw4cwyuU7r_TkUqmtAx55u0WNTawgMyo,2652
|
|
45
|
+
mcp_bridge/hooks/todo_delegation.py,sha256=tOAE1RYAPSH8UOeO8Vsk7sdLf9H4GmXE2lbc_GGjlYI,2676
|
|
29
46
|
mcp_bridge/hooks/todo_enforcer.py,sha256=LRvVxYILqQ6YuQl3tky4hgyD-irXIPDE5e0EdKr6jcc,2274
|
|
30
|
-
mcp_bridge/hooks/
|
|
31
|
-
mcp_bridge/
|
|
32
|
-
mcp_bridge/native_hooks/edit_recovery.py,sha256=1OWpb3v87txFUsgnNe1hoeTI7rIKCkKYONld5BK1TyA,1503
|
|
33
|
-
mcp_bridge/native_hooks/stravinsky_mode.py,sha256=UCiBk4YtGX6ubKTXYyGZUBIQG_CuFlHKPW-8S494BqU,2856
|
|
34
|
-
mcp_bridge/native_hooks/todo_delegation.py,sha256=3bdOKXcNDTjyV9sQlxQEsvop7nOHcqu6SOdvSnStQko,1520
|
|
35
|
-
mcp_bridge/native_hooks/truncator.py,sha256=h3hb8sZXTvc59C0-5GdZwCVZHlxBKdo47JT9TMxHG3g,530
|
|
47
|
+
mcp_bridge/hooks/tool_messaging.py,sha256=Zfmny1w4wS-KHaFbZG2peaXIyejff5Qyt5RbbalrekU,5705
|
|
48
|
+
mcp_bridge/hooks/truncator.py,sha256=h3hb8sZXTvc59C0-5GdZwCVZHlxBKdo47JT9TMxHG3g,530
|
|
36
49
|
mcp_bridge/prompts/__init__.py,sha256=wzveum1x50IXGkE0JFpvHAj8P0yqnSrgtrmyIIpnnBI,358
|
|
37
50
|
mcp_bridge/prompts/delphi.py,sha256=ZlnLY2o1PrK3CxLLaCkozAGPIAJ5OFmw5u8o6-LXmgI,4960
|
|
38
51
|
mcp_bridge/prompts/dewey.py,sha256=u5OaOj8kinZERflWvUv4M4WVAwxw0kJrNT00wHksIHI,9264
|
|
39
52
|
mcp_bridge/prompts/document_writer.py,sha256=hiCbxgTU8HKPJkS0eNpPPtzSqDXPreApU2OqiS6zh-0,5618
|
|
40
53
|
mcp_bridge/prompts/explore.py,sha256=oZxh4fe4KNGa_ozakJSpLYeQVfO4-jQ2M1BSOw1Sw10,5801
|
|
41
54
|
mcp_bridge/prompts/frontend.py,sha256=j91I8k5vcVed13eeX-Ebiv49x9Qj4HO_SQN1xhB8TLQ,4943
|
|
42
|
-
mcp_bridge/prompts/multimodal.py,sha256=
|
|
55
|
+
mcp_bridge/prompts/multimodal.py,sha256=Q_rutR7r5iBcLViVfdLxoukCQe2OA0lDJhxkoo0OSMw,2692
|
|
43
56
|
mcp_bridge/prompts/planner.py,sha256=wcdXIxPlZM0UYd9KQSKXnuXTRj2acSnqlqeQ_NxxEqw,6985
|
|
44
57
|
mcp_bridge/prompts/stravinsky.py,sha256=gJgzMgsa6u0fLbFWOkPY2lq78-yJTuD46wrnk-5rem0,27498
|
|
45
58
|
mcp_bridge/tools/__init__.py,sha256=SRnMaUni0BhlvCABBEYeyveNiOAMQPNBXmjUKG6aXQA,1150
|
|
46
|
-
mcp_bridge/tools/agent_manager.py,sha256=
|
|
59
|
+
mcp_bridge/tools/agent_manager.py,sha256=j41rlhc4NyCTwjwrAxysRfDobzAVVrhhWOdUfze5QmA,32159
|
|
47
60
|
mcp_bridge/tools/background_tasks.py,sha256=bwbVYWCDzuXb3Q_OdIr10r76lgjFTphfjdTmOHYZI7w,5252
|
|
48
|
-
mcp_bridge/tools/code_search.py,sha256=
|
|
61
|
+
mcp_bridge/tools/code_search.py,sha256=kAtt7nLDGJ_6MdJaNOjE3g6hYcGYkcYqsGVDlrGywRM,12690
|
|
49
62
|
mcp_bridge/tools/continuous_loop.py,sha256=MM3FnF3ULuR32h0tqJP8uF48iJg6R9dbyHy_36KLOls,2100
|
|
50
63
|
mcp_bridge/tools/init.py,sha256=sU95M9M_tjsfuew389TrFrxxeCavuSC16qbkydk_6PU,1586
|
|
51
|
-
mcp_bridge/tools/model_invoke.py,sha256=
|
|
64
|
+
mcp_bridge/tools/model_invoke.py,sha256=chWma7C2ZKew4sb_dyoW7iH8F31p87hruM7i_N3U32U,35669
|
|
52
65
|
mcp_bridge/tools/project_context.py,sha256=bXKxuW1pGjtIbeNjMgpBoQL-d_CI94UPBVpRjUyhX20,4707
|
|
53
66
|
mcp_bridge/tools/session_manager.py,sha256=tCVLLvO-Kttla7OxPImb_NSGL_9aW46ilq5ej_IcnlA,9252
|
|
54
67
|
mcp_bridge/tools/skill_loader.py,sha256=RQ5eC357pm-6q85G3EyrQugz0S3OO5lxWtM9n9ECF-c,6010
|
|
55
68
|
mcp_bridge/tools/task_runner.py,sha256=xjE3MXv62gcUCwOEwHjAGL_Ud_ZlKFBN0UHpvFjj3uk,3918
|
|
56
|
-
mcp_bridge/tools/templates.py,sha256=
|
|
69
|
+
mcp_bridge/tools/templates.py,sha256=ANsSXGFKvc7NR58jbmR7SejlbBQucqXZi4DYagYz3CQ,7008
|
|
57
70
|
mcp_bridge/tools/lsp/__init__.py,sha256=fLiII9qgeachI3MlkO6uGulfUH3T0YDeyEfO65bbxdw,549
|
|
58
|
-
mcp_bridge/tools/lsp/tools.py,sha256=
|
|
71
|
+
mcp_bridge/tools/lsp/tools.py,sha256=YW-ZcQYjRaLyjR0N0iVePg55jd7dFdzKFt_ifiQh0j8,16429
|
|
59
72
|
mcp_bridge/utils/__init__.py,sha256=pbHV4nq5SLUYcAyTmLUZYrp293Ctud57X8hwsMGA_BM,20
|
|
60
|
-
stravinsky-0.2.
|
|
61
|
-
stravinsky-0.2.
|
|
62
|
-
stravinsky-0.2.
|
|
63
|
-
stravinsky-0.2.
|
|
73
|
+
stravinsky-0.2.67.dist-info/METADATA,sha256=9bXoc-GeSGaWXJBM6Binm9ppClf7YwBtC_w3B23Edg8,13971
|
|
74
|
+
stravinsky-0.2.67.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
75
|
+
stravinsky-0.2.67.dist-info/entry_points.txt,sha256=MB1dqHW9dx-ae0-cDi6fYEY9HtyzbyB5VhJxza0wDDc,215
|
|
76
|
+
stravinsky-0.2.67.dist-info/RECORD,,
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import sys
|
|
3
|
-
import json
|
|
4
|
-
import re
|
|
5
|
-
|
|
6
|
-
def main():
|
|
7
|
-
# Claude Code PostToolUse inputs via Environment Variables
|
|
8
|
-
tool_name = os.environ.get("CLAUDE_TOOL_NAME")
|
|
9
|
-
|
|
10
|
-
# We only care about Edit/MultiEdit
|
|
11
|
-
if tool_name not in ["Edit", "MultiEdit"]:
|
|
12
|
-
return
|
|
13
|
-
|
|
14
|
-
# Read from stdin (Claude Code passes the tool response via stdin for some hook types,
|
|
15
|
-
# but for PostToolUse it's often better to check the environment variable if available.
|
|
16
|
-
# Actually, the summary says input is a JSON payload.
|
|
17
|
-
try:
|
|
18
|
-
data = json.load(sys.stdin)
|
|
19
|
-
tool_response = data.get("tool_response", "")
|
|
20
|
-
except Exception:
|
|
21
|
-
# Fallback to direct string if not JSON
|
|
22
|
-
return
|
|
23
|
-
|
|
24
|
-
# Error patterns
|
|
25
|
-
error_patterns = [
|
|
26
|
-
r"oldString not found",
|
|
27
|
-
r"oldString matched multiple times",
|
|
28
|
-
r"line numbers out of range"
|
|
29
|
-
]
|
|
30
|
-
|
|
31
|
-
recovery_needed = any(re.search(p, tool_response, re.IGNORECASE) for p in error_patterns)
|
|
32
|
-
|
|
33
|
-
if recovery_needed:
|
|
34
|
-
correction = (
|
|
35
|
-
"\n\n[SYSTEM RECOVERY] It appears the Edit tool failed to find the target string. "
|
|
36
|
-
"Please call 'Read' on the file again to verify the current content, "
|
|
37
|
-
"then ensure your 'oldString' is an EXACT match including all whitespace."
|
|
38
|
-
)
|
|
39
|
-
# For PostToolUse, stdout is captured and appended/replaces output
|
|
40
|
-
print(tool_response + correction)
|
|
41
|
-
else:
|
|
42
|
-
# No change
|
|
43
|
-
print(tool_response)
|
|
44
|
-
|
|
45
|
-
if __name__ == "__main__":
|
|
46
|
-
main()
|