codexmgr 0.1.2__tar.gz → 0.2.0__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.
Files changed (128) hide show
  1. {codexmgr-0.1.2 → codexmgr-0.2.0}/.gitignore +4 -1
  2. {codexmgr-0.1.2 → codexmgr-0.2.0}/PKG-INFO +183 -23
  3. {codexmgr-0.1.2 → codexmgr-0.2.0}/README.md +180 -22
  4. {codexmgr-0.1.2 → codexmgr-0.2.0}/pyproject.toml +4 -2
  5. {codexmgr-0.1.2 → codexmgr-0.2.0}/src/codexmgr/__init__.py +1 -1
  6. codexmgr-0.2.0/src/codexmgr/agents/__init__.py +1 -0
  7. codexmgr-0.1.2/src/codexmgr/agents_file.py → codexmgr-0.2.0/src/codexmgr/agents/file.py +1 -1
  8. codexmgr-0.1.2/src/codexmgr/agentsmd.py → codexmgr-0.2.0/src/codexmgr/agents/manager.py +7 -7
  9. {codexmgr-0.1.2/src/codexmgr → codexmgr-0.2.0/src/codexmgr/agents}/renderer.py +1 -1
  10. codexmgr-0.2.0/src/codexmgr/commands/__init__.py +1 -0
  11. {codexmgr-0.1.2/src/codexmgr → codexmgr-0.2.0/src/codexmgr/commands}/codex.py +30 -3
  12. codexmgr-0.2.0/src/codexmgr/commands/codex_jit.py +230 -0
  13. codexmgr-0.2.0/src/codexmgr/commands/config_mutations.py +265 -0
  14. {codexmgr-0.1.2/src/codexmgr → codexmgr-0.2.0/src/codexmgr/commands}/health.py +82 -8
  15. {codexmgr-0.1.2/src/codexmgr → codexmgr-0.2.0/src/codexmgr/commands}/navigation.py +1 -1
  16. codexmgr-0.2.0/src/codexmgr/commands/rules.py +115 -0
  17. codexmgr-0.2.0/src/codexmgr/core/__init__.py +45 -0
  18. codexmgr-0.2.0/src/codexmgr/custom_agents/__init__.py +1 -0
  19. codexmgr-0.2.0/src/codexmgr/custom_agents/cli.py +120 -0
  20. codexmgr-0.2.0/src/codexmgr/custom_agents/config.py +165 -0
  21. codexmgr-0.2.0/src/codexmgr/custom_agents/copies.py +164 -0
  22. codexmgr-0.2.0/src/codexmgr/custom_agents/listing.py +131 -0
  23. codexmgr-0.2.0/src/codexmgr/custom_agents/resolution.py +95 -0
  24. codexmgr-0.2.0/src/codexmgr/custom_agents/sources.py +135 -0
  25. codexmgr-0.2.0/src/codexmgr/hooks/__init__.py +25 -0
  26. codexmgr-0.2.0/src/codexmgr/hooks/config.py +167 -0
  27. codexmgr-0.2.0/src/codexmgr/hooks/copies.py +219 -0
  28. codexmgr-0.2.0/src/codexmgr/hooks/listing.py +131 -0
  29. codexmgr-0.2.0/src/codexmgr/hooks/merge.py +255 -0
  30. codexmgr-0.2.0/src/codexmgr/hooks/resolution.py +258 -0
  31. codexmgr-0.2.0/src/codexmgr/hooks/sources.py +127 -0
  32. codexmgr-0.2.0/src/codexmgr/interface/__init__.py +1 -0
  33. {codexmgr-0.1.2/src/codexmgr → codexmgr-0.2.0/src/codexmgr/interface}/cli.py +41 -90
  34. codexmgr-0.1.2/src/codexmgr/cli_parser.py → codexmgr-0.2.0/src/codexmgr/interface/parser.py +106 -62
  35. codexmgr-0.2.0/src/codexmgr/interface/parsers/__init__.py +2 -0
  36. codexmgr-0.2.0/src/codexmgr/interface/parsers/agents.py +27 -0
  37. codexmgr-0.2.0/src/codexmgr/interface/parsers/mcp.py +88 -0
  38. codexmgr-0.2.0/src/codexmgr/mcp/__init__.py +56 -0
  39. codexmgr-0.1.2/src/codexmgr/mcp_apply.py → codexmgr-0.2.0/src/codexmgr/mcp/apply.py +2 -2
  40. codexmgr-0.1.2/src/codexmgr/mcp_cli.py → codexmgr-0.2.0/src/codexmgr/mcp/cli.py +31 -24
  41. codexmgr-0.1.2/src/codexmgr/mcp.py → codexmgr-0.2.0/src/codexmgr/mcp/config.py +60 -85
  42. codexmgr-0.1.2/src/codexmgr/mcp_discovery.py → codexmgr-0.2.0/src/codexmgr/mcp/discovery.py +1 -1
  43. codexmgr-0.1.2/src/codexmgr/mcp_fields.py → codexmgr-0.2.0/src/codexmgr/mcp/fields.py +2 -2
  44. codexmgr-0.2.0/src/codexmgr/mcp/tables.py +90 -0
  45. codexmgr-0.2.0/src/codexmgr/packages/__init__.py +13 -0
  46. codexmgr-0.2.0/src/codexmgr/packages/cli.py +109 -0
  47. codexmgr-0.2.0/src/codexmgr/packages/config.py +207 -0
  48. codexmgr-0.2.0/src/codexmgr/packages/listing.py +17 -0
  49. codexmgr-0.2.0/src/codexmgr/packages/mutation.py +221 -0
  50. codexmgr-0.2.0/src/codexmgr/packages/sources.py +80 -0
  51. codexmgr-0.2.0/src/codexmgr/project/__init__.py +1 -0
  52. codexmgr-0.2.0/src/codexmgr/project/apply.py +299 -0
  53. codexmgr-0.1.2/src/codexmgr/project_config.py → codexmgr-0.2.0/src/codexmgr/project/config.py +3 -3
  54. codexmgr-0.2.0/src/codexmgr/project/generated.py +197 -0
  55. codexmgr-0.2.0/src/codexmgr/project/snapshot.py +145 -0
  56. codexmgr-0.2.0/src/codexmgr/project/state.py +53 -0
  57. codexmgr-0.2.0/src/codexmgr/project/sync.py +280 -0
  58. codexmgr-0.2.0/src/codexmgr/rules/__init__.py +1 -0
  59. codexmgr-0.2.0/src/codexmgr/rules/config.py +193 -0
  60. codexmgr-0.2.0/src/codexmgr/rules/copies.py +198 -0
  61. codexmgr-0.2.0/src/codexmgr/rules/listing.py +135 -0
  62. codexmgr-0.2.0/src/codexmgr/rules/resolution.py +180 -0
  63. codexmgr-0.2.0/src/codexmgr/rules/sources.py +146 -0
  64. codexmgr-0.2.0/src/codexmgr/skills/__init__.py +28 -0
  65. codexmgr-0.1.2/src/codexmgr/skills.py → codexmgr-0.2.0/src/codexmgr/skills/config.py +31 -42
  66. codexmgr-0.2.0/src/codexmgr/skills/copies.py +199 -0
  67. codexmgr-0.1.2/src/codexmgr/skill_listing.py → codexmgr-0.2.0/src/codexmgr/skills/listing.py +28 -33
  68. codexmgr-0.2.0/src/codexmgr/skills/resolution.py +147 -0
  69. codexmgr-0.2.0/src/codexmgr/skills/sources.py +274 -0
  70. codexmgr-0.2.0/src/codexmgr/tui/__init__.py +2 -0
  71. codexmgr-0.2.0/src/codexmgr/tui/app.py +294 -0
  72. codexmgr-0.2.0/src/codexmgr/tui/cli.py +34 -0
  73. codexmgr-0.2.0/src/codexmgr/tui/diff.py +27 -0
  74. codexmgr-0.2.0/src/codexmgr/tui/items.py +289 -0
  75. codexmgr-0.2.0/src/codexmgr/tui/models.py +50 -0
  76. codexmgr-0.2.0/src/codexmgr/tui/mutations.py +170 -0
  77. codexmgr-0.2.0/src/codexmgr/tui/package_refs.py +89 -0
  78. codexmgr-0.2.0/src/codexmgr/tui/package_selection.py +23 -0
  79. codexmgr-0.2.0/src/codexmgr/tui/package_state.py +214 -0
  80. codexmgr-0.2.0/src/codexmgr/tui/rendering.py +114 -0
  81. codexmgr-0.2.0/src/codexmgr/tui/rule_items.py +58 -0
  82. codexmgr-0.2.0/src/codexmgr/tui/sections.py +203 -0
  83. codexmgr-0.2.0/src/codexmgr/tui/staged_packages.py +99 -0
  84. codexmgr-0.2.0/src/codexmgr/tui/state.py +256 -0
  85. {codexmgr-0.1.2 → codexmgr-0.2.0}/tests/conftest.py +1 -1
  86. codexmgr-0.2.0/tests/test_agents_cli.py +245 -0
  87. {codexmgr-0.1.2 → codexmgr-0.2.0}/tests/test_agents_file.py +2 -2
  88. codexmgr-0.2.0/tests/test_apply_check_cli.py +346 -0
  89. {codexmgr-0.1.2 → codexmgr-0.2.0}/tests/test_cd_cli.py +1 -1
  90. {codexmgr-0.1.2 → codexmgr-0.2.0}/tests/test_cli.py +125 -6
  91. codexmgr-0.2.0/tests/test_codex_cli.py +481 -0
  92. codexmgr-0.2.0/tests/test_hooks_cli.py +436 -0
  93. {codexmgr-0.1.2 → codexmgr-0.2.0}/tests/test_mcp_cli.py +60 -4
  94. codexmgr-0.2.0/tests/test_packages_cli.py +765 -0
  95. {codexmgr-0.1.2 → codexmgr-0.2.0}/tests/test_paths.py +1 -1
  96. {codexmgr-0.1.2 → codexmgr-0.2.0}/tests/test_renderer.py +2 -2
  97. codexmgr-0.2.0/tests/test_rules_cli.py +264 -0
  98. codexmgr-0.2.0/tests/test_skill_copies_cli.py +179 -0
  99. codexmgr-0.2.0/tests/test_skill_home_sources_cli.py +58 -0
  100. {codexmgr-0.1.2 → codexmgr-0.2.0}/tests/test_skills_cli.py +51 -0
  101. codexmgr-0.2.0/tests/test_status_doctor_cli.py +417 -0
  102. {codexmgr-0.1.2 → codexmgr-0.2.0}/tests/test_sync_cli.py +10 -4
  103. {codexmgr-0.1.2 → codexmgr-0.2.0}/tests/test_toml_io.py +2 -2
  104. codexmgr-0.2.0/tests/test_tui_app.py +215 -0
  105. codexmgr-0.2.0/tests/test_tui_state.py +484 -0
  106. {codexmgr-0.1.2 → codexmgr-0.2.0}/uv.lock +125 -1
  107. codexmgr-0.1.2/src/codexmgr/project.py +0 -206
  108. codexmgr-0.1.2/src/codexmgr/sync.py +0 -134
  109. codexmgr-0.1.2/tests/test_apply_check_cli.py +0 -83
  110. codexmgr-0.1.2/tests/test_codex_cli.py +0 -154
  111. codexmgr-0.1.2/tests/test_status_doctor_cli.py +0 -164
  112. {codexmgr-0.1.2 → codexmgr-0.2.0}/.github/actions/install_package/action.yml +0 -0
  113. {codexmgr-0.1.2 → codexmgr-0.2.0}/.github/workflows/py_test.yml +0 -0
  114. {codexmgr-0.1.2 → codexmgr-0.2.0}/.github/workflows/version_publish_main.yml +0 -0
  115. {codexmgr-0.1.2 → codexmgr-0.2.0}/pytest.toml +0 -0
  116. {codexmgr-0.1.2/src/codexmgr → codexmgr-0.2.0/src/codexmgr/core}/errors.py +0 -0
  117. {codexmgr-0.1.2/src/codexmgr → codexmgr-0.2.0/src/codexmgr/core}/options.py +0 -0
  118. {codexmgr-0.1.2/src/codexmgr → codexmgr-0.2.0/src/codexmgr/core}/paths.py +0 -0
  119. {codexmgr-0.1.2/src/codexmgr → codexmgr-0.2.0/src/codexmgr/core}/toml_io.py +0 -0
  120. {codexmgr-0.1.2 → codexmgr-0.2.0}/src/codexmgr/py.typed +0 -0
  121. {codexmgr-0.1.2 → codexmgr-0.2.0}/tests/test_agentsmd_list_cli.py +0 -0
  122. {codexmgr-0.1.2 → codexmgr-0.2.0}/tests/test_agentsmd_tools_cli.py +0 -0
  123. {codexmgr-0.1.2 → codexmgr-0.2.0}/tests/test_empty_skill_config_cli.py +0 -0
  124. {codexmgr-0.1.2 → codexmgr-0.2.0}/tests/test_home_resolution_cli.py +0 -0
  125. {codexmgr-0.1.2 → codexmgr-0.2.0}/tests/test_mcp_apply_cli.py +0 -0
  126. {codexmgr-0.1.2 → codexmgr-0.2.0}/tests/test_package_metadata.py +0 -0
  127. {codexmgr-0.1.2 → codexmgr-0.2.0}/tests/test_python_compatibility.py +0 -0
  128. {codexmgr-0.1.2 → codexmgr-0.2.0}/tests/test_skill_list_cli.py +0 -0
