feat(connect): add Kilo CLI adapter#630
Conversation
Adds a connect adapter for Kilo (kilo-code), a fork of OpenCode.
Kilo uses a different MCP config shape with a top-level "mcp" key
and command as an array, rather than the standard mcpServers object.
The adapter:
- Detects Kilo via ~/.config/kilo/ directory
- Writes to kilo.jsonc > kilo.json > opencode.jsonc > opencode.json
- Uses the correct MCP entry shape: { type: "local", command: [...], environment: {...}, enabled: true }
- Notes that Kilo implements memory hooks natively (no plugin needed)
|
@tgunr is attempting to deploy a commit to the rohitg00's projects Team on Vercel. A member of the Team first needs to authorize it. |
📝 WalkthroughWalkthroughThis PR adds support for the Kilo agent by creating a new adapter module that detects Kilo configuration, safely installs an MCP entry for agentmemory with environment variable expansion, and registers the adapter into the CLI's agent resolution system. ChangesKilo Agent Adapter Integration
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~22 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)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add 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: 2
🧹 Nitpick comments (1)
src/cli/connect/kilo.ts (1)
1-12: ⚡ Quick winImport
@clack/promptsfor consistent logging.The adapter uses
console.log(line 81) andconsole.error(line 99), but the established pattern injson-mcp-adapter.tsusesp.log.infoandp.log.errorfrom@clack/promptsfor UI consistency across adapters.📦 Add the missing import
import { existsSync } from "node:fs"; import { homedir } from "node:os"; import { join } from "node:path"; +import * as p from "`@clack/prompts`"; import type { ConnectAdapter, ConnectOptions, ConnectResult } from "./types.js";Then update line 81:
- console.log( + p.log.info( `[dry-run] Would ${alreadyHas ? "overwrite" : "add"} mcp.agentmemory in ${configPath}`, );And line 99:
- console.error( + p.log.error( `Verification failed: ${configPath} did not contain mcp.agentmemory after write.`, );🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/cli/connect/kilo.ts` around lines 1 - 12, The file uses console.log/console.error for user messages but other adapters use `@clack/prompts` logging; add an import for p from "`@clack/prompts`" and replace console.log(...) calls with p.log.info(...) and console.error(...) with p.log.error(...). Specifically, add the import statement for p and update the occurrences of console.log and console.error in the connect logic (the lines with those calls in src/cli/connect/kilo.ts) to use p.log.info and p.log.error respectively so the adapter matches the json-mcp-adapter.ts logging pattern.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/cli/connect/index.ts`:
- Line 23: Tests expect 8 adapters but src/cli/connect/index.ts added "kilo" to
ADAPTERS; update test/cli-connect.test.ts to assert 9 adapters and include
"kilo" in the knownAgents() expected list (or adjust the assertion that checks
for exclusion of "kilo"), ensuring the test references the ADAPTERS count and
knownAgents() output accordingly.
In `@src/cli/connect/kilo.ts`:
- Line 46: The config discovery uses configFiles (["kilo.jsonc", "kilo.json",
"opencode.jsonc", "opencode.json"]) and reads them via readJsonSafe, but
readJsonSafe uses strict JSON.parse so .jsonc files with comments/trailing
commas return null and are treated as empty, then overwritten by
writeJsonAtomic; fix by either making readJsonSafe JSONC-aware (preferable) —
update readJsonSafe to detect .jsonc (or use jsonc-parser/json5) and parse
accordingly so it returns the actual object for kilo.jsonc/opencode.jsonc — or
remove ".jsonc" entries from configFiles to avoid parsing clobbering; ensure
references to configFiles, readJsonSafe and writeJsonAtomic are updated
consistently and preserve backup behavior when migrating formats.
---
Nitpick comments:
In `@src/cli/connect/kilo.ts`:
- Around line 1-12: The file uses console.log/console.error for user messages
but other adapters use `@clack/prompts` logging; add an import for p from
"`@clack/prompts`" and replace console.log(...) calls with p.log.info(...) and
console.error(...) with p.log.error(...). Specifically, add the import statement
for p and update the occurrences of console.log and console.error in the connect
logic (the lines with those calls in src/cli/connect/kilo.ts) to use p.log.info
and p.log.error respectively so the adapter matches the json-mcp-adapter.ts
logging pattern.
🪄 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: 59789ac3-771a-495c-973c-c5678c03c098
📒 Files selected for processing (2)
src/cli/connect/index.tssrc/cli/connect/kilo.ts
| hermes, | ||
| pi, | ||
| openhuman, | ||
| kilo, |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check the test expectations for adapter count and list
rg -n "ships exactly the 8 agents" test/cli-connect.test.ts
rg -n 'ADAPTERS\.length.*toBe' test/cli-connect.test.ts
rg -A10 'knownAgents.*toEqual' test/cli-connect.test.tsRepository: rohitg00/agentmemory
Length of output: 391
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Show the ADAPTERS definition around the referenced line in source
echo "---- src/cli/connect/index.ts (around line 1-80) ----"
nl -ba src/cli/connect/index.ts | sed -n '1,120p'
echo
echo "---- test/cli-connect.test.ts (around key expectations) ----"
nl -ba test/cli-connect.test.ts | sed -n '1,120p'
# Also show any "kilo" mentions
echo
echo "---- occurrences of 'kilo' ----"
rg -n "\"kilo\"|kilo" src/cli/connect/index.ts test/cli-connect.test.ts || trueRepository: rohitg00/agentmemory
Length of output: 179
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "---- src/cli/connect/index.ts (around line 1-120) ----"
nl -ba src/cli/connect/index.ts | sed -n '1,120p'
echo
echo "---- test/cli-connect.test.ts (around line 1-120) ----"
nl -ba test/cli-connect.test.ts | sed -n '1,140p'
echo
echo "---- occurrences of 'kilo' ----"
rg -n "\"kilo\"|kilo" src/cli/connect/index.ts test/cli-connect.test.ts || trueRepository: rohitg00/agentmemory
Length of output: 180
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Show the ADAPTERS definition around the referenced line in source
echo "---- src/cli/connect/index.ts (around line 1-120) ----"
nl -ba src/cli/connect/index.ts | sed -n '1,120p'
echo
echo "---- test/cli-connect.test.ts (around line 1-140) ----"
nl -ba test/cli-connect.test.ts | sed -n '1,140p'
echo
echo "---- occurrences of 'kilo' ----"
rg -n "\"kilo\"|kilo" src/cli/connect/index.ts test/cli-connect.test.ts || trueRepository: rohitg00/agentmemory
Length of output: 180
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "---- src/cli/connect/index.ts (lines 1-160) ----"
awk '{printf "%5d\t%s\n", NR, $0}' src/cli/connect/index.ts | sed -n '1,160p'
echo
echo "---- test/cli-connect.test.ts (lines 1-200) ----"
awk '{printf "%5d\t%s\n", NR, $0}' test/cli-connect.test.ts | sed -n '1,200p'
echo
echo "---- occurrences of 'kilo' ----"
rg -n "\"kilo\"|kilo" src/cli/connect/index.ts test/cli-connect.test.ts || trueRepository: rohitg00/agentmemory
Length of output: 14748
Update test/cli-connect.test.ts to include the new kilo adapter (expect 9 adapters)
src/cli/connect/index.ts now registers kilo in ADAPTERS, but the test still expects exactly 8 adapters and a knownAgents() list that excludes "kilo".
🧪 Proposed test fix
- it("ships exactly the 8 agents specified by the spec", () => {
+ it("ships exactly the 9 agents specified by the spec", () => {
expect(knownAgents().sort()).toEqual(
[
"claude-code",
"codex",
"cursor",
"gemini-cli",
"hermes",
+ "kilo",
"openclaw",
"openhuman",
"pi",
].sort(),
);
- expect(ADAPTERS.length).toBe(8);
+ expect(ADAPTERS.length).toBe(9);
});🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/cli/connect/index.ts` at line 23, Tests expect 8 adapters but
src/cli/connect/index.ts added "kilo" to ADAPTERS; update
test/cli-connect.test.ts to assert 9 adapters and include "kilo" in the
knownAgents() expected list (or adjust the assertion that checks for exclusion
of "kilo"), ensuring the test references the ADAPTERS count and knownAgents()
output accordingly.
| } | ||
|
|
||
| const configDir = join(homedir(), ".config", "kilo"); | ||
| const configFiles = ["kilo.jsonc", "kilo.json", "opencode.jsonc", "opencode.json"]; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if a JSONC parser is available in package.json dependencies
cat package.json | jq '.dependencies, .devDependencies' | grep -i 'jsonc\|strip-json'Repository: rohitg00/agentmemory
Length of output: 46
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 1) Inspect the referenced file and relevant helpers
sed -n '1,140p' src/cli/connect/kilo.ts | cat -n
# 2) Locate the implementations of readJsonSafe / writeJsonAtomic in the repo
echo "---- rg readJsonSafe ----"
rg -n "readJsonSafe" -S src
echo "---- rg writeJsonAtomic ----"
rg -n "writeJsonAtomic" -S src
# 3) Re-check package.json for JSONC-related deps
echo "---- package.json deps matching jsonc/strip-json-comments ----"
cat package.json | jq -r '
([.dependencies, .devDependencies] | add | to_entries | map(.key) | .[])
' 2>/dev/null | rg -i 'jsonc|strip-json'Repository: rohitg00/agentmemory
Length of output: 6083
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect JSON helpers
sed -n '1,120p' src/cli/connect/util.ts | cat -n
# Search package.json for jsonc/strip-json-comments mentions
echo "---- rg package.json for jsonc/strip-json-comments ----"
rg -n "jsonc|strip-json-comments" package.json || trueRepository: rohitg00/agentmemory
Length of output: 3032
Critical: kilo.jsonc/opencode.jsonc configs are parsed as strict JSON, so existing config can be silently overwritten
src/cli/connect/kilo.tssearches["kilo.jsonc", "kilo.json", "opencode.jsonc", "opencode.json"], but it reads both withreadJsonSafe, which usesJSON.parse(src/cli/connect/util.ts), so JSONC (comments/trailing commas) returnsnull.- When parsing returns
null,kilo.tstreats the config as empty and overwrites it viawriteJsonAtomic(configPath, next), discarding existing fields (backup is created, but the live config is clobbered).
Fix options
- Make
readJsonSafeJSONC-aware for.jsonc(recommended: usejsonc-parserorjson5so comments + trailing commas are handled), or - Remove
.jsoncfromconfigFilesto avoid clobbering unsupported formats.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/cli/connect/kilo.ts` at line 46, The config discovery uses configFiles
(["kilo.jsonc", "kilo.json", "opencode.jsonc", "opencode.json"]) and reads them
via readJsonSafe, but readJsonSafe uses strict JSON.parse so .jsonc files with
comments/trailing commas return null and are treated as empty, then overwritten
by writeJsonAtomic; fix by either making readJsonSafe JSONC-aware (preferable) —
update readJsonSafe to detect .jsonc (or use jsonc-parser/json5) and parse
accordingly so it returns the actual object for kilo.jsonc/opencode.jsonc — or
remove ".jsonc" entries from configFiles to avoid parsing clobbering; ensure
references to configFiles, readJsonSafe and writeJsonAtomic are updated
consistently and preserve backup behavior when migrating formats.
Summary
connectadapter for Kilo (kilo-code), a fork of OpenCode with 17k+ GitHub starsmcpkey with command as array (not the standardmcpServersobject)Config shape
{ "mcp": { "agentmemory": { "type": "local", "command": ["npx", "-y", "@agentmemory/mcp"], "environment": { "AGENTMEMORY_URL": "${AGENTMEMORY_URL}", "AGENTMEMORY_SECRET": "${AGENTMEMORY_SECRET}" }, "enabled": true } } }Detection
Checks for
~/.config/kilo/directory or any of:kilo.jsonc,kilo.json,opencode.jsonc,opencode.jsonin that directory.Summary by CodeRabbit