Files
msd-core/tests
Oleksander Palian 73b9d1dac0 fix(install): use colon namespace for Gemini slash commands (#2768)
* fix(install): use colon namespace for Gemini slash commands and help reference

This fixes unexecutable command recommendations in Gemini CLI by correctly
namespacing slash commands (/gsd: instead of /gsd-) in all installed
artifacts (agents, commands, workflows).

- Implements a lazy command roster discovery to ensure 100% accurate
  conversion and protect file paths, URLs, and agent names.
- Adds isolated behavioral and unit tests covering all boundary cases.
- Fixes hardcoded command strings in banners and help output.

Closes #2783

* fix(install): close roster gaps in Gemini /gsd- → /gsd: conversion (#2783)

Addresses adversarial review findings on PR #2768:

- Restore regex boundaries (lookbehind + extension lookahead). Roster-only
  matching was insufficient: a URL like `https://example.com/gsd-plan-phase`
  ends in a known command and would be incorrectly converted. Boundaries +
  roster now agree before any conversion fires.
- Smarter trailing lookahead `(?!\.[a-z])` distinguishes file extensions
  (`.cjs`, `.md`) from sentence-ending punctuation (`.` at end of input or
  before whitespace), so `/gsd-help.` correctly converts.
- Fail loud on missing roster. `commands/gsd/` not found previously fell
  through to an empty Set, silently no-op'ing every conversion — exactly the
  bug this code exists to prevent. Now emits a one-shot console.warn (gated
  on GSD_TEST_MODE) before returning the empty set.
- Drop unnecessary `i` flag — GSD commands are always lowercase; matching
  uppercase tokens against a lowercase roster always misses anyway.
- Export `_resetGsdCommandRoster` for test isolation against the module-level
  cache.

Test additions pin the actual safety property of the roster check by using
KNOWN command names embedded in URLs and sub-paths — the cases the prior
tests didn't reach because they used `gsd-tools` (not in roster). Added a
roster-load assertion that fails loudly if the empty-Set fallback path
silently neutralises conversions.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix(install): centralize <sub> stripping and add structural test assertions

CodeRabbit findings on the prior commit:

- (actionable) Centralizing the Gemini conversion through
  convertClaudeToGeminiMarkdown dropped the stripSubTags() call that the
  inline command path used to make before TOML conversion. Move stripSubTags
  inside convertClaudeToGeminiMarkdown so command/agent/non-command Gemini
  outputs all have <sub> consistently stripped. Remove the now-redundant
  stripSubTags call in convertClaudeToGeminiAgent (single source of truth).
- (nitpick) Replace `.includes()` checks in the TOML test with structured
  parsing — JSON-decode each TOML value and assert on parsed fields, per
  the project's "tests parse, never grep" convention.
- (nitpick) Strengthen the install behavioral test to read a real installed
  artifact (.gemini/commands/gsd/plan-phase.toml), parse it, and assert the
  prompt body actually contains a /gsd: reference and no unconverted
  /gsd-plan-phase. A directory-only check would have passed even if every
  conversion silently no-op'd.
- Add a regression test that <sub> tags are stripped through the
  convertClaudeToGeminiMarkdown pipeline.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Tom Boucher <trekkie@nomorestars.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 22:37:57 -04:00
..