@@ -11,5 +11,8 @@ wheels/
11
11
  AGENTS.md
12
12
  tasks.md
13
13
  .thoughts
14
+ .brainstorm
14
15
  .plan
15
- .agent
16
+ .agent
17
+ .rules
18
+ .docs
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codexmgr
3
- Version: 0.1.2
3
+ Version: 0.2.0
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: textual>=8.2.7
16
17
  Requires-Dist: tomlkit>=0.15.0
17
18
  Provides-Extra: dev
19
+ Requires-Dist: pytest-asyncio>=1.4.0; extra == 'dev'
18
20
  Requires-Dist: pytest>=9.0.3; extra == 'dev'
19
21
  Requires-Dist: pyyaml>=6.0.3; extra == 'dev'
20
22
  Description-Content-Type: text/markdown
@@ -31,7 +33,12 @@ The tool is intentionally narrow:
31
33
 
32
34
  - compose reusable AGENTS.md instruction fragments
33
35
  - enable or disable Codex skills per project
36
+ - enable or disable reusable Codex hook bundles per project
37
+ - enable or disable project custom agents from reusable TOML files
38
+ - enable or disable reusable rule files copied into project-local `.rules/`
39
+ - enable or disable packaged sets of AGENTS.md, agent, skill, hook, and rule settings
34
40
  - enable, disable, inspect, and update safe project-local MCP overrides
