feat(scripts): add gemini-adapt-agents utility for Gemini CLI compatibility#1318
feat(scripts): add gemini-adapt-agents utility for Gemini CLI compatibility#1318Dobbymin wants to merge 7 commits intoaffaan-m:mainfrom
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds a Node.js CLI and exported Changes
Sequence Diagram(s)sequenceDiagram
participant CLI as CLI (node script)
participant FS as Filesystem (.gemini/agents)
participant ADAPT as adaptContent
CLI->>FS: check directory exists
alt directory missing
CLI->>CLI: log error, exit(1)
else directory present
CLI->>FS: list top-level `*.md` files
loop for each file
CLI->>FS: read file content
CLI->>ADAPT: adaptContent(content)
ADAPT-->>CLI: transformedContent
alt content changed
CLI->>FS: write updated file
else unchanged
CLI-->>FS: skip write
end
end
CLI->>CLI: print "fixed X/Y"
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
scripts/gemini-adapt-agents.js (2)
72-80: Redundant file read: content is read twice per file.The file is read at line 74 (
original) and again insideadaptFileat line 38. Consider passing the content toadaptFileto avoid redundant I/O.♻️ Refactor to pass content and avoid double read
Update the function signature:
-function adaptFile(fp) { - const content = fs.readFileSync(fp, 'utf8'); +function adaptContent(content) { let result = content;Update the call site:
for (const f of files) { const fp = path.join(agentsDir, f); const original = fs.readFileSync(fp, 'utf8'); - const adapted = adaptFile(fp); + const adapted = adaptContent(original); if (adapted !== original) {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/gemini-adapt-agents.js` around lines 72 - 80, The loop reads each file into `original` and `adaptFile(fp)` reads the same file again, causing redundant I/O; change `adaptFile` to accept file content (e.g., `adaptFile(content, fp?)`) and update the call site in the for-loop to pass the already-read `original` instead of the path, then have `adaptFile` operate on the passed content (optionally keeping `fp` for metadata) and remove the internal `fs.readFileSync` call—ensure `fs.writeFileSync(fp, adapted)` and the `changed++` logic remain unchanged.
29-30: Minor inconsistency:WebSearchandWebFetchlack lowercase variants.Other tools have both PascalCase and lowercase mappings (e.g.,
Read/read,Bash/bash), butWebSearchandWebFetchonly have PascalCase. While existing agents appear to use PascalCase consistently, adding lowercase variants would maintain the defensive pattern.🔧 Add lowercase variants for consistency
WebSearch: 'google_web_search', WebFetch: 'web_fetch', + websearch: 'google_web_search', + webfetch: 'web_fetch', };🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/gemini-adapt-agents.js` around lines 29 - 30, Add lowercase variants for the two tool keys so mappings remain consistent: duplicate the existing WebSearch and WebFetch entries by adding 'websearch': 'google_web_search' and 'webfetch': 'web_fetch' alongside the PascalCase keys (refer to the existing WebSearch and WebFetch entries in the mapping). This preserves the defensive pattern used for other tools (e.g., Read/read, Bash/bash) and ensures agents can look up tools via lowercase keys.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@scripts/gemini-adapt-agents.js`:
- Around line 55-57: The loop that removes unsupported frontmatter keys using
UNSUPPORTED_KEYS currently uses a regex requiring a trailing newline so keys at
EOF (e.g., "color:" last line) aren't matched; update the replacement regex in
the loop that iterates over UNSUPPORTED_KEYS (and operates on result) to accept
either a newline or end-of-string (for example replace the ending "\\n" with
"(?:\\r?\\n|$)" or otherwise make the newline optional) so lines without a
trailing newline are also removed.
---
Nitpick comments:
In `@scripts/gemini-adapt-agents.js`:
- Around line 72-80: The loop reads each file into `original` and
`adaptFile(fp)` reads the same file again, causing redundant I/O; change
`adaptFile` to accept file content (e.g., `adaptFile(content, fp?)`) and update
the call site in the for-loop to pass the already-read `original` instead of the
path, then have `adaptFile` operate on the passed content (optionally keeping
`fp` for metadata) and remove the internal `fs.readFileSync` call—ensure
`fs.writeFileSync(fp, adapted)` and the `changed++` logic remain unchanged.
- Around line 29-30: Add lowercase variants for the two tool keys so mappings
remain consistent: duplicate the existing WebSearch and WebFetch entries by
adding 'websearch': 'google_web_search' and 'webfetch': 'web_fetch' alongside
the PascalCase keys (refer to the existing WebSearch and WebFetch entries in the
mapping). This preserves the defensive pattern used for other tools (e.g.,
Read/read, Bash/bash) and ensures agents can look up tools via lowercase keys.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 0af08d2f-9360-4181-a909-b58c10ccbf10
📒 Files selected for processing (1)
scripts/gemini-adapt-agents.js
There was a problem hiding this comment.
Pull request overview
Adds a Node.js utility script to convert ECC agent Markdown frontmatter from Claude Code tool naming to Gemini CLI-compatible naming so copied agents load successfully in Gemini CLI (addresses #1316).
Changes:
- Added
scripts/gemini-adapt-agents.jsto rewritetools:entries (including MCP tool name normalization). - Strips unsupported frontmatter keys (
color:) to satisfy Gemini CLI agent schema validation. - Writes changes in-place only when file content actually differs.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Greptile SummaryAdds Confidence Score: 5/5Safe to merge; all remaining findings are minor P2 style/robustness suggestions. Both P1-level concerns raised in previous review threads are resolved: adaptContent now takes a content string (no internal readFileSync double-read), and color: removal operates on the frontmatter-scoped fm variable rather than the full document. The two remaining findings are a minor TOOL_MAP inconsistency and a defensive directory-entry guard, neither of which affects correctness for any real ECC agent file. No files require special attention.
|
| Filename | Overview |
|---|---|
| scripts/gemini-adapt-agents.js | New utility script adapting Claude Code agent frontmatter to Gemini CLI format; minor inconsistencies in lowercase TOOL_MAP entries and missing directory-entry type guard in the file loop. |
| tests/scripts/gemini-adapt-agents.test.js | Comprehensive unit and CLI integration tests covering all tool mappings, MCP name conversion, color key removal, idempotency, and temp-dir cleanup. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[CLI invoked] --> B{agentsDir exists?}
B -- No --> C[Exit 1: Directory not found]
B -- Yes --> D[readdirSync .md files]
D --> E[For each .md file]
E --> F[readFileSync original content]
F --> G[adaptContent]
G --> H{Frontmatter block\nfound via regex?}
H -- No --> I[Return content unchanged]
H -- Yes --> J[Rewrite tools array via TOOL_MAP]
J --> K[Normalize mcp__server__tool → mcp_server_tool]
K --> L[Strip UNSUPPORTED_KEYS e.g. color]
L --> M{adapted != original?}
M -- Yes --> N[writeFileSync updated content]
M -- No --> O[Skip write — idempotent]
N --> P[changed++]
O --> P
P --> Q{More files?}
Q -- Yes --> E
Q -- No --> R[Print summary and exit 0]
Reviews (6): Last reviewed commit: "chore(tests): replace misleading frontma..." | Re-trigger Greptile
There was a problem hiding this comment.
3 issues found across 1 file
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="scripts/gemini-adapt-agents.js">
<violation number="1" location="scripts/gemini-adapt-agents.js:42">
P2: Tool conversion only handles flow-style `tools: [...]` and misses YAML block-list `tools:` entries, so valid agent files may not be adapted.</violation>
<violation number="2" location="scripts/gemini-adapt-agents.js:56">
P2: Unsupported-key stripping is applied to the entire markdown text, so it can remove non-frontmatter `color:` lines from document body content.</violation>
<violation number="3" location="scripts/gemini-adapt-agents.js:56">
P2: The regex `^${key}:.*\\n` requires a trailing newline. If `color:` is the last line in the frontmatter without a trailing newline, the pattern silently fails to match and the key is not removed. Use `(?:\n|$)` instead of `\n` to handle both cases.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
tests/scripts/gemini-adapt-agents.test.js (1)
143-147: Avoid hardcoded missing path in CLI failure test.
/nonexistent/path/agentsis brittle and not guaranteed absent on every environment. Build a guaranteed-missing path under a temp dir for deterministic behavior.More deterministic missing-directory setup
if (test('CLI errors on missing directory', () => { - const result = run(['/nonexistent/path/agents']); - assert.strictEqual(result.code, 1); - assert.ok(result.stderr.includes('Directory not found')); + const base = fs.mkdtempSync(path.join(os.tmpdir(), 'gaa-missing-')); + const missing = path.join(base, 'does-not-exist'); + try { + const result = run([missing]); + assert.strictEqual(result.code, 1); + assert.ok(result.stderr.includes('Directory not found')); + } finally { + fs.rmSync(base, { recursive: true, force: true }); + } })) passed++; else failed++;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/scripts/gemini-adapt-agents.test.js` around lines 143 - 147, The test "CLI errors on missing directory" is using a hardcoded path '/nonexistent/path/agents' which may exist on some systems; modify the test to generate a guaranteed-missing path under the system temp directory instead of a hardcoded path: create a unique temp-based pathname (e.g., using os.tmpdir() + a random/UUID component or by creating and removing a temp folder) and pass that path to run(...) in the test, then assert result.code and stderr as before; update the test declaration (the test('CLI errors on missing directory', ...)) to use this generated missingPath so the test is deterministic across environments while still exercising run().
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@tests/scripts/gemini-adapt-agents.test.js`:
- Around line 107-114: The test for the malformed frontmatter case is too weak
(it only checks typeof result); update the assertion in the test that calls
adaptContent so it verifies the output exactly matches the original input (or a
specific expected string) to ensure no unintended modifications occur; locate
the test block containing the input variable and replace/assert
assert.strictEqual(typeof result, 'string') with assert.strictEqual(result,
input) (or assert.strictEqual(result, '---\nname: test\ncolor: blue') to lock
the expected behavior).
---
Nitpick comments:
In `@tests/scripts/gemini-adapt-agents.test.js`:
- Around line 143-147: The test "CLI errors on missing directory" is using a
hardcoded path '/nonexistent/path/agents' which may exist on some systems;
modify the test to generate a guaranteed-missing path under the system temp
directory instead of a hardcoded path: create a unique temp-based pathname
(e.g., using os.tmpdir() + a random/UUID component or by creating and removing a
temp folder) and pass that path to run(...) in the test, then assert result.code
and stderr as before; update the test declaration (the test('CLI errors on
missing directory', ...)) to use this generated missingPath so the test is
deterministic across environments while still exercising run().
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 5d72886e-3f0c-4a27-8692-87f027918c52
📒 Files selected for processing (2)
scripts/gemini-adapt-agents.jstests/scripts/gemini-adapt-agents.test.js
🚧 Files skipped from review as they are similar to previous changes (1)
- scripts/gemini-adapt-agents.js
There was a problem hiding this comment.
2 issues found across 2 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="scripts/gemini-adapt-agents.js">
<violation number="1" location="scripts/gemini-adapt-agents.js:44">
P2: Frontmatter detection is not anchored to the beginning of the file, so mid-file `--- ... ---` blocks can be incorrectly rewritten.</violation>
</file>
<file name="tests/scripts/gemini-adapt-agents.test.js">
<violation number="1" location="tests/scripts/gemini-adapt-agents.test.js:107">
P2: Test name claims `color:` removal at EOF, but assertion only checks no-crash/string type, so the stated behavior is not actually tested.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
tests/scripts/gemini-adapt-agents.test.js (2)
78-86: Consider adding test coverage forWebFetchtool mapping.The
TOOL_MAPinscripts/gemini-adapt-agents.jsincludesWebFetch: 'web_fetch'(per context snippet 1), but there's no dedicated test for this mapping. Adding a test would ensure complete coverage of all supported tool conversions.Suggested addition (after line 81)
})) passed++; else failed++; + if (test('maps WebFetch → web_fetch', () => { + const input = '---\ntools: [WebFetch]\n---\n'; + assert.ok(adaptContent(input).includes('"web_fetch"')); + })) passed++; else failed++; + if (test('converts mcp__server__tool → mcp_server_tool', () => {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/scripts/gemini-adapt-agents.test.js` around lines 78 - 86, Add a test that verifies the WebFetch → web_fetch mapping by calling adaptContent with a frontmatter entry using WebFetch and asserting the output includes the string "web_fetch"; locate tests near the existing adaptContent checks (e.g., the tests around 'maps WebSearch → google_web_search' and 'converts mcp__server__tool → mcp_server_tool') and add a similar if (test(...)) passed++/else failed++ block that uses adaptContent and assert.ok to confirm the conversion for the WebFetch key present in TOOL_MAP in scripts/gemini-adapt-agents.js.
45-180: Test runner function exceeds 50-line guideline but is acceptable here.At ~135 lines,
runTests()exceeds the guideline for function length. However, for a sequential test runner with flat structure and no complex branching, this is a reasonable trade-off for readability. If the test suite grows significantly, consider grouping tests into separate functions (e.g.,runUnitTests(),runCliTests()).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/scripts/gemini-adapt-agents.test.js` around lines 45 - 180, runTests() is longer than the 50-line guideline; split it into smaller logical functions to improve maintainability. Create two new functions (e.g., runUnitTests() and runCliTests()) and move the flat sequence of unit test blocks (all adaptContent/assert checks) into runUnitTests() and the CLI integration blocks (calls to run(), tmpDir setups, fs assertions) into runCliTests(); then have runTests() simply call runUnitTests(); runCliTests(); aggregate passed/failed counts and keep existing process.exit behavior. Ensure you preserve shared variables and helper calls (adaptContent, run, fs, path, os, assert) and return/update the passed/failed counters from the new functions so runTests() can log the final summary exactly as before.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@tests/scripts/gemini-adapt-agents.test.js`:
- Around line 107-114: Rename the test description to accurately reflect the
asserted behavior: update the test title string in the test block that calls
adaptContent (currently "removes color: at EOF without trailing newline") to
something like "does not remove color: at EOF when frontmatter is unclosed" or
"keeps color: at EOF when frontmatter is unclosed" so the test name matches the
assertion that the unclosed frontmatter is returned unchanged; ensure you only
change the test title text surrounding the test(...) call and not the assertion
or adaptContent invocation.
---
Nitpick comments:
In `@tests/scripts/gemini-adapt-agents.test.js`:
- Around line 78-86: Add a test that verifies the WebFetch → web_fetch mapping
by calling adaptContent with a frontmatter entry using WebFetch and asserting
the output includes the string "web_fetch"; locate tests near the existing
adaptContent checks (e.g., the tests around 'maps WebSearch → google_web_search'
and 'converts mcp__server__tool → mcp_server_tool') and add a similar if
(test(...)) passed++/else failed++ block that uses adaptContent and assert.ok to
confirm the conversion for the WebFetch key present in TOOL_MAP in
scripts/gemini-adapt-agents.js.
- Around line 45-180: runTests() is longer than the 50-line guideline; split it
into smaller logical functions to improve maintainability. Create two new
functions (e.g., runUnitTests() and runCliTests()) and move the flat sequence of
unit test blocks (all adaptContent/assert checks) into runUnitTests() and the
CLI integration blocks (calls to run(), tmpDir setups, fs assertions) into
runCliTests(); then have runTests() simply call runUnitTests(); runCliTests();
aggregate passed/failed counts and keep existing process.exit behavior. Ensure
you preserve shared variables and helper calls (adaptContent, run, fs, path, os,
assert) and return/update the passed/failed counters from the new functions so
runTests() can log the final summary exactly as before.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 8b75baae-9828-46ee-b938-38b3e5977990
📒 Files selected for processing (2)
scripts/gemini-adapt-agents.jstests/scripts/gemini-adapt-agents.test.js
🚧 Files skipped from review as they are similar to previous changes (1)
- scripts/gemini-adapt-agents.js
There was a problem hiding this comment.
1 issue found across 2 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="tests/scripts/gemini-adapt-agents.test.js">
<violation number="1" location="tests/scripts/gemini-adapt-agents.test.js:113">
P3: Misleading test name: the test is called `'removes color: at EOF without trailing newline'` but the assertion verifies the input is returned **unchanged** (i.e., `color:` is *not* removed because frontmatter is unclosed). Rename to something like `'leaves unclosed frontmatter unchanged'` to match the actual behavior being tested.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
There was a problem hiding this comment.
🧹 Nitpick comments (2)
tests/scripts/gemini-adapt-agents.test.js (2)
45-180:runTestsis too large and repetitive—split into small grouped runners.This function is difficult to scan/extend due to length and repeated pass/fail boilerplate. Consider extracting grouped test suites (
runAdaptContentTests,runCliTests) and a tiny result accumulator helper.♻️ Suggested refactor shape
-function runTests() { - console.log('\n=== Testing gemini-adapt-agents.js ===\n'); - let passed = 0; - let failed = 0; - // ...many inline if (test(...)) passed++; else failed++; - console.log(`\nResults: Passed: ${passed}, Failed: ${failed}`); - process.exit(failed > 0 ? 1 : 0); -} +function runCase(name, fn, stats) { + if (test(name, fn)) stats.passed++; + else stats.failed++; +} + +function runAdaptContentTests(stats) { + runCase('maps Read → read_file', () => { + const input = '---\ntools: [Read]\n---\n'; + assert.ok(adaptContent(input).includes('"read_file"')); + }, stats); + // ...other adaptContent cases +} + +function runCliTests(stats) { + runCase('CLI errors on missing directory', () => { + // ... + }, stats); + // ...other CLI cases +} + +function runTests() { + console.log('\n=== Testing gemini-adapt-agents.js ===\n'); + const stats = { passed: 0, failed: 0 }; + runAdaptContentTests(stats); + runCliTests(stats); + console.log(`\nResults: Passed: ${stats.passed}, Failed: ${stats.failed}`); + process.exit(stats.failed > 0 ? 1 : 0); +}As per coding guidelines, “Keep functions small (less than 50 lines)” and “Keep functions small (<50 lines) and files focused (<800 lines, typical 200-400 lines)”.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/scripts/gemini-adapt-agents.test.js` around lines 45 - 180, The runTests function is too large and repetitive; split it into smaller, focused runners by extracting the adapt-content unit tests into a new runAdaptContentTests function and the CLI tests into runCliTests, and add a tiny result accumulator helper (e.g., TestResults or accumulateResult) to track passed/failed counts; update runTests to call these helpers and print/exit based on the combined accumulator. Locate the existing runTests, move the individual if(test(...)) blocks that assert adaptContent behavior into runAdaptContentTests (keeping their assertions intact and returning a TestResults object), move the CLI integration blocks into runCliTests, implement a small helper used by both to increment passed/failed, and ensure runTests only orchestrates calling the two runners, printing combined results and exiting with the correct code.
143-147: Use a generated missing path instead of a hardcoded POSIX path.Line 144 uses
'/nonexistent/path/agents', which is brittle across environments. Build a definitely-missing path from a temp dir to keep the test platform-agnostic.✅ Suggested change
- if (test('CLI errors on missing directory', () => { - const result = run(['/nonexistent/path/agents']); + if (test('CLI errors on missing directory', () => { + const missingDir = path.join( + fs.mkdtempSync(path.join(os.tmpdir(), 'gaa-missing-')), + 'agents-does-not-exist' + ); + const result = run([missingDir]); assert.strictEqual(result.code, 1); assert.ok(result.stderr.includes('Directory not found')); })) passed++; else failed++;Based on learnings, “Use Node.js scripts in the scripts directory for platform-agnostic helper tools that support Windows, macOS, and Linux.”
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/scripts/gemini-adapt-agents.test.js` around lines 143 - 147, The test "CLI errors on missing directory" currently uses a hardcoded POSIX path '/nonexistent/path/agents' which fails on non-Unix systems; replace that literal with a platform-agnostic generated missing path using Node's os.tmpdir() (and path.join) so the path is definitely absent on the current system before calling run(). Update the test block that calls run(...) (and inspects result.code/result.stderr) to construct the missing directory path from a temp directory (ensure it does not exist) instead of the hardcoded string, referencing the same test name and run() invocation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@tests/scripts/gemini-adapt-agents.test.js`:
- Around line 45-180: The runTests function is too large and repetitive; split
it into smaller, focused runners by extracting the adapt-content unit tests into
a new runAdaptContentTests function and the CLI tests into runCliTests, and add
a tiny result accumulator helper (e.g., TestResults or accumulateResult) to
track passed/failed counts; update runTests to call these helpers and print/exit
based on the combined accumulator. Locate the existing runTests, move the
individual if(test(...)) blocks that assert adaptContent behavior into
runAdaptContentTests (keeping their assertions intact and returning a
TestResults object), move the CLI integration blocks into runCliTests, implement
a small helper used by both to increment passed/failed, and ensure runTests only
orchestrates calling the two runners, printing combined results and exiting with
the correct code.
- Around line 143-147: The test "CLI errors on missing directory" currently uses
a hardcoded POSIX path '/nonexistent/path/agents' which fails on non-Unix
systems; replace that literal with a platform-agnostic generated missing path
using Node's os.tmpdir() (and path.join) so the path is definitely absent on the
current system before calling run(). Update the test block that calls run(...)
(and inspects result.code/result.stderr) to construct the missing directory path
from a temp directory (ensure it does not exist) instead of the hardcoded
string, referencing the same test name and run() invocation.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 2ac9eb11-ebf8-47f7-98d2-63bccceaf3cd
📒 Files selected for processing (1)
tests/scripts/gemini-adapt-agents.test.js
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
tests/scripts/gemini-adapt-agents.test.js (1)
28-33: Useprocess.execPathinstead of hardcoded'node'for CLI invocation.Hardcoding
'node'can be flaky in some CI/shell environments. Prefer the current runtime path for portability.Suggested patch
- const stdout = execFileSync('node', [SCRIPT, ...args], { + const stdout = execFileSync(process.execPath, [SCRIPT, ...args], { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'], timeout: 10000, });Based on learnings: "Use Node.js scripts in the scripts/ directory for cross-platform utilities that support Windows, macOS, and Linux."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/scripts/gemini-adapt-agents.test.js` around lines 28 - 33, The test helper function run uses execFileSync with a hardcoded 'node' which can break in some CI/shell environments; update the call in run to invoke the current Node binary via process.execPath instead of the string 'node' (leave the rest of the execFileSync options and the SCRIPT and args parameters unchanged) so execFileSync(SCRIPT invocation) uses process.execPath to improve cross-platform/CI reliability.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@tests/scripts/gemini-adapt-agents.test.js`:
- Around line 109-113: The inline comments around the unclosed-frontmatter test
are misleading: update the comments next to the adaptContent call and the
assert.strictEqual(result, input) to state that when frontmatter is unclosed the
function performs no transform and returns the input unchanged. Locate the test
block using the adaptContent invocation and the result/assert lines in
tests/scripts/gemini-adapt-agents.test.js and replace the existing misleading
words about frontmatter regex/closure with a clear no-op expectation, e.g.,
"Unclosed frontmatter: adaptContent should return input unchanged (no transform
expected)."
---
Nitpick comments:
In `@tests/scripts/gemini-adapt-agents.test.js`:
- Around line 28-33: The test helper function run uses execFileSync with a
hardcoded 'node' which can break in some CI/shell environments; update the call
in run to invoke the current Node binary via process.execPath instead of the
string 'node' (leave the rest of the execFileSync options and the SCRIPT and
args parameters unchanged) so execFileSync(SCRIPT invocation) uses
process.execPath to improve cross-platform/CI reliability.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 27133b2d-bbec-4b60-b324-0908ed66b087
📒 Files selected for processing (1)
tests/scripts/gemini-adapt-agents.test.js
What Changed
Added
scripts/gemini-adapt-agents.js— a utility script that converts ECC agent frontmatter from Claude Code format to Gemini CLI format.The script rewrites three things in every
.mdfile under the target agents directory:Tool names — maps Claude Code names to Gemini CLI equivalents:
Readread_fileWritewrite_fileEditreplaceBashrun_shell_commandGrepgrep_searchGlobglobWebSearchgoogle_web_searchWebFetchweb_fetchMCP tool name format — converts double-underscore separators to single:
mcp__context7__query-docs→mcp_context7_query-docsUnsupported frontmatter keys — strips
color:, which Gemini CLI's agent schema does not recognise. (model:is intentionally preserved — it is valid in Gemini CLI's schema.)Handles both quoted (
["Read", "Grep"]) and unquoted ([Read, Grep]) YAML array styles. Idempotent — only writes files that changed.Why This Change
Closes #1316.
ECC agents use Claude Code tool names in their
tools:frontmatter field. Gemini CLI validates this field against its own built-in registry (ALL_BUILTIN_TOOL_NAMES) and rejects all unrecognised names. When users follow the documented workflow of copyingagents/*.mdinto.gemini/agents/, all 47 agents fail to load at Gemini CLI startup:This script lets users fix all agents in one command after copying:
Testing Done
node tests/run-all.js)["Read", "Grep", "Glob"][Read, Grep, Glob]mcp__context7__resolve-library-id→mcp_context7_resolve-library-idcolor:key — stripped cleanlyType of Change
fix:Bug fixfeat:New featurerefactor:Code refactoringdocs:Documentationtest:Testschore:Maintenance/toolingci:CI/CD changesSecurity & Quality Checklist
Documentation
Summary by cubic
Adds
scripts/gemini-adapt-agents.jsto convert ECC agent frontmatter from Claude Code to Gemini CLI so copied agents load without validation errors. Addresses #1316.New Features
read_file, Write/write→write_file, Edit/edit→replace, Bash/bash→run_shell_command, Grep/grep→grep_search, Glob/glob→glob, WebSearch→google_web_search, WebFetch→web_fetch).mcp__server__tool→mcp_server_tool) and removes unsupportedcolor(keepsmodel)../.gemini/agents, prints a fixed-files summary, and exits with a clear error if the agents dir is missing. Includes unit and CLI tests.Migration
cp /path/to/everything-claude-code/agents/*.md .gemini/agents/node /path/to/everything-claude-code/scripts/gemini-adapt-agents.js [agents-dir](optional; defaults to./.gemini/agents)Written for commit 029ac3f. Summary will update on new commits.
Summary by CodeRabbit