* test(#4705): add failing-first coverage for native Antigravity tool sequences * fix(#4705): emit Antigravity-native tool names as a YAML sequence convertClaudeAgentToAntigravityAgent and the installer's twin emitted Gemini CLI tool names as a comma-separated scalar. Antigravity's documented subagent contract (antigravity.google/docs/subagents) wants a YAML sequence of native names — view_file, grep_search, run_command, replace_file_content are the documented examples, and wrong or malformed grants can hang the subagent per Antigravity's own warning. Map values move to the native vocabulary where documented (Read -> view_file, Edit -> replace_file_content, Bash -> run_command, Grep -> grep_search); undocumented entries keep their best-known grant rather than being dropped (dropping would silently remove a restriction). The emitter writes one '- name' item per line; an agent whose every tool was filtered emits an explicit tools: [] instead of an empty scalar. Pre-existing pins updated to the native vocabulary. * test(#4705): update the #4727 map-value pin to the Antigravity-native vocabulary The #4727-era pin held the map VALUES at the Gemini CLI dialect on the belief that Antigravity speaks it; the confirmed bug #4705 (with Antigravity's own documented subagent contract) supersedes that for the four documented names. Key/shape pinning is preserved; only the values move. * docs(#4705): backfill changeset PR number --------- Co-authored-by: sim <sim@local>
This commit is contained in:
@@ -217,13 +217,14 @@ describe('#1928 Antigravity preserved (shared surface with the removed gemini ru
|
||||
assert.strictEqual(getRuntimeLabel('antigravity'), 'Antigravity');
|
||||
});
|
||||
|
||||
test('the shared Gemini-backend tool vocabulary still powers Antigravity agent conversion', () => {
|
||||
test('the Antigravity-native tool vocabulary powers Antigravity agent conversion (#4705)', () => {
|
||||
const input = ['---', 'name: gsd-x', 'description: d', 'tools: Read, Write, WebFetch, Skill', '---', '', 'body'].join('\n');
|
||||
const toolsLine = convertClaudeAgentToAntigravityAgent(input).split('\n').find((l) => l.startsWith('tools:')) || '';
|
||||
assert.ok(toolsLine.includes('read_file'), 'Read → read_file via the retained convertAntigravityToolName');
|
||||
assert.ok(toolsLine.includes('write_file'), 'Write → write_file');
|
||||
assert.ok(toolsLine.includes('web_fetch'), 'WebFetch → web_fetch');
|
||||
assert.ok(!/\bskill\b/.test(toolsLine), 'Skill is still excluded (would be an invalid backend tool name)');
|
||||
const result = convertClaudeAgentToAntigravityAgent(input);
|
||||
const toolsBlock = result.slice(result.indexOf('tools:')).split('\n').filter((l) => l.startsWith('- '));
|
||||
assert.ok(toolsBlock.includes('- view_file'), 'Read → view_file (native name, #4705)');
|
||||
assert.ok(toolsBlock.includes('- write_file'), 'Write → write_file');
|
||||
assert.ok(toolsBlock.includes('- web_fetch'), 'WebFetch → web_fetch');
|
||||
assert.ok(!toolsBlock.some((l) => /\bskill\b/.test(l)), 'Skill is still excluded (would be an invalid backend tool name)');
|
||||
});
|
||||
|
||||
test('#4727 the rename is complete: no gemini-named alias survives alongside the antigravity-named exports', () => {
|
||||
@@ -250,20 +251,25 @@ describe('#1928 Antigravity preserved (shared surface with the removed gemini ru
|
||||
'the retired gemini-named function must not still be exported — a surviving alias means the rename never finished',
|
||||
);
|
||||
|
||||
// The rename must be a pure identifier change: every value byte-identical, so an added OR
|
||||
// removed key (not just a renamed export) fails this too.
|
||||
// The #4727 rename remains a pure identifier change: same KEYS, same shape
|
||||
// (an added OR removed key still fails). The VALUES moved from the Gemini
|
||||
// CLI dialect to Antigravity-native names in #4705 — Antigravity's own
|
||||
// documented subagent contract (antigravity.google/docs/subagents) names
|
||||
// view_file / replace_file_content / grep_search / run_command as native,
|
||||
// and its tool-validation warning says wrong names can hang the subagent.
|
||||
// The old "Antigravity speaks the Gemini dialect" rationale was the belief
|
||||
// at #4727 time; the confirmed bug #4705 supersedes it.
|
||||
assert.deepStrictEqual(mod.claudeToAntigravityTools, {
|
||||
Read: 'read_file',
|
||||
Read: 'view_file',
|
||||
Write: 'write_file',
|
||||
Edit: 'replace',
|
||||
Bash: 'run_shell_command',
|
||||
Edit: 'replace_file_content',
|
||||
Bash: 'run_command',
|
||||
Glob: 'glob',
|
||||
Grep: 'search_file_content',
|
||||
Grep: 'grep_search',
|
||||
WebSearch: 'google_web_search',
|
||||
WebFetch: 'web_fetch',
|
||||
TodoWrite: 'write_todos',
|
||||
}, 'the tool map values are Gemini\'s built-in tool dialect, which Antigravity speaks — Google\'s '
|
||||
+ 'contract, not GSD\'s to alter by renaming the map that carries it');
|
||||
}, 'the tool map keys are the #4727 rename surface (add/remove still fails); the VALUES are the #4705 Antigravity-native vocabulary');
|
||||
|
||||
// In-set / out-of-set boundary pair: the excluded ids still return null individually...
|
||||
for (const excluded of ['mcp__anything', 'Task', 'Agent', 'AskUserQuestion', 'ask_user', 'Skill', 'SlashCommand']) {
|
||||
|
||||
@@ -478,12 +478,12 @@ tools: Read, Write, Bash, Skill, WebFetch, SlashCommand
|
||||
<role>Plan the phase.</role>`;
|
||||
|
||||
const result = convertClaudeAgentToAntigravityAgent(input);
|
||||
const toolsLine = result.split('\n').find(l => l.startsWith('tools:')) || '';
|
||||
const toolsItems = result.split('\n').filter(l => l.startsWith('- ')).map(l => l.slice(2));
|
||||
|
||||
assert.ok(toolsLine.includes('read_file'), 'maps Read -> read_file');
|
||||
assert.ok(toolsLine.includes('web_fetch'), 'maps WebFetch -> web_fetch');
|
||||
assert.ok(!/\bskill\b/.test(toolsLine), 'no invalid skill tool in Antigravity frontmatter');
|
||||
assert.ok(!/\bslashcommand\b/.test(toolsLine), 'no invalid slashcommand tool in Antigravity frontmatter');
|
||||
assert.ok(toolsItems.includes('view_file'), 'maps Read -> view_file (#4705 native name)');
|
||||
assert.ok(toolsItems.includes('web_fetch'), 'maps WebFetch -> web_fetch');
|
||||
assert.ok(!toolsItems.some(t => /\bskill\b/.test(t)), 'no invalid skill tool in Antigravity frontmatter');
|
||||
assert.ok(!toolsItems.some(t => /\bslashcommand\b/.test(t)), 'no invalid slashcommand tool in Antigravity frontmatter');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2667,3 +2667,40 @@ describe('#3706: the layout seam actually threads the variant', () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// ── #4705 — Antigravity agent tools: native names, YAML sequence ─────────────
|
||||
// The converter emitted Gemini CLI tool names as a comma-separated scalar;
|
||||
// Antigravity's documented subagent contract (antigravity.google/docs/subagents)
|
||||
// wants a YAML sequence of native tool names (view_file, grep_search,
|
||||
// run_command, replace_file_content are the documented examples). A scalar or a
|
||||
// wrong-vocabulary grant can hang the subagent per Antigravity's own warning.
|
||||
describe('#4705 — Antigravity agent tools are native names in a YAML sequence', () => {
|
||||
const input = `---
|
||||
name: example-reviewer
|
||||
description: Inspect source files
|
||||
tools: Read, Grep, Bash
|
||||
---
|
||||
|
||||
Inspect source files.`;
|
||||
|
||||
test('emits the documented native tools as a YAML sequence (#4705)', () => {
|
||||
const result = convertClaudeAgentToAntigravityAgent(input);
|
||||
assert.match(result, /tools:\n- view_file\n- grep_search\n- run_command\n/,
|
||||
'tools must be a YAML sequence of Antigravity-native names (view_file, grep_search, run_command)');
|
||||
assert.doesNotMatch(result, /tools:.*,/m, 'no comma-separated scalar may survive');
|
||||
});
|
||||
|
||||
test('Edit maps to the documented replace_file_content (#4705)', () => {
|
||||
const result = convertClaudeAgentToAntigravityAgent(
|
||||
`---\nname: e\ndescription: d\ntools: Edit\n---\n\nbody`);
|
||||
assert.match(result, /- replace_file_content/, 'Edit -> replace_file_content (documented native name)');
|
||||
assert.ok(!/- replace\b/.test(result), 'the Gemini CLI name replace must not survive');
|
||||
});
|
||||
|
||||
test('unmapped tools keep their lowercase grant (no silent restriction drop) (#4705)', () => {
|
||||
const result = convertClaudeAgentToAntigravityAgent(
|
||||
`---\nname: e\ndescription: d\ntools: Glob, WebFetch\n---\n\nbody`);
|
||||
assert.match(result, /- glob/, 'undocumented tools keep their mapped/lowercase grant');
|
||||
assert.match(result, /- web_fetch/, 'WebFetch stays granted');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user