#2705

fix(add): let users select Antigravity for global installs

OpenNuttapongPunwants to merge intofrom

Problem

Antigravity and Antigravity CLI cannot be selected in the interactive skills add prompt for a global install.

Both agents use .agents/skills in project scope, so they are treated as universal, and both set showInUniversalPrompt: false. In the prompt they only show up in the locked "Universal (.agents/skills)" section's hidden "…and N more" count. Since #2566 they have globalReadsCanonical: false, so ensureUniversalAgents does not add them to global installs. The result is that a global install from the prompt never reaches ~/.gemini/config/skills. The only way to select them was with -a antigravity / -a antigravity-cli.

There are two ways a user hit this:

  1. skills add <pkg> --global: the global prompt hid them, as described above.
  2. skills add <pkg> without -g: the agent prompt ran in project layout first, and the scope question came afterwards. Choosing Global there could not include Antigravity either.

Fix

1. Global prompt (selectAgentsInteractive). The agents shown as locked and the agents shown as selectable now follow the same rule the installer uses (readsCanonicalGlobally in global scope, isUniversalAgent in project scope; see splitAgentsByType and getAgentBaseDir).

  • Global: universal agents that do not read ~/.agents/skills (today antigravity and antigravity-cli) are listed as normal selectable agents, with their globalSkillsDir as the hint. The locked section and its hidden count now include only agents that read the canonical dir.
  • Project: unchanged, and a test asserts the prompt arguments are identical to before.
  • A remembered Antigravity selection is pre-checked in global mode.

2. Scope before agents. When no scope flag was given and the agent multiselect is about to run, the "Installation scope" question is now asked first, so the prompt matches the chosen scope. This applies to the three callers of selectAgentsInteractive: 2+ detected agents, Eve detected but declined, and well-known sources. The two copies of the scope prompt now share one helper, promptForInstallScope.

  • Unchanged paths: -g, explicit project scope, -y, -a / -a '*', 0 detected agents (flat list, where Antigravity was already selectable), 1 detected agent, and Eve accepted all keep their previous order.
  • Why no extra prompt is added: in the reordered branches the old post-selection scope question was always shown, because the locked universal agents always include agents with a global dir.

User-visible changes

  • In the three flows above, "Installation scope" is now asked before the agent list.
  • With Global chosen first, the agent list is the global one:
    • agents without a global directory are not offered, so the "Skipping X: no global skills directory" notice no longer appears in these flows;
    • hints show global paths;
    • Antigravity and Antigravity CLI are selectable.

selectAgentsInteractive is now exported from src/add.ts for tests. The public API in src/index.ts is unchanged, and so is the tsnapi snapshot.

Tests

  • src/add-prompt.test.ts: covers the project-mode prompt arguments (unchanged), global-mode Antigravity items and the locked section, history pre-selection, and the return/save path.
  • tests/antigravity-global-install.test.ts:
    • a global -y -a install of codex, antigravity and antigravity-cli writes both ~/.agents/skills and ~/.gemini/config/skills;
    • new in-process interactive runAdd tests, with os.homedir mocked to a temp dir. They check that the scope is asked first and that choosing Global lets the user pick Antigravity, for 2+ detected agents, Eve declined, and a well-known source, with the skill landing in ~/.gemini/config/skills. Choosing Project keeps the project prompt.
  • All new global-mode and scope-first tests fail on the previous code.

Local results (node 24, macOS, isolated HOME):

  • vitest run src/add-prompt.test.ts src/add.test.ts tests/antigravity-global-install.test.ts: 94 passed.
  • pnpm type-check, pnpm build (no snapshot change) and pnpm format:check all pass.
  • Full suite: the only failures are 6 in tests/invalid-local-lock.test.ts, which also fail on main on macOS (the /var vs /private/var realpath).

Notes

  • A tip for local runs: running the full suite with the real HOME left a symlink in ~/.gemini/config/skills on my machine, from an existing download-lock test. I didn't change that test here.
  • Related: #1470, #1874, #1060. This may conflict textually with #1089, which also touches selectAgentsInteractive.

🤖 Generated with Claude Code