Skip to content

feat(kimi): add kimi-code v0.11+ support with ~/.kimi-code paths#840

Open
salema97 wants to merge 13 commits into
Gentleman-Programming:mainfrom
salema97:feat/kimi-code-v0.11-support
Open

feat(kimi): add kimi-code v0.11+ support with ~/.kimi-code paths#840
salema97 wants to merge 13 commits into
Gentleman-Programming:mainfrom
salema97:feat/kimi-code-v0.11-support

Conversation

@salema97

@salema97 salema97 commented Jun 12, 2026

Copy link
Copy Markdown

Closes #782

Summary

This PR delivers end-to-end support for the Node.js-based Kimi Code CLI v0.11+ (~/.kimi-code) while preserving compatibility with the legacy Python/uv-based ~/.kimi layout. It also folds in the related work that landed on this branch: the self-update / update-advisory experience, organic agent trigger-rules, and the latest install/upgrade hardening.

Kimi Code v0.11+ highlights

  • Version-aware path resolution: prefers ~/.kimi-code (or KIMI_CODE_HOME), falls back to ~/.kimi.
  • BootstrapTemplate writes KIMI.md, config.toml, project AGENTS.md, and merges v0.11+ extras (extra_skill_dirs, SessionStart hook) into existing configs.
  • Plugin-based skill distribution via ~/.kimi-code/plugins/managed/gentle-ai/:
    • kimi.plugin.json follows the official schema (skills as string, sessionStart.skill).
    • Plugin is registered in ~/.kimi-code/plugins/installed.json so Kimi loads it on startup.
    • Engram is not declared inside the plugin manifest; it is provided by the Engram component through ~/.kimi-code/mcp.json, keeping the canonical engram name.
  • skill-registry hook runs on every session start to keep .atl/skill-registry.md up to date.
  • Skill routing respects the adapter's SkillsDir so legacy installs do not accidentally create ~/.kimi-code.
  • AGENTS.md search is bounded to the project root.

