logoalt Hacker News

iamkrystian17today at 8:45 AM0 repliesview on HN

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:

.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.