test(#1394): assert Gemini tool exclusion via exported converter, not internal
The back-merge of next carried #1559/#1565 (audit installer compatibility
exports), which removed convertGeminiToolName from bin/install.js's
module.exports. This PR's regression test destructured it from
require('../bin/install.js'), so after the merge it was undefined →
"TypeError: convertGeminiToolName is not a function" across all test lanes.
Rewrite the regression to assert the user-visible behavior through the
still-exported convertClaudeToGeminiAgent: a Skill/SlashCommand/AskUserQuestion
tools entry must not appear in the emitted Gemini frontmatter (the lowercase
fallback would emit invalid tool names that abort agent load — #1394/#3362),
while mapped tools (Read→read_file, WebFetch→web_fetch) survive. Folds the
dropped AskUserQuestion/ask_user coverage into the behavior test and removes
the internal-function import, so the test no longer depends on a private export
#1559 intentionally pruned. The exclusion fix itself is unchanged.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -18,7 +18,6 @@ const {
|
||||
convertClaudeToOpencodeFrontmatter,
|
||||
convertClaudeToKiloFrontmatter,
|
||||
convertClaudeToGeminiAgent,
|
||||
convertGeminiToolName,
|
||||
convertClaudeAgentToAntigravityAgent,
|
||||
convertClaudeCommandToOpencodeSkill,
|
||||
convertClaudeCommandToKiloSkill,
|
||||
@@ -302,25 +301,17 @@ Offer choices via AskUserQuestion when user input is needed.
|
||||
// validation (tools.N: Invalid tool name) and aborts the entire agent load —
|
||||
// previously killing 22 of 34 GSD agents on Gemini.
|
||||
|
||||
// Direct unit assertion against the LIVE install path (bin/install.js copy —
|
||||
// the one that actually generates agents), not the tsc build artifact, so a
|
||||
// stale build can't give a false-green while the live copy is broken.
|
||||
test('convertGeminiToolName returns null for Skill and SlashCommand', () => {
|
||||
assert.equal(convertGeminiToolName('Skill'), null, 'Skill is excluded, not lowercased to "skill"');
|
||||
assert.equal(convertGeminiToolName('SlashCommand'), null, 'SlashCommand is excluded, not lowercased to "slashcommand"');
|
||||
// Existing AskUserQuestion/ask_user exclusion (the same if-block this PR extends) must still hold.
|
||||
assert.equal(convertGeminiToolName('AskUserQuestion'), null, 'AskUserQuestion remains excluded');
|
||||
assert.equal(convertGeminiToolName('ask_user'), null, 'ask_user remains excluded');
|
||||
// Sanity: a mapped tool still converts.
|
||||
assert.equal(convertGeminiToolName('Read'), 'read_file', 'mapped tools still convert');
|
||||
});
|
||||
|
||||
// Agent-level assertion against the live install path (criterion 2/3).
|
||||
test('a Skill tools entry produces no skill/slashcommand in emitted frontmatter', () => {
|
||||
// Asserts the emitted frontmatter rather than the internal converter so the
|
||||
// test exercises the public, install-path-exported API (convertGeminiToolName
|
||||
// is an internal helper, deliberately not exported per #1559). The Skill,
|
||||
// SlashCommand, and AskUserQuestion inputs all exercise the exclusion if-block;
|
||||
// Read/WebFetch exercise the mapped-tool path that must survive.
|
||||
test('Skill/SlashCommand/AskUserQuestion are dropped from emitted Gemini frontmatter', () => {
|
||||
const input = `---
|
||||
name: gsd-planner
|
||||
description: Creates executable phase plans.
|
||||
tools: Read, Write, Bash, Glob, Grep, Skill, WebFetch, SlashCommand
|
||||
tools: Read, Write, Bash, Glob, Grep, Skill, WebFetch, SlashCommand, AskUserQuestion
|
||||
---
|
||||
|
||||
<role>
|
||||
@@ -330,10 +321,15 @@ Plan the phase.
|
||||
const result = convertClaudeToGeminiAgent(input);
|
||||
const frontmatter = result.split('---')[1] || '';
|
||||
|
||||
// Mapped tools still convert (the exclusion must not break the happy path).
|
||||
assert.ok(frontmatter.includes(' - read_file'), 'maps Read -> read_file');
|
||||
assert.ok(frontmatter.includes(' - web_fetch'), 'maps WebFetch -> web_fetch');
|
||||
// Claude-only tools with no Gemini equivalent are excluded, not lowercased
|
||||
// into invalid names that would fail frontmatter validation (#1394 / #3362).
|
||||
assert.ok(!frontmatter.includes(' - skill'), 'does not emit invalid Gemini skill tool');
|
||||
assert.ok(!frontmatter.includes(' - slashcommand'), 'does not emit invalid Gemini slashcommand tool');
|
||||
assert.ok(!frontmatter.includes(' - ask_user'), 'AskUserQuestion remains excluded');
|
||||
assert.ok(!frontmatter.includes(' - askuserquestion'), 'AskUserQuestion is not lowercased into an invalid tool');
|
||||
});
|
||||
|
||||
// Antigravity reuses convertGeminiToolName (it runs on the Gemini backend),
|
||||
|
||||
Reference in New Issue
Block a user