Repository navigation
fix(claude): invoke composer skills and filter unavailable commands - #118
Conversation
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>
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 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".
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.
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
There was a problem hiding this comment.
💡 Codex Review
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".
| const slashCommands = snapshot.slashCommands.filter( | ||
| (command) => command.name === "compact" || !skillNames.has(command.name), | ||
| ); |
There was a problem hiding this comment.
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 👍 / 👎.
| // Never fall back to the startup project's skills while a scoped request loads or fails. | ||
| const composerCatalog = | ||
| selectedProvider === "claudeAgent" ? scopedCatalog.data : selectedProviderStatus; |
There was a problem hiding this comment.
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 👍 / 👎.
| 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), |
There was a problem hiding this comment.
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 👍 / 👎.
Claude received composer
$skillpicks 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
$skillinto a final/skilltext 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:
origin/mainbefore opening.Model: GPT-6. Harness: Codex.
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.