codexmgr 0.2.0__tar.gz → 0.3.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 (137) hide show
  1. codexmgr-0.3.0/PKG-INFO +584 -0
  2. codexmgr-0.3.0/README.md +560 -0
  3. {codexmgr-0.2.0 → codexmgr-0.3.0}/pyproject.toml +4 -1
  4. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/__init__.py +1 -1
  5. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/interface/parsers/mcp.py +8 -8
  6. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/mcp/__init__.py +38 -0
  7. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/mcp/apply.py +16 -9
  8. codexmgr-0.3.0/src/codexmgr/mcp/cli.py +242 -0
  9. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/mcp/fields.py +9 -20
  10. codexmgr-0.3.0/src/codexmgr/mcp/project.py +181 -0
  11. codexmgr-0.3.0/src/codexmgr/mcp/resolution.py +112 -0
  12. codexmgr-0.3.0/src/codexmgr/mcp/sources.py +186 -0
  13. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/project/apply.py +31 -137
  14. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/project/generated.py +10 -6
  15. codexmgr-0.3.0/src/codexmgr/project/resolution.py +180 -0
  16. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/rules/listing.py +21 -13
  17. codexmgr-0.3.0/src/codexmgr/rules/tree.py +206 -0
  18. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/tui/app.py +79 -90
  19. codexmgr-0.3.0/src/codexmgr/tui/focus.py +182 -0
  20. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/tui/items.py +1 -57
  21. codexmgr-0.3.0/src/codexmgr/tui/mcp_items.py +50 -0
  22. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/tui/mutations.py +14 -0
  23. codexmgr-0.3.0/src/codexmgr/tui/panels.py +113 -0
  24. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/tui/rendering.py +5 -0
  25. codexmgr-0.3.0/src/codexmgr/tui/rule_items.py +56 -0
  26. codexmgr-0.3.0/src/codexmgr/tui/rule_tree.py +141 -0
  27. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/tui/sections.py +1 -1
  28. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/tui/state.py +17 -14
  29. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_mcp_apply_cli.py +81 -6
  30. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_mcp_cli.py +190 -96
  31. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_package_metadata.py +8 -0
  32. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_packages_cli.py +33 -0
  33. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_rules_cli.py +59 -3
  34. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_tui_app.py +125 -0
  35. codexmgr-0.3.0/tests/test_tui_selection_focus.py +142 -0
  36. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_tui_state.py +44 -13
  37. {codexmgr-0.2.0 → codexmgr-0.3.0}/uv.lock +1 -1
  38. codexmgr-0.2.0/PKG-INFO +0 -504
  39. codexmgr-0.2.0/README.md +0 -481
  40. codexmgr-0.2.0/src/codexmgr/mcp/cli.py +0 -197
  41. codexmgr-0.2.0/src/codexmgr/tui/rule_items.py +0 -58
  42. {codexmgr-0.2.0 → codexmgr-0.3.0}/.github/actions/install_package/action.yml +0 -0
  43. {codexmgr-0.2.0 → codexmgr-0.3.0}/.github/workflows/py_test.yml +0 -0
  44. {codexmgr-0.2.0 → codexmgr-0.3.0}/.github/workflows/version_publish_main.yml +0 -0
  45. {codexmgr-0.2.0 → codexmgr-0.3.0}/.gitignore +0 -0
  46. {codexmgr-0.2.0 → codexmgr-0.3.0}/pytest.toml +0 -0
  47. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/agents/__init__.py +0 -0
  48. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/agents/file.py +0 -0
  49. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/agents/manager.py +0 -0
  50. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/agents/renderer.py +0 -0
  51. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/commands/__init__.py +0 -0
  52. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/commands/codex.py +0 -0
  53. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/commands/codex_jit.py +0 -0
  54. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/commands/config_mutations.py +0 -0
  55. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/commands/health.py +0 -0
  56. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/commands/navigation.py +0 -0
  57. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/commands/rules.py +0 -0
  58. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/core/__init__.py +0 -0
  59. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/core/errors.py +0 -0
  60. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/core/options.py +0 -0
  61. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/core/paths.py +0 -0
  62. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/core/toml_io.py +0 -0
  63. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/custom_agents/__init__.py +0 -0
  64. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/custom_agents/cli.py +0 -0
  65. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/custom_agents/config.py +0 -0
  66. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/custom_agents/copies.py +0 -0
  67. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/custom_agents/listing.py +0 -0
  68. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/custom_agents/resolution.py +0 -0
  69. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/custom_agents/sources.py +0 -0
  70. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/hooks/__init__.py +0 -0
  71. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/hooks/config.py +0 -0
  72. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/hooks/copies.py +0 -0
  73. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/hooks/listing.py +0 -0
  74. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/hooks/merge.py +0 -0
  75. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/hooks/resolution.py +0 -0
  76. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/hooks/sources.py +0 -0
  77. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/interface/__init__.py +0 -0
  78. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/interface/cli.py +0 -0
  79. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/interface/parser.py +0 -0
  80. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/interface/parsers/__init__.py +0 -0
  81. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/interface/parsers/agents.py +0 -0
  82. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/mcp/config.py +0 -0
  83. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/mcp/discovery.py +0 -0
  84. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/mcp/tables.py +0 -0
  85. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/packages/__init__.py +0 -0
  86. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/packages/cli.py +0 -0
  87. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/packages/config.py +0 -0
  88. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/packages/listing.py +0 -0
  89. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/packages/mutation.py +0 -0
  90. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/packages/sources.py +0 -0
  91. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/project/__init__.py +0 -0
  92. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/project/config.py +0 -0
  93. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/project/snapshot.py +0 -0
  94. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/project/state.py +0 -0
  95. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/project/sync.py +0 -0
  96. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/py.typed +0 -0
  97. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/rules/__init__.py +0 -0
  98. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/rules/config.py +0 -0
  99. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/rules/copies.py +0 -0
  100. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/rules/resolution.py +0 -0
  101. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/rules/sources.py +0 -0
  102. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/skills/__init__.py +0 -0
  103. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/skills/config.py +0 -0
  104. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/skills/copies.py +0 -0
  105. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/skills/listing.py +0 -0
  106. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/skills/resolution.py +0 -0
  107. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/skills/sources.py +0 -0
  108. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/tui/__init__.py +0 -0
  109. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/tui/cli.py +0 -0
  110. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/tui/diff.py +0 -0
  111. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/tui/models.py +0 -0
  112. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/tui/package_refs.py +0 -0
  113. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/tui/package_selection.py +0 -0
  114. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/tui/package_state.py +0 -0
  115. {codexmgr-0.2.0 → codexmgr-0.3.0}/src/codexmgr/tui/staged_packages.py +0 -0
  116. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/conftest.py +0 -0
  117. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_agents_cli.py +0 -0
  118. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_agents_file.py +0 -0
  119. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_agentsmd_list_cli.py +0 -0
  120. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_agentsmd_tools_cli.py +0 -0
  121. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_apply_check_cli.py +0 -0
  122. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_cd_cli.py +0 -0
  123. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_cli.py +0 -0
  124. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_codex_cli.py +0 -0
  125. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_empty_skill_config_cli.py +0 -0
  126. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_home_resolution_cli.py +0 -0
  127. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_hooks_cli.py +0 -0
  128. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_paths.py +0 -0
  129. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_python_compatibility.py +0 -0
  130. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_renderer.py +0 -0
  131. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_skill_copies_cli.py +0 -0
  132. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_skill_home_sources_cli.py +0 -0
  133. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_skill_list_cli.py +0 -0
  134. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_skills_cli.py +0 -0
  135. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_status_doctor_cli.py +0 -0
  136. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_sync_cli.py +0 -0
  137. {codexmgr-0.2.0 → codexmgr-0.3.0}/tests/test_toml_io.py +0 -0
