fix: sanitize colons in skill/agent names for Windows path compatibility#398
fix: sanitize colons in skill/agent names for Windows path compatibility#398
Conversation
Colons in namespaced skill names (e.g. ce:brainstorm) are illegal in Windows filenames, causing ENOTDIR errors during convert/install. Add sanitizePathName() that replaces colons with hyphens, applied across all 10 target writers and 3 sync files. Output paths now match source directory names (e.g. skills/ce-brainstorm/). Closes #366
The OpenCode command sync path used raw command names directly in path.join, bypassing resolveCommandPath — so namespaced commands like workflows:plan produced colon paths instead of nested directories. Also adds sanitizePathName unit tests and collision detection tests that load the real compound-engineering plugin and verify no two skill or agent names collide after sanitization.
Three issues where converters didn't account for filesystem sanitization: 1. OpenClaw manifest advertised colon paths (skills/cmd-ce:plan) while the writer created hyphenated dirs (skills/cmd-ce-plan), making namespaced skills undiscoverable. 2. Copilot reserved raw skill names (ce:plan) in the dedupe set, so a generated skill normalizing to ce-plan didn't detect the collision and both wrote to skills/ce-plan/, with pass-through overwriting. 3. Windsurf same pattern — agent skill dedupe used unsanitized names. Fix: use sanitizePathName when building dedupe sets and manifest paths. Add regression tests for all three cases.
…ance Document the colon-in-path sanitization fix as a solution under integrations/ (not developer-experience/), and add guidance to AGENTS.md explaining the distinction: developer-experience/ is for repo contributor friction, integrations/ is for end-user platform issues.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c418f4d016
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Warn and skip when two names collapse to the same path after sanitization (e.g. ce:plan and ce-plan both becoming ce-plan). Defense-in-depth alongside the converter-level dedupe and test-level collision detection already in place.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 109cdfd856
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Summary
Colon-namespaced skill names like
ce:brainstormwere used directly as directory names across all target writers, sync paths, and converter manifests. Colons are illegal in Windows filenames, sobun convertandbun installfailed withENOTDIRon Windows.Fixes this by adding
sanitizePathName()that replaces colons with hyphens, applied at three layers:sanitizePathName()when constructing output pathsAlso fixes a pre-existing bug where
syncOpenCodeCommandsbypassedresolveCommandPath, producing colon paths for namespaced commands.Key decisions
/as the replacement (turningce:brainstormintoce/brainstorm/), but switched to-because the source directories already use hyphens,validatePathSaferejects/, and nesting adds unnecessary structure.resolveCommandPathleft as-is: Commands use a different pattern (colons to nested dirs) which is intentional — commands and skills have different resolution semantics across target platforms.Test plan
bun convert --to opencodeproduces zero colon paths in outputFixes #366 #307
🤖 Generated with Claude Opus 4.6 (1M context, extended thinking) via Claude Code