Problem
When a developer works on the ido4shape plugin itself (editing skills, agents, scripts), every Claude Code session here fires the plugin's own hooks:
SessionStart creates a .ido4shape/ workspace inside the plugin repo
UserPromptSubmit injects canvas context on every prompt
Stop nags about canvas updates and session summaries
PreCompact prompts to save spec insights
None of this is relevant when the user is developing the plugin rather than using it. It creates noise, pollutes the repo with a workspace directory, and confuses fresh contributors. The quick workaround is disabling the plugin per-repo via .claude/settings.local.json, but that's a manual step every forker/contributor has to discover.
Proposed fix
Each hook script should detect "I'm running inside my own plugin source repo" and exit early.
Detection logic: walk from CWD up to the git root looking for .claude-plugin/plugin.json. If found, parse it and check name == "ido4shape". If yes, exit 0 silently.
Scope — scripts to guard:
scripts/session-start.sh (SessionStart)
scripts/canvas-context.sh (UserPromptSubmit)
scripts/phase-gate.sh (PreToolUse on Write)
Extract the detection into a shared helper (e.g., scripts/lib/is-plugin-source.sh) so all three stay consistent.
Escape hatch: honor an env var like IDO4SHAPE_FORCE_ACTIVE=1 so plugin maintainers can still exercise the hooks against the plugin itself when testing.
Testing
Unit test for the detection helper — given a fake directory tree, does it correctly identify:
- CWD is the plugin root → true
- CWD is a subdirectory of the plugin root → true
- CWD is an unrelated repo containing a coincidentally-named
plugin.json (different `name`) → false
- No
plugin.json anywhere in the chain → false
- Escape hatch env var set → hook runs anyway
Integration test — extend tests/validate-plugin.sh:
- Simulate a session-start with CWD inside the plugin source → assert no
.ido4shape/ created, no stdout noise
- Simulate with the escape hatch env var set → assert hook runs normally
Manual smoke test — fresh clone of ido4shape, open Claude Code in it, confirm:
- No workspace created
- No canvas prompts injected on every turn
- No Stop hook nagging
Out of scope
- Generalizing this to "any plugin running inside its own source" (other plugins can copy the pattern if useful)
- Documenting the escape hatch in user-facing docs (internal contributor knowledge for now)
Context
Discovered 2026-04-05 when a maintainer session in the ido4shape repo triggered workspace creation and persistent Stop-hook nagging during purely operational work (plugin disable question). Quick fix applied via personal .claude/settings.local.json.
Problem
When a developer works on the ido4shape plugin itself (editing skills, agents, scripts), every Claude Code session here fires the plugin's own hooks:
SessionStartcreates a.ido4shape/workspace inside the plugin repoUserPromptSubmitinjects canvas context on every promptStopnags about canvas updates and session summariesPreCompactprompts to save spec insightsNone of this is relevant when the user is developing the plugin rather than using it. It creates noise, pollutes the repo with a workspace directory, and confuses fresh contributors. The quick workaround is disabling the plugin per-repo via
.claude/settings.local.json, but that's a manual step every forker/contributor has to discover.Proposed fix
Each hook script should detect "I'm running inside my own plugin source repo" and exit early.
Detection logic: walk from CWD up to the git root looking for
.claude-plugin/plugin.json. If found, parse it and checkname == "ido4shape". If yes, exit 0 silently.Scope — scripts to guard:
scripts/session-start.sh(SessionStart)scripts/canvas-context.sh(UserPromptSubmit)scripts/phase-gate.sh(PreToolUse on Write)Extract the detection into a shared helper (e.g.,
scripts/lib/is-plugin-source.sh) so all three stay consistent.Escape hatch: honor an env var like
IDO4SHAPE_FORCE_ACTIVE=1so plugin maintainers can still exercise the hooks against the plugin itself when testing.Testing
Unit test for the detection helper — given a fake directory tree, does it correctly identify:
plugin.json(different `name`) → falseplugin.jsonanywhere in the chain → falseIntegration test — extend
tests/validate-plugin.sh:.ido4shape/created, no stdout noiseManual smoke test — fresh clone of ido4shape, open Claude Code in it, confirm:
Out of scope
Context
Discovered 2026-04-05 when a maintainer session in the ido4shape repo triggered workspace creation and persistent Stop-hook nagging during purely operational work (plugin disable question). Quick fix applied via personal
.claude/settings.local.json.