* 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:
@@ -1317,7 +1317,7 @@ describe('antigravity local install writes to .agents/ canonical dir (#791)', ()
|
||||
'.agent/ must not be created by a fresh install (new installs use .agents/)');
|
||||
});
|
||||
|
||||
test('global antigravity install still writes to ~/.gemini/antigravity (unchanged)', () => {
|
||||
test('global antigravity install writes skills/agents to ~/.gemini/config, runtime files to the configHome (#3738)', () => {
|
||||
const homeDir = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-ag-global-'));
|
||||
const savedHome = process.env.HOME;
|
||||
const savedUserProfile = process.env.USERPROFILE;
|
||||
@@ -1332,13 +1332,39 @@ describe('antigravity local install writes to .agents/ canonical dir (#791)', ()
|
||||
result.configDir.startsWith(homeDir),
|
||||
`global antigravity install must go under HOME, got: ${result.configDir}`,
|
||||
);
|
||||
// #3738: Antigravity scans ~/.gemini/config for machine-local discovery,
|
||||
// so skills and agents install under the global layout's home override…
|
||||
const configRoot = path.join(homeDir, '.gemini', 'config');
|
||||
assert.ok(
|
||||
fs.existsSync(path.join(result.configDir, 'skills')),
|
||||
'global antigravity install must create skills/ under ~/.gemini/antigravity',
|
||||
fs.existsSync(path.join(configRoot, 'skills', 'gsd-help', 'SKILL.md')),
|
||||
'global antigravity install must create gsd-* skills under ~/.gemini/config/skills',
|
||||
);
|
||||
assert.ok(
|
||||
fs.existsSync(path.join(configRoot, 'agents')),
|
||||
'global antigravity install must create agents/ under ~/.gemini/config',
|
||||
);
|
||||
assert.ok(
|
||||
!fs.existsSync(path.join(result.configDir, 'skills')),
|
||||
'no skills/ may be created under the configHome (~/.gemini/antigravity) — AGY does not scan it (#3738)',
|
||||
);
|
||||
assert.ok(
|
||||
!fs.existsSync(path.join(result.configDir, 'agents')),
|
||||
'no agents/ may be created under the configHome (~/.gemini/antigravity) (#3738)',
|
||||
);
|
||||
assert.ok(
|
||||
!fs.existsSync(path.join(homeDir, '.agents')),
|
||||
'.agents/ must NOT be created by a global install (global path is ~/.gemini/antigravity)',
|
||||
'.agents/ must NOT be created by a global install (global skills path is ~/.gemini/config)',
|
||||
);
|
||||
// #3738 review finding 1: the manifest must record the agents surface at
|
||||
// its ACTUAL install root — writeManifest resolves the agents-kind home
|
||||
// override, so drift detection sees the files AGY reads.
|
||||
const manifestPath = path.join(result.configDir, 'gsd-file-manifest.json');
|
||||
assert.ok(fs.existsSync(manifestPath), 'global install must write the manifest');
|
||||
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
||||
const agentKeys = Object.keys(manifest.files).filter((k) => k.startsWith('agents/'));
|
||||
assert.ok(
|
||||
agentKeys.length > 0,
|
||||
`manifest must track agents/ at the home-override root, got keys: ${Object.keys(manifest.files).slice(0, 5).join(', ')}`,
|
||||
);
|
||||
} finally {
|
||||
if (savedHome === undefined) delete process.env.HOME;
|
||||
@@ -6473,6 +6499,10 @@ describe('install.js --skills-root', () => {
|
||||
// #2088 (ADR-1239 upgrade 3): Codex skills resolve to the canonical
|
||||
// $HOME/.agents/skills root (skills-kind home override), not $CODEX_HOME/skills.
|
||||
{ runtime: 'codex', expected: path.join(os.homedir(), '.agents', 'skills') },
|
||||
// #3738: Antigravity global discovery scans ~/.gemini/config/ — skills resolve
|
||||
// to the skills-kind home override, not the configHome (~/.gemini/antigravity)
|
||||
// that still holds settings.json and the gsd-core runtime files.
|
||||
{ runtime: 'antigravity', expected: path.join(os.homedir(), '.gemini', 'config', 'skills') },
|
||||
{ runtime: 'copilot', expected: path.join(os.homedir(), '.copilot', 'skills') },
|
||||
{ runtime: 'cursor', expected: path.join(os.homedir(), '.cursor', 'skills') },
|
||||
{ runtime: 'trae', expected: path.join(os.homedir(), '.trae', 'skills') },
|
||||
@@ -6515,6 +6545,8 @@ describe('#3024: gsd-tools query skills-root', () => {
|
||||
const CASES = [
|
||||
{ runtime: 'claude', expected: path.join(os.homedir(), '.claude', 'skills') },
|
||||
{ runtime: 'codex', expected: path.join(os.homedir(), '.agents', 'skills') },
|
||||
// #3738: the query surface must agree with install.js --skills-root above.
|
||||
{ runtime: 'antigravity', expected: path.join(os.homedir(), '.gemini', 'config', 'skills') },
|
||||
{ runtime: 'cursor', expected: path.join(os.homedir(), '.cursor', 'skills') },
|
||||
];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user