Sync with Python SDK v0.2.134: validate skill names in ClaudeAgentOptions#skills - #53
Merged
Merged
Conversation
… #1145)
Skill names from `skills: [...]` were formatted into the --allowedTools
value unchecked. The CLI splits that value into permission rules on
commas and spaces outside parentheses, and its tokenizer honors no
escape sequences, so a name carrying one of those delimiters cannot be
passed through reliably. CommandBuilder now validates each name and
fails closed.
Rejected: parentheses, commas, control characters (C0, DEL, C1),
U+FEFF, empty names; a literal '*' and wildcard suffixes (':*', ' *');
and shapes that parse but can never match the listed skill --
surrounding whitespace, a leading '/', consecutive backslashes, a
trailing unpaired backslash, and byte sequences that cannot form valid
UTF-8 (Ruby's analogue of Python's surrogate check).
Ruby adaptations: ValueError -> ArgumentError (TypeError kept for
non-String entries); Unicode-aware edge-whitespace checks via
[[:space:]] since String#strip is ASCII-only; valid non-UTF-8 names are
converted so the argv join cannot raise Encoding::CompatibilityError.
Breaking: skills: ['*'] / ['plugin:*'] / [' name'] / ['/name'] now
raise; the latter two previously built a rule that could never match,
so the skill was silently unavailable.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TS6ALBqEGJc3rGqNjnXGqD
ya-luotao
added a commit
that referenced
this pull request
Aug 8, 2026
Python SDK v0.2.134 parity: skill names in ClaudeAgentOptions#skills are now validated and fail closed (port of Python SDK #1145, PR #53). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TS6ALBqEGJc3rGqNjnXGqD
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Brings the Ruby SDK to parity with Python SDK v0.2.134.
Ported: anthropics/claude-agent-sdk-python#1145 — validate skill names in
ClaudeAgentOptions.skills(v0.2.129)Skill names from
skills: [...]were formatted into the--allowedToolsvalue unchecked. The CLI splits that value into permission rules on commas and spaces outside parentheses, and its tokenizer honors no escape sequences, so a name carrying one of those delimiters cannot be passed through reliably.CommandBuilder#skills_defaultsnow validates each name and fails closed.Rejected: parentheses, commas, control characters (C0, DEL, C1), U+FEFF, empty names; a literal
*and wildcard suffixes (:*,*); and shapes that parse but can never match the listed skill — surrounding whitespace, a leading/, consecutive backslashes, a trailing unpaired backslash, and byte sequences that cannot form valid UTF-8.Unaffected: ordinary names, including plugin-qualified names, interior spaces, single backslashes, and non-ASCII.
Breaking:
skills: ['*']andskills: ['plugin:*']now raise — useskills: 'all', or aSkill(...)rule inallowed_toolsfor prefix matching.skills: [' name']andskills: ['/name']now raise as well; both previously built a rule that could never match, so the skill was silently unavailable.Ruby adaptations
ValueError→ArgumentError;TypeErrorkept for non-String entries. The existingArgumentErrorfor non-Array/non-'all'shapes is unchanged (Python's tuple/set/generator/bare-string cases collapse into that one check in Ruby).join(",")cannot raiseEncoding::CompatibilityError.[[:space:]](Unicode-aware) since Ruby'sString#stripis ASCII-only —" pdf"rejects like Python.Not applicable from v0.2.129–v0.2.134
All remaining upstream commits are bundled-CLI version bumps (2.1.221 → 2.1.226) and changelog updates; the Ruby gem does not bundle the CLI.
Test plan
spec/unit/command_builder_spec.rb(16 new examples), plus Ruby-specific cases: NBSP edge whitespace, invalid byte sequences, UTF-16 name conversion.bundle exec rspec— 1226 examples, 0 failures.bundle exec rubocop— clean.🤖 Generated with Claude Code
https://claude.ai/code/session_01TS6ALBqEGJc3rGqNjnXGqD