Skip to content

rgdevme/luxia

Repository files navigation

agnos

One config. Every coding agent.
Project-level configuration for AI coding agents, materialized into whatever each tool expects to find on disk.

CI downloads node agent friendly license


What is agnos?

agnos is a project-level configuration manager for AI coding agents. You declare your docs, rules, skills, MCP servers, and hooks once in a single agnos.json at the root of your repo. agnos materializes that declaration into whatever each agent expects to find on disk: CLAUDE.md + .mcp.json + .claude/settings.json for Claude Code, AGENTS.md + .codex/config.toml for OpenAI Codex, GEMINI.md + .gemini/settings.json for Gemini CLI, and so on.

agnos ships as a single package (@luxia/agnos) with a fixed, built-in set of agents (Claude Code, Codex, Gemini CLI) and domains (docs, rules, skills, mcp, hooks, agents). Point it at your project, run it once, or leave it in watch mode: every agent's files stay in sync with your one source of truth.

What does it solve?

Every coding agent invents its own on-disk configuration format. Keeping them consistent by hand is tedious and error-prone:

  • Drift: CLAUDE.md and AGENTS.md say different things because you updated one and forgot the other.
  • Duplication: the same MCP server, the same hook, the same rule copied into three tool-specific files with three different syntaxes.
  • Onboarding cost: adding a new agent to a repo means learning yet another file layout and hand-translating everything you already wrote.
  • No single source of truth: nothing in the repo tells you what the intended configuration is; it's scattered across whatever files each tool happens to read.

agnos collapses all of that into one declarative agnos.json. You edit intent; agnos renders the per-agent reality. Adding an agent becomes "render its files"; removing one becomes "delete its files."

Table of contents

Features

  • 🎯 One source of truth: declare docs, rules, skills, MCP servers, and hooks once in agnos.json.
  • πŸ”Œ Multi-agent output: renders native files for Claude Code, OpenAI Codex, and Gemini CLI from the same config.
  • πŸ‘€ Watch mode: a per-domain watcher tree keeps agent files in sync as your sources change; edit a rule fragment and the canonical files re-render.
  • 🧩 Composable rules: inject titled sections (by frontmatter title) from fragment files into your canonical rules file, preserving your hand-written sections.
  • πŸ“š Docs index: compile a metadata index from your docs directory and surface it to agents.
  • πŸ“¦ Skills management: fetch, pin, verify, and update agent skills from GitHub/GitLab/Bitbucket or local paths, linked per-agent.
  • πŸ›°οΈ MCP registry integration: search and add MCP servers from the registry, or configure them manually; agnos renders them per-agent.
  • πŸͺ Portable hooks: declare command hooks once against a normalized event vocabulary; each agent gets them in its native format.
  • ♻️ Migrate what you already have: import existing MCP servers, hooks, and skills from your agents' current config into agnos.json.
  • πŸ§ͺ Dry runs: --dry shows exactly what would change without writing anything.

The model: config writers + one config reader

agnos splits its work in two:

  • Config-writer domains manage their own slice of the project. skills/mcp/hooks write entries into agnos.json; docs compiles a documentation index; rules injects titled sections into your canonical rules file(s).
  • One config-reader domain, agents: reads agnos.json and the canonical outputs and renders every per-agent native file via per-agent adapters. Installing an agent is just "render its files"; removing it is "delete its files."
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ config WRITERS ────────────┐      β”Œβ”€β”€ reader ──┐
 docs ──▢ .docs/index.md                                 β”‚            β”‚
 rules ─▢ ./AGENTS.md (titled sections injected) ───────▢│  agents    │──▢ CLAUDE.md, .mcp.json,
 skills β–Ά agnos.json#skills + .agnos/skills/             β”‚ (adapters) β”‚    .claude/settings.json,
 mcp ───▢ agnos.json#mcp                                 β”‚            β”‚    .claude/skills, .codex/*
 hooks ─▢ agnos.json#hooks                               β”‚            β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Domains run in priority order (skills β†’ docs β†’ rules β†’ mcp β†’ hooks β†’ agents), so every writer has produced its canonical output before the reader renders.

Installation

