Errata
Please use the full script name in "allowed-tools" like below:
Save the :* syntax for "arguments following a tool call", never treat it like a glob pattern.
Permissions are notoriously spotty and I've been having inconsistent behavior with the configuration in this lesson. We'll introduce stronger control in a "hooks" section in upcoming lessons.
Escape Claude Skill Limitations with Scripts
When building Claude Code skills, you may encounter limitations with the allowed-tools feature, particularly when a CLI tool's syntax includes special characters like shell redirects (>). This can cause parsing issues and prevent your agent from getting the necessary permissions to run the command.
This lesson demonstrates a powerful workaround: abstracting complex or problematic CLI commands into dedicated scripts. By doing this, you can create more robust, maintainable, and even cross-platform skills.
The Problem: allowed-tools and Shell Redirects
Directly allowing a tool like tar or gzip that requires output redirection can fail because the parser for allowed-tools may not correctly handle the special characters. This leads to the agent getting stuck and unable to proceed.
The Solution: Abstracting Logic into a Script
Instead of fighting with the syntax, we can move the complex logic into a script (e.g., a TypeScript script run with Bun). This approach offers several advantages:
- Bypasses Parsing Issues: The skill only needs permission to run the script (
bun run scripts/compress.ts), which is a much simpler command forallowed-toolsto handle. - Enhanced Control: Inside the script, you have full programmatic control over execution, error handling, and logging, providing richer feedback to the agent and user.
- Cross-Platform Compatibility: By using Node.js/Bun packages (like
tar-fs), you can replace system-specific commands (liketar) with JavaScript implementations that work consistently across Windows, macOS, and Linux. - Composability: Your skill can remain focused on its primary goal (e.g., "compress files") while delegating the low-level implementation details to one or more scripts.
Workflow Demonstrated
- Identify the Limitation: We start by showing how a
tarcommand with a redirect fails theallowed-toolspermission step in our compress skill. - Generate a Script: We prompt Claude to convert the problematic command into a Bun + TypeScript script that accepts arguments instead of using redirects.
- Refactor the Skill: We update the
SKILL.mdfile to remove the directtarcommand and replace it with a call to our new script, updating theallowed-toolsaccordingly (e.g.,Bash(bun run scripts:*)). - Iteratively Improve: We refine the script by removing redundant logic (like timestamp generation, which is already handled by the separate timestamp skill we built in earlier lessons) and fixing TypeScript errors.
- Achieve Cross-Platform Support: As a final step, we convert the script to use a cross-platform package (
tar-fs) instead of relying on the system'starcommand, making the skill universally usable.
This lesson provides a practical pattern for building sophisticated and reliable Claude Code skills, moving beyond simple CLI commands to create powerful, script-driven automations that work seamlessly with the skill stacking patterns learned in previous lessons.
Prompts
Terminal Commands
Code Snippets
The initial compress skill's SKILL.md file uses a tar command that causes issues with allowed-tools:
After creating the script, we update the allowed-tools to reference our script instead:
