Uh oh!
There was an error while loading. Please reload this page.
feat(swift-ios): show skill invocations as pills - #9071
Conversation
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This PR introduces substantial automatic pill rendering and attributed-text editing behavior across the iOS composer and transcript, including custom selection and undo handling. An unresolved Medium-severity issue also allows disabled skills to appear as invocation pills. Not approved because:
Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more. |
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Team Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Warning Your free Security trial is over. An organization admin can upgrade to Advanced for continuous pull request security review or dismiss this notice. Comment |
4e612e5 to
c0c69faCompareUh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
mackinleysmith
commented
Sep 2, 2026
Hey, just acknowledging the failing CI Release Smoke phase: it looks like this was preexisting and will be fixed by #9240. Whenever that merges, I will rebase against the base branch. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit ad01975. Configure here.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
70d6758 to
4ebf88bCompare| placeholder: composerPlaceholder, | ||
| acceptsImages: imagesAllowed, | ||
| isReadOnly: voiceInputController.isBusy, | ||
| skills: powerFeatures.skills, |
There was a problem hiding this comment.
🟡 MediumChat/FeatureComposerView.swift:303
Typing a disabled skill token such as $disabled renders it as an invocation pill, even though that skill cannot be selected or used. expandedComposer passes disabled entries in powerFeatures.skills to the parser, which matches by name without checking isEnabled; filter the list before passing it.
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/swift-ios/Features/Chat/FeatureComposerView.swift around line 303:
Typing a disabled skill token such as `$disabled ` renders it as an invocation pill, even though that skill cannot be selected or used. `expandedComposer` passes disabled entries in `powerFeatures.skills` to the parser, which matches by name without checking `isEnabled`; filter the list before passing it.

What Changed
The SwiftUI client now renders known
$skillinvocations as labeled pills in the composer and sent chat messages. The underlying value stays plain text, so sending, selection, copy, and cut still use the original token.Inline code, links, and unknown
$tokensremain unchanged.This is built on the caret fix in #8428. Until that PR lands, GitHub will show its small prerequisite commit in this branch too.
Why
Web and desktop already make skill invocations easy to spot. SwiftUI showed the raw token, which made the same message harder to scan and visually inconsistent across clients.
UI Changes
Verification
$file-prtext survives composer edits and message renderingChecklist
Created with GPT-5.6-Sol in T3 Code using the Codex harness.
Note
Medium Risk
Composer editing now depends on attributed-string projection and custom undo around pill sync; regressions could affect caret, undo, or what text is actually sent, though behavior is covered by new tests.
Overview
Recognized
$skilltokens from the active provider now render as labeled inline pills in the composer and chat markdown, while the bound message text and send payload stay the original plain tokens.A new inline-skill stack parses tokens, maps between plain-text and attachment display coordinates, and draws cached pill images as
NSTextAttachments. Composer input takes askillslist, continuously re-syncs attributed text (including a trailing-token rule so a pill is not committed until a following space), reports selection in plain offsets, and registers custom undo/redo that restores source text, caret, and trailing pill state. Copy/cut on pill selections writes$skilltext viaFeatureInlineSkillTextView.Thread transcript and
MarkdownMessageViewreceive provider skills so rendered messages show pills too; parsing is skipped inside code and links and respects whitespace boundaries across formatted runs.Reviewed by Cursor Bugbot for commit e64d785. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Add inline skill invocation pills to iOS composer and transcript
$skilltokens into styled inline attachment pills in FeatureInlineSkillPill.swift.$skilltext on the pasteboard instead of an attachment character.Macroscope summarized e64d785.