stravinsky 0.2.67__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.
- mcp_bridge/__init__.py +1 -1
- mcp_bridge/auth/token_store.py +113 -11
- mcp_bridge/config/MANIFEST_SCHEMA.md +305 -0
- mcp_bridge/config/README.md +276 -0
- mcp_bridge/config/hook_config.py +249 -0
- mcp_bridge/config/hooks_manifest.json +138 -0
- mcp_bridge/config/rate_limits.py +222 -0
- mcp_bridge/config/skills_manifest.json +128 -0
- mcp_bridge/hooks/__init__.py +8 -3
- mcp_bridge/hooks/manager.py +8 -0
- mcp_bridge/hooks/tool_messaging.py +113 -10
- mcp_bridge/notifications.py +151 -0
- mcp_bridge/server.py +202 -48
- mcp_bridge/server_tools.py +440 -0
- mcp_bridge/tools/__init__.py +22 -18
- mcp_bridge/tools/agent_manager.py +197 -28
- mcp_bridge/tools/code_search.py +16 -2
- mcp_bridge/tools/lsp/__init__.py +7 -0
- mcp_bridge/tools/lsp/manager.py +448 -0
- mcp_bridge/tools/lsp/tools.py +634 -151
- mcp_bridge/tools/model_invoke.py +186 -159
- mcp_bridge/tools/query_classifier.py +323 -0
- mcp_bridge/tools/semantic_search.py +3042 -0
- mcp_bridge/update_manager.py +589 -0
- mcp_bridge/update_manager_pypi.py +299 -0
- {stravinsky-0.2.67.dist-info → stravinsky-0.4.18.dist-info}/METADATA +209 -25
- {stravinsky-0.2.67.dist-info → stravinsky-0.4.18.dist-info}/RECORD +29 -17
- {stravinsky-0.2.67.dist-info → stravinsky-0.4.18.dist-info}/WHEEL +0 -0
- {stravinsky-0.2.67.dist-info → stravinsky-0.4.18.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
# Stravinsky Configuration & Manifest System
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The `mcp_bridge/config/` directory contains:
|
|
6
|
+
|
|
7
|
+
1. **hooks_manifest.json** - Version tracking for 32 official hooks
|
|
8
|
+
2. **skills_manifest.json** - Metadata for 16 slash commands/skills
|
|
9
|
+
3. **MANIFEST_SCHEMA.md** - Detailed schema documentation
|
|
10
|
+
4. **hooks.py** - Hook configuration utilities
|
|
11
|
+
5. **README.md** - This file
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
### For Users
|
|
16
|
+
No action needed. Manifests are automatically managed by the Stravinsky package.
|
|
17
|
+
|
|
18
|
+
### For Maintainers
|
|
19
|
+
When releasing a new version:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# 1. Update version in pyproject.toml and mcp_bridge/__init__.py
|
|
23
|
+
# 2. Regenerate manifests (if hooks/skills changed)
|
|
24
|
+
python scripts/generate_manifests.py
|
|
25
|
+
|
|
26
|
+
# 3. Commit changes
|
|
27
|
+
git add mcp_bridge/config/*.json
|
|
28
|
+
git commit -m "chore: update manifests for v0.3.X"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## File Descriptions
|
|
32
|
+
|
|
33
|
+
### hooks_manifest.json
|
|
34
|
+
Tracks all 32 official hooks provided by Stravinsky:
|
|
35
|
+
|
|
36
|
+
- **Core execution hooks** (3): `parallel_execution`, `stravinsky_mode`, `todo_delegation`
|
|
37
|
+
- **Context hooks** (6): `context`, `todo_continuation`, `todo_enforcer`, `directory_context`, `rules_injector`, `pre_compact`
|
|
38
|
+
- **Tool enhancement hooks** (6): `tool_messaging`, `edit_recovery`, `truncator`, `empty_message_sanitizer`, `comment_checker`, `compaction`
|
|
39
|
+
- **Agent lifecycle hooks** (4): `notification_hook`, `subagent_stop`, `session_recovery`, `task_validator`
|
|
40
|
+
- **Advanced optimization** (5): `preemptive_compaction`, `parallel_enforcer`, `auto_slash_command`, `agent_reminder`, `budget_optimizer`
|
|
41
|
+
- **Execution context** (3): `keyword_detector`, `git_noninteractive`, `session_idle`, `session_notifier`, `tmux_manager`
|
|
42
|
+
|
|
43
|
+
**Key Metrics:**
|
|
44
|
+
- 9 required hooks (critical path)
|
|
45
|
+
- 23 optional hooks (enhanced behavior)
|
|
46
|
+
- 2 critical priority, 11 high, 12 medium, 7 low
|
|
47
|
+
|
|
48
|
+
### skills_manifest.json
|
|
49
|
+
Tracks all 16 slash commands (skills):
|
|
50
|
+
|
|
51
|
+
**Core Skills (4):**
|
|
52
|
+
- `/strav` - Task orchestration
|
|
53
|
+
- `/strav:loop` - Continuation loop management
|
|
54
|
+
- `/strav:cancel-loop` - Loop cancellation
|
|
55
|
+
- `/version` - Diagnostic info
|
|
56
|
+
|
|
57
|
+
**Implementation Skills (4):**
|
|
58
|
+
- `/commit` - Git commit orchestration
|
|
59
|
+
- `/review` - Code review
|
|
60
|
+
- `/verify` - Testing and deployment verification
|
|
61
|
+
- `/publish` - PyPI deployment
|
|
62
|
+
|
|
63
|
+
**Research Skills (7):**
|
|
64
|
+
- `/dewey` - Documentation research
|
|
65
|
+
- `/index` - Semantic search indexing
|
|
66
|
+
- `/str:index` - Detailed semantic indexing
|
|
67
|
+
- `/str:search` - Semantic code search
|
|
68
|
+
- `/str:start_filewatch` - File watching
|
|
69
|
+
- `/str:stop_filewatch` - Stop file watching
|
|
70
|
+
- `/str:stats` - Index statistics
|
|
71
|
+
|
|
72
|
+
**Architecture Skills (1):**
|
|
73
|
+
- `/delphi` - Strategic advisor
|
|
74
|
+
|
|
75
|
+
**Key Metrics:**
|
|
76
|
+
- 6 blocking skills (immediate execution)
|
|
77
|
+
- 10 async skills (background execution)
|
|
78
|
+
- All skills marked updatable=true (user customizable)
|
|
79
|
+
|
|
80
|
+
## Integration with update_manager.py
|
|
81
|
+
|
|
82
|
+
The manifests enable smart update workflows:
|
|
83
|
+
|
|
84
|
+
### Version Checking
|
|
85
|
+
```python
|
|
86
|
+
# Load manifest from installed package
|
|
87
|
+
manifest = load_manifest_from_package()
|
|
88
|
+
|
|
89
|
+
# Compare with remote version
|
|
90
|
+
if manifest.manifest_version < remote_version:
|
|
91
|
+
# Updates available
|
|
92
|
+
show_update_notification()
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Integrity Verification
|
|
96
|
+
```python
|
|
97
|
+
# Before updating a hook, verify it hasn't been modified
|
|
98
|
+
current_hash = compute_sha256(hook_file)
|
|
99
|
+
expected_hash = manifest[hook_name].checksum
|
|
100
|
+
|
|
101
|
+
if current_hash != expected_hash:
|
|
102
|
+
# User has customized this hook
|
|
103
|
+
if manifest[hook_name].updatable:
|
|
104
|
+
warn_about_modifications()
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Selective Updates
|
|
108
|
+
```python
|
|
109
|
+
# Only update files marked updatable=true
|
|
110
|
+
# Respect user customizations in .claude/hooks/
|
|
111
|
+
for hook_name, hook_info in manifest.hooks.items():
|
|
112
|
+
if hook_info.updatable and hook_info.priority in ["critical", "high"]:
|
|
113
|
+
update_hook(hook_name)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Dependency Resolution
|
|
117
|
+
```python
|
|
118
|
+
# Ensure all dependencies are installed
|
|
119
|
+
for dependency in hook_info.dependencies:
|
|
120
|
+
if not is_installed(dependency):
|
|
121
|
+
error(f"Missing dependency: {dependency}")
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Manifest Fields Reference
|
|
125
|
+
|
|
126
|
+
### Hook Entry
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"hook_name": {
|
|
130
|
+
"version": "0.2.63",
|
|
131
|
+
"source": "mcp_bridge/hooks/hook_name.py",
|
|
132
|
+
"description": "What this hook does",
|
|
133
|
+
"hook_type": "PreToolUse|PostToolUse|UserPromptSubmit|...",
|
|
134
|
+
"checksum": "sha256_first_12_chars",
|
|
135
|
+
"lines_of_code": 150,
|
|
136
|
+
"updatable": true,
|
|
137
|
+
"priority": "critical|high|medium|low",
|
|
138
|
+
"required": true,
|
|
139
|
+
"dependencies": ["manager.py"]
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Skill Entry
|
|
145
|
+
```json
|
|
146
|
+
{
|
|
147
|
+
"skill_name": {
|
|
148
|
+
"file_path": "strav.md or str/search.md",
|
|
149
|
+
"description": "What this skill does",
|
|
150
|
+
"category": "core|research|implementation|architecture",
|
|
151
|
+
"checksum": "sha256_first_12_chars",
|
|
152
|
+
"lines_of_code": 200,
|
|
153
|
+
"updatable": true,
|
|
154
|
+
"priority": "critical|high|medium|low",
|
|
155
|
+
"agent_type": "explore|dewey|frontend|...",
|
|
156
|
+
"blocking": true,
|
|
157
|
+
"requires_auth": true,
|
|
158
|
+
"version_first_added": "0.1.0"
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
See **MANIFEST_SCHEMA.md** for complete field documentation.
|
|
164
|
+
|
|
165
|
+
## Checksum Verification
|
|
166
|
+
|
|
167
|
+
### Generate Checksums
|
|
168
|
+
```bash
|
|
169
|
+
# For a single file
|
|
170
|
+
sha256sum mcp_bridge/hooks/parallel_execution.py | awk '{print substr($1,1,12)}'
|
|
171
|
+
|
|
172
|
+
# For all hooks
|
|
173
|
+
for f in mcp_bridge/hooks/*.py; do
|
|
174
|
+
echo "$(basename $f): $(sha256sum $f | awk '{print substr($1,1,12)}')"
|
|
175
|
+
done
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Verify File Integrity
|
|
179
|
+
```bash
|
|
180
|
+
# Check if a file has been modified
|
|
181
|
+
current=$(sha256sum mcp_bridge/hooks/parallel_execution.py | awk '{print substr($1,1,12)}')
|
|
182
|
+
expected=$(jq -r '.hooks.parallel_execution.checksum' mcp_bridge/config/hooks_manifest.json)
|
|
183
|
+
|
|
184
|
+
if [ "$current" != "$expected" ]; then
|
|
185
|
+
echo "File has been modified locally"
|
|
186
|
+
fi
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Update Strategy
|
|
190
|
+
|
|
191
|
+
### Priority Levels
|
|
192
|
+
- **critical**: Security, core functionality - update immediately
|
|
193
|
+
- **high**: New features, important improvements - include in next release
|
|
194
|
+
- **medium**: Enhancements - can batch together
|
|
195
|
+
- **low**: Optional improvements - can defer
|
|
196
|
+
|
|
197
|
+
### Update Workflow
|
|
198
|
+
1. Check `manifest_version` against installed version
|
|
199
|
+
2. If newer version available, proceed to verify step
|
|
200
|
+
3. For each hook/skill:
|
|
201
|
+
- Compute current checksum
|
|
202
|
+
- Compare with manifest checksum
|
|
203
|
+
- If modified: warn user or skip (respect customizations)
|
|
204
|
+
- If unmodified and priority is high/critical: update
|
|
205
|
+
4. After updates, recompute checksums
|
|
206
|
+
5. Update manifest with new version
|
|
207
|
+
|
|
208
|
+
## Best Practices
|
|
209
|
+
|
|
210
|
+
### For Stravinsky Maintainers
|
|
211
|
+
1. **Always update manifests on release** - Use `scripts/generate_manifests.py`
|
|
212
|
+
2. **Document hook changes** - Update descriptions if functionality changes
|
|
213
|
+
3. **Keep checksums current** - Run verification script before commits
|
|
214
|
+
4. **Track dependencies** - Add any new hook dependencies to manifest
|
|
215
|
+
5. **Test manifest generation** - Validate JSON before commit
|
|
216
|
+
|
|
217
|
+
### For Package Users
|
|
218
|
+
1. **Don't edit manifests manually** - Let automated tools manage them
|
|
219
|
+
2. **Preserve customizations** - Store custom hooks in `.claude/hooks/` instead
|
|
220
|
+
3. **Check authentication** - Skills requiring auth need OAuth setup
|
|
221
|
+
4. **Review update notes** - Read manifest notes for important context
|
|
222
|
+
|
|
223
|
+
### For Hook Developers
|
|
224
|
+
1. **Add to manifest immediately** - New hooks must be in manifest
|
|
225
|
+
2. **Include checksum** - Use `sha256sum | awk '{print substr($1,1,12)}'`
|
|
226
|
+
3. **Document dependencies** - List all other hooks/modules needed
|
|
227
|
+
4. **Test locally** - Verify hook works before adding to manifest
|
|
228
|
+
5. **Update version field** - Bump manifest version on release
|
|
229
|
+
|
|
230
|
+
## Troubleshooting
|
|
231
|
+
|
|
232
|
+
### Manifest JSON is invalid
|
|
233
|
+
```bash
|
|
234
|
+
# Validate JSON syntax
|
|
235
|
+
python -m json.tool mcp_bridge/config/hooks_manifest.json > /dev/null
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Checksums don't match
|
|
239
|
+
```bash
|
|
240
|
+
# Regenerate checksums
|
|
241
|
+
python scripts/generate_manifests.py --recalc-checksums
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Missing hooks in manifest
|
|
245
|
+
```bash
|
|
246
|
+
# List all hooks not in manifest
|
|
247
|
+
diff <(ls mcp_bridge/hooks/*.py | sed 's/.*\///' | sort) \
|
|
248
|
+
<(jq -r '.hooks | keys[]' mcp_bridge/config/hooks_manifest.json | sort)
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Update fails for a hook
|
|
252
|
+
1. Check file permissions: `ls -l mcp_bridge/hooks/hook_name.py`
|
|
253
|
+
2. Verify checksum: Compare current vs manifest
|
|
254
|
+
3. Check dependencies: Ensure all are installed
|
|
255
|
+
4. Review logs: Look for error messages in update output
|
|
256
|
+
|
|
257
|
+
## Related Files
|
|
258
|
+
|
|
259
|
+
- `mcp_bridge/__init__.py` - Package version
|
|
260
|
+
- `mcp_bridge/hooks/manager.py` - Hook execution system
|
|
261
|
+
- `mcp_bridge/cli/install_hooks.py` - Hook installation
|
|
262
|
+
- `.claude/settings.json` - Hook configuration
|
|
263
|
+
- `pyproject.toml` - Package metadata
|
|
264
|
+
|
|
265
|
+
## Version History
|
|
266
|
+
|
|
267
|
+
### v1.0.0 (Current)
|
|
268
|
+
- Initial manifest schema
|
|
269
|
+
- 32 hooks tracked
|
|
270
|
+
- 16 skills tracked
|
|
271
|
+
- SHA-256 checksum verification
|
|
272
|
+
- Priority-based update strategy
|
|
273
|
+
|
|
274
|
+
## Questions?
|
|
275
|
+
|
|
276
|
+
See **MANIFEST_SCHEMA.md** for detailed documentation.
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Hook configuration with selective disabling support.
|
|
3
|
+
|
|
4
|
+
Provides batteries-included defaults with user-configurable overrides.
|
|
5
|
+
Users can disable specific hooks via ~/.stravinsky/disable_hooks.txt
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Set, Optional
|
|
11
|
+
import logging
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
# Default locations for disable hooks config
|
|
16
|
+
DISABLE_HOOKS_PATHS = [
|
|
17
|
+
Path.home() / ".stravinsky" / "disable_hooks.txt",
|
|
18
|
+
Path(".stravinsky") / "disable_hooks.txt",
|
|
19
|
+
Path(".claude") / "disable_hooks.txt",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def get_disabled_hooks() -> Set[str]:
|
|
24
|
+
"""
|
|
25
|
+
Load disabled hooks from config files.
|
|
26
|
+
|
|
27
|
+
Checks (in order):
|
|
28
|
+
1. ~/.stravinsky/disable_hooks.txt (user global)
|
|
29
|
+
2. .stravinsky/disable_hooks.txt (project local)
|
|
30
|
+
3. .claude/disable_hooks.txt (claude project local)
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
Set of hook names that should be disabled.
|
|
34
|
+
"""
|
|
35
|
+
disabled = set()
|
|
36
|
+
|
|
37
|
+
for path in DISABLE_HOOKS_PATHS:
|
|
38
|
+
if path.exists():
|
|
39
|
+
try:
|
|
40
|
+
content = path.read_text()
|
|
41
|
+
for line in content.splitlines():
|
|
42
|
+
line = line.strip()
|
|
43
|
+
# Skip comments and empty lines
|
|
44
|
+
if line and not line.startswith("#"):
|
|
45
|
+
disabled.add(line)
|
|
46
|
+
logger.debug(f"Loaded disabled hooks from {path}: {disabled}")
|
|
47
|
+
except Exception as e:
|
|
48
|
+
logger.warning(f"Failed to read {path}: {e}")
|
|
49
|
+
|
|
50
|
+
return disabled
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def is_hook_enabled(hook_name: str) -> bool:
|
|
54
|
+
"""
|
|
55
|
+
Check if a specific hook is enabled.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
hook_name: Name of the hook (e.g., 'comment_checker', 'session_recovery')
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
True if the hook is enabled (not in disable list), False otherwise.
|
|
62
|
+
"""
|
|
63
|
+
disabled = get_disabled_hooks()
|
|
64
|
+
return hook_name not in disabled
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def get_hook_config_path() -> Path:
|
|
68
|
+
"""
|
|
69
|
+
Get the path to the user's hook config directory.
|
|
70
|
+
Creates it if it doesn't exist.
|
|
71
|
+
"""
|
|
72
|
+
config_dir = Path.home() / ".stravinsky"
|
|
73
|
+
config_dir.mkdir(parents=True, exist_ok=True)
|
|
74
|
+
return config_dir
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def create_sample_disable_hooks() -> Optional[Path]:
|
|
78
|
+
"""
|
|
79
|
+
Create a sample disable_hooks.txt file with documentation.
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
Path to the created file, or None if it already exists.
|
|
83
|
+
"""
|
|
84
|
+
config_dir = get_hook_config_path()
|
|
85
|
+
disable_file = config_dir / "disable_hooks.txt"
|
|
86
|
+
|
|
87
|
+
if disable_file.exists():
|
|
88
|
+
return None
|
|
89
|
+
|
|
90
|
+
sample_content = """# Stravinsky Hook Disabling Configuration
|
|
91
|
+
# Add hook names (one per line) to disable them.
|
|
92
|
+
# Lines starting with # are comments.
|
|
93
|
+
#
|
|
94
|
+
# Available hooks:
|
|
95
|
+
# ================
|
|
96
|
+
#
|
|
97
|
+
# PreToolUse Hooks:
|
|
98
|
+
# - comment_checker (checks git commit comments for quality)
|
|
99
|
+
# - stravinsky_mode (blocks direct tool calls, forces delegation)
|
|
100
|
+
# - notification_hook (displays agent spawn notifications)
|
|
101
|
+
#
|
|
102
|
+
# PostToolUse Hooks:
|
|
103
|
+
# - session_recovery (detects API errors and logs recovery info)
|
|
104
|
+
# - parallel_execution (injects parallel execution instructions)
|
|
105
|
+
# - todo_delegation (enforces parallel Task spawning for todos)
|
|
106
|
+
# - tool_messaging (user-friendly MCP tool messages)
|
|
107
|
+
# - edit_recovery (suggests recovery for Edit failures)
|
|
108
|
+
# - truncator (truncates long responses)
|
|
109
|
+
# - subagent_stop (handles subagent completion)
|
|
110
|
+
#
|
|
111
|
+
# UserPromptSubmit Hooks:
|
|
112
|
+
# - context (injects CLAUDE.md content)
|
|
113
|
+
# - todo_continuation (reminds about incomplete todos)
|
|
114
|
+
#
|
|
115
|
+
# PreCompact Hooks:
|
|
116
|
+
# - pre_compact (preserves critical context before compaction)
|
|
117
|
+
#
|
|
118
|
+
# Example - to disable the comment checker:
|
|
119
|
+
# comment_checker
|
|
120
|
+
#
|
|
121
|
+
# Example - to disable ultrawork mode detection:
|
|
122
|
+
# parallel_execution
|
|
123
|
+
"""
|
|
124
|
+
|
|
125
|
+
disable_file.write_text(sample_content)
|
|
126
|
+
logger.info(f"Created sample disable_hooks.txt at {disable_file}")
|
|
127
|
+
return disable_file
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
# Hook metadata for batteries-included config
|
|
131
|
+
HOOK_DEFAULTS = {
|
|
132
|
+
# PreToolUse hooks
|
|
133
|
+
"comment_checker": {
|
|
134
|
+
"type": "PreToolUse",
|
|
135
|
+
"description": "Checks git commit comments for quality issues",
|
|
136
|
+
"default_enabled": True,
|
|
137
|
+
"exit_on_block": 0, # Warn but don't block
|
|
138
|
+
},
|
|
139
|
+
"stravinsky_mode": {
|
|
140
|
+
"type": "PreToolUse",
|
|
141
|
+
"description": "Blocks direct tool calls, forces Task delegation",
|
|
142
|
+
"default_enabled": True,
|
|
143
|
+
"exit_on_block": 2, # Hard block
|
|
144
|
+
},
|
|
145
|
+
"notification_hook": {
|
|
146
|
+
"type": "PreToolUse",
|
|
147
|
+
"description": "Displays agent spawn notifications",
|
|
148
|
+
"default_enabled": True,
|
|
149
|
+
"exit_on_block": 0,
|
|
150
|
+
},
|
|
151
|
+
# PostToolUse hooks
|
|
152
|
+
"session_recovery": {
|
|
153
|
+
"type": "PostToolUse",
|
|
154
|
+
"description": "Detects API errors and logs recovery suggestions",
|
|
155
|
+
"default_enabled": True,
|
|
156
|
+
"exit_on_block": 0,
|
|
157
|
+
},
|
|
158
|
+
"parallel_execution": {
|
|
159
|
+
"type": "PostToolUse",
|
|
160
|
+
"description": "Injects parallel execution and ULTRAWORK mode",
|
|
161
|
+
"default_enabled": True,
|
|
162
|
+
"exit_on_block": 0,
|
|
163
|
+
},
|
|
164
|
+
"todo_delegation": {
|
|
165
|
+
"type": "PostToolUse",
|
|
166
|
+
"description": "Enforces parallel Task spawning for 2+ todos",
|
|
167
|
+
"default_enabled": True,
|
|
168
|
+
"exit_on_block": 2, # Hard block in stravinsky mode
|
|
169
|
+
},
|
|
170
|
+
"tool_messaging": {
|
|
171
|
+
"type": "PostToolUse",
|
|
172
|
+
"description": "User-friendly messages for MCP tools",
|
|
173
|
+
"default_enabled": True,
|
|
174
|
+
"exit_on_block": 0,
|
|
175
|
+
},
|
|
176
|
+
"edit_recovery": {
|
|
177
|
+
"type": "PostToolUse",
|
|
178
|
+
"description": "Suggests recovery for Edit failures",
|
|
179
|
+
"default_enabled": True,
|
|
180
|
+
"exit_on_block": 0,
|
|
181
|
+
},
|
|
182
|
+
"truncator": {
|
|
183
|
+
"type": "PostToolUse",
|
|
184
|
+
"description": "Truncates responses longer than 30k chars",
|
|
185
|
+
"default_enabled": True,
|
|
186
|
+
"exit_on_block": 0,
|
|
187
|
+
},
|
|
188
|
+
"subagent_stop": {
|
|
189
|
+
"type": "SubagentStop",
|
|
190
|
+
"description": "Handles subagent completion events",
|
|
191
|
+
"default_enabled": True,
|
|
192
|
+
"exit_on_block": 0,
|
|
193
|
+
},
|
|
194
|
+
# UserPromptSubmit hooks
|
|
195
|
+
"context": {
|
|
196
|
+
"type": "UserPromptSubmit",
|
|
197
|
+
"description": "Injects CLAUDE.md content to prompts",
|
|
198
|
+
"default_enabled": True,
|
|
199
|
+
"exit_on_block": 0,
|
|
200
|
+
},
|
|
201
|
+
"todo_continuation": {
|
|
202
|
+
"type": "UserPromptSubmit",
|
|
203
|
+
"description": "Reminds about incomplete todos",
|
|
204
|
+
"default_enabled": True,
|
|
205
|
+
"exit_on_block": 0,
|
|
206
|
+
},
|
|
207
|
+
# PreCompact hooks
|
|
208
|
+
"pre_compact": {
|
|
209
|
+
"type": "PreCompact",
|
|
210
|
+
"description": "Preserves critical context before compaction",
|
|
211
|
+
"default_enabled": True,
|
|
212
|
+
"exit_on_block": 0,
|
|
213
|
+
},
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def get_enabled_hooks() -> dict:
|
|
218
|
+
"""
|
|
219
|
+
Get all enabled hooks with their configuration.
|
|
220
|
+
|
|
221
|
+
Returns:
|
|
222
|
+
Dict of hook_name -> hook_config for enabled hooks only.
|
|
223
|
+
"""
|
|
224
|
+
disabled = get_disabled_hooks()
|
|
225
|
+
enabled = {}
|
|
226
|
+
|
|
227
|
+
for hook_name, config in HOOK_DEFAULTS.items():
|
|
228
|
+
if hook_name not in disabled and config.get("default_enabled", True):
|
|
229
|
+
enabled[hook_name] = config
|
|
230
|
+
|
|
231
|
+
return enabled
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def list_hooks() -> str:
|
|
235
|
+
"""
|
|
236
|
+
List all hooks with their status.
|
|
237
|
+
|
|
238
|
+
Returns:
|
|
239
|
+
Formatted string showing hook status.
|
|
240
|
+
"""
|
|
241
|
+
disabled = get_disabled_hooks()
|
|
242
|
+
lines = ["# Stravinsky Hooks Status", ""]
|
|
243
|
+
|
|
244
|
+
for hook_name, config in sorted(HOOK_DEFAULTS.items()):
|
|
245
|
+
status = "DISABLED" if hook_name in disabled else "enabled"
|
|
246
|
+
icon = "" if hook_name in disabled else ""
|
|
247
|
+
lines.append(f"{icon} {hook_name}: {status} - {config['description']}")
|
|
248
|
+
|
|
249
|
+
return "\n".join(lines)
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_version": "1.0.0",
|
|
3
|
+
"manifest_version": "0.3.9",
|
|
4
|
+
"description": "Stravinsky hooks for Claude Code integration",
|
|
5
|
+
"generated_date": "2026-01-08T23:53:08.836595Z",
|
|
6
|
+
"hooks": {
|
|
7
|
+
"context.py": {
|
|
8
|
+
"version": "0.3.9",
|
|
9
|
+
"source": "mcp_bridge/hooks/context.py",
|
|
10
|
+
"description": "Project context injection from local files",
|
|
11
|
+
"checksum": "2411ea9d7ef9",
|
|
12
|
+
"lines_of_code": 38,
|
|
13
|
+
"updatable": true,
|
|
14
|
+
"priority": "high",
|
|
15
|
+
"required": true
|
|
16
|
+
},
|
|
17
|
+
"context_monitor.py": {
|
|
18
|
+
"version": "0.3.9",
|
|
19
|
+
"source": "mcp_bridge/hooks/context_monitor.py",
|
|
20
|
+
"description": "Pre-emptive context optimization at 70% threshold",
|
|
21
|
+
"checksum": "7a8d0615af4f",
|
|
22
|
+
"lines_of_code": 153,
|
|
23
|
+
"updatable": true,
|
|
24
|
+
"priority": "high",
|
|
25
|
+
"required": true
|
|
26
|
+
},
|
|
27
|
+
"edit_recovery.py": {
|
|
28
|
+
"version": "0.3.9",
|
|
29
|
+
"source": "mcp_bridge/hooks/edit_recovery.py",
|
|
30
|
+
"description": "Edit/MultiEdit error recovery helper",
|
|
31
|
+
"checksum": "d4e5a96f7bfc",
|
|
32
|
+
"lines_of_code": 46,
|
|
33
|
+
"updatable": true,
|
|
34
|
+
"priority": "high",
|
|
35
|
+
"required": true
|
|
36
|
+
},
|
|
37
|
+
"notification_hook.py": {
|
|
38
|
+
"version": "0.3.9",
|
|
39
|
+
"source": "mcp_bridge/hooks/notification_hook.py",
|
|
40
|
+
"description": "Agent spawn message formatting",
|
|
41
|
+
"checksum": "184947c5a227",
|
|
42
|
+
"lines_of_code": 103,
|
|
43
|
+
"updatable": true,
|
|
44
|
+
"priority": "high",
|
|
45
|
+
"required": true
|
|
46
|
+
},
|
|
47
|
+
"parallel_execution.py": {
|
|
48
|
+
"version": "0.3.9",
|
|
49
|
+
"source": "mcp_bridge/hooks/parallel_execution.py",
|
|
50
|
+
"description": "Pre-emptive parallel execution enforcement",
|
|
51
|
+
"checksum": "9c820d3d19be",
|
|
52
|
+
"lines_of_code": 111,
|
|
53
|
+
"updatable": true,
|
|
54
|
+
"priority": "high",
|
|
55
|
+
"required": true
|
|
56
|
+
},
|
|
57
|
+
"pre_compact.py": {
|
|
58
|
+
"version": "0.3.9",
|
|
59
|
+
"source": "mcp_bridge/hooks/pre_compact.py",
|
|
60
|
+
"description": "Context preservation before compaction",
|
|
61
|
+
"checksum": "4177023bd901",
|
|
62
|
+
"lines_of_code": 123,
|
|
63
|
+
"updatable": true,
|
|
64
|
+
"priority": "high",
|
|
65
|
+
"required": true
|
|
66
|
+
},
|
|
67
|
+
"stop_hook.py": {
|
|
68
|
+
"version": "0.3.9",
|
|
69
|
+
"source": "mcp_bridge/hooks/stop_hook.py",
|
|
70
|
+
"description": "Continuation loop handler",
|
|
71
|
+
"checksum": "820aef797e2e",
|
|
72
|
+
"lines_of_code": 234,
|
|
73
|
+
"updatable": true,
|
|
74
|
+
"priority": "high",
|
|
75
|
+
"required": true
|
|
76
|
+
},
|
|
77
|
+
"stravinsky_mode.py": {
|
|
78
|
+
"version": "0.3.9",
|
|
79
|
+
"source": "mcp_bridge/hooks/stravinsky_mode.py",
|
|
80
|
+
"description": "Hard blocking of native tools",
|
|
81
|
+
"checksum": "5968a95ebcbe",
|
|
82
|
+
"lines_of_code": 146,
|
|
83
|
+
"updatable": true,
|
|
84
|
+
"priority": "high",
|
|
85
|
+
"required": true
|
|
86
|
+
},
|
|
87
|
+
"subagent_stop.py": {
|
|
88
|
+
"version": "0.3.9",
|
|
89
|
+
"source": "mcp_bridge/hooks/subagent_stop.py",
|
|
90
|
+
"description": "Subagent completion handler",
|
|
91
|
+
"checksum": "1943d8dc5355",
|
|
92
|
+
"lines_of_code": 98,
|
|
93
|
+
"updatable": true,
|
|
94
|
+
"priority": "high",
|
|
95
|
+
"required": true
|
|
96
|
+
},
|
|
97
|
+
"todo_continuation.py": {
|
|
98
|
+
"version": "0.3.9",
|
|
99
|
+
"source": "mcp_bridge/hooks/todo_continuation.py",
|
|
100
|
+
"description": "Todo continuation enforcer",
|
|
101
|
+
"checksum": "b6685355f319",
|
|
102
|
+
"lines_of_code": 90,
|
|
103
|
+
"updatable": true,
|
|
104
|
+
"priority": "high",
|
|
105
|
+
"required": true
|
|
106
|
+
},
|
|
107
|
+
"todo_delegation.py": {
|
|
108
|
+
"version": "0.3.9",
|
|
109
|
+
"source": "mcp_bridge/hooks/todo_delegation.py",
|
|
110
|
+
"description": "Parallel task spawning enforcement",
|
|
111
|
+
"checksum": "b4e004d51600",
|
|
112
|
+
"lines_of_code": 88,
|
|
113
|
+
"updatable": true,
|
|
114
|
+
"priority": "high",
|
|
115
|
+
"required": true
|
|
116
|
+
},
|
|
117
|
+
"tool_messaging.py": {
|
|
118
|
+
"version": "0.3.9",
|
|
119
|
+
"source": "mcp_bridge/hooks/tool_messaging.py",
|
|
120
|
+
"description": "User-friendly tool messaging",
|
|
121
|
+
"checksum": "04a10e76f890",
|
|
122
|
+
"lines_of_code": 263,
|
|
123
|
+
"updatable": true,
|
|
124
|
+
"priority": "high",
|
|
125
|
+
"required": true
|
|
126
|
+
},
|
|
127
|
+
"truncator.py": {
|
|
128
|
+
"version": "0.3.9",
|
|
129
|
+
"source": "mcp_bridge/hooks/truncator.py",
|
|
130
|
+
"description": "Tool response truncation at 30k chars",
|
|
131
|
+
"checksum": "87785bf2c657",
|
|
132
|
+
"lines_of_code": 23,
|
|
133
|
+
"updatable": true,
|
|
134
|
+
"priority": "high",
|
|
135
|
+
"required": true
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|