41
+ - use an interactive terminal UI for common project management tasks
35
42
  - write reproducible lock data for the resolved project configuration
36
43
  - run `codex` with project `.codex/config.toml` values translated into `-c`
37
44
  overrides
@@ -95,10 +102,16 @@ This updates `.codex/codexmgr.toml`, runs `apply`, writes
95
102
 
96
103
  - `.codex/codexmgr.toml`: source configuration edited by CLI commands or by
97
104
  hand
98
- - `.codex/codexmgr.lock`: resolved template, skill, and MCP state written by
99
- `apply`
105
+ - `.codex/codexmgr.lock`: resolved template, agent, skill, hook, and MCP state
106
+ written by `apply`
100
107
  - `.codex/config.toml`: Codex config updated with `[[skills.config]]` entries
101
108
  and `[mcp_servers.<id>]` overrides
109
+ - `.codex/hooks.json`: Codex hook config updated with enabled reusable hook
110
+ bundles while preserving unmanaged local hooks
111
+ - `.codex/hooks/<name>`: project-local copies of enabled hook bundle support
112
+ files
113
+ - `.codex/agents/<name>.toml`: project-local copies of enabled custom agents
114
+ - `.rules/<path>`: project-local copies of enabled reusable rule files
102
115
  - `AGENTS.md`: project instructions, with only the managed block replaced
103
116
 
104
117
  The managed AGENTS.md block is:
@@ -113,8 +126,8 @@ Manual content outside this block is preserved. If the block is missing,
113
126
 
114
127
  ## Project Configuration
115
128
 
116
- `.codex/codexmgr.toml` supports AGENTS.md templates, skill state, and MCP
117
- overrides:
129
+ `.codex/codexmgr.toml` supports AGENTS.md templates, custom-agent state, skill
130
+ state, hook state, and MCP overrides:
118
131
 
