One-time bootstrap: detect OS, install/verify system package manager, bun, git, and GitHub CLI.
This is a one-time setup task. The agent runs it automatically on first session, notes the results, and never loads it again.
[!IMPORTANT] Never give up on installing a tool. If the system package manager (brew on macOS, winget on Windows) is locked, broken, or permission-denied, the agent must automatically pivot to alternative installation methods:
- macOS/Linux: Use
curlscripts or direct binary downloads- Windows: Use PowerShell web requests (
irm) or direct.msi/.zipdownloadsDo not attempt to fix package manager permissions (e.g.,
chownorchmodon brew directories) as this risks breaking other users' setups on shared machines.
When extensions.json has "setup-package-manager": "pending", execute this flow. Run each check in order. If a tool is already installed, skip to the next one.
At the very start (before the welcome message), create a checklist file at ~/.gemini/setup/setup-progress.md:
# Liftoff Setup Progress
- [ ] Step 0: Welcome + GitHub check
- [ ] Step 1: Detect OS
- [ ] Step 1.5: Windows Build Essentials (Windows only)
- [ ] Step 2: Install Homebrew (macOS) / detect package manager
- [ ] Step 3: Install bun
- [ ] Step 4: Detect git
- [ ] Step 5: Install and authenticate GitHub CLI
- [ ] Step 6: Write Machine Environment
- [ ] Step 7: Mark setup-package-manager as done
- [ ] Step 8: Confirm all tools
- [ ] Step 9: Handoff to project init
After completing each step, update the checklist:
[x][x] Step 3: Install bun (fallback: curl install)If the agent gets interrupted, errors out, or loses context, it should:
~/.gemini/setup/setup-progress.md[ ] itemAfter Step 9 completes successfully, delete the file - it's no longer needed.
[!IMPORTANT] Error recovery: If any step fails, do NOT skip it and do NOT abandon the setup. Troubleshoot the issue, try alternative approaches (see fallback instructions in each step), and resolve it before moving on. After resolving, check off the step in
setup-progress.mdwith a note about what was done differently, then continue from the next unchecked step.
Start the session with this message (include the line breaks exactly as shown):
"Welcome Astronaut 🧑🚀 to samihermes.ai Liftoff! 🚀 Are you ready to move with rocket speed and get an AI upgrade?
I'm going to set up your developer toolkit now to give you a super boost ⚡️ - this will take just a few minutes. I'll install everything automatically and ask you only when I need your help. Enjoy the magic 🪄
- First things first - do you have a GitHub account? If you don't, create one right now as the first step at github.com/signup - this is essential and mandatory to move on. (don't worry, you will learn what it is and how to use it over time working with me)
If you already have an account, go and sign in right now. Reply with 'Ready' when you have done this."
Wait for the user to confirm before proceeding to Step 1.
The system context includes OS version: mac or OS version: windows. Use this to branch.
[!IMPORTANT] This step is the Windows equivalent of macOS Xcode Command Line Tools. On Mac, Homebrew automatically detects and installs the C/C++ compiler and system headers. Windows has no such automatic chain - the agent must explicitly check for and install these foundational tools. Without them,
bun installornpm installwill fail with cryptic errors on any package with native bindings (e.g.,sharp,better-sqlite3,node-canvas).
Skip this entire step on macOS/Linux - macOS handles this via Xcode CLI Tools (triggered automatically by Homebrew), and Linux distributions ship with gcc/build-essential.
where cl.exe
Build Tools: Visual C++ (present) and skip to 1.5.2"I'm installing Windows Build Tools - these are foundational tools your computer needs to compile software. On Mac this happens automatically, but on Windows we set it up once. This may take 5-10 minutes."
winget install Microsoft.VisualStudio.2022.BuildTools --override "--quiet --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended"
"Please download Build Tools from https://visualstudio.microsoft.com/visual-cpp-build-tools/ - click Download, run the installer, select 'Desktop development with C++', and click Install. Reply with 'Done' when finished."
where cl.exe
Build Tools: unavailable (manual install needed) and move on. The user may hit errors later with native packages, but core tools (bun, git, gh) will still work.Many native Node.js/Bun packages use node-gyp to compile, which requires Python. macOS ships with Python; Windows does not.
python --version
winget install Python.Python.3.12
powershell -c "irm https://www.python.org/ftp/python/3.12.0/python-3.12.0-amd64.exe -OutFile python-installer.exe; Start-Process python-installer.exe -ArgumentList '/quiet InstallAllUsers=1 PrependPath=1' -Wait"
python --version
Python: unavailable and move on. Most projects will work, but some native compilation steps may fail.macOS:
which brewbrew --version
brew --version succeeds: brew is healthy, use it for subsequent installsbrew --version fails (permission denied, errors): brew is unusable on this account. Note Package Manager: unavailable (permission denied) and use curl/direct-download for all subsequent tool installs. Do not reinstall brew or modify permissions - this would break other users on the same machinewhich brew returns nothing (brew not installed): tell the user you're installing Homebrew, then run:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
echo >> ~/.zprofile
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"
brew --versionPackage Manager: unavailable and use curl/direct-download for all subsequent toolsWindows:
where winget or winget --versionwinget and skip to step 3where choco and where scoop"Do you have a preferred package manager? If you don't know, just say 'I don't know'."
winget ships with Windows 10/11 - verify with winget --version. If truly missing, install via the App Installer package from the Microsoft Store, or note Package Manager: unavailable and use PowerShell/direct-download for all subsequent toolsPackage Manager: unavailable and move onLinux:
which apt, which dnf, which pacman, which zypperwhich bun (or where bun on Windows)| OS | Primary (package manager) | Fallback (direct install) |
|---|---|---|
| macOS | brew install oven-sh/bun/bun | curl -fsSL https://bun.sh/install \| bash |
| Windows | winget install Oven-sh.Bun | powershell -c "irm bun.sh/install.ps1 \| iex" |
| Linux | curl -fsSL https://bun.sh/install \| bash | Same (curl is the primary method) |
bun --versionRuntime: manual (bun install blocked) and provide the user with: https://bun.sh/docs/installationMost systems ship with git. Check first.
git --version| OS | Primary (package manager) | Fallback |
|---|---|---|
| macOS | brew install git | xcode-select --install (opens a system dialog - tell the user: "A dialog will appear asking to install Command Line Tools. Click Install and wait for it to finish.") |
| Windows | winget install Git.Git | Tell the user: "Please download Git from https://git-scm.com/download/win and run the installer. Use the default settings." |
| Linux | sudo apt install git / sudo dnf install git | Always available via system package manager |
git --versiongh --version| OS | Primary (package manager) | Fallback (direct install) |
|---|---|---|
| macOS | brew install gh | curl -sS https://webi.sh/gh \| bash |
| Windows | winget install GitHub.cli | powershell -c "irm https://webi.sh/gh \| iex" |
| Linux | See gh install docs | curl -sS https://webi.sh/gh \| bash |
Authenticate (fully automated - no user interaction at the terminal):
gh auth login --hostname github.com --git-protocol https --web
[!CAUTION] This command has TWO interactive prompts. The agent MUST handle BOTH automatically:
Prompt 1:
? Authenticate Git with your GitHub credentials? (Y/n)- The agent MUST immediately sendY\n(the letter Y followed by Enter) via stdin/send-input. Do NOT wait. Do NOT ask the user. Just send it.Prompt 2:
Press Enter to open github.com in your browser...- The agent MUST immediately send\n(Enter) via stdin/send-input. Do NOT wait. Do NOT ask the user. Just send it.Both of these are mandatory automated actions. The user cannot interact with the terminal - there is no button for them to click. The agent is the only one who can send input. If the agent does not have permission to send input, it must request permission to do so - but it must NEVER ask the user to type in the terminal.
"👉 A browser should have opened. Log in to GitHub and enter this code: [CODE]
Reply with 'Done' when you've completed the authorization."
gh auth status. If auth is NOT successful, tell the user:
"Hmm, it looks like the connection didn't go through yet. Did you enter the code [CODE] and click Authorize on GitHub? Try again and reply with 'Done' when connected."
gh auth status confirms authenticationIf the user doesn't have a GitHub account:
"You'll need a GitHub account to store your code. Head to github.com/signup, create a free account, then come back here and we'll finish connecting."
Verify with gh auth status (skip if already verified in step 4 above)
After GitHub CLI is authenticated, tell the user:
"You're now connected to GitHub - this is where all your projects get safely stored and backed up.
Think of GitHub as a cloud vault for everything you build. Every change I make gets saved there automatically, so you'll never lose your work. It also makes it easy to share projects or collaborate later.
This connection is permanent - you won't need to do this again."
Append a ## Machine Environment section to the user's ~/.gemini/skills/liftoff-lifecycle/SKILL.md (at the end of the file):
## Machine Environment
- OS: [macOS / Windows / Linux] ([architecture if detectable])
- Package Manager: [brew / winget / choco / scoop / apt / dnf / pacman / unavailable]
- Build Tools: [Xcode CLI Tools (macOS) / Visual C++ Build Tools 2022 (Windows) / gcc (Linux) / unavailable]
- Python: [version] (or: unavailable / not needed)
- Runtime: bun [version]
- Git: [version]
- GitHub CLI: gh [version] (authenticated as @[username])
If the section already exists (re-run scenario), update it instead of duplicating.
Update ~/.gemini/extensions/extensions.json: change "setup-package-manager" from "pending" to "done".
Tell the user (dynamic - reflect what you ACTUALLY did, do not hard-code):
"Global setup is complete! 🥳 Everything is ready ✅
Here's what I just took care of and why each one matters:"
Then list ONLY the tools that are relevant to the user's OS. For each tool, honestly state what happened:
Use these explanations (adapt to actual tool names on user's OS):
End with:
"I'll use the right commands for your system automatically from now on.
I'm juiced up and boosted ⚡️"
Then immediately proceed to Step 9.
Goal: Reduce the risk of brand‑new, compromised releases (like axios-style incidents) without blocking normal beginners.
These steps are for the agent only. Do not ask the user to edit config files; apply changes silently during setup and explain briefly afterwards.
npm is available:
npm --version
~/.npmrc exists and add a minimum release age gate if not already present:
touch ~/.npmrc
if ! grep -q "min-release-age" ~/.npmrc; then
printf '\nmin-release-age=7d\n' >> ~/.npmrc
fi
"I configured npm to avoid installing packages that were published less than 7 days ago. This gives the ecosystem time to catch compromised releases before they land on your machine."
If pnpm is installed (pnpm --version succeeds):
.npmrc also contains:
minimum-release-age=7d
Only add this key if it is not already present.If Yarn 4 is installed (yarn -v) and a .yarnrc.yml file is present (user or project level):
npmMinimalAgeGate: "7d"
Only set this if npmMinimalAgeGate is not yet defined.bun remains the primary package manager for installs and scaffolding. It does not use min-release-age directly, but keeping npm’s age gate in place ensures any fallback npm install obeys the same safety window.
If uv is installed (uv --version) and ~/.config/uv/uv.toml exists, append a commented block describing a similar option for PyPI packages:
# [install]
# minimumReleaseAge = "7d" # uncomment to avoid PyPI packages younger than 7 days
Do not enable this by default; reserve it for paranoid mode (see security-guardian).
If the user explicitly asks for "maximum security", "paranoid mode", or similar:
npm ci --ignore-scripts / pnpm equivalents in CI workflows where feasible.[!IMPORTANT] Do not stop after Step 8. New users will not know what to do next. This step bridges the gap between global setup and their first project.
Tell the user:
"Now let's create your first project folder. This is where your first project will be built.
‼️ You should not build inside this setup folder. ‼️
So let's create a new one and I will guide you.
What would you like to name your project?
You can either:
- Give me a name directly (e.g.,
my-portfolio,ai-chat-app)- Or describe what you want to do for your next project in a few sentences and I'll pick a good name for you"
Wait for the user's response. If they describe what they're building, generate a lowercase, hyphenated folder name from their description (e.g., "I want to build a recipe sharing app" becomes recipe-share).
[!CAUTION] Extension activation guardrail: If the user's response mentions an extension or tool name (NotebookLM, Cloudflare, Firecrawl, etc.), do NOT activate the extension. Treat their response purely as a project description and generate a folder name from it. Example: "I want to do notebookLM research" -> folder name:
notebooklm-research. Extensions are set up AFTER the user opens their new project folder - never inside the Liftoff source directory. The idea here is only to understand what the user wants generate a folder name from it.
Always use ~/dev/ as the parent directory. This is a hard convention - all projects live in ~/dev/. Create it if it doesn't exist.
macOS/Linux:
mkdir -p ~/dev/<project-name>
Windows (PowerShell):
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\dev\<project-name>"
Before showing the closing message, delete the progress tracker:
rm -f ~/.gemini/setup/setup-progress.md
After creating, tell the user:
"We are ready for take-off ⚡️! Instead of moving on foot, you now have a rocket 🚀
Sami says hi 👋 😊 and congratulations 🎉 - you just unlocked what 99% of builders don't have. This is your unfair but totally fair advantage 😉 you will see once you start using Antigravity.
‼️ A note from Sami: Keep all your projects inside
~/dev/- that's the convention for everything going forward. And once a folder is created, never rename it - renaming breaks git remotes, symlinks, and cached paths. If you want a different name, create a new project from scratch. Don't worry - your agent will also know all of this automatically!👉 Now, to start building, open your new project folder:
Step 1: In Antigravity at the top, find File > Open Folder (or use Cmd+O on Mac / Ctrl+O on Windows) Step 2: Navigate to
~/dev/<project-name>/and open it (If a dialog asks to save changes, click Don't Save - the setup is already done) Step 3: In the new window, say the word liftoff👋🏼 Important: Don't say liftoff here - you need to be in your new project folder first! Follow the steps above."
The agent in the new window will detect an empty, un-initialized project folder (no .gemini/ directory) and should automatically run the init-project workflow. The user saying "liftoff" confirms this, but even if they say something else, the auto-detection should trigger. See the Session Start rules in the liftoff-lifecycle skill and the "Liftoff" rule for details.
The agent should use the correct commands based on what was noted:
| Action | brew (macOS) | winget (Windows) | apt (Linux) |
|---|---|---|---|
| Install | brew install <pkg> | winget install <pkg> | sudo apt install <pkg> |
| Update all | brew upgrade | winget upgrade --all | sudo apt update && sudo apt upgrade |
| Search | brew search <pkg> | winget search <pkg> | apt search <pkg> |
| Uninstall | brew uninstall <pkg> | winget uninstall <pkg> | sudo apt remove <pkg> |
| Health check | brew doctor | n/a | sudo apt --fix-broken install |
"brew: command not found" after install: Shell env not loaded. Run the Step 2 shell env commands, then restart terminal.
brew exists but permission denied: Multi-user Mac. Do not fix permissions. Note Package Manager: unavailable and use curl/direct-download for all tools.
"winget is not recognized": Windows version too old (pre-10) or App Installer not installed. Direct user to Microsoft Store to install "App Installer".
"error: could not find cl.exe" or "node-gyp rebuild failed" on Windows: Visual C++ Build Tools are missing. Run: winget install Microsoft.VisualStudio.2022.BuildTools --override "--quiet --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended" and restart the terminal.
"python is not recognized" on Windows: Python is not installed. Run: winget install Python.Python.3.12 and restart the terminal.
Visual C++ Build Tools install hangs or fails: The download is large (~2-4 GB). Ensure the user has a stable internet connection. If winget fails, direct the user to https://visualstudio.microsoft.com/visual-cpp-build-tools/ for manual download.
"gh: command not found" after install: Restart terminal or run eval "$(/opt/homebrew/bin/brew shellenv)" on macOS.
Permission denied on any OS: Corporate/managed machine. Note unavailable in Machine Environment and move on. The agent will provide manual download links instead of package manager commands.
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer