stravinsky 0.2.52__py3-none-any.whl → 0.4.18__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.

Files changed (58) hide show
  1. mcp_bridge/__init__.py +1 -1
  2. mcp_bridge/auth/token_store.py +113 -11
  3. mcp_bridge/cli/__init__.py +6 -0
  4. mcp_bridge/cli/install_hooks.py +1265 -0
  5. mcp_bridge/cli/session_report.py +585 -0
  6. mcp_bridge/config/MANIFEST_SCHEMA.md +305 -0
  7. mcp_bridge/config/README.md +276 -0
  8. mcp_bridge/config/hook_config.py +249 -0
  9. mcp_bridge/config/hooks_manifest.json +138 -0
  10. mcp_bridge/config/rate_limits.py +222 -0
  11. mcp_bridge/config/skills_manifest.json +128 -0
  12. mcp_bridge/hooks/HOOKS_SETTINGS.json +175 -0
  13. mcp_bridge/hooks/README.md +215 -0
  14. mcp_bridge/hooks/__init__.py +119 -60
  15. mcp_bridge/hooks/edit_recovery.py +42 -37
  16. mcp_bridge/hooks/git_noninteractive.py +89 -0
  17. mcp_bridge/hooks/keyword_detector.py +30 -0
  18. mcp_bridge/hooks/manager.py +8 -0
  19. mcp_bridge/hooks/notification_hook.py +103 -0
  20. mcp_bridge/hooks/parallel_execution.py +111 -0
  21. mcp_bridge/hooks/pre_compact.py +82 -183
  22. mcp_bridge/hooks/rules_injector.py +507 -0
  23. mcp_bridge/hooks/session_notifier.py +125 -0
  24. mcp_bridge/{native_hooks → hooks}/stravinsky_mode.py +51 -16
  25. mcp_bridge/hooks/subagent_stop.py +98 -0
  26. mcp_bridge/hooks/task_validator.py +73 -0
  27. mcp_bridge/hooks/tmux_manager.py +141 -0
  28. mcp_bridge/hooks/todo_continuation.py +90 -0
  29. mcp_bridge/hooks/todo_delegation.py +88 -0
  30. mcp_bridge/hooks/tool_messaging.py +267 -0
  31. mcp_bridge/hooks/truncator.py +21 -17
  32. mcp_bridge/notifications.py +151 -0
  33. mcp_bridge/prompts/multimodal.py +24 -3
  34. mcp_bridge/server.py +214 -49
  35. mcp_bridge/server_tools.py +445 -0
  36. mcp_bridge/tools/__init__.py +22 -18
  37. mcp_bridge/tools/agent_manager.py +220 -32
  38. mcp_bridge/tools/code_search.py +97 -11
  39. mcp_bridge/tools/lsp/__init__.py +7 -0
  40. mcp_bridge/tools/lsp/manager.py +448 -0
  41. mcp_bridge/tools/lsp/tools.py +637 -150
  42. mcp_bridge/tools/model_invoke.py +208 -106
  43. mcp_bridge/tools/query_classifier.py +323 -0
  44. mcp_bridge/tools/semantic_search.py +3042 -0
  45. mcp_bridge/tools/templates.py +32 -18
  46. mcp_bridge/update_manager.py +589 -0
  47. mcp_bridge/update_manager_pypi.py +299 -0
  48. stravinsky-0.4.18.dist-info/METADATA +468 -0
  49. stravinsky-0.4.18.dist-info/RECORD +88 -0
  50. stravinsky-0.4.18.dist-info/entry_points.txt +5 -0
  51. mcp_bridge/native_hooks/edit_recovery.py +0 -46
  52. mcp_bridge/native_hooks/todo_delegation.py +0 -54
  53. mcp_bridge/native_hooks/truncator.py +0 -23
  54. stravinsky-0.2.52.dist-info/METADATA +0 -204
  55. stravinsky-0.2.52.dist-info/RECORD +0 -63
  56. stravinsky-0.2.52.dist-info/entry_points.txt +0 -3
  57. /mcp_bridge/{native_hooks → hooks}/context.py +0 -0
  58. {stravinsky-0.2.52.dist-info → stravinsky-0.4.18.dist-info}/WHEEL +0 -0