119
132
  ```toml
120
133
  [agents_md]
@@ -124,6 +137,18 @@ src = ["coding", "/absolute/or/project-relative/template.toml"]
124
137
  enabled = ["review-helper"]
125
138
  disabled = ["experimental-skill", "skills/local-disabled"]
126
139
 
140
+ [agents]
141
+ enabled = ["rule-retriever"]
142
+ disabled = ["experimental-agent"]
143
+
144
+ [hooks]
145
+ enabled = ["repo-rules"]
146
+ disabled = ["experimental-hook"]
147
+
148
+ [rules]
149
+ enabled = ["react/", "python/testing.md"]
150
+ disabled = ["react/materials/"]
151
+
127
152
  [mcp.servers.browsermcp]
128
153
  enabled = true
129
154
  bearer_token_env_var = "BROWSERMCP_TOKEN"
@@ -134,15 +159,101 @@ Named AGENTS.md templates resolve from `$CODEXMGR_HOME/agentsmd/<name>.toml`.
134
159
  Path-like template values resolve relative to the project unless they are
135
160
  absolute paths.
136
161
 
137
- Named skills resolve from `$CODEX_HOME/skills/<name>/SKILL.md`. If `CODEX_HOME`
138
- is unset, `~/.codex` is used. Path-like skill values resolve to either a
139
- `SKILL.md` file or a directory containing `SKILL.md`. Missing skills are written
140
- as name-based entries so Codex can resolve them later.
162
+ Named skills resolve from `$CODEXMGR_HOME/skills/<name>/SKILL.md` or
163
+ `$CODEX_HOME/skills/<name>/SKILL.md`; duplicate names across distinct homes
164
+ fail. Enabled CODEXMGR_HOME skills are copied into `.agents/skills/<name>` on
165
+ every apply by overlaying source files while preserving extra local files.
166
+ Path-like skill values resolve to either a `SKILL.md` file or a directory
167
+ containing `SKILL.md`. Missing skills are written as name-based entries so Codex
168
+ can resolve them later.
169
+
170
+ Named custom agents resolve from `$CODEXMGR_HOME/agents/<name>.toml`. Enabled
171
+ agents are copied into `.codex/agents/<name>.toml` on every apply. Disabled
172
+ agents remove their managed copy only when the lock records the file as
173
+ codexmgr-managed.
174
+
175
+ Named hooks resolve from `$CODEXMGR_HOME/hooks/<name>/hooks.json`. Enabled hook
176
+ bundles are merged into `.codex/hooks.json` on every apply with
177
+ `codexmanager_meta` added to each managed handler. Existing unmanaged hooks are
178
+ preserved. Bundle files other than the root `hooks.json` are copied into
179
+ `.codex/hooks/<name>`.
180
+
181
+ Rule refs resolve under `$CODEXMGR_HOME/rules/` and are POSIX-style relative
182
+ paths. Folder refs are stored with a trailing slash and copy all regular files
183
+ recursively into `.rules/` while preserving relative paths. File refs copy one
184
+ file. Extensionless refs prefer an existing `<ref>.md`. Enabled refs expand
185
+ first, then disabled file or folder refs remove entries from that candidate set.
186
+ First-time applies refuse to overwrite unmanaged `.rules/...` files.
187
+
188
+ Packaged configurations resolve from
189
+ `$CODEXMGR_HOME/packages/<name>/config.toml`. A package config is a TOML
190
+ document that can contain root `agentsmd`, `agents`, `hooks`, `skills`, and `rules`
191
+ string lists plus optional profile tables:
192
+
193
+ ```toml
194
+ agentsmd = []
195
+ agents = ["rule-retriever"]
196
+ hooks = ["repo-rules"]
197
+ skills = ["repo-rule-manager"]
198
+ rules = ["react/"]
199
+
200
+ [profiles.strict]
201
+ agentsmd = ["strict-coding"]
202
+ agents = ["strict-agent"]
203
+ hooks = ["strict-rules"]
204
+ skills = ["strict-review"]
205
+ rules = ["python/testing.md"]
206
+ ```
207
+
208
+ `codexmgr package enable <name>` validates package AGENTS.md and hook
209
+ references, then updates `.codex/codexmgr.toml` as if the corresponding
210
+ `agentsmd add`, `hooks enable`, and `skill enable` commands had been run.
211
+ `codexmgr package disable <name>` removes package AGENTS.md entries when
212
+ present and disables the package skills, hooks, agents, and rules.
213
+
214
+ Package profiles are merged with the root package entries:
215
+
216
+ ```bash
217
+ codexmgr package enable repo-rules --profile strict coding --profile python
218
+ ```
219
+
220
+ Direct mutating commands also accept batch targets, for example:
221
+
222
+ ```bash
223
+ codexmgr agentsmd add coding python
224
+ codexmgr skill enable review-helper repo-rule-manager
225
+ codexmgr hooks enable repo-rules audit
226
+ codexmgr mcp enable browsermcp context7
227
+ ```
141
228
 
142
229
  Mutating commands run `apply` automatically unless `--no-sync` is passed.
143
230
  Project guidelines require `apply` whenever `.codex/codexmgr.toml` changes,
144
231
  unless `--no-sync` was explicitly requested.
145
232
 
233
+ ## Interactive TUI
234
+
235
+ `codexmgr tui` opens a Textual-based terminal UI for managing project-local
236
+ configuration. It shows AGENTS.md templates, skills, hooks, custom agents,
237
+ rules, packages, and MCP server enable overrides in selectable lists. Changes are
238
+ staged in memory while you navigate and toggle entries. Press `s` to save; the
239
+ save writes `.codex/codexmgr.toml` once and runs `apply` once unless
240
+ `--no-sync` was used.
241
+ For resources with explicit enable and disable lists, `space` cycles the
242
+ highlighted row through available, enabled, and disabled states.
243
+ Package profiles appear as separate selectable rows under their package.
244
+
245
+ ```bash
246
+ codexmgr tui
247
+ codexmgr tui --no-sync
248
+ codexmgr tui --show-diff
249
+ ```
250
+
251
+ The dashboard shows generated-file sync state. By default it lists stale
252
+ generated paths; with `--show-diff`, it shows unified diffs for the staged
253
+ configuration. MCP editing in the TUI is intentionally limited to the
254
+ project-local `enabled` override. Advanced MCP fields remain available through
255
+ the classic `codexmgr mcp ...` commands.
256
+
146
257
  ## Template Format
147
258
 
148
259
  Template files are TOML documents. Each top-level key must be a table and
@@ -180,20 +291,33 @@ codexmgr apply --diff
180
291
  codexmgr cd [--path | --explorer | --terminal]
181
292
  codexmgr doctor
182
293
  codexmgr status
294
+ codexmgr tui [--no-sync] [--show-diff]
183
295
  codexmgr agentsmd list
184
296
  codexmgr agentsmd show <name-or-template-path>
185
297
  codexmgr agentsmd validate <name-or-template-path>
186
- codexmgr agentsmd add [--no-sync] <name-or-template-path>
187
- codexmgr agentsmd remove [--no-sync] <name-or-template-path>
298
+ codexmgr agentsmd add [--no-sync] <name-or-template-path> [...]
299
+ codexmgr agentsmd remove [--no-sync] <name-or-template-path> [...]
188
300
  codexmgr init-template agentsmd <name>
189
301
  codexmgr skill list
190
- codexmgr skill enable [--no-sync] <name-or-skill-path>
191
- codexmgr skill disable [--no-sync] <name-or-skill-path>
302
+ codexmgr skill enable [--no-sync] <name-or-skill-path> [...]
303
+ codexmgr skill disable [--no-sync] <name-or-skill-path> [...]
304
+ codexmgr agents list
305
+ codexmgr agents enable [--no-sync] <agent-name> [...]
306
+ codexmgr agents disable [--no-sync] <agent-name> [...]
307
+ codexmgr hooks list
308
+ codexmgr hooks enable [--no-sync] <hook-name> [...]
309
+ codexmgr hooks disable [--no-sync] <hook-name> [...]
310
+ codexmgr rules list
311
+ codexmgr rules enable [--no-sync] <rule-ref> [...]
312
+ codexmgr rules disable [--no-sync] <rule-ref> [...]
313
+ codexmgr package list
314
+ codexmgr package enable [--no-sync] <package-name> [...] [--profile <name> [...]]
315
+ codexmgr package disable [--no-sync] <package-name> [...] [--profile <name> [...]]
192
316
  codexmgr mcp list
193
317
  codexmgr mcp show <server-id>
194
318
  codexmgr mcp validate
195
- codexmgr mcp enable [--no-sync] <server-id>
196
- codexmgr mcp disable [--no-sync] <server-id>
319
+ codexmgr mcp enable [--no-sync] <server-id> [...]
320
+ codexmgr mcp disable [--no-sync] <server-id> [...]
197
321
  codexmgr mcp set-token-env [--no-sync] <server-id> <ENV_VAR>
198
322
  codexmgr mcp add-env-var [--no-sync] <server-id> <ENV_VAR>
199
323
  codexmgr mcp remove-env-var [--no-sync] <server-id> <ENV_VAR>
@@ -207,9 +331,12 @@ codexmgr codex <args...>
207
331
 
208
332
  `apply` reads `.codex/codexmgr.toml`, resolves configured sources, writes
209
333
  `.codex/codexmgr.lock`, updates `.codex/config.toml` skill entries when a
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.
334
+ `[skills]` table is configured, copies `.codex/agents/<name>.toml` files when
335
+ `[agents]` is configured, writes `.codex/hooks.json` when `[hooks]` is
336
+ configured, copies `.rules/<path>` files when `[rules]` is configured, writes
337
+ local `[mcp_servers.<id>]` overrides when `[mcp]` is
338
+ configured, and refreshes the generated `AGENTS.md` block when `[agents_md]` is
339
+ configured.
213
340
 
214
341
  `apply --check` exits with a failure if generated files are out of sync without
215
342
  writing them. `apply --diff` also avoids writing and prints unified diffs for
@@ -221,10 +348,19 @@ the directory in a file explorer, and `codexmgr cd --terminal` to open a new
221
348
  terminal there.
222
349
 
223
350
  `doctor` checks project setup, home environment variables, project TOML syntax,
224
- referenced snippets, enabled skills, and stale generated files.
351
+ referenced snippets, enabled skills, enabled custom agents, enabled hook
352
+ bundles, enabled rules, and stale generated files.
353
+
354
+ `status` prints the resolved homes, configured snippets, skills, custom agents,
355
+ hooks, rules, and whether generated files are in sync.
225
356
 
226
- `status` prints the resolved homes, configured snippets and skills, and whether
227
- generated files are in sync.
357
+ `codexmgr codex` can run with a just-in-time package/profile overlay without
358
+ changing `.codex/codexmgr.toml`. Put Codex arguments after `--` when using this
359
+ syntax:
360
+
361
+ ```bash
362
+ codexmgr codex repo-rules --profile strict coding --profile python -- exec "review this"
363
+ ```
228
364
 
229
365
  ## Project MCP Overrides
230
366
 
@@ -302,12 +438,36 @@ is not present.
302
438
  `init-template agentsmd` creates a starter template under
303
439
  `$CODEXMGR_HOME/agentsmd` and refuses to overwrite an existing template.
304
440
 
305
- `skill list` prints available `$CODEX_HOME/skills/*/SKILL.md` entries and marks
306
- configured skills as enabled, disabled, or missing.
441
+ `skill list` prints available `$CODEXMGR_HOME/skills/*/SKILL.md`,
442
+ `$CODEX_HOME/skills/*/SKILL.md`, and local `.agents/skills/*/SKILL.md` entries
443
+ and marks configured skills as enabled, disabled, or missing.
307
444
 
308
445
  `skill enable` and `skill disable` keep enabled and disabled lists mutually
309
446
  exclusive. Repeated commands keep one entry.
310
447
 
448
+ `hooks list` prints available `$CODEXMGR_HOME/hooks/*/hooks.json` entries and
449
+ marks configured hook bundles as enabled, disabled, or missing.
450
+
451
+ `hooks enable` validates that the named hook bundle exists before writing
452
+ config. `hooks enable` and `hooks disable` keep enabled and disabled lists
453
+ mutually exclusive. Repeated commands keep one entry.
454
+
455
+ `rules list` prints available `$CODEXMGR_HOME/rules/**` files and folders and
456
+ marks configured rule refs as enabled, disabled, or missing.
457
+
458
+ `rules enable` validates and canonicalizes refs before writing config.
459
+ `rules disable` canonicalizes existing refs and permits missing exclusions.
460
+ Enabled and disabled lists are exact-ref mutually exclusive, so parent enables
461
+ and child disables can intentionally coexist.
462
+
463
+ `package list` prints available `$CODEXMGR_HOME/packages/*/config.toml`
464
+ entries in sorted order.
465
+
466
+ `package enable` and `package disable` proxy to existing AGENTS.md, custom-agent,
467
+ skill, hook, and rule project-config mutations. Package state is not tracked
468
+ separately; the resulting `[agents_md]`, `[agents]`, `[skills]`, `[hooks]`, and `[rules]`
469
+ tables remain the source of truth.
470
+
311
471
  `codex` forwards arguments to the real `codex` command. Values from
312
472
  `.codex/config.toml` are flattened into `-c key=value` overrides. User-provided
313
473
  `-c` or `--config` overrides are merged after project config: scalar values
@@ -10,7 +10,12 @@ The tool is intentionally narrow:
10
10
 
11
11
  - compose reusable AGENTS.md instruction fragments
12
12
  - enable or disable Codex skills per project
13
+ - enable or disable reusable Codex hook bundles per project
14
+ - enable or disable project custom agents from reusable TOML files
15
+ - enable or disable reusable rule files copied into project-local `.rules/`
16
+ - enable or disable packaged sets of AGENTS.md, agent, skill, hook, and rule settings
13
17
  - enable, disable, inspect, and update safe project-local MCP overrides
18
+ - use an interactive terminal UI for common project management tasks
14
19
  - write reproducible lock data for the resolved project configuration
15
20
  - run `codex` with project `.codex/config.toml` values translated into `-c`
16
21
  overrides
@@ -74,10 +79,16 @@ This updates `.codex/codexmgr.toml`, runs `apply`, writes
74
79
 
75
80
  - `.codex/codexmgr.toml`: source configuration edited by CLI commands or by
76
81
  hand
77
- - `.codex/codexmgr.lock`: resolved template, skill, and MCP state written by
78
- `apply`
82
+ - `.codex/codexmgr.lock`: resolved template, agent, skill, hook, and MCP state
83
+ written by `apply`
79
84
  - `.codex/config.toml`: Codex config updated with `[[skills.config]]` entries
80
85
  and `[mcp_servers.<id>]` overrides
86
+ - `.codex/hooks.json`: Codex hook config updated with enabled reusable hook
87
+ bundles while preserving unmanaged local hooks
88
+ - `.codex/hooks/<name>`: project-local copies of enabled hook bundle support
89
+ files
90
+ - `.codex/agents/<name>.toml`: project-local copies of enabled custom agents
91
+ - `.rules/<path>`: project-local copies of enabled reusable rule files
81
92
  - `AGENTS.md`: project instructions, with only the managed block replaced
82
93
 
83
94
  The managed AGENTS.md block is:
@@ -92,8 +103,8 @@ Manual content outside this block is preserved. If the block is missing,
92
103
 
93
104
  ## Project Configuration
94
105
 
95
- `.codex/codexmgr.toml` supports AGENTS.md templates, skill state, and MCP
96
- overrides:
106
+ `.codex/codexmgr.toml` supports AGENTS.md templates, custom-agent state, skill
107
+ state, hook state, and MCP overrides:
97
108
 
98
109
  ```toml
