lint: stop --fix from destroying inline code and allowed-tools lists - #128
Merged
Conversation
…ists
`cue lint-skill --fix` corrupted content. Measured over the 453-skill
library, one run destroyed 723 inline code spans across 178 files and folded
block-sequence allowed-tools into a single garbage string.
R009 (em dashes). stripCodeAndFrontmatter is length-preserving: it blanks
inline code to spaces so offsets stay aligned. The fixer used that mask to
FIND em dashes, correctly, and then also to walk backwards over surrounding
whitespace. A blanked `` `code span` `` reads as whitespace, so the walk
crossed it and the slice dropped it:
- `get_latest_news` — Fetch the most recent news articles
-, Fetch the most recent news articles
The tool name is simply gone. The search still uses the mask; the whitespace
walk now runs on the original content.
R005 (allowed-tools). Two defects. It read the field with fmField, whose
`\s*` crosses a newline, so a block sequence returned the first bullet line
and `-` was parsed as a tool name, yielding `Bash(-:*)`. Its fix then
rewrote only the key line, orphaning the remaining ` - item` lines under a
scalar, which YAML folds into that scalar. research/trendradar went from a
17-entry list to one 600-character string. It stayed VALID YAML, which is why
a syntax-level check waved it through -- only a semantic comparison catches
it.
R005 now reads both YAML shapes, replaces the whole construct, and leaves
`mcp__*` ids and top-level tools bare instead of wrapping them. Bare `Bash`
is a tool name, not a CLI name; wrapping produced `Bash(Bash:*)`.
12 regression tests, built from the shapes that actually broke. The existing
suite covered em dashes in fenced blocks but never inline spans, which is how
this shipped.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
NagyVikt
added a commit
that referenced
this pull request
Aug 7, 2026
…#130) Two defects the review of #128 turned up in that PR, after it had merged. Space-separated bare names regressed. The pre-#128 code split on /[,\s]+/; readAllowedTools split on commas only, so `allowed-tools: nmap curl` produced the single bogus `Bash(nmap curl:*)` instead of two entries. splitToolNames restores the old behaviour but leaves a part containing `(` whole, so `Bash(git diff:*)` stays one tool rather than being torn in half -- something the original only avoided by early-returning on any wrapped value, which also meant it fixed nothing in a mixed list. fixedNames was computed and never read: the fix closure recomputes the same map from a fresh parse. `bun run lint` flags it, and #128 passed CI only because unused variables are a warning. Removed, and the wrap predicate that had been written out three times is now isWellFormedTool + wrapTool. 4 more regression tests: space-separated names, a wrapper containing a space, and flow-sequence brackets. Neither defect reached opencue/skills#21: no skill carries a bare multi-word allowed-tools value, and on its own base the repaired fixer reproduces that PR byte-for-byte. Co-authored-by: NagyVikt <nagy.viktordp@gmail.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
cue lint-skill --fixcorrupts the files it edits. Measured over the 453-skill library, one run destroyed 723 inline code spans across 178 files and folded block-sequenceallowed-toolsinto a single garbage string.R009 — the em-dash fixer eats adjacent code spans
stripCodeAndFrontmatteris length-preserving: it blanks inline code to spaces so offsets stay aligned with the original. The fixer used that mask to find em dashes (correct) and to walk backwards over surrounding whitespace (not correct). A blanked`code span`reads as whitespace, so the walk crossed it and the slice dropped it:The tool name is simply gone. Worst single file lost 44 spans.
Fix: the search still uses the mask; the whitespace walk now runs on the original content.
R005 — allowed-tools block lists collapse into one string
Two defects compounding:
fmField, whose\s*crosses a newline. For a block sequence that returned the first bullet line, so-was parsed as a tool name →Bash(-:*).- itemlines beneath a scalar. YAML folds those into the scalar.research/trendradarwent from a 17-entry list to one ~600-character string:That is still valid YAML — which is why a syntax-level integrity check waved it through. Only a semantic comparison (list of 17 → str) catches it.
Fix: R005 now reads both YAML shapes, replaces the whole construct, and leaves
mcp__*ids and top-level tools bare rather than wrapping them. BareBashis a tool name, not a CLI name — wrapping it produced the nonsenseBash(Bash:*).Why this shipped
The existing suite tested em dashes inside fenced code blocks but never inline spans. This PR adds 12 regression tests built from the shapes that actually broke, including the real-world lines above.
Verification
bun test src/lib/skill-linter.test.tsbun test(full)--fixover 453 skills, inline spans lostallowed-toolslist → scalarname:/description:/ fences alteredAlso confirmed no new
Bash(Bash:*)is introduced: 47 pre-existing occurrences, unchanged.The corpus-wide application of the repaired fixer is opencue/skills#21.
🤖 Generated with Claude Code