You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
APM needs to support OpenAI's Codex CLI as a first-class integration target. Codex uses a unique multi-directory configuration model unlike any existing target: skills live under .agents/skills/ (cross-tool agent skills standard), while hooks, subagent definitions, and config live under .codex/. Instructions are read from AGENTS.md at repo root. This breaks APM's current assumption that all primitives for a target deploy under a single root_dir.
Key insight: Codex skills use the agent skills standard -- the same SKILL.md format APM already supports. This is a direct format match.
Key Architectural Decisions
Decision 1: deploy_root on PrimitiveMapping
Problem: Current TargetProfile assumes all primitives deploy under one root_dir. Codex needs .codex/ for hooks/agents but .agents/ for skills.
Decision: Add deploy_root: Optional[str] = None to PrimitiveMapping. When set, integrators use it instead of target.root_dir. Default None preserves all existing behavior (zero regression).
Rejected alternatives:
Option B (hardcode Codex paths in SkillIntegrator): creates precedent rot, defeats data-driven architecture
Option C (two target entries for .codex/ and .agents/): breaks 1:1 target-to-tool model, leaks implementation details to users
Security implication: get_integration_prefixes() must also emit prefixes from deploy_root values, so .agents/ enters the allowed prefix set.
Decision 2: Extend AgentIntegrator, not new SubagentIntegrator
Problem: Codex agents are TOML files; APM agents are Markdown.
Decision: Add _write_codex_agent() transformer to AgentIntegrator, dispatched via format_id == "codex_agent". Same pattern as Cursor rules (format_id == "cursor_rules" triggers frontmatter conversion).
Rationale: The transform is ~30 lines. One call site. Creating a new integrator class would violate "abstract when 3+ call sites" guideline.
Decision 3: Instructions via compile only, not install
Problem: Codex reads ONE AGENTS.md per directory level. Individual file deployment (like Copilot's .instructions.md) is not viable.
Decision: apm compile --target codex generates AGENTS.md. No instructions primitive in the Codex target profile during install.
Note: Install-time AGENTS.md with <!-- APM:BEGIN/END --> managed sections is a strong v2 candidate but adds merge complexity that doesn't exist in any other target.
Decision 4: Detect by .codex/ only, not .agents/
Problem: .agents/ is cross-tool (agent skills standard). Its presence doesn't mean Codex is active.
Decision: detect_by_dir=True checks .codex/ only. Consistent with all other targets (.github/ -> copilot, .claude/ -> claude, etc.).
Decision 5: Defer Starlark rules to v2
Rationale: Starlark is a new format family with no existing APM primitive mapping.
Decision 6: Flat tree output, "agents" label
Problem: Codex deploys to two roots. Should output group by root?
Decision: Flat list with full paths. No grouping by root. Use "agents" label (not "subagents") -- APM is the abstraction layer, label follows the filesystem.
Codex hooks merge into single .codex/hooks.json, following the Claude/Cursor pattern exactly. APM entries tagged with _apm_source for safe cleanup. The hooks.json file itself is NOT tracked in deployed_files (cleaned via markers); only referenced script files are tracked.
Lockfile Management
No schema changes required
LockedDependency.deployed_files is List[str] -- flat list of relative POSIX paths with no single-root constraint. A single dependency already supports files across multiple roots (confirmed by existing tests where skills deploy to both .github/skills/ and .claude/skills/).
Note: .codex/hooks.json is NOT listed -- it's a shared file cleaned via _apm_source markers (same as Claude's settings.json). Only script files referenced by hooks are tracked.
managed_files set is built from ALL existing lockfile deployed_files before install starts. Passed to every integrator. The .agents/skills/ paths are included automatically -- no changes to the collision detection pipeline.
All parallelizable once 1-deploy-root completes (it unblocks 1-target-registration and 1-security-prefixes). 1-cli-choices has no dependencies and can start immediately.
Gate: All Wave 1 items must complete before Wave 2 starts. 1-deploy-root and 1-target-registration are on the critical path.
1-deploy-root -- Add deploy_root to PrimitiveMapping
File: src/apm_cli/integration/targets.py
Add deploy_root: Optional[str] = None field to PrimitiveMapping dataclass. When deploy_root is not None, integrators use it instead of target.root_dir for path computation. Default None preserves all existing behavior (zero regression risk).
Dependencies: none
1-target-registration -- Register Codex in KNOWN_TARGETS
File: src/apm_cli/integration/targets.py
Add "codex"TargetProfile to KNOWN_TARGETS: root_dir=".codex", primitives for agents (.toml), skills (deploy_root=".agents"), hooks (.json). auto_create=False, detect_by_dir=True.
Dependencies: 1-deploy-root
1-security-prefixes -- Update security validation for .agents/ prefix
File: src/apm_cli/integration/targets.py
Update get_integration_prefixes() to also emit prefixes from deploy_root values. Ensures .agents/ is in the allowed prefix set for validate_deploy_path(). Do NOT add empty string "" as prefix (repo-root AGENTS.md needs explicit handling if added later).
Dependencies: 1-deploy-root
1-cli-choices -- Add "codex" to --target CLI option
Add "codex" to the click.Choice list for --target option across install, compile, and pack commands.
Dependencies: none
1-bucket-aliases -- Add Codex bucket aliases for partition_managed_files
File: src/apm_cli/integration/base_integrator.py
Add bucket alias entries for Codex primitives (e.g., agents_codex). Ensure partition_managed_files() handles the .agents/ root for skills correctly within the O(1) component-based path routing.
Dependencies: 1-target-registration
Wave 2: Integrator Updates
All four items are parallelizable across integrators. They fan out from 1-target-registration and converge into Wave 3.
Gate: All Wave 2 items must complete before Wave 3 starts. All four items are on the critical path.
2-agent-toml -- Add Codex TOML transformer to AgentIntegrator
File: src/apm_cli/integration/agent_integrator.py
Add _write_codex_agent() method: transforms .agent.md -> .toml. Parse agent frontmatter (name, description) and body (instructions). Emit TOML with required Codex fields: name, description, developer_instructions. Dispatch via format_id == "codex_agent" in integrate_agents_for_target(). Use tomli_w or manual TOML serialization (check existing deps).
Dependencies: 1-target-registration
2-skill-deploy-root -- Teach SkillIntegrator about deploy_root
File: src/apm_cli/integration/skill_integrator.py
Currently hardcodes target.root_dir / "skills" as deploy path. Update to use mapping.deploy_root or target.root_dir when computing skill deploy dir. For Codex: skills deploy to .agents/skills/ instead of .codex/skills/. Also update copy_skill_to_target() standalone function.
Each integrator that computes project_root / target.root_dir / mapping.subdir must use mapping.deploy_root or target.root_dir instead. Small change per integrator (~1 line each), but critical for correctness. Also update _log_integration deploy_dir computation in install.py.
Dependencies: 1-deploy-root
Wave 3: Install/Uninstall Flows + Compile + Scope
All parallelizable. Validates end-to-end data flows through the lockfile and uninstall pipeline.
Gate: All Wave 3 items must complete before Wave 4 starts.
3-lockfile-verify -- Verify lockfile with cross-root deployed_files
File: src/apm_cli/commands/install.py (verify, likely zero changes)
Confirm .agents/skills/... and .codex/agents/... paths are both recorded in the same deployed_files list via tp.relative_to(project_root).as_posix(). Confirm managed_files set includes paths from both roots for collision detection. Confirm .codex/hooks.json is NOT tracked (only script files are). Write a focused test confirming cross-root deployed_files round-trip through the lockfile.
4-uninstall-codex -- Wire Codex into uninstall sync
File: src/apm_cli/commands/uninstall/engine.py (verify + minor updates)
Codex target is automatically handled by the data-driven sync loop. Verify partition_bucket_key() returns correct keys for Codex primitives. Verify sync_for_target() works with the deploy_root override. Special attention to .agents/skills/ cleanup (different root than .codex/). Test that removing all Codex packages leaves .codex/hooks.json with only user hooks.
3-compile-codex -- Add Codex target to apm compile
File: src/apm_cli/commands/compile/cli.py
Add "codex" to compile's --target choices. Codex compilation emits AGENTS.md at repo root (same general approach as copilot target). Codex reads AGENTS.md walking from root to CWD, layering files. May need minor format adjustments vs copilot's AGENTS.md output.
Dependencies: 1-cli-choices
5-user-scope -- Add Codex to USER_SCOPE_TARGETS
File: src/apm_cli/core/scope.py
Add Codex entry to USER_SCOPE_TARGETS with appropriate support level. Codex user-scope config lives at ~/.codex/ (hooks, agents). Codex user-scope skills live at ~/.agents/skills/. Determine which primitives are supported at user scope (skills, agents likely yes; hooks maybe partial).
Dependencies: 1-target-registration
Wave 4: Unit Tests
Highly parallelizable. Each test file targets one specific integration area.
Gate: All Wave 4 tests must pass before Wave 5 starts.
6-test-target-profile -- Test Codex target registration
File: tests/unit/integration/test_targets.py
Test active_targets() with .codex/ directory present (auto-detect). Test explicit --target codex resolution. Test --target all includes Codex. Test Codex is NOT detected when only .agents/ exists (no .codex/).
Dependencies: 1-target-registration
6-test-dispatch -- Test data-driven dispatch for Codex
Add Codex to TestTargetGatingRegression (no cross-target primitive writes). Add Codex to TestExhaustivenessChecks (all primitives have handlers). Test partition_bucket_key for Codex primitives. Test that deploy_root flows correctly through dispatch.
Test _write_codex_agent() with frontmatter parsing. Test with name/description in frontmatter. Test with body-only (no frontmatter) -- extract from content. Test TOML output has required Codex fields. Test filename: .agent.md source -> .toml target.
Test merge into new .codex/hooks.json (no existing file). Test merge into existing hooks.json (preserves user hooks). Test _apm_source markers for cleanup. Test re-install replaces old APM hooks, keeps user hooks. Test script path rewriting to .codex/hooks/{package}/.
Dependencies: 2-hook-codex
6-test-skill-deploy-root -- Test skill deployment to .agents/
Test that Codex skills deploy to .agents/skills/ not .codex/skills/. Test that other targets still deploy to their own {root_dir}/skills/. Test skill uninstall cleans up .agents/skills/{name}/.
Dependencies: 2-skill-deploy-root
6-test-uninstall-codex -- Test uninstall cleanup
File: tests/unit/integration/test_sync_integration_url_normalization.py or new
Test partition_managed_files with Codex deployed files. Test sync removes Codex-specific files from correct locations. Test .codex/hooks.json cleanup removes APM entries only.
Dependencies: 4-uninstall-codex
6-test-lockfile-crossroot -- Test cross-root deployed_files lockfile round-trip
Test that deployed_files with paths from both .codex/ and .agents/ roots serialize/deserialize correctly through apm.lock.yaml. Test collision detection works across roots.
Dependencies: 3-lockfile-verify
Wave 5: Documentation + E2E
Highly parallelizable. Documentation and E2E testing can proceed independently.
Add codex to allowed target values. Document effect of target: codex.
Dependencies: none
7-docs-skills -- Update skills guide
File: docs/src/content/docs/guides/skills.md
Add .agents/skills/ as Codex deploy path. Note that Codex uses the agent skills standard natively.
Dependencies: none
7-changelog -- Update CHANGELOG.md
File: CHANGELOG.md
Add entries under [Unreleased] > Added for Codex CLI target support.
Dependencies: 1-target-registration
E2E Testing with Real Codex CLI
8-e2e-install -- E2E: Install packages with --target codex
Create a test APM package containing skills, agents, and hooks. Run apm install --target codex in a fresh project. Verify: .agents/skills/{name}/SKILL.md exists and is valid. Verify: .codex/agents/{name}.toml exists with correct TOML schema. Verify: .codex/hooks.json exists with merged hooks and _apm_source markers. Verify: apm.lock contains correct deployed_files paths from both .codex/ and .agents/ roots.
Install Codex CLI (npm install -g @openai/codex or use npx). Deploy a test skill via APM to .agents/skills/. Run codex and verify it discovers the skill (use /skills TUI command). Deploy a test agent to .codex/agents/. Verify Codex lists the custom agent. Deploy hooks to .codex/hooks.json with codex_hooks = true in config. Verify hooks are loaded (check codex logs).
Dependencies: 8-e2e-install
8-e2e-autodetect -- E2E: Auto-detection with .codex/ directory
Create .codex/config.toml (minimal valid config) in test project. Run apm install (no --target flag). Verify Codex is auto-detected in the targets list. Verify primitives deploy to correct Codex locations.
Dependencies: 8-e2e-install
8-e2e-uninstall -- E2E: Uninstall cleans up Codex files
Install a package with --target codex. Run apm uninstall {package}. Verify: .agents/skills/{name}/ is removed. Verify: .codex/agents/{name}.toml is removed. Verify: .codex/hooks.json retains user hooks, removes APM entries. Verify: apm.lock no longer references the removed files.
Dependencies: 8-e2e-install
8-e2e-compile -- E2E: Compile generates AGENTS.md for Codex
Create an apm.yml with instructions-bearing packages. Run apm compile --target codex. Verify AGENTS.md is generated at repo root. Verify content is valid Codex instruction format. Run Codex CLI and verify it reads the generated AGENTS.md.
Create project with both .github/ and .codex/ dirs. Run apm install (auto-detect both). Verify skills deploy to BOTH .github/skills/ AND .agents/skills/. Verify agents deploy to both .github/agents/*.agent.md AND .codex/agents/*.toml.
Dependencies: 8-e2e-install
Files Changed Summary
File
Change Type
Wave
src/apm_cli/integration/targets.py
Modify: deploy_root field + codex target + prefixes
Support Codex CLI as integration target
Problem Statement
APM needs to support OpenAI's Codex CLI as a first-class integration target. Codex uses a unique multi-directory configuration model unlike any existing target: skills live under
.agents/skills/(cross-tool agent skills standard), while hooks, subagent definitions, and config live under.codex/. Instructions are read fromAGENTS.mdat repo root. This breaks APM's current assumption that all primitives for a target deploy under a singleroot_dir.Research: Codex CLI Configuration Model
Sources:
.agents/skills/*/SKILL.md.codex/agents/*.tomlname,description,developer_instructions).codex/hooks.jsonSessionStart,PreToolUse,PostToolUse,UserPromptSubmit,Stop)AGENTS.mdat repo root (walked from root to CWD).codex/rules/*.rules.codex/config.toml[mcp_servers.*]Key insight: Codex skills use the agent skills standard -- the same
SKILL.mdformat APM already supports. This is a direct format match.Key Architectural Decisions
Decision 1:
deploy_rooton PrimitiveMappingProblem: Current
TargetProfileassumes all primitives deploy under oneroot_dir. Codex needs.codex/for hooks/agents but.agents/for skills.Decision: Add
deploy_root: Optional[str] = NonetoPrimitiveMapping. When set, integrators use it instead oftarget.root_dir. DefaultNonepreserves all existing behavior (zero regression).Rejected alternatives:
.codex/and.agents/): breaks 1:1 target-to-tool model, leaks implementation details to usersSecurity implication:
get_integration_prefixes()must also emit prefixes fromdeploy_rootvalues, so.agents/enters the allowed prefix set.Decision 2: Extend AgentIntegrator, not new SubagentIntegrator
Problem: Codex agents are TOML files; APM agents are Markdown.
Decision: Add
_write_codex_agent()transformer toAgentIntegrator, dispatched viaformat_id == "codex_agent". Same pattern as Cursor rules (format_id == "cursor_rules"triggers frontmatter conversion).Rationale: The transform is ~30 lines. One call site. Creating a new integrator class would violate "abstract when 3+ call sites" guideline.
Decision 3: Instructions via compile only, not install
Problem: Codex reads ONE
AGENTS.mdper directory level. Individual file deployment (like Copilot's.instructions.md) is not viable.Decision:
apm compile --target codexgeneratesAGENTS.md. No instructions primitive in the Codex target profile during install.Note: Install-time
AGENTS.mdwith<!-- APM:BEGIN/END -->managed sections is a strong v2 candidate but adds merge complexity that doesn't exist in any other target.Decision 4: Detect by
.codex/only, not.agents/Problem:
.agents/is cross-tool (agent skills standard). Its presence doesn't mean Codex is active.Decision:
detect_by_dir=Truechecks.codex/only. Consistent with all other targets (.github/-> copilot,.claude/-> claude, etc.).Decision 5: Defer Starlark rules to v2
Rationale: Starlark is a new format family with no existing APM primitive mapping.
Decision 6: Flat tree output, "agents" label
Problem: Codex deploys to two roots. Should output group by root?
Decision: Flat list with full paths. No grouping by root. Use "agents" label (not "subagents") -- APM is the abstraction layer, label follows the filesystem.
Format transformation (MD->TOML) shown as verbose-only detail:
Decision 7: Hook merge with
_apm_sourcemarkersCodex hooks merge into single
.codex/hooks.json, following the Claude/Cursor pattern exactly. APM entries tagged with_apm_sourcefor safe cleanup. The hooks.json file itself is NOT tracked indeployed_files(cleaned via markers); only referenced script files are tracked.Lockfile Management
No schema changes required
LockedDependency.deployed_filesisList[str]-- flat list of relative POSIX paths with no single-root constraint. A single dependency already supports files across multiple roots (confirmed by existing tests where skills deploy to both.github/skills/and.claude/skills/).Codex deployed_files example
Note:
.codex/hooks.jsonis NOT listed -- it's a shared file cleaned via_apm_sourcemarkers (same as Claude'ssettings.json). Only script files referenced by hooks are tracked.Path flow
Collision detection
managed_filesset is built from ALL existing lockfiledeployed_filesbefore install starts. Passed to every integrator. The.agents/skills/paths are included automatically -- no changes to the collision detection pipeline.Partition for uninstall
partition_managed_files()uses O(1)(root_dir, subdir)component lookup. Codex adds new bucket keys:agents_codex-- files under.codex/agents/skills-- files under.agents/skills/(cross-target bucket, shared with existing skill entries but routed viadeploy_root)hooks--.codex/hooks/scripts (cross-target bucket)Codex Target Registration
Key Logging Decisions (Consistency Across Targets)
Tree output pattern (all targets follow this)
Codex adds no new output primitives. Every line maps to existing logger methods.
Label follows filesystem, not tool branding
.github/instructions/instruction(s).cursor/rules/rule(s).claude/agents/agent(s).codex/agents/agent(s)(not "subagent(s)").agents/skills/skill(s).codex/hooks.jsonhook(s)Format transformation is verbose-only
Codex MD->TOML agent transform follows the Cursor precedent (Cursor silently converts
.instructions.mdto.mdcwith frontmatter rewriting):Hook merge diagnostics
No direct
_rich_*calls in integration codeAll output goes through
logger.tree_item(),logger.verbose_detail(), ordiagnostics.*(). The rendering layer (console.py) owns colors and symbols.Architecture Diagram
Execution Waves
Dependency Graph
Wave 1: Foundation
All parallelizable once
1-deploy-rootcompletes (it unblocks1-target-registrationand1-security-prefixes).1-cli-choiceshas no dependencies and can start immediately.Gate: All Wave 1 items must complete before Wave 2 starts.
1-deploy-rootand1-target-registrationare on the critical path.1-deploy-root-- Adddeploy_rootto PrimitiveMappingsrc/apm_cli/integration/targets.pydeploy_root: Optional[str] = Nonefield toPrimitiveMappingdataclass. Whendeploy_root is not None, integrators use it instead oftarget.root_dirfor path computation. DefaultNonepreserves all existing behavior (zero regression risk).1-target-registration-- Register Codex in KNOWN_TARGETSsrc/apm_cli/integration/targets.py"codex"TargetProfiletoKNOWN_TARGETS:root_dir=".codex", primitives for agents (.toml), skills (deploy_root=".agents"), hooks (.json).auto_create=False,detect_by_dir=True.1-deploy-root1-security-prefixes-- Update security validation for.agents/prefixsrc/apm_cli/integration/targets.pyget_integration_prefixes()to also emit prefixes fromdeploy_rootvalues. Ensures.agents/is in the allowed prefix set forvalidate_deploy_path(). Do NOT add empty string""as prefix (repo-root AGENTS.md needs explicit handling if added later).1-deploy-root1-cli-choices-- Add "codex" to--targetCLI optionsrc/apm_cli/commands/install.py,src/apm_cli/commands/compile/cli.py, pack commands"codex"to theclick.Choicelist for--targetoption across install, compile, and pack commands.1-bucket-aliases-- Add Codex bucket aliases forpartition_managed_filessrc/apm_cli/integration/base_integrator.pyagents_codex). Ensurepartition_managed_files()handles the.agents/root for skills correctly within the O(1) component-based path routing.1-target-registrationWave 2: Integrator Updates
All four items are parallelizable across integrators. They fan out from
1-target-registrationand converge into Wave 3.Gate: All Wave 2 items must complete before Wave 3 starts. All four items are on the critical path.
2-agent-toml-- Add Codex TOML transformer to AgentIntegratorsrc/apm_cli/integration/agent_integrator.py_write_codex_agent()method: transforms.agent.md->.toml. Parse agent frontmatter (name,description) and body (instructions). Emit TOML with required Codex fields:name,description,developer_instructions. Dispatch viaformat_id == "codex_agent"inintegrate_agents_for_target(). Usetomli_wor manual TOML serialization (check existing deps).1-target-registration2-skill-deploy-root-- Teach SkillIntegrator aboutdeploy_rootsrc/apm_cli/integration/skill_integrator.pytarget.root_dir / "skills"as deploy path. Update to usemapping.deploy_root or target.root_dirwhen computing skill deploy dir. For Codex: skills deploy to.agents/skills/instead of.codex/skills/. Also updatecopy_skill_to_target()standalone function.1-deploy-root,1-target-registration2-hook-codex-- Add Codex hook merge to HookIntegratorsrc/apm_cli/integration/hook_integrator.pyintegrate_package_hooks_codex()method following Claude/Cursor merge pattern. Merge hooks into single.codex/hooks.json(additive,_apm_sourcemarkers for safe cleanup). Map APM hook events to Codex lifecycle events (SessionStart,PreToolUse,PostToolUse,UserPromptSubmit,Stop). Script path rewriting to.codex/hooks/{package_name}/. Add dispatch inintegrate_hooks_for_target()fortarget.name == "codex".1-target-registration2-deploy-root-integrators-- Update path computation in all integratorsagent_integrator.py,command_integrator.py,instruction_integrator.py,install.pyproject_root / target.root_dir / mapping.subdirmust usemapping.deploy_root or target.root_dirinstead. Small change per integrator (~1 line each), but critical for correctness. Also update_log_integrationdeploy_dir computation ininstall.py.1-deploy-rootWave 3: Install/Uninstall Flows + Compile + Scope
All parallelizable. Validates end-to-end data flows through the lockfile and uninstall pipeline.
Gate: All Wave 3 items must complete before Wave 4 starts.
3-lockfile-verify-- Verify lockfile with cross-rootdeployed_filessrc/apm_cli/commands/install.py(verify, likely zero changes).agents/skills/...and.codex/agents/...paths are both recorded in the samedeployed_fileslist viatp.relative_to(project_root).as_posix(). Confirmmanaged_filesset includes paths from both roots for collision detection. Confirm.codex/hooks.jsonis NOT tracked (only script files are). Write a focused test confirming cross-rootdeployed_filesround-trip through the lockfile.2-agent-toml,2-deploy-root-integrators,2-hook-codex,2-skill-deploy-root4-uninstall-codex-- Wire Codex into uninstall syncsrc/apm_cli/commands/uninstall/engine.py(verify + minor updates)partition_bucket_key()returns correct keys for Codex primitives. Verifysync_for_target()works with thedeploy_rootoverride. Special attention to.agents/skills/cleanup (different root than.codex/). Test that removing all Codex packages leaves.codex/hooks.jsonwith only user hooks.1-bucket-aliases,2-deploy-root-integrators3-compile-codex-- Add Codex target toapm compilesrc/apm_cli/commands/compile/cli.py"codex"to compile's--targetchoices. Codex compilation emitsAGENTS.mdat repo root (same general approach as copilot target). Codex reads AGENTS.md walking from root to CWD, layering files. May need minor format adjustments vs copilot's AGENTS.md output.1-cli-choices5-user-scope-- Add Codex toUSER_SCOPE_TARGETSsrc/apm_cli/core/scope.pyUSER_SCOPE_TARGETSwith appropriate support level. Codex user-scope config lives at~/.codex/(hooks, agents). Codex user-scope skills live at~/.agents/skills/. Determine which primitives are supported at user scope (skills, agents likely yes; hooks maybe partial).1-target-registrationWave 4: Unit Tests
Highly parallelizable. Each test file targets one specific integration area.
Gate: All Wave 4 tests must pass before Wave 5 starts.
6-test-target-profile-- Test Codex target registrationtests/unit/integration/test_targets.pyactive_targets()with.codex/directory present (auto-detect). Test explicit--target codexresolution. Test--target allincludes Codex. Test Codex is NOT detected when only.agents/exists (no.codex/).1-target-registration6-test-dispatch-- Test data-driven dispatch for Codextests/unit/integration/test_data_driven_dispatch.pyTestTargetGatingRegression(no cross-target primitive writes). Add Codex toTestExhaustivenessChecks(all primitives have handlers). Testpartition_bucket_keyfor Codex primitives. Test thatdeploy_rootflows correctly through dispatch.1-bucket-aliases,2-deploy-root-integrators6-test-agent-toml-- Test MD-to-TOML agent transformationtests/unit/integration/test_agent_integrator.py_write_codex_agent()with frontmatter parsing. Test withname/descriptionin frontmatter. Test with body-only (no frontmatter) -- extract from content. Test TOML output has required Codex fields. Test filename:.agent.mdsource ->.tomltarget.2-agent-toml6-test-hooks-codex-- Test Codex hook mergingtests/unit/integration/test_hook_integrator.py.codex/hooks.json(no existing file). Test merge into existinghooks.json(preserves user hooks). Test_apm_sourcemarkers for cleanup. Test re-install replaces old APM hooks, keeps user hooks. Test script path rewriting to.codex/hooks/{package}/.2-hook-codex6-test-skill-deploy-root-- Test skill deployment to.agents/tests/unit/integration/test_skill_integrator.py.agents/skills/not.codex/skills/. Test that other targets still deploy to their own{root_dir}/skills/. Test skill uninstall cleans up.agents/skills/{name}/.2-skill-deploy-root6-test-uninstall-codex-- Test uninstall cleanuptests/unit/integration/test_sync_integration_url_normalization.pyor newpartition_managed_fileswith Codex deployed files. Test sync removes Codex-specific files from correct locations. Test.codex/hooks.jsoncleanup removes APM entries only.4-uninstall-codex6-test-lockfile-crossroot-- Test cross-rootdeployed_fileslockfile round-triptests/unit/integration/test_deployed_files_manifest.pydeployed_fileswith paths from both.codex/and.agents/roots serialize/deserialize correctly throughapm.lock.yaml. Test collision detection works across roots.3-lockfile-verifyWave 5: Documentation + E2E
Highly parallelizable. Documentation and E2E testing can proceed independently.
Documentation
7-docs-integration-- Add Codex integration guidedocs/src/content/docs/integrations/ide-tool-integration.md.codex/directory). Document format details (TOML agents,hooks.jsonschema). Document that instructions useapm compile --target codex.2-agent-toml,2-hook-codex,2-skill-deploy-root7-docs-cli-ref-- Update CLI referencedocs/src/content/docs/reference/cli-commands.mdcodexto--targetoption values for install, compile, pack. Update examples showing--target codex.1-cli-choices7-docs-compilation-- Update compilation guidedocs/src/content/docs/guides/compilation.md3-compile-codex7-docs-manifest-- Update manifest schema referencedocs/src/content/docs/reference/manifest-schema.mdcodexto allowedtargetvalues. Document effect oftarget: codex.7-docs-skills-- Update skills guidedocs/src/content/docs/guides/skills.md.agents/skills/as Codex deploy path. Note that Codex uses the agent skills standard natively.7-changelog-- Update CHANGELOG.mdCHANGELOG.md[Unreleased]>Addedfor Codex CLI target support.1-target-registrationE2E Testing with Real Codex CLI
8-e2e-install-- E2E: Install packages with--target codexapm install --target codexin a fresh project. Verify:.agents/skills/{name}/SKILL.mdexists and is valid. Verify:.codex/agents/{name}.tomlexists with correct TOML schema. Verify:.codex/hooks.jsonexists with merged hooks and_apm_sourcemarkers. Verify:apm.lockcontains correctdeployed_filespaths from both.codex/and.agents/roots.6-test-target-profile,6-test-agent-toml,6-test-hooks-codex,6-test-skill-deploy-root8-e2e-codex-reads-- E2E: Codex CLI discovers APM-deployed primitivesnpm install -g @openai/codexor usenpx). Deploy a test skill via APM to.agents/skills/. Runcodexand verify it discovers the skill (use/skillsTUI command). Deploy a test agent to.codex/agents/. Verify Codex lists the custom agent. Deploy hooks to.codex/hooks.jsonwithcodex_hooks = truein config. Verify hooks are loaded (check codex logs).8-e2e-install8-e2e-autodetect-- E2E: Auto-detection with.codex/directory.codex/config.toml(minimal valid config) in test project. Runapm install(no--targetflag). Verify Codex is auto-detected in the targets list. Verify primitives deploy to correct Codex locations.8-e2e-install8-e2e-uninstall-- E2E: Uninstall cleans up Codex files--target codex. Runapm uninstall {package}. Verify:.agents/skills/{name}/is removed. Verify:.codex/agents/{name}.tomlis removed. Verify:.codex/hooks.jsonretains user hooks, removes APM entries. Verify:apm.lockno longer references the removed files.8-e2e-install8-e2e-compile-- E2E: Compile generates AGENTS.md for Codexapm.ymlwith instructions-bearing packages. Runapm compile --target codex. VerifyAGENTS.mdis generated at repo root. Verify content is valid Codex instruction format. Run Codex CLI and verify it reads the generatedAGENTS.md.3-compile-codex8-e2e-multi-target-- E2E: Multi-target install (copilot + codex).github/and.codex/dirs. Runapm install(auto-detect both). Verify skills deploy to BOTH.github/skills/AND.agents/skills/. Verify agents deploy to both.github/agents/*.agent.mdAND.codex/agents/*.toml.8-e2e-installFiles Changed Summary
src/apm_cli/integration/targets.pydeploy_rootfield + codex target + prefixessrc/apm_cli/integration/base_integrator.pysrc/apm_cli/commands/install.pysrc/apm_cli/integration/agent_integrator.pysrc/apm_cli/integration/hook_integrator.pysrc/apm_cli/integration/skill_integrator.pydeploy_rootpath (~5 lines)src/apm_cli/integration/instruction_integrator.pydeploy_rootpath (~2 lines)src/apm_cli/integration/command_integrator.pydeploy_rootpath (~2 lines)src/apm_cli/commands/compile/cli.pysrc/apm_cli/commands/uninstall/engine.pysrc/apm_cli/core/scope.pyUSER_SCOPE_TARGETScodex entryCHANGELOG.mdEstimated: ~200 lines production, ~400 lines tests, 0 new classes, ~20 files.
Deferred to v2
.codex/rules/).codex/config.toml)Risk Assessment
deploy_rootregression on existing targetsNone= no behavior change; full unit suite validatesformat_idcheck, thorough testsKNOWN_TARGETSonly