@@ -0,0 +1,468 @@
1
+ Metadata-Version: 2.4
2
+ Name: stravinsky
3
+ Version: 0.4.18
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.14,>=3.11
11
+ Requires-Dist: aiofiles>=23.1.0
12
+ Requires-Dist: chromadb>=0.6.0
13
+ Requires-Dist: cryptography>=41.0.0
14
+ Requires-Dist: google-auth-oauthlib>=1.0.0
15
+ Requires-Dist: google-auth>=2.20.0
16
+ Requires-Dist: httpx>=0.24.0
17
+ Requires-Dist: jedi-language-server>=0.41.0
18
+ Requires-Dist: jedi>=0.19.2
19
+ Requires-Dist: keyring>=25.7.0
20
+ Requires-Dist: lsprotocol>=2023.0.0
21
+ Requires-Dist: mcp>=1.2.1
22
+ Requires-Dist: ollama>=0.6.1
23
+ Requires-Dist: openai>=1.0.0
24
+ Requires-Dist: pathspec>=0.12.0
25
+ Requires-Dist: plyer>=2.1.0
26
+ Requires-Dist: psutil>=5.9.0
27
+ Requires-Dist: pydantic>=2.0.0
28
+ Requires-Dist: pygls>=1.3.0
29
+ Requires-Dist: python-dotenv>=1.0.0
30
+ Requires-Dist: rich>=13.0.0
31
+ Requires-Dist: ruff>=0.14.10
32
+ Requires-Dist: tenacity>=8.5.0
33
+ Requires-Dist: watchdog~=5.0.0
34
+ Provides-Extra: dev
35
+ Requires-Dist: mypy>=1.10.0; extra == 'dev'
36
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
37
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
38
+ Requires-Dist: ruff>=0.4.0; extra == 'dev'
39
+ Provides-Extra: semantic
40
+ Requires-Dist: chromadb>=0.5.0; extra == 'semantic'
41
+ Description-Content-Type: text/markdown
42
+
43
+ # Stravinsky
44
+
45
+ **The Avant-Garde MCP Bridge for Claude Code**
46
+
47
+ *Movement • Rhythm • Precision*
48
+
49
+ ---
50
+
51
+ ## What is Stravinsky?
52
+
53
+ **Multi-model AI orchestration** with OAuth authentication for Claude Code.
54
+
55
+ ## Features
56
+
57
+ - 🔐 **OAuth Authentication** - Secure browser-based auth for Google (Gemini) and OpenAI (ChatGPT)
58
+ - 🤖 **Multi-Model Support** - Seamlessly invoke Gemini and GPT models from Claude
59
+ - 🎯 **Native Subagent Orchestration** - Auto-delegating orchestrator with parallel execution (zero CLI overhead)
60
+ - 🛠️ **40 MCP Tools** - Model invocation, code search, semantic search, LSP refactoring, session management, and more
61
+ - 🧠 **9 Specialized Native Agents** - Stravinsky (orchestrator), Research Lead, Implementation Lead, Delphi (GPT-5.2 advisor), Dewey (documentation), Explore (code search), Frontend (Gemini 3 Pro High UI/UX), Code Reviewer, Debugger
62
+ - 🔄 **Hook-Based Delegation** - PreToolUse hooks enforce delegation patterns with hard boundaries (exit code 2)
63
+ - 📝 **LSP Integration** - Full Language Server Protocol support with persistent servers (35x speedup), code refactoring, and advanced navigation
64
+ - 🔍 **AST-Aware Search** - Structural code search and refactoring with ast-grep
65
+ - 🧠 **Semantic Code Search** - Natural language queries with local embeddings (ChromaDB + Ollama)
66
+ - ⚡ **Cost-Optimized Routing** - Free/cheap agents (explore, dewey) always async, expensive (delphi) only when needed
67
+
68
+ ## Quick Start
69
+
70
+ ### Installation
71
+
72
+ **CRITICAL: Always use --scope user with @latest for auto-updates and Python 3.13**
73
+
74
+ ```bash
75
+ # CORRECT: User-level installation with Python 3.13 and automatic updates
76
+ claude mcp add --scope user stravinsky -- uvx --python python3.13 stravinsky@latest
77
+
78
+ # Why this matters:
79
+ # - --scope user: Works across all projects (stored in ~/.claude.json)
80
+ # - @latest: Auto-checks PyPI on every Claude restart (no stale cache)
81
+ # - --python python3.13: Required due to chromadb → onnxruntime dependency (no Python 3.14+ support)
82
+ ```
83
+
84
+ **⚠️ Python 3.13 Required**: Stravinsky requires Python 3.13 or earlier. Python 3.14+ is not supported because chromadb depends on onnxruntime, which lacks wheels for Python 3.14+.
85
+
86
+ **WRONG - Do NOT use these:**
87
+
88
+ ```bash
89
+ # ❌ Missing --python python3.13 (will fail on system Python 3.14+)
90
+ claude mcp add --global stravinsky -- uvx stravinsky@latest
91
+
92
+ # ❌ Local scope (only works in one project)
93
+ claude mcp add stravinsky -- uvx --python python3.13 stravinsky@latest
94
+
95
+ # ❌ No @latest (cache never updates, stays on old version)
96
+ claude mcp add --global stravinsky -- uvx --python python3.13 stravinsky
97
+
98
+ # ❌ uv tool install (requires manual upgrades)
99
+ uv tool install stravinsky
100
+ ```
101
+
102
+ **Development (local editable install):**
103
+
104
+ ```bash
105
+ # ONLY for active development on stravinsky source code
106
+ cd /path/to/stravinsky
107
+ uv tool install --editable . --force
108
+ claude mcp add --scope user stravinsky -- stravinsky
109
+ ```
110
+
111
+ ### Authentication
112
+
113
+ ```bash
114
+ # Login to Google (Gemini)
115
+ stravinsky-auth login gemini
116
+
117
+ # Login to OpenAI (ChatGPT Plus/Pro required)
118
+ stravinsky-auth login openai
119
+
120
+ # Check status
121
+ stravinsky-auth status
122
+
123
+ # Logout
124
+ stravinsky-auth logout gemini
125
+ ```
126
+
127
+ **Secure Token Storage:**
128
+
129
+ OAuth tokens are stored securely with automatic fallback:
130
+ - **Primary**: System keyring (macOS Keychain, Linux Secret Service, Windows Credential Locker)
131
+ - **Fallback**: Encrypted files at `~/.stravinsky/tokens/` using Fernet symmetric encryption
132
+ - **Encryption**: AES-128-CBC with keys stored at `~/.stravinsky/tokens/.key` (0o600 permissions)
133
+ - **No password prompts**: Seamless authentication across all terminal sessions after initial login
134
+ - **Global access**: Works everywhere after one-time authentication per provider
135
+
136
+ #### Troubleshooting: Password Prompts (macOS)
137
+
138
+ If you experience persistent password prompts when authenticating, configure keyring to bypass macOS Keychain:
139
+
140
+ ```bash
141
+ # 1. Create keyring config directory
142
+ mkdir -p ~/.config/python_keyring
143
+
144
+ # 2. Configure keyring to use fail backend (bypasses Keychain entirely)
145
+ cat <<EOT > ~/.config/python_keyring/keyringrc.cfg
146
+ [backend]
147
+ default-keyring = keyring.backends.fail.Keyring
148
+ EOT
149
+
150
+ # 3. Verify configuration
151
+ cat ~/.config/python_keyring/keyringrc.cfg
152
+
153
+ # 4. Re-authenticate (tokens will be stored in encrypted files only)
154
+ stravinsky-auth login gemini
155
+ ```
156
+
157
+ This configuration stores tokens in encrypted files at `~/.stravinsky/tokens/` instead of macOS Keychain, eliminating password prompts across terminal sessions. See [docs/KEYRING_AUTH_FIX.md](docs/KEYRING_AUTH_FIX.md) for detailed information.
158
+
159
+ ### Slash Commands
160
+
161
+ Slash commands are discovered from:
162
+ - Project-local: `.claude/commands/**/*.md` (recursive)
163
+ - User-global: `~/.claude/commands/**/*.md` (recursive)
164
+
165
+ Commands can be organized in subdirectories (e.g., `.claude/commands/strav/stravinsky.md`).
166
+
167
+ ## Native Subagent Architecture
168
+
169
+ Stravinsky uses **native Claude Code subagents** (.claude/agents/) with automatic delegation:
170
+
171
+ ### How It Works
172
+
173
+ 1. **Auto-Delegation**: Claude Code automatically delegates complex tasks to the Stravinsky orchestrator
174
+ 2. **Hook-Based Control**: PreToolUse hooks intercept direct tool calls and enforce delegation patterns
175
+ 3. **Parallel Execution**: Task tool enables true parallel execution of specialist agents
176
+ 4. **Multi-Model Routing**: Specialists use invoke_gemini/openai MCP tools for multi-model access
177
+
178
+ ### Agent Types
179
+
180
+ | Agent | Model | Cost | Use For |
181
+ |-------|-------|------|---------|
182
+ | **stravinsky** | Claude Sonnet 4.5 (32k thinking) | Moderate | Auto-delegating orchestrator (primary) |
183
+ | **explore** | Gemini 3 Flash (via MCP) | Free | Code search, always async |
184
+ | **dewey** | Gemini 3 Flash + WebSearch | Cheap | Documentation research, always async |
185
+ | **code-reviewer** | Claude Sonnet (native) | Cheap | Quality analysis, always async |
186
+ | **debugger** | Claude Sonnet (native) | Medium | Root cause (after 2+ failures) |
187
+ | **frontend** | Gemini 3 Pro High (via MCP) | Medium | ALL visual changes (blocking) |
188
+ | **delphi** | GPT-5.2 Medium (via MCP) | Expensive | Architecture (after 3+ failures) |
189
+
190
+ ### Delegation Rules (oh-my-opencode Pattern)
191
+
192
+ - **Always Async**: explore, dewey, code-reviewer (free/cheap)
193
+ - **Blocking**: debugger (2+ failures), frontend (ALL visual), delphi (3+ failures or architecture)
194
+ - **Never Work Alone**: Orchestrator blocks Read/Grep/Bash via PreToolUse hooks
195
+
196
+ ### ULTRATHINK / ULTRAWORK
197
+
198
+ - **ULTRATHINK**: Engage exhaustive deep reasoning with extended thinking budget (32k tokens)
199
+ - **ULTRAWORK**: Maximum parallel execution - spawn all async agents immediately
200
+
201
+ ---
202
+
203
+ ## Tools (40)
204
+
205
+ | Category | Tools |
206
+ | ---------------- | ---------------------------------------------------------------------------------- |
207
+ | **Model Invoke** | `invoke_gemini`, `invoke_openai`, `get_system_health` |
208
+ | **Environment** | `get_project_context`, `task_spawn`, `task_status`, `task_list` |
209
+ | **Agents** | `agent_spawn`, `agent_output`, `agent_cancel`, `agent_list`, `agent_progress`, `agent_retry` |
210
+ | **Code Search** | `ast_grep_search`, `ast_grep_replace`, `grep_search`, `glob_files` |
211
+ | **Semantic** | `semantic_search`, `semantic_index`, `semantic_stats`, `cancel_indexing`, `delete_index` |
212
+ | **LSP** | `lsp_diagnostics`, `lsp_hover`, `lsp_goto_definition`, `lsp_find_references`, `lsp_document_symbols`, `lsp_workspace_symbols`, `lsp_prepare_rename`, `lsp_rename`, `lsp_code_actions`, `lsp_code_action_resolve`, `lsp_extract_refactor`, `lsp_servers` (12 tools) |
213
+ | **Sessions** | `session_list`, `session_read`, `session_search` |
214
+ | **Skills** | `skill_list`, `skill_get` |
215
+
216
+ ### LSP Performance & Refactoring
217
+
218
+ The Phase 2 update introduced the `LSPManager`, which maintains persistent language server instances:
219
+
220
+ - **35x Speedup**: Subsequent LSP calls are near-instant because the server no longer needs to re-initialize and re-index the codebase for every request
221
+ - **Code Refactoring**: New support for `lsp_extract_refactor` allows automated code extraction (e.g., extracting a method or variable) with full symbol resolution
222
+ - **Code Actions**: `lsp_code_action_resolve` enables complex, multi-step refactoring workflows with automatic fixes for diagnostics
223
+
224
+ ### Semantic Code Search
225
+
226
+ Natural language code search powered by embeddings. Find code by meaning, not just keywords.
227
+
228
+ **Prerequisites:**
229
+
230
+ ```bash
231
+ # Install Ollama (default provider - free, local)
232
+ brew install ollama
233
+
234
+ # Pull the recommended lightweight embedding model (274MB)
235
+ ollama pull nomic-embed-text
236
+
237
+ # Or for better accuracy (670MB, slower):
238
+ ollama pull mxbai-embed-large
239
+ ```
240
+
241
+ **Recommended model:** `nomic-embed-text` is lightweight (274MB), fast, and works great for code search. It's the best choice for most users, especially on space-constrained systems like MacBooks.
242
+
243
+ **Workflow:**
244
+
245
+ ```bash
246
+ # STEP 1: Initial indexing (REQUIRED - run once per project)
247
+ semantic_index(project_path=".", provider="ollama")
248
+
249
+ # STEP 2: Enable auto-updates (OPTIONAL - recommended for active projects)
250
+ start_file_watcher(".", provider="ollama", debounce_seconds=2.0)
251
+
252
+ # STEP 3: Search your codebase with natural language
253
+ semantic_search(query="OAuth authentication logic", n_results=5)
254
+ semantic_stats() # View index statistics
255
+
256
+ # STEP 4: Stop watching when done (optional - watcher cleans up on exit)
257
+ stop_file_watcher(".")
258
+
259
+ # OPTIONAL: Cancel ongoing indexing (for large codebases)
260
+ cancel_indexing(project_path=".", provider="ollama")
261
+
262
+ # OPTIONAL: Delete indexes
263
+ delete_index(project_path=".", provider="ollama") # Delete ollama index for this project
264
+ delete_index(project_path=".") # Delete all provider indexes for this project
265
+ delete_index(delete_all=True) # Delete ALL indexes for ALL projects
266
+ ```
267
+
268
+ **⚠️ Important:** You MUST run `semantic_index()` first before using semantic search or starting the FileWatcher. If you skip this step:
269
+ - `semantic_search()` will return no results
270
+ - `start_file_watcher()` will show a warning but still work (indexes on first file change)
271
+
272
+ **Example queries:**
273
+ - "find authentication logic"
274
+ - "error handling in API endpoints"
275
+ - "database connection pooling"
276
+
277
+ **Providers:**
278
+
279
+ | Provider | Model | Size | Cost | Setup |
280
+ |----------|-------|------|------|-------|
281
+ | `ollama` (default) | nomic-embed-text (recommended) | 274MB | Free/local | `ollama pull nomic-embed-text` |
282
+ | `ollama` | mxbai-embed-large (advanced) | 670MB | Free/local | `ollama pull mxbai-embed-large` |
283
+ | `gemini` | gemini-embedding-001 | N/A | OAuth/cloud | `stravinsky-auth login gemini` |
284
+ | `openai` | text-embedding-3-small | N/A | OAuth/cloud | `stravinsky-auth login openai` |
285
+
286
+ **Technical details:**
287
+ - **AST-aware chunking**: Python files split by functions/classes for better semantic boundaries
288
+ - **Persistent storage**: ChromaDB at `~/.stravinsky/vectordb/<project>_<provider>/`
289
+ - **Async parallel embeddings**: 10 concurrent for fast indexing
290
+ - **Automatic file watching**: Background reindexing on code changes with configurable debouncing (2s default)
291
+
292
+ ## Native Subagents (9)
293
+
294
+ Configured in `.claude/agents/*.md`:
295
+
296
+ | Agent | Purpose | Location |
297
+ | ---------------- | --------------------------------------------------------------------- | -------- |
298
+ | `stravinsky` | Task orchestration with 32k extended thinking (Sonnet 4.5) | .claude/agents/stravinsky.md |
299
+ | `research-lead` | Research coordinator - spawns explore/dewey, synthesizes findings (Gemini Flash) | .claude/agents/research-lead.md |
300
+ | `implementation-lead` | Implementation coordinator - spawns frontend/debugger/reviewer (Haiku) | .claude/agents/implementation-lead.md |
301
+ | `explore` | Codebase search and structural analysis (Gemini 3 Flash) | .claude/agents/explore.md |
302
+ | `dewey` | Documentation research and web search (Gemini 3 Flash) | .claude/agents/dewey.md |
303
+ | `code-reviewer` | Security, quality, and best practice analysis (Claude Sonnet) | .claude/agents/code-reviewer.md |
304
+ | `debugger` | Root cause analysis and fix strategies (Claude Sonnet) | .claude/agents/debugger.md |
305
+ | `frontend` | UI/UX implementation with creative generation (Gemini 3 Pro High) | .claude/agents/frontend.md |
306
+ | `delphi` | Strategic architecture advisor with 32k thinking (GPT-5.2 Medium) | .claude/agents/delphi.md |
307
+
308
+ ## Development
309
+
310
+ ```bash
311
+ # Install in development mode
312
+ uv pip install -e .
313
+
314
+ # Run server
315
+ stravinsky
316
+ ```
317
+
318
+ ## Project Structure
319
+
320
+ ```
321
+ stravinsky/
322
+ ├── .claude/ # Claude Code configuration
323
+ │ ├── agents/ # Native subagent configurations (7 agents)
324
+ │ │ ├── stravinsky.md # Orchestrator (auto-delegated)
325
+ │ │ ├── explore.md # Code search specialist
326
+ │ │ ├── dewey.md # Documentation research
327
+ │ │ ├── code-reviewer.md # Quality analysis
328
+ │ │ ├── debugger.md # Root cause analysis
329
+ │ │ ├── frontend.md # UI/UX specialist
330
+ │ │ ├── delphi.md # Strategic advisor (GPT-5.2)
331
+ │ │ └── HOOKS.md # Hook architecture guide
332
+ │ ├── commands/ # Slash commands (skills)
333
+ │ │ ├── stravinsky.md # /strav orchestrator
334
+ │ │ ├── delphi.md # /delphi strategic advisor
335
+ │ │ ├── dewey.md # /dewey documentation research
336
+ │ │ ├── publish.md # /publish PyPI release
337
+ │ │ ├── review.md # /review code review
338
+ │ │ ├── verify.md # /verify post-implementation
339
+ │ │ └── version.md # /version diagnostic info
340
+ │ ├── hooks/ # Native Claude Code hooks (11 hooks)
341
+ │ │ ├── stravinsky_mode.py # PreToolUse delegation enforcer
342
+ │ │ ├── context.py # UserPromptSubmit context injection
343
+ │ │ ├── todo_continuation.py # UserPromptSubmit todo continuation
344
+ │ │ ├── truncator.py # PostToolUse output truncation
345
+ │ │ ├── tool_messaging.py # PostToolUse user messaging
346
+ │ │ ├── edit_recovery.py # PostToolUse edit backup
347
+ │ │ ├── todo_delegation.py # PostToolUse parallel reminder
348
+ │ │ ├── parallel_execution.py # PostToolUse parallel enforcement
349
+ │ │ ├── notification_hook.py # PreToolUse agent spawn notifications
350
+ │ │ ├── subagent_stop.py # PostToolUse agent completion handling
351
+ │ │ └── pre_compact.py # PreCompact context preservation
352
+ │ ├── skills/ # Skill library (empty, skills in commands/)
353
+ │ ├── settings.json # Hook configuration
354
+ │ └── HOOKS_INTEGRATION.md # Hook integration guide
355
+ ├── mcp_bridge/ # Python MCP server
356
+ │ ├── server.py # MCP server entry point
357
+ │ ├── server_tools.py # Tool definitions
358
+ │ ├── auth/ # OAuth authentication
359
+ │ │ ├── oauth.py # Google OAuth (Gemini)
360
+ │ │ ├── openai_oauth.py # OpenAI OAuth (ChatGPT)
361
+ │ │ ├── token_store.py # Keyring storage
362
+ │ │ ├── token_refresh.py # Auto-refresh tokens
363
+ │ │ └── cli.py # stravinsky-auth CLI
364
+ │ ├── tools/ # MCP tool implementations
365
+ │ │ ├── model_invoke.py # invoke_gemini, invoke_openai
366
+ │ │ ├── agent_manager.py # agent_spawn, agent_output, etc.
367
+ │ │ ├── code_search.py # ast_grep, grep, glob
368
+ │ │ ├── semantic_search.py # semantic_search, semantic_index, semantic_stats
369
+ │ │ ├── session_manager.py # session_list, session_read, etc.
370
+ │ │ ├── skill_loader.py # skill_list, skill_get
371
+ │ │ ├── project_context.py # get_project_context
372
+ │ │ ├── lsp/ # LSP tool implementations
373
+ │ │ └── templates.py # Project templates
374
+ │ ├── prompts/ # Agent system prompts (legacy CLI)
375
+ │ │ ├── stravinsky.py # Legacy orchestrator prompt
376
+ │ │ ├── delphi.py # Legacy advisor prompt
377
+ │ │ ├── dewey.py # Legacy research prompt
378
+ │ │ ├── explore.py # Legacy search prompt
379
+ │ │ ├── frontend.py # Legacy UI/UX prompt
380
+ │ │ └── multimodal.py # Multimodal analysis prompt
381
+ │ ├── hooks/ # MCP internal hooks (17+ hooks)
382
+ │ │ ├── manager.py # Hook orchestration
383
+ │ │ ├── truncator.py # Output truncation
384
+ │ │ ├── parallel_enforcer.py # Parallel execution
385
+ │ │ ├── todo_enforcer.py # Todo continuation
386
+ │ │ └── ... # 13+ more optimization hooks
387
+ │ ├── native_hooks/ # Native Claude Code hooks
388
+ │ │ ├── stravinsky_mode.py # PreToolUse delegation enforcer
389
+ │ │ ├── tool_messaging.py # PostToolUse user messaging
390
+ │ │ ├── todo_delegation.py # TodoWrite parallel reminder
391
+ │ │ ├── todo_continuation.py # UserPromptSubmit todo injection
392
+ │ │ ├── context.py # UserPromptSubmit context
393
+ │ │ ├── truncator.py # PostToolUse truncation
394
+ │ │ └── edit_recovery.py # PostToolUse backup
395
+ │ ├── cli/ # CLI utilities
396
+ │ │ └── session_report.py # Session analysis
397
+ │ ├── config/ # Configuration
398
+ │ │ └── hooks.py # Hook configuration
399
+ │ └── utils/ # Utility functions
400
+ ├── .stravinsky/ # Agent execution logs (gitignored)
401
+ ├── assets/ # Logo, images
402
+ ├── docs/ # Additional documentation
403
+ ├── logs/ # Application logs
404
+ ├── tests/ # Test suite
405
+ ├── pyproject.toml # Build configuration
406
+ ├── uv.lock # Dependency lock
407
+ ├── ARCHITECTURE.md # Architecture guide (oh-my-opencode comparison)
408
+ ├── CLAUDE.md # Project instructions
409
+ ├── INSTALL.md # Installation guide
410
+ └── README.md # This file
411
+ ```
412
+
413
+ ## Troubleshooting
414
+
415
+ ### OpenAI "Port 1455 in use"
416
+
417
+ The Codex CLI uses the same port. Stop it with: `killall codex`
418
+
419
+ ### OpenAI Authentication Failed
420
+
421
+ - Ensure you have a ChatGPT Plus/Pro subscription
422
+ - Tokens expire occasionally; run `stravinsky-auth login openai` to refresh
423
+
424
+ ### Claude Code Not Loading Latest Version After Update
425
+
426
+ **Problem:** After deploying a new version to PyPI, Claude Code still uses the old cached version even after restart.
427
+
428
+ **Root Cause:** `uvx` caches packages and doesn't automatically check for updates. This is a known uvx behavior that affects all packages, not just Stravinsky.
429
+
430
+ **Solution - Force Reinstall:**
431
+
432
+ ```bash
433
+ # Option 1: Run latest version with uvx (if using uvx in .mcp.json)
434
+ uvx stravinsky@latest
435
+
436
+ # Option 2: Upgrade with uv tool (if installed globally)
437
+ uv tool install --upgrade --force stravinsky
438
+ # or reinstall all tools:
439
+ uv tool upgrade --all --reinstall
440
+
441
+ # Option 3: Clear uvx cache entirely (nuclear option)
442
+ uv cache prune
443
+
444
+ # Option 4: Remove and re-add MCP server
445
+ claude mcp remove stravinsky
446
+ claude mcp add stravinsky -- uvx stravinsky@latest
447
+
448
+ # After any option, restart Claude Code
449
+ claude restart
450
+ ```
451
+
452
+ **Verify Version:**
453
+
454
+ ```bash
455
+ # Check installed version
456
+ stravinsky --version
457
+ # or
458
+ python -c "import mcp_bridge; print(mcp_bridge.__version__)"
459
+
460
+ # Check PyPI latest version
461
+ curl -s https://pypi.org/pypi/stravinsky/json | python -c "import sys, json; print(json.load(sys.stdin)['info']['version'])"
462
+ ```
463
+
464
+ ## License
465
+
466
+ MIT
467
+
468
+ ---
@@ -0,0 +1,88 @@
1
+ mcp_bridge/__init__.py,sha256=my_eRKQWrGqOjGcYUQ3l4O21n-LMG22J283Pb5L90kw,23
2
+ mcp_bridge/notifications.py,sha256=C4qPvGD1NnAsU_ukwbiqWdo7cA6ScU0qGhjie3vPpjM,5134
3
+ mcp_bridge/server.py,sha256=n17tRjAMmO5rmtofmuck3q3okMe5aqk1O86ei86TH2U,31938
4
+ mcp_bridge/server_tools.py,sha256=J_0_qCxuMdyyl5ej6h4akK8SLa1rLcxbKOgEY0n4xlk,47232
5
+ mcp_bridge/update_manager.py,sha256=3bXPsE0xb1ESAZq7eqPOir6sf9uq3-IaFQy2DjtwIxo,20272
6
+ mcp_bridge/update_manager_pypi.py,sha256=mo1G-XFhLXljEqEpGwXoMqjeB7a4m2dz3DAGtELQVvQ,9415
7
+ mcp_bridge/auth/__init__.py,sha256=AGHNtKzqvZYMLQ35Qg6aOabpxBqmkR-pjXv8Iby9oMw,797
8
+ mcp_bridge/auth/cli.py,sha256=jaXyrzq6HwnW61g6CHHcj8bF5PJLYrYufD_jmN0jeiQ,8502
9
+ mcp_bridge/auth/oauth.py,sha256=gWYk3KJWbUM1J5AKVDJ_4k4zdQzwwaYJZ5J25If0r8c,12804
10
+ mcp_bridge/auth/openai_oauth.py,sha256=0Ks2X-NXLCBzqs3xnbj9QLZpugICOX5qB5y5vtDENOo,11522
11
+ mcp_bridge/auth/token_refresh.py,sha256=goWp1Wz3yWOoFuxvFMDZLjo8gLPXcajZxHpzZtSoKcQ,3760
12
+ mcp_bridge/auth/token_store.py,sha256=cOQfxFK9z4lvhHZsAcAbzWFcMZiM_RJjjCLQ1XLetac,9508
13
+ mcp_bridge/cli/__init__.py,sha256=J1cFw06fYSm3uU7cbEj3GgWuDxTn1X0cDhPi1gJq7eM,200
14
+ mcp_bridge/cli/install_hooks.py,sha256=cmLctih9xie1iaY8uyzO11egvEkpMa7Zc-Nyb5dITlg,36955
15
+ mcp_bridge/cli/session_report.py,sha256=sYUje44R4qIwxML_GCaEyJwz4jgis4sZOwTDZGQJ3MM,22198
16
+ mcp_bridge/config/MANIFEST_SCHEMA.md,sha256=KVODUO8n5J9DcsBP19EIflQcGW39ulMnYs3evyZIrJg,10074
17
+ mcp_bridge/config/README.md,sha256=HzzkpS3-iDw0mGKQ2zjFETyi4r1ot03pZ4pUXp3FZJ0,8506
18
+ mcp_bridge/config/__init__.py,sha256=uapHdrSWWrafVKD9CTB1J_7Dw0_RajRhoDGjy9zH21o,256
19
+ mcp_bridge/config/hook_config.py,sha256=Fm1AWsgQfzp8J8eBp6RmL7aXFEZrAJL6Wpn7g0d11oI,7502
20
+ mcp_bridge/config/hooks.py,sha256=WvWC6ZUc8y1IXPlGCjLYAAsGGigd5tWeGiw585OGNwA,4624
21
+ mcp_bridge/config/hooks_manifest.json,sha256=e-1_Qh15WVY1IE1r6pL67WW10LYoSmcmRYEuRNz53qw,4189
22
+ mcp_bridge/config/rate_limits.py,sha256=1XXvQjlhAiuYrDY9m-O6NlWhtg3_GTx99dINavzcXGU,7189
23
+ mcp_bridge/config/skills_manifest.json,sha256=6i5KfwqnZUAE9HCyTXoZfKA4tIXMaIZs4Kzf6Kj4bA4,3693
24
+ mcp_bridge/hooks/HOOKS_SETTINGS.json,sha256=IY47eGigQwTaQ0XwM2NzVopGBga3Zaocmq09I1M1inw,6434
25
+ mcp_bridge/hooks/README.md,sha256=ocKp2BE6U4o8OhnA4dbXoth8A9YD8MYQLi5uXw7bLEo,7549
26
+ mcp_bridge/hooks/__init__.py,sha256=_R8Qbz7puDeQ_LWwKLSU_GKnxdA1JyESEihM1PM5HFo,3946
27
+ mcp_bridge/hooks/agent_reminder.py,sha256=OxKPxi7e2MIBm44Ebzzl9j9fDV5bBgogGF0lj7wun5s,1913
28
+ mcp_bridge/hooks/auto_slash_command.py,sha256=LUndZHxUzEF7PQuOdp3v7VfqNUgsiDE2gzI_TkR9he4,5280
29
+ mcp_bridge/hooks/budget_optimizer.py,sha256=Im0qSGVUdRByk04hP5VyKt7tjlDVYG0LJb6IeUjjnj8,1323
30
+ mcp_bridge/hooks/comment_checker.py,sha256=MslXZYiHjfxjUU7VzmZfa1n2WR9o4lnaktJ6eUPBUDs,3772
31
+ mcp_bridge/hooks/compaction.py,sha256=UXTwmyo9C4Jm3j72KvVU11ukSAHaGaTey_h3L43e3rY,1186
32
+ mcp_bridge/hooks/context.py,sha256=JBHqnX75qtMO3JAEFooBEAK6DxcsVaXykhrP7tdFm6E,949
33
+ mcp_bridge/hooks/context_monitor.py,sha256=IEr75e_gqbPEUslxxfkwftiy6alDmJxQhSB6cy8BVg4,1885
34
+ mcp_bridge/hooks/directory_context.py,sha256=0VjdJITJIGUqR4-q-wZlB6kmkFQMraaFvU2Nz2PnJCM,1225
35
+ mcp_bridge/hooks/edit_recovery.py,sha256=1OWpb3v87txFUsgnNe1hoeTI7rIKCkKYONld5BK1TyA,1503
36
+ mcp_bridge/hooks/empty_message_sanitizer.py,sha256=iZZnETju1wBvJXV1k4msV8FxLNg5LkVm2eaFA2nQWxI,6606
37
+ mcp_bridge/hooks/git_noninteractive.py,sha256=1VETo7Gf76NYEx_J7RxA52wYnlj5wiOwFL9lSMdshEM,2864
38
+ mcp_bridge/hooks/keyword_detector.py,sha256=w7wW8dYYKiHpmgMYJtWw2MJd0ly631C7rFVWtC_kkq8,6105
39
+ mcp_bridge/hooks/manager.py,sha256=cWgHbaW2qD-Gl0Xxbl-2o6ffn3R2U6X0E5ezZDxH4A0,5994
40
+ mcp_bridge/hooks/notification_hook.py,sha256=GElHxaIn0BF935IXuRQjYERk7W_msBiCm0UwutumdiM,2770
41
+ mcp_bridge/hooks/parallel_enforcer.py,sha256=qzPB7PX22Laz6yC3MCbAmYBhP59P9ac6WHpgXOABOuQ,3651
42
+ mcp_bridge/hooks/parallel_execution.py,sha256=nIINPRm-1P1dci3lTCacJKN_4NIkm9IyTrVx-rmbXl4,3602
43
+ mcp_bridge/hooks/pre_compact.py,sha256=QXcCO9kByn8Ta27NWoQP8IPPUa379KO4qb1BBLzfzuU,3398
44
+ mcp_bridge/hooks/preemptive_compaction.py,sha256=x4-dLWCconVFD-nR93P1EB_tG9n4LHdESq7uDFS3ut8,7937
45
+ mcp_bridge/hooks/rules_injector.py,sha256=jZN9_b464ATEKAFJvIlIVKT-UvcoNAuZGDI4TmJ0Uxc,16485
46
+ mcp_bridge/hooks/session_idle.py,sha256=5wo6XakXglWVCP-HN1i976OptfntwCNnbjxoM--veh4,3525
47
+ mcp_bridge/hooks/session_notifier.py,sha256=dkrSwRquMbcCRuUCsBVqUY6cHSGDO2UuPWKTNf6Y7fc,3750
48
+ mcp_bridge/hooks/session_recovery.py,sha256=c5eoIWJAgMTPY0wq_64MmCUNLCB_GSowZlA3lo4R9LU,6260
49
+ mcp_bridge/hooks/stravinsky_mode.py,sha256=ru9vg5m1QjhK0ABwopC68S2Gzy2-sEW1b1AbveFO57o,4066
50
+ mcp_bridge/hooks/subagent_stop.py,sha256=GUPY3FNVAtsc6J4PbddSRK9XuDs-gw2CaFoGXt5gsME,2865
51
+ mcp_bridge/hooks/task_validator.py,sha256=YSeUWbtwjA-oWCrOVS5DTRxu9_0VTgzpF2mf-QIIw9E,2183
52
+ mcp_bridge/hooks/tmux_manager.py,sha256=vXU0o612PrJ8Xb0IMq4qnEY3i_Z1sT_E-56SqalmrQA,4125
53
+ mcp_bridge/hooks/todo_continuation.py,sha256=tmhTVfMZMDuDw4cwyuU7r_TkUqmtAx55u0WNTawgMyo,2652
54
+ mcp_bridge/hooks/todo_delegation.py,sha256=tOAE1RYAPSH8UOeO8Vsk7sdLf9H4GmXE2lbc_GGjlYI,2676
55
+ mcp_bridge/hooks/todo_enforcer.py,sha256=LRvVxYILqQ6YuQl3tky4hgyD-irXIPDE5e0EdKr6jcc,2274
56
+ mcp_bridge/hooks/tool_messaging.py,sha256=LBwv52NklmNtYbNl_72kik2H1zdvZssYIVUFCUWJK9g,9687
57
+ mcp_bridge/hooks/truncator.py,sha256=h3hb8sZXTvc59C0-5GdZwCVZHlxBKdo47JT9TMxHG3g,530
58
+ mcp_bridge/prompts/__init__.py,sha256=wzveum1x50IXGkE0JFpvHAj8P0yqnSrgtrmyIIpnnBI,358
59
+ mcp_bridge/prompts/delphi.py,sha256=ZlnLY2o1PrK3CxLLaCkozAGPIAJ5OFmw5u8o6-LXmgI,4960
60
+ mcp_bridge/prompts/dewey.py,sha256=u5OaOj8kinZERflWvUv4M4WVAwxw0kJrNT00wHksIHI,9264
61
+ mcp_bridge/prompts/document_writer.py,sha256=hiCbxgTU8HKPJkS0eNpPPtzSqDXPreApU2OqiS6zh-0,5618
62
+ mcp_bridge/prompts/explore.py,sha256=oZxh4fe4KNGa_ozakJSpLYeQVfO4-jQ2M1BSOw1Sw10,5801
63
+ mcp_bridge/prompts/frontend.py,sha256=j91I8k5vcVed13eeX-Ebiv49x9Qj4HO_SQN1xhB8TLQ,4943
64
+ mcp_bridge/prompts/multimodal.py,sha256=Q_rutR7r5iBcLViVfdLxoukCQe2OA0lDJhxkoo0OSMw,2692
65
+ mcp_bridge/prompts/planner.py,sha256=wcdXIxPlZM0UYd9KQSKXnuXTRj2acSnqlqeQ_NxxEqw,6985
66
+ mcp_bridge/prompts/stravinsky.py,sha256=gJgzMgsa6u0fLbFWOkPY2lq78-yJTuD46wrnk-5rem0,27498
67
+ mcp_bridge/tools/__init__.py,sha256=1Ks_gdsnN7BhKE8738pBAsI1VH66Kkj9bE71Xo68GvI,1301
68
+ mcp_bridge/tools/agent_manager.py,sha256=EHcmLD5-0wsDuRSpWx9-SKIZKdvJULNxa_qr4_GvPmQ,38506
69
+ mcp_bridge/tools/background_tasks.py,sha256=bwbVYWCDzuXb3Q_OdIr10r76lgjFTphfjdTmOHYZI7w,5252
70
+ mcp_bridge/tools/code_search.py,sha256=xawUBapNSCp1lL_LESsiiVU6fno1iFeSji2Ke5WAO6M,13170
71
+ mcp_bridge/tools/continuous_loop.py,sha256=MM3FnF3ULuR32h0tqJP8uF48iJg6R9dbyHy_36KLOls,2100
72
+ mcp_bridge/tools/init.py,sha256=sU95M9M_tjsfuew389TrFrxxeCavuSC16qbkydk_6PU,1586
73
+ mcp_bridge/tools/model_invoke.py,sha256=WoiTKAkUDe-mlQs3ArWNgMy1DBx2MTXtKdrV4LawYsM,37384
74
+ mcp_bridge/tools/project_context.py,sha256=bXKxuW1pGjtIbeNjMgpBoQL-d_CI94UPBVpRjUyhX20,4707
75
+ mcp_bridge/tools/query_classifier.py,sha256=Jj8AoDEkur5eE5N6Szlh9tUX3rkdReqGCAL4-lEtTY4,12324
76
+ mcp_bridge/tools/semantic_search.py,sha256=UBvW3mYHxp03IxzZ4X0D051-3kkggKxgka_fHLlb5c4,106839
77
+ mcp_bridge/tools/session_manager.py,sha256=tCVLLvO-Kttla7OxPImb_NSGL_9aW46ilq5ej_IcnlA,9252
78
+ mcp_bridge/tools/skill_loader.py,sha256=RQ5eC357pm-6q85G3EyrQugz0S3OO5lxWtM9n9ECF-c,6010
79
+ mcp_bridge/tools/task_runner.py,sha256=xjE3MXv62gcUCwOEwHjAGL_Ud_ZlKFBN0UHpvFjj3uk,3918
80
+ mcp_bridge/tools/templates.py,sha256=ANsSXGFKvc7NR58jbmR7SejlbBQucqXZi4DYagYz3CQ,7008
81
+ mcp_bridge/tools/lsp/__init__.py,sha256=v-2OENfPrZxglAwpbooH3rFjcZDmhAMXEFZhygwq3II,753
82
+ mcp_bridge/tools/lsp/manager.py,sha256=DR0XDDL0ElKsf8I3iqJIXhV4oX25Kh2QoPLGGtpgM7o,16272
83
+ mcp_bridge/tools/lsp/tools.py,sha256=DANgPzp52vPomBAEnwOU9YZiNowz9yWQZGLQZ1wXTeY,34521
84
+ mcp_bridge/utils/__init__.py,sha256=pbHV4nq5SLUYcAyTmLUZYrp293Ctud57X8hwsMGA_BM,20
85
+ stravinsky-0.4.18.dist-info/METADATA,sha256=6cnhEnVZ6b_FIEFUsuPUVi_Vpkiol3m6uEf71LTxycU,22008
86
+ stravinsky-0.4.18.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
87
+ stravinsky-0.4.18.dist-info/entry_points.txt,sha256=MB1dqHW9dx-ae0-cDi6fYEY9HtyzbyB5VhJxza0wDDc,215
88
+ stravinsky-0.4.18.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ [console_scripts]
2
+ stravinsky = mcp_bridge.server:main
3
+ stravinsky-auth = mcp_bridge.auth.cli:main
4
+ stravinsky-install-hooks = mcp_bridge.cli.install_hooks:main
5
+ stravinsky-sessions = mcp_bridge.cli.session_report:main
@@ -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()
@@ -1,54 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- PostToolUse hook for TodoWrite: Enforces parallel delegation.
4
-
5
- After TodoWrite is called, this hook injects a reminder to spawn
6
- parallel Task agents for all independent TODOs.
7
- """
8
- import json
9
- import sys
10
-
11
-
12
- def main():
13
- # Read hook input from stdin
14
- try:
15
- hook_input = json.load(sys.stdin)
16
- except (json.JSONDecodeError, EOFError):
17
- return 0
18
-
19
- tool_name = hook_input.get("tool_name", "")
20
-
21
- if tool_name != "TodoWrite":
22
- return 0
23
-
24
- # Get the todos that were just written
25
- tool_input = hook_input.get("tool_input", {})
26
- todos = tool_input.get("todos", [])
27
-
28
- # Count pending todos
29
- pending_count = sum(1 for t in todos if t.get("status") == "pending")
30
-
31
- if pending_count < 2:
32
- return 0
33
-
34
- # Output the parallel delegation reminder
35
- reminder = f"""
36
- [PARALLEL DELEGATION REQUIRED]
37
-
38
- You just created {pending_count} pending TODOs. Before your NEXT response:
39
-
40
- 1. Identify which TODOs are INDEPENDENT (can run simultaneously)
41
- 2. For EACH independent TODO, spawn a Task agent:
42
- Task(subagent_type="Explore", prompt="[TODO details]", run_in_background=true)
43
- 3. Fire ALL Task calls in ONE response - do NOT wait between them
44
- 4. Do NOT mark any TODO as in_progress until agents return
45
-
46
- WRONG: Create TODO list -> Mark TODO 1 in_progress -> Work -> Complete -> Repeat
47
- CORRECT: Create TODO list -> Spawn Task for each -> Collect results -> Mark complete
48
- """
49
- print(reminder)
50
- return 0
51
-
52
-
53
- if __name__ == "__main__":
54
- sys.exit(main())