5 Commits

  • [codex] Preserve skill descriptions outside model context (#29006)
    ## Why
    
    Skill descriptions are used in model-visible lists: the default
    available-skills catalog that supports implicit selection, and the
    on-demand `skills.list` tool response used to discover orchestrator
    skills. A single overlong description should not consume a
    disproportionate share of either list.
    
    Enforcing the 1024-character limit while loading or migrating skills is
    the wrong boundary: it rejects otherwise-valid skills and discards
    metadata that non-model consumers and full skill reads may need. Skill
    metadata and `SKILL.md` content should remain intact; the cap belongs at
    model-visible list rendering boundaries.
    
    ## What changed
    
    - Preserve full `description` and `metadata.short-description` values
    when loading skills.
    - Preserve full external-agent command descriptions during
    `source-command-*` migration instead of skipping commands solely because
    their descriptions exceed 1024 characters.
    - Preserve full normalized orchestrator descriptions in the underlying
    skills catalog.
    - Cap each description at 1024 Unicode characters when rendering the
    default available-skills context in `codex-core-skills` and
    `codex-skills-extension`.
    - Apply the same cap when serializing descriptions in the model-visible
    `skills.list` response.
    - Render truncated descriptions as 1021 original characters plus `...`.
    - Leave explicit `$skill` injection, `skills.read`, underlying metadata,
    and on-disk `SKILL.md` files unchanged and full-fidelity.
    
    ## Implicit skill selection
    
    Codex injects a bounded catalog containing each implicitly allowed
    skill's name, description, and source locator, together with
    instructions to use a skill when the task clearly matches its
    description. The model makes that semantic choice; after selecting a
    skill, it reads the full `SKILL.md` from its filesystem or provider
    resource. Explicit `$skill` mentions remain a separate path that injects
    the full skill instructions. For orchestrator skills, `skills.list`
    provides bounded discovery metadata before `skills.read` returns the
    full selected resource.
    
    ## Test plan
    
    - `just test -p codex-core-skills`
    - `just test -p codex-skills-extension`
    - `just test -p codex-external-agent-migration`
    
    The focused regressions verify that overlong metadata is preserved at
    load and migration boundaries while default available-skills rendering
    and `skills.list` output produce the 1021-character prefix plus `...`.
  • [codex] Record external agent import results (#28396)
    ## Summary
    - restore `externalAgentConfig/import/progress` notifications while
    keeping `externalAgentConfig/import/completed` as the must-deliver event
    - persist completed external-agent config imports in state DB by
    `importId`, including concrete success/failure details for config,
    AGENTS.md, skills, plugins, MCP servers, subagents, hooks, commands, and
    sessions
    - add `externalAgentConfig/import/readHistories` so clients can recover
    persisted import results after missing the live completion notification
    - include `errorType` on import failures in protocol
    responses/notifications and persisted DB JSON so future code can
    classify failures without another wire/storage shape change
    
    ## Validation
    - `git diff --check`
    - `just test -p codex-state external_agent_config_imports`
    - `just test -p codex-app-server-protocol`
    - `CODEX_SQLITE_HOME=/private/tmp/codex-app-server-sqlite-read-details
    just test -p codex-app-server
    external_agent_config_import_sends_completion_notification_for_sync_only_import`
    
    Also ran earlier broader checks before publishing:
    - `just test -p codex-state`
    -
    `CODEX_SQLITE_HOME=/private/tmp/codex-app-server-external-agent-test-sqlite
    just test -p codex-app-server external_agent_config`
    - `just test -p codex-external-agent-migration`
  • external-agent-migration: avoid mixed MCP transport configs (#26435)
    ## Why
    
    MCP migration could recursively merge an imported server into an
    existing same-named Codex server. When one definition used stdio and the
    other used HTTP, this produced an invalid mixed configuration containing
    both `command` and `url`.
    
    ## What changed
    
    - Merge MCP configuration at the server level instead of field by field.
    - Preserve an existing same-named Codex MCP server unchanged.
    - Report only MCP servers that would actually be added during detection.
    - Add regression coverage for mixed command/HTTP source configurations.
    - Use neutral fixture names and reserved `example.com` URLs.
    
    ## Test plan
    
    - `just test -p codex-app-server repo_mcp`
      - 5 tests passed.
    - `just test -p codex-external-agent-migration
    mcp_migration_prefers_command_transport_for_mixed_server_config`
      - 1 test passed.
  • Fix migrated hook path rewriting (#20144)
    ## Summary
    - Rewrite migrated external-agent hook commands by replacing the full
    hook script path token instead of only the `.claude/hooks/` segment.
    - Preserve quoting around the full rewritten target path so script names
    with spaces, absolute paths, and shell operators/redirection continue to
    work.
    - Apply `.claude/settings.local.json` over `.claude/settings.json` for
    config, MCP, and plugin migration so local scope matches Claude settings
    precedence.
    - Skip legacy command markdown without `description` frontmatter,
    including README-style docs under `.claude/commands`.
    
    ## Root Cause
    The previous hook rewrite handled `.claude/hooks/` as a substring
    replacement. For absolute source commands, that left the original
    project-root prefix before the newly quoted `.codex/hooks` directory,
    producing invalid commands like
    `project/'project/.codex/hooks'/script.sh`.
    
    The migration also only used project `settings.json` for
    config/MCP/plugin decisions, so local settings such as
    `disabledMcpjsonServers` could be ignored even though Claude gives local
    settings higher precedence than project settings.
    
    ## Validation
    - `just fmt`
    - `cargo test -p codex-external-agent-migration`
    - `cargo test -p codex-app-server external_agent_config`
    - `just fix -p codex-external-agent-migration`
    - `just fix -p codex-app-server`
    - `git diff --check`
  • Support detect and import MCP, Subagents, hooks, commands from external (#19949)
    ## Why
    This PR expands the migration path so Codex can detect and import MCP
    server config, hooks, commands, and subagents configs in a Codex-native
    shape.
    
    ## What changed
    
    - Added a `codex-external-agent-migration` crate that owns conversion
    logic for external-agent MCP servers, hooks, commands, and subagents.
    - Extended the app-server external-agent config detection/import API
    with migration item types for MCP server config, hooks, commands, and
    subagents.
    
    ## Migration strategy
    
    The migration is intentionally conservative: Codex only imports
    external-agent config that can be represented safely in Codex today.
    Unsupported or ambiguous config is skipped instead of being partially
    translated into behavior that may not match the source system.
    
    - **MCP servers**: import supported stdio and HTTP MCP server
    definitions into `mcp_servers`. Disabled servers and servers filtered
    out by source `enabledMcpjsonServers` / `disabledMcpjsonServers` are
    skipped. Project-scoped MCP entries from `.claude.json` are included
    when they match the repo path.
    - **Hooks**: import only supported command hooks into
    `.codex/hooks.json`. Unsupported hook features such as conditional
    groups, async handlers, prompt/http hooks, or unknown fields are
    skipped. Referenced hook scripts are copied into `.codex/hooks/`,
    preserving any existing target scripts.
    - **Commands**: import supported external commands as Codex skills under
    `.agents/skills/source-command-*`. Commands that rely on source runtime
    expansion such as `$ARGUMENTS`, `$1`, `@file` references, shell
    interpolation, or colliding generated names are skipped.
    - **Subagents**: import valid subagent Markdown files into
    `.codex/agents/*.toml` when they have the minimum Codex agent fields.
    Source model names are not migrated, so imported agents keep the user’s
    Codex default model; compatible reasoning effort and sandbox mode are
    migrated when present.
    - **Skills and project guidance**: copy missing skill directories into
    `.agents/skills` and migrate `CLAUDE.md` guidance into `AGENTS.md`,
    rewriting source-agent terminology to Codex terminology where
    appropriate.
    - **Detection details**: detected migration items include lightweight
    details for UI preview, such as MCP server names, hook event names,
    generated command skill names, and subagent names. Import still
    recomputes from disk instead of trusting details as the source of truth.
    
    - Adds focused coverage for the new migration behavior and app-server
    import flow.
    
    ## Verification
    
    - `cargo test -p codex-external-agent-migration`
    - `cargo test -p codex-hooks`
    - `cargo test -p codex-app-server external_agent_config`
    - `just bazel-lock-check`