Skip to content

fix(claude): invoke composer skills and filter unavailable commands - #118

Merged
coreybain merged 2 commits into
mainfrom
fix-skills-slash-commands
Sep 9, 2026
Merged

coreybain merged 2 commits into
mainfrom
fix-skills-slash-commands

Conversation

@coreybain

@coreybain coreybain commented Sep 9, 2026 •

Copy link
Copy Markdown
Collaborator

Claude received composer $skill picks as prose, so a selected skill could be ignored or mistaken for another one. Discovery ignored invocation restrictions and disabled skills, and provider commands appeared on later lines where they could not expand. This adapts the merged fix from t3code #9128, which closed issue #7671.

Pathway's Claude v2 adapter now translates the last recognized $skill into a final /skill text block on initial sends and live steering, preserving surrounding text, effort instructions, and attachment paths. Images precede the command block. Discovery follows Claude's directory names, user-over-project precedence, invocation flags, and settings overrides. Unavailable skills leave both picker data and the slash-command snapshot, while native /compact survives skill-name collisions. Menus request a catalog scoped to the environment, provider instance, and selected project/worktree, with no fallback to startup-project skills. Messages without a syntactically valid skill token skip filesystem discovery. Provider slash completion is limited to message start in web/desktop and both native composer entry points; local commands remain available on later lines.

Claude still directly expands only one skill per message. Earlier mentions become inline Skill-tool requests, which cannot reliably invoke user-only skills. Other provider adapters retain their existing dispatch behavior. The server handles translation for local and remote clients through the existing protocol, with optional skill metadata added to the contract.

Validation:

  • Reproduced eight regression failures against the original Pathway implementation.
  • 176 focused server tests, 7 web tests, and 1 client-runtime catalog isolation test pass, covering discovery, snapshots, dispatch, image ordering, steering, settings changes, and picker filtering.
  • Server, web, client-runtime, and contracts typechecks pass. Scoped lint, formatting, and diff checks pass.
  • Both modified native Swift files pass syntax checking. Native build/runtime and live Claude execution were not run.
  • Browser checks and screenshots omitted at the maintainer's request to use code checks only.
  • Rebased against the latest origin/main before opening.

Model: GPT-6. Harness: Codex.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Adapt pingdotgg/t3code#9128 to Pathway orchestration v2 and native composers.

Co-authored-by: Rodrigo Brechard <rodrigo@clubtidy.fr>

Co-authored-by: Theo Browne <me@t3.gg>

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Your trial has ended. Reactivate Greptile to resume code reviews.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 9, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-09T02:37:52.350060Z d5084f6 New commits
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@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: c29d73e7ab

ℹ️ 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 apps/server/src/provider/Layers/ClaudeProvider.ts Outdated
Comment thread apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
Comment thread apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts Outdated
Keep native compact available when skill names collide and skip discovery for dollar signs outside the skill-token grammar. Address the three review findings on PR #118.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Your trial has ended. Reactivate Greptile to resume code reviews.

@coreybain
coreybain merged commit 40d97a7 into main Sep 9, 2026
3 checks passed

@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


P2 Badge Stop decorating unavailable skills as valid selections

When a draft contains $deploy and the refreshed Claude catalog marks that skill disabled or userInvocable: false, the menu correctly omits it and send-time dispatch leaves it as prose, but this unfiltered array still reaches ComposerPromptEditor. Its skillMetadataByName indexes every supplied skill without checking availability, so the draft continues to show an atomic skill chip that appears runnable even though sending it cannot invoke the skill. Pass only enabled, user-invocable skills to the editor token decorator while retaining the full catalog for any separate availability UI.

AGENTS.md reference: AGENTS.md:L156-L156

ℹ️ 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 on lines +14 to +16
const slashCommands = snapshot.slashCommands.filter(
(command) => command.name === "compact" || !skillNames.has(command.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 Preserve native commands when rebuilding the catalog

When the selected workspace contains a disabled or agent-only skill named review, this name-only filter removes Claude's native /review command, and the loop below does not add anything back. Fresh evidence in apps/server/src/orchestration-v2/testkit/fixtures/thread_fork_native_fork_local_rollback/claude_transcript.ndjson:6 lists review in the SDK's slash_commands while omitting it from skills, confirming that it is native; special-casing only compact therefore leaves the earlier collision issue in place for other native commands. Preserve native-versus-skill identity instead of filtering the snapshot by the union of skill names.

Useful? React with 👍 / 👎.

Comment on lines +1158 to +1160
// Never fall back to the startup project's skills while a scoped request loads or fails.
const composerCatalog =
selectedProvider === "claudeAgent" ? scopedCatalog.data : selectedProviderStatus;

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 Keep scoped skills after the suggestion menu closes

After a user selects $deploy , the trailing space closes the skill trigger, so needsClaudeCatalog becomes false and useEnvironmentQuery(null) immediately exposes data: null; composerCatalog consequently becomes null for Claude and the editor receives an empty skill list. ComposerPromptEditor rewrites its state when that skill signature changes, turning the just-selected atomic skill chip back into plain $deploy text and also rendering any loaded Claude skill tokens without their labels until the menu is reopened. Retain the last catalog for the current environment/instance/cwd while using the trigger only to control refreshes.

Useful? React with 👍 / 👎.

Comment on lines +12 to +15
const skills = yield* discoverClaudeSkills(config, cwd ?? undefined, environment);
const skillNames = new Set([...snapshot.skills, ...skills].map((skill) => skill.name));
const slashCommands = snapshot.slashCommands.filter(
(command) => command.name === "compact" || !skillNames.has(command.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 Scope legacy Claude commands to the requested workspace

In a multi-project environment, Claude's legacy project commands under .claude/commands are included in the startup cwd's probed slashCommands, but discoverClaudeSkills only scans .claude/skills. Consequently these lines cannot identify and remove project A's legacy commands when loading project B, nor can they discover commands that exist only in B: the composer can offer an A-only command that is unknown in B while omitting B's valid commands. Rebuild project-command entries from the requested cwd or perform a cwd-scoped capability probe rather than carrying all non-skill snapshot commands forward.

Useful? React with 👍 / 👎.

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.

Composer offers skills and slash commands that cannot run

1 participant