Skip to content

Standardize coding-agent configuration via a dedicated kelos-dev tool (instructions, MCP, skills, hooks, settings) #1237

@gjkim42

Description

@gjkim42

Problem

There is no standard way to manage coding-agent configuration across the agents Kelos supports (claude-code, codex, gemini, cursor, opencode). The pieces a user wants to define once — instructions (AGENTS.md), MCP servers, skills, hooks, and settings/permissions — must today be expressed in each agent's own native format and location.

Inside Kelos this capability half-exists:

  • AgentConfig is the neutral config model.
  • Each */kelos_entrypoint.sh is a bespoke translation layer.
  • docs/agent-image-interface.md is the contract (KELOS_* env vars).

But the translation logic is duplicated across five shell scripts, coverage is incomplete (no hooks, no settings; MCP missing for opencode; no Claude plugin marketplace — see #503), and it's locked inside Kelos so nothing else can reuse it. This also surfaces as recurring config drift/alignment work (#601, #300, #1208).

Proposal

Extract the neutral-config → per-agent-native translation into a standalone, general-purpose tool in the kelos-dev org, and make Kelos its first adopter.

Confirmed direction (from design discussion):

  • Model: neutral-only abstraction — one neutral schema, translated to each agent; no-op (logged) where an agent lacks the concept.
  • Form: a single static Go binary (baked into agent images, called by entrypoints) that is also importable as a Go library by the controller.
  • Schema ownership: the tool owns the canonical neutral schema; Kelos's AgentConfig maps onto it.
  • Audience: general-purpose OSS standard; Kelos is the first consumer. Align with AGENTS.md + MCP conventions.

Tool surface (v1)

  • apply --agent <type> [--home DIR] [--project DIR] -f config.yaml — render the neutral config into the target agent's native files. (Core call for entrypoints.)
  • render --agent <type> -f config.yaml — dry-run; print what would be written.
  • validate -f config.yaml — schema validation, fail fast.
  • Library API Apply(cfg, agent, targets) for in-process use by the controller / kelos --dry-run.
  • Later: import (native → neutral) and verify (drift detection).

Verified per-agent translation matrix

Dimension claude-code codex gemini cursor opencode
Instructions ~/.claude/CLAUDE.md, .claude/CLAUDE.md AGENTS.md (+~/.codex/AGENTS.md) GEMINI.md/AGENTS.md .cursor/rules/*.mdc + AGENTS.md AGENTS.md (+~/.config/opencode/AGENTS.md)
MCP ~/.claude.json/.mcp.json JSON mcpServers config.toml [mcp_servers.*] (TOML) settings.json mcpServers ~/.cursor/mcp.json mcpServers opencode.json mcp (diff shape: type, command:[], environment)
Skills .claude/skills/<n>/SKILL.md .agents/skills/ .gemini/skills/ or .agents/skills/ .cursor/skills/ (+ .agents/skills/) .opencode/skills/ (+ .claude/skills/, .agents/skills/)
Hooks settings.json hooks (PreToolUse/…) [hooks] in config.toml (command only) settings.json hooks (BeforeTool/…) .cursor/hooks.json (beforeShellExecution/…) ⚠️ no declarative hooks (plugin system only)
Settings/perms settings.json: permissions{allow,ask,deny}, env, model, enabledPlugins, extraKnownMarketplaces config.toml: approval_policy, sandbox_mode, model settings.json: mcp.allowed/excluded, model ⚠️ interactive approval only (no verified declarative perms file) opencode.json: per-tool permission, model

Portability: instructions + skills (SKILL.md; .agents/skills/ is a shared alias) are cheap; MCP is one neutral schema + minor shaping; hooks and settings genuinely diverge (four hook taxonomies, opencode has none, cursor has no declarative perms) so the neutral schema there is a deliberately-small common subset, translated where supported and skipped-with-a-log elsewhere. Ship those last.

Neutral schema sketch

instructions: |            # → CLAUDE.md / AGENTS.md / GEMINI.md / .cursor/rules/*.mdc
  # project rules
mcpServers:                # JSON shape; → TOML for codex, command:[]/environment for opencode
  github: { type: stdio, command: gh, args: [...], env: {...} }
skills:                    # local SKILL.md bundles + skills.sh refs
  - { name: deploy, content: "..." }
  - { source: owner/repo }
hooks:                     # small common event set; skipped+logged on opencode
  - { event: PreToolUse, matcher: Bash, command: ["..."] }
settings:                  # common subset only; lossy
  permissions: { allow: [...], ask: [...], deny: [...] }
  env: { KEY: value }
  model: <name>

Roadmap (one PR per step; additive, backward-compatible)

  • Phase 0 — Tool to parity. Build the tool covering exactly today's Kelos behavior (instructions, skills/plugins dir, MCP) for all five agents. Golden-file tests per adapter. Tag a release.
  • Phase 1 — Adopt in Kelos, no behavior change. Bake the binary into the five images; replace the translation shell in each entrypoint with <tool> apply. Existing KELOS_* interface and AgentConfig fields unchanged. Gate on existing e2e (test/e2e/skills_test.go, MCP/plugin tests) proving identical output. (Note: current entrypoints predate some conventions, e.g. codex skills at ~/.codex/skills/... rather than .agents/skills/; Phase 1 reproduces current behavior 1:1, modernization is a tracked Phase-2 follow-up — not a silent change.)
  • Phase 2 — Close gaps (one dimension per PR): (1) opencode MCP parity; (2) hooks; (3) settings/permissions (folds in the Claude plugin marketplace as enabledPlugins + extraKnownMarketplaces, i.e. the support github plugin in AgentConfig #503 ask, as a settings sub-case).
  • Phase 3 — Make it the standard. Rewrite docs/agent-image-interface.md around the tool; deprecate the duplicated shell.

Prior art / why a new tool (honest)

This is not greenfield. rulesync (npm, 30+ agents) already covers all five dimensions across all five target agents, but is a stateless one-shot generator and npm-distributed (a Node runtime in every agent image). Others cover subsets: coder-config (drops cursor + opencode), agent_sync (bash), ai-rules-sync (symlinks), agent-rules-sync (python daemon), vercel-labs/skills (skills only). AGENTS.md is a standard, not a tool.

Defensible reasons to build new for Kelos: (1) a Go static binary embeds in images and is importable by the Go controller (npm/bash/python are not); (2) depth/correctness of MCP/hooks/permissions over instructions-first breadth; (3) a verify/drift mode. If those don't outweigh adopting/extending rulesync, that's the cheapest point to pivot.

Open questions

  • Build new vs. adopt/extend rulesync.
  • Tool name + repo under kelos-dev.
  • Phase 1 transport: keep per-dimension KELOS_* vars vs. one KELOS_AGENT_CONFIG neutral blob (leaning: introduce the blob, keep old vars during a deprecation window).
  • Final neutral schema field names (align to AGENTS.md/MCP before tagging v0.1).

Related: #503 (marketplace), #601 (config alignment), #300 (opencode parity), #1208 (agentsMD path varies by agent).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions