diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 6a96390..0319aab 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -1,6 +1,6 @@ { "name": "wisdom", - "version": "3.2.0", + "version": "3.2.1", "owner": { "name": "cmj", "url": "https://github.com/cmj0121" @@ -9,7 +9,7 @@ { "name": "wisdom", "description": "Single-purpose skills to plan, build, review and ship software, led by smith.", - "version": "3.2.0", + "version": "3.2.1", "source": "./plugins/wisdom" } ] diff --git a/plugins/wisdom/.claude-plugin/plugin.json b/plugins/wisdom/.claude-plugin/plugin.json index 536396b..b2b3860 100644 --- a/plugins/wisdom/.claude-plugin/plugin.json +++ b/plugins/wisdom/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "wisdom", "description": "Single-purpose skills to plan, build, review and ship software, led by smith.", - "version": "3.2.0", + "version": "3.2.1", "license": "MIT", "author": { "name": "cmj", diff --git a/plugins/wisdom/hooks/shortcut-prompt.py b/plugins/wisdom/hooks/shortcut-prompt.py index ed54159..10d1a8d 100644 --- a/plugins/wisdom/hooks/shortcut-prompt.py +++ b/plugins/wisdom/hooks/shortcut-prompt.py @@ -5,7 +5,7 @@ (`metadata.shortcut` in their frontmatter) and, on a hit, tells the model which skill to run. Dispatch therefore no longer depends on the model choosing to run the `shortcut` skill, and no skill file is read at the model's expense. -Silent no-op when no word matches. +Silent no-op when no word matches, or when the prompt is not the user's own text. """ import glob import json @@ -13,6 +13,18 @@ import re import sys +# How Claude Code opens a prompt the user did not type: a subagent's report, a +# background-task event, a message from another session. A magic word in one +# is something a model wrote, so it must not dispatch a skill. +NOT_USER = ( + "Another Claude session sent a message:", + "`; user and project ones bare. def sources(cwd, plugin_root): @@ -56,6 +68,8 @@ def main() -> int: # tell the model to run what it is running. if not prompt.strip() or prompt.lstrip().startswith("/"): return 0 + if prompt.lstrip().startswith(NOT_USER): + return 0 cwd = data.get("cwd") or os.environ.get("CLAUDE_PROJECT_DIR") or os.getcwd() plugin_root = os.environ.get("CLAUDE_PLUGIN_ROOT") or os.path.dirname(os.path.dirname(__file__))