Skip to content

feat(connect): add Kilo CLI adapter#630

Open
tgunr wants to merge 1 commit into
rohitg00:mainfrom
tgunr:feat/kilo-connect-adapter
Open

feat(connect): add Kilo CLI adapter#630
tgunr wants to merge 1 commit into
rohitg00:mainfrom
tgunr:feat/kilo-connect-adapter

Conversation

@tgunr
Copy link
Copy Markdown

@tgunr tgunr commented May 24, 2026

Summary

  • Adds a connect adapter for Kilo (kilo-code), a fork of OpenCode with 17k+ GitHub stars
  • Kilo uses the OpenCode MCP config shape: top-level mcp key with command as array (not the standard mcpServers object)
  • Kilo implements memory hooks natively in its codebase, so no plugin installation is needed — MCP wiring is the only step

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.json in that directory.

Summary by CodeRabbit

  • New Features
    • Added Kilo integration for agent connectivity
    • Automatic detection and installation with dry-run mode
    • Force-overwrite option for existing configurations
    • Automatic backup creation before configuration changes
    • Built-in verification of successful installation

Review Change Stack

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)
@vercel
Copy link
Copy Markdown

vercel Bot commented May 24, 2026

@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.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 24, 2026

📝 Walkthrough

Walkthrough

This 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.

Changes

Kilo Agent Adapter Integration

Layer / File(s) Summary
Kilo adapter implementation
src/cli/connect/kilo.ts
New adapter module that discovers Kilo config across multiple candidate filenames in ~/.config/kilo, reads JSON/JSONC safely, checks for existing agentmemory MCP entries, backs up and atomically writes mcp.agentmemory with ${AGENTMEMORY_URL} and ${AGENTMEMORY_SECRET} expansion, supports force and dryRun modes, and performs post-write verification to ensure installation succeeded.
Adapter registration in system
src/cli/connect/index.ts
Import the Kilo adapter module and add it to the exported ADAPTERS array so the CLI can detect, select, and install Kilo agent wiring.

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰 A kilo of joy hops into the fold,
With configs discovered and MCP dreams told,
Safe backups and atoms, verification so keen,
Agentmemory wired in the smoothest of scene!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(connect): add Kilo CLI adapter' directly and concisely describes the main change: adding support for the Kilo CLI adapter to the connect module.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/cli/connect/kilo.ts (1)

1-12: ⚡ Quick win

Import @clack/prompts for consistent logging.

The adapter uses console.log (line 81) and console.error (line 99), but the established pattern in json-mcp-adapter.ts uses p.log.info and p.log.error from @clack/prompts for 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

📥 Commits

Reviewing files that changed from the base of the PR and between 3551241 and eeebde6.

📒 Files selected for processing (2)
  • src/cli/connect/index.ts
  • src/cli/connect/kilo.ts

Comment thread src/cli/connect/index.ts
hermes,
pi,
openhuman,
kilo,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

🧩 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.ts

Repository: 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 || true

Repository: 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 || true

Repository: 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 || true

Repository: 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 || true

Repository: 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.

Comment thread src/cli/connect/kilo.ts
}

const configDir = join(homedir(), ".config", "kilo");
const configFiles = ["kilo.jsonc", "kilo.json", "opencode.jsonc", "opencode.json"];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | 🏗️ Heavy lift

🧩 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 || true

Repository: 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.ts searches ["kilo.jsonc", "kilo.json", "opencode.jsonc", "opencode.json"], but it reads both with readJsonSafe, which uses JSON.parse (src/cli/connect/util.ts), so JSONC (comments/trailing commas) returns null.
  • When parsing returns null, kilo.ts treats the config as empty and overwrites it via writeJsonAtomic(configPath, next), discarding existing fields (backup is created, but the live config is clobbered).

Fix options

  • Make readJsonSafe JSONC-aware for .jsonc (recommended: use jsonc-parser or json5 so comments + trailing commas are handled), or
  • Remove .jsonc from configFiles to 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant