fix(#704): exclude } and ) from Codex path-rewrite lookbehind (no literal $gsd-core in installs) (#710)

* fix(#704): exclude } and ) from Codex path-rewrite lookbehind

Shell variable expressions like \${VAR}/gsd-core/ and command-substitution
paths like \$(cmd)/gsd-local-patches were being rewritten to \$gsd-core and
\$gsd-local-patches respectively because the negative lookbehind in
convertSlashCommandsToCodexSkillMentions did not include } or ).

Add both characters to the lookbehind set:
  (?<![a-zA-Z0-9./})])

Also adds regression test:
  tests/bug-704-codex-launcher-path-corruption.test.cjs

Closes #704

* chore: add changeset for #704

* test: use RUNTIME_ROOT_PATH in assertion to eliminate dead-code lint warning

Replace the partial hard-coded fragment '}/gsd-core/bin/' with the
existing RUNTIME_ROOT_PATH const so the assertion both compiles clean
(no unused variable) and self-documents which canonical launcher path
must survive Codex conversion intact (#704).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: link changeset to PR #710

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Tom Boucher
2026-06-06 12:40:06 -04:00
committed by GitHub
parent b4e817cfa0
commit 4b50a686e5
3 changed files with 248 additions and 3 deletions

View File

@@ -2802,9 +2802,12 @@ function convertSlashCommandsToCodexSkillMentions(content) {
return `$gsd-${String(commandName).toLowerCase()}`;
});
// Convert hyphen-style command references (workflow output) to Codex $ prefix.
// Negative lookbehind excludes file paths like bin/gsd-tools.cjs where
// the slash is preceded by a word char, dot, or another slash.
converted = converted.replace(/(?<![a-zA-Z0-9./])\/gsd-([a-z0-9-]+)/gi, (_, commandName) => {
// Negative lookbehind excludes shell path contexts where `/gsd-` is a path
// segment, not a slash-command mention:
// - word chars / dot / slash: `bin/gsd-tools.cjs`, `.claude/gsd-core/`
// - `}`: shell variable expressions `${VAR}/gsd-core/` (#704)
// - `)`: command-substitution paths `$(cmd)/gsd-local-patches` (#704)
converted = converted.replace(/(?<![a-zA-Z0-9./})])\/gsd-([a-z0-9-]+)/gi, (_, commandName) => {
return `$gsd-${String(commandName).toLowerCase()}`;
});
return converted;