fix(context): accept USER.md-style names for show/pull/push#59
Conversation
The .md extension is three bytes, but the normalizer took the last four characters as the suffix, so USER.md compared R.md to .md and never stripped. Use MD_SUFFIX.len() for slicing and document optional .md on show/pull/push in help and the hotdata skill.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Review
Blocking Issues
src/context.rslines 62-65:normalize_context_cli_namepanics on user input that ends with a multi-byte UTF-8 character whose last bytes straddle the 3-byte.mdboundary (e.g."x𝕌"is 5 bytes →start = 2, which lands inside the 4-byte𝕌sequence → Rust panics with "byte index is not a char boundary").
Action Required
Replace the byte-level slice with a safe suffix check:
let lower = basename.to_ascii_lowercase();
if lower.ends_with(".md") {
return basename[..basename.len() - MD_SUFFIX.len()].to_string();
}
basename.to_string()lower.ends_with(".md") guarantees the last 3 bytes are the ASCII characters ., m, d. Because ASCII bytes are never UTF-8 continuation bytes, basename.len() - 3 is then guaranteed to be a valid character boundary, making the slice safe.
Check the last three bytes on the UTF-8 byte slice before slicing the str, so stems like x𝕌 (without .md) do not use a misaligned str index. Adds regression tests for multibyte stems with and without .md.
There was a problem hiding this comment.
Blocking issue from cycle 1 is fixed. The byte-level suffix check in normalize_context_cli_name is correct: it only slices basename[..i] after confirming the last three bytes are ASCII .md, which guarantees i is a valid UTF-8 char boundary. Tests cover the multi-byte edge cases directly.
Normalizes the context name argument for
show,pull, andpush: trim, take the final path segment, then strip a trailing.md(ASCII case-insensitive) so autocomplete paths likeUSER.mdor./DATAMODEL.mdmap to API stemUSER/DATAMODELand local./<STEM>.md.Bugfix: the first implementation compared the last four bytes to
.md, but.mdis three bytes, so names likeUSER.mdnever matched. Suffix handling now uses".md".len().Docs: clap help for the three subcommands and a short note in
skills/hotdata/SKILL.md.context list/--prefixare unchanged (prefix still matches server names as typed).