跪拜 Guibai
← All articles
Frontend · Backend · Artificial Intelligence

A Single Config Syncs AI Rules, Skills, and MCP Servers Across Five IDEs

By 码云之上 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

AI-assisted coding is fragmenting across a half-dozen editors, each with its own conventions directory. Without tooling, a team's shared coding standards and MCP tool definitions drift immediately. A single-config sync tool turns those conventions into version-controlled infrastructure, the way `.editorconfig` or `prettier` did for formatting.

Summary

A growing team mixing five different AI IDEs ran into the obvious problem: each IDE stores its rules, skills, and MCP server configs in a different directory. Copying files by hand and nagging the group chat to re-sync broke down immediately. xingwu-ai-kit replaces that with a single `xingwu-ai-kit.config.ts` and a `sync` command that writes symlinks into every supported IDE directory.

Under the hood, the CLI uses IDE adapters to map the declarative config onto each tool's expected layout. Rules and skills land as symlinks pointing at shared templates, so a template update in the npm package reaches every developer on the next install without overwriting local project-specific files. MCP server definitions are written as JSON merges that preserve user-added servers.

Three implementation details stand out. A `safeLink` routine prevents symlink nesting and respects an override strategy when a real file already exists. JSDoc type annotations on the config file remove the runtime import, letting the config work under `npx`, global installs, or project-local installs with zero dependencies. And a custom `defu` merger overrides arrays instead of concatenating them, avoiding a silent bug where the IDE list doubled itself.

Takeaways
One `xingwu-ai-kit.config.ts` declares IDE targets, rule presets, skill presets, and MCP server definitions for five editors at once.
Rules and skills are deployed as symlinks into each IDE's native directory, so a template update in the npm package propagates without a manual re-sync.
A `safeLink` routine clears stale symlinks before creating new ones and skips or overwrites real files based on a configurable strategy.
JSDoc type annotations (`@type {import('...').AIKitConfig}`) keep the config file free of runtime imports, making it work with `npx`, global installs, and project-local installs.
`defu`'s default array concatenation silently doubled the IDE list; a custom merger that overwrites arrays fixed the bug.
A `doctor --fix` command scans for and removes broken symlinks left after `pnpm install` refreshes `node_modules`.
Templates live in the monorepo root and are copied into `dist/` via a post-build script so they ship inside the published npm package.
Conclusions

The fragmentation of AI IDE conventions directories is creating the same kind of coordination tax that `.editorconfig` and `prettier` solved for code style. A symlink-based sync tool is the natural next piece of shared infrastructure.

Making the config file zero-dependency via JSDoc annotations is a small change with outsized practical impact: it removes the most common reason a CLI tool fails when used casually via `npx` or a global install.

`defu`'s array-concatenation default is a sharp edge that will bite any CLI author who uses `c12` with array-shaped config fields. The fix is trivial once you know it, but the symptom (duplicated work) points in the wrong direction during debugging.

Concepts & terms
symlink sync for IDE rules
Instead of copying rule files into each IDE's directory, the CLI creates symbolic links pointing to shared template files. Updating the template immediately affects every IDE without re-running a sync command, and local project-specific files are not overwritten.
defu array concatenation pitfall
The `defu` library merges objects recursively, but its default behavior for array fields is to concatenate values from both objects rather than replace them. When a user config and default config both list the same IDEs, the merged array doubles in length, causing every operation to run twice.
JSDoc zero-dependency config
Using `/** @type {import('pkg').Type} */` above a default export provides TypeScript type-checking and editor autocompletion without generating a runtime `import` statement. The config file runs even when the package is not installed locally, enabling `npx` and global install usage.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