feat(gemini): Add support for Gemini CLI / Antigravity via Hub Pattern#499
feat(gemini): Add support for Gemini CLI / Antigravity via Hub Pattern#499
Conversation
📝 WalkthroughWalkthroughAdds an installation workflow for Gemini Superpowers: a shell installer that symlinks repository skills into Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Installer as ".gemini/install.sh"
participant Repo as "repo/.gemini/skills/*"
participant FS as "Filesystem (~/.gemini, GEMINI.md)"
User->>Installer: run install script
Installer->>FS: ensure ~/.gemini and skills dir exist
Installer->>Repo: enumerate skill subdirectories
Repo-->>Installer: list of skill dirs
loop per-skill
Installer->>FS: create symlink at ~/.gemini/skills/<skill> (skip/verify existing)
FS-->>Installer: symlink created / skipped / error
end
Installer->>FS: read/replace/append SUPERPOWERS-CONTEXT block in GEMINI.md
FS-->>Installer: updated GEMINI.md
Installer-->>User: print completion and verification steps
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
.gemini/install.sh (2)
76-76: Preferprintfoverecho -efor portability.While
#!/bin/bashmakesecho -egenerally safe,printfis the more portable and predictable choice for embedded newlines.- echo -e "\n$CONTEXT_BLOCK" >> "$GEMINI_MD" + printf '\n%s\n' "$CONTEXT_BLOCK" >> "$GEMINI_MD"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.gemini/install.sh at line 76, Replace the portable but nonstandard echo usage with printf: change the line that appends CONTEXT_BLOCK to GEMINI_MD (currently using echo -e "\n$CONTEXT_BLOCK" >> "$GEMINI_MD") to use printf so newlines are handled predictably; reference the variables CONTEXT_BLOCK and GEMINI_MD and ensure printf is invoked to prepend a newline and append the content to the file in the same redirection.
66-77: No update path for the context block on re-install.If the context block content changes in a future version, re-running
install.shwill skip injection because the header marker already exists. Consider replacing the block between the START/END markers on re-install so users get updated instructions.♻️ Proposed update-aware injection
-if grep -q "$CONTEXT_HEADER" "$GEMINI_MD"; then - echo "Superpowers context already present in $GEMINI_MD. Skipping injection." -else +if grep -qF "$CONTEXT_HEADER" "$GEMINI_MD"; then + echo "Updating Superpowers context in $GEMINI_MD..." + # Remove old block (sed between markers, inclusive) + sed -i.bak "/$CONTEXT_HEADER/,/$CONTEXT_FOOTER/d" "$GEMINI_MD" +fi +{ echo "Injecting Superpowers context into $GEMINI_MD..." - echo -e "\n$CONTEXT_BLOCK" >> "$GEMINI_MD" -fi + printf '\n%s\n' "$CONTEXT_BLOCK" >> "$GEMINI_MD" +}Also note:
grep -qinterprets$CONTEXT_HEADERas a regex. Usegrep -qFfor a fixed-string match to avoid issues with the<!--characters.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.gemini/install.sh around lines 66 - 77, The installer currently only checks for CONTEXT_HEADER with grep -q (regex) and skips injection, so updated CONTEXT_BLOCK changes won't be applied; modify the logic in install.sh to (1) use grep -qF to perform a fixed-string search for CONTEXT_HEADER and (2) when the START/END marker pair exists, replace the entire block between those markers with the new CONTEXT_BLOCK (rather than skipping), creating the file if missing and appending the block only when no markers are present; reference CONTEXT_HEADER and CONTEXT_BLOCK to locate the existing conditional and implement the replace-via-sed/awk or temp-file rewrite approach.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.gemini/INSTALL.md:
- Around line 57-64: The uninstall instructions currently use the commands "rm
~/.gemini/skills/*" and "rm -rf ~/.gemini/skills" which will remove all user
skills; change the guidance to only delete symlinks created by this installer by
replacing the blanket rm with a safe command that finds and deletes symbolic
links whose target path includes "superpowers" (i.e., only remove symlinks
pointing into the superpowers repo), and keep the note that "rm -rf
~/.gemini/skills" should only be used if the user truly has no other skills.
In @.gemini/install.sh:
- Around line 27-40: The loop unconditionally uses rm -rf on $target_path which
can delete real user directories; change the removal logic in the loop to only
unlink existing symlinks and refuse or warn if $target_path exists and is not a
symlink: test $target_path with [ -L "$target_path" ] (or [ -h ]) and run rm (or
unlink) only for symlinks, otherwise log/echo a warning and skip linking; keep
variables referenced (skill_path, skill_name, target_path, SKILLS_LINK) and
ensure the script still creates the symlink when safe.
---
Nitpick comments:
In @.gemini/install.sh:
- Line 76: Replace the portable but nonstandard echo usage with printf: change
the line that appends CONTEXT_BLOCK to GEMINI_MD (currently using echo -e
"\n$CONTEXT_BLOCK" >> "$GEMINI_MD") to use printf so newlines are handled
predictably; reference the variables CONTEXT_BLOCK and GEMINI_MD and ensure
printf is invoked to prepend a newline and append the content to the file in the
same redirection.
- Around line 66-77: The installer currently only checks for CONTEXT_HEADER with
grep -q (regex) and skips injection, so updated CONTEXT_BLOCK changes won't be
applied; modify the logic in install.sh to (1) use grep -qF to perform a
fixed-string search for CONTEXT_HEADER and (2) when the START/END marker pair
exists, replace the entire block between those markers with the new
CONTEXT_BLOCK (rather than skipping), creating the file if missing and appending
the block only when no markers are present; reference CONTEXT_HEADER and
CONTEXT_BLOCK to locate the existing conditional and implement the
replace-via-sed/awk or temp-file rewrite approach.
5d7d89f to
123b851
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
.gemini/install.sh (2)
19-23: Silently removing an existingskillssymlink may surprise users.If a user intentionally set up
~/.gemini/skillsas a symlink to their own skills directory, this code silently removes it and replaces it with a plain directory. Consider warning the user before proceeding, similar to the guard on Line 25-28.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.gemini/install.sh around lines 19 - 23, The install script currently unconditionally removes the existing SKILLS_LINK symlink, which can surprise users; modify the symlink-handling block that checks SKILLS_LINK so it warns the user and prompts for confirmation (or exits) before removing the symlink—mirror the guarded behavior used later in the script (the existing prompt/guard around skills directory handling) so that when SKILLS_LINK is a symlink the script prints a clear message including the path, asks the user to confirm replacement, and only calls rm and recreates the directory after explicit consent (or provides a FORCE/yes flag to skip confirmation).
78-89: Sed-based block removal may leave trailing blank lines on repeated runs.Each invocation appends
\n$CONTEXT_BLOCK(Line 89), and theseddelete (Line 82) removes only the marker-delimited lines, not the preceding newline added byecho -e "\n...". After multiple re-installs, blank lines accumulate at the end ofGEMINI.md.Consider using
printfand trimming trailing whitespace after the sed deletion:♻️ Suggested improvement
- sed -i.bak "/$CONTEXT_HEADER/,/$CONTEXT_FOOTER/d" "$GEMINI_MD" - rm "${GEMINI_MD}.bak" + # Delete the block and the blank line immediately before it + sed -i.bak "/$CONTEXT_HEADER/,/$CONTEXT_FOOTER/d" "$GEMINI_MD" + # Trim trailing blank lines + sed -i.bak -e :a -e '/^\n*$/{$d;N;ba' -e '}' "$GEMINI_MD" + rm -f "${GEMINI_MD}.bak" ... -echo -e "\n$CONTEXT_BLOCK" >> "$GEMINI_MD" +printf '\n%s\n' "$CONTEXT_BLOCK" >> "$GEMINI_MD"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.gemini/install.sh around lines 78 - 89, The sed deletion of the CONTEXT_HEADER..CONTEXT_FOOTER block followed by echo -e "\n$CONTEXT_BLOCK" causes accumulating blank lines in GEMINI_MD; change the append step to avoid a leading newline and ensure only a single terminating newline (for example, replace echo -e "\n$CONTEXT_BLOCK" >> "$GEMINI_MD" with a printf that normalizes spacing, e.g. use printf "%s\n\n" "$CONTEXT_BLOCK" >> "$GEMINI_MD" or printf "%s\n" "$CONTEXT_BLOCK" and then run a trailing-whitespace trim after sed (e.g. a portable sed/perl snippet that collapses multiple trailing newlines to a single newline) so functions/variables to touch are CONTEXT_BLOCK, CONTEXT_HEADER/CONTEXT_FOOTER, the sed removal block and the append command.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.gemini/INSTALL.md:
- Around line 3-4: Replace the unreachable link 'https://gemini-cli.com' (the
"Gemini CLI" markdown link) with the correct, reachable Gemini CLI URL or
remove/replace that markdown link with an authoritative alternative (e.g., the
official Gemini CLI homepage or repository), keeping the anchor text "Gemini
CLI" and verifying the new URL returns HTTP 200 before merging.
In @.gemini/install.sh:
- Line 8: The REPO_SKILLS_DIR assignment uses cd on a potentially missing
directory, which under set -e aborts with an unhelpful "No such file or
directory"; guard the operation by checking the target directory exists before
cd (e.g., test [ -d "$(dirname "${BASH_SOURCE[0]}")/../skills" ]), and if it
doesn't exist print a clear error and exit (include context like "skills/
directory not found for REPO_SKILLS_DIR") so the script fails with a helpful
message rather than a bare shell error; update the logic around REPO_SKILLS_DIR
to perform this test and conditional cd/exit.
---
Duplicate comments:
In @.gemini/INSTALL.md:
- Around line 57-64: The uninstall instructions currently use the unsafe
commands `rm ~/.gemini/skills/*` and `rm -rf ~/.gemini/skills` which delete all
user skills; update the text to instead remove only symlinks that point to the
superpowers install (i.e., find and delete entries in ~/.gemini/skills that are
symbolic links whose target path contains "superpowers"), and keep the note that
the full `rm -rf` of the skills directory should only be suggested if the user
truly has no other skills.
In @.gemini/install.sh:
- Around line 32-45: The current loop uses rm -rf "$target_path" which can
irreversibly delete real directories; change the removal logic to only unlink
existing symlinks and never recursively remove real directories: check if
"$target_path" is a symlink (e.g., [ -L "$target_path" ] or [ -h "$target_path"
]) and if so remove it (rm "$target_path"), but if [ -e "$target_path" ] and not
a symlink then skip linking and print a warning (or exit non‑destructively) so
real user content is preserved; update the block around skill_path/target_path
and the rm -rf call accordingly so only symlinks are removed before ln -s.
---
Nitpick comments:
In @.gemini/install.sh:
- Around line 19-23: The install script currently unconditionally removes the
existing SKILLS_LINK symlink, which can surprise users; modify the
symlink-handling block that checks SKILLS_LINK so it warns the user and prompts
for confirmation (or exits) before removing the symlink—mirror the guarded
behavior used later in the script (the existing prompt/guard around skills
directory handling) so that when SKILLS_LINK is a symlink the script prints a
clear message including the path, asks the user to confirm replacement, and only
calls rm and recreates the directory after explicit consent (or provides a
FORCE/yes flag to skip confirmation).
- Around line 78-89: The sed deletion of the CONTEXT_HEADER..CONTEXT_FOOTER
block followed by echo -e "\n$CONTEXT_BLOCK" causes accumulating blank lines in
GEMINI_MD; change the append step to avoid a leading newline and ensure only a
single terminating newline (for example, replace echo -e "\n$CONTEXT_BLOCK" >>
"$GEMINI_MD" with a printf that normalizes spacing, e.g. use printf "%s\n\n"
"$CONTEXT_BLOCK" >> "$GEMINI_MD" or printf "%s\n" "$CONTEXT_BLOCK" and then run
a trailing-whitespace trim after sed (e.g. a portable sed/perl snippet that
collapses multiple trailing newlines to a single newline) so functions/variables
to touch are CONTEXT_BLOCK, CONTEXT_HEADER/CONTEXT_FOOTER, the sed removal block
and the append command.
123b851 to
82cd62e
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@README.md`:
- Line 19: Replace the informal contraction in the README where the phrase
"YAGNI (You Aren't Gonna Need It)" appears: change "Gonna" to "Going to" so the
parenthetical reads "You Aren't Going to Need It" (update the exact string
"YAGNI (You Aren't Gonna Need It)" to "YAGNI (You Aren't Going to Need It)").
---
Duplicate comments:
In @.gemini/INSTALL.md:
- Around line 57-64: The uninstall instructions currently delete everything in
~/.gemini/skills (lines containing "rm ~/.gemini/skills/*" and "rm -rf
~/.gemini/skills"); change the doc to only remove symlinks that point into the
superpowers repo by replacing those broad rm commands with a scoped removal that
detects symlinks in ~/.gemini/skills and deletes them only if their target path
contains the superpowers repo identifier (e.g., check -L/readlink or readlink -f
and match "superpowers"), leaving regular user-managed directories and files
intact; update the two occurrences of the removal snippet in INSTALL.md
accordingly.
b8a3a5e to
7af108e
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (2)
.gemini/install.sh (2)
91-91:echo -eis not portable — useprintfinstead.
echo -eis not specified by POSIX and behaves inconsistently across platforms. On some systems (e.g., macOS/bin/sh, or whenbashis invoked assh), it may print a literal-e. Since the script targets both macOS and Linux (as noted by the BSD/GNU sed comment on Line 82), preferprintf:♻️ Proposed fix
-echo -e "\n$CONTEXT_BLOCK" >> "$GEMINI_MD" +printf '\n%s\n' "$CONTEXT_BLOCK" >> "$GEMINI_MD"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.gemini/install.sh at line 91, Replace the non-portable echo -e usage with printf to ensure consistent behavior across sh implementations: change the line that uses echo -e "\n$CONTEXT_BLOCK" >> "$GEMINI_MD" to use printf with proper quoting and format specifiers, e.g. using printf '\n%s\n' "$CONTEXT_BLOCK" >> "$GEMINI_MD" so a leading newline and the CONTENT_BLOCK are appended reliably.
80-85:sedpattern treats.in the HTML comment markers as regex wildcards.
CONTEXT_HEADERandCONTEXT_FOOTERcontain<!-- ... -->, and.matches any character in a basic regex. This means the sed deletion could match unintended lines (e.g.,<!XX SUPERPOWERS-CONTEXT-START XXX>). Since the markers are under your control this is low-risk, but for correctness you should escape the dots or use a fixed-string approach.♻️ One option: escape the variables for sed
- sed -i.bak "/$CONTEXT_HEADER/,/$CONTEXT_FOOTER/d" "$GEMINI_MD" + escaped_header=$(printf '%s\n' "$CONTEXT_HEADER" | sed 's/[.[\/*^$]/\\&/g') + escaped_footer=$(printf '%s\n' "$CONTEXT_FOOTER" | sed 's/[.[\/*^$]/\\&/g') + sed -i.bak "/$escaped_header/,/$escaped_footer/d" "$GEMINI_MD"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.gemini/install.sh around lines 80 - 85, The sed range deletion uses CONTEXT_HEADER and CONTEXT_FOOTER which contain literal dots from HTML comments, so sed treats them as regex wildcards and may overmatch; update the sed usage in the block that references CONTEXT_HEADER, CONTEXT_FOOTER and GEMINI_MD to pass regex-escaped versions of those variables (escape . [ ] * ^ $ \ etc.) or switch to a fixed-string approach (use sed's non-regex/fixed-string mode or build the range with escaped markers) so the deletion only matches the exact <!-- ... --> markers; ensure the backup removal (rm "${GEMINI_MD}.bak") remains unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In @.gemini/INSTALL.md:
- Around line 57-64: The uninstall instructions currently use "rm
~/.gemini/skills/*" (and "rm -rf ~/.gemini/skills") which deletes all skills;
change this to only remove symlinks pointing into the superpowers repo by
replacing that command with a safe removal loop or find invocation that checks
symlink targets (e.g. iterate over ~/.gemini/skills/*, test -L and resolve with
readlink -f, then unlink only if the resolved path is inside the superpowers
repo). Update the text that references "Remove the symlinks" to show the new
safe command sequence and remove the blanket rm -rf example.
In @.gemini/install.sh:
- Around line 1-8: The subshell assignment to REPO_SKILLS_DIR uses cd into
../skills and will fail under set -e if that directory is missing; before
computing REPO_SKILLS_DIR (the line using "$(cd "$(dirname
"${BASH_SOURCE[0]}")/../skills" && pwd)"), guard against a missing skills
directory by checking existence (e.g., test -d on "$(dirname
"${BASH_SOURCE[0]}")/../skills") and either create the directory or emit a clear
error and exit, then compute REPO_SKILLS_DIR only after the check succeeds so
the subshell cd cannot cause an unhandled failure.
- Around line 34-47: The current install loop in .gemini/install.sh uses rm -rf
on $target_path which can delete real user directories; change the removal logic
to only unlink/remove when $target_path is a symlink (use the existing [ -L
"$target_path" ] test) and do not call rm -rf for regular directories—if
$target_path exists but is not a symlink, skip creating the link and emit a
warning/error so the user can resolve the conflict; update the block that
references target_path and SKILLS_LINK accordingly (remove unconditional rm -rf
and only remove symlinks).
---
Nitpick comments:
In @.gemini/install.sh:
- Line 91: Replace the non-portable echo -e usage with printf to ensure
consistent behavior across sh implementations: change the line that uses echo -e
"\n$CONTEXT_BLOCK" >> "$GEMINI_MD" to use printf with proper quoting and format
specifiers, e.g. using printf '\n%s\n' "$CONTEXT_BLOCK" >> "$GEMINI_MD" so a
leading newline and the CONTENT_BLOCK are appended reliably.
- Around line 80-85: The sed range deletion uses CONTEXT_HEADER and
CONTEXT_FOOTER which contain literal dots from HTML comments, so sed treats them
as regex wildcards and may overmatch; update the sed usage in the block that
references CONTEXT_HEADER, CONTEXT_FOOTER and GEMINI_MD to pass regex-escaped
versions of those variables (escape . [ ] * ^ $ \ etc.) or switch to a
fixed-string approach (use sed's non-regex/fixed-string mode or build the range
with escaped markers) so the deletion only matches the exact <!-- ... -->
markers; ensure the backup removal (rm "${GEMINI_MD}.bak") remains unchanged.
3625c15 to
02343b1
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.gemini/install.sh:
- Around line 90-102: The current remove-and-append logic leaves accumulating
blank lines because sed deletes the block but preserves whitespace and the
script unconditionally echoes "\n$CONTEXT_BLOCK"; update the block replace to
trim trailing blank lines in "$GEMINI_MD" after the sed deletion (or check the
file end) before appending: after running sed -i.bak
"/$CONTEXT_HEADER/,/$CONTEXT_FOOTER/d" "$GEMINI_MD" remove any trailing empty
lines from GEMINI_MD (e.g., collapse/strip final blank lines) and then append
CONTEXT_BLOCK without adding an extra leading newline if the file already ends
with a newline; reference CONTEXT_HEADER, CONTEXT_FOOTER, GEMINI_MD and
CONTEXT_BLOCK when making the change.
---
Duplicate comments:
In @.gemini/install.sh:
- Around line 8-14: REPO_SKILLS_DIR may be empty when the subshell cd fails,
producing an unhelpful error message; fix by computing the canonical path only
after verifying the directory exists (e.g., compute SCRIPT_DIR="$(dirname
"${BASH_SOURCE[0]}")" then EXPECTED_DIR="$SCRIPT_DIR/../skills" and check [ -d
"$EXPECTED_DIR" ] before calling cd/pwd), or if you must use the subshell
approach capture the cd return status and fall back to printing the resolved
expected path; update the guard that references REPO_SKILLS_DIR (and the error
message) so it prints the expected path variable when REPO_SKILLS_DIR is empty
and only uses pwd output when cd succeeded.
0766358 to
94e7ad4
Compare
94e7ad4 to
b45a20a
Compare
There was a problem hiding this comment.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In @.gemini/install.sh:
- Around line 101-106: The current awk command (awk 'NF{p=1} p') only strips
leading blank lines and allows trailing blank lines to accumulate; locate the
line containing that awk invocation (operating on "$GEMINI_MD") and replace it
with a command that removes trailing blank lines from "$GEMINI_MD" (so you
rewrite to "${GEMINI_MD}.tmp" and mv back), then change the append invocation
that currently uses echo -e "\n\n$CONTEXT_BLOCK" to append with exactly one
separating newline (use a single newline before "$CONTEXT_BLOCK"); ensure you
reference the same variables GEMINI_MD and CONTEXT_BLOCK and preserve the tmp+mv
pattern.
- Around line 8-14: The guard is ineffective because REPO_SKILLS_DIR is computed
with command substitution using cd (via BASH_SOURCE) which will cause the script
to exit under set -e if the directory doesn't exist; instead compute the raw
path first (e.g. derive a candidate path from dirname
"${BASH_SOURCE[0]}"/../skills), test that candidate with [ -d ] and exit if
missing, and only then canonicalize into REPO_SKILLS_DIR (e.g. using cd
"$candidate" && pwd or readlink -f) so the existence check actually runs.
There was a problem hiding this comment.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In @.gemini/INSTALL.md:
- Around line 3-4: The README links to external sites "https://geminicli.com"
and "https://antigravity.google"; verify that the Gemini CLI URL is the
official, current homepage and returns HTTP 200 (reachable) and update the
INSTALL.md link accordingly if it differs (use the maintainer's official site or
documentation/GitHub release page); if the URL is incorrect, replace
"https://geminicli.com" with the verified canonical URL and add a short note or
citation to the maintainer source.
|
One thing I'd like to mention for your consideration, is the changing of all the "Claude"-specific mentions in Gemini's skills. I fixed it like this: https://gist.github.com/tomioe/5038760f7f40d0c7eb86b2cc4a538b7f#file-gemini-setup-sh-L73-L81 It is also the reason why I decided against including the "writing-skills" in my Gemini install script, VERY Claude specific... It might be enough for the GEMINI.md-context you've provided, but thought I would mention it anyway. Also, you're not porting the Other than that, this installation script provided a very smooth installation process, kudos! I especially like that you're checking for existing links :-) |
|
I'd be happy to build on this to create a Gemini CLI extension and/or Antigravity workflows. That would allow for the |
Summary
Summary by CodeRabbit
Documentation
Chores
Issues Addressed
May adequately address Issue #128 : Gemini CLI now supports skills natively, so an extension isn't required.
Would also address Issue #270: Gemini CLI and Antigravity share the same centralized config for skills.