code-agnostic 0.1.0__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- code_agnostic-0.2.2/PKG-INFO +222 -0
- code_agnostic-0.2.2/README.md +200 -0
- code_agnostic-0.2.2/code_agnostic/__main__.py +989 -0
- code_agnostic-0.2.2/code_agnostic/agents/__init__.py +0 -0
- code_agnostic-0.2.2/code_agnostic/agents/compilers.py +35 -0
- code_agnostic-0.2.2/code_agnostic/agents/models.py +29 -0
- code_agnostic-0.2.2/code_agnostic/agents/parser.py +77 -0
- code_agnostic-0.2.2/code_agnostic/apps/__init__.py +0 -0
- code_agnostic-0.2.2/code_agnostic/apps/app_id.py +98 -0
- code_agnostic-0.2.2/code_agnostic/apps/apps_service.py +135 -0
- code_agnostic-0.2.2/code_agnostic/apps/codex/__init__.py +1 -0
- code_agnostic-0.2.2/code_agnostic/apps/codex/config_repository.py +121 -0
- code_agnostic-0.2.2/code_agnostic/apps/codex/mapper.py +134 -0
- code_agnostic-0.2.2/code_agnostic/apps/codex/schema.json +40 -0
- code_agnostic-0.2.2/code_agnostic/apps/codex/schema_repository.py +14 -0
- code_agnostic-0.2.2/code_agnostic/apps/codex/service.py +137 -0
- code_agnostic-0.2.2/code_agnostic/apps/common/__init__.py +15 -0
- code_agnostic-0.2.2/code_agnostic/apps/common/framework.py +66 -0
- code_agnostic-0.2.2/code_agnostic/apps/common/interfaces/__init__.py +17 -0
- code_agnostic-0.2.2/code_agnostic/apps/common/interfaces/mapper.py +14 -0
- code_agnostic-0.1.0/code_agnostic/repositories/base.py → code_agnostic-0.2.2/code_agnostic/apps/common/interfaces/repositories.py +34 -26
- code_agnostic-0.2.2/code_agnostic/apps/common/interfaces/service.py +84 -0
- code_agnostic-0.2.2/code_agnostic/apps/common/loader.py +13 -0
- code_agnostic-0.2.2/code_agnostic/apps/common/models.py +28 -0
- code_agnostic-0.2.2/code_agnostic/apps/common/schema.py +56 -0
- code_agnostic-0.2.2/code_agnostic/apps/common/symlink_planning.py +132 -0
- code_agnostic-0.2.2/code_agnostic/apps/common/utils.py +94 -0
- code_agnostic-0.2.2/code_agnostic/apps/cursor/__init__.py +1 -0
- code_agnostic-0.2.2/code_agnostic/apps/cursor/config_repository.py +50 -0
- code_agnostic-0.2.2/code_agnostic/apps/cursor/mapper.py +93 -0
- code_agnostic-0.2.2/code_agnostic/apps/cursor/schema.json +57 -0
- code_agnostic-0.2.2/code_agnostic/apps/cursor/schema_repository.py +12 -0
- code_agnostic-0.2.2/code_agnostic/apps/cursor/service.py +165 -0
- code_agnostic-0.2.2/code_agnostic/apps/opencode/__init__.py +1 -0
- code_agnostic-0.1.0/code_agnostic/repositories/opencode.py → code_agnostic-0.2.2/code_agnostic/apps/opencode/config_repository.py +38 -21
- code_agnostic-0.2.2/code_agnostic/apps/opencode/mapper.py +100 -0
- code_agnostic-0.2.2/code_agnostic/apps/opencode/schema.json +7675 -0
- code_agnostic-0.2.2/code_agnostic/apps/opencode/schema_repository.py +14 -0
- code_agnostic-0.2.2/code_agnostic/apps/opencode/service.py +211 -0
- code_agnostic-0.2.2/code_agnostic/constants.py +13 -0
- code_agnostic-0.2.2/code_agnostic/core/__init__.py +0 -0
- code_agnostic-0.1.0/code_agnostic/repositories/common.py → code_agnostic-0.2.2/code_agnostic/core/repository.py +70 -34
- code_agnostic-0.2.2/code_agnostic/core/workspace_repository.py +44 -0
- code_agnostic-0.2.2/code_agnostic/executor.py +180 -0
- code_agnostic-0.2.2/code_agnostic/git_exclude_service.py +87 -0
- code_agnostic-0.2.2/code_agnostic/imports/__init__.py +0 -0
- code_agnostic-0.2.2/code_agnostic/imports/adapters.py +59 -0
- code_agnostic-0.2.2/code_agnostic/imports/filesystem.py +69 -0
- code_agnostic-0.2.2/code_agnostic/imports/models.py +57 -0
- code_agnostic-0.2.2/code_agnostic/imports/service.py +385 -0
- code_agnostic-0.2.2/code_agnostic/mcp_service.py +101 -0
- {code_agnostic-0.1.0 → code_agnostic-0.2.2}/code_agnostic/models.py +45 -63
- code_agnostic-0.2.2/code_agnostic/planner.py +416 -0
- code_agnostic-0.2.2/code_agnostic/rules/__init__.py +0 -0
- code_agnostic-0.2.2/code_agnostic/rules/compilers.py +56 -0
- code_agnostic-0.2.2/code_agnostic/rules/models.py +21 -0
- code_agnostic-0.2.2/code_agnostic/rules/parser.py +56 -0
- code_agnostic-0.2.2/code_agnostic/rules/repository.py +46 -0
- code_agnostic-0.2.2/code_agnostic/skills/__init__.py +0 -0
- code_agnostic-0.2.2/code_agnostic/skills/compilers.py +39 -0
- code_agnostic-0.2.2/code_agnostic/skills/models.py +28 -0
- code_agnostic-0.2.2/code_agnostic/skills/parser.py +74 -0
- code_agnostic-0.2.2/code_agnostic/status.py +167 -0
- code_agnostic-0.2.2/code_agnostic/tui/import_selector.py +99 -0
- code_agnostic-0.2.2/code_agnostic/tui/renderers.py +291 -0
- {code_agnostic-0.1.0 → code_agnostic-0.2.2}/code_agnostic/tui/sections.py +6 -4
- code_agnostic-0.2.2/code_agnostic/tui/tables.py +384 -0
- {code_agnostic-0.1.0 → code_agnostic-0.2.2}/code_agnostic/utils.py +21 -9
- code_agnostic-0.2.2/code_agnostic/workspaces.py +30 -0
- code_agnostic-0.2.2/code_agnostic.egg-info/PKG-INFO +222 -0
- code_agnostic-0.2.2/code_agnostic.egg-info/SOURCES.txt +109 -0
- {code_agnostic-0.1.0 → code_agnostic-0.2.2}/code_agnostic.egg-info/entry_points.txt +1 -0
- {code_agnostic-0.1.0 → code_agnostic-0.2.2}/code_agnostic.egg-info/requires.txt +5 -0
- {code_agnostic-0.1.0 → code_agnostic-0.2.2}/pyproject.toml +14 -3
- code_agnostic-0.2.2/tests/test_cli_agents.py +57 -0
- code_agnostic-0.2.2/tests/test_cli_aliases.py +52 -0
- code_agnostic-0.2.2/tests/test_cli_apply_apps.py +171 -0
- code_agnostic-0.2.2/tests/test_cli_apply_codex.py +109 -0
- {code_agnostic-0.1.0 → code_agnostic-0.2.2}/tests/test_cli_apply_cursor.py +37 -1
- code_agnostic-0.2.2/tests/test_cli_apply_target.py +217 -0
- code_agnostic-0.2.2/tests/test_cli_apps.py +86 -0
- code_agnostic-0.2.2/tests/test_cli_flags.py +149 -0
- code_agnostic-0.2.2/tests/test_cli_git_exclude.py +64 -0
- code_agnostic-0.2.2/tests/test_cli_import.py +223 -0
- code_agnostic-0.2.2/tests/test_cli_import_interactive.py +40 -0
- code_agnostic-0.2.2/tests/test_cli_mcp.py +187 -0
- code_agnostic-0.2.2/tests/test_cli_plan.py +92 -0
- code_agnostic-0.2.2/tests/test_cli_rules.py +65 -0
- code_agnostic-0.2.2/tests/test_cli_skills.py +57 -0
- {code_agnostic-0.1.0 → code_agnostic-0.2.2}/tests/test_cli_status.py +29 -3
- code_agnostic-0.2.2/tests/test_cli_workspaces.py +198 -0
- code_agnostic-0.2.2/tests/test_common_mcp_to_dto.py +172 -0
- code_agnostic-0.2.2/tests/test_common_repository.py +195 -0
- code_agnostic-0.2.2/tests/test_dto_to_common_mcp.py +28 -0
- code_agnostic-0.2.2/tests/test_git_exclude_service.py +87 -0
- code_agnostic-0.2.2/tests/test_mcp_service.py +195 -0
- code_agnostic-0.2.2/tests/test_planner_executor.py +350 -0
- code_agnostic-0.2.2/tests/test_planner_rules.py +94 -0
- code_agnostic-0.2.2/tests/test_symlink_planning.py +214 -0
- code_agnostic-0.2.2/tests/test_sync_plan_model.py +184 -0
- code_agnostic-0.2.2/tests/test_utils.py +125 -0
- code_agnostic-0.2.2/tests/test_workspace_config_sync.py +572 -0
- code_agnostic-0.2.2/tests/test_workspaces.py +73 -0
- code_agnostic-0.1.0/PKG-INFO +0 -94
- code_agnostic-0.1.0/README.md +0 -77
- code_agnostic-0.1.0/code_agnostic/__main__.py +0 -275
- code_agnostic-0.1.0/code_agnostic/apps.py +0 -71
- code_agnostic-0.1.0/code_agnostic/constants.py +0 -19
- code_agnostic-0.1.0/code_agnostic/executor.py +0 -158
- code_agnostic-0.1.0/code_agnostic/mappers/__init__.py +0 -4
- code_agnostic-0.1.0/code_agnostic/mappers/base.py +0 -17
- code_agnostic-0.1.0/code_agnostic/mappers/opencode.py +0 -50
- code_agnostic-0.1.0/code_agnostic/planner.py +0 -212
- code_agnostic-0.1.0/code_agnostic/repositories/__init__.py +0 -13
- code_agnostic-0.1.0/code_agnostic/repositories/cursor.py +0 -11
- code_agnostic-0.1.0/code_agnostic/status.py +0 -136
- code_agnostic-0.1.0/code_agnostic/tui/renderers.py +0 -79
- code_agnostic-0.1.0/code_agnostic/tui/tables.py +0 -201
- code_agnostic-0.1.0/code_agnostic/workspaces.py +0 -45
- code_agnostic-0.1.0/code_agnostic.egg-info/PKG-INFO +0 -94
- code_agnostic-0.1.0/code_agnostic.egg-info/SOURCES.txt +0 -43
- code_agnostic-0.1.0/tests/test_cli_apply_target.py +0 -92
- code_agnostic-0.1.0/tests/test_cli_apps.py +0 -57
- code_agnostic-0.1.0/tests/test_cli_plan.py +0 -13
- code_agnostic-0.1.0/tests/test_cli_workspaces.py +0 -38
- code_agnostic-0.1.0/tests/test_common_repository.py +0 -93
- code_agnostic-0.1.0/tests/test_mapper_opencode.py +0 -53
- code_agnostic-0.1.0/tests/test_planner_executor.py +0 -163
- code_agnostic-0.1.0/tests/test_workspaces.py +0 -34
- {code_agnostic-0.1.0 → code_agnostic-0.2.2}/LICENSE +0 -0
- {code_agnostic-0.1.0 → code_agnostic-0.2.2}/code_agnostic/__init__.py +0 -0
- {code_agnostic-0.1.0 → code_agnostic-0.2.2}/code_agnostic/errors.py +0 -0
- {code_agnostic-0.1.0 → code_agnostic-0.2.2}/code_agnostic/tui/__init__.py +0 -0
- {code_agnostic-0.1.0 → code_agnostic-0.2.2}/code_agnostic/tui/enums.py +0 -0
- {code_agnostic-0.1.0 → code_agnostic-0.2.2}/code_agnostic.egg-info/dependency_links.txt +0 -0
- {code_agnostic-0.1.0 → code_agnostic-0.2.2}/code_agnostic.egg-info/top_level.txt +0 -0
- {code_agnostic-0.1.0 → code_agnostic-0.2.2}/setup.cfg +0 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: code-agnostic
|
|
3
|
+
Version: 0.2.2
|
|
4
|
+
Summary: Centralized hub for LLM coding config: MCP, skills, rules, and agents.
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Dist: click
|
|
9
|
+
Requires-Dist: rich
|
|
10
|
+
Requires-Dist: jsonschema>=4.0
|
|
11
|
+
Requires-Dist: tomli
|
|
12
|
+
Requires-Dist: pyyaml>=6.0
|
|
13
|
+
Requires-Dist: textual>=0.47
|
|
14
|
+
Provides-Extra: dev
|
|
15
|
+
Requires-Dist: pre-commit>=4.0; extra == "dev"
|
|
16
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
17
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
|
|
18
|
+
Requires-Dist: jsonschema>=4.0; extra == "dev"
|
|
19
|
+
Requires-Dist: ruff>=0.8.0; extra == "dev"
|
|
20
|
+
Requires-Dist: mypy>=1.11; extra == "dev"
|
|
21
|
+
Dynamic: license-file
|
|
22
|
+
|
|
23
|
+
# code-agnostic
|
|
24
|
+
|
|
25
|
+
One config, every AI editor. Keep MCP servers, rules, skills, and agents in a single hub and sync them into editor-specific layouts.
|
|
26
|
+
|
|
27
|
+
## Why
|
|
28
|
+
|
|
29
|
+
AI coding tools each want config in a different place and format. When you use more than one, you end up copy-pasting MCP servers, duplicating rules, and manually keeping things in sync. `code-agnostic` removes that overhead: define once, sync everywhere.
|
|
30
|
+
|
|
31
|
+
## How it works
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
~/.config/code-agnostic/ Your single source of truth
|
|
35
|
+
├── config/
|
|
36
|
+
│ └── mcp.base.json MCP servers (editor-agnostic)
|
|
37
|
+
├── rules/
|
|
38
|
+
│ └── python-style.md Rules with YAML frontmatter
|
|
39
|
+
├── skills/
|
|
40
|
+
│ └── code-reviewer/SKILL.md Skills with YAML frontmatter
|
|
41
|
+
└── agents/
|
|
42
|
+
└── architect.md Agents with YAML frontmatter
|
|
43
|
+
|
|
44
|
+
↓ plan / apply ↓
|
|
45
|
+
|
|
46
|
+
~/.config/opencode/ Compiled & synced for OpenCode
|
|
47
|
+
~/.cursor/ Compiled & synced for Cursor
|
|
48
|
+
~/.codex/ Compiled & synced for Codex
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Each resource is cross-compiled to the target editor's native format. Rules become `.mdc` files for Cursor, `AGENTS.md` sections for OpenCode/Codex, etc.
|
|
52
|
+
|
|
53
|
+
## Install
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
uv tool install code-agnostic
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Or run without installing:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
uvx code-agnostic
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Or run the published Docker image to isolate filesystem access to mounted paths only:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
docker run --rm -it \
|
|
69
|
+
-v "$(pwd):/workspace" \
|
|
70
|
+
-w /workspace \
|
|
71
|
+
ghcr.io/dhvcc/code-agnostic:latest plan
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
By default, config stays inside the container at `/root/.config` unless you mount a host path.
|
|
75
|
+
|
|
76
|
+
## Quick start
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# Import existing config from an editor you already use
|
|
80
|
+
code-agnostic import plan -a codex
|
|
81
|
+
code-agnostic import apply -a codex
|
|
82
|
+
|
|
83
|
+
# Enable target editors
|
|
84
|
+
code-agnostic apps enable -a cursor
|
|
85
|
+
code-agnostic apps enable -a opencode
|
|
86
|
+
|
|
87
|
+
# Preview and apply
|
|
88
|
+
code-agnostic plan
|
|
89
|
+
code-agnostic apply
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Editor compatibility
|
|
93
|
+
|
|
94
|
+
| Feature | OpenCode | Cursor | Codex |
|
|
95
|
+
|---------|:--------:|:------:|:-----:|
|
|
96
|
+
| MCP sync | yes | yes | yes |
|
|
97
|
+
| Rules sync (cross-compiled) | yes | yes | yes |
|
|
98
|
+
| Skills sync | yes | yes | yes |
|
|
99
|
+
| Agents sync | yes | yes | -- |
|
|
100
|
+
| Workspace propagation | yes | -- | yes |
|
|
101
|
+
| Import from | yes | yes | yes |
|
|
102
|
+
| Interactive import (TUI) | yes | yes | yes |
|
|
103
|
+
|
|
104
|
+
Codex does not support agents natively. Workspace propagation is intentionally disabled for Cursor to avoid duplicate MCP initialization in multi-root workspaces: https://forum.cursor.com/t/mcp-multi-root-workspace-causes-duplicate-mcp-server-initialization-4x-createclient-actions/144003
|
|
105
|
+
|
|
106
|
+
## Features
|
|
107
|
+
|
|
108
|
+
### Sync engine
|
|
109
|
+
|
|
110
|
+
Plan-then-apply workflow. Preview every change before it touches disk.
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
code-agnostic plan -a cursor # dry-run for one editor
|
|
114
|
+
code-agnostic plan # dry-run for all
|
|
115
|
+
code-agnostic apply # apply changes
|
|
116
|
+
code-agnostic status # check drift
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### MCP management
|
|
120
|
+
|
|
121
|
+
Add, remove, and list MCP servers without editing JSON by hand.
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
code-agnostic mcp add github --command npx --args @modelcontextprotocol/server-github --env GITHUB_TOKEN
|
|
125
|
+
code-agnostic mcp list
|
|
126
|
+
code-agnostic mcp remove github
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Env vars without a value (`--env GITHUB_TOKEN`) are stored as `${GITHUB_TOKEN}` references.
|
|
130
|
+
|
|
131
|
+
### Rules with metadata
|
|
132
|
+
|
|
133
|
+
Rules live in `rules/` as markdown files with optional YAML frontmatter:
|
|
134
|
+
|
|
135
|
+
```markdown
|
|
136
|
+
---
|
|
137
|
+
description: "Python coding standards"
|
|
138
|
+
globs: ["*.py"]
|
|
139
|
+
always_apply: false
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
Always use type hints. Prefer dataclasses over dicts.
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Cross-compiled per editor: Cursor gets `.mdc` files with native frontmatter, OpenCode/Codex get `AGENTS.md` sections.
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
code-agnostic rules list
|
|
149
|
+
code-agnostic rules remove --name python-style
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Skills and agents
|
|
153
|
+
|
|
154
|
+
Canonical YAML frontmatter format, cross-compiled per editor.
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
code-agnostic skills list
|
|
158
|
+
code-agnostic agents list
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Workspaces
|
|
162
|
+
|
|
163
|
+
Register workspace directories. Repos inside them get rules, skills, and agents propagated as symlinks for OpenCode and Codex.
|
|
164
|
+
|
|
165
|
+
`.cursor` workspace propagation is intentionally disabled to avoid duplicate MCP initialization when opening multi-root workspaces in Cursor (related issue: https://forum.cursor.com/t/mcp-multi-root-workspace-causes-duplicate-mcp-server-initialization-4x-createclient-actions/144003).
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
code-agnostic workspaces add --name myproject --path ~/code/myproject
|
|
169
|
+
code-agnostic workspaces list
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Git exclude
|
|
173
|
+
|
|
174
|
+
Prevent synced paths from showing up in `git status`. Managed per-workspace with customizable patterns.
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
code-agnostic workspaces git-exclude # all workspaces
|
|
178
|
+
code-agnostic workspaces git-exclude -w myproject # one workspace
|
|
179
|
+
code-agnostic workspaces exclude-add --pattern "*.generated" -w myproject
|
|
180
|
+
code-agnostic workspaces exclude-list -w myproject
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Import
|
|
184
|
+
|
|
185
|
+
Migrate existing config from any supported editor into the hub.
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
code-agnostic import plan -a codex
|
|
189
|
+
code-agnostic import apply -a codex
|
|
190
|
+
code-agnostic import apply -a cursor --include mcp --on-conflict overwrite
|
|
191
|
+
code-agnostic import plan -a codex -i # interactive TUI picker
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### CLI conventions
|
|
195
|
+
|
|
196
|
+
All commands use named flags (`-a`, `-w`, `-v`). Singular aliases work too: `app` = `apps`, `workspace` = `workspaces`.
|
|
197
|
+
|
|
198
|
+
## Roadmap
|
|
199
|
+
|
|
200
|
+
- [x] Plan/apply/status sync engine
|
|
201
|
+
- [x] MCP server sync across editors
|
|
202
|
+
- [x] Skills and agents sync (symlink-based)
|
|
203
|
+
- [x] Workspace propagation into git repos
|
|
204
|
+
- [x] Import from existing editor configs
|
|
205
|
+
- [x] Consistent CLI with named flags and aliases
|
|
206
|
+
- [x] MCP add/remove/list commands
|
|
207
|
+
- [x] Rules system with YAML frontmatter and per-editor compilation
|
|
208
|
+
- [x] Cross-compilation for skills and agents
|
|
209
|
+
- [x] Per-workspace git-exclude customization
|
|
210
|
+
- [x] Interactive TUI for import selection
|
|
211
|
+
- [ ] Claude Code support
|
|
212
|
+
- [ ] `rules add` / `skills add` / `agents add` commands (open `$EDITOR` with template)
|
|
213
|
+
- [ ] Planner integration for cross-compiled skills and agents
|
|
214
|
+
- [ ] Shell auto-complete
|
|
215
|
+
- [ ] Full TUI mode (command palette + menus)
|
|
216
|
+
|
|
217
|
+
## Testing
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
uv sync --dev
|
|
221
|
+
uv run test
|
|
222
|
+
```
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# code-agnostic
|
|
2
|
+
|
|
3
|
+
One config, every AI editor. Keep MCP servers, rules, skills, and agents in a single hub and sync them into editor-specific layouts.
|
|
4
|
+
|
|
5
|
+
## Why
|
|
6
|
+
|
|
7
|
+
AI coding tools each want config in a different place and format. When you use more than one, you end up copy-pasting MCP servers, duplicating rules, and manually keeping things in sync. `code-agnostic` removes that overhead: define once, sync everywhere.
|
|
8
|
+
|
|
9
|
+
## How it works
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
~/.config/code-agnostic/ Your single source of truth
|
|
13
|
+
├── config/
|
|
14
|
+
│ └── mcp.base.json MCP servers (editor-agnostic)
|
|
15
|
+
├── rules/
|
|
16
|
+
│ └── python-style.md Rules with YAML frontmatter
|
|
17
|
+
├── skills/
|
|
18
|
+
│ └── code-reviewer/SKILL.md Skills with YAML frontmatter
|
|
19
|
+
└── agents/
|
|
20
|
+
└── architect.md Agents with YAML frontmatter
|
|
21
|
+
|
|
22
|
+
↓ plan / apply ↓
|
|
23
|
+
|
|
24
|
+
~/.config/opencode/ Compiled & synced for OpenCode
|
|
25
|
+
~/.cursor/ Compiled & synced for Cursor
|
|
26
|
+
~/.codex/ Compiled & synced for Codex
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Each resource is cross-compiled to the target editor's native format. Rules become `.mdc` files for Cursor, `AGENTS.md` sections for OpenCode/Codex, etc.
|
|
30
|
+
|
|
31
|
+
## Install
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
uv tool install code-agnostic
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Or run without installing:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
uvx code-agnostic
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Or run the published Docker image to isolate filesystem access to mounted paths only:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
docker run --rm -it \
|
|
47
|
+
-v "$(pwd):/workspace" \
|
|
48
|
+
-w /workspace \
|
|
49
|
+
ghcr.io/dhvcc/code-agnostic:latest plan
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
By default, config stays inside the container at `/root/.config` unless you mount a host path.
|
|
53
|
+
|
|
54
|
+
## Quick start
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# Import existing config from an editor you already use
|
|
58
|
+
code-agnostic import plan -a codex
|
|
59
|
+
code-agnostic import apply -a codex
|
|
60
|
+
|
|
61
|
+
# Enable target editors
|
|
62
|
+
code-agnostic apps enable -a cursor
|
|
63
|
+
code-agnostic apps enable -a opencode
|
|
64
|
+
|
|
65
|
+
# Preview and apply
|
|
66
|
+
code-agnostic plan
|
|
67
|
+
code-agnostic apply
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Editor compatibility
|
|
71
|
+
|
|
72
|
+
| Feature | OpenCode | Cursor | Codex |
|
|
73
|
+
|---------|:--------:|:------:|:-----:|
|
|
74
|
+
| MCP sync | yes | yes | yes |
|
|
75
|
+
| Rules sync (cross-compiled) | yes | yes | yes |
|
|
76
|
+
| Skills sync | yes | yes | yes |
|
|
77
|
+
| Agents sync | yes | yes | -- |
|
|
78
|
+
| Workspace propagation | yes | -- | yes |
|
|
79
|
+
| Import from | yes | yes | yes |
|
|
80
|
+
| Interactive import (TUI) | yes | yes | yes |
|
|
81
|
+
|
|
82
|
+
Codex does not support agents natively. Workspace propagation is intentionally disabled for Cursor to avoid duplicate MCP initialization in multi-root workspaces: https://forum.cursor.com/t/mcp-multi-root-workspace-causes-duplicate-mcp-server-initialization-4x-createclient-actions/144003
|
|
83
|
+
|
|
84
|
+
## Features
|
|
85
|
+
|
|
86
|
+
### Sync engine
|
|
87
|
+
|
|
88
|
+
Plan-then-apply workflow. Preview every change before it touches disk.
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
code-agnostic plan -a cursor # dry-run for one editor
|
|
92
|
+
code-agnostic plan # dry-run for all
|
|
93
|
+
code-agnostic apply # apply changes
|
|
94
|
+
code-agnostic status # check drift
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### MCP management
|
|
98
|
+
|
|
99
|
+
Add, remove, and list MCP servers without editing JSON by hand.
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
code-agnostic mcp add github --command npx --args @modelcontextprotocol/server-github --env GITHUB_TOKEN
|
|
103
|
+
code-agnostic mcp list
|
|
104
|
+
code-agnostic mcp remove github
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Env vars without a value (`--env GITHUB_TOKEN`) are stored as `${GITHUB_TOKEN}` references.
|
|
108
|
+
|
|
109
|
+
### Rules with metadata
|
|
110
|
+
|
|
111
|
+
Rules live in `rules/` as markdown files with optional YAML frontmatter:
|
|
112
|
+
|
|
113
|
+
```markdown
|
|
114
|
+
---
|
|
115
|
+
description: "Python coding standards"
|
|
116
|
+
globs: ["*.py"]
|
|
117
|
+
always_apply: false
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
Always use type hints. Prefer dataclasses over dicts.
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Cross-compiled per editor: Cursor gets `.mdc` files with native frontmatter, OpenCode/Codex get `AGENTS.md` sections.
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
code-agnostic rules list
|
|
127
|
+
code-agnostic rules remove --name python-style
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Skills and agents
|
|
131
|
+
|
|
132
|
+
Canonical YAML frontmatter format, cross-compiled per editor.
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
code-agnostic skills list
|
|
136
|
+
code-agnostic agents list
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Workspaces
|
|
140
|
+
|
|
141
|
+
Register workspace directories. Repos inside them get rules, skills, and agents propagated as symlinks for OpenCode and Codex.
|
|
142
|
+
|
|
143
|
+
`.cursor` workspace propagation is intentionally disabled to avoid duplicate MCP initialization when opening multi-root workspaces in Cursor (related issue: https://forum.cursor.com/t/mcp-multi-root-workspace-causes-duplicate-mcp-server-initialization-4x-createclient-actions/144003).
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
code-agnostic workspaces add --name myproject --path ~/code/myproject
|
|
147
|
+
code-agnostic workspaces list
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Git exclude
|
|
151
|
+
|
|
152
|
+
Prevent synced paths from showing up in `git status`. Managed per-workspace with customizable patterns.
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
code-agnostic workspaces git-exclude # all workspaces
|
|
156
|
+
code-agnostic workspaces git-exclude -w myproject # one workspace
|
|
157
|
+
code-agnostic workspaces exclude-add --pattern "*.generated" -w myproject
|
|
158
|
+
code-agnostic workspaces exclude-list -w myproject
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Import
|
|
162
|
+
|
|
163
|
+
Migrate existing config from any supported editor into the hub.
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
code-agnostic import plan -a codex
|
|
167
|
+
code-agnostic import apply -a codex
|
|
168
|
+
code-agnostic import apply -a cursor --include mcp --on-conflict overwrite
|
|
169
|
+
code-agnostic import plan -a codex -i # interactive TUI picker
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### CLI conventions
|
|
173
|
+
|
|
174
|
+
All commands use named flags (`-a`, `-w`, `-v`). Singular aliases work too: `app` = `apps`, `workspace` = `workspaces`.
|
|
175
|
+
|
|
176
|
+
## Roadmap
|
|
177
|
+
|
|
178
|
+
- [x] Plan/apply/status sync engine
|
|
179
|
+
- [x] MCP server sync across editors
|
|
180
|
+
- [x] Skills and agents sync (symlink-based)
|
|
181
|
+
- [x] Workspace propagation into git repos
|
|
182
|
+
- [x] Import from existing editor configs
|
|
183
|
+
- [x] Consistent CLI with named flags and aliases
|
|
184
|
+
- [x] MCP add/remove/list commands
|
|
185
|
+
- [x] Rules system with YAML frontmatter and per-editor compilation
|
|
186
|
+
- [x] Cross-compilation for skills and agents
|
|
187
|
+
- [x] Per-workspace git-exclude customization
|
|
188
|
+
- [x] Interactive TUI for import selection
|
|
189
|
+
- [ ] Claude Code support
|
|
190
|
+
- [ ] `rules add` / `skills add` / `agents add` commands (open `$EDITOR` with template)
|
|
191
|
+
- [ ] Planner integration for cross-compiled skills and agents
|
|
192
|
+
- [ ] Shell auto-complete
|
|
193
|
+
- [ ] Full TUI mode (command palette + menus)
|
|
194
|
+
|
|
195
|
+
## Testing
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
uv sync --dev
|
|
199
|
+
uv run test
|
|
200
|
+
```
|