I've been using Claude Code, Cursor, and Codex on the same projects. Each tool has its own config format: Claude wants `.claude/`, Cursor wants `.cursor/`, Codex wants `.codex/`. Every time I updated a skill/rule, I had to update it in 3+ places. Usually I'd forget one, and my tools would give inconsistent suggestions.
LNAI is a CLI that lets you define your AI configs once in a `.ai/` directory:
Run `lnai sync` and it exports to native formats for 7 tools: Claude Code, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Windsurf, and Codex.
The interesting part is it's not just copying files. Each tool has quirks:
- Cursor wants `.mdc` files with `globs` arrays in frontmatter
- Gemini reads rules at the directory level, so rules get grouped
- Permissions like `Bash(git:*)` become `Shell(git)` for Cursor
- Some tools don't support certain features (e.g., Cursor has no "ask" permission level). LNAI warns but doesn't fail
Where possible, it uses symlinks. So `.claude/CLAUDE.md` → `../.ai/AGENTS.md`. Edit the source, all tools see the change immediately without re-syncing.
Usage:
npm install -g lnai
lnai init # Creates .ai/ directory
lnai validate # Checks for config errors
lnai sync # Exports to all enabled tools
Would appreciate feedback, especially from anyone else dealing with this config hell problem.
OsamaJaber•23m ago
Nice. The config fragmentation across tools is a real annoyance
Does it handle conflicts if tools expect different formats for the same setting?
iamkrystian17•11m ago
Yes, the tool takes that into account and transforms mcps/permissions/rules to different tool formats.
Sadly some tools might not support fine-grained permissions (e.g. Codex) in which case a warning will be displayed but everything else will get transformed/symlinked.
Additionally you can put per-tool overrides in ‘.ai/{codex/claude/cursor/etc.}/‘ if needed and lnai will automatically symlink those overrides to respective tools.
anupamchugh•6m ago
This solves distribution well. Curious about the change propagation story though - what happens when you update your .ai/ source and tools have cached/transformed versions?
I ran into this building a spec/skill sync system [1] - the "sync once" model breaks down when you need to track whether downstream consumers are aware of upstream changes.
iamkrystian17•1h ago
.ai/ ├── AGENTS.md ├── rules/ ├── skills/ └── settings.json # MCP servers, permissions
Run `lnai sync` and it exports to native formats for 7 tools: Claude Code, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Windsurf, and Codex. The interesting part is it's not just copying files. Each tool has quirks:
- Cursor wants `.mdc` files with `globs` arrays in frontmatter - Gemini reads rules at the directory level, so rules get grouped - Permissions like `Bash(git:*)` become `Shell(git)` for Cursor - Some tools don't support certain features (e.g., Cursor has no "ask" permission level). LNAI warns but doesn't fail
Where possible, it uses symlinks. So `.claude/CLAUDE.md` → `../.ai/AGENTS.md`. Edit the source, all tools see the change immediately without re-syncing.
Usage:
npm install -g lnai lnai init # Creates .ai/ directory lnai validate # Checks for config errors lnai sync # Exports to all enabled tools
It's MIT licensed. The code is TypeScript with a plugin architecture, each tool is a plugin that implements import/export/validate. GitHub: https://github.com/KrystianJonca/lnai Docs: https://lnai.sh
Would appreciate feedback, especially from anyone else dealing with this config hell problem.