Requires Node.js 24 or newer. agnos is ESM-only. This project uses pnpm exclusively.

# global (recommended for the CLI)
pnpm add -g @luxia/agnos

# or per-project
pnpm add -D @luxia/agnos

Usage

cd my-project
agnos --init        # bootstrap agnos.json + pick agents (add -y for defaults)
agnos --once        # run the pipeline once: prepare skills β†’ docs β†’ rules β†’ render agents
agnos               # watch mode: keep agent files in sync as sources change

NOTE: agnos always tries a symlink first when the agents domain links skills or mirrors rules. On Windows, creating a file symlink can require an elevated terminal or Developer Mode; when that's not available it falls back to a hardlink, then a plain copy. Directories use junctions on Windows instead, which don't need elevation. macOS/Linux create symlinks without any special privileges.

Typical workflow:

  1. agnos --init creates agnos.json and walks you through picking agents, a docs root, a rules file, and a skills directory. Add -y to accept every default non-interactively.
  2. Edit agnos.json (or use the domain subcommands like agnos mcp add github and agnos skills add owner/repo) to declare what you want.
  3. agnos in one terminal watches all domains and re-renders on change. Run agnos --once in CI or a pre-commit hook for a single deterministic pass, or agnos --dry to preview.

You can also run a single domain: agnos rules --once, agnos docs, etc.

Configuration (agnos.json)

agnos --init walks you through building agnos.json interactively; running it seeds agents, docs.root, rules.files, and skills.route. mcp and hooks entries are added afterward via their subcommands (or by hand). Here's an example showing every domain populated at once:

{
  "$schema": "https://unpkg.com/@luxia/agnos/schema.json",
  "schemaVersion": 1,
  "agents": ["claude-code", "codex", "gemini-cli"],
  "docs": { "root": ".docs" },
  "rules": {
    "files": {
      "./AGENTS.md": ["./.docs/index.md", "./.rules/security.md", "./.rules/style.md"]
    }
  },
  "skills": {
    "sources": {
      "pdf": "github:vercel-labs/agent-skills/skills/pdf"
    }
  },
  "mcp": [
    {
      "name": "github",
      "transport": "stdio",
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": { "GITHUB_TOKEN": "${GITHUB_TOKEN}" }
    }
  ],
  "hooks": [
    {
      "event": "PreToolUse",
      "matcher": "git",
      "type": "command",
      "command": "echo 'about to run git'",
      "message": "checking git usage"
    }
  ]
}

agnos.json is parsed as strict JSON (no comments, no trailing commas), so the block above is copy-pasteable as-is. ${VAR} placeholders inside mcp.env/mcp.headers are resolved at render time.

Field reference (see schema.json for the authoritative definition):

Field Type Description
schemaVersion 1 Required. Config schema version; must be 1.
agents string[] Active agent ids: "claude-code", "codex", "gemini-cli".
docs.root string Directory the docs index is compiled from (default .docs).
rules.files { [canonical]: string[] } Maps each canonical rules file β†’ fragment files whose titled sections are injected into it.
skills.route string Canonical skills directory (default .agnos/skills); agents link their own skills dir here.
skills.sources { [name]: string } Local skill name β†’ composite source ref (github:/gitlab:/bitbucket:/file:).
mcp object[] MCP server declarations (name, transport, command, args, env, headers, …).
hooks object[] Flat array of command hooks (event, matcher?, type, command, message?).

Commands

agnos [domain] [subcommand] [args] [flags]
  • agnos: watch all domains and keep agent files in sync.
  • agnos --once: run the full pipeline once and exit.
  • agnos <domain>: run a single domain (docs|rules|skills|mcp|hooks|agents).
  • agnos <domain> <subcommand>: mutate config or run a domain action.
  • agnos <domain> --help: show help for a domain and its subcommands.

Global flags

Available on every command:

Flag Description
--dry Resolve and log planned actions; write nothing (implies --once).
--once Single pass, no watchers.
--quiet Errors only.
--init Run initialization (bootstrap), then exit.
-y, --yes Accept defaults (non-interactive).
--cwd <dir> Run as if invoked from <dir>.
--debug Print debug output and full stack traces on error.
-h, --help Show help.

