fix(#3738): antigravity global skills/agents install to ~/.gemini/config (#3921)

* test(#3738): antigravity global skills/agents must resolve under ~/.gemini/config

Regression tests (RED first): --skills-root and gsd-tools query surfaces,
install-plan dest dirs, and converter skills-path rewrite.

* fix(#3738): antigravity global skills/agents install to ~/.gemini/config

Antigravity's machine-local discovery scans ~/.gemini/config/{skills,agents};
the configHome (~/.gemini/antigravity) is deprecated for artifacts. Declare the
ADR-1239 skills/agents 'home' override on the antigravity global layout — the
same mechanism codex uses (.agents) — and divert ~/.claude/skills/ references
in converted global content to ~/.gemini/config/skills/. configHome, settings,
probe/migration semantics, and the local .agents layout are unchanged.

* fix(#3738): retire deprecated configHome artifacts via installer migration 010

Next install converges an existing antigravity install: manifest-managed
skills/gsd-*/ and agents/gsd-*.md under the configHome (a location AGY does
not scan) are removed — modified files backed up first, unmanifested and
non-gsd entries preserved — and now-empty containers retired. Global scope
only; the local .agents surface is live. Docs + inventory updated.

* fix(#3738): converter sync in bin/install.js, harness emit-root coverage, migration baseline

- bin/install.js converter gains the same ~/.claude/skills → ~/.gemini/config/
  rewrite as src (ADR-1508 dual copy must stay in sync).
- Parity-manifest walk covers home-override emit roots (extraEmitRootsFor) so
  antigravity's emitted skills/agents stay differential-visible at their new
  install root; install-tree fixture regen confirms an unchanged key set.
- skills-from-commands rule declares the antigravity converter as a
  runtime-scoped transform; one ack fragment covers the identity-classed
  workflow whose antigravity copy embeds the old skills path.
- Migration 010 checksum baseline + home-override set doc updated; existing
  tests updated to the #3738 contract (global dest, golden parity via layout
  dest, integration expectations).

* fix(#3738): tolerate an absent extra emit root on baseline-side measurement

The base tree's installer predates the home override, so <HOME>/.gemini/config
does not exist there; walk() threw ENOENT and the in-job baseline build failed.
An absent extra root is the legitimate pre-override shape — skip it.

* fix(#3738): review findings — manifest agents root, bare skills-path rewrite, guard comment

- writeManifest resolves the agents-kind home override (_kindDestDirSafe), so
  the manifest records agents at their actual install root and drift detection
  keeps working (isolated review finding 1, major).
- Converter bare forms ~/.claude/skills and $HOME/.claude/skills (no trailing
  slash) divert to ~/.gemini/config/skills instead of falling through to the
  retired configHome path (finding 2).
- real-home-guard comment updated: antigravity's global agents kind is the
  first agents-kind home override (finding 3, doc-only).
- Regression tests for both behavioral findings.

* chore(#3738): changeset fragment (pr number backfilled after PR creation)

* chore(#3738): backfill changeset PR number (3921)

* fix(#3738): sandbox HOME in tests that install antigravity global artifacts

antigravity is the first home-override runtime in the golden-parity and
skills-wrapper suites (codex is not in their runtime lists), so those tests
never needed HOME sandboxing — the real-home guard now (correctly) refuses
their un-sandboxed global installs on CI, where HOME is the passwd home.

* fix(#3738): stop the K3 sequential-sandbox env leak; sandbox L2's home-override plans

K3's two back-to-back sandboxHome calls leave HOME pointing at the first
sandbox once the after-hooks restore (each call saves the env as it found
it, so the second saves the first's sandbox as 'original'). On the windows
matrix that leaked gsd-k3-qwen-* home into the L2 property, whose
antigravity/global run then (correctly) refused via the #3712 real-home
guard — antigravity is the runtime that made L2's plan escape into
os.homedir(). K3 now manages the env with a single restore; L2 sandboxes
HOME per run, mirroring L1.

* fix(#3738): L2 property's HOME sandbox must exist on disk

The #3712 guard's sandbox exemption fails closed when identify(effectiveHome)
is 'absent' — L2 never created its configDir, so on the windows matrix (tmpdir
under the real home) the antigravity/global run refused even with HOME
sandboxed. Create the per-run sandbox dir and clean it up.

---------

Co-authored-by: sim <sim@local>
This commit is contained in:
Tom Boucher
2026-08-27 02:24:03 -04:00
committed by GitHub
parent e20744eacb
commit 39673ae9ff
29 changed files with 936 additions and 55 deletions

View File

@@ -688,7 +688,7 @@ Equivalent paths for other runtimes:
- **Kimi CLI:** first-existing generic global root (`~/.config/agents/` recommended, then `~/.agents/` if its `skills/` directory already exists); local install is deferred and guarded
- **Codex:** `~/.codex/` global or `./.codex/` local
- **Copilot:** `~/.copilot/` global or `./.github/` local
- **Antigravity:** auto-detected global root (`~/.gemini/antigravity/`, `~/.gemini/antigravity-ide/`, or `~/.gemini/antigravity-cli/`) or `./.agent/` local
- **Antigravity:** auto-detected global root (`~/.gemini/antigravity/`, `~/.gemini/antigravity-ide/`, or `~/.gemini/antigravity-cli/`) for settings and runtime files; global skills/agents under `~/.gemini/config/` (the machine-local discovery dir, #3738) or `./.agent/` local
- **Cursor:** `~/.cursor/` global or `./.cursor/` local
- **Windsurf/Devin Desktop:** `~/.codeium/windsurf/` global config or `./.windsurf/` local workflows
- **Augment Code:** `~/.augment/` global or `./.augment/` local
@@ -952,7 +952,7 @@ The migration-specific ownership and source snapshots live in
| Kimi CLI | First-existing generic root: `~/.config/agents` recommended, then `~/.agents` when `~/.agents/skills` exists and `~/.config/agents/skills` does not | Deferred and guarded | `skills/gsd-*/SKILL.md` (flat) invoked as `/skill:gsd-*` | `agents/gsd.yaml`, `agents/gsd.md`, and `agents/subagents/gsd-*` YAML/prompt pairs | Explicit `kimi --agent-file <configRoot>/agents/gsd.yaml`; no GSD hooks or statusline |
| Codex | `~/.codex` | `./.codex` | `skills/gsd-*/SKILL.md` (flat) | `agents/` source markdown plus per-agent TOML (Codex auto-discovers each `agents/gsd-*.toml`; this is the sole canonical role registration, #2406) | `config.toml` bare `[agents]` dispatch-tuning scalar (`max_depth`, no per-role `[agents.gsd-*]` tables), `[features].hooks` (canonical; legacy alias `codex_hooks` is recognized and migrated forward on reinstall, #3566), and hook tables |
| GitHub Copilot | `~/.copilot` | `./.github` | `skills/gsd-*/SKILL.md` (flat), `copilot-instructions.md`, and `AGENTS.md` (repo root, local) | `.agent.md` files | Self-contained `sessionStart` hook (`hooks/gsd-session.json`, inline `command` type); no statusline |
| Antigravity | auto-detected: `~/.gemini/antigravity`, `~/.gemini/antigravity-ide`, or `~/.gemini/antigravity-cli` | `./.agent` | `skills/gsd-*/SKILL.md` (flat, #1614) | `agents/gsd-*.md` | Gemini-style `settings.json` hook entries when installed by GSD |
| Antigravity | auto-detected: `~/.gemini/antigravity`, `~/.gemini/antigravity-ide`, or `~/.gemini/antigravity-cli` | `./.agent` | `~/.gemini/config/skills/gsd-*/SKILL.md` (flat, #1614; global home override #3738) | `~/.gemini/config/agents/gsd-*.md` (#3738) | Gemini-style `settings.json` hook entries when installed by GSD |
| Cursor | `~/.cursor` | `./.cursor` | `skills/gsd-*/SKILL.md` (flat) | `agents/gsd-*.md` | Rule references under `rules/`; `hooks.json` with sessionStart context injection and postToolUse STATE.md monitor (#777) |
| Windsurf | `~/.codeium/windsurf` config | `./.windsurf` | `workflows/gsd-*.md` slash-command workflows | No custom-agent artifact surface | No GSD hooks |
| Augment Code | `~/.augment` | `./.augment` | `skills/gsd-ns-*/SKILL.md` (6 routers) + `skills/gsd-ns-*/skills/<name>/SKILL.md` (nested concretes) | `agents/gsd-*.md` | No GSD hooks or statusline |

View File

@@ -425,6 +425,7 @@
"installer-migrations/007-retire-config-root-commonjs-marker.cjs",
"installer-migrations/008-cursor-retire-commands-surface.cjs",
"installer-migrations/009-pi-retire-reserved-hooks-dir.cjs",
"installer-migrations/010-antigravity-retire-confighome-artifacts.cjs",
"intel-command-router.cjs",
"intel.cjs",
"io.cjs",

View File

@@ -453,6 +453,7 @@ Full listing: `gsd-core/bin/lib/*.cjs`.
| `installer-migrations/007-retire-config-root-commonjs-marker.cjs` | Installer migration: retires the config-root `{"type":"commonjs"}` marker that pre-#2544 installs wrote over `<configRoot>/package.json` |
| `installer-migrations/008-cursor-retire-commands-surface.cjs` | Installer migration: retires Cursor's duplicate `commands/` surface now that skills are the sole workflow surface (#2644) |
| `installer-migrations/009-pi-retire-reserved-hooks-dir.cjs` | Installer migration: retires pi's legacy `hooks/` directory after GSD's shared hook bundle moved to `gsd-hooks/` (#3023) |
| `installer-migrations/010-antigravity-retire-confighome-artifacts.cjs` | Installer migration: retires Antigravity's configHome `skills/`/`agents/` surfaces after the global layout moved to the `~/.gemini/config` home override (#3738) |
| `active-workstream-store.cjs` | Workstream source precedence and selection (CLI `--ws` > `GSD_WORKSTREAM` env > stored pointer); name validation and environment propagation |
| `adapter-declarative.cjs` | Declarative host-integration adapter — projects workflow artifacts through the install engine for hosts that declare a descriptor-driven surface (#1680) |
| `adapter-imperative.cjs` | Imperative host-integration adapter — binds the composed capability registry in-process for hosts that drive emission themselves (#1680) |

View File

@@ -439,7 +439,7 @@ Skills land in `~/.augment/skills/` and slash command definitions land in `~/.au
npx @opengsd/gsd-core@latest --antigravity --global
```
The installer auto-detects the Antigravity config directory (`~/.gemini/antigravity`, `~/.gemini/antigravity-ide`, or `~/.gemini/antigravity-cli`). Uses Gemini-compatible settings policy.
The installer auto-detects the Antigravity config directory (`~/.gemini/antigravity`, `~/.gemini/antigravity-ide`, or `~/.gemini/antigravity-cli`). Uses Gemini-compatible settings policy. Global skills and agents install under `~/.gemini/config/skills/` and `~/.gemini/config/agents/` — the directories Antigravity scans for machine-local discovery (#3738); the config directory above holds settings and GSD's runtime files.
**Override the install directory:**

View File

@@ -443,7 +443,7 @@ for the new shape before changing migration behavior.
| Kimi CLI | Agent Skills in `skills/gsd-*/SKILL.md`; explicit custom agent YAML/prompt artifacts in `agents/gsd.yaml`, `agents/gsd.md`, and `agents/subagents/gsd-*`; `gsd-core/` payload files referenced by generated skills; manifest, pristine, local-patch, and migration journal files from the normal installer safety pipeline | Global `KIMI_CONFIG_DIR`, explicit `--config-dir`, or first-existing generic skills root: `~/.config/agents` when `~/.config/agents/skills` exists or no generic skills root exists yet, otherwise `~/.agents` when `~/.agents/skills` exists and `~/.config/agents/skills` does not; `KIMI_CONFIG_DIR` and `--config-dir` are GSD write-location overrides and arbitrary roots require Kimi-side `--skills-dir` or `extra_skill_dirs` configuration for skill discovery; local `--kimi --local` is guarded and writes no project-level artifacts | GSD owns only generated `skills/gsd-*`, `agents/gsd.*`, `agents/subagents/gsd-*`, installed `gsd-core/` payload files, and manifest/preservation/migration records. GSD does not own Kimi config files, hooks, settings, rules, statusline, update-banner registration, or non-GSD Kimi skills/agents. Reinstall/update must preserve locally modified generated Kimi artifacts through manifest-backed `gsd-local-patches/`; uninstall removes only GSD-owned Kimi artifacts and preserves non-GSD user content. | [Agent Skills](https://moonshotai.github.io/kimi-cli/en/customization/skills.html), [Agents and Subagents](https://moonshotai.github.io/kimi-cli/en/customization/agents.html), [Tools](https://moonshotai.github.io/kimi-code/en/reference/tools.html); docs checked 2026-06-07 |
| Codex | Skills in `skills/gsd-*/SKILL.md`; agents as source markdown plus per-agent TOML in `agents/` (Codex auto-discovers each standalone `agents/gsd-*.toml` — that is the sole role-registration source, #2406); bare `[agents]` dispatch-tuning scalar and hooks in `config.toml` | Global `CODEX_HOME` or `~/.codex`; local `./.codex` | GSD owns generated skills, generated agent TOML, the managed bare `[agents]` scalar table (`max_depth`; no `[agents.gsd-*]` role sections — those were a duplicate registration removed in #2406), `[features].hooks` when added by GSD (canonical; legacy alias `codex_hooks` is recognized and migrated forward, #3566), and GSD hook entries | [Codex config schema](https://developers.openai.com/codex/config-schema.json), [Codex developer docs](https://developers.openai.com/codex/); docs not versioned, checked 2026-05-15; installer compatibility sentinel: Codex 0.130.0 features.hooks key (legacy `codex_hooks` recognized) |
| GitHub Copilot | Skills in `skills/gsd-*/SKILL.md`; agents as `.agent.md`; repository instructions in `copilot-instructions.md` | Global `COPILOT_CONFIG_DIR`, `COPILOT_HOME`, or `~/.copilot`; local `./.github` | GSD owns generated skill/agent files and GSD-authored instruction files; no hook/statusline ownership | [Repository custom instructions](https://docs.github.com/en/copilot/how-tos/configure-custom-instructions/add-repository-instructions), [Copilot CLI custom instructions](https://docs.github.com/en/copilot/how-tos/copilot-cli/add-custom-instructions); GitHub Docs product docs, checked 2026-05-11 |
| Antigravity | Skills in `skills/gsd-*/SKILL.md`; agents in `agents/`; Gemini-style `settings.json` hooks when installed by GSD | Global `ANTIGRAVITY_CONFIG_DIR` or `~/.gemini/antigravity`; local `./.agents` (canonical, #791) or `./.agent` (legacy, recognized for backward-compat) | GSD owns generated skills/agents/hooks and GSD settings entries only | Public Antigravity install/config docs for this file layout were not stable or complete as of 2026-05-11; installer compatibility therefore uses GSD's Gemini-compatible settings policy, documented shim baseline. Fresh installs write to `.agents/` (the Google-Codelabs-documented form); existing `.agent/` installs continue to be detected and served. |
| Antigravity | Global skills in `~/.gemini/config/skills/gsd-*/SKILL.md` and agents in `~/.gemini/config/agents/` (the machine-local discovery dir, #3738; pre-#3738 installs wrote them under the configHome and migration 010 retires that spot); Gemini-style `settings.json` hooks at the configHome when installed by GSD | Global `ANTIGRAVITY_CONFIG_DIR` or `~/.gemini/antigravity`; local `./.agents` (canonical, #791) or `./.agent` (legacy, recognized for backward-compat) | GSD owns generated skills/agents/hooks and GSD settings entries only | Public Antigravity install/config docs for this file layout were not stable or complete as of 2026-05-11; installer compatibility therefore uses GSD's Gemini-compatible settings policy, documented shim baseline. Fresh installs write to `.agents/` (the Google-Codelabs-documented form); existing `.agent/` installs continue to be detected and served. |
| Cursor | Skills in `skills/gsd-*/SKILL.md`; agents in `agents/`; rule references under `rules/`; lifecycle hooks via `hooks.json` (sessionStart + postToolUse, #777) | Global `CURSOR_CONFIG_DIR` or `~/.cursor`; local `./.cursor` | GSD owns generated skills/agents, GSD rule files or references, and GSD-managed `hooks.json` entries (sentinel `gsd-managed:true`); no statusline ownership | [Cursor rules](https://docs.cursor.com/context/rules); [Cursor hooks](https://docs.cursor.com/context/hooks); docs not versioned, checked 2026-06-07 |
| Windsurf / Devin Desktop | Local slash-command workflows in `workflows/gsd-*.md`; no custom-agent artifact surface | Local workflow directory `./.windsurf/workflows`; global workflow install is intentionally a no-op | GSD owns generated local workflow files only; no hook/statusline ownership | Windsurf workflows are the documented `/` command surface. Workspace workflows live under `.windsurf/workflows/*.md`; global workflow locations are outside GSD's normal user-owned runtime config directory and are not written by the GSD installer. |
| Augment Code | Skills in `skills/gsd-*/SKILL.md`; agents in `agents/` | Global `AUGMENT_CONFIG_DIR` or `~/.augment`; local `./.augment` | GSD owns generated skills/agents only; no hook/statusline ownership | [Augment Agent Skills](https://docs.augmentcode.com/cli/skills), [Augment IDE skills](https://docs.augmentcode.com/using-augment/skills); IDE skills public beta in VS Code 0.789.0+, checked 2026-05-11 |
@@ -580,6 +580,7 @@ Each row corresponds to one migration record in `src/installer-migrations/`.
| `2026-07-28-retire-config-root-commonjs-marker` | `007-retire-config-root-commonjs-marker.cts` | 1.8.0 | global, local | Yes | Removes `<configRoot>/package.json` when it is exactly the `{"type":"commonjs"}` marker pre-#2544 installs wrote there. #2544 moved that marker into the directories GSD fills (`hooks/`, and the native plugin dir), so an upgraded install would otherwise keep both and stay pinned to CommonJS at a config root GSD no longer writes. Ownership is proven by exact content match, not the manifest (the marker was never manifest-recorded) — a `package.json` with any other content is left untouched, with no backup-and-remove branch. All runtimes; kimi's root marker lives outside `configDir` and is retired by the installer instead. |
| `2026-07-29-cursor-retire-commands-surface` | `008-cursor-retire-commands-surface.cts` | 1.8.1 | global, local | Yes | Removes manifest-managed `commands/gsd-*.md` files from Cursor installs. Cursor already exposes the corresponding skills in the slash menu and to contextual model invocation, so the command copies produced duplicate entries (#2644). Modified files are backed up; unmanifested files are preserved. |
| `2026-08-07-pi-retire-reserved-hooks-dir` | `009-pi-retire-reserved-hooks-dir.cts` | 1.9.2 | global, local | Yes | Removes manifest-managed files under pi's legacy `hooks/` directory and, once empty, the directory itself (and `hooks/lib/`), now that the shared hook bundle installs at `gsd-hooks/` instead. pi's `checkDeprecatedExtensionDirs()` warns on `hooks/`'s mere existence, not its contents, so an emptied shell would keep warning forever without the new `remove-empty-dir` action (#3023). Modified files are backed up; unmanifested files are preserved and keep the directory alive. pi only. |
| `2026-08-26-antigravity-retire-confighome-artifacts` | `010-antigravity-retire-confighome-artifacts.cts` | 1.11.0 | global | Yes | Removes manifest-managed `skills/gsd-*/` and `agents/gsd-*.md` under the Antigravity configHome (`~/.gemini/antigravity{,-ide,-cli}`) and, once empty, the container directories. Antigravity's machine-local discovery scans `~/.gemini/config/{skills,agents}` and does not scan the configHome, so pre-#3738 artifacts were silently ignored; since #3738 the global layout installs both kinds under the `.gemini/config` home override. Modified files are backed up; unmanifested and non-`gsd-` files are preserved and keep their directory alive. Global scope only — the local `.agents` workspace surface is live. Antigravity only. |
## Prior Art