From aa3aacec0c174e5b023b8a20bf8f75ea8de5f505 Mon Sep 17 00:00:00 2001 From: Kirill Ryzhikov Date: Tue, 27 Jan 2026 21:13:07 +0000 Subject: [PATCH 1/6] docs: add skill-activation-hooks design document Design for two prompt-based hooks: - UserPromptSubmit: skill activation reminders - Stop: advisory self-check based on edited files Co-Authored-By: Claude Opus 4.5 --- ...026-01-27-skill-activation-hooks-design.md | 185 ++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 docs/plans/2026-01-27-skill-activation-hooks-design.md diff --git a/docs/plans/2026-01-27-skill-activation-hooks-design.md b/docs/plans/2026-01-27-skill-activation-hooks-design.md new file mode 100644 index 0000000..8a46bce --- /dev/null +++ b/docs/plans/2026-01-27-skill-activation-hooks-design.md @@ -0,0 +1,185 @@ +# Skill Activation Hooks - Design Document + +**Date:** 2026-01-27 +**Status:** Approved + +## Overview + +Two prompt-based hooks to improve Claude's skill awareness: + +1. **UserPromptSubmit** - Analyzes prompts before Claude sees them, injects skill activation reminders +2. **Stop** - Advisory self-check reminders based on edited files (non-blocking) + +## Decisions + +- **Location:** New plugin in this marketplace (`skill-activation-hooks/`) +- **Config approach:** Minimal framework + examples (polars-expertise, arxiv-search) +- **Hook type:** Prompt-based for both hooks (native, no external API) +- **Stop behavior:** Advisory only, never blocks + +## Plugin Structure + +``` +skill-activation-hooks/ +├── plugin.json +├── hooks/ +│ └── hooks.json +├── config/ +│ └── skill-rules.json +└── README.md +``` + +## Configuration Schema: skill-rules.json + +```json +{ + "$schema": "./skill-rules-schema.json", + "version": "1.0", + + "skills": { + "polars-expertise": { + "description": "Polars DataFrame library for Python/Rust - expressions, lazy evaluation, performance", + "type": "domain", + "enforcement": "suggest", + "priority": "high", + + "promptTriggers": { + "keywords": [ + "polars", "dataframe", "lazyframe", "parquet", + "scan_parquet", "group_by_dynamic", "rolling_mean", + "asof join", "OHLCV", "window function" + ], + "intentPatterns": [ + "(convert|migrate).*?(pandas|pyspark|kdb).*?polars", + "(lazy|eager).*?(evaluation|execution)", + "(read|write|scan).*?parquet", + "(rolling|window).*?(mean|std|sum)", + "time series.*?(resample|aggregate)" + ] + }, + + "fileTriggers": { + "pathPatterns": ["**/*.py", "**/*.rs"], + "contentPatterns": [ + "import polars", + "use polars::", + "pl\\.scan_", + "pl\\.read_", + "LazyFrame", + "\\.collect\\(\\)" + ] + }, + + "stopChecks": { + "patterns": ["map_elements", "iter_rows", "apply\\(", "pandas"], + "reminders": [ + "Using native expressions instead of map_elements?", + "Early projection (select columns before filter)?", + "Lazy evaluation for large data?" + ] + } + }, + + "arxiv-search": { + "description": "Search arXiv for academic papers and preprints", + "type": "research", + "enforcement": "suggest", + "priority": "medium", + + "promptTriggers": { + "keywords": [ + "arxiv", "preprint", "research paper", "academic paper", + "scientific literature", "paper search", "find papers", + "ML research", "recent research" + ], + "intentPatterns": [ + "(find|search|look up).*?(paper|research|preprint)", + "(latest|recent).*?(research|paper|work).*?(on|about)", + "what does the (literature|research) say", + "(state of the art|SOTA).*?(in|for)" + ] + }, + + "fileTriggers": { + "pathPatterns": [], + "contentPatterns": [] + }, + + "stopChecks": { + "patterns": [], + "reminders": [] + } + } + } +} +``` + +## Hook Configuration: hooks.json + +```json +{ + "description": "Skill activation hooks - prompt analysis and self-check reminders", + "hooks": { + "UserPromptSubmit": [ + { + "matcher": "*", + "hooks": [ + { + "type": "prompt", + "prompt": "You are a skill activation analyzer. Read the skill rules from the project's skill-rules.json and analyze the user's prompt.\n\nUser prompt: $USER_PROMPT\n\nFor each skill in skill-rules.json, check:\n1. Does the prompt contain any keywords from promptTriggers.keywords?\n2. Does the prompt match any regex in promptTriggers.intentPatterns?\n\nIf ANY skill matches, return a systemMessage in this format:\n\n{\"systemMessage\": \"SKILL ACTIVATION CHECK\\n\\nRelevant skills detected:\\n- [skill-name]: [brief reason]\\n\\nConsider invoking these skills before responding.\"}\n\nIf NO skills match, return: {\"systemMessage\": \"\"}\n\nBe concise. Only list genuinely relevant skills.", + "timeout": 30 + } + ] + } + ], + + "Stop": [ + { + "matcher": "*", + "hooks": [ + { + "type": "prompt", + "prompt": "You are a self-check reminder. Analyze what was done in this session.\n\nReview the conversation and any files that were edited. For each skill in skill-rules.json that has stopChecks defined:\n\n1. Check if edited files match the skill's fileTriggers (pathPatterns or contentPatterns)\n2. If they match, check if the file content contains any stopChecks.patterns\n3. If patterns found, include the corresponding reminders\n\nReturn format:\n{\"decision\": \"approve\", \"systemMessage\": \"Self-check reminders:\\n- [reminder 1]\\n- [reminder 2]\"}\n\nIf no relevant patterns found, return:\n{\"decision\": \"approve\", \"systemMessage\": \"\"}\n\nAlways approve (advisory only). Keep reminders brief and actionable.", + "timeout": 30 + } + ] + } + ], + + "SessionStart": [ + { + "matcher": "*", + "hooks": [ + { + "type": "command", + "command": "cat ${CLAUDE_PLUGIN_ROOT}/config/skill-rules.json 2>/dev/null || echo '{}'", + "timeout": 5 + } + ] + } + ] + } +} +``` + +## Plugin Manifest: plugin.json + +```json +{ + "name": "skill-activation-hooks", + "version": "1.0.0", + "description": "Prompt-based hooks for skill activation reminders and self-check", + "author": "Deevs", + "hooks": ["./hooks/"] +} +``` + +## Implementation Steps + +1. Create `skill-activation-hooks/` directory +2. Create `plugin.json` +3. Create `hooks/hooks.json` +4. Create `config/skill-rules.json` with examples +5. Create `README.md` +6. Register in `marketplace.json` +7. Test with `claude --debug` From 0d83dd803ebf2c162e1fed393776310549541baa Mon Sep 17 00:00:00 2001 From: Kirill Ryzhikov Date: Tue, 27 Jan 2026 21:24:13 +0000 Subject: [PATCH 2/6] feat: add skill-activation-hooks plugin Two prompt-based hooks for skill awareness: - UserPromptSubmit: analyzes prompts, injects skill reminders - Stop: advisory self-check based on edited files Includes example rules for polars-expertise and arxiv-search skills. Co-Authored-By: Claude Opus 4.5 --- .claude-plugin/marketplace.json | 6 ++ skill-activation-hooks/README.md | 90 +++++++++++++++++++ .../config/skill-rules.json | 80 +++++++++++++++++ skill-activation-hooks/hooks/hooks.json | 43 +++++++++ skill-activation-hooks/plugin.json | 7 ++ 5 files changed, 226 insertions(+) create mode 100644 skill-activation-hooks/README.md create mode 100644 skill-activation-hooks/config/skill-rules.json create mode 100644 skill-activation-hooks/hooks/hooks.json create mode 100644 skill-activation-hooks/plugin.json diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 5c8574a..e7bc289 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -77,6 +77,12 @@ "description": "Fast DataFrame library (Apache Arrow) for Python and Rust: expressions, lazy/streaming, GPU acceleration, time series patterns, pandas/spark/kdb migration", "source": "./polars-expertise", "skills": ["./"] + }, + { + "name": "skill-activation-hooks", + "description": "Prompt-based hooks for skill activation reminders and self-check", + "source": "./skill-activation-hooks", + "hooks": ["./hooks/"] } ] } diff --git a/skill-activation-hooks/README.md b/skill-activation-hooks/README.md new file mode 100644 index 0000000..88395c5 --- /dev/null +++ b/skill-activation-hooks/README.md @@ -0,0 +1,90 @@ +# skill-activation-hooks + +Automatic skill activation reminders and self-check for Claude Code. + +## How It Works + +Two prompt-based hooks that improve skill awareness: + +1. **UserPromptSubmit** - Analyzes your prompt before Claude sees it, injects skill reminders based on keywords and intent patterns + +2. **Stop** - When Claude finishes, checks edited files for patterns that warrant self-check reminders (advisory, non-blocking) + +3. **SessionStart** - Loads skill-rules.json into context for the prompt hooks to reference + +## Configuration + +Edit `config/skill-rules.json` to add your own skills. Each skill can define: + +### promptTriggers + +Activates when user submits a prompt: + +- `keywords` - Exact words/phrases to match (case-insensitive) +- `intentPatterns` - Regex patterns to catch user intent + +### fileTriggers + +Activates based on files being edited: + +- `pathPatterns` - Glob patterns for file paths +- `contentPatterns` - Regex patterns for file content + +### stopChecks + +What to look for when Claude finishes: + +- `patterns` - Regex patterns to search in edited files +- `reminders` - Human-readable reminders shown if patterns found + +## Example Rule + +```json +{ + "my-skill": { + "description": "Brief description", + "type": "domain", + "enforcement": "suggest", + "priority": "high", + + "promptTriggers": { + "keywords": ["keyword1", "keyword2"], + "intentPatterns": ["(create|add).*?thing"] + }, + + "fileTriggers": { + "pathPatterns": ["src/**/*.ts"], + "contentPatterns": ["import.*MyLib"] + }, + + "stopChecks": { + "patterns": ["antiPattern", "badPractice"], + "reminders": ["Did you avoid the anti-pattern?"] + } + } +} +``` + +## Installation + +This plugin is part of the deevs-agent-system marketplace. Install via: + +```bash +claude plugins add deevs-agent-system/skill-activation-hooks +``` + +Or add to your local plugins directory. + +## Testing + +Run Claude Code with debug mode to see hook execution: + +```bash +claude --debug +``` + +## Notes + +- All hooks are advisory - they never block Claude from completing +- Prompt hooks use the session's model (no external API calls) +- Skill rules are loaded once at session start via SessionStart hook diff --git a/skill-activation-hooks/config/skill-rules.json b/skill-activation-hooks/config/skill-rules.json new file mode 100644 index 0000000..4e9e62e --- /dev/null +++ b/skill-activation-hooks/config/skill-rules.json @@ -0,0 +1,80 @@ +{ + "version": "1.0", + "description": "Skill activation rules - add your own skills here", + + "skills": { + "polars-expertise": { + "description": "Polars DataFrame library for Python/Rust - expressions, lazy evaluation, performance", + "type": "domain", + "enforcement": "suggest", + "priority": "high", + + "promptTriggers": { + "keywords": [ + "polars", "dataframe", "lazyframe", "parquet", + "scan_parquet", "group_by_dynamic", "rolling_mean", + "asof join", "OHLCV", "window function" + ], + "intentPatterns": [ + "(convert|migrate).*?(pandas|pyspark|kdb).*?polars", + "(lazy|eager).*?(evaluation|execution)", + "(read|write|scan).*?parquet", + "(rolling|window).*?(mean|std|sum)", + "time series.*?(resample|aggregate)" + ] + }, + + "fileTriggers": { + "pathPatterns": ["**/*.py", "**/*.rs"], + "contentPatterns": [ + "import polars", + "use polars::", + "pl\\.scan_", + "pl\\.read_", + "LazyFrame", + "\\.collect\\(\\)" + ] + }, + + "stopChecks": { + "patterns": ["map_elements", "iter_rows", "apply\\(", "pandas"], + "reminders": [ + "Using native expressions instead of map_elements?", + "Early projection (select columns before filter)?", + "Lazy evaluation for large data?" + ] + } + }, + + "arxiv-search": { + "description": "Search arXiv for academic papers and preprints", + "type": "research", + "enforcement": "suggest", + "priority": "medium", + + "promptTriggers": { + "keywords": [ + "arxiv", "preprint", "research paper", "academic paper", + "scientific literature", "paper search", "find papers", + "ML research", "recent research" + ], + "intentPatterns": [ + "(find|search|look up).*?(paper|research|preprint)", + "(latest|recent).*?(research|paper|work).*?(on|about)", + "what does the (literature|research) say", + "(state of the art|SOTA).*?(in|for)" + ] + }, + + "fileTriggers": { + "pathPatterns": [], + "contentPatterns": [] + }, + + "stopChecks": { + "patterns": [], + "reminders": [] + } + } + } +} diff --git a/skill-activation-hooks/hooks/hooks.json b/skill-activation-hooks/hooks/hooks.json new file mode 100644 index 0000000..383fce2 --- /dev/null +++ b/skill-activation-hooks/hooks/hooks.json @@ -0,0 +1,43 @@ +{ + "description": "Skill activation hooks - prompt analysis and self-check reminders", + "hooks": { + "UserPromptSubmit": [ + { + "matcher": "*", + "hooks": [ + { + "type": "prompt", + "prompt": "You are a skill activation analyzer. Read the skill rules from the project's skill-rules.json and analyze the user's prompt.\n\nUser prompt: $USER_PROMPT\n\nFor each skill in skill-rules.json, check:\n1. Does the prompt contain any keywords from promptTriggers.keywords?\n2. Does the prompt match any regex in promptTriggers.intentPatterns?\n\nIf ANY skill matches, return a systemMessage in this format:\n\n{\"systemMessage\": \"SKILL ACTIVATION CHECK\\n\\nRelevant skills detected:\\n- [skill-name]: [brief reason]\\n\\nConsider invoking these skills before responding.\"}\n\nIf NO skills match, return: {\"systemMessage\": \"\"}\n\nBe concise. Only list genuinely relevant skills.", + "timeout": 30 + } + ] + } + ], + + "Stop": [ + { + "matcher": "*", + "hooks": [ + { + "type": "prompt", + "prompt": "You are a self-check reminder. Analyze what was done in this session.\n\nReview the conversation and any files that were edited. For each skill in skill-rules.json that has stopChecks defined:\n\n1. Check if edited files match the skill's fileTriggers (pathPatterns or contentPatterns)\n2. If they match, check if the file content contains any stopChecks.patterns\n3. If patterns found, include the corresponding reminders\n\nReturn format:\n{\"decision\": \"approve\", \"systemMessage\": \"Self-check reminders:\\n- [reminder 1]\\n- [reminder 2]\"}\n\nIf no relevant patterns found, return:\n{\"decision\": \"approve\", \"systemMessage\": \"\"}\n\nAlways approve (advisory only). Keep reminders brief and actionable.", + "timeout": 30 + } + ] + } + ], + + "SessionStart": [ + { + "matcher": "*", + "hooks": [ + { + "type": "command", + "command": "cat ${CLAUDE_PLUGIN_ROOT}/config/skill-rules.json 2>/dev/null || echo '{}'", + "timeout": 5 + } + ] + } + ] + } +} diff --git a/skill-activation-hooks/plugin.json b/skill-activation-hooks/plugin.json new file mode 100644 index 0000000..70d5af7 --- /dev/null +++ b/skill-activation-hooks/plugin.json @@ -0,0 +1,7 @@ +{ + "name": "skill-activation-hooks", + "version": "1.0.0", + "description": "Prompt-based hooks for skill activation reminders and self-check", + "author": "ryzhikok", + "hooks": ["./hooks/"] +} From d91e45030ec25ff4bb14e14fc78c2006eb2fceb8 Mon Sep 17 00:00:00 2001 From: Kirill Ryzhikov Date: Tue, 27 Jan 2026 21:49:44 +0000 Subject: [PATCH 3/6] fix: correct hook response schema and embed skill rules - Add required "ok": true field to response formats - Embed skill rules directly in prompts (prompt hooks cannot read files) - Remove SessionStart hook (no longer needed) Co-Authored-By: Claude Opus 4.5 --- skill-activation-hooks/hooks/hooks.json | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/skill-activation-hooks/hooks/hooks.json b/skill-activation-hooks/hooks/hooks.json index 383fce2..05b9d89 100644 --- a/skill-activation-hooks/hooks/hooks.json +++ b/skill-activation-hooks/hooks/hooks.json @@ -7,7 +7,7 @@ "hooks": [ { "type": "prompt", - "prompt": "You are a skill activation analyzer. Read the skill rules from the project's skill-rules.json and analyze the user's prompt.\n\nUser prompt: $USER_PROMPT\n\nFor each skill in skill-rules.json, check:\n1. Does the prompt contain any keywords from promptTriggers.keywords?\n2. Does the prompt match any regex in promptTriggers.intentPatterns?\n\nIf ANY skill matches, return a systemMessage in this format:\n\n{\"systemMessage\": \"SKILL ACTIVATION CHECK\\n\\nRelevant skills detected:\\n- [skill-name]: [brief reason]\\n\\nConsider invoking these skills before responding.\"}\n\nIf NO skills match, return: {\"systemMessage\": \"\"}\n\nBe concise. Only list genuinely relevant skills.", + "prompt": "You are a skill activation analyzer. Check if the user's prompt matches any skill rules.\n\nUser prompt: $USER_PROMPT\n\nSKILL RULES:\n1. polars-expertise - keywords: polars, dataframe, lazyframe, parquet, scan_parquet, group_by_dynamic, rolling_mean, asof join, OHLCV, window function. Intent patterns: convert/migrate pandas/pyspark/kdb to polars, lazy/eager evaluation, read/write/scan parquet, rolling/window operations, time series resample/aggregate.\n\n2. arxiv-search - keywords: arxiv, preprint, research paper, academic paper, scientific literature, paper search, find papers, ML research, recent research. Intent patterns: find/search/look up paper/research/preprint, latest/recent research/paper/work, what does the literature/research say, state of the art/SOTA.\n\nIf ANY skill matches (keyword found OR intent pattern matches), return:\n{\"ok\": true, \"systemMessage\": \"SKILL ACTIVATION CHECK - Relevant: [skill-name] ([reason])\"}\n\nIf NO skills match, return:\n{\"ok\": true, \"systemMessage\": \"\"}\n\nBe concise. Case-insensitive matching.", "timeout": 30 } ] @@ -20,24 +20,11 @@ "hooks": [ { "type": "prompt", - "prompt": "You are a self-check reminder. Analyze what was done in this session.\n\nReview the conversation and any files that were edited. For each skill in skill-rules.json that has stopChecks defined:\n\n1. Check if edited files match the skill's fileTriggers (pathPatterns or contentPatterns)\n2. If they match, check if the file content contains any stopChecks.patterns\n3. If patterns found, include the corresponding reminders\n\nReturn format:\n{\"decision\": \"approve\", \"systemMessage\": \"Self-check reminders:\\n- [reminder 1]\\n- [reminder 2]\"}\n\nIf no relevant patterns found, return:\n{\"decision\": \"approve\", \"systemMessage\": \"\"}\n\nAlways approve (advisory only). Keep reminders brief and actionable.", + "prompt": "You are a self-check reminder for code quality. Based on the session context, check if any of these reminders apply:\n\nFor Python files with polars code, check for anti-patterns:\n- map_elements (use native expressions instead)\n- iter_rows (use vectorized operations)\n- apply() (use expressions)\n- pandas imports alongside polars (stick to one)\n\nIf any apply, return:\n{\"ok\": true, \"decision\": \"approve\", \"systemMessage\": \"Self-check: [relevant reminders]\"}\n\nIf nothing applies, return:\n{\"ok\": true, \"decision\": \"approve\", \"systemMessage\": \"\"}\n\nAlways approve. Keep brief.", "timeout": 30 } ] } - ], - - "SessionStart": [ - { - "matcher": "*", - "hooks": [ - { - "type": "command", - "command": "cat ${CLAUDE_PLUGIN_ROOT}/config/skill-rules.json 2>/dev/null || echo '{}'", - "timeout": 5 - } - ] - } ] } } From 9662c89b1b2a0268c7c75ca54fcaf639137a25e0 Mon Sep 17 00:00:00 2001 From: Kirill Ryzhikov Date: Tue, 27 Jan 2026 21:52:27 +0000 Subject: [PATCH 4/6] remove docs --- ...026-01-27-skill-activation-hooks-design.md | 185 ------------------ 1 file changed, 185 deletions(-) delete mode 100644 docs/plans/2026-01-27-skill-activation-hooks-design.md diff --git a/docs/plans/2026-01-27-skill-activation-hooks-design.md b/docs/plans/2026-01-27-skill-activation-hooks-design.md deleted file mode 100644 index 8a46bce..0000000 --- a/docs/plans/2026-01-27-skill-activation-hooks-design.md +++ /dev/null @@ -1,185 +0,0 @@ -# Skill Activation Hooks - Design Document - -**Date:** 2026-01-27 -**Status:** Approved - -## Overview - -Two prompt-based hooks to improve Claude's skill awareness: - -1. **UserPromptSubmit** - Analyzes prompts before Claude sees them, injects skill activation reminders -2. **Stop** - Advisory self-check reminders based on edited files (non-blocking) - -## Decisions - -- **Location:** New plugin in this marketplace (`skill-activation-hooks/`) -- **Config approach:** Minimal framework + examples (polars-expertise, arxiv-search) -- **Hook type:** Prompt-based for both hooks (native, no external API) -- **Stop behavior:** Advisory only, never blocks - -## Plugin Structure - -``` -skill-activation-hooks/ -├── plugin.json -├── hooks/ -│ └── hooks.json -├── config/ -│ └── skill-rules.json -└── README.md -``` - -## Configuration Schema: skill-rules.json - -```json -{ - "$schema": "./skill-rules-schema.json", - "version": "1.0", - - "skills": { - "polars-expertise": { - "description": "Polars DataFrame library for Python/Rust - expressions, lazy evaluation, performance", - "type": "domain", - "enforcement": "suggest", - "priority": "high", - - "promptTriggers": { - "keywords": [ - "polars", "dataframe", "lazyframe", "parquet", - "scan_parquet", "group_by_dynamic", "rolling_mean", - "asof join", "OHLCV", "window function" - ], - "intentPatterns": [ - "(convert|migrate).*?(pandas|pyspark|kdb).*?polars", - "(lazy|eager).*?(evaluation|execution)", - "(read|write|scan).*?parquet", - "(rolling|window).*?(mean|std|sum)", - "time series.*?(resample|aggregate)" - ] - }, - - "fileTriggers": { - "pathPatterns": ["**/*.py", "**/*.rs"], - "contentPatterns": [ - "import polars", - "use polars::", - "pl\\.scan_", - "pl\\.read_", - "LazyFrame", - "\\.collect\\(\\)" - ] - }, - - "stopChecks": { - "patterns": ["map_elements", "iter_rows", "apply\\(", "pandas"], - "reminders": [ - "Using native expressions instead of map_elements?", - "Early projection (select columns before filter)?", - "Lazy evaluation for large data?" - ] - } - }, - - "arxiv-search": { - "description": "Search arXiv for academic papers and preprints", - "type": "research", - "enforcement": "suggest", - "priority": "medium", - - "promptTriggers": { - "keywords": [ - "arxiv", "preprint", "research paper", "academic paper", - "scientific literature", "paper search", "find papers", - "ML research", "recent research" - ], - "intentPatterns": [ - "(find|search|look up).*?(paper|research|preprint)", - "(latest|recent).*?(research|paper|work).*?(on|about)", - "what does the (literature|research) say", - "(state of the art|SOTA).*?(in|for)" - ] - }, - - "fileTriggers": { - "pathPatterns": [], - "contentPatterns": [] - }, - - "stopChecks": { - "patterns": [], - "reminders": [] - } - } - } -} -``` - -## Hook Configuration: hooks.json - -```json -{ - "description": "Skill activation hooks - prompt analysis and self-check reminders", - "hooks": { - "UserPromptSubmit": [ - { - "matcher": "*", - "hooks": [ - { - "type": "prompt", - "prompt": "You are a skill activation analyzer. Read the skill rules from the project's skill-rules.json and analyze the user's prompt.\n\nUser prompt: $USER_PROMPT\n\nFor each skill in skill-rules.json, check:\n1. Does the prompt contain any keywords from promptTriggers.keywords?\n2. Does the prompt match any regex in promptTriggers.intentPatterns?\n\nIf ANY skill matches, return a systemMessage in this format:\n\n{\"systemMessage\": \"SKILL ACTIVATION CHECK\\n\\nRelevant skills detected:\\n- [skill-name]: [brief reason]\\n\\nConsider invoking these skills before responding.\"}\n\nIf NO skills match, return: {\"systemMessage\": \"\"}\n\nBe concise. Only list genuinely relevant skills.", - "timeout": 30 - } - ] - } - ], - - "Stop": [ - { - "matcher": "*", - "hooks": [ - { - "type": "prompt", - "prompt": "You are a self-check reminder. Analyze what was done in this session.\n\nReview the conversation and any files that were edited. For each skill in skill-rules.json that has stopChecks defined:\n\n1. Check if edited files match the skill's fileTriggers (pathPatterns or contentPatterns)\n2. If they match, check if the file content contains any stopChecks.patterns\n3. If patterns found, include the corresponding reminders\n\nReturn format:\n{\"decision\": \"approve\", \"systemMessage\": \"Self-check reminders:\\n- [reminder 1]\\n- [reminder 2]\"}\n\nIf no relevant patterns found, return:\n{\"decision\": \"approve\", \"systemMessage\": \"\"}\n\nAlways approve (advisory only). Keep reminders brief and actionable.", - "timeout": 30 - } - ] - } - ], - - "SessionStart": [ - { - "matcher": "*", - "hooks": [ - { - "type": "command", - "command": "cat ${CLAUDE_PLUGIN_ROOT}/config/skill-rules.json 2>/dev/null || echo '{}'", - "timeout": 5 - } - ] - } - ] - } -} -``` - -## Plugin Manifest: plugin.json - -```json -{ - "name": "skill-activation-hooks", - "version": "1.0.0", - "description": "Prompt-based hooks for skill activation reminders and self-check", - "author": "Deevs", - "hooks": ["./hooks/"] -} -``` - -## Implementation Steps - -1. Create `skill-activation-hooks/` directory -2. Create `plugin.json` -3. Create `hooks/hooks.json` -4. Create `config/skill-rules.json` with examples -5. Create `README.md` -6. Register in `marketplace.json` -7. Test with `claude --debug` From 84d22f26dbe8c9b79e89162aa785ae7c8a559ea6 Mon Sep 17 00:00:00 2001 From: Kirill Ryzhikov Date: Mon, 16 Feb 2026 22:11:50 +0000 Subject: [PATCH 5/6] feat: rewrite skill-activation-hooks with shell-based weighted keyword matching Replace prompt-based hooks (LLM calls) with a deterministic shell script that scores user prompts against weighted keywords and regex intent patterns. Runs in ~150ms with zero external deps beyond jq. - UserPromptSubmit hook injects additionalContext when skills match - Single jq pass flattens config into TSV, pure bash scoring loop - Configurable thresholds, keyword weights, and intent pattern bonuses - Covers 8 skills/agents: polars, arxiv, reviewer, tester, architect, python-dev, strategist, 97-dev - Tested via --plugin-dir and marketplace installation Co-Authored-By: Claude Opus 4.6 --- .claude-plugin/marketplace.json | 5 +- .../.claude-plugin/plugin.json | 8 + skill-activation-hooks/README.md | 90 --------- .../config/skill-rules.json | 80 -------- skill-activation-hooks/config/skills.json | 181 ++++++++++++++++++ skill-activation-hooks/hooks/hooks.json | 21 +- skill-activation-hooks/plugin.json | 7 - skill-activation-hooks/scripts/activate.sh | 88 +++++++++ 8 files changed, 283 insertions(+), 197 deletions(-) create mode 100644 skill-activation-hooks/.claude-plugin/plugin.json delete mode 100644 skill-activation-hooks/README.md delete mode 100644 skill-activation-hooks/config/skill-rules.json create mode 100644 skill-activation-hooks/config/skills.json delete mode 100644 skill-activation-hooks/plugin.json create mode 100755 skill-activation-hooks/scripts/activate.sh diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index e7bc289..143e0e0 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -80,9 +80,8 @@ }, { "name": "skill-activation-hooks", - "description": "Prompt-based hooks for skill activation reminders and self-check", - "source": "./skill-activation-hooks", - "hooks": ["./hooks/"] + "description": "Shell-based keyword matching hooks that inject skill/agent reminders into user prompts", + "source": "./skill-activation-hooks" } ] } diff --git a/skill-activation-hooks/.claude-plugin/plugin.json b/skill-activation-hooks/.claude-plugin/plugin.json new file mode 100644 index 0000000..5e123f7 --- /dev/null +++ b/skill-activation-hooks/.claude-plugin/plugin.json @@ -0,0 +1,8 @@ +{ + "name": "skill-activation-hooks", + "version": "2.0.0", + "description": "Shell-based keyword matching hooks that inject skill reminders into user prompts", + "author": { + "name": "ryzhikok" + } +} diff --git a/skill-activation-hooks/README.md b/skill-activation-hooks/README.md deleted file mode 100644 index 88395c5..0000000 --- a/skill-activation-hooks/README.md +++ /dev/null @@ -1,90 +0,0 @@ -# skill-activation-hooks - -Automatic skill activation reminders and self-check for Claude Code. - -## How It Works - -Two prompt-based hooks that improve skill awareness: - -1. **UserPromptSubmit** - Analyzes your prompt before Claude sees it, injects skill reminders based on keywords and intent patterns - -2. **Stop** - When Claude finishes, checks edited files for patterns that warrant self-check reminders (advisory, non-blocking) - -3. **SessionStart** - Loads skill-rules.json into context for the prompt hooks to reference - -## Configuration - -Edit `config/skill-rules.json` to add your own skills. Each skill can define: - -### promptTriggers - -Activates when user submits a prompt: - -- `keywords` - Exact words/phrases to match (case-insensitive) -- `intentPatterns` - Regex patterns to catch user intent - -### fileTriggers - -Activates based on files being edited: - -- `pathPatterns` - Glob patterns for file paths -- `contentPatterns` - Regex patterns for file content - -### stopChecks - -What to look for when Claude finishes: - -- `patterns` - Regex patterns to search in edited files -- `reminders` - Human-readable reminders shown if patterns found - -## Example Rule - -```json -{ - "my-skill": { - "description": "Brief description", - "type": "domain", - "enforcement": "suggest", - "priority": "high", - - "promptTriggers": { - "keywords": ["keyword1", "keyword2"], - "intentPatterns": ["(create|add).*?thing"] - }, - - "fileTriggers": { - "pathPatterns": ["src/**/*.ts"], - "contentPatterns": ["import.*MyLib"] - }, - - "stopChecks": { - "patterns": ["antiPattern", "badPractice"], - "reminders": ["Did you avoid the anti-pattern?"] - } - } -} -``` - -## Installation - -This plugin is part of the deevs-agent-system marketplace. Install via: - -```bash -claude plugins add deevs-agent-system/skill-activation-hooks -``` - -Or add to your local plugins directory. - -## Testing - -Run Claude Code with debug mode to see hook execution: - -```bash -claude --debug -``` - -## Notes - -- All hooks are advisory - they never block Claude from completing -- Prompt hooks use the session's model (no external API calls) -- Skill rules are loaded once at session start via SessionStart hook diff --git a/skill-activation-hooks/config/skill-rules.json b/skill-activation-hooks/config/skill-rules.json deleted file mode 100644 index 4e9e62e..0000000 --- a/skill-activation-hooks/config/skill-rules.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "version": "1.0", - "description": "Skill activation rules - add your own skills here", - - "skills": { - "polars-expertise": { - "description": "Polars DataFrame library for Python/Rust - expressions, lazy evaluation, performance", - "type": "domain", - "enforcement": "suggest", - "priority": "high", - - "promptTriggers": { - "keywords": [ - "polars", "dataframe", "lazyframe", "parquet", - "scan_parquet", "group_by_dynamic", "rolling_mean", - "asof join", "OHLCV", "window function" - ], - "intentPatterns": [ - "(convert|migrate).*?(pandas|pyspark|kdb).*?polars", - "(lazy|eager).*?(evaluation|execution)", - "(read|write|scan).*?parquet", - "(rolling|window).*?(mean|std|sum)", - "time series.*?(resample|aggregate)" - ] - }, - - "fileTriggers": { - "pathPatterns": ["**/*.py", "**/*.rs"], - "contentPatterns": [ - "import polars", - "use polars::", - "pl\\.scan_", - "pl\\.read_", - "LazyFrame", - "\\.collect\\(\\)" - ] - }, - - "stopChecks": { - "patterns": ["map_elements", "iter_rows", "apply\\(", "pandas"], - "reminders": [ - "Using native expressions instead of map_elements?", - "Early projection (select columns before filter)?", - "Lazy evaluation for large data?" - ] - } - }, - - "arxiv-search": { - "description": "Search arXiv for academic papers and preprints", - "type": "research", - "enforcement": "suggest", - "priority": "medium", - - "promptTriggers": { - "keywords": [ - "arxiv", "preprint", "research paper", "academic paper", - "scientific literature", "paper search", "find papers", - "ML research", "recent research" - ], - "intentPatterns": [ - "(find|search|look up).*?(paper|research|preprint)", - "(latest|recent).*?(research|paper|work).*?(on|about)", - "what does the (literature|research) say", - "(state of the art|SOTA).*?(in|for)" - ] - }, - - "fileTriggers": { - "pathPatterns": [], - "contentPatterns": [] - }, - - "stopChecks": { - "patterns": [], - "reminders": [] - } - } - } -} diff --git a/skill-activation-hooks/config/skills.json b/skill-activation-hooks/config/skills.json new file mode 100644 index 0000000..d3fa820 --- /dev/null +++ b/skill-activation-hooks/config/skills.json @@ -0,0 +1,181 @@ +{ + "version": "1.0", + + "skills": { + "polars-expertise": { + "threshold": 3, + "keywords": [ + {"term": "polars", "w": 5}, + {"term": "lazyframe", "w": 5}, + {"term": "scan_parquet", "w": 5}, + {"term": "group_by_dynamic", "w": 5}, + {"term": "rolling_mean", "w": 4}, + {"term": "asof join", "w": 4}, + {"term": "join_asof", "w": 4}, + {"term": "map_elements", "w": 3}, + {"term": "ohlcv", "w": 3}, + {"term": "dataframe", "w": 1}, + {"term": "parquet", "w": 2}, + {"term": "window function", "w": 2}, + {"term": "lazy evaluation", "w": 3}, + {"term": "arrow", "w": 1} + ], + "intentPatterns": [ + "(convert|migrate|switch|move|rewrite|port).*?(pandas|pyspark|spark|kdb).*?polars", + "(convert|migrate|switch|move|rewrite|port).*?polars", + "polars.*?(instead of|replace|vs|over).*?(pandas|spark)", + "(lazy|eager).*?(evaluat|execut|frame|mode)", + "(scan|read|write|load|stream).*?parquet", + "(rolling|window|moving).*?(mean|std|sum|average|median)", + "time.?series.*?(resample|aggregat|ohlc|bar)" + ], + "intentWeight": 4, + "message": "SKILL AVAILABLE: polars-expertise -- Invoke via Skill tool for Polars DataFrame guidance (expressions, lazy eval, parquet I/O, time series, pandas/spark/kdb migration)." + }, + + "arxiv-search": { + "threshold": 3, + "keywords": [ + {"term": "arxiv", "w": 5}, + {"term": "preprint", "w": 4}, + {"term": "research paper", "w": 4}, + {"term": "academic paper", "w": 4}, + {"term": "scientific literature", "w": 4}, + {"term": "paper search", "w": 3}, + {"term": "find papers", "w": 3}, + {"term": "recent research", "w": 2}, + {"term": "state of the art", "w": 2}, + {"term": "sota", "w": 2} + ], + "intentPatterns": [ + "(find|search|look.?up|fetch|get).*?(paper|research|preprint|publication)", + "(latest|recent|new).*?(research|paper|work|result).*?(on|about|in|for)", + "what does the (literature|research) say", + "(state of the art|sota|survey).*?(in|for|on|about)" + ], + "intentWeight": 4, + "message": "SKILL AVAILABLE: arxiv-search -- Invoke via Skill tool to search arXiv for academic papers and preprints." + }, + + "dev-experts:reviewer": { + "threshold": 3, + "keywords": [ + {"term": "code review", "w": 5}, + {"term": "review my code", "w": 5}, + {"term": "review this", "w": 3}, + {"term": "security review", "w": 4}, + {"term": "before commit", "w": 3}, + {"term": "before merging", "w": 3}, + {"term": "before pr", "w": 3}, + {"term": "race condition", "w": 3}, + {"term": "memory leak", "w": 3} + ], + "intentPatterns": [ + "(review|check|audit|inspect).*?(code|changes|diff|pr|pull request|commit)", + "(security|vulnerability|bug).*?(review|check|scan|audit)", + "(before|pre).?(commit|merge|push|pr).*?(review|check)" + ], + "intentWeight": 4, + "message": "AGENT AVAILABLE: dev-experts:reviewer -- Launch via Task tool (subagent_type='dev-experts:reviewer') for thorough code review with security, performance, and correctness checks." + }, + + "dev-experts:tester": { + "threshold": 3, + "keywords": [ + {"term": "write tests", "w": 5}, + {"term": "add tests", "w": 5}, + {"term": "unit test", "w": 4}, + {"term": "test coverage", "w": 4}, + {"term": "integration test", "w": 4}, + {"term": "edge cases", "w": 2}, + {"term": "test plan", "w": 3} + ], + "intentPatterns": [ + "(write|add|create|generate|implement).*?(test|spec|assertion)", + "(need|missing|improve|increase).*?(test|coverage|spec)", + "(test|cover).*?(edge case|error|failure|boundary)" + ], + "intentWeight": 4, + "message": "AGENT AVAILABLE: dev-experts:tester -- Launch via Task tool (subagent_type='dev-experts:tester') for comprehensive test writing with edge cases and error conditions." + }, + + "dev-experts:architect": { + "threshold": 4, + "keywords": [ + {"term": "system design", "w": 5}, + {"term": "software architecture", "w": 5}, + {"term": "design decision", "w": 4}, + {"term": "trade-off", "w": 3}, + {"term": "implementation plan", "w": 4}, + {"term": "feature design", "w": 4}, + {"term": "alternatives", "w": 2} + ], + "intentPatterns": [ + "(design|architect|plan|structure).*?(feature|system|service|module|component)", + "(compare|evaluate|choose|pick).*?(approach|pattern|framework|architecture)", + "how.?should.?(i|we).*?(design|structure|implement|build|organize)" + ], + "intentWeight": 4, + "message": "AGENT AVAILABLE: dev-experts:architect -- Launch via Task tool (subagent_type='dev-experts:architect') for feature design with trade-off analysis and implementation planning." + }, + + "dev-experts:python-dev": { + "threshold": 4, + "keywords": [ + {"term": "pythonic", "w": 5}, + {"term": "python refactor", "w": 5}, + {"term": "msgspec", "w": 4}, + {"term": "type hint", "w": 2}, + {"term": "python review", "w": 4}, + {"term": "uv pip", "w": 3} + ], + "intentPatterns": [ + "(review|refactor|improve|clean).*?python.*?(code|module|file|script)", + "(make|rewrite).*?(pythonic|idiomatic).*?python", + "python.*?(best practice|pattern|idiom|style)" + ], + "intentWeight": 4, + "message": "AGENT AVAILABLE: dev-experts:python-dev -- Launch via Task tool (subagent_type='dev-experts:python-dev') for Python code review, refactoring, and modern Python patterns." + }, + + "research-experts:strategist": { + "threshold": 4, + "keywords": [ + {"term": "strategy", "w": 3}, + {"term": "alpha", "w": 3}, + {"term": "signal", "w": 2}, + {"term": "backtest", "w": 3}, + {"term": "pnl", "w": 3}, + {"term": "hypothesis", "w": 2}, + {"term": "edge case", "w": 1}, + {"term": "hft", "w": 4}, + {"term": "market making", "w": 4}, + {"term": "microstructure", "w": 4} + ], + "intentPatterns": [ + "(research|investigate|analyze|decompose).*?(strategy|signal|alpha|edge)", + "(why|how|when).*?(strategy|signal).*?(work|fail|perform|behave)", + "(improve|optimize|tune).*?(strategy|signal|execution)" + ], + "intentWeight": 4, + "message": "AGENT AVAILABLE: research-experts:strategist -- Launch via Task tool (subagent_type='research-experts:strategist') for strategy research, hypothesis decomposition, and signal analysis." + }, + + "97-dev": { + "threshold": 3, + "keywords": [ + {"term": "best practice", "w": 3}, + {"term": "programming wisdom", "w": 4}, + {"term": "code quality", "w": 2}, + {"term": "professional development", "w": 3}, + {"term": "97 things", "w": 5} + ], + "intentPatterns": [ + "what.?(should|would).*?(good|experienced|senior).*?(developer|programmer|engineer)", + "(principle|wisdom|lesson).*?(programming|software|coding)" + ], + "intentWeight": 3, + "message": "SKILL AVAILABLE: 97-dev -- Invoke via Skill tool for programming wisdom from '97 Things Every Programmer Should Know'." + } + } +} diff --git a/skill-activation-hooks/hooks/hooks.json b/skill-activation-hooks/hooks/hooks.json index 05b9d89..3ab5a96 100644 --- a/skill-activation-hooks/hooks/hooks.json +++ b/skill-activation-hooks/hooks/hooks.json @@ -1,27 +1,14 @@ { - "description": "Skill activation hooks - prompt analysis and self-check reminders", + "description": "Weighted keyword matching for skill activation on user prompts", "hooks": { "UserPromptSubmit": [ { "matcher": "*", "hooks": [ { - "type": "prompt", - "prompt": "You are a skill activation analyzer. Check if the user's prompt matches any skill rules.\n\nUser prompt: $USER_PROMPT\n\nSKILL RULES:\n1. polars-expertise - keywords: polars, dataframe, lazyframe, parquet, scan_parquet, group_by_dynamic, rolling_mean, asof join, OHLCV, window function. Intent patterns: convert/migrate pandas/pyspark/kdb to polars, lazy/eager evaluation, read/write/scan parquet, rolling/window operations, time series resample/aggregate.\n\n2. arxiv-search - keywords: arxiv, preprint, research paper, academic paper, scientific literature, paper search, find papers, ML research, recent research. Intent patterns: find/search/look up paper/research/preprint, latest/recent research/paper/work, what does the literature/research say, state of the art/SOTA.\n\nIf ANY skill matches (keyword found OR intent pattern matches), return:\n{\"ok\": true, \"systemMessage\": \"SKILL ACTIVATION CHECK - Relevant: [skill-name] ([reason])\"}\n\nIf NO skills match, return:\n{\"ok\": true, \"systemMessage\": \"\"}\n\nBe concise. Case-insensitive matching.", - "timeout": 30 - } - ] - } - ], - - "Stop": [ - { - "matcher": "*", - "hooks": [ - { - "type": "prompt", - "prompt": "You are a self-check reminder for code quality. Based on the session context, check if any of these reminders apply:\n\nFor Python files with polars code, check for anti-patterns:\n- map_elements (use native expressions instead)\n- iter_rows (use vectorized operations)\n- apply() (use expressions)\n- pandas imports alongside polars (stick to one)\n\nIf any apply, return:\n{\"ok\": true, \"decision\": \"approve\", \"systemMessage\": \"Self-check: [relevant reminders]\"}\n\nIf nothing applies, return:\n{\"ok\": true, \"decision\": \"approve\", \"systemMessage\": \"\"}\n\nAlways approve. Keep brief.", - "timeout": 30 + "type": "command", + "command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/activate.sh", + "timeout": 5 } ] } diff --git a/skill-activation-hooks/plugin.json b/skill-activation-hooks/plugin.json deleted file mode 100644 index 70d5af7..0000000 --- a/skill-activation-hooks/plugin.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "skill-activation-hooks", - "version": "1.0.0", - "description": "Prompt-based hooks for skill activation reminders and self-check", - "author": "ryzhikok", - "hooks": ["./hooks/"] -} diff --git a/skill-activation-hooks/scripts/activate.sh b/skill-activation-hooks/scripts/activate.sh new file mode 100755 index 0000000..8424753 --- /dev/null +++ b/skill-activation-hooks/scripts/activate.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash +set -euo pipefail + +PLUGIN_ROOT="$(cd "$(dirname "$0")/.." && pwd)" +CONFIG="$PLUGIN_ROOT/config/skills.json" + +if ! command -v jq &>/dev/null; then + exit 0 +fi + +if [ ! -f "$CONFIG" ]; then + exit 0 +fi + +input=$(cat) +prompt=$(echo "$input" | jq -r '.prompt // empty') + +if [ -z "$prompt" ]; then + exit 0 +fi + +prompt_lower=$(echo "$prompt" | tr '[:upper:]' '[:lower:]') + +# Single jq call: flatten all rules into TSV grouped by skill. +# Entry types prefixed for ordering: 0meta before 1kw before 2ip. +# jq iterates keys in insertion order, so entries for each skill are contiguous. +rules=$(jq -r ' + .skills | to_entries[] | + .key as $sk | .value as $v | + ([$sk, "0meta", ($v.threshold // 3 | tostring), $v.message] | @tsv), + (($v.keywords // [])[] | [$sk, "1kw", .term, (.w // 1 | tostring)] | @tsv), + (($v.intentPatterns // [])[] | [$sk, "2ip", ., ($v.intentWeight // 3 | tostring)] | @tsv) +' "$CONFIG") + +current_skill="" +score=0 +threshold=0 +message="" +matched="" + +emit_if_matched() { + if [ -n "$current_skill" ] && [ "$score" -ge "$threshold" ]; then + matched="${matched}${message}\n" + fi +} + +while IFS=$'\t' read -r skill typ val extra; do + [ -z "$skill" ] && continue + + if [ "$skill" != "$current_skill" ]; then + emit_if_matched + current_skill="$skill" + score=0 + threshold=0 + message="" + fi + + case "$typ" in + 0meta) + threshold="$val" + message="$extra" + ;; + 1kw) + if echo "$prompt_lower" | grep -qiF -- "$val"; then + score=$((score + extra)) + fi + ;; + 2ip) + if echo "$prompt_lower" | grep -qiE -- "$val" 2>/dev/null; then + score=$((score + extra)) + fi + ;; + esac +done <<< "$rules" +emit_if_matched + +if [ -z "$matched" ]; then + exit 0 +fi + +# additionalContext injects into Claude's conversation context. +# Plain stdout also works but is more visible in the transcript. +context=$(printf '%b' "$matched" | sed '/^$/d') +json_context=$(echo "$context" | jq -Rs '.') + +cat < Date: Mon, 16 Feb 2026 22:24:21 +0000 Subject: [PATCH 6/6] feat: add all missing skills and agents to activation hooks config Expanded from 8 to 28 entries covering the full marketplace: - Skills: golang-pro, venue-expert, datetime, anti-ai-slop - dev-experts: cpp-dev, rust-dev, devops - bug-hunters: orchestrator, logic-hunter, cpp-hunter, python-hunter - alpha-squad: fundamentalist, vulture, network-architect, book-physicist, causal-detective - mft-research-experts: mft-strategist, data-sentinel, factor-geometer, skeptic, forensic-auditor Also fixed: research-experts:strategist -> mft-research-experts:mft-strategist Co-Authored-By: Claude Opus 4.6 --- skill-activation-hooks/config/skills.json | 511 ++++++++++++++++++++-- 1 file changed, 486 insertions(+), 25 deletions(-) diff --git a/skill-activation-hooks/config/skills.json b/skill-activation-hooks/config/skills.json index d3fa820..d9c1b39 100644 --- a/skill-activation-hooks/config/skills.json +++ b/skill-activation-hooks/config/skills.json @@ -57,6 +57,135 @@ "message": "SKILL AVAILABLE: arxiv-search -- Invoke via Skill tool to search arXiv for academic papers and preprints." }, + "golang-pro": { + "threshold": 3, + "keywords": [ + {"term": "golang", "w": 5}, + {"term": "goroutine", "w": 5}, + {"term": "goroutines", "w": 5}, + {"term": "go channel", "w": 5}, + {"term": "go module", "w": 4}, + {"term": "go.mod", "w": 4}, + {"term": "go.sum", "w": 4}, + {"term": "grpc", "w": 2}, + {"term": "go test", "w": 3}, + {"term": "go build", "w": 3}, + {"term": "go run", "w": 3}, + {"term": "sync.mutex", "w": 5}, + {"term": "sync.waitgroup", "w": 5}, + {"term": "go generics", "w": 4}, + {"term": "go interface", "w": 3}, + {"term": "go concurrency", "w": 5} + ], + "intentPatterns": [ + "(write|build|create|implement).*?(in|with|using)\\s+go\\b", + "\\bgo\\b.*?(concurren|parallel|goroutine|channel|select)", + "(table.?driven|benchmark).*?(test|go)", + "\\bgo\\b.*?(error handling|interface|struct|method)" + ], + "intentWeight": 4, + "message": "SKILL AVAILABLE: golang-pro -- Invoke via Skill tool for senior Go developer guidance (concurrency, generics, gRPC, performance, testing, GC tuning)." + }, + + "venue-expert": { + "threshold": 3, + "keywords": [ + {"term": "microstructure", "w": 4}, + {"term": "order book", "w": 4}, + {"term": "nbbo", "w": 5}, + {"term": "reg nms", "w": 5}, + {"term": "maker-taker", "w": 5}, + {"term": "price-time priority", "w": 5}, + {"term": "opening cross", "w": 5}, + {"term": "closing cross", "w": 5}, + {"term": "noii", "w": 5}, + {"term": "itch", "w": 3}, + {"term": "ouch", "w": 3}, + {"term": "luld", "w": 5}, + {"term": "sip feed", "w": 5}, + {"term": "direct feed", "w": 4}, + {"term": "feed handler", "w": 4}, + {"term": "ctp", "w": 2}, + {"term": "shfe", "w": 5}, + {"term": "dce", "w": 4}, + {"term": "czce", "w": 5}, + {"term": "cffex", "w": 5}, + {"term": "ine", "w": 3}, + {"term": "trading venue", "w": 4}, + {"term": "exchange mechanics", "w": 4}, + {"term": "tick size", "w": 3}, + {"term": "trade-through", "w": 5}, + {"term": "best execution", "w": 3}, + {"term": "auction", "w": 2}, + {"term": "halt", "w": 1} + ], + "intentPatterns": [ + "(how|what|explain|describe).*?(order book|matching engine|auction|exchange)", + "(exchange|venue).*?(rule|mechanic|session|schedule|fee)", + "(feed|market data).*?(handler|protocol|format|latency)", + "(chinese|china).*?(futures|exchange|venue|ctp)" + ], + "intentWeight": 4, + "message": "SKILL AVAILABLE: venue-expert -- Invoke via Skill tool for trading venue mechanics (order books, auctions, Reg NMS, feed handlers, Chinese futures/CTP, execution models)." + }, + + "datetime": { + "threshold": 4, + "keywords": [ + {"term": "current date", "w": 5}, + {"term": "current time", "w": 5}, + {"term": "what time", "w": 5}, + {"term": "what date", "w": 5}, + {"term": "today's date", "w": 5}, + {"term": "timestamp", "w": 2}, + {"term": "iso 8601", "w": 4}, + {"term": "utc time", "w": 4} + ], + "intentPatterns": [ + "what('s|\\s+is)\\s+the\\s+(current|today).*?(date|time)", + "(give|get|show|tell).*?(current|now).*?(date|time|timestamp)" + ], + "intentWeight": 5, + "message": "SKILL AVAILABLE: datetime -- Invoke via Skill tool to get current date/time in various formats (ISO 8601, UTC, epoch, etc.)." + }, + + "anti-ai-slop": { + "threshold": 4, + "keywords": [ + {"term": "ai slop", "w": 5}, + {"term": "ai-slop", "w": 5}, + {"term": "remove slop", "w": 5}, + {"term": "clean up slop", "w": 5}, + {"term": "unnecessary comments", "w": 3}, + {"term": "comment bloat", "w": 4}, + {"term": "defensive checks", "w": 2}, + {"term": "redundant validation", "w": 3} + ], + "intentPatterns": [ + "(clean|remove|strip|delete).*?(ai|generated|unnecessary|redundant).*?(comment|check|validation|slop)", + "(too many|bloated|excessive).*?(comment|docstring|type annotation|validation)" + ], + "intentWeight": 4, + "message": "SKILL AVAILABLE: anti-ai-slop -- Invoke via Skill tool to clean up AI-generated slop (unnecessary comments, bloated docstrings, redundant checks) from the branch." + }, + + "97-dev": { + "threshold": 3, + "keywords": [ + {"term": "best practice", "w": 3}, + {"term": "programming wisdom", "w": 4}, + {"term": "code quality", "w": 2}, + {"term": "professional development", "w": 3}, + {"term": "97 things", "w": 5} + ], + "intentPatterns": [ + "what.?(should|would).*?(good|experienced|senior).*?(developer|programmer|engineer)", + "(principle|wisdom|lesson).*?(programming|software|coding)" + ], + "intentWeight": 3, + "message": "SKILL AVAILABLE: 97-dev -- Invoke via Skill tool for programming wisdom from '97 Things Every Programmer Should Know'." + }, + "dev-experts:reviewer": { "threshold": 3, "keywords": [ @@ -138,44 +267,376 @@ "message": "AGENT AVAILABLE: dev-experts:python-dev -- Launch via Task tool (subagent_type='dev-experts:python-dev') for Python code review, refactoring, and modern Python patterns." }, - "research-experts:strategist": { + "dev-experts:cpp-dev": { + "threshold": 3, + "keywords": [ + {"term": "c++ review", "w": 5}, + {"term": "c++20", "w": 5}, + {"term": "c++23", "w": 5}, + {"term": "undefined behavior", "w": 3}, + {"term": "raii", "w": 4}, + {"term": "move semantics", "w": 4}, + {"term": "template metaprogramming", "w": 4}, + {"term": "cache line", "w": 4}, + {"term": "lock-free", "w": 4}, + {"term": "constexpr", "w": 4}, + {"term": "std::span", "w": 5}, + {"term": "std::optional", "w": 3}, + {"term": "std::variant", "w": 4} + ], + "intentPatterns": [ + "(review|refactor|improve|optimize).*?(c\\+\\+|cpp).*?(code|module|file)", + "(c\\+\\+|cpp).*?(best practice|pattern|idiom|modern)", + "(latency|performance|cache).*?(c\\+\\+|cpp|hft)" + ], + "intentWeight": 4, + "message": "AGENT AVAILABLE: dev-experts:cpp-dev -- Launch via Task tool (subagent_type='dev-experts:cpp-dev') for HFT-grade C++20 review (UB, memory bugs, latency, cache efficiency)." + }, + + "dev-experts:rust-dev": { + "threshold": 3, + "keywords": [ + {"term": "rust review", "w": 5}, + {"term": "ownership", "w": 2}, + {"term": "borrowing", "w": 3}, + {"term": "idiomatic rust", "w": 5}, + {"term": "unsafe rust", "w": 5}, + {"term": "cargo", "w": 2}, + {"term": "async rust", "w": 4}, + {"term": "tokio", "w": 3}, + {"term": "zero-cost abstraction", "w": 4}, + {"term": "lifetime", "w": 2}, + {"term": "trait", "w": 1}, + {"term": "unwrap", "w": 2}, + {"term": "clone", "w": 1} + ], + "intentPatterns": [ + "(review|refactor|improve|optimize).*?rust.*?(code|module|crate|file)", + "rust.*?(best practice|pattern|idiom|safety)", + "(make|rewrite).*?(idiomatic|safe).*?rust" + ], + "intentWeight": 4, + "message": "AGENT AVAILABLE: dev-experts:rust-dev -- Launch via Task tool (subagent_type='dev-experts:rust-dev') for idiomatic Rust review (ownership, safety, performance, un-Rusty patterns)." + }, + + "dev-experts:devops": { + "threshold": 3, + "keywords": [ + {"term": "production issue", "w": 5}, + {"term": "production debugging", "w": 5}, + {"term": "infrastructure problem", "w": 4}, + {"term": "deployment failure", "w": 4}, + {"term": "failure investigation", "w": 4}, + {"term": "service down", "w": 4}, + {"term": "outage", "w": 4}, + {"term": "incident", "w": 2}, + {"term": "diagnostic", "w": 2} + ], + "intentPatterns": [ + "(debug|investigate|diagnose|troubleshoot).*?(production|deploy|infra|server|service)", + "(service|server|pod|container).*?(down|crash|fail|error|timeout|oom)", + "(why|what).?(is|did).*?(fail|crash|break|timeout|hang)" + ], + "intentWeight": 4, + "message": "AGENT AVAILABLE: dev-experts:devops -- Launch via Task tool (subagent_type='dev-experts:devops') for production debugging, failure investigation, and systematic infrastructure diagnostics." + }, + + "bug-hunters:orchestrator": { + "threshold": 3, + "keywords": [ + {"term": "bug hunt", "w": 5}, + {"term": "find bugs", "w": 5}, + {"term": "hunt bugs", "w": 5}, + {"term": "systematic bugs", "w": 4}, + {"term": "spec reconstruction", "w": 5}, + {"term": "adversarial validation", "w": 5} + ], + "intentPatterns": [ + "(find|hunt|search|look for|detect).*?(bug|defect|issue|flaw).*?(systematic|thorough|comprehensive)", + "(systematic|thorough|comprehensive|deep).*?(bug|defect|issue).*?(hunt|search|find|audit)", + "are there.*?(bug|issue|flaw|defect).*?(in|across|throughout)" + ], + "intentWeight": 4, + "message": "AGENT AVAILABLE: bug-hunters:orchestrator -- Launch via Task tool (subagent_type='bug-hunters:orchestrator') for systematic bug hunting with spec reconstruction, adversarial validation, and confidence-ranked reports." + }, + + "bug-hunters:logic-hunter": { "threshold": 4, "keywords": [ - {"term": "strategy", "w": 3}, - {"term": "alpha", "w": 3}, - {"term": "signal", "w": 2}, - {"term": "backtest", "w": 3}, - {"term": "pnl", "w": 3}, - {"term": "hypothesis", "w": 2}, - {"term": "edge case", "w": 1}, - {"term": "hft", "w": 4}, - {"term": "market making", "w": 4}, - {"term": "microstructure", "w": 4} + {"term": "logic bug", "w": 5}, + {"term": "spec violation", "w": 5}, + {"term": "algorithm correctness", "w": 5}, + {"term": "data flow bug", "w": 5}, + {"term": "invariant", "w": 3}, + {"term": "state machine", "w": 3}, + {"term": "contract violation", "w": 4} ], "intentPatterns": [ - "(research|investigate|analyze|decompose).*?(strategy|signal|alpha|edge)", - "(why|how|when).*?(strategy|signal).*?(work|fail|perform|behave)", - "(improve|optimize|tune).*?(strategy|signal|execution)" + "(logic|algorithm|correctness|specification).*?(bug|error|flaw|violation|gap)", + "(spec|requirement).*?(vs|mismatch|gap|diverge).*?(implementation|code)" ], "intentWeight": 4, - "message": "AGENT AVAILABLE: research-experts:strategist -- Launch via Task tool (subagent_type='research-experts:strategist') for strategy research, hypothesis decomposition, and signal analysis." + "message": "AGENT AVAILABLE: bug-hunters:logic-hunter -- Launch via Task tool (subagent_type='bug-hunters:logic-hunter') for language-agnostic logic bug hunting (spec-vs-implementation gaps, data flow, algorithm correctness)." }, - "97-dev": { + "bug-hunters:cpp-hunter": { + "threshold": 4, + "keywords": [ + {"term": "memory corruption", "w": 5}, + {"term": "use-after-free", "w": 5}, + {"term": "data race", "w": 5}, + {"term": "asan", "w": 5}, + {"term": "tsan", "w": 5}, + {"term": "ubsan", "w": 5}, + {"term": "buffer overflow", "w": 5}, + {"term": "double free", "w": 5}, + {"term": "dangling pointer", "w": 5} + ], + "intentPatterns": [ + "(memory|pointer|buffer).*?(bug|corruption|overflow|leak|error).*?(c\\+\\+|cpp)", + "(c\\+\\+|cpp).*?(memory|concurrency|threading).*?(bug|issue|problem)", + "(asan|tsan|ubsan|valgrind|sanitizer).*?(report|finding|error)" + ], + "intentWeight": 4, + "message": "AGENT AVAILABLE: bug-hunters:cpp-hunter -- Launch via Task tool (subagent_type='bug-hunters:cpp-hunter') for C++ memory corruption, UB, and concurrency bug hunting." + }, + + "bug-hunters:python-hunter": { + "threshold": 4, + "keywords": [ + {"term": "none propagation", "w": 5}, + {"term": "mutable default", "w": 5}, + {"term": "async pitfall", "w": 5}, + {"term": "type violation", "w": 4}, + {"term": "import cycle", "w": 5}, + {"term": "gil issue", "w": 5} + ], + "intentPatterns": [ + "python.*?(bug|issue|problem).*?(async|none|type|import|mutable)", + "(none|null).*?(propagat|check|error|bug).*?python", + "(async|await).*?(pitfall|bug|deadlock|race).*?python" + ], + "intentWeight": 4, + "message": "AGENT AVAILABLE: bug-hunters:python-hunter -- Launch via Task tool (subagent_type='bug-hunters:python-hunter') for Python bug hunting (async pitfalls, None propagation, mutable defaults, type violations)." + }, + + "alpha-squad:fundamentalist": { + "threshold": 4, + "keywords": [ + {"term": "value investing", "w": 4}, + {"term": "fundamental analysis", "w": 5}, + {"term": "earnings quality", "w": 5}, + {"term": "financial statements", "w": 3}, + {"term": "10-k", "w": 4}, + {"term": "10-q", "w": 4}, + {"term": "accruals", "w": 5}, + {"term": "cash flow analysis", "w": 3}, + {"term": "roic", "w": 4}, + {"term": "intrinsic value", "w": 5}, + {"term": "capital efficiency", "w": 4} + ], + "intentPatterns": [ + "(analyz|decompos|parse).*?(financial|earning|accounting|statement|10-k|10-q)", + "(value|fundamental|intrinsic).*?(thesis|analysis|mispricing|opportunity)", + "(earnings|accounting).*?(quality|game|manipulation|restatement)" + ], + "intentWeight": 4, + "message": "AGENT AVAILABLE: alpha-squad:fundamentalist -- Launch via Task tool for accounting and intrinsic value analysis (financial statements, earnings quality, capital efficiency, mispricing)." + }, + + "alpha-squad:vulture": { + "threshold": 4, + "keywords": [ + {"term": "forced seller", "w": 5}, + {"term": "index reconstitution", "w": 5}, + {"term": "13f", "w": 4}, + {"term": "short interest", "w": 4}, + {"term": "borrow rate", "w": 4}, + {"term": "etf flows", "w": 4}, + {"term": "liquidation", "w": 3}, + {"term": "crowding", "w": 4}, + {"term": "calendar flows", "w": 5} + ], + "intentPatterns": [ + "(track|detect|find|analyze).*?(forced|constrained).*?(seller|buyer|liquidation|flow)", + "(index|etf).*?(reconstitut|rebalance|flow|add|delete)", + "(13f|filing|ownership).*?(crowd|concentrat|overlap)" + ], + "intentWeight": 4, + "message": "AGENT AVAILABLE: alpha-squad:vulture -- Launch via Task tool for flows and constraints analysis (forced sellers, index reconstitution, 13F crowding, liquidation signatures)." + }, + + "alpha-squad:network-architect": { + "threshold": 4, + "keywords": [ + {"term": "customer-supplier", "w": 5}, + {"term": "lead-lag", "w": 5}, + {"term": "contagion", "w": 4}, + {"term": "supply chain", "w": 3}, + {"term": "spillover", "w": 4}, + {"term": "cross-asset", "w": 3}, + {"term": "network analysis", "w": 3}, + {"term": "propagation", "w": 2} + ], + "intentPatterns": [ + "(customer|supplier|upstream|downstream).*?(network|chain|relationship|link|impact)", + "(lead|lag|spill|propag|contag).*?(across|between|from|to).*?(sector|stock|asset|market)", + "(network|graph).*?(shock|propag|transmit|spread)" + ], + "intentWeight": 4, + "message": "AGENT AVAILABLE: alpha-squad:network-architect -- Launch via Task tool for relationship and propagation analysis (customer-supplier networks, lead-lag, contagion paths, cross-asset spillover)." + }, + + "alpha-squad:book-physicist": { + "threshold": 4, + "keywords": [ + {"term": "order flow", "w": 3}, + {"term": "kyle model", "w": 5}, + {"term": "glosten-milgrom", "w": 5}, + {"term": "hawkes process", "w": 5}, + {"term": "information asymmetry", "w": 4}, + {"term": "adverse selection", "w": 4}, + {"term": "price impact", "w": 3}, + {"term": "shannon entropy", "w": 5}, + {"term": "order flow toxicity", "w": 5}, + {"term": "vpin", "w": 5} + ], + "intentPatterns": [ + "(order book|order flow).*?(model|entropy|information|toxicity|impact)", + "(kyle|glosten|milgrom|hawkes|vpin).*?(model|estimat|calibrat)", + "(information|adverse).*?(asymmetry|selection).*?(measure|detect|quantify)" + ], + "intentWeight": 4, + "message": "AGENT AVAILABLE: alpha-squad:book-physicist -- Launch via Task tool for microstructure and entropy analysis (order book physics, Kyle/Glosten-Milgrom models, order flow informativity, entropy regimes)." + }, + + "alpha-squad:causal-detective": { + "threshold": 4, + "keywords": [ + {"term": "causal inference", "w": 5}, + {"term": "double ml", "w": 5}, + {"term": "frisch-waugh", "w": 5}, + {"term": "orthogonalization", "w": 5}, + {"term": "instrumental variable", "w": 5}, + {"term": "placebo test", "w": 5}, + {"term": "dag", "w": 2}, + {"term": "confounding", "w": 3}, + {"term": "causality", "w": 3} + ], + "intentPatterns": [ + "(causal|orthogonal|confound).*?(infer|test|identif|estimat|analys)", + "(double ml|frisch.?waugh|instrumental variable|placebo)", + "(is|does).*?(caus|confound|spurious).*?(or|versus|vs)" + ], + "intentWeight": 4, + "message": "AGENT AVAILABLE: alpha-squad:causal-detective -- Launch via Task tool for causal inference (Frisch-Waugh-Lovell orthogonalization, Double ML, DAGs, placebo tests, confounding analysis)." + }, + + "mft-research-experts:mft-strategist": { + "threshold": 4, + "keywords": [ + {"term": "orchestrate research", "w": 5}, + {"term": "hypothesis generation", "w": 4}, + {"term": "research workflow", "w": 4}, + {"term": "ship or kill", "w": 5}, + {"term": "alpha research", "w": 3}, + {"term": "research pipeline", "w": 4} + ], + "intentPatterns": [ + "(orchestrat|coordinat|manag).*?(research|hypothesis|validation|squad)", + "(ship|kill|iterate).*?(hypothesis|signal|strategy|alpha)", + "(end.?to.?end|full).*?(research|validation|pipeline).*?(workflow|process)" + ], + "intentWeight": 4, + "message": "AGENT AVAILABLE: mft-research-experts:mft-strategist -- Launch via Task tool for research orchestration (hypothesis generation/destruction, squad coordination, SHIP/KILL/ITERATE decisions)." + }, + + "mft-research-experts:data-sentinel": { "threshold": 3, "keywords": [ - {"term": "best practice", "w": 3}, - {"term": "programming wisdom", "w": 4}, - {"term": "code quality", "w": 2}, - {"term": "professional development", "w": 3}, - {"term": "97 things", "w": 5} + {"term": "data validation", "w": 4}, + {"term": "data quality", "w": 4}, + {"term": "survivorship bias", "w": 5}, + {"term": "look-ahead bias", "w": 5}, + {"term": "lookahead bias", "w": 5}, + {"term": "timestamp validation", "w": 5}, + {"term": "corporate actions", "w": 4}, + {"term": "data integrity", "w": 3}, + {"term": "point-in-time", "w": 4} ], "intentPatterns": [ - "what.?(should|would).*?(good|experienced|senior).*?(developer|programmer|engineer)", - "(principle|wisdom|lesson).*?(programming|software|coding)" + "(validat|check|verify|audit).*?(data|timestamp|price|identifier|dataset)", + "(survivorship|look.?ahead|point.?in.?time).*?(bias|issue|problem|check)", + "(corporate action|split|dividend).*?(adjust|handle|check|miss)" ], - "intentWeight": 3, - "message": "SKILL AVAILABLE: 97-dev -- Invoke via Skill tool for programming wisdom from '97 Things Every Programmer Should Know'." + "intentWeight": 4, + "message": "AGENT AVAILABLE: mft-research-experts:data-sentinel -- INVOKE FIRST on any dataset. Paranoid data gatekeeper for timestamp validation, survivorship bias, look-ahead bias, corporate actions." + }, + + "mft-research-experts:factor-geometer": { + "threshold": 4, + "keywords": [ + {"term": "factor model", "w": 5}, + {"term": "risk model", "w": 4}, + {"term": "covariance", "w": 3}, + {"term": "alpha-orthogonal", "w": 5}, + {"term": "factor exposure", "w": 5}, + {"term": "ledoit-wolf", "w": 5}, + {"term": "gram-schmidt", "w": 5}, + {"term": "eigenvalue", "w": 3}, + {"term": "factor loading", "w": 5}, + {"term": "risk decomposition", "w": 4} + ], + "intentPatterns": [ + "(factor|risk).*?(model|loading|exposure|decompos|orthogonal)", + "(covariance|correlation).*?(estimat|shrink|ledoit|eigen|clean)", + "(alpha|signal).*?(orthogonal|residual|spanned|factor.?neutral)" + ], + "intentWeight": 4, + "message": "AGENT AVAILABLE: mft-research-experts:factor-geometer -- Launch via Task tool for factor/risk geometry (factor loadings, covariance shrinkage, alpha-orthogonal decomposition)." + }, + + "mft-research-experts:skeptic": { + "threshold": 4, + "keywords": [ + {"term": "backtest validation", "w": 5}, + {"term": "deflated sharpe", "w": 5}, + {"term": "rademacher", "w": 5}, + {"term": "walk-forward", "w": 5}, + {"term": "multiple testing", "w": 5}, + {"term": "overfitting", "w": 3}, + {"term": "subsample stability", "w": 5}, + {"term": "out of sample", "w": 3}, + {"term": "oos", "w": 2} + ], + "intentPatterns": [ + "(validat|verify|test|check).*?(backtest|strategy|signal|hypothesis)", + "(overfit|spurious|lucky|multiple testing|data.?min).*?(check|test|correct)", + "(deflated|adjusted).*?(sharpe|performance|return)" + ], + "intentWeight": 4, + "message": "AGENT AVAILABLE: mft-research-experts:skeptic -- Launch via Task tool for hypothesis execution and validation (Rademacher haircuts, walk-forward OOS, deflated Sharpe, subsample stability)." + }, + + "mft-research-experts:forensic-auditor": { + "threshold": 4, + "keywords": [ + {"term": "post-mortem", "w": 5}, + {"term": "postmortem", "w": 5}, + {"term": "failure analysis", "w": 4}, + {"term": "assumption audit", "w": 5}, + {"term": "regime change", "w": 4}, + {"term": "performance degradation", "w": 4}, + {"term": "why did it break", "w": 5}, + {"term": "drawdown analysis", "w": 4} + ], + "intentPatterns": [ + "(why|what|when).*?(break|fail|degrade|stop working|underperform|drawdown)", + "(post.?mortem|forensic|audit|investigat).*?(strategy|signal|performance|failure)", + "(regime|structural).*?(change|shift|break).*?(detect|investigat|explain)" + ], + "intentWeight": 4, + "message": "AGENT AVAILABLE: mft-research-experts:forensic-auditor -- Launch via Task tool for post-mortem investigation (assumption failures, regime changes, performance degradation, drawdown forensics)." } } }