Files changed (high-level)

  • internal/agents/kimi/* — v0.11+ adapter, plugin manifest, registration, tests.
  • internal/components/sdd/*, internal/components/skills/*, internal/components/persona/* — Kimi-specific injection fixes and test hardening.
  • internal/update/*, internal/tui/*, internal/cli/* — update/advisory flow and CLI wiring.
  • internal/catalog/*, internal/components/sdd/triggerrules* — trigger-rules implementation.
  • internal/assets/*, testdata/golden/* — regenerated orchestrators, agents, and golden files.
  • README.md, docs/*.md, openspec/* — documentation and SDD artifacts.

Test Plan

  • go test ./internal/agents/kimi/... — passes
  • go test ./internal/components/sdd ./internal/components/skills ./internal/components/persona — passes
  • go vet ./... — clean
  • Local install with gentle-ai install --agents kimi --components sdd,skills succeeds
  • kimi doctor reports config.toml and tui.toml valid
  • gentle-ai skill-registry refresh generates .atl/skill-registry.md

Contributor Checklist

@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds version-aware Kimi path resolution for the v0.11+ Node.js rewrite, which uses ~/.kimi-code instead of the legacy ~/.kimi. The adapter now prefers ~/.kimi-code when present, falls back to ~/.kimi, and wires all path helpers to use the resolved directory. A new PluginInstaller interface enables plugin-based skill distribution. Bootstrap template now injects project AGENTS.md and ensures full config.toml content. System scan, catalog, registry, TUI, and injection code updated to detect and route skills correctly.

Changes

Kimi v0.11+ directory layout & plugin support

Layer / File(s) Summary
Adapter: config-dir resolution, path helpers, and bootstrap rewiring
internal/agents/kimi/adapter.go
Introduces KIMI_CODE_HOME~/.kimi-code (if present) → ~/.kimi resolution; rewires all path helpers (GlobalConfigDir, SystemPromptFile, SkillsDir, MCPConfigPath, SubAgentsDir, AGENTSMDPath); reworks BootstrapTemplate to inject sanitized project AGENTS.md, write full config.toml with permissions, and copy resolved AGENTS.md to config dir. Adds helpers for project AGENTS.md lookup, Jinja-syntax sanitization, and TOML content generation.
PluginInstaller interface and Kimi plugin manifest
internal/agents/interface.go, internal/agents/kimi/plugin.go
Adds optional PluginInstaller capability interface; defines Kimi manifest structures (KimiPluginManifest, KimiPluginSkills, KimiPluginHooks, KimiHookRef, KimiMCPServer) and methods to compute plugin directory (~/.kimi-code/plugins/managed/gentle-ai/), manifest path, and install kimi.plugin.json with version, skills subdir, session-start hook, and engram MCP server entry.
Plugin installer tests and adapter test helpers
internal/agents/kimi/plugin_test.go, internal/agents/kimi/test_helpers.go
Comprehensive tests for plugin paths, manifest content, install behavior, v0.11+ vs legacy skills directory ordering, and error handling when plugin directory creation fails; test helper infrastructure (StatResult, TestAdapterOption, WithStatPath, WithPathExists, NewTestAdapter) for constructing adapters with stubbed filesystem behaviors.
Adapter unit tests for v0.11+ behavior
internal/agents/kimi/adapter_test.go
Extensive new and updated tests covering v0.11+ config path generation, Detect behavior and config discovery, PostInstallMessage with v0.11+ marker, KIMI_CODE_HOME override and fallback, ConfigPath selection, AllSkillsDirs ordering, AGENTS.md resolution, sanitizeJinjaSyntax, and BootstrapTemplate behaviors (config.toml permissions, no overwrite of existing config, project AGENTS.md injection).
Catalog, registry, system scan, TUI, and permissions updates
internal/catalog/agents.go, internal/skillregistry/registry.go, internal/system/config_scan.go, internal/tui/model.go, internal/components/permissions/inject.go, internal/components/permissions/inject_test.go
Catalog AgentKimi ConfigPath updated; registry adds ~/.kimi-code/skills to user sources; system scan probes ~/.kimi-code before falling back to ~/.kimi; TUI agent builder maps AgentKimi to v0.11+ skills path when present; permissions overlay returns nil for Kimi (managed via config.toml).
Persona bootstrap and plugin-aware skills/SDD injection
internal/components/persona/inject_test.go, internal/components/skills/inject.go, internal/components/skills/inject_test.go, internal/components/sdd/inject_test.go
Updated persona test to expect resolved placeholders; InjectWithCapability routes skills to plugin subdirectory for PluginInstaller adapters; SDD and skills tests detect and accept modern vs legacy agents/skills layouts and normalize line endings for cross-platform robustness.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested labels

type:feature, size:exception

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 29.51% 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
Title check ✅ Passed The title 'feat(kimi): add kimi-code v0.11+ support with ~/.kimi-code paths' clearly and concisely summarizes the main feature being added: v0.11+ support with new directory paths.
Linked Issues check ✅ Passed All objectives from issue #782 are met: v0.11+ detection with directory preference, dynamic path resolution across all required methods, v0.11+ skills directory support, updated post-install messaging, system config scan integration, and agent builder/TUI updates.
Out of Scope Changes check ✅ Passed All changes are directly scoped to issue #782 requirements. New plugin installer interface and implementation support the v0.11+ architecture but remain focused on enabling correct path resolution and skills handling.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

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

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 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 `@internal/agents/kimi/adapter.go`:
- Around line 133-144: The detection for v0.11+ should use "is directory"
semantics instead of pathExists to avoid treating a file named ".kimi-code" as
the v11+ install; update the logic in resolveConfigDir and isV11Plus (and the
related check around Line 315) to call a.pathIsDir or a.isDir-equivalent (create
one if missing) when checking filepath.Join(homeDir, ".kimi-code"), and fall
back to ".kimi" only if ".kimi-code" is not a directory; ensure all references
consistently use the directory-check helper rather than pathExists.

In `@internal/system/config_scan.go`:
- Around line 31-36: The code currently falls back to the legacy path for any
os.Stat error; change the os.Stat(kimiDir) handling so you only fallback when
the entry truly doesn't exist or when it exists but is not a directory. Call fi,
err := os.Stat(kimiDir); if err == nil use kimiDir, if os.IsNotExist(err) set
kimiDir = filepath.Join(homeDir, ".kimi"), and if err != nil (but not
IsNotExist) do not silently switch to the legacy path (optionally return or log
the error); also if err == nil but !fi.IsDir() treat it like not-found and set
the legacy path—refer to kimiDir, homeDir, and the os.Stat call to locate and
update the logic.

In `@internal/tui/model.go`:
- Around line 3819-3820: The Kimi branch currently always returns
filepath.Join(home, ".kimi-code", "skills") which breaks legacy installs; update
the model.AgentKimi case to first detect and honor the legacy skills directory
(e.g. check for existence of the legacy path using os.Stat and os.IsNotExist)
and return the legacy path when present, otherwise return filepath.Join(home,
".kimi-code", "skills") as the new path; keep the same boolean return value and
use the same symbols (model.AgentKimi and the filepath.Join call) so behavior
matches the adapter’s legacy fallback.
🪄 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: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a8541e8d-6a75-44af-a13e-88b6c959573e

📥 Commits

Reviewing files that changed from the base of the PR and between f9154a0 and 03bd614.

⛔ Files ignored due to path filters (3)
  • openspec/changes/kimi-code-v0.11-support/design.md is excluded by !openspec/**
  • openspec/changes/kimi-code-v0.11-support/proposal.md is excluded by !openspec/**
  • openspec/changes/kimi-code-v0.11-support/tasks.md is excluded by !openspec/**
📒 Files selected for processing (6)
  • internal/agents/kimi/adapter.go
  • internal/agents/kimi/adapter_test.go
  • internal/catalog/agents.go
  • internal/skillregistry/registry.go
  • internal/system/config_scan.go
  • internal/tui/model.go

Comment thread internal/agents/kimi/adapter.go
Comment thread internal/system/config_scan.go
Comment thread internal/tui/model.go Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/agents/kimi/adapter.go (1)

370-387: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

KIMI.md is always overwritten without backup.

Per coding guidelines, writes to user config must have a backup/restore path. The current implementation always overwrites KIMI.md (and unconditionally writes AGENTS.md at Line 400). If users have made manual edits to these files, those changes are lost.

Consider either:

  1. Adding backup before overwrite (e.g., KIMI.md.bak)
  2. Checking for user modifications before overwriting
  3. Documenting that these files are fully managed and should not be edited
🤖 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 `@internal/agents/kimi/adapter.go` around lines 370 - 387, The KIMI.md write
unconditionally overwrites user files (see skeletonPath, a.SystemPromptFile,
a.resolveProjectAGENTSMD, a.sanitizeJinjaSyntax and the
filemerge.WriteFileAtomic call) so implement a safe overwrite: before writing,
check if the target exists and differs from the generated content and if so
create a timestamped backup (e.g., KIMI.md.bak.TIMESTAMP) and only then call
filemerge.WriteFileAtomic; alternatively, if the file was modified by the user,
either skip the overwrite and log a warning or prompt/return an error so the
user can merge — apply the same backup/skip logic to the AGENTS.md write path
and ensure error handling includes the backup filename for easy restore.

Source: Coding guidelines

🤖 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 `@internal/agents/kimi/adapter_test.go`:
- Around line 653-691: Add a test that covers pre-escaped Jinja content for
NewAdapter().sanitizeJinjaSyntax: include a case with input like "{{{{
already_escaped }}}}" and assert the sanitizer does not double-escape (i.e., the
sanitized output should be idempotent), and add an idempotence check that
sanitizeJinjaSyntax(sanitizeJinjaSyntax(input)) == sanitizeJinjaSyntax(input) to
catch double-escaping bugs in sanitizeJinjaSyntax.

In `@internal/agents/kimi/adapter.go`:
- Around line 423-431: The current Adapter.sanitizeJinjaSyntax sequential
replacements double-escape existing brace sequences and are not idempotent;
change sanitizeJinjaSyntax to perform a single-pass safe transform by first
protecting already-escaped sequences with temporary tokens (e.g., replace
literal "{{{{"/"}}}}"/"{{%"/"%}}" with placeholders), then perform the intended
escaping for unprotected "{{","}}","{%","%}", and finally restore the
placeholders — or use a single regex-based replacement that only matches
unescaped brace patterns; ensure the function (Adapter.sanitizeJinjaSyntax)
skips already-escaped sequences so repeated runs do not compound escaping.

---

Outside diff comments:
In `@internal/agents/kimi/adapter.go`:
- Around line 370-387: The KIMI.md write unconditionally overwrites user files
(see skeletonPath, a.SystemPromptFile, a.resolveProjectAGENTSMD,
a.sanitizeJinjaSyntax and the filemerge.WriteFileAtomic call) so implement a
safe overwrite: before writing, check if the target exists and differs from the
generated content and if so create a timestamped backup (e.g.,
KIMI.md.bak.TIMESTAMP) and only then call filemerge.WriteFileAtomic;
alternatively, if the file was modified by the user, either skip the overwrite
and log a warning or prompt/return an error so the user can merge — apply the
same backup/skip logic to the AGENTS.md write path and ensure error handling
includes the backup filename for easy restore.
🪄 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: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e1b80f69-bbdf-45ce-a5ea-95ce720aab2d

📥 Commits

Reviewing files that changed from the base of the PR and between 03bd614 and bf43405.

⛔ Files ignored due to path filters (8)
  • openspec/changes/archive/2026-06-12-kimi-code-v0.11-support/design.md is excluded by !openspec/**
  • openspec/changes/archive/2026-06-12-kimi-code-v0.11-support/proposal.md is excluded by !openspec/**
  • openspec/changes/archive/2026-06-12-kimi-code-v0.11-support/specs/adapter/spec.md is excluded by !openspec/**
  • openspec/changes/archive/2026-06-12-kimi-code-v0.11-support/specs/agents-md-injection/spec.md is excluded by !openspec/**
  • openspec/changes/archive/2026-06-12-kimi-code-v0.11-support/tasks.md is excluded by !openspec/**
  • openspec/changes/archive/2026-06-12-kimi-code-v0.11-support/verify-report.md is excluded by !openspec/**
  • openspec/specs/adapter/spec.md is excluded by !openspec/**
  • openspec/specs/agents-md-injection/spec.md is excluded by !openspec/**
📒 Files selected for processing (5)
  • internal/agents/kimi/adapter.go
  • internal/agents/kimi/adapter_test.go
  • internal/components/permissions/inject.go
  • internal/components/permissions/inject_test.go
  • internal/components/persona/inject_test.go

Comment thread internal/agents/kimi/adapter_test.go Outdated
Comment thread internal/agents/kimi/adapter.go Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@internal/agents/kimi/adapter.go`:
- Around line 149-151: isV11Plus currently only checks <home>/.kimi-code and
ignores any KIMI_CODE_HOME resolved by resolveConfigDir, causing v0.11+
installations to be misdetected; update Adapter.isV11Plus to first call
resolveConfigDir(homeDir) (or read KIMI_CODE_HOME if used elsewhere) and use
a.statPath on that resolved config dir, and return true if that stat indicates a
directory OR if statPath(filepath.Join(homeDir, ".kimi-code")) indicates a
directory; reference the isV11Plus, resolveConfigDir, and statPath symbols and
ensure the function returns true when either path exists as a directory so
SkillsDir/AllSkillsDirs routing and post-install messaging use the v0.11+
behavior.
🪄 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: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 238ab606-2ecc-4920-978e-428a053be6bd

📥 Commits

Reviewing files that changed from the base of the PR and between bf43405 and dc44c08.

📒 Files selected for processing (4)
  • internal/agents/kimi/adapter.go
  • internal/agents/kimi/adapter_test.go
  • internal/system/config_scan.go
  • internal/tui/model.go

Comment thread internal/agents/kimi/adapter.go Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
internal/agents/kimi/adapter.go (2)

136-144: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Inconsistent stat approach between env var and fallback checks.

The KIMI_CODE_HOME check (line 137) uses os.Stat directly, while the .kimi-code fallback (line 142) uses a.statPath. This makes the env var path untestable via the adapter's statPath stub.

For consistency and testability, consider using a.statPath for both:

Suggested fix
 func (a *Adapter) resolveConfigDir(homeDir string) string {
 	if envDir := os.Getenv("KIMI_CODE_HOME"); envDir != "" {
-		if info, err := os.Stat(envDir); err == nil && info.IsDir() {
+		if stat := a.statPath(envDir); stat.err == nil && stat.isDir {
 			return envDir
 		}
 	}
🤖 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 `@internal/agents/kimi/adapter.go` around lines 136 - 144, The env var path
check uses os.Stat directly which bypasses the adapter's test stub; update the
KIMI_CODE_HOME handling to call a.statPath(envDir) and use the returned stat.err
and stat.isDir the same way you do for kimiCodeDir, so both branches use the
adapter's statPath helper (refer to the envDir variable, the KIMI_CODE_HOME
check, a.statPath, and kimiCodeDir/stat handling).

410-424: ⚠️ Potential issue | 🟠 Major

Fix KIMI ${KIMI_AGENTS_MD} lookup to search the project root (not the user home)

  • kimiSystemPromptHubStep passes homeDir from osUserHomeDir() (user home) into kimi.NewAdapter().BootstrapTemplate(s.homeDir).
  • resolveProjectAGENTSMD(homeDir) only checks homeDir/AGENTS.md and homeDir/../AGENTS.md, so it will not find a typical workspace/project-root AGENTS.md.
  • Update BootstrapTemplate/callers so project-root resolution starts from the workspace/project directory (or implement “walk upward to project root” starting from there); any shared root-discovery logic should live in internal/components/ (not duplicated per-agent).
🤖 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 `@internal/agents/kimi/adapter.go` around lines 410 - 424, The KIMI AGENTS.md
lookup is using the user home (osUserHomeDir) via
kimi.NewAdapter().BootstrapTemplate(s.homeDir) and resolveProjectAGENTSMD only
checks homeDir and homeDir/.., so it misses the workspace/project root; update
callers (e.g., kimiSystemPromptHubStep) to pass the workspace/project directory
(not the user home) into Adapter.BootstrapTemplate and modify
resolveProjectAGENTSMD to walk upward from the provided start directory to
locate AGENTS.md (or implement a shared "find project root" helper) and return
the first found AGENTS.md; move the root-discovery helper into
internal/components so it can be reused by agents instead of duplicating logic.
🤖 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 `@internal/components/sdd/inject.go`:
- Around line 473-477: The code currently forces skillDir to
filepath.Join(pi.PluginDir(homeDir), "skills") whenever an adapter implements
agents.PluginInstaller, which overrides the adapter's own routing and breaks
legacy-mode fallback; change the logic in functions setting skillDir
(referencing skillDir, agents.PluginInstaller, and pi.PluginDir) to first use
adapter.SkillsDir(homeDir) as the source of truth and only switch to the plugin
subpath when the adapter explicitly indicates v0.11+ plugin behavior (e.g., via
an adapter-level version check or a dedicated method) so legacy adapters retain
adapter.SkillsDir(homeDir) unless the adapter explicitly opts into plugin
routing.

In `@internal/components/skills/inject_test.go`:
- Around line 381-398: Remove the unused test double struct
mockPluginInstallerAdapter and its methods (PluginDir, PluginManifestPath,
InstallPlugin, Agent) from internal/components/skills/inject_test.go since it is
never instantiated; simply delete the type definition and the associated method
implementations to satisfy golangci-lint and avoid the dead-code failure in CI.

---

Outside diff comments:
In `@internal/agents/kimi/adapter.go`:
- Around line 136-144: The env var path check uses os.Stat directly which
bypasses the adapter's test stub; update the KIMI_CODE_HOME handling to call
a.statPath(envDir) and use the returned stat.err and stat.isDir the same way you
do for kimiCodeDir, so both branches use the adapter's statPath helper (refer to
the envDir variable, the KIMI_CODE_HOME check, a.statPath, and kimiCodeDir/stat
handling).
- Around line 410-424: The KIMI AGENTS.md lookup is using the user home
(osUserHomeDir) via kimi.NewAdapter().BootstrapTemplate(s.homeDir) and
resolveProjectAGENTSMD only checks homeDir and homeDir/.., so it misses the
workspace/project root; update callers (e.g., kimiSystemPromptHubStep) to pass
the workspace/project directory (not the user home) into
Adapter.BootstrapTemplate and modify resolveProjectAGENTSMD to walk upward from
the provided start directory to locate AGENTS.md (or implement a shared "find
project root" helper) and return the first found AGENTS.md; move the
root-discovery helper into internal/components so it can be reused by agents
instead of duplicating logic.
🪄 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: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f4346668-0876-4ca3-892e-3b53404e1e8f

📥 Commits

Reviewing files that changed from the base of the PR and between dc44c08 and 2370c96.

⛔ Files ignored due to path filters (4)
  • openspec/changes/kimi-plugin-architecture/design.md is excluded by !openspec/**
  • openspec/changes/kimi-plugin-architecture/proposal.md is excluded by !openspec/**
  • openspec/changes/kimi-plugin-architecture/specs/adapter/spec.md is excluded by !openspec/**
  • openspec/changes/kimi-plugin-architecture/specs/kimi-plugin-installer/spec.md is excluded by !openspec/**
📒 Files selected for processing (10)
  • internal/agents/interface.go
  • internal/agents/kimi/adapter.go
  • internal/agents/kimi/adapter_test.go
  • internal/agents/kimi/plugin.go
  • internal/agents/kimi/plugin_test.go
  • internal/agents/kimi/test_helpers.go
  • internal/components/sdd/inject.go
  • internal/components/sdd/inject_test.go
  • internal/components/skills/inject.go
  • internal/components/skills/inject_test.go

Comment thread internal/components/sdd/inject.go Outdated
Comment thread internal/components/skills/inject_test.go Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
internal/agents/kimi/adapter.go (2)

407-410: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Propagate unreadable AGENTS.md errors instead of writing the placeholder.

resolveProjectAGENTSMD() treats every ReadFile failure as “not found”. If AGENTS.md exists but is unreadable, bootstrap silently injects the placeholder and persists that placeholder into the config-side AGENTS.md, which hides the real filesystem error and writes the wrong content.

Suggested fix
-func (a *Adapter) resolveProjectAGENTSMD(homeDir string) string {
+func (a *Adapter) resolveProjectAGENTSMD(homeDir string) (string, error) {
 	candidates := []string{
 		filepath.Join(homeDir, "AGENTS.md"),
 		filepath.Join(homeDir, "..", "AGENTS.md"),
 	}
 	for _, path := range candidates {
 		data, err := os.ReadFile(path)
 		if err == nil {
-			return string(data)
+			return string(data), nil
+		}
+		if !os.IsNotExist(err) {
+			return "", fmt.Errorf("read %s: %w", path, err)
 		}
 	}
-	return "<!-- No project AGENTS.md found -->"
+	return "<!-- No project AGENTS.md found -->", nil
 }
-	agentsMDContent := a.resolveProjectAGENTSMD(homeDir)
+	agentsMDContent, err := a.resolveProjectAGENTSMD(homeDir)
+	if err != nil {
+		return err
+	}

Also applies to: 423-429

🤖 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 `@internal/agents/kimi/adapter.go` around lines 407 - 410, The code in
resolveProjectAGENTSMD currently treats any ReadFile error as “not found” and
falls back to a placeholder which is then written out (see
resolveProjectAGENTSMD and the ReadFile calls), so if an existing AGENTS.md is
unreadable we silently overwrite it; change resolveProjectAGENTSMD to
distinguish os.IsNotExist errors from other read errors and return/propagate
non-NotExist errors upward instead of returning the placeholder, and ensure
callers that write the file (the branch that computes agentsMDOutPath and calls
filemerge.WriteFileAtomic) only write when the content was successfully read or
intentionally generated; apply the same change for the other ReadFile usage
referenced around the 423-429 region so unreadable-file errors are surfaced
instead of saved over with a placeholder.

207-214: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Honor the resolved config dir in AllSkillsDirs().

When KIMI_CODE_HOME points outside homeDir, isV11Plus() takes the v0.11+ branch, but this second entry still hard-codes homeDir/.kimi-code/skills. That makes discovery miss <KIMI_CODE_HOME>/skills and scan the wrong tree instead.

Suggested fix
 func (a *Adapter) AllSkillsDirs(homeDir string) []string {
 	if a.isV11Plus(homeDir) {
+		configDir := a.resolveConfigDir(homeDir)
 		return []string{
 			filepath.Join(a.PluginDir(homeDir), "skills"),
-			filepath.Join(homeDir, ".kimi-code", "skills"),
+			filepath.Join(configDir, "skills"),
 			filepath.Join(homeDir, ".agents", "skills"),
 			filepath.Join(homeDir, ".config", "agents", "skills"),
 		}
 	}
 	return []string{filepath.Join(homeDir, ".config", "agents", "skills")}
 }
🤖 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 `@internal/agents/kimi/adapter.go` around lines 207 - 214, AllSkillsDirs
currently hard-codes homeDir+"/.kimi-code/skills" in the v0.11+ branch which
ignores an externally set KIMI_CODE_HOME; update that entry to use the resolved
config/plugin directory instead of the hard-coded path (use the same resolver
used elsewhere in this file — e.g. call a.PluginDir(homeDir) or the existing
helper that returns the resolved KIMI_CODE_HOME) so the second entry becomes
filepath.Join(<resolvedKimiCodeDir>, "skills") (make the change inside
AllSkillsDirs and keep isV11Plus logic intact).
🤖 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 `@internal/components/sdd/inject_test.go`:
- Around line 1067-1072: The test is too permissive: although you create the
v0.11+ directory, assertions still accept legacy fallbacks which hides
regressions in resolveConfigDir; update the test in inject_test.go to assert
only the v0.11+ destinations by validating sddModulePath resolves to
~/.kimi-code/sdd-orchestrator.md and the plugin skills path resolves to the
v0.11+ plugin location (do not accept ~/.kimi or ~/.config/agents/skills), and
move/clone the legacy fallback assertions into a separate legacy-only test case
that sets up the legacy directories and asserts the legacy paths; ensure you
reference resolveConfigDir (or the calling helper used in the test) and the test
helpers that create ~/.kimi-code so the assertions strictly check the v0.11+
behavior.

---

Outside diff comments:
In `@internal/agents/kimi/adapter.go`:
- Around line 407-410: The code in resolveProjectAGENTSMD currently treats any
ReadFile error as “not found” and falls back to a placeholder which is then
written out (see resolveProjectAGENTSMD and the ReadFile calls), so if an
existing AGENTS.md is unreadable we silently overwrite it; change
resolveProjectAGENTSMD to distinguish os.IsNotExist errors from other read
errors and return/propagate non-NotExist errors upward instead of returning the
placeholder, and ensure callers that write the file (the branch that computes
agentsMDOutPath and calls filemerge.WriteFileAtomic) only write when the content
was successfully read or intentionally generated; apply the same change for the
other ReadFile usage referenced around the 423-429 region so unreadable-file
errors are surfaced instead of saved over with a placeholder.
- Around line 207-214: AllSkillsDirs currently hard-codes
homeDir+"/.kimi-code/skills" in the v0.11+ branch which ignores an externally
set KIMI_CODE_HOME; update that entry to use the resolved config/plugin
directory instead of the hard-coded path (use the same resolver used elsewhere
in this file — e.g. call a.PluginDir(homeDir) or the existing helper that
returns the resolved KIMI_CODE_HOME) so the second entry becomes
filepath.Join(<resolvedKimiCodeDir>, "skills") (make the change inside
AllSkillsDirs and keep isV11Plus logic intact).
🪄 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: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c39cf45f-a652-4169-b679-bf8bff2cf561

📥 Commits

Reviewing files that changed from the base of the PR and between 2370c96 and fc8b62a.

⛔ Files ignored due to path filters (6)
  • openspec/changes/archive/2026-06-12-kimi-plugin-architecture/design.md is excluded by !openspec/**
  • openspec/changes/archive/2026-06-12-kimi-plugin-architecture/proposal.md is excluded by !openspec/**
  • openspec/changes/archive/2026-06-12-kimi-plugin-architecture/specs/adapter/spec.md is excluded by !openspec/**
  • openspec/changes/archive/2026-06-12-kimi-plugin-architecture/specs/kimi-plugin-installer/spec.md is excluded by !openspec/**
  • openspec/specs/adapter/spec.md is excluded by !openspec/**
  • openspec/specs/kimi-plugin-installer/spec.md is excluded by !openspec/**
📒 Files selected for processing (4)
  • internal/agents/kimi/adapter.go
  • internal/agents/kimi/adapter_test.go
  • internal/components/sdd/inject_test.go
  • internal/components/skills/inject_test.go
💤 Files with no reviewable changes (1)
  • internal/components/skills/inject_test.go

Comment thread internal/components/sdd/inject_test.go Outdated
@salema97

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@salema97 salema97 marked this pull request as draft June 15, 2026 06:07
@salema97 salema97 marked this pull request as ready for review June 15, 2026 06:07
salema97 added 11 commits June 16, 2026 05:23
Detect and prefer ~/.kimi-code (Node.js v0.11+) over legacy ~/.kimi (Python/uv).
All path methods now resolve dynamically based on directory presence:
- GlobalConfigDir, SystemPromptDir, SystemPromptFile
- SettingsPath, MCPConfigPath, SubAgentsDir
- SkillsDir returns ~/.kimi-code/skills for v0.11+, keeps shared path for legacy
- PostInstallMessage omits --agent-file for v0.11+ (feature removed)
- ConfigPath standalone function updated with same resolution logic

Also updates system config scan and TUI agent builder skills dir.

Closes: TBD (issue will be created)
Refs: openspec/changes/kimi-code-v0.11-support
Ensures skills installed in the v0.11+ native directory are discovered
by the skill registry scanner alongside legacy paths.

Refs: openspec/changes/kimi-code-v0.11-support
Reflects the v0.11+ path as the primary config location in agent metadata.

Refs: openspec/changes/kimi-code-v0.11-support
Updates openspec tasks with completed work including skill registry
and catalog changes discovered during implementation.

Refs: openspec/changes/kimi-code-v0.11-support
…fig.toml, and AGENTS.md injection

- Respect KIMI_CODE_HOME env var for custom data directory
- Write functional config.toml with merge_all_available_skills and permission rules
- Inject AGENTS.md via resolveProjectAGENTSMD with Jinja sanitization
- Add AllSkillsDirs method for complete skills scan directory discovery
- Add 28 new tests covering all spec scenarios (strict TDD)
- Archive SDD change to openspec/changes/archive/
…y fallback

- resolveConfigDir/isV11Plus: use statPath with isDir check instead of pathExists
- config_scan: fallback to ~/.kimi only on IsNotExist, not all stat errors
- tui/model.go: add legacy skills dir fallback for AgentKimi
- adapter_test.go: update V11Plus mocks to simulate .kimi-code as directory
- Add PluginInstaller optional interface for plugin-based distribution
- Implement Kimi plugin manifest generation (kimi.plugin.json)
- Write skills to plugin directory (~/.kimi-code/plugins/managed/gentle-ai/)
- Bundle Engram MCP server in plugin manifest
- Add sessionStart hook to auto-load sdd-orchestrator
- Update inject flow to use plugin dir when adapter implements PluginInstaller
- Fix cross-platform line ending issues in tests
- Update Kimi inject test to check both v0.11+ and legacy paths
- Add SDD specs and design for plugin architecture
- isV11Plus: respect KIMI_CODE_HOME env var for v0.11+ detection
- sanitizeJinjaSyntax: use placeholder tokens for idempotent escaping
- sdd/inject.go: remove redundant interface-presence override
- skills/inject_test.go: remove unused mockPluginInstallerAdapter
- adapter_test.go: add pre-escaped Jinja tests and idempotence check
- sdd/inject_test.go: fix test to use correct v0.11+ paths
- Archive kimi-plugin-architecture SDD change
Remove legacy fallback paths from TestInjectKimiWritesNativeAgentFilesAndGlobalSkills.
Since .kimi-code is created in the test, assert only v0.11+ destinations
to prevent masking resolveConfigDir regressions.
…kill-registry

- Add versions.GentleAI constant for plugin manifest versioning
- Wire BootstrapTemplate to call InstallPlugin for v0.11+
- Create skills/ subdirectory in plugin during InstallPlugin
- Add [[hooks]] sessionStart and extra_skill_dirs to config.toml
- Add Kimi case to installSkillRegistryAutomation
- Graceful fallback: bootstrap warns but doesn't fail on plugin error
- 27 new tests covering v0.11+ wiring, legacy guard, config.toml content
- Archive kimi-plugin-completion SDD change
@salema97 salema97 force-pushed the feat/kimi-code-v0.11-support branch from 6b81bf7 to 0be1af4 Compare June 16, 2026 10:28
- Fix invalid TOML hook quoting in config.toml (SessionStart + single-quoted
  command) and repair previously malformed hook blocks.
- Merge v0.11+ extra_skill_dirs into existing config.toml instead of only
  appending them on fresh files.
- Register the gentle-ai plugin in ~/.kimi-code/plugins/installed.json so Kimi
  loads it on startup.
- Align kimi.plugin.json with the official schema: skills as string,
  sessionStart.skill, and no mcpServers (Engram is provided by the Engram
  component via ~/.kimi-code/mcp.json to keep the canonical 'engram' name).
- Bound AGENTS.md search to the project root so it does not escape into parent
  directories.
- Respect adapter.SkillsDir for Kimi instead of overriding it via
  PluginInstaller, avoiding creation of ~/.kimi-code on legacy installs.
- Make Kimi persona test hermetic and normalize CRLF in the tone-section
  comparison test.
@Alan-TheGentleman Alan-TheGentleman added the type:feature New feature label Jun 17, 2026

@Alan-TheGentleman Alan-TheGentleman left a comment

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.

I’m requesting changes because the current global config write crosses a provider boundary. BootstrapTemplate() copies cwd-derived AGENTS.md into global Kimi config, so running install from an untrusted repo can persist repo-controlled instructions into future sessions. Please keep project instructions project-scoped or require an explicit trust step before writing them globally. Also route plugin registration and skill discovery through the resolved Kimi config dir so KIMI_CODE_HOME does not split config, plugins, and skills across different trees.

@salema97

salema97 commented Jun 17, 2026

Copy link
Copy Markdown
Author

Thanks for the clear security/architecture feedback. Both concerns should now be addressed in the latest push.

1. Project instructions are now project-scoped

BootstrapTemplate() no longer reads AGENTS.md from the cwd, and it no longer writes cwd-derived content to the global Kimi config (~/.kimi-code/AGENTS.md or ~/.kimi/AGENTS.md). Instead, ${KIMI_AGENTS_MD} is replaced with a static placeholder that tells Kimi to respect the current worktree's AGENTS.md at runtime. This removes the provider-boundary crossing and the untrusted-repo persistence risk.

2. Plugin and skill paths now route through resolveConfigDir

All v0.11+ plugin and skill paths are now rooted under the resolved Kimi config directory, so KIMI_CODE_HOME no longer splits config, plugins, and skills:

  • PluginDir() uses resolveConfigDir(homeDir) instead of hardcoding ~/.kimi-code.
  • registerPlugin() writes installed.json under the same resolved directory.
  • AllSkillsDirs() uses resolveConfigDir(homeDir) for the user skills directory.

Tests added for the new KIMI_CODE_HOME behavior and for the project-scoped AGENTS.md handling. go test ./internal/agents/kimi/... ./internal/components/persona/... passes.

Let me know if you'd prefer an explicit trust step instead of the project-scoped approach, or if anything else looks off.

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

Labels

type:feature New feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(kimi): Add support for kimi-code v0.11+ (Node.js rewrite)

2 participants