stravinsky 0.4.36__tar.gz → 0.4.41__tar.gz
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.
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/agents/stravinsky.md +3 -3
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/commands/strav.md +12 -12
- stravinsky-0.4.41/.claude/hooks/README.md +248 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/hooks/context_monitor.py +1 -1
- stravinsky-0.4.41/.claude/hooks/dependency_tracker.py +73 -0
- stravinsky-0.4.41/.claude/hooks/execution_state_tracker.py +68 -0
- stravinsky-0.4.41/.claude/hooks/notification_hook_v2.py +96 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/hooks/parallel_execution.py +21 -21
- stravinsky-0.4.41/.claude/hooks/parallel_reinforcement.py +106 -0
- stravinsky-0.4.41/.claude/hooks/parallel_reinforcement_v2.py +112 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/hooks/pre_compact.py +1 -1
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/hooks/tool_messaging.py +17 -6
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/rules/pypi_deployment.md +1 -1
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/settings.json +8 -45
- stravinsky-0.4.41/.claude/task_dependencies.json +9 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.gitignore +2 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/PKG-INFO +20 -12
- {stravinsky-0.4.36 → stravinsky-0.4.41}/README.md +19 -11
- stravinsky-0.4.41/mcp_bridge/__init__.py +1 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/cli/install_hooks.py +2 -2
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/config/hook_config.py +2 -2
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/keyword_detector.py +6 -6
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/parallel_execution.py +1 -1
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/pre_compact.py +1 -1
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/prompts/dewey.py +1 -1
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/prompts/stravinsky.py +10 -10
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/server.py +96 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/tools/agent_manager.py +22 -9
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/tools/model_invoke.py +23 -18
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/tools/semantic_search.py +7 -7
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/tools/task_runner.py +1 -1
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/tools/templates.py +3 -3
- {stravinsky-0.4.36 → stravinsky-0.4.41}/pyproject.toml +13 -1
- stravinsky-0.4.36/.claude/hooks/parallel_reinforcement.py +0 -85
- stravinsky-0.4.36/.coverage +0 -0
- stravinsky-0.4.36/.github/workflows/publish.yml +0 -37
- stravinsky-0.4.36/.stravinsky/agents/agent_22ea4fd7.log +0 -1
- stravinsky-0.4.36/.stravinsky/agents/agent_2adee6b3.log +0 -1
- stravinsky-0.4.36/.stravinsky/agents/agent_2f19ccb0.log +0 -1
- stravinsky-0.4.36/.stravinsky/agents/agent_4312ce18.log +0 -1
- stravinsky-0.4.36/.stravinsky/agents/agent_4efc8f46.log +0 -1
- stravinsky-0.4.36/.stravinsky/agents/agent_61c9181c.log +0 -1
- stravinsky-0.4.36/.stravinsky/agents/agent_61f58446.log +0 -1
- stravinsky-0.4.36/.stravinsky/agents/agent_64e18f27.log +0 -1
- stravinsky-0.4.36/.stravinsky/agents/agent_6510e677.log +0 -1
- stravinsky-0.4.36/.stravinsky/agents/agent_70ddf50b.log +0 -1
- stravinsky-0.4.36/.stravinsky/agents/agent_7afbeeb2.log +0 -1
- stravinsky-0.4.36/.stravinsky/agents/agent_7bf8bd61.log +0 -1
- stravinsky-0.4.36/.stravinsky/agents/agent_7c4c4581.log +0 -1
- stravinsky-0.4.36/.stravinsky/agents/agent_91993dfa.log +0 -1
- stravinsky-0.4.36/.stravinsky/agents/agent_a0bd5fb4.log +0 -1
- stravinsky-0.4.36/.stravinsky/agents/agent_a500ada6.log +0 -1
- stravinsky-0.4.36/.stravinsky/agents/agent_abc732c9.log +0 -1
- stravinsky-0.4.36/.stravinsky/agents/agent_b9c789bd.log +0 -1
- stravinsky-0.4.36/.stravinsky/agents/agent_c061a891.log +0 -1
- stravinsky-0.4.36/.stravinsky/agents/agent_c1671b80.log +0 -1
- stravinsky-0.4.36/.stravinsky/agents/agent_c95f8211.log +0 -1
- stravinsky-0.4.36/.stravinsky/agents/agent_d4e46c9b.log +0 -1
- stravinsky-0.4.36/.stravinsky/agents/agent_d80fba02.log +0 -1
- stravinsky-0.4.36/.stravinsky/agents/agent_ed55bb33.log +0 -1
- stravinsky-0.4.36/.stravinsky/agents/agent_f90a5968.log +0 -1
- stravinsky-0.4.36/.stravinsky/mcp_mode +0 -1
- stravinsky-0.4.36/ARCHITECTURE.md +0 -1133
- stravinsky-0.4.36/ARCHITECTURE_FLOWS.md +0 -599
- stravinsky-0.4.36/ARCHITECTURE_MAP.md +0 -715
- stravinsky-0.4.36/AUTO_INDEXING_TEST_SUMMARY.md +0 -353
- stravinsky-0.4.36/BASELINE_INDEX.md +0 -363
- stravinsky-0.4.36/BASELINE_SUMMARY.md +0 -303
- stravinsky-0.4.36/CLAUDE.md +0 -279
- stravinsky-0.4.36/COMPREHENSIVE_TEST_IMPLEMENTATION.txt +0 -602
- stravinsky-0.4.36/COVERAGE_REPORT.md +0 -226
- stravinsky-0.4.36/DELEGATION_FLOW_VERIFICATION.md +0 -437
- stravinsky-0.4.36/FILEWATCHER_DOCS_UPDATE_SUMMARY.md +0 -186
- stravinsky-0.4.36/FILEWATCHER_README.md +0 -413
- stravinsky-0.4.36/INSTALL.md +0 -484
- stravinsky-0.4.36/LSP_CLEANUP_FIX.md +0 -141
- stravinsky-0.4.36/MANUAL_TESTING_CHECKLIST.md +0 -368
- stravinsky-0.4.36/TESTING_AUTO_INDEXING.md +0 -348
- stravinsky-0.4.36/TESTING_SUMMARY_FINAL.md +0 -234
- stravinsky-0.4.36/TEST_ARTIFACTS_README.md +0 -430
- stravinsky-0.4.36/TEST_COVERAGE_INVOKE_GEMINI_AGENTIC.md +0 -144
- stravinsky-0.4.36/TEST_EXECUTION_REPORT.md +0 -157
- stravinsky-0.4.36/TEST_PLAN_AUTO_INDEXING.md +0 -500
- stravinsky-0.4.36/assets/logo.png +0 -0
- stravinsky-0.4.36/assets/logo.png.txt +0 -2
- stravinsky-0.4.36/assets/logo_small.png +0 -0
- stravinsky-0.4.36/auth0.txt +0 -1
- stravinsky-0.4.36/deploy.sh +0 -215
- stravinsky-0.4.36/docs/AGENTS.md +0 -382
- stravinsky-0.4.36/docs/AGENT_WORKFLOW.md +0 -974
- stravinsky-0.4.36/docs/CALL_FLOW_DIAGRAM.txt +0 -168
- stravinsky-0.4.36/docs/COMMANDS_CONSOLIDATION_REPORT.md +0 -310
- stravinsky-0.4.36/docs/COMMANDS_QUICK_SUMMARY.md +0 -114
- stravinsky-0.4.36/docs/DEPLOYMENT.md +0 -121
- stravinsky-0.4.36/docs/FILEWATCHER_ARCHITECTURE.md +0 -530
- stravinsky-0.4.36/docs/FILEWATCHER_IMPLEMENTATION_SUMMARY.md +0 -375
- stravinsky-0.4.36/docs/FILE_WATCHER.md +0 -357
- stravinsky-0.4.36/docs/GEMINI_API_KEY_USAGE.md +0 -280
- stravinsky-0.4.36/docs/HOOKS.md +0 -277
- stravinsky-0.4.36/docs/HOOKS_INSTALLATION.md +0 -194
- stravinsky-0.4.36/docs/IMPLEMENTATION_PLAN.md +0 -768
- stravinsky-0.4.36/docs/INDEX_TOOL_CALL_LOGGING.md +0 -189
- stravinsky-0.4.36/docs/INJECTION_POINT_CODE_LOCATIONS.txt +0 -322
- stravinsky-0.4.36/docs/INSTALL.md +0 -370
- stravinsky-0.4.36/docs/INTELLIGENT_SEARCH_DESIGN.md +0 -650
- stravinsky-0.4.36/docs/KEYRING_AUTH_FIX.md +0 -216
- stravinsky-0.4.36/docs/LSP_MIGRATION_GUIDE.md +0 -1452
- stravinsky-0.4.36/docs/MCP_TOOL_CALL_INJECTION_POINTS.md +0 -377
- stravinsky-0.4.36/docs/MODEL_ROUTING.md +0 -72
- stravinsky-0.4.36/docs/PARALLEL_EXECUTION_FIX.md +0 -247
- stravinsky-0.4.36/docs/QUERY_CLASSIFIER_DESIGN.md +0 -533
- stravinsky-0.4.36/docs/QUICKSTART.md +0 -127
- stravinsky-0.4.36/docs/QUICK_REFERENCE_INJECTION_POINTS.md +0 -97
- stravinsky-0.4.36/docs/README.md +0 -79
- stravinsky-0.4.36/docs/README_COMMANDS_ANALYSIS.md +0 -180
- stravinsky-0.4.36/docs/README_filewatcher.md +0 -213
- stravinsky-0.4.36/docs/REPORT_INDEX.txt +0 -189
- stravinsky-0.4.36/docs/SEARCH_STRATEGY_TEST_SUITE.md +0 -308
- stravinsky-0.4.36/docs/SEARCH_TOOLS_ANALYSIS.md +0 -826
- stravinsky-0.4.36/docs/SEMANTIC_INDEXING_INDEX.md +0 -214
- stravinsky-0.4.36/docs/SEMANTIC_SEARCH_BEST_PRACTICES.md +0 -1392
- stravinsky-0.4.36/docs/SEMANTIC_SEARCH_QUICK_START.md +0 -215
- stravinsky-0.4.36/docs/SEMANTIC_SEARCH_TESTING_INDEX.md +0 -278
- stravinsky-0.4.36/docs/SEMANTIC_SEARCH_TEST_REPORT.md +0 -225
- stravinsky-0.4.36/docs/SEMANTIC_WATCHER_USAGE.md +0 -400
- stravinsky-0.4.36/docs/TEMPLATES_STRUCTURE.md +0 -170
- stravinsky-0.4.36/docs/TROUBLESHOOTING.md +0 -382
- stravinsky-0.4.36/docs/USAGE.md +0 -537
- stravinsky-0.4.36/docs/architecture_workflow.md +0 -157
- stravinsky-0.4.36/docs/filewatcher_design_summary.md +0 -287
- stravinsky-0.4.36/docs/filewatcher_integration_design.md +0 -606
- stravinsky-0.4.36/docs/filewatcher_quick_reference.md +0 -448
- stravinsky-0.4.36/docs/remediation_plan.md +0 -38
- stravinsky-0.4.36/docs/semantic_indexing_analysis.md +0 -444
- stravinsky-0.4.36/docs/semantic_indexing_quick_start.md +0 -422
- stravinsky-0.4.36/error.log +0 -4
- stravinsky-0.4.36/htmlcov/.gitignore +0 -2
- stravinsky-0.4.36/htmlcov/class_index.html +0 -411
- stravinsky-0.4.36/htmlcov/coverage_html_cb_6fb7b396.js +0 -733
- stravinsky-0.4.36/htmlcov/favicon_32_cb_58284776.png +0 -0
- stravinsky-0.4.36/htmlcov/function_index.html +0 -2059
- stravinsky-0.4.36/htmlcov/index.html +0 -223
- stravinsky-0.4.36/htmlcov/keybd_closed_cb_ce680311.png +0 -0
- stravinsky-0.4.36/htmlcov/status.json +0 -1
- stravinsky-0.4.36/htmlcov/style_cb_6b508a39.css +0 -377
- stravinsky-0.4.36/htmlcov/z_bb9220b593e8850a___init___py.html +0 -133
- stravinsky-0.4.36/htmlcov/z_bb9220b593e8850a_manager_py.html +0 -539
- stravinsky-0.4.36/htmlcov/z_bb9220b593e8850a_tools_py.html +0 -1110
- stravinsky-0.4.36/htmlcov/z_bbf7571ef27a4a09___init___py.html +0 -146
- stravinsky-0.4.36/htmlcov/z_bbf7571ef27a4a09_agent_manager_py.html +0 -1218
- stravinsky-0.4.36/htmlcov/z_bbf7571ef27a4a09_background_tasks_py.html +0 -260
- stravinsky-0.4.36/htmlcov/z_bbf7571ef27a4a09_code_search_py.html +0 -483
- stravinsky-0.4.36/htmlcov/z_bbf7571ef27a4a09_continuous_loop_py.html +0 -163
- stravinsky-0.4.36/htmlcov/z_bbf7571ef27a4a09_init_py.html +0 -148
- stravinsky-0.4.36/htmlcov/z_bbf7571ef27a4a09_model_invoke_py.html +0 -1457
- stravinsky-0.4.36/htmlcov/z_bbf7571ef27a4a09_project_context_py.html +0 -237
- stravinsky-0.4.36/htmlcov/z_bbf7571ef27a4a09_query_classifier_py.html +0 -420
- stravinsky-0.4.36/htmlcov/z_bbf7571ef27a4a09_semantic_search_py.html +0 -3418
- stravinsky-0.4.36/htmlcov/z_bbf7571ef27a4a09_session_manager_py.html +0 -397
- stravinsky-0.4.36/htmlcov/z_bbf7571ef27a4a09_skill_loader_py.html +0 -312
- stravinsky-0.4.36/htmlcov/z_bbf7571ef27a4a09_task_runner_py.html +0 -236
- stravinsky-0.4.36/htmlcov/z_bbf7571ef27a4a09_templates_py.html +0 -286
- stravinsky-0.4.36/jwt_io.txt +0 -1
- stravinsky-0.4.36/mcp_bridge/__init__.py +0 -1
- stravinsky-0.4.36/owasp.txt +0 -1
- stravinsky-0.4.36/pre_deploy_check.sh +0 -126
- stravinsky-0.4.36/repro_spawn.py +0 -29
- stravinsky-0.4.36/rfc7519.txt +0 -1
- stravinsky-0.4.36/run-mcp.sh +0 -3
- stravinsky-0.4.36/security_advisory.txt +0 -1
- stravinsky-0.4.36/stdout_handshake_auditor.py +0 -85
- stravinsky-0.4.36/test_agentic_api.py +0 -64
- stravinsky-0.4.36/test_auth_visibility.py +0 -100
- stravinsky-0.4.36/test_coverage_report.md +0 -206
- stravinsky-0.4.36/test_lsp_cleanup.py +0 -103
- stravinsky-0.4.36/test_lsp_manager.py +0 -307
- stravinsky-0.4.36/test_plan_uncovered_tools.md +0 -868
- stravinsky-0.4.36/tests/MANUAL_TEST_GUIDE.md +0 -414
- stravinsky-0.4.36/tests/QUERY_CLASSIFICATION_GUIDE.md +0 -375
- stravinsky-0.4.36/tests/QUICK_REFERENCE.md +0 -165
- stravinsky-0.4.36/tests/README.md +0 -89
- stravinsky-0.4.36/tests/README_AUTO_INDEXING_TESTS.md +0 -354
- stravinsky-0.4.36/tests/README_LSP_TESTS.md +0 -259
- stravinsky-0.4.36/tests/README_QUERY_CLASSIFICATION.md +0 -344
- stravinsky-0.4.36/tests/TEST_IMPLEMENTATION_SUMMARY.md +0 -391
- stravinsky-0.4.36/tests/TEST_RESULTS_direct_gemini.md +0 -299
- stravinsky-0.4.36/tests/conftest.py +0 -8
- stravinsky-0.4.36/tests/manual_test_auto_indexing.py +0 -788
- stravinsky-0.4.36/tests/manual_test_hooks.py +0 -57
- stravinsky-0.4.36/tests/test_agent_manager.py +0 -834
- stravinsky-0.4.36/tests/test_api_key_auth.py +0 -134
- stravinsky-0.4.36/tests/test_auto_indexing.py +0 -665
- stravinsky-0.4.36/tests/test_code_search.py +0 -780
- stravinsky-0.4.36/tests/test_direct_gemini.py +0 -321
- stravinsky-0.4.36/tests/test_file_watcher.py +0 -349
- stravinsky-0.4.36/tests/test_file_watcher_no_index.py +0 -404
- stravinsky-0.4.36/tests/test_hooks.py +0 -29
- stravinsky-0.4.36/tests/test_invoke_gemini_agentic.py +0 -926
- stravinsky-0.4.36/tests/test_lsp_tools.py +0 -730
- stravinsky-0.4.36/tests/test_mcp_server_integration.py +0 -169
- stravinsky-0.4.36/tests/test_new_hooks.py +0 -330
- stravinsky-0.4.36/tests/test_query_classification.py +0 -982
- stravinsky-0.4.36/tests/test_query_classifier.py +0 -566
- stravinsky-0.4.36/tests/test_symlink_boundary.py +0 -148
- stravinsky-0.4.36/tests/test_update_manager.py +0 -1120
- stravinsky-0.4.36/tests/verify_semantic_search.py +0 -155
- stravinsky-0.4.36/uv.lock +0 -2572
- stravinsky-0.4.36/verify_gemini_key.py +0 -37
- stravinsky-0.4.36/verify_tools.py +0 -43
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/HOOKS_INTEGRATION.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/agents/HOOKS.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/agents/code-reviewer.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/agents/debugger.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/agents/delphi.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/agents/dewey.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/agents/explore.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/agents/frontend.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/agents/implementation-lead.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/agents/research-lead.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/commands/delphi.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/commands/dewey.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/commands/git-master.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/commands/index.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/commands/publish.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/commands/review.md +0 -0
- /stravinsky-0.4.36/.claude/commands/str-cancel.md → /stravinsky-0.4.41/.claude/commands/str/cancel.md +0 -0
- /stravinsky-0.4.36/.claude/commands/str-clean.md → /stravinsky-0.4.41/.claude/commands/str/clean.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/commands/str/index.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/commands/str/list_watchers.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/commands/str/search.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/commands/str/start_filewatch.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/commands/str/stats.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/commands/str/stop_filewatch.md +0 -0
- /stravinsky-0.4.36/.claude/commands/str-unwatch.md → /stravinsky-0.4.41/.claude/commands/str/unwatch.md +0 -0
- /stravinsky-0.4.36/.claude/commands/str-watch.md → /stravinsky-0.4.41/.claude/commands/str/watch.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/commands/verify.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/commands/version.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/hooks/comment_checker.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/hooks/context.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/hooks/edit_recovery.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/hooks/notification_hook.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/hooks/session_recovery.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/hooks/stravinsky_mode.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/hooks/subagent_stop.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/hooks/todo_continuation.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/hooks/todo_delegation.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/hooks/truncator.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/rules/deployment_safety.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/skills/chrome-devtools/SKILL.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/skills/sqlite/SKILL.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/.claude/skills/supabase/SKILL.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/auth/__init__.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/auth/cli.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/auth/oauth.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/auth/openai_oauth.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/auth/token_refresh.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/auth/token_store.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/cli/__init__.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/cli/session_report.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/config/MANIFEST_SCHEMA.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/config/README.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/config/__init__.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/config/hooks.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/config/hooks_manifest.json +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/config/rate_limits.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/config/skills_manifest.json +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/HOOKS_SETTINGS.json +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/README.md +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/__init__.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/agent_reminder.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/auto_slash_command.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/budget_optimizer.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/comment_checker.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/compaction.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/context.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/context_monitor.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/directory_context.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/edit_recovery.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/empty_message_sanitizer.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/git_noninteractive.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/manager.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/notification_hook.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/parallel_enforcer.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/preemptive_compaction.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/rules_injector.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/session_idle.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/session_notifier.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/session_recovery.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/stravinsky_mode.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/subagent_stop.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/task_validator.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/tmux_manager.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/todo_continuation.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/todo_delegation.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/todo_enforcer.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/tool_messaging.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/hooks/truncator.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/notifications.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/prompts/__init__.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/prompts/delphi.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/prompts/document_writer.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/prompts/explore.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/prompts/frontend.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/prompts/multimodal.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/prompts/planner.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/server_tools.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/tools/__init__.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/tools/background_tasks.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/tools/code_search.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/tools/continuous_loop.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/tools/init.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/tools/lsp/__init__.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/tools/lsp/manager.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/tools/lsp/tools.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/tools/project_context.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/tools/query_classifier.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/tools/session_manager.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/tools/skill_loader.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/update_manager.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/update_manager_pypi.py +0 -0
- {stravinsky-0.4.36 → stravinsky-0.4.41}/mcp_bridge/utils/__init__.py +0 -0
|
@@ -74,7 +74,7 @@ Task(
|
|
|
74
74
|
|
|
75
75
|
## Workflow
|
|
76
76
|
|
|
77
|
-
### Step 0: Check Skills
|
|
77
|
+
### Step 0: Check Skills FUWT (BLOCKING)
|
|
78
78
|
|
|
79
79
|
**Before ANY classification or action, scan for matching skills.**
|
|
80
80
|
|
|
@@ -92,7 +92,7 @@ Classify every request into one of 6 types:
|
|
|
92
92
|
|
|
93
93
|
| Type | Signal | Action |
|
|
94
94
|
|------|--------|--------|
|
|
95
|
-
| **Skill Match** | Matches skill trigger phrase | **INVOKE skill
|
|
95
|
+
| **Skill Match** | Matches skill trigger phrase | **INVOKE skill FUWT** via `skill_get` tool |
|
|
96
96
|
| **Trivial** | Typo fix, single-line change, known exact location | Direct tools only (UNLESS delegation applies) |
|
|
97
97
|
| **Explicit** | Specific file/line, clear directive | Execute directly |
|
|
98
98
|
| **Exploratory** | "How does X work?", "Find Y", "Where is Z?" | Fire explore (1-3) + tools in parallel |
|
|
@@ -137,7 +137,7 @@ This assessment guides how much freedom you have to make changes without asking.
|
|
|
137
137
|
|
|
138
138
|
## Parallel Execution (MANDATORY)
|
|
139
139
|
|
|
140
|
-
### ⚠️ CRITICAL: PARALLEL-
|
|
140
|
+
### ⚠️ CRITICAL: PARALLEL-FUWT WORKFLOW
|
|
141
141
|
|
|
142
142
|
**BLOCKING REQUIREMENT**: For implementation tasks, your response structure MUST be:
|
|
143
143
|
|
|
@@ -15,7 +15,7 @@ Named after the composer known for revolutionary orchestration.
|
|
|
15
15
|
|
|
16
16
|
---
|
|
17
17
|
|
|
18
|
-
## Phase 0: Check Skills
|
|
18
|
+
## Phase 0: Check Skills FUWT (BLOCKING)
|
|
19
19
|
|
|
20
20
|
Before ANY classification or action:
|
|
21
21
|
1. Call `skill_list` to check available skills
|
|
@@ -26,13 +26,13 @@ Before ANY classification or action:
|
|
|
26
26
|
|
|
27
27
|
## Phase 1: Classify & Validate
|
|
28
28
|
|
|
29
|
-
### Step 0:
|
|
29
|
+
### Step 0: ULTRAWORK Mode Detection (PRIORITY CHECK)
|
|
30
30
|
|
|
31
31
|
**BEFORE classification, scan prompt for:**
|
|
32
|
-
- Keywords: `
|
|
32
|
+
- Keywords: `ultrawork`, `uw`, `ultrawork`, `ulw` (case-insensitive)
|
|
33
33
|
- If detected: **ACTIVATE MAXIMUM PARALLEL MODE**
|
|
34
34
|
|
|
35
|
-
**
|
|
35
|
+
**ULTRAWORK MODE RULES:**
|
|
36
36
|
1. **ALWAYS use agents** - NEVER work alone with Read/Grep/Bash
|
|
37
37
|
2. **Spawn ALL independent tasks in parallel** - Minimum 2+ agents for any multi-step work
|
|
38
38
|
3. **Default to explore/dewey** - Use cheap agents aggressively
|
|
@@ -40,7 +40,7 @@ Before ANY classification or action:
|
|
|
40
40
|
|
|
41
41
|
**Example:**
|
|
42
42
|
```
|
|
43
|
-
User: "
|
|
43
|
+
User: "ultrawork Find auth flow and error handling"
|
|
44
44
|
→ IMMEDIATE: agent_spawn(explore, "auth flow") + agent_spawn(explore, "error handling")
|
|
45
45
|
→ NEVER: Read file yourself, grep yourself, or work sequentially
|
|
46
46
|
```
|
|
@@ -49,7 +49,7 @@ User: "ironstar Find auth flow and error handling"
|
|
|
49
49
|
|
|
50
50
|
| Type | Signal | Action |
|
|
51
51
|
|------|--------|--------|
|
|
52
|
-
| **
|
|
52
|
+
| **ULTRAWORK Mode** | Contains: ultrawork, uw, ultrawork, ulw | Maximum parallel delegation (2+ agents minimum) |
|
|
53
53
|
| **Skill Match** | Matches skill trigger | INVOKE skill via `skill_get` |
|
|
54
54
|
| **Exploratory** | "How does X work?", "Find Y" | Fire explore agents in parallel |
|
|
55
55
|
| **Implementation** | "Add feature", "Refactor" | Create TODO list → spawn parallel agents |
|
|
@@ -60,11 +60,11 @@ User: "ironstar Find auth flow and error handling"
|
|
|
60
60
|
- Do I have implicit assumptions?
|
|
61
61
|
- What tools/agents can I use: `agent_spawn`, parallel tools, LSP?
|
|
62
62
|
- Should I challenge the user if design seems flawed?
|
|
63
|
-
- **If
|
|
63
|
+
- **If ULTRAWORK detected**: Am I spawning at least 2+ agents in parallel?
|
|
64
64
|
|
|
65
65
|
---
|
|
66
66
|
|
|
67
|
-
## ⚠️ CRITICAL: PARALLEL-
|
|
67
|
+
## ⚠️ CRITICAL: PARALLEL-FUWT WORKFLOW
|
|
68
68
|
|
|
69
69
|
**For ANY task with 2+ independent steps, your response MUST be:**
|
|
70
70
|
|
|
@@ -173,16 +173,16 @@ When using `agent_spawn`, include ALL 7 sections:
|
|
|
173
173
|
|
|
174
174
|
| Domain | Delegate To | Trigger |
|
|
175
175
|
|--------|-------------|---------|
|
|
176
|
-
| **Maximum Parallel Mode** | `explore` + `dewey` | **
|
|
176
|
+
| **Maximum Parallel Mode** | `explore` + `dewey` | **ULTRAWORK, UW, ULTRAWORK, ULW** |
|
|
177
177
|
| Frontend Visual | `frontend` | Color, spacing, layout, CSS, animation |
|
|
178
178
|
| External Research | `dewey` | Docs, library usage, OSS examples |
|
|
179
179
|
| Internal Search | `explore` | Find patterns in THIS repo |
|
|
180
180
|
| Architecture | `delphi` | Design decisions, tradeoffs |
|
|
181
181
|
| Hard Debugging | `delphi` | After 2+ failed fixes |
|
|
182
182
|
|
|
183
|
-
###
|
|
183
|
+
### ULTRAWORK Mode Behavior
|
|
184
184
|
|
|
185
|
-
When
|
|
185
|
+
When ULTRAWORK/UW/ULTRAWORK/ULW keywords detected:
|
|
186
186
|
|
|
187
187
|
**MANDATORY:**
|
|
188
188
|
- ✅ Spawn 2+ agents minimum (even for simple tasks)
|
|
@@ -199,7 +199,7 @@ When IRONSTAR/IRS/ULTRAWORK/ULW keywords detected:
|
|
|
199
199
|
|
|
200
200
|
---
|
|
201
201
|
|
|
202
|
-
## Execution Context (READ THIS
|
|
202
|
+
## Execution Context (READ THIS FUWT)
|
|
203
203
|
|
|
204
204
|
**You are running as:** Stravinsky MCP Skill (via `/strav` command)
|
|
205
205
|
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
# Claude Code Hooks Architecture
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This directory contains Claude Code hooks that enforce parallel delegation, provide rich console notifications, and track execution state across conversation turns.
|
|
6
|
+
|
|
7
|
+
## Hook Execution Order
|
|
8
|
+
|
|
9
|
+
### UserPromptSubmit (6 hooks)
|
|
10
|
+
1. `context_monitor.py` - Track session context
|
|
11
|
+
2. `parallel_execution.py` - Initial ULTRAWORK mode activation
|
|
12
|
+
3. `parallel_reinforcement.py` - Legacy parallel reminders (deprecated)
|
|
13
|
+
4. `parallel_reinforcement_v2.py` - **NEW** Smart adaptive reminders based on state
|
|
14
|
+
5. `context.py` - Inject project context
|
|
15
|
+
6. `todo_continuation.py` - Resume incomplete todos
|
|
16
|
+
|
|
17
|
+
### PostToolUse
|
|
18
|
+
1. `truncator.py` - Truncate large outputs
|
|
19
|
+
2. `session_recovery.py` - Session state backup
|
|
20
|
+
3. `execution_state_tracker.py` - **NEW** Track tool usage patterns across turns
|
|
21
|
+
4. `tool_messaging.py` - User-friendly tool notifications (with colors)
|
|
22
|
+
5. `edit_recovery.py` - Backup edited files
|
|
23
|
+
6. `todo_delegation.py` - Enforce parallel after TodoWrite
|
|
24
|
+
7. `dependency_tracker.py` - **NEW** Parse TODO dependencies and build graph
|
|
25
|
+
|
|
26
|
+
## State Files
|
|
27
|
+
|
|
28
|
+
Located in `.claude/` directory:
|
|
29
|
+
|
|
30
|
+
- `execution_state.json` - Tool usage tracking (last 10 tools, Task spawn history)
|
|
31
|
+
- `task_dependencies.json` - TODO dependency graph (independent vs dependent tasks)
|
|
32
|
+
- `hooks/state/agent_batch.json` - Agent spawn batching for grouped notifications
|
|
33
|
+
- `~/.stravinsky_mode` - Hard blocking mode marker (enables stravinsky mode)
|
|
34
|
+
|
|
35
|
+
## Utilities
|
|
36
|
+
|
|
37
|
+
### `utils/colors.py`
|
|
38
|
+
- ANSI color codes for terminal output
|
|
39
|
+
- Agent-specific color mappings (blue=explore, purple=dewey, etc.)
|
|
40
|
+
- Terminal capability detection (`supports_color()`)
|
|
41
|
+
|
|
42
|
+
### `utils/debug.py`
|
|
43
|
+
- Debug mode control via `STRAVINSKY_DEBUG` environment variable
|
|
44
|
+
- Silent by default, verbose when `STRAVINSKY_DEBUG=1`
|
|
45
|
+
|
|
46
|
+
### `utils/console_format.py`
|
|
47
|
+
- Standardized message formatting with `MessageType` enum
|
|
48
|
+
- Multi-line agent spawn formatting
|
|
49
|
+
- Tool usage formatting with colors
|
|
50
|
+
|
|
51
|
+
## Environment Variables
|
|
52
|
+
|
|
53
|
+
- `STRAVINSKY_DEBUG=1` - Enable debug output from hooks
|
|
54
|
+
- `STRAVINSKY_NO_COLOR=1` - Disable ANSI colors (for unsupported terminals)
|
|
55
|
+
- `NO_COLOR=1` - Standard no-color environment variable (also supported)
|
|
56
|
+
|
|
57
|
+
## Key Features
|
|
58
|
+
|
|
59
|
+
### 1. Parallel Delegation Enforcement
|
|
60
|
+
|
|
61
|
+
**Problem**: After turn 3+, Claude degrades to sequential execution despite having independent tasks.
|
|
62
|
+
|
|
63
|
+
**Solution**: State-based reinforcement via `parallel_reinforcement_v2.py`
|
|
64
|
+
- Tracks last 10 tool calls
|
|
65
|
+
- Detects when Task() hasn't been used recently (2+ turns)
|
|
66
|
+
- Parses TODOs for dependency keywords
|
|
67
|
+
- Injects aggressive reminders when degradation detected
|
|
68
|
+
|
|
69
|
+
**Files**:
|
|
70
|
+
- `dependency_tracker.py` - Parses TODOs for "after", "depends on", etc.
|
|
71
|
+
- `execution_state_tracker.py` - Tracks tool usage history
|
|
72
|
+
- `parallel_reinforcement_v2.py` - Smart context-aware reminders
|
|
73
|
+
|
|
74
|
+
### 2. Rich Agent Notifications
|
|
75
|
+
|
|
76
|
+
**Before**:
|
|
77
|
+
```
|
|
78
|
+
spawned explore:gemini-3-flash('task delegated')
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**After**:
|
|
82
|
+
```
|
|
83
|
+
🔵 EXPLORE → gemini-3-flash
|
|
84
|
+
Task: Find all authentication implementations in codebase
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Features**:
|
|
88
|
+
- Color-coded by agent type (blue, purple, green, orange, red)
|
|
89
|
+
- Multi-line format with clear task descriptions
|
|
90
|
+
- Model name explicitly shown
|
|
91
|
+
- Graceful degradation if terminal doesn't support colors
|
|
92
|
+
|
|
93
|
+
### 3. Silent Debug Mode
|
|
94
|
+
|
|
95
|
+
**Problem**: Hook debug output pollutes console (`Failed to send event: ...`)
|
|
96
|
+
|
|
97
|
+
**Solution**: File-based logging with `STRAVINSKY_DEBUG` control
|
|
98
|
+
- `send_event.py` logs to `~/.claude/hooks/logs/event_sender.log`
|
|
99
|
+
- All debug output hidden unless `STRAVINSKY_DEBUG=1`
|
|
100
|
+
- Clean console by default
|
|
101
|
+
|
|
102
|
+
## Agent Color Mapping
|
|
103
|
+
|
|
104
|
+
| Agent | Color | Emoji | Model |
|
|
105
|
+
|-------|-------|-------|-------|
|
|
106
|
+
| explore | Blue | 🔵 | gemini-3-flash |
|
|
107
|
+
| dewey | Purple | 🟣 | gemini-3-flash |
|
|
108
|
+
| frontend | Green | 🟢 | gemini-3-pro-high |
|
|
109
|
+
| delphi | Orange | 🟠 | gpt-5.2-medium |
|
|
110
|
+
| debugger | Red | 🔴 | sonnet-4.5 |
|
|
111
|
+
| code-reviewer | Purple | 🟣 | sonnet-4.5 |
|
|
112
|
+
|
|
113
|
+
## Dependency Detection
|
|
114
|
+
|
|
115
|
+
The `dependency_tracker.py` hook parses TODO content for dependency signals:
|
|
116
|
+
|
|
117
|
+
**Dependency Keywords** (marks as dependent):
|
|
118
|
+
- "after", "depends on", "requires", "once", "when", "then"
|
|
119
|
+
|
|
120
|
+
**Parallel Keywords** (marks as independent):
|
|
121
|
+
- "also", "meanwhile", "simultaneously", "and", "plus"
|
|
122
|
+
|
|
123
|
+
**Example**:
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"dependencies": {
|
|
127
|
+
"todo_1": {"deps": [], "independent": true, "parallel_safe": true},
|
|
128
|
+
"todo_2": {"deps": [], "independent": true, "parallel_safe": true},
|
|
129
|
+
"todo_3": {"deps": ["todo_1"], "independent": false, "parallel_safe": false}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Parallel Reinforcement Algorithm
|
|
135
|
+
|
|
136
|
+
1. **Check Mode**: Is `~/.stravinsky_mode` active? If not, skip.
|
|
137
|
+
2. **Check State**: Are there 2+ pending TODOs? If not, skip.
|
|
138
|
+
3. **Check History**: How many turns since last `Task()` spawn?
|
|
139
|
+
- If < 2 turns → skip (still fresh)
|
|
140
|
+
- If >= 2 turns → degradation detected
|
|
141
|
+
4. **Check Dependencies**: How many independent tasks exist?
|
|
142
|
+
- If < 2 → skip (no parallelization needed)
|
|
143
|
+
- If >= 2 → inject aggressive reminder
|
|
144
|
+
5. **Inject Reminder**: Add context-aware instructions to prompt
|
|
145
|
+
|
|
146
|
+
## Testing
|
|
147
|
+
|
|
148
|
+
### Test Parallel Delegation Persistence
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
# Create a multi-step task and track behavior over 10+ turns
|
|
152
|
+
# Expected: Task() spawns for independent tasks even at turn 10
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Test Console Output
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
# Run hooks and verify no debug clutter
|
|
159
|
+
export STRAVINSKY_DEBUG=0
|
|
160
|
+
# Should see ONLY user-relevant messages (colored agent notifications)
|
|
161
|
+
|
|
162
|
+
# Enable debug mode
|
|
163
|
+
export STRAVINSKY_DEBUG=1
|
|
164
|
+
# Should see debug output in ~/.claude/hooks/logs/event_sender.log
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Test Color Support
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
# Disable colors
|
|
171
|
+
export STRAVINSKY_NO_COLOR=1
|
|
172
|
+
# Should see emojis but no ANSI codes
|
|
173
|
+
|
|
174
|
+
# Enable colors (default)
|
|
175
|
+
unset STRAVINSKY_NO_COLOR
|
|
176
|
+
# Should see colored output
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Architecture Comparison: Stravinsky vs oh-my-opencode
|
|
180
|
+
|
|
181
|
+
| Aspect | oh-my-opencode (TS) | Stravinsky (Python) |
|
|
182
|
+
|--------|---------------------|---------------------|
|
|
183
|
+
| Parallel Enforcement | Structural (orchestrator pattern) | Prompt-based with state tracking |
|
|
184
|
+
| State Management | Built-in TypeScript state | External JSON files |
|
|
185
|
+
| Dependency Tracking | Explicit graph | Keyword-based parsing |
|
|
186
|
+
| Agent Notifications | Rich formatting (assumed) | Rich formatting with ANSI colors |
|
|
187
|
+
| Console Output | Clean separation | File-based logging + formatting |
|
|
188
|
+
|
|
189
|
+
## Future Enhancements
|
|
190
|
+
|
|
191
|
+
1. **Agent Batching** - Group parallel agent spawns visually
|
|
192
|
+
2. **Dependency Graph Visualization** - CLI tool to view task dependencies
|
|
193
|
+
3. **Performance Metrics** - Track agent completion times
|
|
194
|
+
4. **ML-Based Agent Selection** - Predict best agent for task type
|
|
195
|
+
|
|
196
|
+
## Troubleshooting
|
|
197
|
+
|
|
198
|
+
### Import Errors in LSP
|
|
199
|
+
|
|
200
|
+
**Symptom**: Pyright shows "Import could not be resolved" for `utils/*` modules
|
|
201
|
+
|
|
202
|
+
**Cause**: LSP can't resolve relative imports in hook scripts
|
|
203
|
+
|
|
204
|
+
**Solution**: These are false positives. Python resolves imports at runtime via `sys.path.insert(0, ...)` in each hook. Safe to ignore.
|
|
205
|
+
|
|
206
|
+
### Parallel Delegation Still Fails
|
|
207
|
+
|
|
208
|
+
**Check**:
|
|
209
|
+
1. Is `~/.stravinsky_mode` file present?
|
|
210
|
+
2. Run: `cat .claude/execution_state.json` - verify state is updating
|
|
211
|
+
3. Run: `cat .claude/task_dependencies.json` - verify dependencies detected
|
|
212
|
+
4. Enable debug: `STRAVINSKY_DEBUG=1` and check logs
|
|
213
|
+
|
|
214
|
+
### Colors Not Showing
|
|
215
|
+
|
|
216
|
+
**Check**:
|
|
217
|
+
1. Terminal supports ANSI colors? (`echo $TERM`)
|
|
218
|
+
2. `STRAVINSKY_NO_COLOR` or `NO_COLOR` set?
|
|
219
|
+
3. Is stderr a TTY? (Colors disabled for piped output)
|
|
220
|
+
|
|
221
|
+
## Maintenance
|
|
222
|
+
|
|
223
|
+
### Adding New Hooks
|
|
224
|
+
|
|
225
|
+
1. Create hook file in `.claude/hooks/`
|
|
226
|
+
2. Add to appropriate section in `.claude/settings.json`
|
|
227
|
+
3. Test in isolation with mock input
|
|
228
|
+
4. Update this README
|
|
229
|
+
|
|
230
|
+
### Modifying State Schema
|
|
231
|
+
|
|
232
|
+
If changing `execution_state.json` or `task_dependencies.json` format:
|
|
233
|
+
1. Update tracker scripts (`execution_state_tracker.py`, `dependency_tracker.py`)
|
|
234
|
+
2. Update consumer scripts (`parallel_reinforcement_v2.py`)
|
|
235
|
+
3. Add migration logic or document breaking change
|
|
236
|
+
4. Consider versioning state files
|
|
237
|
+
|
|
238
|
+
### Deprecating Old Hooks
|
|
239
|
+
|
|
240
|
+
1. Mark as deprecated in comments
|
|
241
|
+
2. Add to "Deprecated" section below
|
|
242
|
+
3. After 1 month, remove from `settings.json`
|
|
243
|
+
4. After 2 months, delete file
|
|
244
|
+
|
|
245
|
+
## Deprecated Hooks
|
|
246
|
+
|
|
247
|
+
- `parallel_reinforcement.py` - Replaced by `parallel_reinforcement_v2.py` (state-based)
|
|
248
|
+
- Removal target: TBD (keep for backward compatibility for now)
|
|
@@ -56,7 +56,7 @@ def set_last_compact_tokens(tokens: int):
|
|
|
56
56
|
"""Record token count at compact recommendation."""
|
|
57
57
|
ensure_state_dir()
|
|
58
58
|
try:
|
|
59
|
-
state = {"last_compact_tokens": tokens, "timestamp": datetime.
|
|
59
|
+
state = {"last_compact_tokens": tokens, "timestamp": datetime.now(timezone.utc).isoformat()}
|
|
60
60
|
CONTEXT_STATE_FILE.write_text(json.dumps(state))
|
|
61
61
|
except IOError:
|
|
62
62
|
pass
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import json
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def get_project_dir():
|
|
9
|
+
return Path(os.environ.get("CLAUDE_CWD", "."))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def get_dependency_graph():
|
|
13
|
+
graph_file = get_project_dir() / ".claude/task_dependencies.json"
|
|
14
|
+
if graph_file.exists():
|
|
15
|
+
try:
|
|
16
|
+
return json.loads(graph_file.read_text())
|
|
17
|
+
except Exception:
|
|
18
|
+
pass
|
|
19
|
+
return {"dependencies": {}}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def save_dependency_graph(graph):
|
|
23
|
+
graph_file = get_project_dir() / ".claude/task_dependencies.json"
|
|
24
|
+
graph_file.parent.mkdir(parents=True, exist_ok=True)
|
|
25
|
+
graph_file.write_text(json.dumps(graph, indent=2))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
DEPENDENCY_KEYWORDS = ["after", "depends on", "requires", "once", "when", "then"]
|
|
29
|
+
PARALLEL_KEYWORDS = ["also", "meanwhile", "simultaneously", "and", "plus"]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def parse_todo_dependencies(todos):
|
|
33
|
+
dependencies = {}
|
|
34
|
+
|
|
35
|
+
for todo in todos:
|
|
36
|
+
todo_id = todo.get("id")
|
|
37
|
+
content = todo.get("content", "").lower()
|
|
38
|
+
|
|
39
|
+
has_dependency = any(kw in content for kw in DEPENDENCY_KEYWORDS)
|
|
40
|
+
is_parallel = any(kw in content for kw in PARALLEL_KEYWORDS)
|
|
41
|
+
|
|
42
|
+
dependencies[todo_id] = {
|
|
43
|
+
"deps": [],
|
|
44
|
+
"independent": not has_dependency,
|
|
45
|
+
"parallel_safe": is_parallel or not has_dependency,
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return dependencies
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def main():
|
|
52
|
+
try:
|
|
53
|
+
hook_input = json.load(sys.stdin)
|
|
54
|
+
except (json.JSONDecodeError, EOFError):
|
|
55
|
+
return 0
|
|
56
|
+
|
|
57
|
+
tool_name = hook_input.get("tool_name", "")
|
|
58
|
+
if tool_name != "TodoWrite":
|
|
59
|
+
return 0
|
|
60
|
+
|
|
61
|
+
tool_input = hook_input.get("tool_input", {})
|
|
62
|
+
todos = tool_input.get("todos", [])
|
|
63
|
+
|
|
64
|
+
graph = get_dependency_graph()
|
|
65
|
+
dependencies = parse_todo_dependencies(todos)
|
|
66
|
+
graph["dependencies"] = dependencies
|
|
67
|
+
save_dependency_graph(graph)
|
|
68
|
+
|
|
69
|
+
return 0
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
if __name__ == "__main__":
|
|
73
|
+
sys.exit(main())
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import json
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def get_project_dir():
|
|
10
|
+
return Path(os.environ.get("CLAUDE_CWD", "."))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def get_execution_state():
|
|
14
|
+
state_file = get_project_dir() / ".claude/execution_state.json"
|
|
15
|
+
if state_file.exists():
|
|
16
|
+
try:
|
|
17
|
+
return json.loads(state_file.read_text())
|
|
18
|
+
except Exception:
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
"last_10_tools": [],
|
|
23
|
+
"last_task_spawn_index": -1,
|
|
24
|
+
"pending_todos": 0,
|
|
25
|
+
"parallel_mode_active": False,
|
|
26
|
+
"last_updated": None,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def save_execution_state(state):
|
|
31
|
+
state_file = get_project_dir() / ".claude/execution_state.json"
|
|
32
|
+
state_file.parent.mkdir(parents=True, exist_ok=True)
|
|
33
|
+
state["last_updated"] = datetime.now().isoformat()
|
|
34
|
+
state_file.write_text(json.dumps(state, indent=2))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def main():
|
|
38
|
+
try:
|
|
39
|
+
hook_input = json.load(sys.stdin)
|
|
40
|
+
except (json.JSONDecodeError, EOFError):
|
|
41
|
+
return 0
|
|
42
|
+
|
|
43
|
+
tool_name = hook_input.get("tool_name", "")
|
|
44
|
+
|
|
45
|
+
state = get_execution_state()
|
|
46
|
+
state["last_10_tools"].append(tool_name)
|
|
47
|
+
state["last_10_tools"] = state["last_10_tools"][-10:]
|
|
48
|
+
|
|
49
|
+
if tool_name == "Task":
|
|
50
|
+
try:
|
|
51
|
+
index = len(state["last_10_tools"]) - 1
|
|
52
|
+
state["last_task_spawn_index"] = index
|
|
53
|
+
except:
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
if tool_name == "TodoWrite":
|
|
57
|
+
tool_input = hook_input.get("tool_input", {})
|
|
58
|
+
todos = tool_input.get("todos", [])
|
|
59
|
+
pending = sum(1 for t in todos if t.get("status") == "pending")
|
|
60
|
+
state["pending_todos"] = pending
|
|
61
|
+
state["parallel_mode_active"] = pending >= 2
|
|
62
|
+
|
|
63
|
+
save_execution_state(state)
|
|
64
|
+
return 0
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
if __name__ == "__main__":
|
|
68
|
+
sys.exit(main())
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import json
|
|
3
|
+
import sys
|
|
4
|
+
import os
|
|
5
|
+
|
|
6
|
+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "utils"))
|
|
7
|
+
|
|
8
|
+
try:
|
|
9
|
+
from colors import get_agent_color, Color
|
|
10
|
+
from console_format import format_agent_spawn
|
|
11
|
+
except ImportError:
|
|
12
|
+
|
|
13
|
+
def get_agent_color(agent_type):
|
|
14
|
+
return ("", "⚪")
|
|
15
|
+
|
|
16
|
+
def format_agent_spawn(agent_type, model, description, color_code, emoji):
|
|
17
|
+
lines = [f"{emoji} {agent_type.upper()} → {model}", f" Task: {description}", ""]
|
|
18
|
+
return "\n".join(lines)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
AGENT_DISPLAY_MODELS = {
|
|
22
|
+
"explore": "gemini-3-flash",
|
|
23
|
+
"dewey": "gemini-3-flash",
|
|
24
|
+
"document_writer": "gemini-3-flash",
|
|
25
|
+
"multimodal": "gemini-3-flash",
|
|
26
|
+
"frontend": "gemini-3-pro-high",
|
|
27
|
+
"delphi": "gpt-5.2-medium",
|
|
28
|
+
"planner": "opus-4.5",
|
|
29
|
+
"code-reviewer": "sonnet-4.5",
|
|
30
|
+
"debugger": "sonnet-4.5",
|
|
31
|
+
"_default": "sonnet-4.5",
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def extract_agent_info(message):
|
|
36
|
+
message_lower = message.lower()
|
|
37
|
+
agent_type = None
|
|
38
|
+
description = ""
|
|
39
|
+
|
|
40
|
+
for agent in AGENT_DISPLAY_MODELS.keys():
|
|
41
|
+
if agent == "_default":
|
|
42
|
+
continue
|
|
43
|
+
if agent in message_lower:
|
|
44
|
+
agent_type = agent
|
|
45
|
+
idx = message_lower.find(agent)
|
|
46
|
+
description = message[idx + len(agent) :].strip()[:80]
|
|
47
|
+
break
|
|
48
|
+
|
|
49
|
+
if not agent_type:
|
|
50
|
+
return None
|
|
51
|
+
|
|
52
|
+
description = description.strip(":-() ")
|
|
53
|
+
if not description:
|
|
54
|
+
description = "task delegated"
|
|
55
|
+
|
|
56
|
+
model = AGENT_DISPLAY_MODELS.get(agent_type, AGENT_DISPLAY_MODELS["_default"])
|
|
57
|
+
color_code, emoji = get_agent_color(agent_type)
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
"agent_type": agent_type,
|
|
61
|
+
"model": model,
|
|
62
|
+
"description": description,
|
|
63
|
+
"color_code": color_code,
|
|
64
|
+
"emoji": emoji,
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def main():
|
|
69
|
+
try:
|
|
70
|
+
hook_input = json.load(sys.stdin)
|
|
71
|
+
except (json.JSONDecodeError, EOFError):
|
|
72
|
+
return 0
|
|
73
|
+
|
|
74
|
+
message = hook_input.get("message", "")
|
|
75
|
+
agent_keywords = ["agent", "spawn", "delegat", "task"]
|
|
76
|
+
if not any(kw in message.lower() for kw in agent_keywords):
|
|
77
|
+
return 0
|
|
78
|
+
|
|
79
|
+
agent_info = extract_agent_info(message)
|
|
80
|
+
if not agent_info:
|
|
81
|
+
return 0
|
|
82
|
+
|
|
83
|
+
formatted = format_agent_spawn(
|
|
84
|
+
agent_info["agent_type"],
|
|
85
|
+
agent_info["model"],
|
|
86
|
+
agent_info["description"],
|
|
87
|
+
agent_info["color_code"],
|
|
88
|
+
agent_info["emoji"],
|
|
89
|
+
)
|
|
90
|
+
print(formatted, file=sys.stderr)
|
|
91
|
+
|
|
92
|
+
return 0
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
if __name__ == "__main__":
|
|
96
|
+
sys.exit(main())
|