99
110
  [agents_md]
@@ -103,6 +114,18 @@ src = ["coding", "/absolute/or/project-relative/template.toml"]
103
114
  enabled = ["review-helper"]
104
115
  disabled = ["experimental-skill", "skills/local-disabled"]
105
116
 
117
+ [agents]
118
+ enabled = ["rule-retriever"]
119
+ disabled = ["experimental-agent"]
120
+
121
+ [hooks]
122
+ enabled = ["repo-rules"]
123
+ disabled = ["experimental-hook"]
124
+
125
+ [rules]
126
+ enabled = ["react/", "python/testing.md"]
127
+ disabled = ["react/materials/"]
128
+
106
129
  [mcp.servers.browsermcp]
107
130
  enabled = true
108
131
  bearer_token_env_var = "BROWSERMCP_TOKEN"
@@ -113,15 +136,101 @@ Named AGENTS.md templates resolve from `$CODEXMGR_HOME/agentsmd/<name>.toml`.
113
136
  Path-like template values resolve relative to the project unless they are
114
137
  absolute paths.
115
138
 
116
- Named skills resolve from `$CODEX_HOME/skills/<name>/SKILL.md`. If `CODEX_HOME`
117
- is unset, `~/.codex` is used. Path-like skill values resolve to either a
118
- `SKILL.md` file or a directory containing `SKILL.md`. Missing skills are written
119
- as name-based entries so Codex can resolve them later.
139
+ Named skills resolve from `$CODEXMGR_HOME/skills/<name>/SKILL.md` or
140
+ `$CODEX_HOME/skills/<name>/SKILL.md`; duplicate names across distinct homes
141
+ fail. Enabled CODEXMGR_HOME skills are copied into `.agents/skills/<name>` on
142
+ every apply by overlaying source files while preserving extra local files.
143
+ Path-like skill values resolve to either a `SKILL.md` file or a directory
144
+ containing `SKILL.md`. Missing skills are written as name-based entries so Codex
145
+ can resolve them later.
146
+
147
+ Named custom agents resolve from `$CODEXMGR_HOME/agents/<name>.toml`. Enabled
148
+ agents are copied into `.codex/agents/<name>.toml` on every apply. Disabled
149
+ agents remove their managed copy only when the lock records the file as
150
+ codexmgr-managed.
151
+
152
+ Named hooks resolve from `$CODEXMGR_HOME/hooks/<name>/hooks.json`. Enabled hook
153
+ bundles are merged into `.codex/hooks.json` on every apply with
154
+ `codexmanager_meta` added to each managed handler. Existing unmanaged hooks are
155
+ preserved. Bundle files other than the root `hooks.json` are copied into
156
+ `.codex/hooks/<name>`.
157
+
158
+ Rule refs resolve under `$CODEXMGR_HOME/rules/` and are POSIX-style relative
159
+ paths. Folder refs are stored with a trailing slash and copy all regular files
160
+ recursively into `.rules/` while preserving relative paths. File refs copy one
161
+ file. Extensionless refs prefer an existing `<ref>.md`. Enabled refs expand
162
+ first, then disabled file or folder refs remove entries from that candidate set.
163
+ First-time applies refuse to overwrite unmanaged `.rules/...` files.
164
+
165
+ Packaged configurations resolve from
166
+ `$CODEXMGR_HOME/packages/<name>/config.toml`. A package config is a TOML
167
+ document that can contain root `agentsmd`, `agents`, `hooks`, `skills`, and `rules`
168
+ string lists plus optional profile tables:
169
+
170
+ ```toml
171
+ agentsmd = []
172
+ agents = ["rule-retriever"]
173
+ hooks = ["repo-rules"]
174
+ skills = ["repo-rule-manager"]
175
+ rules = ["react/"]
176
+
177
+ [profiles.strict]
178
+ agentsmd = ["strict-coding"]
179
+ agents = ["strict-agent"]
180
+ hooks = ["strict-rules"]
181
+ skills = ["strict-review"]
182
+ rules = ["python/testing.md"]
183
+ ```
184
+
185
+ `codexmgr package enable <name>` validates package AGENTS.md and hook
186
+ references, then updates `.codex/codexmgr.toml` as if the corresponding
187
+ `agentsmd add`, `hooks enable`, and `skill enable` commands had been run.
188
+ `codexmgr package disable <name>` removes package AGENTS.md entries when
189
+ present and disables the package skills, hooks, agents, and rules.
190
+
191
+ Package profiles are merged with the root package entries:
192
+
193
+ ```bash
194
+ codexmgr package enable repo-rules --profile strict coding --profile python
195
+ ```
196
+
197
+ Direct mutating commands also accept batch targets, for example:
198
+
199
+ ```bash
200
+ codexmgr agentsmd add coding python
201
+ codexmgr skill enable review-helper repo-rule-manager
202
+ codexmgr hooks enable repo-rules audit
203
+ codexmgr mcp enable browsermcp context7
204
+ ```
120
205
 
