Skip to content

feat(ui): collapse slash command into inline mark#768

Merged
Astro-Han merged 13 commits into
devfrom
claude/skill-inline-mark
May 19, 2026
Merged

feat(ui): collapse slash command into inline mark#768
Astro-Han merged 13 commits into
devfrom
claude/skill-inline-mark

Conversation

@Astro-Han

@Astro-Han Astro-Han commented May 19, 2026

Copy link
Copy Markdown
Owner

Summary

Replace the thousands-of-words skill methodology that floods a chat bubble after a slash trigger (e.g. /brainstorming xxx) with a single inline mark: 16 px filled icon (visually replacing the slash) + brand-coloured command name + the user's args rendered as regular text. The bubble shell, copy / revert affordances, and user-pasted attachments are preserved. What the model receives is unchanged — only the visible layer changes.

Why

Today every /<cmd> user message pastes the full template (multi-thousand-word markdown) into the chat feed. Mainstream agent apps (Codex desktop, Claude Code CLI, Cursor's pinned skills) all fold these to a compact representation; PawWork was on the old path.

Spec (V8, locked after 7 external review passes): docs/superpowers/specs/2026-05-19-slash-command-card-design.md.
Implementation plan: docs/superpowers/specs/2026-05-19-slash-command-card-plan.md.
Visual reference (light + dark, with / without args): docs/design/scratch/slash-command-final.html.

Related Issue

Related: #762

Human Review Status

Pending

Review Focus

  • Backend metadata stamping in executeCommand (packages/opencode/src/session/prompt.ts) and marker propagation through resolvePart's two FilePart-deriving sites via the new inheritMetadata helper.
  • Title seed branch: confirm the title model only sees Command: /<name> <args>, even when the template begins with an @file or agent reference (resolvePart can shuffle parts before the title seed runs).
  • The new shared helper @opencode-ai/ui/lib/command-invocation and the bad-data degradation rule: missing / empty / non-string source / icon / args must never make the helper return null — only missing / empty / non-string name does.
  • user-message.tsx render order: command-mode renders inline mark, then attachments, then the hover meta / action row (the row has min-height: 30px and is not absolutely positioned, so it would otherwise leave a visible gap between the mark and the attachment when revealed on hover).
  • extractPromptFromParts command-mode branch preserves user-pasted attachments on Undo / Fork and drops the template-tagged file.

Risk Notes

  • No persistence / SDK / MessageV2.Part / Command.Info schema changes; metadata lives in the free-form metadata record that already exists on TextPart and FilePart.
  • Older clients that ignore metadata fall back to the original text rendering — graceful degradation.

How To Verify

bun run typecheck                              → 8/8 packages PASS
bun run lint                                   → PASS (eslint, no warnings)
bun --cwd packages/ui test command-invocation  → 8/8 PASS (helper guard + normalize + suppress lists + truncation)
bun --cwd packages/ui test command-icon        → 2/2 PASS (registry default + unknown-id fallback)
bun --cwd packages/opencode test inherit-metadata → 4/4 PASS (commandTemplate propagation + source wins + no-op + derived-fields preserve)
bun --cwd packages/opencode test command-title-seed → 5/5 PASS (first-part carrier + @file-prefixed template + null cases + no-args)
bun --cwd packages/app test prompt             → 6/6 PASS (existing attachment / AgentPart cases + 3 new command-mode cases: markerless user attachment preserved, no-args trailing space, template file suppressed)
bun --cwd packages/app run snap message-command-inline → 1/1 PASS (DPR=2 grid: no-args / with-args / long-args; suppression invariant checked)

Screenshots or Recordings

Snap output committed to docs/design/preview/screenshots/message-command-inline.png — three scenarios in one grid: no-args, with-args, long-args. Matches docs/design/scratch/slash-command-final.html 1:1 (icon replaces slash, brand-primary on the prefix, args inherit --fg-strong).

Checklist

  • Type label — this PR carries exactly one of bug, enhancement, task, documentation. Type labels are author-added; the labeler bot does NOT assign them. Add the label in the GitHub UI, then tick this.
  • Routing labels — this PR carries at least one of app, ui, platform, harness, ci. The labeler bot assigns these on PR open based on changed paths. Confirm the bot's choice (or override if wrong), then tick this.
  • Priority label — this PR carries exactly one of P0, P1, P2, P3. The priority-triage bot suggests one on PR open. Confirm or override, then tick this.
  • Human Review Status above is set to Pending, Approved by @<reviewer>, or Not required: <reason> (default is Pending; "not required" is restricted to bot-authored low-risk PRs).
  • I linked the related issue, or stated in Summary why there is no issue.
  • I described the review focus and any meaningful risks.
  • I replaced the example block in How To Verify with the real verification steps and the key result for each.
  • I did not introduce unrelated refactors, dependencies, generated files, or file changes beyond the stated scope.
  • (conditional) I manually checked visible UI or copy changes when needed, with screenshots or recordings. Leave unticked only if no visible UI or copy changed.
  • (conditional) I considered macOS and Windows impact for platform, packaging, updater, signing, paths, shell, or permissions changes. Leave unticked only if no platform/packaging surface was touched.
  • (conditional) I called out docs, release notes, dependencies, permissions, credentials, deletion behavior, generated content, or local file changes when relevant. Leave unticked only if none of those surfaces was touched.
  • I reviewed the final diff for unrelated changes and suspicious dependency changes.
  • I am targeting dev, and my PR title and commit messages use Conventional Commits in English.

Summary by CodeRabbit

  • New Features

    • Added command invocation support with inline rendering and visual styling
    • Command icons, labels, and arguments are now displayed distinctly in messages
    • Fork messages now derive preview text from command invocations
  • Improvements

    • Command metadata is properly inherited in generated content
    • Template content is suppressed from message copies
  • Tests

    • Added comprehensive test coverage for command invocation derivation and metadata inheritance
    • Added snapshot tests for inline command brainstorming render

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 19, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 4b95613f-06fa-4eb0-97e8-74b577ae039e

📥 Commits

Reviewing files that changed from the base of the PR and between 2b2b54b and 7ede416.

⛔ Files ignored due to path filters (1)
  • packages/ui/src/assets/icons/command-default.svg is excluded by !**/*.svg
📒 Files selected for processing (15)
  • packages/app/e2e/snap/message-command-inline.snap.ts
  • packages/app/src/components/dialog-fork.tsx
  • packages/app/src/utils/prompt.test.ts
  • packages/app/src/utils/prompt.ts
  • packages/opencode/src/session/inherit-metadata.ts
  • packages/opencode/src/session/prompt.ts
  • packages/opencode/test/session/command-title-seed.test.ts
  • packages/opencode/test/session/inherit-metadata.test.ts
  • packages/ui/package.json
  • packages/ui/src/components/command-icon.css
  • packages/ui/src/components/command-icon.tsx
  • packages/ui/src/components/message-part.css
  • packages/ui/src/components/message-part/user-message.tsx
  • packages/ui/src/lib/command-invocation.test.ts
  • packages/ui/src/lib/command-invocation.ts

📝 Walkthrough

Walkthrough

This PR introduces command invocation rendering to display slash-command templates as compact inline chips. It derives command metadata from message parts, preserves metadata through synthetic attachments, updates session title generation, restores prompts to command text, refactors user message rendering to show command chips, and adds comprehensive tests and e2e coverage.

Changes

Command Invocation & Rendering

Layer / File(s) Summary
Command Invocation Core Contract & Derivation
packages/ui/src/lib/command-invocation.ts, packages/ui/src/lib/command-invocation.test.ts, packages/ui/package.json
Defines CommandInvocation interface with normalized text variants (copyText, restoreText, forkPreviewText), deriveCommandInvocation() scans message parts for command metadata and builds suppression lists, type guard validates commandInvocation name field, and helpers normalize source/icon/args with defaults and truncation.
Metadata Inheritance Utility
packages/opencode/src/session/inherit-metadata.ts, packages/opencode/test/session/inherit-metadata.test.ts
New inheritMetadata() merges source metadata into derived objects while preserving commandTemplate: true, enabling metadata propagation through synthetic attachments and ensuring command-related flags survive part transformations.
Session Title Generation & Template Stamping
packages/opencode/src/session/prompt.ts, packages/opencode/test/session/command-title-seed.test.ts
Adds deriveCommandTitleSeed() to extract "Command: /<name> <args>" from first user message, updates title generation to prefer command seeds, stamps template parts with commandTemplate: true and injects commandInvocation metadata into first text part, and applies inheritMetadata() to preserve source metadata in synthetic read-tool results and data-URL attachments.
Command-Aware Prompt Extraction
packages/app/src/utils/prompt.ts, packages/app/src/utils/prompt.test.ts
Updates extractPromptFromParts() to detect command invocations via deriveCommandInvocation() and return command-restored text directly with filtered data-URL attachments, suppressing commandTemplate-marked files; otherwise falls back to prior text-part reconstruction for non-command messages.
User Message Command Display Components
packages/ui/src/components/command-icon.tsx, packages/ui/src/components/command-icon.css, packages/ui/src/components/message-part/user-message.tsx, packages/ui/src/components/message-part.css
Introduces CommandIcon component with SVG registry and inline-flex styling, refactors UserMessageDisplay to conditionally render command chips (mark/label/args in brand color) or highlighted text based on invocation presence, filters suppressed text/file part IDs, updates copy behavior to use invocation.copyText, and adds spacing/styling rules for inline command layout.
Integration & E2E Testing
packages/app/src/components/dialog-fork.tsx, packages/app/e2e/snap/message-command-inline.snap.ts
Updates DialogFork to derive invocations and use forkPreviewText for previews; adds e2e snapshot test seeding command-invocation sessions and verifying command chips render correctly across scenarios (no-args, with-args, long-args) while ensuring template body text does not leak into DOM.

Sequence Diagram

sequenceDiagram
  participant User as User Message
  participant Derive as deriveCommandInvocation
  participant Filter as Suppress Parts
  participant Render as Render UI
  participant Copy as Copy Action

  User->>Derive: message parts
  Derive-->>User: CommandInvocation object
  User->>Filter: check suppression lists
  Filter-->>User: filtered text/files
  
  User->>Render: invocation exists?
  alt Command Path
    Render->>Render: render command chip
    Render->>Render: mark + label + args
  else Text Path
    Render->>Render: render highlighted text
    Render->>Render: with attachments
  end
  
  User->>Copy: user clicks copy
  alt Using Command
    Copy->>Copy: copy invocation.copyText
  else Using Text
    Copy->>Copy: copy derived text
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

The PR spans multiple layers (core command derivation, metadata utilities, session integration, prompt extraction, and UI rendering) with mixed complexity. The command-invocation.ts core is straightforward validation/normalization logic; the session stamping involves moderate field manipulation; the UI refactor in user-message.tsx is substantial (165 lines net) with branching logic. Dense but well-tested across unit and e2e coverage.

Possibly related issues

Poem

🐰 A rabbit hops through slash commands with glee,
Command chips bloom where templates used to be,
Metadata flows through synthetic delight,
Copy and render—the UI shines bright!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: collapsing a verbose slash command template into a compact inline visual mark.
Description check ✅ Passed The description follows the template structure comprehensively, including all required sections (Summary, Why, Related Issue, Human Review Status, Review Focus, Risk Notes, How To Verify, Screenshots, and a completed Checklist).
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/skill-inline-mark

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Astro-Han Astro-Han added the enhancement New feature or request label May 19, 2026
@github-actions github-actions Bot added app Application behavior and product flows ui Design system and user interface harness Model harness, prompts, tool descriptions, and session mechanics P2 Medium priority labels May 19, 2026

@github-actions github-actions 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.

Suggested priority: P2 (includes user-path files (packages/app/src/components/dialog-fork.tsx, packages/app/src/utils/prompt.ts)).

P1/P0 are reserved for maintainer confirmation. Please relabel manually if this is a release blocker, security issue, data-loss risk, or updater/runtime failure.

@github-actions

github-actions Bot commented May 19, 2026

Copy link
Copy Markdown

Perf delta summary

Comparator: pass

Profile / Scenario interaction median interaction worst long task max tbt frame gap p95 frame gap max jank count cls status
default / homepage-cold 32 -> 32 (0) 48 -> 40 (-8) 75 -> 71 (-4) 25 -> 21 (-4) 33.4 -> 33.3 (-0.1) 133.3 -> 116.7 (-16.6) 4 -> 4 (0) 0 -> 0 (0) pass
default / long-session-input-lag 40 -> 48 (+8) 64 -> 48 (-16) 0 -> 0 (0) 0 -> 0 (0) 16.8 -> 16.7 (-0.1) 16.8 -> 16.8 (0) 0 -> 0 (0) 0 -> 0 (0) pass
default / session-streaming-long 48 -> 48 (0) 64 -> 72 (+8) 0 -> 0 (0) 0 -> 0 (0) 16.7 -> 16.7 (0) 33.4 -> 33.4 (0) 0 -> 0 (0) 0 -> 0 (0) pass
default / tool-call-expand 16 -> 16 (0) 16 -> 24 (+8) 0 -> 0 (0) 0 -> 0 (0) 16.7 -> 16.8 (+0.1) 16.7 -> 16.8 (+0.1) 0 -> 0 (0) 0 -> 0 (0) pass
default / tool-default-open-heavy-bash 24 -> 24 (0) 24 -> 24 (0) 62 -> 65 (+3) 12 -> 15 (+3) 50.1 -> 66.6 (+16.5) 100 -> 116.7 (+16.7) 4 -> 4 (0) 0 -> 0 (0) pass
default / terminal-side-panel-open 56 -> 56 (0) 56 -> 56 (0) 0 -> 0 (0) 0 -> 0 (0) 33.4 -> 33.4 (0) 33.4 -> 33.5 (+0.1) 0 -> 0 (0) 0 -> 0 (0) pass
default / session-scroll-reading 32 -> 24 (-8) 32 -> 24 (-8) 0 -> 0 (0) 0 -> 0 (0) 16.8 -> 16.8 (0) 16.8 -> 16.8 (0) 0 -> 0 (0) 0.505 -> 0.505 (0) warn: cls
low-end / session-scroll-reading-long 72 -> 64 (-8) 72 -> 64 (-8) 96 -> 93 (-3) 64 -> 55 (-9) 16.8 -> 16.8 (0) 133.3 -> 233.2 (+99.9) 3 -> 3 (0) 0.011 -> 0.011 (0) pass
low-end / session-timeline-recompute 144 -> 128 (-16) 160 -> 144 (-16) 127 -> 120 (-7) 248 -> 247 (-1) 116.6 -> 100 (-16.6) 216.7 -> 200 (-16.7) 3 -> 3 (0) 0.081 -> 0.081 (0) pass
low-end / concurrent-shimmer-extreme 0 -> 0 (0) 0 -> 0 (0) 0 -> 0 (0) 0 -> 0 (0) 16.7 -> 16.7 (0) 16.8 -> 16.8 (0) 0 -> 0 (0) 0 -> 0 (0) pass

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces a command invocation system, allowing for structured command representation within messages. It adds utilities to derive command metadata from message parts, updates the UI to render these commands with specific icons and labels, and ensures proper metadata inheritance and display logic. No review comments were provided for this pull request.

Astro-Han added 6 commits May 19, 2026 21:14
- Keep /<name> as a single nowrap token so long args don't fragment the command name across rows.
- Args use overflow-wrap: anywhere so long single-token args still wrap inside the bubble.
- Add e2e snap target (message-command-inline) covering no-args / with-args / long-args; injects commandInvocation metadata via session.prompt({ noReply: true }) to bypass the LLM round-trip.
V8 spec text wrote /<name> as the displayed label, but the visual reference
docs/design/scratch/slash-command-final.html shows the icon visually replacing
the slash — the bubble renders <icon> <name>, not <icon> /<name>.

- displayLabel: name only (used by the bubble inline mark)
- copyText / restoreText / forkPreviewText: keep /<name> (plain-text contexts
  where the slash carries re-trigger / identifier semantics)
- Move color: var(--brand-primary) from the label to the prefix flex container so both icon and label inherit it. Icon was rendering in fg-strong before because color: inherit walked past the label to the bubble text color.
- Snap target uses deviceScaleFactor: 2 to match the real mac retina render. At DPR=1 the 16px icon's internal detail (scroll curl, three lines, sparkle tips) collapses into a solid blob; DPR=2 produces 32 real pixels and the figure reads as designed.
The hover action wrapper (`user-message-copy-wrapper`) is a flex row with
`min-height: 30px`, not an absolute overlay — when a `/command` is invoked
together with a pasted user attachment, the wrapper still occupies a 30px
gap that becomes visible on hover, breaking the "inline mark first,
attachments second" layout.

Swap the render order in command mode so the mark sits directly above its
attachments, matching the no-command branch where attachments render first.
ensureTitle previously read the first text part of the user message to
decide whether to seed the title prompt with `Command: /<name> <args>`.
That works when the template body is also the first part, but resolvePart
can prepend synthetic read-text in front of an `@file` reference, and the
command stamper writes `commandInvocation` onto the first text part of
the *template* rather than the assembled message. The mismatch lets a
file-leading or agent-leading template slip past the seed and feed the
title model the expanded body instead.

Extract the seed logic into `deriveCommandTitleSeed` and scan for the
text part that actually carries `metadata.commandInvocation`, so the
title prompt stays compact regardless of part ordering. Covered by five
unit tests including a synthetic-read-text-prepended scenario.
PR description claimed `packages/app test prompt` covered command-mode
restore, but the suite only had attachment and AgentPart cases. Add three
cases that lock in the actual contract:

- `/<cmd> <args>` restores alongside a markerless user attachment (the
  template-tagged file is suppressed, the user file is preserved).
- Argless invocations restore as `/<cmd> ` with a trailing space so the
  editor caret lands ready for typing.
- A `commandTemplate=true` file with no companion user attachment yields a
  text-only restore — the template file must not leak through.
@Astro-Han Astro-Han merged commit bb7f938 into dev May 19, 2026
29 checks passed
@Astro-Han Astro-Han deleted the claude/skill-inline-mark branch May 19, 2026 14:20
Astro-Han added a commit that referenced this pull request May 20, 2026
Resolved SDK gen conflicts by regenerating from the merged OpenAPI source.
SDK now exposes:
- externalResult.list (from PR B)
- RateLimit, command-inline, draft-isolation surfaces from dev

Legacy question/blocker routes stay deleted (PR B's intent preserved).
typecheck + bun test pass on app/opencode/core/ui/sdk.
Astro-Han added a commit that referenced this pull request May 20, 2026
## Summary

Collapse `/<command> args` in the prompt input into the same inline pill (icon + brand-colored name) that PR #768 already renders in the sent bubble. Selecting from the slash popover, typing the command followed by Space, or pasting `/<known-name> args` into an empty input all materialise the leading `/<name>` into a `data-cmd-mark` element while the args remain plain text.

## Why

Fixes #778. The sent bubble shows the command name as a brand-colored pill, but until now the same text in the prompt input rendered as raw `/<name>`. Two surfaces, two visual treatments for the same concept. This PR aligns the editor side to the send-side model: a single optional `TextPart.command` field carries the metadata, content stays `/<name> <args>` end-to-end, and `metadata.commandInvocation` on the wire is unchanged.

## Related Issue

Fixes #778

## Human Review Status

Pending

## Review Focus

The marked-TextPart invariants. There is at most one per Prompt, always at index 0, and `content` always equals `/<name> <args>` with a single trailing space after the name. Most of the new code is the helpers (`command-text-part.ts`, `command-prepend.ts`, `command-space-trigger.ts`, `command-paste.ts`, `command-backspace.ts`) that enforce these invariants on the way into the store, plus the editor-side primitives (`editor-dom.ts`, `editor-serialize.ts`) that treat the pill as a unit of logical length `1 + name.length`. The contenteditable round-trip is the most fragile surface and has the largest test coverage.

Other things worth double-checking:

- ASCII-only case-insensitive matching in `command-text-part.ts:16-45`. Non-ASCII names fall back to exact byte match so caret math stays length-preserving.
- Path B trigger uses `inputType === "insertText" && data === " "`, which is naturally false on paste, Backspace, IME commit, and programmatic mutations. No flag state machine.
- Backspace ladder in `command-backspace.ts`: caret inside the prefix region of a marked TextPart degrades the pill back to plain text without dropping attachments.

## Risk Notes

- Path A (popover-select) and Path B (Space-trigger) preserve image attachments by passing `imageAttachments()` through to the new prompt, so the existing image flow is unchanged. Same for `prompt.context.items()`.
- E1 mid-prompt variant: when the popover is opened by the global trigger while the editor already has unrelated content, the marked TextPart is prepended and original parts keep both order and reference identity. No clone of incoming `FileAttachmentPart` / `AgentPart` / `ImagePart`.
- Legacy fallback boundary: the existing `text.split(" ")[0] === "/<known-name>"` codepath in `submit.ts` is kept as a safety net; the new path only fires when `part.command` metadata is present.
- Deferred follow-ups, none of which affect this PR's user-facing acceptance:
  - Homepage owner-mirror in Path A and Path C (Codex P2, narrow widening of an existing gap on Path A; new but narrow on Path C).
  - E2E snap target for the pill rendering. The unit tests at `editor-dom.test.ts` and `editor-serialize.test.ts` cover the DOM contract; a visual diff for the pill itself can be added in a small follow-up.
  - `dev:desktop` walkthrough of the IME + paste + Backspace paths on macOS/Windows. The unit and integration coverage exercises the same code paths.

## How To Verify

```text
bun --cwd packages/app test                  → 1405 pass, 0 fail
bun --cwd packages/app run typecheck         → 0 errors
gh pr diff (visual)                          → 17 commits, 1 P0 + 2 P1 from crosscheck addressed
manual: open slash popover, select brainstorming → pill renders, caret lands after the trailing space
manual: type `/brainstorming ` (with Space)  → buffer materialises into pill, popover closes
manual: Backspace just after pill            → pill collapses back to `/brainstorming ` plain text, attachments survive
manual: paste `/brainstorming hello` into empty input → pill + " hello" args
```

The 4 pre-existing icon-button test failures on `dev` (CSS 30x30 vs test expectation 24x24) are unrelated to this PR.

## Screenshots or Recordings

(To be attached by reviewer; pill visuals match PR #768 sent-bubble exactly, sharing `--brand-primary` and `--font-weight-body` via `command-pill.css`.)

## Checklist

- [ ] **Type label** — this PR carries exactly one of `bug`, `enhancement`, `task`, `documentation`. Type labels are author-added; the labeler bot does NOT assign them. Add the label in the GitHub UI, then tick this.
- [ ] **Routing labels** — this PR carries at least one of `app`, `ui`, `platform`, `harness`, `ci`. The labeler bot assigns these on PR open based on changed paths. Confirm the bot's choice (or override if wrong), then tick this.
- [ ] **Priority label** — this PR carries exactly one of `P0`, `P1`, `P2`, `P3`. The priority-triage bot suggests one on PR open. Confirm or override, then tick this.
- [x] Human Review Status above is set to `Pending`, `Approved by @<reviewer>`, or `Not required: <reason>` (default is `Pending`; "not required" is restricted to bot-authored low-risk PRs).
- [x] I linked the related issue, or stated in Summary why there is no issue.
- [x] I described the review focus and any meaningful risks.
- [x] I replaced the example block in How To Verify with the real verification steps and the key result for each.
- [x] I did not introduce unrelated refactors, dependencies, generated files, or file changes beyond the stated scope.
- [ ] **(conditional)** I manually checked visible UI or copy changes when needed, with screenshots or recordings. Leave unticked only if no visible UI or copy changed.
- [ ] **(conditional)** I considered macOS and Windows impact for platform, packaging, updater, signing, paths, shell, or permissions changes. Leave unticked only if no platform/packaging surface was touched.
- [ ] **(conditional)** I called out docs, release notes, dependencies, permissions, credentials, deletion behavior, generated content, or local file changes when relevant. Leave unticked only if none of those surfaces was touched.
- [x] I reviewed the final diff for unrelated changes and suspicious dependency changes.
- [x] I am targeting `dev`, and my PR title and commit messages use Conventional Commits in English.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **New Features**
  * Added visual command pills that display slash commands in the prompt editor with branded styling and icons.
  * Implemented copy/paste support for slash commands with proper clipboard handling and text rewriting.
  * Added keyboard interactions for command editing, including backspace handling to remove or modify command content.
  * Command icons now display with appropriate visual resolution and styling.

<!-- review_stack_entry_start -->

[![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/Astro-Han/pawwork/pull/785?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app Application behavior and product flows enhancement New feature or request harness Model harness, prompts, tool descriptions, and session mechanics P2 Medium priority ui Design system and user interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant