Summary
src/manifest/kimi.ts (detectKimiCode()) reads the generic, cross-tool shared skills shelf — ~/.agents/skills (user scope) and .agents/skills (project scope) — and attributes everything it finds there to client: 'kimi-code'. Nothing in detectKimiCode() or the detect() orchestrator (src/manifest/index.ts) checks that Kimi Code is actually installed (no gate on ~/.kimi-code/ or the kimi binary) before doing so. ~/.agents/skills genuinely is one of Kimi Code's own documented discovery roots, so this isn't fabricated data — but it's reported with more specificity (one named product) than the evidence supports, since the same path is natively read by many other tools.
Reachability — confirmed two ways, different severity by scope
Project scope is unconditional. In detect(), Claude Code's project scanner reads .claude/skills; Codex has no project-scope skills root at all (per its own doc comment); Cursor has no skills detection whatsoever. Kimi Code's scanner is the only one that reads .agents/skills. Any project directory containing a populated .agents/skills/ is attributed entirely to Kimi Code, 100% of the time, regardless of whether Kimi is installed anywhere.
User scope is only masked by coincidence. ~/.claude/skills and ~/.codex/skills are typically symlink farms into the same canonical ~/.agents/skills directory. Since detect() scans Claude Code before Kimi Code and dedupe() keys on resolved (symlink-following) path, a shelf reachable through all three normally surfaces once, under Claude Code — masking the Kimi attribution as a side effect of scan order, not a real gate. The test suite already proves this isn't robust: test/unit/manifest/kimi.skills.test.ts, describe block 'shared shelf — Claude Code, Codex, and Kimi Code all reach one directory', the second test — 'a skill only Kimi Code reaches (no Claude/Codex farm entry) still appears, under Kimi Code' — is exactly the phantom case, asserted as current expected behavior.
Who's actually exposed
This isn't a narrow Kimi-specific edge case. Independently confirmed as native, first-party behavior in the official docs or source of at least 10 other AI coding CLIs — OpenCode, Gemini CLI, Cline, Roo Code, Windsurf/Devin Desktop, Zed, Goose, Amp, Crush, and Factory all read .agents/skills and/or ~/.agents/skills natively. Separately, skills.sh (vercel-labs/skills, 27k+ GitHub stars) assigns that same global path as the shared install target for several of its 70+ supported agents whenever the target tool has no established convention of its own (its own compatibility table names Cline, Dexto, Kimi Code CLI, Loaf, Warp, and Zed sharing one global path).
Concretely exposed: anyone with populated content at ~/.agents/skills or .agents/skills — installed via any of the above tools, via skills.sh targeting any tool except Kimi, or hand-curated (exactly the shape of a personal cross-tool skill shelf, independent of any specific tool) — who doesn't also run Claude Code/Codex with a farm pointed at that same canonical directory.
Suggested fix shape
Not prescribing the implementation, just the shape that would close the gap: gate the generic root reads (~/.agents/skills, .agents/skills) on Kimi's own install marker (~/.kimi-code/ existing, or the kimi binary on PATH) before attributing hits there to kimi-code — while leaving the brand root (~/.kimi-code/skills, .kimi-code/skills) ungated, since that path is exclusively Kimi's regardless. Absent that gate, a hit on the generic root with no other client's farm resolving to it might be better reported as an unbranded "shared agent-skills shelf" entry than attributed to a specific product name the evidence doesn't actually support.
Sources
Full research (12-tool support matrix, convergence analysis, citations): knowledge/research/2026-08-03-devcat-ai-cli-scanner-matrix.md in AnobleSCM/knowledge-stack (merge pending — blocked on a stale required-review ruleset with no configured reviewer, flagged separately).
Summary
src/manifest/kimi.ts(detectKimiCode()) reads the generic, cross-tool shared skills shelf —~/.agents/skills(user scope) and.agents/skills(project scope) — and attributes everything it finds there toclient: 'kimi-code'. Nothing indetectKimiCode()or thedetect()orchestrator (src/manifest/index.ts) checks that Kimi Code is actually installed (no gate on~/.kimi-code/or thekimibinary) before doing so.~/.agents/skillsgenuinely is one of Kimi Code's own documented discovery roots, so this isn't fabricated data — but it's reported with more specificity (one named product) than the evidence supports, since the same path is natively read by many other tools.Reachability — confirmed two ways, different severity by scope
Project scope is unconditional. In
detect(), Claude Code's project scanner reads.claude/skills; Codex has no project-scope skills root at all (per its own doc comment); Cursor has no skills detection whatsoever. Kimi Code's scanner is the only one that reads.agents/skills. Any project directory containing a populated.agents/skills/is attributed entirely to Kimi Code, 100% of the time, regardless of whether Kimi is installed anywhere.User scope is only masked by coincidence.
~/.claude/skillsand~/.codex/skillsare typically symlink farms into the same canonical~/.agents/skillsdirectory. Sincedetect()scans Claude Code before Kimi Code anddedupe()keys on resolved (symlink-following) path, a shelf reachable through all three normally surfaces once, under Claude Code — masking the Kimi attribution as a side effect of scan order, not a real gate. The test suite already proves this isn't robust:test/unit/manifest/kimi.skills.test.ts, describe block'shared shelf — Claude Code, Codex, and Kimi Code all reach one directory', the second test —'a skill only Kimi Code reaches (no Claude/Codex farm entry) still appears, under Kimi Code'— is exactly the phantom case, asserted as current expected behavior.Who's actually exposed
This isn't a narrow Kimi-specific edge case. Independently confirmed as native, first-party behavior in the official docs or source of at least 10 other AI coding CLIs — OpenCode, Gemini CLI, Cline, Roo Code, Windsurf/Devin Desktop, Zed, Goose, Amp, Crush, and Factory all read
.agents/skillsand/or~/.agents/skillsnatively. Separately, skills.sh (vercel-labs/skills, 27k+ GitHub stars) assigns that same global path as the shared install target for several of its 70+ supported agents whenever the target tool has no established convention of its own (its own compatibility table names Cline, Dexto, Kimi Code CLI, Loaf, Warp, and Zed sharing one global path).Concretely exposed: anyone with populated content at
~/.agents/skillsor.agents/skills— installed via any of the above tools, via skills.sh targeting any tool except Kimi, or hand-curated (exactly the shape of a personal cross-tool skill shelf, independent of any specific tool) — who doesn't also run Claude Code/Codex with a farm pointed at that same canonical directory.Suggested fix shape
Not prescribing the implementation, just the shape that would close the gap: gate the generic root reads (
~/.agents/skills,.agents/skills) on Kimi's own install marker (~/.kimi-code/existing, or thekimibinary on PATH) before attributing hits there tokimi-code— while leaving the brand root (~/.kimi-code/skills,.kimi-code/skills) ungated, since that path is exclusively Kimi's regardless. Absent that gate, a hit on the generic root with no other client's farm resolving to it might be better reported as an unbranded "shared agent-skills shelf" entry than attributed to a specific product name the evidence doesn't actually support.Sources
src/manifest/kimi.ts,src/manifest/index.ts,test/unit/manifest/kimi.skills.test.ts— read fromorigin/main(matches the published0.2.3npm release), 2026-08-03~/.agents/skillsas a native discovery root: https://moonshotai.github.io/kimi-code/en/customization/skills.htmlFull research (12-tool support matrix, convergence analysis, citations):
knowledge/research/2026-08-03-devcat-ai-cli-scanner-matrix.mdinAnobleSCM/knowledge-stack(merge pending — blocked on a stale required-review ruleset with no configured reviewer, flagged separately).