121
206
  Mutating commands run `apply` automatically unless `--no-sync` is passed.
122
207
  Project guidelines require `apply` whenever `.codex/codexmgr.toml` changes,
123
208
  unless `--no-sync` was explicitly requested.
124
209
 
210
+ ## Interactive TUI
211
+
212
+ `codexmgr tui` opens a Textual-based terminal UI for managing project-local
213
+ configuration. It shows AGENTS.md templates, skills, hooks, custom agents,
214
+ rules, packages, and MCP server enable overrides in selectable lists. Changes are
215
+ staged in memory while you navigate and toggle entries. Press `s` to save; the
216
+ save writes `.codex/codexmgr.toml` once and runs `apply` once unless
217
+ `--no-sync` was used.
218
+ For resources with explicit enable and disable lists, `space` cycles the
219
+ highlighted row through available, enabled, and disabled states.
220
+ Package profiles appear as separate selectable rows under their package.
221
+
222
+ ```bash
223
+ codexmgr tui
224
+ codexmgr tui --no-sync
225
+ codexmgr tui --show-diff
226
+ ```
227
+
228
+ The dashboard shows generated-file sync state. By default it lists stale
229
+ generated paths; with `--show-diff`, it shows unified diffs for the staged
230
+ configuration. MCP editing in the TUI is intentionally limited to the
231
+ project-local `enabled` override. Advanced MCP fields remain available through
232
+ the classic `codexmgr mcp ...` commands.
233
+
125
234
  ## Template Format
