codexmgr 0.1.1__tar.gz → 0.1.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.
- {codexmgr-0.1.1 → codexmgr-0.1.2}/.gitignore +4 -0
- {codexmgr-0.1.1 → codexmgr-0.1.2}/PKG-INFO +130 -8
- {codexmgr-0.1.1 → codexmgr-0.1.2}/README.md +127 -7
- {codexmgr-0.1.1 → codexmgr-0.1.2}/pyproject.toml +5 -2
- {codexmgr-0.1.1 → codexmgr-0.1.2}/src/codexmgr/__init__.py +1 -1
- {codexmgr-0.1.1 → codexmgr-0.1.2}/src/codexmgr/agents_file.py +15 -1
- codexmgr-0.1.2/src/codexmgr/agentsmd.py +210 -0
- {codexmgr-0.1.1 → codexmgr-0.1.2}/src/codexmgr/cli.py +61 -58
- codexmgr-0.1.2/src/codexmgr/cli_parser.py +239 -0
- codexmgr-0.1.2/src/codexmgr/health.py +210 -0
- codexmgr-0.1.2/src/codexmgr/mcp.py +293 -0
- codexmgr-0.1.2/src/codexmgr/mcp_apply.py +69 -0
- codexmgr-0.1.2/src/codexmgr/mcp_cli.py +190 -0
- codexmgr-0.1.2/src/codexmgr/mcp_discovery.py +120 -0
- codexmgr-0.1.2/src/codexmgr/mcp_fields.py +150 -0
- codexmgr-0.1.2/src/codexmgr/navigation.py +156 -0
- codexmgr-0.1.2/src/codexmgr/options.py +35 -0
- codexmgr-0.1.2/src/codexmgr/project.py +206 -0
- {codexmgr-0.1.1 → codexmgr-0.1.2}/src/codexmgr/project_config.py +7 -8
- codexmgr-0.1.2/src/codexmgr/skill_listing.py +152 -0
- {codexmgr-0.1.1 → codexmgr-0.1.2}/src/codexmgr/skills.py +17 -12
- codexmgr-0.1.2/src/codexmgr/sync.py +134 -0
- {codexmgr-0.1.1 → codexmgr-0.1.2}/src/codexmgr/toml_io.py +90 -69
- codexmgr-0.1.2/tests/test_agentsmd_list_cli.py +87 -0
- codexmgr-0.1.2/tests/test_agentsmd_tools_cli.py +111 -0
- codexmgr-0.1.2/tests/test_apply_check_cli.py +83 -0
- codexmgr-0.1.2/tests/test_cd_cli.py +145 -0
- codexmgr-0.1.2/tests/test_mcp_apply_cli.py +119 -0
- codexmgr-0.1.2/tests/test_mcp_cli.py +308 -0
- codexmgr-0.1.2/tests/test_skill_list_cli.py +52 -0
- codexmgr-0.1.2/tests/test_status_doctor_cli.py +164 -0
- {codexmgr-0.1.1 → codexmgr-0.1.2}/tests/test_toml_io.py +7 -0
- codexmgr-0.1.2/uv.lock +158 -0
- codexmgr-0.1.1/src/codexmgr/agentsmd.py +0 -96
- codexmgr-0.1.1/src/codexmgr/project.py +0 -74
- codexmgr-0.1.1/uv.lock +0 -86
- {codexmgr-0.1.1 → codexmgr-0.1.2}/.github/actions/install_package/action.yml +0 -0
- {codexmgr-0.1.1 → codexmgr-0.1.2}/.github/workflows/py_test.yml +0 -0
- {codexmgr-0.1.1 → codexmgr-0.1.2}/.github/workflows/version_publish_main.yml +0 -0
- {codexmgr-0.1.1 → codexmgr-0.1.2}/pytest.toml +0 -0
- {codexmgr-0.1.1 → codexmgr-0.1.2}/src/codexmgr/codex.py +0 -0
- {codexmgr-0.1.1 → codexmgr-0.1.2}/src/codexmgr/errors.py +0 -0
- {codexmgr-0.1.1 → codexmgr-0.1.2}/src/codexmgr/paths.py +0 -0
- {codexmgr-0.1.1 → codexmgr-0.1.2}/src/codexmgr/py.typed +0 -0
- {codexmgr-0.1.1 → codexmgr-0.1.2}/src/codexmgr/renderer.py +0 -0
- {codexmgr-0.1.1 → codexmgr-0.1.2}/tests/conftest.py +0 -0
- {codexmgr-0.1.1 → codexmgr-0.1.2}/tests/test_agents_file.py +0 -0
- {codexmgr-0.1.1 → codexmgr-0.1.2}/tests/test_cli.py +0 -0
- {codexmgr-0.1.1 → codexmgr-0.1.2}/tests/test_codex_cli.py +0 -0
- {codexmgr-0.1.1 → codexmgr-0.1.2}/tests/test_empty_skill_config_cli.py +0 -0
- {codexmgr-0.1.1 → codexmgr-0.1.2}/tests/test_home_resolution_cli.py +0 -0
- {codexmgr-0.1.1 → codexmgr-0.1.2}/tests/test_package_metadata.py +0 -0
- {codexmgr-0.1.1 → codexmgr-0.1.2}/tests/test_paths.py +0 -0
- {codexmgr-0.1.1 → codexmgr-0.1.2}/tests/test_python_compatibility.py +0 -0
- {codexmgr-0.1.1 → codexmgr-0.1.2}/tests/test_renderer.py +0 -0
- {codexmgr-0.1.1 → codexmgr-0.1.2}/tests/test_skills_cli.py +0 -0
- {codexmgr-0.1.1 → codexmgr-0.1.2}/tests/test_sync_cli.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codexmgr
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: Manage project-local Codex configuration from reusable templates
|
|
5
5
|
Keywords: agents,cli,codex,configuration,skills
|
|
6
6
|
Classifier: Development Status :: 4 - Beta
|
|
@@ -13,8 +13,10 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
13
13
|
Classifier: Topic :: Software Development
|
|
14
14
|
Classifier: Typing :: Typed
|
|
15
15
|
Requires-Python: >=3.11
|
|
16
|
+
Requires-Dist: tomlkit>=0.15.0
|
|
16
17
|
Provides-Extra: dev
|
|
17
18
|
Requires-Dist: pytest>=9.0.3; extra == 'dev'
|
|
19
|
+
Requires-Dist: pyyaml>=6.0.3; extra == 'dev'
|
|
18
20
|
Description-Content-Type: text/markdown
|
|
19
21
|
|
|
20
22
|
# codexmgr
|
|
@@ -22,12 +24,14 @@ Description-Content-Type: text/markdown
|
|
|
22
24
|
`codexmgr` manages project-local Codex configuration from reusable templates.
|
|
23
25
|
It keeps hand-written project instructions in `AGENTS.md` and generated Codex
|
|
24
26
|
configuration in `.codex/` synchronized from a small declarative
|
|
25
|
-
`.codex/codexmgr.toml` file.
|
|
27
|
+
`.codex/codexmgr.toml` file. It can also keep project-local MCP server
|
|
28
|
+
overrides in sync without editing the user Codex config.
|
|
26
29
|
|
|
27
30
|
The tool is intentionally narrow:
|
|
28
31
|
|
|
29
32
|
- compose reusable AGENTS.md instruction fragments
|
|
30
33
|
- enable or disable Codex skills per project
|
|
34
|
+
- enable, disable, inspect, and update safe project-local MCP overrides
|
|
31
35
|
- write reproducible lock data for the resolved project configuration
|
|
32
36
|
- run `codex` with project `.codex/config.toml` values translated into `-c`
|
|
33
37
|
overrides
|
|
@@ -91,8 +95,10 @@ This updates `.codex/codexmgr.toml`, runs `apply`, writes
|
|
|
91
95
|
|
|
92
96
|
- `.codex/codexmgr.toml`: source configuration edited by CLI commands or by
|
|
93
97
|
hand
|
|
94
|
-
- `.codex/codexmgr.lock`: resolved template and
|
|
98
|
+
- `.codex/codexmgr.lock`: resolved template, skill, and MCP state written by
|
|
99
|
+
`apply`
|
|
95
100
|
- `.codex/config.toml`: Codex config updated with `[[skills.config]]` entries
|
|
101
|
+
and `[mcp_servers.<id>]` overrides
|
|
96
102
|
- `AGENTS.md`: project instructions, with only the managed block replaced
|
|
97
103
|
|
|
98
104
|
The managed AGENTS.md block is:
|
|
@@ -107,7 +113,8 @@ Manual content outside this block is preserved. If the block is missing,
|
|
|
107
113
|
|
|
108
114
|
## Project Configuration
|
|
109
115
|
|
|
110
|
-
`.codex/codexmgr.toml` supports AGENTS.md templates
|
|
116
|
+
`.codex/codexmgr.toml` supports AGENTS.md templates, skill state, and MCP
|
|
117
|
+
overrides:
|
|
111
118
|
|
|
112
119
|
```toml
|
|
113
120
|
[agents_md]
|
|
@@ -116,6 +123,11 @@ src = ["coding", "/absolute/or/project-relative/template.toml"]
|
|
|
116
123
|
[skills]
|
|
117
124
|
enabled = ["review-helper"]
|
|
118
125
|
disabled = ["experimental-skill", "skills/local-disabled"]
|
|
126
|
+
|
|
127
|
+
[mcp.servers.browsermcp]
|
|
128
|
+
enabled = true
|
|
129
|
+
bearer_token_env_var = "BROWSERMCP_TOKEN"
|
|
130
|
+
env_vars = ["BROWSER_ENV"]
|
|
119
131
|
```
|
|
120
132
|
|
|
121
133
|
Named AGENTS.md templates resolve from `$CODEXMGR_HOME/agentsmd/<name>.toml`.
|
|
@@ -163,10 +175,31 @@ keeps template mistakes visible during `apply`.
|
|
|
163
175
|
```bash
|
|
164
176
|
codexmgr setup
|
|
165
177
|
codexmgr apply
|
|
178
|
+
codexmgr apply --check
|
|
179
|
+
codexmgr apply --diff
|
|
180
|
+
codexmgr cd [--path | --explorer | --terminal]
|
|
181
|
+
codexmgr doctor
|
|
182
|
+
codexmgr status
|
|
183
|
+
codexmgr agentsmd list
|
|
184
|
+
codexmgr agentsmd show <name-or-template-path>
|
|
185
|
+
codexmgr agentsmd validate <name-or-template-path>
|
|
166
186
|
codexmgr agentsmd add [--no-sync] <name-or-template-path>
|
|
167
187
|
codexmgr agentsmd remove [--no-sync] <name-or-template-path>
|
|
188
|
+
codexmgr init-template agentsmd <name>
|
|
189
|
+
codexmgr skill list
|
|
168
190
|
codexmgr skill enable [--no-sync] <name-or-skill-path>
|
|
169
191
|
codexmgr skill disable [--no-sync] <name-or-skill-path>
|
|
192
|
+
codexmgr mcp list
|
|
193
|
+
codexmgr mcp show <server-id>
|
|
194
|
+
codexmgr mcp validate
|
|
195
|
+
codexmgr mcp enable [--no-sync] <server-id>
|
|
196
|
+
codexmgr mcp disable [--no-sync] <server-id>
|
|
197
|
+
codexmgr mcp set-token-env [--no-sync] <server-id> <ENV_VAR>
|
|
198
|
+
codexmgr mcp add-env-var [--no-sync] <server-id> <ENV_VAR>
|
|
199
|
+
codexmgr mcp remove-env-var [--no-sync] <server-id> <ENV_VAR>
|
|
200
|
+
codexmgr mcp set-env-header [--no-sync] <server-id> <HEADER> <ENV_VAR>
|
|
201
|
+
codexmgr mcp unset-env-header [--no-sync] <server-id> <HEADER>
|
|
202
|
+
codexmgr mcp set-field [--no-sync] <server-id> <field> <toml-value>
|
|
170
203
|
codexmgr codex <args...>
|
|
171
204
|
```
|
|
172
205
|
|
|
@@ -174,8 +207,91 @@ codexmgr codex <args...>
|
|
|
174
207
|
|
|
175
208
|
`apply` reads `.codex/codexmgr.toml`, resolves configured sources, writes
|
|
176
209
|
`.codex/codexmgr.lock`, updates `.codex/config.toml` skill entries when a
|
|
177
|
-
`[skills]` table is configured,
|
|
178
|
-
|
|
210
|
+
`[skills]` table is configured, writes local `[mcp_servers.<id>]` overrides when
|
|
211
|
+
`[mcp]` is configured, and refreshes the generated `AGENTS.md` block when
|
|
212
|
+
`[agents_md]` is configured.
|
|
213
|
+
|
|
214
|
+
`apply --check` exits with a failure if generated files are out of sync without
|
|
215
|
+
writing them. `apply --diff` also avoids writing and prints unified diffs for
|
|
216
|
+
the expected generated-file changes.
|
|
217
|
+
|
|
218
|
+
`cd` launches a shell in `$CODEXMGR_HOME`. Use
|
|
219
|
+
`codexmgr cd --path` to print only the path, `codexmgr cd --explorer` to open
|
|
220
|
+
the directory in a file explorer, and `codexmgr cd --terminal` to open a new
|
|
221
|
+
terminal there.
|
|
222
|
+
|
|
223
|
+
`doctor` checks project setup, home environment variables, project TOML syntax,
|
|
224
|
+
referenced snippets, enabled skills, and stale generated files.
|
|
225
|
+
|
|
226
|
+
`status` prints the resolved homes, configured snippets and skills, and whether
|
|
227
|
+
generated files are in sync.
|
|
228
|
+
|
|
229
|
+
## Project MCP Overrides
|
|
230
|
+
|
|
231
|
+
`codexmgr mcp ...` edits only project-local configuration:
|
|
232
|
+
|
|
233
|
+
- source state is stored in `.codex/codexmgr.toml` under
|
|
234
|
+
`[mcp.servers.<id>]`
|
|
235
|
+
- `apply` writes generated overrides into `.codex/config.toml` under
|
|
236
|
+
`[mcp_servers.<id>]`
|
|
237
|
+
- `$CODEX_HOME/config.toml` and `~/.codex/config.toml` are never modified
|
|
238
|
+
|
|
239
|
+
Mutating MCP commands require a project `.codex/` directory and run `apply`
|
|
240
|
+
automatically unless `--no-sync` is passed. They do not create or remove MCP
|
|
241
|
+
server definitions; use `codex mcp add` or direct Codex config editing for the
|
|
242
|
+
base server setup.
|
|
243
|
+
|
|
244
|
+
List MCP servers available from Codex and show any project override state:
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
codexmgr mcp list
|
|
248
|
+
codexmgr mcp show context7
|
|
249
|
+
codexmgr mcp validate
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
`codexmgr mcp list` shells out to `codex mcp list --json` for read-only
|
|
253
|
+
discovery. It does not edit user configuration.
|
|
254
|
+
|
|
255
|
+
Enable or disable an existing server without deleting its definition:
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
codexmgr mcp disable context7
|
|
259
|
+
codexmgr mcp enable context7
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Update token and environment references without storing literal token values:
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
codexmgr mcp set-token-env figma FIGMA_TOKEN
|
|
266
|
+
codexmgr mcp add-env-var context7 CONTEXT7_TOKEN
|
|
267
|
+
codexmgr mcp remove-env-var context7 CONTEXT7_TOKEN
|
|
268
|
+
codexmgr mcp set-env-header figma Authorization FIGMA_AUTH_HEADER
|
|
269
|
+
codexmgr mcp unset-env-header figma Authorization
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Set a small allowlist of non-secret fields from TOML literals:
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
codexmgr mcp set-field context7 required true
|
|
276
|
+
codexmgr mcp set-field context7 enabled_tools '["search", "open"]'
|
|
277
|
+
codexmgr mcp set-field context7 default_tools_approval_mode '"prompt"'
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
Supported `set-field` names are `required`, `startup_timeout_sec`,
|
|
281
|
+
`tool_timeout_sec`, `enabled_tools`, `disabled_tools`, and
|
|
282
|
+
`default_tools_approval_mode`. The direct `enable` and `disable` commands manage
|
|
283
|
+
the `enabled` field.
|
|
284
|
+
|
|
285
|
+
Literal API token writes are intentionally not part of this command surface;
|
|
286
|
+
prefer environment variable references such as `bearer_token_env_var`,
|
|
287
|
+
`env_vars`, and `env_http_headers`.
|
|
288
|
+
|
|
289
|
+
`agentsmd list` prints the named templates available under
|
|
290
|
+
`$CODEXMGR_HOME/agentsmd` in sorted order.
|
|
291
|
+
|
|
292
|
+
`agentsmd show` renders one template as AGENTS.md markdown without changing the
|
|
293
|
+
project configuration. `agentsmd validate` loads and renders a template to catch
|
|
294
|
+
TOML or template-shape errors before adding it.
|
|
179
295
|
|
|
180
296
|
`agentsmd add` validates that the template exists before writing config.
|
|
181
297
|
Repeated adds keep one source entry.
|
|
@@ -183,6 +299,12 @@ Repeated adds keep one source entry.
|
|
|
183
299
|
`agentsmd remove` removes a configured template source and fails if the source
|
|
184
300
|
is not present.
|
|
185
301
|
|
|
302
|
+
`init-template agentsmd` creates a starter template under
|
|
303
|
+
`$CODEXMGR_HOME/agentsmd` and refuses to overwrite an existing template.
|
|
304
|
+
|
|
305
|
+
`skill list` prints available `$CODEX_HOME/skills/*/SKILL.md` entries and marks
|
|
306
|
+
configured skills as enabled, disabled, or missing.
|
|
307
|
+
|
|
186
308
|
`skill enable` and `skill disable` keep enabled and disabled lists mutually
|
|
187
309
|
exclusive. Repeated commands keep one entry.
|
|
188
310
|
|
|
@@ -212,8 +334,8 @@ uv build
|
|
|
212
334
|
```
|
|
213
335
|
|
|
214
336
|
The package is typed (`py.typed`) and the test suite covers CLI behavior,
|
|
215
|
-
template rendering, TOML writing, skill resolution,
|
|
216
|
-
home-directory resolution, and package metadata.
|
|
337
|
+
template rendering, TOML writing, skill resolution, generated-file sync checks,
|
|
338
|
+
Codex command generation, home-directory resolution, and package metadata.
|
|
217
339
|
|
|
218
340
|
## Release Notes
|
|
219
341
|
|
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
`codexmgr` manages project-local Codex configuration from reusable templates.
|
|
4
4
|
It keeps hand-written project instructions in `AGENTS.md` and generated Codex
|
|
5
5
|
configuration in `.codex/` synchronized from a small declarative
|
|
6
|
-
`.codex/codexmgr.toml` file.
|
|
6
|
+
`.codex/codexmgr.toml` file. It can also keep project-local MCP server
|
|
7
|
+
overrides in sync without editing the user Codex config.
|
|
7
8
|
|
|
8
9
|
The tool is intentionally narrow:
|
|
9
10
|
|
|
10
11
|
- compose reusable AGENTS.md instruction fragments
|
|
11
12
|
- enable or disable Codex skills per project
|
|
13
|
+
- enable, disable, inspect, and update safe project-local MCP overrides
|
|
12
14
|
- write reproducible lock data for the resolved project configuration
|
|
13
15
|
- run `codex` with project `.codex/config.toml` values translated into `-c`
|
|
14
16
|
overrides
|
|
@@ -72,8 +74,10 @@ This updates `.codex/codexmgr.toml`, runs `apply`, writes
|
|
|
72
74
|
|
|
73
75
|
- `.codex/codexmgr.toml`: source configuration edited by CLI commands or by
|
|
74
76
|
hand
|
|
75
|
-
- `.codex/codexmgr.lock`: resolved template and
|
|
77
|
+
- `.codex/codexmgr.lock`: resolved template, skill, and MCP state written by
|
|
78
|
+
`apply`
|
|
76
79
|
- `.codex/config.toml`: Codex config updated with `[[skills.config]]` entries
|
|
80
|
+
and `[mcp_servers.<id>]` overrides
|
|
77
81
|
- `AGENTS.md`: project instructions, with only the managed block replaced
|
|
78
82
|
|
|
79
83
|
The managed AGENTS.md block is:
|
|
@@ -88,7 +92,8 @@ Manual content outside this block is preserved. If the block is missing,
|
|
|
88
92
|
|
|
89
93
|
## Project Configuration
|
|
90
94
|
|
|
91
|
-
`.codex/codexmgr.toml` supports AGENTS.md templates
|
|
95
|
+
`.codex/codexmgr.toml` supports AGENTS.md templates, skill state, and MCP
|
|
96
|
+
overrides:
|
|
92
97
|
|
|
93
98
|
```toml
|
|
94
99
|
[agents_md]
|
|
@@ -97,6 +102,11 @@ src = ["coding", "/absolute/or/project-relative/template.toml"]
|
|
|
97
102
|
[skills]
|
|
98
103
|
enabled = ["review-helper"]
|
|
99
104
|
disabled = ["experimental-skill", "skills/local-disabled"]
|
|
105
|
+
|
|
106
|
+
[mcp.servers.browsermcp]
|
|
107
|
+
enabled = true
|
|
108
|
+
bearer_token_env_var = "BROWSERMCP_TOKEN"
|
|
109
|
+
env_vars = ["BROWSER_ENV"]
|
|
100
110
|
```
|
|
101
111
|
|
|
102
112
|
Named AGENTS.md templates resolve from `$CODEXMGR_HOME/agentsmd/<name>.toml`.
|
|
@@ -144,10 +154,31 @@ keeps template mistakes visible during `apply`.
|
|
|
144
154
|
```bash
|
|
145
155
|
codexmgr setup
|
|
146
156
|
codexmgr apply
|
|
157
|
+
codexmgr apply --check
|
|
158
|
+
codexmgr apply --diff
|
|
159
|
+
codexmgr cd [--path | --explorer | --terminal]
|
|
160
|
+
codexmgr doctor
|
|
161
|
+
codexmgr status
|
|
162
|
+
codexmgr agentsmd list
|
|
163
|
+
codexmgr agentsmd show <name-or-template-path>
|
|
164
|
+
codexmgr agentsmd validate <name-or-template-path>
|
|
147
165
|
codexmgr agentsmd add [--no-sync] <name-or-template-path>
|
|
148
166
|
codexmgr agentsmd remove [--no-sync] <name-or-template-path>
|
|
167
|
+
codexmgr init-template agentsmd <name>
|
|
168
|
+
codexmgr skill list
|
|
149
169
|
codexmgr skill enable [--no-sync] <name-or-skill-path>
|
|
150
170
|
codexmgr skill disable [--no-sync] <name-or-skill-path>
|
|
171
|
+
codexmgr mcp list
|
|
172
|
+
codexmgr mcp show <server-id>
|
|
173
|
+
codexmgr mcp validate
|
|
174
|
+
codexmgr mcp enable [--no-sync] <server-id>
|
|
175
|
+
codexmgr mcp disable [--no-sync] <server-id>
|
|
176
|
+
codexmgr mcp set-token-env [--no-sync] <server-id> <ENV_VAR>
|
|
177
|
+
codexmgr mcp add-env-var [--no-sync] <server-id> <ENV_VAR>
|
|
178
|
+
codexmgr mcp remove-env-var [--no-sync] <server-id> <ENV_VAR>
|
|
179
|
+
codexmgr mcp set-env-header [--no-sync] <server-id> <HEADER> <ENV_VAR>
|
|
180
|
+
codexmgr mcp unset-env-header [--no-sync] <server-id> <HEADER>
|
|
181
|
+
codexmgr mcp set-field [--no-sync] <server-id> <field> <toml-value>
|
|
151
182
|
codexmgr codex <args...>
|
|
152
183
|
```
|
|
153
184
|
|
|
@@ -155,8 +186,91 @@ codexmgr codex <args...>
|
|
|
155
186
|
|
|
156
187
|
`apply` reads `.codex/codexmgr.toml`, resolves configured sources, writes
|
|
157
188
|
`.codex/codexmgr.lock`, updates `.codex/config.toml` skill entries when a
|
|
158
|
-
`[skills]` table is configured,
|
|
159
|
-
|
|
189
|
+
`[skills]` table is configured, writes local `[mcp_servers.<id>]` overrides when
|
|
190
|
+
`[mcp]` is configured, and refreshes the generated `AGENTS.md` block when
|
|
191
|
+
`[agents_md]` is configured.
|
|
192
|
+
|
|
193
|
+
`apply --check` exits with a failure if generated files are out of sync without
|
|
194
|
+
writing them. `apply --diff` also avoids writing and prints unified diffs for
|
|
195
|
+
the expected generated-file changes.
|
|
196
|
+
|
|
197
|
+
`cd` launches a shell in `$CODEXMGR_HOME`. Use
|
|
198
|
+
`codexmgr cd --path` to print only the path, `codexmgr cd --explorer` to open
|
|
199
|
+
the directory in a file explorer, and `codexmgr cd --terminal` to open a new
|
|
200
|
+
terminal there.
|
|
201
|
+
|
|
202
|
+
`doctor` checks project setup, home environment variables, project TOML syntax,
|
|
203
|
+
referenced snippets, enabled skills, and stale generated files.
|
|
204
|
+
|
|
205
|
+
`status` prints the resolved homes, configured snippets and skills, and whether
|
|
206
|
+
generated files are in sync.
|
|
207
|
+
|
|
208
|
+
## Project MCP Overrides
|
|
209
|
+
|
|
210
|
+
`codexmgr mcp ...` edits only project-local configuration:
|
|
211
|
+
|
|
212
|
+
- source state is stored in `.codex/codexmgr.toml` under
|
|
213
|
+
`[mcp.servers.<id>]`
|
|
214
|
+
- `apply` writes generated overrides into `.codex/config.toml` under
|
|
215
|
+
`[mcp_servers.<id>]`
|
|
216
|
+
- `$CODEX_HOME/config.toml` and `~/.codex/config.toml` are never modified
|
|
217
|
+
|
|
218
|
+
Mutating MCP commands require a project `.codex/` directory and run `apply`
|
|
219
|
+
automatically unless `--no-sync` is passed. They do not create or remove MCP
|
|
220
|
+
server definitions; use `codex mcp add` or direct Codex config editing for the
|
|
221
|
+
base server setup.
|
|
222
|
+
|
|
223
|
+
List MCP servers available from Codex and show any project override state:
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
codexmgr mcp list
|
|
227
|
+
codexmgr mcp show context7
|
|
228
|
+
codexmgr mcp validate
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
`codexmgr mcp list` shells out to `codex mcp list --json` for read-only
|
|
232
|
+
discovery. It does not edit user configuration.
|
|
233
|
+
|
|
234
|
+
Enable or disable an existing server without deleting its definition:
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
codexmgr mcp disable context7
|
|
238
|
+
codexmgr mcp enable context7
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Update token and environment references without storing literal token values:
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
codexmgr mcp set-token-env figma FIGMA_TOKEN
|
|
245
|
+
codexmgr mcp add-env-var context7 CONTEXT7_TOKEN
|
|
246
|
+
codexmgr mcp remove-env-var context7 CONTEXT7_TOKEN
|
|
247
|
+
codexmgr mcp set-env-header figma Authorization FIGMA_AUTH_HEADER
|
|
248
|
+
codexmgr mcp unset-env-header figma Authorization
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Set a small allowlist of non-secret fields from TOML literals:
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
codexmgr mcp set-field context7 required true
|
|
255
|
+
codexmgr mcp set-field context7 enabled_tools '["search", "open"]'
|
|
256
|
+
codexmgr mcp set-field context7 default_tools_approval_mode '"prompt"'
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Supported `set-field` names are `required`, `startup_timeout_sec`,
|
|
260
|
+
`tool_timeout_sec`, `enabled_tools`, `disabled_tools`, and
|
|
261
|
+
`default_tools_approval_mode`. The direct `enable` and `disable` commands manage
|
|
262
|
+
the `enabled` field.
|
|
263
|
+
|
|
264
|
+
Literal API token writes are intentionally not part of this command surface;
|
|
265
|
+
prefer environment variable references such as `bearer_token_env_var`,
|
|
266
|
+
`env_vars`, and `env_http_headers`.
|
|
267
|
+
|
|
268
|
+
`agentsmd list` prints the named templates available under
|
|
269
|
+
`$CODEXMGR_HOME/agentsmd` in sorted order.
|
|
270
|
+
|
|
271
|
+
`agentsmd show` renders one template as AGENTS.md markdown without changing the
|
|
272
|
+
project configuration. `agentsmd validate` loads and renders a template to catch
|
|
273
|
+
TOML or template-shape errors before adding it.
|
|
160
274
|
|
|
161
275
|
`agentsmd add` validates that the template exists before writing config.
|
|
162
276
|
Repeated adds keep one source entry.
|
|
@@ -164,6 +278,12 @@ Repeated adds keep one source entry.
|
|
|
164
278
|
`agentsmd remove` removes a configured template source and fails if the source
|
|
165
279
|
is not present.
|
|
166
280
|
|
|
281
|
+
`init-template agentsmd` creates a starter template under
|
|
282
|
+
`$CODEXMGR_HOME/agentsmd` and refuses to overwrite an existing template.
|
|
283
|
+
|
|
284
|
+
`skill list` prints available `$CODEX_HOME/skills/*/SKILL.md` entries and marks
|
|
285
|
+
configured skills as enabled, disabled, or missing.
|
|
286
|
+
|
|
167
287
|
`skill enable` and `skill disable` keep enabled and disabled lists mutually
|
|
168
288
|
exclusive. Repeated commands keep one entry.
|
|
169
289
|
|
|
@@ -193,8 +313,8 @@ uv build
|
|
|
193
313
|
```
|
|
194
314
|
|
|
195
315
|
The package is typed (`py.typed`) and the test suite covers CLI behavior,
|
|
196
|
-
template rendering, TOML writing, skill resolution,
|
|
197
|
-
home-directory resolution, and package metadata.
|
|
316
|
+
template rendering, TOML writing, skill resolution, generated-file sync checks,
|
|
317
|
+
Codex command generation, home-directory resolution, and package metadata.
|
|
198
318
|
|
|
199
319
|
## Release Notes
|
|
200
320
|
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "codexmgr"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.2"
|
|
4
4
|
description = "Manage project-local Codex configuration from reusable templates"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
7
|
-
dependencies = [
|
|
7
|
+
dependencies = [
|
|
8
|
+
"tomlkit>=0.15.0",
|
|
9
|
+
]
|
|
8
10
|
keywords = ["codex", "cli", "configuration", "agents", "skills"]
|
|
9
11
|
classifiers = [
|
|
10
12
|
"Development Status :: 4 - Beta",
|
|
@@ -24,6 +26,7 @@ codexmgr = "codexmgr.cli:entrypoint"
|
|
|
24
26
|
[project.optional-dependencies]
|
|
25
27
|
dev = [
|
|
26
28
|
"pytest>=9.0.3",
|
|
29
|
+
"pyyaml>=6.0.3",
|
|
27
30
|
]
|
|
28
31
|
|
|
29
32
|
[build-system]
|
|
@@ -19,10 +19,24 @@ def write_managed_agents_md(path: Path, generated_markdown: str) -> None:
|
|
|
19
19
|
None. The file is written with UTF-8 encoding.
|
|
20
20
|
"""
|
|
21
21
|
current = path.read_text(encoding="utf-8") if path.exists() else ""
|
|
22
|
-
updated =
|
|
22
|
+
updated = render_managed_agents_md(current, generated_markdown)
|
|
23
23
|
path.write_text(updated, encoding="utf-8")
|
|
24
24
|
|
|
25
25
|
|
|
26
|
+
def render_managed_agents_md(current: str, generated_markdown: str) -> str:
|
|
27
|
+
"""Render AGENTS.md content with an updated managed block.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
current: Existing AGENTS.md content, or an empty string for a new file.
|
|
31
|
+
generated_markdown: Markdown content for the managed block.
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
Full AGENTS.md content with the codexmgr managed block replaced or
|
|
35
|
+
appended.
|
|
36
|
+
"""
|
|
37
|
+
return _replace_block(current, generated_markdown)
|
|
38
|
+
|
|
39
|
+
|
|
26
40
|
def _replace_block(current: str, generated_markdown: str) -> str:
|
|
27
41
|
"""Replace or append the generated block in AGENTS.md content.
|
|
28
42
|
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"""Manage configured AGENTS.md template sources and rendered output."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from .agents_file import write_managed_agents_md
|
|
7
|
+
from .errors import CommandError
|
|
8
|
+
from .options import list_toml_options
|
|
9
|
+
from .paths import agents_md_path, config_path, resolve_template
|
|
10
|
+
from .project_config import (
|
|
11
|
+
agents_md_sources,
|
|
12
|
+
load_required_project_config,
|
|
13
|
+
require_codex_dir,
|
|
14
|
+
set_agents_md_sources,
|
|
15
|
+
)
|
|
16
|
+
from .renderer import render_agents_markdown
|
|
17
|
+
from .toml_io import load_optional_toml_file, load_toml_file, write_toml_file
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def add_agentsmd(reference: str, cwd: Path, codexmgr_home: Path) -> str:
|
|
21
|
+
"""Add an AGENTS.md template reference to project configuration.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
reference: Named template or TOML path to add.
|
|
25
|
+
cwd: Project directory whose codexmgr.toml should be updated.
|
|
26
|
+
codexmgr_home: codexmgr home used to validate named template references.
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
The reference that was added or already present.
|
|
30
|
+
"""
|
|
31
|
+
require_codex_dir(cwd)
|
|
32
|
+
resolve_template(reference, cwd, codexmgr_home)
|
|
33
|
+
|
|
34
|
+
config = load_optional_toml_file(config_path(cwd))
|
|
35
|
+
sources = agents_md_sources(config)
|
|
36
|
+
if reference not in sources:
|
|
37
|
+
sources.append(reference)
|
|
38
|
+
set_agents_md_sources(config, sources)
|
|
39
|
+
write_toml_file(config_path(cwd), config)
|
|
40
|
+
return reference
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def remove_agentsmd(source_id: str, cwd: Path) -> str:
|
|
44
|
+
"""Remove an AGENTS.md template reference from project configuration.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
source_id: Source identifier or reference to remove.
|
|
48
|
+
cwd: Project directory whose codexmgr.toml should be updated.
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
The removed source identifier.
|
|
52
|
+
"""
|
|
53
|
+
config = load_required_project_config(cwd)
|
|
54
|
+
sources = agents_md_sources(config)
|
|
55
|
+
if source_id not in sources:
|
|
56
|
+
raise CommandError(f"Source not found in codexmgr.toml: {source_id}")
|
|
57
|
+
|
|
58
|
+
set_agents_md_sources(config, [source for source in sources if source != source_id])
|
|
59
|
+
write_toml_file(config_path(cwd), config)
|
|
60
|
+
return source_id
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def list_agentsmd_options(codexmgr_home: Path) -> list[str]:
|
|
64
|
+
"""List named AGENTS.md template options available to add.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
codexmgr_home: codexmgr home directory containing the ``agentsmd``
|
|
68
|
+
template store.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
Sorted template names that can be passed to ``codexmgr agentsmd add``.
|
|
72
|
+
"""
|
|
73
|
+
return list_toml_options(codexmgr_home / "agentsmd")
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def show_agentsmd(reference: str, cwd: Path, codexmgr_home: Path) -> str:
|
|
77
|
+
"""Render one AGENTS.md template reference as markdown.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
reference: Named template or TOML path to render.
|
|
81
|
+
cwd: Project directory used to resolve path references.
|
|
82
|
+
codexmgr_home: codexmgr home used to resolve named references.
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
Rendered markdown for the template.
|
|
86
|
+
"""
|
|
87
|
+
source_id, template_data = _load_template(reference, cwd, codexmgr_home)
|
|
88
|
+
return render_agents_markdown({source_id: template_data})
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def validate_agentsmd(reference: str, cwd: Path, codexmgr_home: Path) -> str:
|
|
92
|
+
"""Validate that one AGENTS.md template can be loaded and rendered.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
reference: Named template or TOML path to validate.
|
|
96
|
+
cwd: Project directory used to resolve path references.
|
|
97
|
+
codexmgr_home: codexmgr home used to resolve named references.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
Source identifier for the valid template.
|
|
101
|
+
"""
|
|
102
|
+
source_id, template_data = _load_template(reference, cwd, codexmgr_home)
|
|
103
|
+
render_agents_markdown({source_id: template_data})
|
|
104
|
+
return source_id
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def init_agentsmd_template(name: str, codexmgr_home: Path) -> Path:
|
|
108
|
+
"""Create a starter named AGENTS.md template.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
name: Bare template name to create.
|
|
112
|
+
codexmgr_home: codexmgr home where the template should be created.
|
|
113
|
+
|
|
114
|
+
Returns:
|
|
115
|
+
Path to the created template file.
|
|
116
|
+
"""
|
|
117
|
+
_validate_template_name(name)
|
|
118
|
+
template_dir = codexmgr_home / "agentsmd"
|
|
119
|
+
template_dir.mkdir(parents=True, exist_ok=True)
|
|
120
|
+
path = template_dir / f"{name}.toml"
|
|
121
|
+
if path.exists():
|
|
122
|
+
raise CommandError(f"Template already exists: {path}")
|
|
123
|
+
path.write_text(_starter_template(), encoding="utf-8")
|
|
124
|
+
return path
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def resolve_locked_agents_md(
|
|
128
|
+
config: dict[str, Any],
|
|
129
|
+
cwd: Path,
|
|
130
|
+
codexmgr_home: Path,
|
|
131
|
+
) -> dict[str, Any]:
|
|
132
|
+
"""Resolve configured AGENTS.md sources into lock data.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
config: Parsed .codex/codexmgr.toml content.
|
|
136
|
+
cwd: Project directory used to resolve path sources.
|
|
137
|
+
codexmgr_home: codexmgr home used to resolve named sources.
|
|
138
|
+
|
|
139
|
+
Returns:
|
|
140
|
+
Resolved source data keyed by source identifier.
|
|
141
|
+
"""
|
|
142
|
+
locked_sources: dict[str, Any] = {}
|
|
143
|
+
for reference in agents_md_sources(config):
|
|
144
|
+
source_id, template_path = resolve_template(reference, cwd, codexmgr_home)
|
|
145
|
+
if source_id in locked_sources:
|
|
146
|
+
raise CommandError(f"Duplicate AGENTS.md source identifier: {source_id}")
|
|
147
|
+
template_data = load_toml_file(template_path)
|
|
148
|
+
if not template_data:
|
|
149
|
+
raise CommandError(f"Template is empty: {template_path}")
|
|
150
|
+
locked_sources[source_id] = template_data
|
|
151
|
+
return locked_sources
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def write_agents_md(cwd: Path, locked_sources: dict[str, Any]) -> None:
|
|
155
|
+
"""Write resolved AGENTS.md lock data to the managed block.
|
|
156
|
+
|
|
157
|
+
Args:
|
|
158
|
+
cwd: Project directory whose root AGENTS.md should be updated.
|
|
159
|
+
locked_sources: Resolved source data keyed by source identifier.
|
|
160
|
+
"""
|
|
161
|
+
write_managed_agents_md(agents_md_path(cwd), render_agents_markdown(locked_sources))
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def _load_template(
|
|
165
|
+
reference: str,
|
|
166
|
+
cwd: Path,
|
|
167
|
+
codexmgr_home: Path,
|
|
168
|
+
) -> tuple[str, dict[str, Any]]:
|
|
169
|
+
"""Load a named or path-backed AGENTS.md template.
|
|
170
|
+
|
|
171
|
+
Args:
|
|
172
|
+
reference: Named template or TOML path to load.
|
|
173
|
+
cwd: Project directory used to resolve path references.
|
|
174
|
+
codexmgr_home: codexmgr home used to resolve named references.
|
|
175
|
+
|
|
176
|
+
Returns:
|
|
177
|
+
Source identifier and parsed TOML data.
|
|
178
|
+
"""
|
|
179
|
+
source_id, template_path = resolve_template(reference, cwd, codexmgr_home)
|
|
180
|
+
template_data = load_toml_file(template_path)
|
|
181
|
+
if not template_data:
|
|
182
|
+
raise CommandError(f"Template is empty: {template_path}")
|
|
183
|
+
return source_id, template_data
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def _validate_template_name(name: str) -> None:
|
|
187
|
+
"""Validate a starter template name.
|
|
188
|
+
|
|
189
|
+
Args:
|
|
190
|
+
name: Candidate bare template name.
|
|
191
|
+
|
|
192
|
+
Returns:
|
|
193
|
+
None. ``CommandError`` is raised for invalid names.
|
|
194
|
+
"""
|
|
195
|
+
if not name or "/" in name or "\\" in name or name.endswith(".toml"):
|
|
196
|
+
raise CommandError(f"Template name must be a bare name: {name}")
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def _starter_template() -> str:
|
|
200
|
+
"""Return starter TOML content for a new AGENTS.md template.
|
|
201
|
+
|
|
202
|
+
Returns:
|
|
203
|
+
A minimal renderable template document.
|
|
204
|
+
"""
|
|
205
|
+
return (
|
|
206
|
+
"[instructions]\n"
|
|
207
|
+
'text = """\n'
|
|
208
|
+
"- Replace this with reusable project guidance.\n"
|
|
209
|
+
'"""\n'
|
|
210
|
+
)
|