From 0fa332bbc45f9e5de46604e0ef2c4a51fba87609 Mon Sep 17 00:00:00 2001 From: Francesco Bertolaccini Date: Thu, 19 Feb 2026 18:00:21 +0100 Subject: [PATCH 1/2] fix: escape raw substitution patterns in workflow-skill-design The skill loader preprocesses $ARGUMENTS, $N, ${CLAUDE_SESSION_ID}, and !`command` patterns before Claude sees the file. The SKILL.md and tool-assignment-guide.md documented these using the raw syntax, causing shell preprocessing to attempt execution of "command" and dollar variables to silently resolve to empty strings. Replace raw patterns with textual descriptions and add a caution note warning skill authors about this pitfall. Co-Authored-By: Claude Opus 4.6 --- .../skills/designing-workflow-skills/SKILL.md | 2 +- .../references/tool-assignment-guide.md | 24 ++++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/plugins/workflow-skill-design/skills/designing-workflow-skills/SKILL.md b/plugins/workflow-skill-design/skills/designing-workflow-skills/SKILL.md index 39dd572..620a056 100644 --- a/plugins/workflow-skill-design/skills/designing-workflow-skills/SKILL.md +++ b/plugins/workflow-skill-design/skills/designing-workflow-skills/SKILL.md @@ -164,7 +164,7 @@ allowed-tools: [Checklist for output validation] ``` -Skills support string substitutions in their content: `$ARGUMENTS` (all args passed after `/skill-name`), `$ARGUMENTS[N]` or `$N` (positional args), `${CLAUDE_SESSION_ID}`, and `` !`command` `` (shell preprocessing — output replaces the placeholder before Claude sees it). See [tool-assignment-guide.md](references/tool-assignment-guide.md) for details. +Skills support string substitutions in their content. The skill loader processes these before Claude sees the file, so do not use the raw syntax in documentation text — it will be interpreted literally. Substitution types: dollar-prefixed variables for arguments and session ID, and exclamation-backtick syntax for shell preprocessing (command output replaces the placeholder). See [tool-assignment-guide.md](references/tool-assignment-guide.md) for the full variable reference and usage guidance. ## Anti-Pattern Quick Reference diff --git a/plugins/workflow-skill-design/skills/designing-workflow-skills/references/tool-assignment-guide.md b/plugins/workflow-skill-design/skills/designing-workflow-skills/references/tool-assignment-guide.md index cb40a8f..5f286c9 100644 --- a/plugins/workflow-skill-design/skills/designing-workflow-skills/references/tool-assignment-guide.md +++ b/plugins/workflow-skill-design/skills/designing-workflow-skills/references/tool-assignment-guide.md @@ -46,20 +46,22 @@ How to choose the right tools for skills, agents, and subagents. ## String Substitutions -Skill content supports dynamic values at invocation time: +Skill content supports dynamic values at invocation time. **CAUTION:** The skill loader processes these substitutions before Claude sees the file. Do not use the raw syntax in documentation or example text — it will be interpreted literally, causing silent corruption (variables resolve to empty strings) or errors (shell preprocessing attempts execution). -| Variable | Description | -|----------|-------------| -| `$ARGUMENTS` | All arguments passed after `/skill-name`. Appended as `ARGUMENTS: ` if placeholder absent. | -| `$ARGUMENTS[N]` | Specific argument by 0-based index. | -| `$N` | Shorthand for `$ARGUMENTS[N]` (e.g., `$0`, `$1`). | -| `${CLAUDE_SESSION_ID}` | Current session ID. | -| `` !`command` `` | Shell preprocessing. Command runs before Claude sees the content; output replaces the placeholder. | +There are three substitution types: + +1. **Argument variables** — Dollar-prefixed: DOLLAR-ARGUMENTS for all args, DOLLAR-ARGUMENTS[N] or DOLLAR-N for positional args (0-based index). If no placeholder exists in the content, arguments are appended as an `ARGUMENTS:` line. + +2. **Session variable** — DOLLAR-{CLAUDE_SESSION_ID} resolves to the current session ID. + +3. **Shell preprocessing** — Exclamation mark followed by a backtick-wrapped command (e.g., exclamation-backtick git status backtick). The command runs before Claude sees the content; its output replaces the placeholder. **Design implications:** -- Use `$ARGUMENTS` when the skill accepts free-form input (file paths, issue numbers) -- Use positional args (`$0`, `$1`) when the skill expects structured input (e.g., `/migrate-component SearchBar React Vue`) -- Use `` !`command` `` to inject live context (git status, PR diff) — pairs well with `context: fork` +- Use argument variables when the skill accepts free-form input (file paths, issue numbers) +- Use positional args when the skill expects structured input (e.g., `/migrate-component SearchBar React Vue`) +- Use shell preprocessing to inject live context (git status, PR diff) — pairs well with `context: fork` + +**When documenting these patterns in a skill:** Describe the syntax textually (as this file does) rather than using the raw patterns. Otherwise the skill loader will process your documentation text as live substitutions. --- From 16e347d28b51a00dc97680a534350bf00be53c05 Mon Sep 17 00:00:00 2001 From: Francesco Bertolaccini Date: Thu, 19 Feb 2026 18:11:55 +0100 Subject: [PATCH 2/2] fix: version bump and clarify substitution docs - Bump version to 1.0.1 in plugin.json and marketplace.json - Replace invented pseudo-syntax (DOLLAR-ARGUMENTS) with natural descriptions (a dollar sign followed by ARGUMENTS) - Clarify shell preprocessing example with proper sentence structure - Warn that code fences do not prevent substitution processing Co-Authored-By: Claude Opus 4.6 --- .claude-plugin/marketplace.json | 2 +- .../workflow-skill-design/.claude-plugin/plugin.json | 2 +- .../skills/designing-workflow-skills/SKILL.md | 2 +- .../references/tool-assignment-guide.md | 10 +++++----- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index dd620f8..492d417 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -276,7 +276,7 @@ }, { "name": "workflow-skill-design", - "version": "1.0.0", + "version": "1.0.1", "description": "Teaches design patterns for workflow-based Claude Code skills and provides a review agent for auditing existing skills", "author": { "name": "Benjamin Samuels", diff --git a/plugins/workflow-skill-design/.claude-plugin/plugin.json b/plugins/workflow-skill-design/.claude-plugin/plugin.json index d104321..c3f2ef6 100644 --- a/plugins/workflow-skill-design/.claude-plugin/plugin.json +++ b/plugins/workflow-skill-design/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "workflow-skill-design", - "version": "1.0.0", + "version": "1.0.1", "description": "Teaches design patterns for workflow-based Claude Code skills and provides a review agent for auditing existing skills", "author": { "name": "Benjamin Samuels", diff --git a/plugins/workflow-skill-design/skills/designing-workflow-skills/SKILL.md b/plugins/workflow-skill-design/skills/designing-workflow-skills/SKILL.md index 620a056..aeb145d 100644 --- a/plugins/workflow-skill-design/skills/designing-workflow-skills/SKILL.md +++ b/plugins/workflow-skill-design/skills/designing-workflow-skills/SKILL.md @@ -164,7 +164,7 @@ allowed-tools: [Checklist for output validation] ``` -Skills support string substitutions in their content. The skill loader processes these before Claude sees the file, so do not use the raw syntax in documentation text — it will be interpreted literally. Substitution types: dollar-prefixed variables for arguments and session ID, and exclamation-backtick syntax for shell preprocessing (command output replaces the placeholder). See [tool-assignment-guide.md](references/tool-assignment-guide.md) for the full variable reference and usage guidance. +Skills support three types of string substitutions: dollar-prefixed variables for arguments and session ID, and exclamation-backtick syntax for shell preprocessing. The skill loader processes these before Claude sees the file — even inside code fences — so never use the raw syntax in documentation text. See [tool-assignment-guide.md](references/tool-assignment-guide.md) for the full variable reference and usage guidance. ## Anti-Pattern Quick Reference diff --git a/plugins/workflow-skill-design/skills/designing-workflow-skills/references/tool-assignment-guide.md b/plugins/workflow-skill-design/skills/designing-workflow-skills/references/tool-assignment-guide.md index 5f286c9..f11b3a8 100644 --- a/plugins/workflow-skill-design/skills/designing-workflow-skills/references/tool-assignment-guide.md +++ b/plugins/workflow-skill-design/skills/designing-workflow-skills/references/tool-assignment-guide.md @@ -46,22 +46,22 @@ How to choose the right tools for skills, agents, and subagents. ## String Substitutions -Skill content supports dynamic values at invocation time. **CAUTION:** The skill loader processes these substitutions before Claude sees the file. Do not use the raw syntax in documentation or example text — it will be interpreted literally, causing silent corruption (variables resolve to empty strings) or errors (shell preprocessing attempts execution). +Skill content supports dynamic values at invocation time. **CAUTION:** The skill loader processes these substitutions before Claude sees the file — even inside code fences and inline code blocks. Do not use the raw syntax in documentation or example text. Variables silently resolve to empty strings, and shell preprocessing attempts execution, causing load errors. There are three substitution types: -1. **Argument variables** — Dollar-prefixed: DOLLAR-ARGUMENTS for all args, DOLLAR-ARGUMENTS[N] or DOLLAR-N for positional args (0-based index). If no placeholder exists in the content, arguments are appended as an `ARGUMENTS:` line. +1. **Argument variables** — A dollar sign followed by ARGUMENTS for all args, or a dollar sign followed by ARGUMENTS[N] or just a dollar sign followed by N for positional args (0-based index, where N is shorthand for ARGUMENTS[N]). If no placeholder exists in the content, arguments are appended as an `ARGUMENTS:` line. -2. **Session variable** — DOLLAR-{CLAUDE_SESSION_ID} resolves to the current session ID. +2. **Session variable** — A dollar sign followed by {CLAUDE_SESSION_ID} (with curly braces) resolves to the current session ID. -3. **Shell preprocessing** — Exclamation mark followed by a backtick-wrapped command (e.g., exclamation-backtick git status backtick). The command runs before Claude sees the content; its output replaces the placeholder. +3. **Shell preprocessing** — An exclamation mark immediately followed by a command enclosed in backticks. For example, to inject the output of `git status`, place an exclamation mark before the backtick-enclosed command. The command runs before Claude sees the content; its output replaces the placeholder. **Design implications:** - Use argument variables when the skill accepts free-form input (file paths, issue numbers) - Use positional args when the skill expects structured input (e.g., `/migrate-component SearchBar React Vue`) - Use shell preprocessing to inject live context (git status, PR diff) — pairs well with `context: fork` -**When documenting these patterns in a skill:** Describe the syntax textually (as this file does) rather than using the raw patterns. Otherwise the skill loader will process your documentation text as live substitutions. +**When documenting these patterns in a skill:** Describe the syntax textually (as this file does) rather than using the raw patterns. Code fences and inline code do NOT prevent substitution — the loader processes the raw file content before any Markdown parsing. ---