126
235
 
127
236
  Template files are TOML documents. Each top-level key must be a table and
@@ -159,20 +268,33 @@ codexmgr apply --diff
159
268
  codexmgr cd [--path | --explorer | --terminal]
160
269
  codexmgr doctor
161
270
  codexmgr status
271
+ codexmgr tui [--no-sync] [--show-diff]
162
272
  codexmgr agentsmd list
163
273
  codexmgr agentsmd show <name-or-template-path>
164
274
  codexmgr agentsmd validate <name-or-template-path>
165
- codexmgr agentsmd add [--no-sync] <name-or-template-path>
166
- codexmgr agentsmd remove [--no-sync] <name-or-template-path>
275
+ codexmgr agentsmd add [--no-sync] <name-or-template-path> [...]
276
+ codexmgr agentsmd remove [--no-sync] <name-or-template-path> [...]
167
277
  codexmgr init-template agentsmd <name>
168
278
  codexmgr skill list
169
- codexmgr skill enable [--no-sync] <name-or-skill-path>
170
- codexmgr skill disable [--no-sync] <name-or-skill-path>
279
+ codexmgr skill enable [--no-sync] <name-or-skill-path> [...]
280
+ codexmgr skill disable [--no-sync] <name-or-skill-path> [...]
281
+ codexmgr agents list
282
+ codexmgr agents enable [--no-sync] <agent-name> [...]
283
+ codexmgr agents disable [--no-sync] <agent-name> [...]
284
+ codexmgr hooks list
285
+ codexmgr hooks enable [--no-sync] <hook-name> [...]
286
+ codexmgr hooks disable [--no-sync] <hook-name> [...]
287
+ codexmgr rules list
288
+ codexmgr rules enable [--no-sync] <rule-ref> [...]
289
+ codexmgr rules disable [--no-sync] <rule-ref> [...]
290
+ codexmgr package list
291
+ codexmgr package enable [--no-sync] <package-name> [...] [--profile <name> [...]]
292
+ codexmgr package disable [--no-sync] <package-name> [...] [--profile <name> [...]]
171
293
  codexmgr mcp list
172
294
  codexmgr mcp show <server-id>
173
295
  codexmgr mcp validate
174
- codexmgr mcp enable [--no-sync] <server-id>
175
- codexmgr mcp disable [--no-sync] <server-id>
296
+ codexmgr mcp enable [--no-sync] <server-id> [...]
297
+ codexmgr mcp disable [--no-sync] <server-id> [...]
176
298
  codexmgr mcp set-token-env [--no-sync] <server-id> <ENV_VAR>
177
299
  codexmgr mcp add-env-var [--no-sync] <server-id> <ENV_VAR>
178
300
  codexmgr mcp remove-env-var [--no-sync] <server-id> <ENV_VAR>
@@ -186,9 +308,12 @@ codexmgr codex <args...>
186
308
 
187
309
  `apply` reads `.codex/codexmgr.toml`, resolves configured sources, writes
188
310
  `.codex/codexmgr.lock`, updates `.codex/config.toml` skill entries when a
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.
311
+ `[skills]` table is configured, copies `.codex/agents/<name>.toml` files when
312
+ `[agents]` is configured, writes `.codex/hooks.json` when `[hooks]` is
313
+ configured, copies `.rules/<path>` files when `[rules]` is configured, writes
314
+ local `[mcp_servers.<id>]` overrides when `[mcp]` is
315
+ configured, and refreshes the generated `AGENTS.md` block when `[agents_md]` is
316
+ configured.
192
317
 
193
318
  `apply --check` exits with a failure if generated files are out of sync without
194
319
  writing them. `apply --diff` also avoids writing and prints unified diffs for
