Skip to content

Expose Codex skills as ACP slash commands#279

Closed
daniel-agentee wants to merge 1 commit into
zed-industries:mainfrom
daniel-agentee:skills-as-slash-commands
Closed

Expose Codex skills as ACP slash commands#279
daniel-agentee wants to merge 1 commit into
zed-industries:mainfrom
daniel-agentee:skills-as-slash-commands

Conversation

@daniel-agentee

@daniel-agentee daniel-agentee commented May 10, 2026

Copy link
Copy Markdown

Summary

Exposes Codex skills as ACP slash commands so clients such as Zed can surface them in the slash-command picker. Builtin commands remain first-class, and skill names that collide with builtins are skipped so /init, /compact, /logout, and review commands cannot be shadowed.

What changed

  • Adds a SkillsManager to ThreadActor and refreshes skill command metadata at session load.
  • Sends AvailableCommandsUpdate after load using the current post-refresh cache, delayed briefly so clients have finished attaching the new/loaded session.
  • Advertises all enabled skills as slash commands, including skills with policy.allow_implicit_invocation: false.
  • Treats ACP slash-command selection as explicit skill invocation by rewriting enabled skill commands from /skill to Codex's $skill form.
  • Keeps builtin commands in builtin_command_names() for collision detection.
  • Adds focused unit tests for slash rewriting, explicit-only skill visibility/routing, default skill routing, and image prompt fixture compatibility with the current Codex protocol.

Tests

cargo fmt --all -- --check
cargo test --locked --lib
cargo check --locked
cargo clippy --all-targets --all-features -- -D warnings
git diff --check

28 lib tests pass.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 05777bafd3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/thread.rs Outdated
drop(response_tx.send(result));
self.refresh_skills().await;
let client = self.client.clone();
let commands = self.available_commands();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Send command updates from current cache, not a stale snapshot

ThreadMessage::Load snapshots self.available_commands() before the 200ms delayed task runs, so if a SkillsUpdateAvailable event arrives during that window, the actor first sends the fresh command list from handle_event and then overwrites it with this older snapshot. In practice this can make newly added/removed skills disappear from the slash menu until another skills event occurs. Recompute commands at send time (or avoid the delayed stale send) so updates are monotonic.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 5c99d75.

The load path no longer computes a command snapshot and sends it later from a delayed task. After handle_load returns, the actor refreshes the skills cache and immediately emits AvailableCommandsUpdate from the current cache, so a stale pre-refresh command list cannot overwrite a newer slash menu. While rebasing onto current main/Codex rust-v0.133, I also removed the obsolete SkillsUpdateAvailable hook because that event is no longer present in the current Codex protocol, and updated image prompt test fixtures for the new detail field. Local validation is green: cargo fmt --all -- --check, cargo test --locked --lib, cargo check --locked, and cargo clippy --all-targets --all-features -- -D warnings.

@daniel-agentee

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5c99d75075

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/thread.rs Outdated
let outcome = skills_manager
.skills_for_cwd(&input, /*force_reload*/ false, /*fs*/ None)
.await;
self.cached_skills = outcome.allowed_skills_for_implicit_invocation();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include explicit-only skills in slash command cache

This cache only keeps skills allowed for implicit invocation, but slash-command selection is an explicit invocation path and Codex still supports explicit $skill use when policy.allow_implicit_invocation: false (per the Codex skills docs). In that configuration an enabled skill is omitted from the ACP command list and /name is not rewritten to $name, so users who disable implicit activation for safety lose the new slash-command access entirely; cache enabled skills separately from the implicit-invocation filter.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 6bbb49f.

The load path now derives two caches from the current SkillLoadOutcome: all enabled skills are advertised through AvailableCommandsUpdate, while only implicit-allowed skills remain eligible for the /name -> $name rewrite bridge. That keeps explicit-only skills available in the ACP slash palette without bypassing their implicit-invocation policy. I also restored the delayed notification, but it now uses commands computed after refresh_skills() so it avoids the stale pre-refresh snapshot from the previous review.

Local validation is green: cargo fmt --all -- --check, cargo test --locked --lib, cargo check --locked, cargo clippy --all-targets --all-features -- -D warnings, and git diff --check.

