a33cbe72f569e75e72d94de85d0930296d1ca1df
3 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
dca12242b5 |
fix(install): skip Gemini local commands/gsd when global GSD present (#3037) (#3041)
* fix(install): skip Gemini local commands/gsd when global GSD present (#3037) Reporter showed that running `npx get-shit-done-cc --gemini --global` followed by `--gemini --local` in a project creates the same 65 GSD command files in both Gemini scopes: - ~/.gemini/commands/gsd/ (user scope) - <project>/.gemini/commands/gsd/ (workspace scope) Gemini conflict-detects by command name across scopes and renames every overlapping /gsd:* command to /workspace.gsd:* and /user.gsd:*, breaking the documented /gsd:* namespace. Fix: in bin/install.js, when handling --gemini --local, detect whether ~/.gemini/commands/gsd/ already exists with managed-shape content. If so, skip the local copy and print a clear three-line warning explaining the conflict avoidance. The user-scope install already provides the same /gsd:* commands in this project; the local copy adds zero value. Sibling fixes (test isolation): - tests/install-minimal-all-runtimes.test.cjs: pass HOME/USERPROFILE through the spawned installer's env so the developer's real ~/.gemini/commands/gsd/ doesn't trigger the new skip path during test runs that want to assert the local-install populates commands/gsd/. - tests/gemini-namespacing.test.cjs: the "Gemini Install (Behavioral)" describe block now creates an isolated tmpHome and points process.env.HOME at it before calling install(false, 'gemini'), with proper restore in afterEach. Test: - tests/bug-3037-gemini-duplicate-commands.test.cjs — 4 structural tests: 1. global install populates HOME/.gemini/commands/gsd 2. local install AFTER global skips the local copy 3. local install with NO existing global still populates locally (no-regression) 4. local install when HOME has .gemini/ but no GSD-managed commands/gsd/ still populates locally (non-GSD-Gemini-user no-regression) 6909/6909 full suite pass. Lints clean. Closes #3037 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix: address CR feedback on PR #3041 — narrower detection + USERPROFILE restore CR findings: 1. **bin/install.js (Major)** — userScopeHasGsd used `fs.readdirSync(homeGeminiGsd).length > 0` which would skip the local install for any non-empty directory, including a user who hand-dropped a single override at ~/.gemini/commands/gsd/<thing> .toml without ever running --gemini --global. Narrowed the detection to require at least 3 canonical GSD command files (help.toml, progress.toml, new-project.toml) — a marker that ships in every GSD Gemini install (minimal mode included) and is structurally impossible to produce by accident. 2. **tests/bug-3037-...:59 (Minor)** — beforeEach overwrites process.env.USERPROFILE but afterEach only restores HOME, leaking the temp home into later tests on Windows or any code path that reads USERPROFILE. Added save/restore symmetric with HOME. Plus added a 5th regression test covering the narrowed detection: "local install when HOME has hand-dropped overrides UNDER commands/gsd/ (but no full GSD) still populates locally" — directly exercises the edge case CR identified. 5/5 targeted tests pass. 6910/6910 full suite pass. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
c72b893916 |
fix(test): unbreak gemini-namespacing test after #2790 skill consolidation (#2886)
Closes #2876 follow-up — CI on main fails because the punctuation test in tests/gemini-namespacing.test.cjs hardcoded `/gsd-scan` as a known command, but #2824 (consolidate 86 → 59 skills) removed scan.md from commands/gsd/. The roster now correctly returns "scan is unknown, leave unchanged" — the conversion is right, the test fixture is stale. Swap `scan` for `health` in the punctuation test. Both are bedrock commands; the test still exercises the original intent (period vs exclamation handling on adjacent slash commands). Note added so the next consolidation reviewer knows the swap pattern. `npm test`: 5936/5936 pass. |
||
|
|
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> |