@@ -0,0 +1,584 @@
1
+ Metadata-Version: 2.4
2
+ Name: codexmgr
3
+ Version: 0.3.0
4
+ Summary: Manage project-local Codex configuration from reusable templates
5
+ Project-URL: Repository, https://github.com/JulianKimmig/codexmgr/
6
+ Keywords: agents,cli,codex,configuration,skills
7
+ Classifier: Development Status :: 4 - Beta
8
+ Classifier: Environment :: Console
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Topic :: Software Development
15
+ Classifier: Typing :: Typed
16
+ Requires-Python: >=3.11
17
+ Requires-Dist: textual>=8.2.7
18
+ Requires-Dist: tomlkit>=0.15.0
19
+ Provides-Extra: dev
20
+ Requires-Dist: pytest-asyncio>=1.4.0; extra == 'dev'
21
+ Requires-Dist: pytest>=9.0.3; extra == 'dev'
22
+ Requires-Dist: pyyaml>=6.0.3; extra == 'dev'
23
+ Description-Content-Type: text/markdown
24
+
25
+ # codexmgr
26
+
27
+ `codexmgr` manages reusable Codex project setup. Keep shared `AGENTS.md`
28
+ snippets, skills, hooks, custom agents, rule files, packages, and reusable MCP
29
+ source files in one manager home, then sync the selected pieces into each
30
+ project from `.codex/codexmgr.toml`.
31
+
32
+ The tool is for people who use Codex in several repositories and do not want to
33
+ copy the same agent instructions by hand. When a shared rule changes, update it
34
+ once in `$CODEXMGR_HOME` and apply it wherever that project has opted in.
35
+
36
+ Use `codexmgr` when a project should:
37
+
38
+ - build `AGENTS.md` from reusable instruction snippets
39
+ - share skills, hooks, custom agents, and rule files across repositories
40
+ - enable packaged Codex setups made from those reusable pieces
41
+ - keep reusable MCP server definitions out of the user-level Codex config
42
+ - check whether generated Codex files match the project config
43
+ - run `codex` with project `.codex/config.toml` values passed as `-c` overrides
44
+
45
+ The basic model has three parts:
46
+
47
+ - `$CODEXMGR_HOME` stores reusable inputs; when unset it defaults to
48
+ `~/.codexmgr`
49
+ - `.codex/codexmgr.toml` records what the current project wants to use
50
+ - `codexmgr apply` resolves the selected inputs and writes the project files
51
+ Codex reads
52
+
53
+ ## Requirements
54
+
55
+ - Python 3.11 or newer
56
+ - `codex` on `PATH` only when using `codexmgr codex ...`
57
+
58
+ ## Install
59
+
60
+ Install `codexmgr` as a command-line tool from the Python package. `pipx` is
61
+ the recommended persistent install because it keeps the tool isolated from
62
+ project environments:
63
+
64
+ ```bash
65
+ pipx install codexmgr
66
+ ```
67
+
68
+ If you use `uv` for command-line tools:
69
+
70
+ ```bash
71
+ uv tool install codexmgr
72
+ ```
73
+
74
+ Plain `pip` also works inside an environment you control:
75
+
76
+ ```bash
77
+ python -m pip install codexmgr
78
+ ```
79
+
80
+ Verify the install:
81
+
82
+ ```bash
83
+ codexmgr --help
84
+ ```
85
+
86
+ ## Quick Start
87
+
88
+ Start inside the project that should receive Codex configuration.
89
+
90
+ ```bash
91
+ codexmgr setup
92
+ ```
93
+
94
+ `setup` creates `.codex/`, creates `.codex/codexmgr.toml` if it is missing, and
95
+ runs `apply`. Existing project config is preserved.
96
+
97
+ Create a reusable `AGENTS.md` snippet in the manager home. This command creates
98
+ `$CODEXMGR_HOME/agentsmd/coding.toml` and refuses to overwrite an existing file:
99
+
100
+ ```bash
101
+ codexmgr init-template agentsmd coding
102
+ ```
103
+
104
+ You can also write the snippet yourself. A snippet is a TOML template whose
105
+ tables become Markdown headings in `AGENTS.md`:
106
+
107
+ ```toml
108
+ # ~/.codexmgr/agentsmd/coding.toml
109
+ [coding]
110
+ text = """
111
+ - Keep source files focused and small.
112
+ - Add tests for behavior changes before implementation.
113
+ """
114
+ [coding.debugging]
115
+ text = "Prefer lasting regression tests over temporary scripts."
116
+ ```
117
+
118
+ Add the snippet to the current project:
119
+
120
+ ```bash
121
+ codexmgr agentsmd add coding
122
+ ```
123
+
124
+ This updates `.codex/codexmgr.toml`, runs `apply`, writes
125
+ `.codex/codexmgr.lock`, and refreshes the managed block in `AGENTS.md`.
126
+
127
+ Preview or validate a snippet when you want to check it before adding it:
128
+
129
+ ```bash
130
+ codexmgr agentsmd show coding
131
+ codexmgr agentsmd validate coding
132
+ ```
133
+
134
+ Check what the project is using after changes:
135
+
136
+ ```bash
137
+ codexmgr status
138
+ codexmgr doctor
139
+ codexmgr apply --check
140
+ ```
141
+
142
+ ## Managed Files
143
+
144
+ The project source of truth is `.codex/codexmgr.toml`. CLI commands edit this
145
+ file for you, and you can also edit it by hand when that is clearer.
146
+
147
+ `apply` resolves the source config and may write or update these managed files:
148
+
149
+ - `.codex/codexmgr.lock`: resolved AGENTS.md, agent, skill, hook, rule, and MCP
150
+ state
151
+ - `.codex/config.toml`: project-local Codex config, including generated
152
+ `[[skills.config]]` entries and `[mcp_servers.<id>]` server definitions
153
+ - `.codex/hooks.json`: generated hook config for enabled reusable hook bundles
154
+ - `.codex/hooks/<name>`: copied support files for enabled hook bundles
155
+ - `.codex/agents/<name>.toml`: copied custom-agent definitions
156
+ - `.agents/skills/<name>`: copied manager-home skills
157
+ - `.rules/<path>`: copied reusable rule files
158
+ - `AGENTS.md`: project instructions with only the generated block replaced
159
+
160
+ The managed `AGENTS.md` block is:
161
+
162
+ ```markdown
163
+ <!-- BEGIN CODEXMGR GENERATED -->
164
+ <!-- END CODEXMGR GENERATED -->
165
+ ```
166
+
167
+ Manual content outside this block is preserved. If the block is missing,
168
+ `codexmgr` appends it. If `AGENTS.md` is missing, `codexmgr` creates it.
169
+
170
+ ## Project Configuration
171
+
172
+ `.codex/codexmgr.toml` can opt into each resource type independently. A minimal
173
+ file may only contain `[agents_md]`; larger projects can add skills, custom
174
+ agents, hooks, reusable rules, and MCP sources or overlays as needed. Package commands
175
+ write those same tables rather than a separate package table.
176
+
177
+ ```toml
178
+ [agents_md]
179
+ src = ["coding", "/absolute/or/project-relative/template.toml"]
180
+ [skills]
181
+ enabled = ["review-helper"]
182
+ disabled = ["experimental-skill", "skills/local-disabled"]
183
+ [agents]
184
+ enabled = ["rule-retriever"]
185
+ disabled = ["experimental-agent"]
186
+ [hooks]
187
+ enabled = ["repo-rules"]
188
+ disabled = ["experimental-hook"]
189
+ [rules]
190
+ enabled = ["react/", "python/testing.md"]
191
+ disabled = ["react/materials/"]
192
+ [mcp]
193
+ enabled = ["browsermcp"]
194
+ [mcp.servers.browsermcp]
195
+ enabled = true
196
+ bearer_token_env_var = "BROWSERMCP_TOKEN"
197
+ env_vars = ["BROWSER_ENV"]
198
+ ```
199
+
200
+ Mutating commands run `apply` automatically unless `--no-sync` is passed. If
201
+ you edit `.codex/codexmgr.toml` by hand, run `codexmgr apply` or
202
+ `codexmgr apply --check` afterwards.
203
+
204
+ ## Reference Resolution
205
+
206
+ Named `AGENTS.md` snippets resolve from
207
+ `$CODEXMGR_HOME/agentsmd/<name>.toml`. Path-like snippet values resolve
208
+ relative to the project unless they are absolute paths.
209
+
210
+ Named skills resolve from `$CODEXMGR_HOME/skills/<name>/SKILL.md` or
211
+ `$CODEX_HOME/skills/<name>/SKILL.md`. Duplicate names across distinct homes
212
+ fail so the selected skill is not ambiguous.
213
+
214
+ Enabled skills from `$CODEXMGR_HOME` are copied into `.agents/skills/<name>` on
215
+ every apply. The copy overlays source files while preserving extra local files.
216
+ Path-like skill values can point to a `SKILL.md` file or a directory containing
217
+ `SKILL.md`.
218
+
219
+ Missing skills are still written as name-based entries. That lets Codex resolve
220
+ them later from another installed skill source.
221
+
222
+ Named custom agents resolve from `$CODEXMGR_HOME/agents/<name>.toml`. Enabled
223
+ agents are copied into `.codex/agents/<name>.toml`; disabled agents remove the
224
+ managed copy only when the lock records it as codexmgr-managed.
225
+
226
+ Named hooks resolve from `$CODEXMGR_HOME/hooks/<name>/hooks.json`. Enabled hook
227
+ bundles are merged into `.codex/hooks.json`, and existing unmanaged hooks are
228
+ preserved.
229
+
230
+ Hook bundle files other than the root `hooks.json` are copied into
231
+ `.codex/hooks/<name>`. Managed hook handlers receive `codexmanager_meta` so
232
+ future applies can distinguish them from local hooks.
233
+
234
+ Rule refs resolve under `$CODEXMGR_HOME/rules/` and use POSIX-style relative
235
+ paths. Folder refs have a trailing slash and copy regular files recursively into
236
+ `.rules/` while preserving relative paths.
237
+
238
+ Rule listings are grouped by folder. `codexmgr rules list` prints an indented
239
+ tree, while the TUI Rules screen shows the same refs in a collapsible tree.
240
+
241
+ File rule refs copy one file. Extensionless refs prefer an existing `<ref>.md`.
242
+ Enabled refs expand first, then disabled file or folder refs remove entries from
243
+ that candidate set.
244
+
245
+ First-time rule applies refuse to overwrite unmanaged `.rules/...` files. This
246
+ keeps existing project-local rules from being replaced accidentally.
247
+
248
+ ## Packages
249
+
250
+ Packages are reusable bundles of snippets, agents, hooks, skills, and rules.
251
+ They resolve from `$CODEXMGR_HOME/packages/<name>/config.toml`.
252
+
253
+ A package config is a TOML document with root lists and optional profile tables:
254
+
255
+ ```toml
256
+ agentsmd = []
257
+ agents = ["rule-retriever"]
258
+ hooks = ["repo-rules"]
259
+ skills = ["repo-rule-manager"]
260
+ rules = ["react/"]
261
+ [profiles.strict]
262
+ agentsmd = ["strict-coding"]
263
+ agents = ["strict-agent"]
264
+ hooks = ["strict-rules"]
265
+ skills = ["strict-review"]
266
+ rules = ["python/testing.md"]
267
+ ```
268
+
269
+ The `agents` list enables custom agents from
270
+ `$CODEXMGR_HOME/agents/<name>.toml`.
271
+
272
+ `codexmgr package enable <name>` validates enabled package sources, then updates
273
+ `.codex/codexmgr.toml` as if the corresponding resource commands had been run.
274
+
275
+ `codexmgr package disable <name>` removes package `AGENTS.md` entries when
276
+ present and disables the package skills, hooks, agents, and rules. Package state
277
+ is not tracked separately; the resulting project config tables remain the
278
+ source of truth.
279
+
280
+ Profiles are merged with the root package entries:
281
+
282
+ ```bash
283
+ codexmgr package enable repo-rules --profile strict python
284
+ ```
285
+
286
+ Direct mutating commands also accept batch targets, for example:
287
+
288
+ ```bash
289
+ codexmgr agentsmd add coding python
290
+ codexmgr skill enable review-helper repo-rule-manager
291
+ codexmgr hooks enable repo-rules audit
292
+ codexmgr mcp enable browsermcp context7
293
+ ```
294
+
295
+ These commands run `apply` automatically unless `--no-sync` is passed.
296
+
297
+ ## Interactive TUI
298
+
299
+ `codexmgr tui` opens a Textual-based terminal UI for project-local
300
+ configuration. It shows `AGENTS.md` snippets, skills, hooks, custom agents,
301
+ packages, and reusable MCP sources in selectable lists. Rules are shown
302
+ in a collapsible folder tree.
303
+
304
+ Changes are staged in memory while you navigate. Press `s` to save; the save
305
+ writes `.codex/codexmgr.toml` once and runs `apply` once unless `--no-sync` was
306
+ used.
307
+
308
+ For resources with explicit enable and disable lists, `space` cycles the
309
+ highlighted row through available, enabled, and disabled states. Package
310
+ profiles appear as separate selectable rows under their package. In the Rules
311
+ tree, cycling a file or folder node updates the full canonical rule ref behind
312
+ that basename label.
313
+
314
+ ```bash
315
+ codexmgr tui
316
+ codexmgr tui --no-sync
317
+ codexmgr tui --show-diff
318
+ ```
319
+
320
+ The dashboard shows generated-file sync state. By default it lists stale
321
+ generated paths; with `--show-diff`, it shows unified diffs for the staged
322
+ configuration.
323
+
324
+ MCP editing in the TUI is intentionally limited to loading and unloading
325
+ reusable `$CODEXMGR_HOME/mcp/*.toml` sources. Advanced per-server overlay fields
326
+ remain available through the `codexmgr mcp ...` commands or direct
327
+ `.codex/codexmgr.toml` edits.
328
+
329
+ ## Template Format
330
+
331
+ Template files are TOML documents. Each top-level key must be a table and
332
+ becomes an AGENTS.md heading. A `text` value inside a table becomes the body
333
+ under that heading. Nested tables become nested headings.
334
+
335
+ ```toml
336
+ [coding]
337
+ text = "Top-level guidance."
338
+ [coding.tests]
339
+ text = "Test behavior, not implementation details."
340
+ ```
341
+
342
+ This example renders a top-level `# coding` section with a nested `## tests`
343
+ section below it.
344
+
345
+ Unsupported scalar entries fail loudly instead of being silently ignored. This
346
+ keeps template mistakes visible during `apply`.
347
+
348
+ ## Command Reference
349
+
350
+ Project lifecycle commands:
351
+
352
+ ```bash
353
+ codexmgr setup
354
+ codexmgr apply
355
+ codexmgr apply --check
356
+ codexmgr apply --diff
357
+ codexmgr doctor
358
+ codexmgr status
359
+ ```
360
+
361
+ `setup` creates `.codex/`, creates `.codex/codexmgr.toml` if missing, then runs
362
+ `apply`.
363
+
364
+ `apply` reads `.codex/codexmgr.toml`, resolves configured sources, writes
365
+ managed project files, and refreshes generated state.
366
+
367
+ `apply --check` exits with a failure if generated files are out of sync without
368
+ writing them. `apply --diff` also avoids writing and prints unified diffs for
369
+ the expected generated-file changes.
370
+
371
+ `doctor` checks project setup, home environment variables, project TOML syntax,
372
+ referenced snippets, enabled skills, enabled custom agents, enabled hook
373
+ bundles, enabled rules, and stale generated files.
374
+
375
+ `status` prints the resolved homes, configured snippets, skills, custom agents,
376
+ hooks, rules, and whether generated files are in sync.
377
+
378
+ Manager-home navigation:
379
+
380
+ ```bash
381
+ codexmgr cd
382
+ codexmgr cd --path
383
+ codexmgr cd --explorer
384
+ codexmgr cd --terminal
385
+ ```
386
+
387
+ `cd` launches a shell in `$CODEXMGR_HOME`. The flags print the path, open a file
388
+ explorer, or open a new terminal there.
389
+
390
+ AGENTS.md snippet commands:
391
+
392
+ ```bash
393
+ codexmgr agentsmd list
394
+ codexmgr agentsmd show <name-or-template-path>
395
+ codexmgr agentsmd validate <name-or-template-path>
396
+ codexmgr agentsmd add [--no-sync] <name-or-template-path> [...]
397
+ codexmgr agentsmd remove [--no-sync] <name-or-template-path> [...]
398
+ codexmgr init-template agentsmd <name>
399
+ ```
400
+
401
+ `agentsmd list` prints named templates from `$CODEXMGR_HOME/agentsmd` in sorted
402
+ order.
403
+
404
+ `agentsmd show` renders one template as `AGENTS.md` markdown without changing
405
+ project configuration. `agentsmd validate` loads and renders a template to catch
406
+ TOML or template-shape errors before adding it.
407
+
408
+ `agentsmd add` validates that the template exists before writing config.
409
+ Repeated adds keep one source entry.
410
+
411
+ `agentsmd remove` removes configured template sources and fails if a requested
412
+ source is not present.
413
+
414
+ `init-template agentsmd` creates a starter template under
415
+ `$CODEXMGR_HOME/agentsmd` and refuses to overwrite an existing template.
416
+
417
+ Shared resource commands:
418
+
419
+ ```bash
420
+ codexmgr skill list
421
+ codexmgr skill enable [--no-sync] <name-or-skill-path> [...]
422
+ codexmgr skill disable [--no-sync] <name-or-skill-path> [...]
423
+ codexmgr agents list
424
+ codexmgr agents enable [--no-sync] <agent-name> [...]
425
+ codexmgr agents disable [--no-sync] <agent-name> [...]
426
+ codexmgr hooks list
427
+ codexmgr hooks enable [--no-sync] <hook-name> [...]
428
+ codexmgr hooks disable [--no-sync] <hook-name> [...]
429
+ codexmgr rules list
430
+ codexmgr rules enable [--no-sync] <rule-ref> [...]
431
+ codexmgr rules disable [--no-sync] <rule-ref> [...]
432
+ ```
433
+
434
+ `skill list`, `agents list`, and `hooks list` print available resources and
435
+ mark configured entries as enabled, disabled, or missing. `rules list` prints
436
+ the same state in an indented folder hierarchy.
437
+
438
+ Enable commands validate manager-home sources when the source type must already
439
+ exist. Enable and disable lists stay mutually exclusive, and repeated commands
440
+ keep one entry.
441
+
442
+ Rules have one exception to exact mutual exclusion: a parent folder enable and a
443
+ child file or folder disable can intentionally coexist.
444
+
445
+ Package commands:
446
+
447
+ ```bash
448
+ codexmgr package list
449
+ codexmgr package enable [--no-sync] <package-name> [...] [--profile <name> [...]]
450
+ codexmgr package disable [--no-sync] <package-name> [...] [--profile <name> [...]]
451
+ ```
452
+
453
+ `package list` prints available `$CODEXMGR_HOME/packages/*/config.toml` entries
454
+ in sorted order.
455
+
456
+ `package enable` and `package disable` proxy to the underlying AGENTS.md,
457
+ custom-agent, skill, hook, and rule project-config mutations.
458
+
459
+ Codex wrapper command:
460
+
461
+ ```bash
462
+ codexmgr codex <args...>
463
+ ```
464
+
465
+ `codexmgr codex` applies the current project config, flattens
466
+ `.codex/config.toml` into `-c key=value` overrides, and forwards the remaining
467
+ arguments to the real `codex` command.
468
+
469
+ User-provided `-c` or `--config` overrides are merged after project config.
470
+ Scalar values replace earlier values, while list values append.
471
+
472
+ The wrapper can run with a just-in-time package/profile overlay without changing
473
+ `.codex/codexmgr.toml`. Put Codex arguments after `--` when using this syntax:
474
+
475
+ ```bash
476
+ codexmgr codex --package repo-rules --profile strict python -- exec "review this"
477
+ ```
478
+
479
+ ## Project MCP Sources
480
+
481
+ `codexmgr mcp ...` loads reusable MCP definitions from `$CODEXMGR_HOME/mcp`
482
+ into project-local configuration:
483
+
484
+ - reusable source state is stored in `.codex/codexmgr.toml` under `[mcp]`
485
+ - per-project server overlays are stored under `[mcp.servers.<id>]`
486
+ - `apply` writes generated server definitions into `.codex/config.toml` under
487
+ `[mcp_servers.<id>]`
488
+ - `$CODEX_HOME/config.toml` and `~/.codex/config.toml` are never modified
489
+
490
+ Mutating MCP commands require a project `.codex/` directory and run `apply`
491
+ automatically unless `--no-sync` is passed.
492
+
493
+ Create reusable source files in the same `mcp_servers` shape Codex reads from
494
+ `config.toml`:
495
+
496
+ ```toml
497
+ # ~/.codexmgr/mcp/browsermcp.toml
498
+ [mcp_servers.browsermcp]
499
+ command = "browsermcp"
500
+ args = ["--port", "3000"]
501
+ env_vars = ["BROWSERMCP_TOKEN"]
502
+ ```
503
+
504
+ List reusable sources and show project state:
505
+
506
+ ```bash
507
+ codexmgr mcp list
508
+ codexmgr mcp show browsermcp
509
+ codexmgr mcp validate
510
+ ```
511
+
512
+ Enable or disable reusable sources for the current project:
513
+
514
+ ```bash
515
+ codexmgr mcp enable browsermcp context7
516
+ codexmgr mcp disable browsermcp
517
+ ```
518
+
519
+ `disable` unloads the source from `[mcp].enabled`. It does not keep a generated
520
+ server definition with `enabled = false`.
521
+
522
+ Use `[mcp.servers.<id>]` for project-local overlays. Overlays merge after source
523
+ files, so they can override or add fields:
524
+
525
+ ```toml
526
+ [mcp]
527
+ enabled = ["browsermcp"]
528
+
529
+ [mcp.servers.browsermcp]
530
+ enabled = false
531
+ bearer_token_env_var = "BROWSERMCP_TOKEN"
532
+ ```
533
+
534
+ Update common token and environment references from the CLI:
535
+
536
+ ```bash
537
+ codexmgr mcp set-token-env figma FIGMA_TOKEN
538
+ codexmgr mcp add-env-var context7 CONTEXT7_TOKEN
539
+ codexmgr mcp remove-env-var context7 CONTEXT7_TOKEN
540
+ codexmgr mcp set-env-header figma Authorization FIGMA_AUTH_HEADER
541
+ codexmgr mcp unset-env-header figma Authorization
542
+ ```
543
+
544
+ Set a small allowlist of overlay fields from TOML literals:
545
+
546
+ ```bash
547
+ codexmgr mcp set-field context7 required true
548
+ codexmgr mcp set-field context7 enabled_tools '["search", "open"]'
549
+ codexmgr mcp set-field context7 default_tools_approval_mode '"prompt"'
550
+ ```
551
+
552
+ Supported `set-field` names are `required`, `startup_timeout_sec`,
553
+ `tool_timeout_sec`, `enabled_tools`, `disabled_tools`, and
554
+ `default_tools_approval_mode`.
555
+
556
+ Source files and hand-written overlays can use the full Codex `mcp_servers`
557
+ shape. Prefer environment variable references such as `bearer_token_env_var`,
558
+ `env_vars`, and `env_http_headers` for secrets.
559
+
560
+ ## Development
561
+
562
+ Use a checkout when developing `codexmgr` itself.
563
+
564
+ Install dependencies:
565
+
566
+ ```bash
567
+ uv sync --group dev
568
+ ```
569
+
570
+ Run tests:
571
+
572
+ ```bash
573
+ uv run pytest
574
+ ```
575
+
576
+ Build distributions:
577
+
578
+ ```bash
579
+ uv build
580
+ ```
581
+
582
+ The package is typed (`py.typed`) and the test suite covers CLI behavior,
583
+ template rendering, TOML writing, skill resolution, generated-file sync checks,
584
+ Codex command generation, home-directory resolution, and package metadata.