@daniel-agentee
daniel-agentee force-pushed the skills-as-slash-commands branch from 5c99d75 to 6bbb49f Compare June 2, 2026 10:27
@daniel-agentee

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6bbb49f292

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/thread.rs Outdated
Comment on lines +3056 to +3058
self.cached_implicit_invocation_skills
.iter()
.find(|s| s.name == name)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Route explicit-only skill commands through $

When a skill is advertised from cached_slash_command_skills but has policy.allow_implicit_invocation: false, it is intentionally absent from cached_implicit_invocation_skills, so selecting that visible ACP slash command falls through as literal /skill ... text instead of invoking the skill. Explicit-only skills still need explicit $skill invocation; otherwise every such advertised slash command is visible but non-functional for users who disable implicit matching.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 6a861ad.

You were right: ACP slash-command selection is explicit, so enabled explicit-only skills should be routed through Codex’s explicit $skill form. The cache now stores enabled skills for both slash-command visibility and /name -> $name rewriting. Disabled skills are still excluded, and builtin collisions still do not rewrite. Local validation is green: cargo fmt --all -- --check, cargo test --locked --lib, cargo check --locked, cargo clippy --all-targets --all-features -- -D warnings, and git diff --check.

@daniel-agentee
daniel-agentee force-pushed the skills-as-slash-commands branch from 6bbb49f to 6a861ad Compare June 2, 2026 10:32
@daniel-agentee

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6a861adf6e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/thread.rs Outdated
Comment on lines +3428 to +3429
let rewritten_items = if self.skill_command_match(name).is_some() {
rewrite_slash_to_skill_invocation(name, &items)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve skill path when invoking duplicate names

When two enabled skills share the same name (Codex allows multiple matching names from different roots), this rewrites the slash command to a plain $name mention. codex_core_skills::collect_explicit_skill_mentions only resolves plain $name when the name is unique, so selecting the advertised /name command in that case injects no skill at all. Route the cached SkillMetadata as a structured UserInput::Skill { name, path } (or a linked mention with the path) instead of only rewriting to $name.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 98f05da. Slash-invoked skills now rewrite to a structured UserInput::Skill { name, path } using the cached SkillMetadata instead of a plain $name text mention, so duplicate skill names preserve the matched SKILL.md path and avoid Codex’s ambiguous-name fallback. Arguments are preserved as a following text item, and non-text trailing inputs are still kept. Added a duplicate-name regression test. Validation is green: cargo fmt --all -- --check, cargo test --locked --lib, cargo check --locked, cargo clippy --all-targets --all-features -- -D warnings, and git diff --check.

@daniel-agentee
daniel-agentee force-pushed the skills-as-slash-commands branch from 6a861ad to 98f05da Compare June 2, 2026 11:13
@daniel-agentee

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 98f05dac1e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/thread.rs Outdated
Comment on lines +3027 to +3029
let input = SkillsLoadInput::new(
self.config.cwd.clone(),
Vec::new(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include plugin skill roots when loading commands

When skills come from an enabled Codex plugin, this Vec::new() means the ACP command cache only loads repo/user/system roots, so those plugin skills are not advertised as slash commands and /plugin-skill is forwarded as plain text instead of the structured UserInput::Skill. Codex turns load plugin skills via the plugin manager's effective skill roots before calling the skills manager, so sessions with plugin-provided skills can use them through Codex but cannot select them from ACP's slash-command palette.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 111c996. CodexAgent now builds SkillsLoadInput with the plugin manager’s effective plugin skill roots for the session config and passes that into ThreadActor; refresh_skills uses that input instead of constructing one with Vec::new(). That keeps plugin-provided skills in the slash-command cache while preserving the structured UserInput::Skill { name, path } routing. Validation is green: cargo fmt --all -- --check, cargo test --locked --lib, cargo check --locked, cargo clippy --all-targets --all-features -- -D warnings, and git diff --check.

@daniel-agentee
daniel-agentee force-pushed the skills-as-slash-commands branch from 98f05da to 111c996 Compare June 2, 2026 11:30
@daniel-agentee

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 111c9968bc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/thread.rs Outdated
return;
};
let outcome = skills_manager
.skills_for_cwd(input, /*force_reload*/ false, /*fs*/ None)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Load repo skills with a filesystem

In sessions rooted in a repository that defines local skills, e.g. .agents/skills/foo/SKILL.md or project-layer .codex/skills, this call never includes those skills in the ACP slash-command cache because SkillsManager only discovers repo/project skill roots when an ExecutorFileSystem is provided; with fs: None it only sees user/system/plugin roots. As a result /foo is neither advertised nor rewritten to a UserInput::Skill, even though Codex can otherwise discover the repo skill for the same cwd. Pass the local filesystem (or use the config-based loader with a filesystem) so cwd-scoped skills are included.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 4cb94d3. refresh_skills now uses the config-based skills loader with LOCAL_FS, so repo/project skill roots such as .codex/skills/.../SKILL.md are included in the slash-command cache. I added refresh_skills_loads_repo_skill_commands, which builds a temp repo-local skill and verifies /repo-helper is cached and advertised. Local validation is green: cargo fmt --all -- --check, cargo test --locked --lib (30 tests), cargo check --locked, cargo clippy --all-targets --all-features -- -D warnings, and git diff --check.

@daniel-agentee

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@daniel-agentee
daniel-agentee force-pushed the skills-as-slash-commands branch from 111c996 to 4cb94d3 Compare June 2, 2026 11:53

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4cb94d39ea

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/thread.rs
@daniel-agentee

Copy link
Copy Markdown
Author

@codex review

@daniel-agentee
daniel-agentee force-pushed the skills-as-slash-commands branch from 4cb94d3 to 1e212ef Compare June 2, 2026 14:37
@daniel-agentee

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1e212ef6af

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/thread.rs
@daniel-agentee
daniel-agentee force-pushed the skills-as-slash-commands branch from 1e212ef to 6a056a6 Compare June 3, 2026 12:43

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6a056a672a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/thread.rs
@daniel-agentee

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep it up!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@daniel-agentee
daniel-agentee force-pushed the skills-as-slash-commands branch from 6a056a6 to e4c8dbb Compare June 3, 2026 12:56
@daniel-agentee

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Nice work!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@iKonrad

iKonrad commented Jun 7, 2026

Copy link
Copy Markdown

Would be great to have this merged

Codex skills (loaded via SkillsManager) are now advertised to ACP clients
alongside the existing builtin slash commands. Selecting a skill rewrites
the leading "/name ..." text into Codex's implicit-skill form ("$name ...")
before submission, so invocation goes through the same implicit-skill path
the TUI uses when a user types `$` and picks a skill from the popup.

The cache is refreshed at session load and whenever Codex emits
EventMsg::SkillsUpdateAvailable; the latter is intercepted at the
ThreadActor level (not per-submission) and triggers a session-wide
AvailableCommandsUpdate. Skill names that collide with a builtin
(/init, /compact, /review, etc.) are dropped with a warning so a skill
cannot shadow a builtin.

Plugin-supplied skill roots are not yet threaded through — only
user/project/system skills appear today. Following PR can wire the
plugin outcome through to fully match the TUI's coverage.

References zed-industries#190.
@daniel-agentee
daniel-agentee force-pushed the skills-as-slash-commands branch from e4c8dbb to 7782e75 Compare June 9, 2026 06:50
@daniel-agentee

Copy link
Copy Markdown
Author

Rebased this onto current origin/main to clear the merge conflict.

Validation after the rebase:

  • cargo check --locked
  • cargo fmt --all -- --check
  • git diff --check
  • cargo test --locked --lib (34 passed)

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@iKonrad

iKonrad commented Jun 22, 2026

Copy link
Copy Markdown

What's the status of this?

@benbrandt

Copy link
Copy Markdown
Member

Hi thanks for taking the time to dig in!
Development is moving to agentclientprotocol/codex-acp. The new adapter is built on the new Codex App Server, and we are pooling implementation and maintenance work across teams there. If this is still needed, please open a PR for that one. Thanks!

@benbrandt benbrandt closed this Jun 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants