Summary
The kilo plugin <module> command (alias kilo plug) installs an npm plugin and patches a config file to register it. The directory and filename it writes to are hardcoded to the upstream opencode names rather than the Kilo equivalents.
Current behavior
From packages/opencode/src/plugin/install.ts:333-343:
```ts
function patchDir(input: PatchInput) {
if (input.global) return input.config ?? Global.Path.config
const git = input.vcs === "git" && input.worktree !== "/"
const root = git ? input.worktree : input.directory
return path.join(root, ".opencode")
}
function patchName(kind: Kind): "opencode" | "tui" {
if (kind === "server") return "opencode"
return "tui"
}
```
This means:
| Scope |
Directory |
Filename |
| Local |
`/.opencode` |
`opencode.{json,jsonc}` / `tui.{json,jsonc}` |
| `--global` |
`~/.config/kilo/` |
`opencode.{json,jsonc}` / `tui.{json,jsonc}` |
So even in a Kilo project that uses `kilo.json` and `.kilo/`, `kilo plugin ` will create or modify `.opencode/opencode.json(c)`. Users who configure plugins manually in `kilo.json` and then run `kilo plugin` to add another one end up with their config split across two files.
Expected behavior
`kilo plugin` should prefer Kilo-named config when available:
- If `kilo.json(c)` / `tui.json(c)` exists in the chosen scope, write there.
- If `.kilo/` exists locally, prefer it over `.opencode/`.
- Fall back to `.opencode/` and `opencode.json(c)` only when no Kilo-named config is present (preserving upstream compatibility).
Notes
- The plugin loader already reads from `kilo.json`, `opencode.json`, `.kilo/`, `.kilocode/`, and `.opencode/` (see `packages/opencode/src/config/config.ts:1615-1630` and `packages/opencode/src/config/paths.ts:21-33`). Only the `kilo plugin` install command is out of sync.
- Related code: `packages/opencode/src/plugin/install.ts`, `packages/opencode/src/cli/cmd/plug.ts`.
Docs
The plugin docs page (`packages/kilo-docs/pages/automate/extending/plugins.md`) currently documents the actual `.opencode/*.jsonc` write behavior. When this is fixed, that page must be updated in the same PR to reflect the new (Kilo-preferred) write paths.
Found while reviewing #9284.
Summary
The
kilo plugin <module>command (aliaskilo plug) installs an npm plugin and patches a config file to register it. The directory and filename it writes to are hardcoded to the upstream opencode names rather than the Kilo equivalents.Current behavior
From
packages/opencode/src/plugin/install.ts:333-343:```ts
function patchDir(input: PatchInput) {
if (input.global) return input.config ?? Global.Path.config
const git = input.vcs === "git" && input.worktree !== "/"
const root = git ? input.worktree : input.directory
return path.join(root, ".opencode")
}
function patchName(kind: Kind): "opencode" | "tui" {
if (kind === "server") return "opencode"
return "tui"
}
```
This means:
So even in a Kilo project that uses `kilo.json` and `.kilo/`, `kilo plugin ` will create or modify `.opencode/opencode.json(c)`. Users who configure plugins manually in `kilo.json` and then run `kilo plugin` to add another one end up with their config split across two files.
Expected behavior
`kilo plugin` should prefer Kilo-named config when available:
Notes
Docs
The plugin docs page (`packages/kilo-docs/pages/automate/extending/plugins.md`) currently documents the actual `.opencode/*.jsonc` write behavior. When this is fixed, that page must be updated in the same PR to reflect the new (Kilo-preferred) write paths.
Found while reviewing #9284.