@@ -200,10 +325,19 @@ the directory in a file explorer, and `codexmgr cd --terminal` to open a new
200
325
  terminal there.
201
326
 
202
327
  `doctor` checks project setup, home environment variables, project TOML syntax,
203
- referenced snippets, enabled skills, and stale generated files.
328
+ referenced snippets, enabled skills, enabled custom agents, enabled hook
329
+ bundles, enabled rules, and stale generated files.
330
+
331
+ `status` prints the resolved homes, configured snippets, skills, custom agents,
332
+ hooks, rules, and whether generated files are in sync.
204
333
 
205
- `status` prints the resolved homes, configured snippets and skills, and whether
206
- generated files are in sync.
334
+ `codexmgr codex` can run with a just-in-time package/profile overlay without
335
+ changing `.codex/codexmgr.toml`. Put Codex arguments after `--` when using this
336
+ syntax:
337
+
338
+ ```bash
339
+ codexmgr codex repo-rules --profile strict coding --profile python -- exec "review this"
340
+ ```
207
341
 
208
342
  ## Project MCP Overrides
209
343
 
@@ -281,12 +415,36 @@ is not present.
281
415
  `init-template agentsmd` creates a starter template under
282
416
  `$CODEXMGR_HOME/agentsmd` and refuses to overwrite an existing template.
283
417
 
284
- `skill list` prints available `$CODEX_HOME/skills/*/SKILL.md` entries and marks
285
- configured skills as enabled, disabled, or missing.
418
+ `skill list` prints available `$CODEXMGR_HOME/skills/*/SKILL.md`,
419
+ `$CODEX_HOME/skills/*/SKILL.md`, and local `.agents/skills/*/SKILL.md` entries
420
+ and marks configured skills as enabled, disabled, or missing.
286
421
 
287
422
  `skill enable` and `skill disable` keep enabled and disabled lists mutually
288
423
  exclusive. Repeated commands keep one entry.
289
424
 
425
+ `hooks list` prints available `$CODEXMGR_HOME/hooks/*/hooks.json` entries and
426
+ marks configured hook bundles as enabled, disabled, or missing.
427
+
428
+ `hooks enable` validates that the named hook bundle exists before writing
429
+ config. `hooks enable` and `hooks disable` keep enabled and disabled lists
430
+ mutually exclusive. Repeated commands keep one entry.
431
+
432
+ `rules list` prints available `$CODEXMGR_HOME/rules/**` files and folders and
433
+ marks configured rule refs as enabled, disabled, or missing.
434
+
435
+ `rules enable` validates and canonicalizes refs before writing config.
436
+ `rules disable` canonicalizes existing refs and permits missing exclusions.
437
+ Enabled and disabled lists are exact-ref mutually exclusive, so parent enables
438
+ and child disables can intentionally coexist.
439
+
440
+ `package list` prints available `$CODEXMGR_HOME/packages/*/config.toml`
441
+ entries in sorted order.
442
+
443
+ `package enable` and `package disable` proxy to existing AGENTS.md, custom-agent,
444
+ skill, hook, and rule project-config mutations. Package state is not tracked
445
+ separately; the resulting `[agents_md]`, `[agents]`, `[skills]`, `[hooks]`, and `[rules]`
446
+ tables remain the source of truth.
447
+
290
448
  `codex` forwards arguments to the real `codex` command. Values from
291
449
  `.codex/config.toml` are flattened into `-c key=value` overrides. User-provided
292
450
  `-c` or `--config` overrides are merged after project config: scalar values
@@ -1,10 +1,11 @@
1
1
  [project]
2
2
  name = "codexmgr"
3
- version = "0.1.2"
3
+ version = "0.2.0"
4
4
  description = "Manage project-local Codex configuration from reusable templates"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
7
7
  dependencies = [
8
+ "textual>=8.2.7",
8
9
  "tomlkit>=0.15.0",
9
10
  ]
10
11
  keywords = ["codex", "cli", "configuration", "agents", "skills"]
@@ -21,12 +22,13 @@ classifiers = [
21
22
  ]
22
23
 
23
24
  [project.scripts]
24
- codexmgr = "codexmgr.cli:entrypoint"
25
+ codexmgr = "codexmgr.interface.cli:entrypoint"
25
26
 
26
27
  [project.optional-dependencies]
27
28
  dev = [
28
29
  "pytest>=9.0.3",
29
30
  "pyyaml>=6.0.3",
31
+ "pytest-asyncio>=1.4.0",
30
32
  ]
31
33
 
32
34
  [build-system]
@@ -2,4 +2,4 @@
2
2
 
3
3
  __all__ = ["__version__"]
4
4
 
5
- __version__ = "0.1.2"
5
+ __version__ = "0.2.0"
@@ -0,0 +1 @@
1
+ """AGENTS.md template resolution, rendering, and managed-file packages."""
@@ -2,7 +2,7 @@
2
2
 
3
3
  from pathlib import Path
4
4
 
5
- from .errors import CommandError
5
+ from ..core.errors import CommandError
6
6
 
7
7
  BEGIN_MARKER = "<!-- BEGIN CODEXMGR GENERATED -->"
8
8
  END_MARKER = "<!-- END CODEXMGR GENERATED -->"
@@ -3,18 +3,18 @@
3
3
  from pathlib import Path
4
4
  from typing import Any
5
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 (
6
+ from .file import write_managed_agents_md
7
+ from .renderer import render_agents_markdown
8
+ from ..core.errors import CommandError
9
+ from ..core.options import list_toml_options
10
+ from ..core.paths import agents_md_path, config_path, resolve_template
11
+ from ..core.toml_io import load_optional_toml_file, load_toml_file, write_toml_file
12
+ from ..project.config import (
11
13
  agents_md_sources,
12
14
  load_required_project_config,
13
15
  require_codex_dir,
14
16
  set_agents_md_sources,
15
17
  )
16
- from .renderer import render_agents_markdown
17
- from .toml_io import load_optional_toml_file, load_toml_file, write_toml_file
18
18
 
19
19
 
20
20
  def add_agentsmd(reference: str, cwd: Path, codexmgr_home: Path) -> str: