v1.92.22.0 feat: Gemini CLI host, and older installs drop the dev toolchain (#3778)

* setup: explicit contributor marker; move pre-v1.91.231.0 installs to production deps (#3447)

./setup used node_modules/typescript as its contributor signal, so every
install made before v1.91.231.0 (a full bun install) kept ~520 MB of test and
eval packages forever. The contributor is now the clone bin/dev-setup marks
with git config gstack.contributor true, or GSTACK_CONTRIBUTOR=1. An unmarked
clone with the dev toolchain moves node_modules aside under a checkout lock,
installs production-only, verifies every dependency, and drops the backup; any
failure puts the full install back with SETUP_DEPS_MIGRATE_FAILED. CI and a
clone whose git config cannot be read never migrate. Bun cache entries for the
pinned Agent SDK are removed only when no other project links to them.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* hosts: add Gemini CLI as an experimental host (#1247)

./setup --host gemini (alias gemini-cli; --host auto when gemini is on PATH)
installs gstack-<skill> directories into ~/.gemini/skills, which Gemini CLI
0.66.0 lists with gemini skills list, plus the ~/.gemini/skills/gstack runtime
root. Renders go to .gemini-cli/ (gitignored) with name+description
frontmatter whose names match their directories, CLAUDE.md rewritten to
GEMINI.md, and a tool glossary for Gemini CLI's names (and Antigravity's, which
can read the same folder). gstack-uninstall removes only gstack-managed entries
there, so the user's own skills stay. Docs: ADDING_A_HOST.md verified facts,
hosts.md, uninstall.md, README.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix: pre-landing review fixes (leave Bun's shared cache alone)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* changelog: Gemini CLI host and contributor marker (#1247, #3447)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs: host lists name Copilot, Antigravity and Gemini CLI

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* test: the plan-mode re-render guard count includes the Gemini CLI host

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs: troubleshooting's runtime-root guard host list names Gemini CLI

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
Garry Tanandcapy-ai[bot] authored and GitHub committed 2026-11-01 09:35:42 +00:00
1 parent c03f185d15
commit e4e4e42967
34 files changed
+910 -74

No files matched your search

+53 -9
View File
@@ -2,7 +2,7 @@
gstack uses a declarative host config system. Each supported AI coding agent
(Claude, Codex, Factory, Kiro, OpenCode, Slate, Cursor, OpenClaw, Hermes,
GBrain, Copilot, Antigravity) is defined as a typed TypeScript config object built by the
GBrain, Copilot, Antigravity, Gemini CLI) is defined as a typed TypeScript config object built by the
`defineHost()` factory. Rendering a new host means creating one file and
re-exporting it: the generator, tests, and validation pick it up. Installing
it is not free: setup still has one install arm per installable host (see
@@ -76,13 +76,13 @@ Inventory of every setup side effect, by phase (line numbers are approximate):
|---|---|---|
| Build | `browse/dist`, `design/dist`, `make-pdf/dist`, `bin/gstack-cso-*` in the source checkout | source |
| Hosts record | `.gstack-installed-hosts` in the source checkout: every host setup installed from it, additive (#1694) | source |
| Generation | renders for the recorded hosts only (`.agents/`, `.kiro/`, `.factory/`, `.opencode/`, `.cursor/`, `.copilot/`, `.agy/`) in the source checkout; `gstack-patch-names` rewrites Claude `name:` fields in place | source |
| Generation | renders for the recorded hosts only (`.agents/`, `.kiro/`, `.factory/`, `.opencode/`, `.cursor/`, `.copilot/`, `.agy/`, `.gemini-cli/`) in the source checkout; `gstack-patch-names` rewrites Claude `name:` fields in place | source |
| Render prune | renders of hosts the record does not name: links into the checkout removed, generated files moved to `$GSTACK_STATE_ROOT/backups/host-renders/<ts>-<id>/`, other files kept | source / state root |
| Chromium | Playwright cache (`~/.cache/ms-playwright`), lock under the state root | machine |
| Config | `skill_prefix`, `timeline_stop_hook`, team-mode keys in `$GSTACK_STATE_ROOT/config.yaml` | state root |
| Claude arm | `~/.claude/skills/gstack` link, one dir per skill with a `SKILL.md` link, alias copies | selected host |
| Codex arm | `${CODEX_HOME:-~/.codex}/skills/gstack` runtime root, `gstack-*` links into `.agents/skills`, `.agents/skills/gstack` sidecar | selected host |
| Kiro, Factory, OpenCode, Cursor, Copilot, Antigravity arms | the host's `skills/gstack` runtime root (built beside the live one and swapped in) and `gstack-*` links | selected host |
| Kiro, Factory, OpenCode, Cursor, Copilot, Antigravity, Gemini CLI arms | the host's `skills/gstack` runtime root (built beside the live one and swapped in) and `gstack-*` links | selected host |
| OpenCode commands | `~/.config/opencode/commands/gstack-*.md` with a managed marker (#2629); user command files are never touched | selected host |
| Registry | one row per activated install in `installs.tsv` | state root |
| Migrations | whatever each `v*.sh` repairs; marker in the state root | state root |
@@ -245,12 +245,15 @@ which Google's docs do not state, so the rendered text names no number.
**Shared `~/.gemini`.** Antigravity CLI and Gemini CLI both live under
`~/.gemini`. Gemini CLI reads `~/.gemini/skills` (and `~/.agents/skills`);
Antigravity CLI reads `~/.gemini/antigravity-cli/skills`. Setup writes only
gstack entries in the latter, uninstall removes only gstack-managed entries
there, and `--host auto` selects Antigravity only for `agy` on `PATH` or an
existing `~/.gemini/antigravity-cli`, never for a bare `~/.gemini`.
`test/setup-install-registry.test.ts` holds both directions. Gemini CLI as a
host is not supported. Two overlaps remain: workspace `.agents/skills` is also
Antigravity CLI reads `~/.gemini/antigravity-cli/skills`, and Google's
migration table lists `~/.gemini/skills` as an Antigravity global path too.
Each host's arm writes only gstack entries in its own directory, uninstall
removes only gstack-managed entries in each, and `--host auto` selects
Antigravity only for `agy` on `PATH` or an existing
`~/.gemini/antigravity-cli`, and Gemini CLI only for `gemini` on `PATH`,
never either for a bare `~/.gemini`. `test/setup-install-registry.test.ts`
holds every direction, including both hosts installed together. Gemini CLI is
its own host ("Gemini CLI" below). Two overlaps remain: workspace `.agents/skills` is also
where a project-local Codex install puts its Codex-flavored `gstack-*`
skills, which Antigravity will list in that repo, and the Antigravity 2.0 app
and IDE read `~/.gemini/config/skills`, which this host does not install
@@ -277,6 +280,46 @@ root's extra markdown files (`ETHOS.md`, `review/*.md`) as skills, the
partial-read behavior of `view_file` on long skills, `ask_question` option
handling, and an upgrade from an existing install.
## Gemini CLI (#1247)
Shipped as `experimental` (`hosts/gemini.ts`, `./setup --host gemini`, alias
`--host gemini-cli`). Verified against Gemini CLI 0.66.0 (its bundled
`docs/cli/skills.md` and `SkillManager.discoverSkills`) on 2026-10-31:
| Fact | Value | Source |
|---|---|---|
| User skills | `~/.gemini/skills/<skill>/SKILL.md`, and the `~/.agents/skills` alias, which wins inside the user tier | [Agent Skills](https://geminicli.com/docs/cli/skills/), `packages/core/src/skills/skillManager.ts` |
| Workspace skills | `.gemini/skills` and the `.agents/skills` alias, loaded only in a trusted folder (`/trust`) | same |
| Precedence | built-in < extension < user < workspace; same name: the higher tier wins | same |
| Discovery | `<dir>/<name>/SKILL.md`, one level deep; symlinked skill dirs are followed; the name comes from frontmatter `name` | same |
| Invocation | the model calls `activate_skill` after you approve; `/skills list` and `gemini skills list` show them | same |
| Tool names | `run_shell_command`, `read_file`, `read_many_files`, `write_file`, `replace`, `grep_search`, `glob`, `list_directory`, `ask_user`, `invoke_agent`, `activate_skill`, `enter_plan_mode`, `exit_plan_mode`, `write_todos`, `web_fetch`, `google_web_search` | 0.66.0 bundle |
| Context file | `GEMINI.md` | 0.66.0 bundle |
What the host does: skills in `~/.gemini/skills/gstack-*`, runtime root
`~/.gemini/skills/gstack` with `.source-path` for `/gstack-upgrade`, `name:`
equal to the `gstack-<skill>` directory, frontmatter limited to `name` and
`description` (1024-character limit), the Gemini model overlay, and a
one-paragraph tool glossary ahead of the preamble's STATUS rules. The glossary
also names Antigravity's `run_command`, `view_file` and `ask_question`,
because an Antigravity CLI that reads `~/.gemini/skills` sees these skills.
The render directory is `.gemini-cli/` (gitignored), not `.gemini/`, so this
repo's own trusted workspace never lists render output as skills. `--local`
is refused: it installs only Claude, and Gemini CLI reads workspace skills only
in trusted folders.
Overlaps: inside a trusted repo, a project-local Codex install's `.agents/skills`
(Codex-flavored `gstack-*` skills) is the workspace tier, which outranks
`~/.gemini/skills`, so Gemini CLI uses those there. gstack never writes
`~/.agents/skills`: that alias is shared with other tools and outranks
`~/.gemini/skills`. Antigravity's own install stays in
`~/.gemini/antigravity-cli/skills`.
Unverified without a Gemini API key on the build machines (why it is not
`full`): a live model run of any skill, `ask_user` option handling, and
plan mode with gstack's plan-review skills. Discovery is verified:
`gemini skills list` after `./setup --host gemini` lists the `gstack-*` skills.
## Instruction-only hosts and agent harnesses
Slate and GBrain have no install arm. OpenClaw and Hermes are harness hosts:
@@ -313,6 +356,7 @@ hosts/
├── gbrain.ts # GBrain
├── copilot.ts # GitHub Copilot CLI
├── agy.ts # Google Antigravity CLI
├── gemini.ts # Google Gemini CLI
└── index.ts # Registry: imports all, derives Host type
```
+1
View File
@@ -20,6 +20,7 @@ gstack/
│ ├── codex.ts, factory.ts, kiro.ts # Existing hosts
│ ├── opencode.ts, slate.ts, cursor.ts, openclaw.ts # IDE hosts
│ ├── hermes.ts, gbrain.ts # Agent runtime hosts
│ ├── copilot.ts, agy.ts, gemini.ts # GitHub Copilot CLI, Antigravity CLI, Gemini CLI
│ └── index.ts # Registry: exports all, derives Host type
├── scripts/ # Build + DX tooling
│ ├── gen-skill-docs.ts # Template → SKILL.md generator (config-driven)
+8
View File
@@ -137,6 +137,14 @@ Antigravity only when `agy` is on `PATH` or `~/.gemini/antigravity-cli` exists,
never for a Gemini-CLI-only `~/.gemini`. The Antigravity 2.0 app and IDE read
`~/.gemini/config/skills`, which this host does not install.
Gemini CLI loads gstack skills itself when a task matches (`activate_skill`,
after you approve); ask for `gstack-office-hours`, or list them with
`/skills list`. Setup writes only `~/.gemini/skills/gstack*` and never
`~/.agents/skills`, and `--host auto` selects Gemini CLI only when `gemini` is on
`PATH`. Inside a repo with a project-local Codex install, Gemini CLI uses the
Codex skills in `.agents/skills` (the workspace tier wins), and workspace skills
load only in trusted folders (`/trust`).
Outside reviews require the selected CLI to be installed and authenticated: Claude Code when using gstack in Codex, or Codex on other harnesses. External harnesses discover these commands as `/gstack-claude-code` and `/gstack-codex`; each harness omits its own wrapper. Explicit provider requests keep that provider. The existing `codex_reviews` setting controls automatic outside reviews where supported, regardless of the provider selected.
`/claude` has been renamed to `/claude-code`. Re-run `./setup --host <name>` to migrate managed installations, including other harnesses sharing the checkout. Setup preserves the previous installation if replacement generation or installation fails and prints repair instructions.
+21 -2
View File
@@ -1239,8 +1239,8 @@ git -C ~/.claude/skills/gstack update-ref -d 'refs/gstack/rescue/<oid>'
<a id="setup-runtime-root-contains-checkout"></a>
### `gstack setup: refusing to replace <root> for <host>: this runtime directory contains the source checkout setup runs from (<checkout>), so replacing it would delete the checkout. Nothing was changed.`
**Meaning.** Setup installs Codex, Factory, OpenCode, Cursor, Copilot and
Antigravity by building a runtime root (such as `~/.cursor/skills/gstack`) and
**Meaning.** Setup installs Codex, Factory, OpenCode, Cursor, Copilot,
Antigravity and Gemini CLI by building a runtime root (such as `~/.cursor/skills/gstack`) and
swapping it in for the old one, and Kiro by writing into `~/.kiro/skills/gstack`.
Your gstack checkout lives at that root or inside it, so the swap would delete
the checkout (#3084), and Kiro would link the checkout into itself. Setup refuses before
@@ -2206,6 +2206,25 @@ anything.
---
<a id="setup-deps-migrate-failed"></a>
### `gstack: WARN kept the full dependency install (SETUP_DEPS_MIGRATE_FAILED; ...): <cause>`
**Meaning.** Your install was made before v1.91.231.0, so it still carries the
test and eval packages (about 520 MB, mostly the Claude Agent SDK). setup moved
`node_modules` aside to install production dependencies only, that install
failed, and setup put the full `node_modules` back. Nothing was removed, and
gstack keeps working on the full install.
**Fix.** Fix the cause the warning names (no network, a proxy, a full disk),
then run `./setup` again. Developing gstack in this checkout? Mark it, and
setup keeps the dev packages from then on:
```bash
git config gstack.contributor true
```
---
<a id="chromium-install-exit-127"></a>
### `Chromium bootstrap: chromium-install — <bun> x playwright install chromium exited 127 (command not found); install Bun from bun.sh (winget Bun ships no bunx), or skip with ./setup --no-browser (Git Bash) or .\setup.ps1 --no-browser (PowerShell)`
+1
View File
@@ -54,6 +54,7 @@ rm -rf "${HERMES_HOME:-$HOME/.hermes}/skills/gstack" 2>/dev/null
rm -rf ~/.cursor/skills/gstack* 2>/dev/null
rm -rf ~/.config/opencode/skills/gstack* 2>/dev/null
rm -rf ~/.gemini/antigravity-cli/skills/gstack* 2>/dev/null
rm -rf ~/.gemini/skills/gstack* 2>/dev/null
# 6. Remove temp files
rm -f /tmp/gstack-* 2>/dev/null