docs

Compiles a documentation index from docs.root. Surface it to agents by listing the generated index in rules.files. No subcommands: configure it via agnos.json or agnos docs --init.

Command Args Description
agnos docs none Compile the docs index (watch mode unless --once/--dry).

rules

Injects titled sections (by frontmatter title) from fragment files into your canonical rules file(s). Hand-written sections are preserved; removed fragments are pruned. No subcommands: configure via agnos.json or agnos rules --init.

Command Args Description
agnos rules none Inject rules (watch mode unless --once/--dry).

skills

Fetches, pins, verifies, and installs skills into the canonical skills dir (linked per-agent by agents).

Subcommand Args / Flags Description
add <skills_address...> Β Β·Β  -p, --provider <p> Β Β·Β  -s, --skills <names> Add skills from one or more sources (owner/repo[#ref] or paths); discovers skills and prompts to pick. --provider sets the default provider (github|gitlab|bitbucket|file) for un-prefixed addresses; --skills pdf,docx skips the prompt.
remove [names...] Remove skill sources (multiselect prompt when no name is given).
fetch none Check that every skill source still resolves (reports moved).
version none Check whether skills are on their pinned commit (reports outdated).
integrity none Verify skill content matches the lock (reports changed).
install none Run the prep pipeline (fetch β†’ version β†’ integrity β†’ install).
update [names...] Re-pin + reinstall skills, accepting upstream changes (default: all).
migrate [file] Β Β·Β  --missing | --force | --skip Import skill sources from a lock file (name β†’ ref JSON; default skills-lock.json).

mcp

Manages MCP servers in agnos.json (rendered per-agent by the agents domain).

Subcommand Args / Flags Description
add [term] Add MCP servers from the registry (search term), or configure one manually (omit the term for an interactive prompt).
update [names...] Update registry-managed MCP servers to their latest version (all if none given).
remove [names...] Remove MCP servers (multiselect prompt when no name is given).
migrate --missing | --force | --skip Import MCP servers from the active agents' native config.

hooks

Manages hooks in agnos.json (a flat array; the agents domain regroups + renders per-agent).

Subcommand Args / Flags Description
add <event> <command> [matcher] Add a command hook. event is one of the normalized events below.
remove [event] [command] [matcher] Remove command hooks (multiselect prompt when no args are given).
migrate --missing | --force | --skip Import hooks from the active agents' native config.

Normalized hook events: PreToolUse, PostToolUse, UserPromptSubmit, Notification, Stop, SubagentStop, PreCompact, SessionStart, SessionEnd. Each agent renders only the events it supports and skips the rest.

agents

The sole config reader: renders every active agent's native files. add/remove toggle agnos.json#agents (remove also cleans up the agent's rendered files).

Subcommand Args Description
add [agents...] Enable agents (their files render on the next agnos run). Omit ids to pick interactively.
remove [agents...] Remove agents' rendered files, then disable them.

--missing / --force / --skip (the migrate conflict policy): --missing (default) adds only entries not already present; --force overwrites conflicting entries and adds missing ones; --skip aborts if any entry conflicts.

Active development

⚠️ agnos is under active development. The built-in roster is currently Claude Code, OpenAI Codex, and Gemini CLI, with more agents planned. Config schema, CLI flags, and rendered output may change between releases: pin a version in CI and read the release notes before upgrading. Feedback and bug reports are very welcome.

Contributing

Node 24+, ESM only, TypeScript throughout. Contributions are welcome: issues and PRs at github.com/rgdevme/luxia.

pnpm install
pnpm build          # bundle with tsup + copy templates
pnpm typecheck      # tsc --noEmit
pnpm test           # vitest
pnpm lint           # eslint
pnpm format         # prettier --write

CI runs format-check, lint, typecheck, test, and build on every pull request; run the same locally before pushing:

pnpm format:check && pnpm lint && pnpm typecheck && pnpm test && pnpm build

Commits are linted via Husky + lint-staged. Please keep changes focused and add tests for new behavior.

License

Released under the MIT license.

About

Project-level configuration manager for AI coding agents.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors