/ui-copy

Interface copy for every state, written against what the product actually does.

Build·Task → Words·MIT
$npx skills add tushaarmehtaa/tushar-skills --skill ui-copy -g -a claude-code -y

Then type /ui-copy in Claude Code, or describe the task and let it pick the skill.

What you get back recorded run · 9 Oct 2026

claude · tallyroom

Using /ui-copy
Every message now says what happened and what to do next.
Claude Code 2.1.295·50s·1 file changed
  • Before, any code other than the three handled ones showed no message at all, so the screen went silent. The fallback message now covers every error that isn't too-many or seats-exceeded.
  • "No invites were sent" for the seats error assumes the server rejects the whole batch.
CaveatIt did not typecheck or render the screen, since the repo has no build setup.

Measured before → after

WhereBeforeAfter
HeadingTeam ManagementInvite your team
IntroPlease enter the emails of users…We'll email each person an invite. Invites expire after 7 days, and you're only billed for a seat when someone accepts.
Inputplaceholder "Enter emails", no labelA visible "Email addresses" label, an example placeholder, and a hint: separate addresses with commas or spaces, up to 20 at a time
Seat count3 seats remaining (said "1 seats" when one was left)3 seats left on your plan / 1 seat left on your plan
ButtonSubmit / Loading...Send invites / Send 3 invites (counts as you type) / Sending invites…
SuccessSuccess!Sent 3 invites. They expire in 7 days. (`sentCount` was stored before but never shown)
Too many addressesError: Invalid input.You've entered 24 addresses. You can send up to 20 at a time, so remove some and send the rest afterward.
Not enough seatsOops! Something went wrong.Not enough seats. You're inviting 5 people, but your plan has 3 seats left. No invites were sent. Remove some addresses or add seats to your plan.
Any other failureAn error has occurred. Please try again later.Couldn't send invites. If any address isn't valid, none are sent, so check the list and try again. Your addresses are still here.
Empty stateNo data.Removed. It showed before anything was typed and told people nothing; the label and hint now cover that state.

Input → output from the run

Your error states
      {status === "error" && errorCode === "TOO_MANY" && (
        <p>Error: Invalid input.</p>
      )}
      {status === "error" && errorCode === "SEATS_EXCEEDED" && (
        <p>Oops! Something went wrong.</p>
      )}
      {status === "error" && errorCode === "UNKNOWN" && (
        <p>An error has occurred. Please try again later.</p>
      )}
After /ui-copy
      {status === "error" && errorCode === "SEATS_EXCEEDED" && (
        <p role="alert">
          Not enough seats. You're inviting {list.length}{" "}
          {list.length === 1 ? "person" : "people"}, but your plan has{" "}
          {seatsLeft === 1 ? "1 seat" : `${seatsLeft} seats`} left. No invites were sent. Remove
          some addresses or add seats to your plan.
        </p>
      )}
      {status === "error" && errorCode !== "TOO_MANY" && errorCode !== "SEATS_EXCEEDED" && (
        <p role="alert">
          Couldn't send invites. If any address isn't valid, none are sent, so check the list
          and try again. Your addresses are still here.
        </p>
      )}

When to use it

Use when

Use when buttons, forms, errors, empty states or notifications must match system behavior and voice.

Skip it when

Skip it for marketing pages (landing-copy) or to force a casual, lowercase voice onto the product.

The thinking behind it

Interface words are part of the product. Write them from what the code actually does, and users know what happens before they click.

Output contract from the skill's Output contract section

Audit

Deliver manifest coverage, prioritized findings, exact source locations, before/after repairs grounded in behavior, decisions to preserve, and states or channels that could not be inspected.

Generate or flow rewrite

Organize copy by flow and state rather than a fixed list of fields:

[Flow / screen / state]
Purpose and system behavior:
Visible copy:
Actions and destinations:
Accessible names or announcements:
Variables and localization notes:
Source/content owner:

Implement

Update the correct source of truth, preserve unrelated strings, and report files changed, migrations or message-ID changes, rendered states checked, and unverified channels.

How it checks its own work from the instructions

  • Every consequential line matches the actual action and state
  • Failure and destructive flows exercised in the running product
  • Plurals, interpolation, and long translations are tested
  • No placeholder copy or fictional proof reaches production

Requirements what it needs

Works in
Codex, Claude Code, Cursor, Claude app
Needs
files you provide

The instructions SKILL.md · 127 lines

Instructions & references

Back to overview ↑
SKILL.md · MIT

UI copy

Write interface language that tells people what state they are in, what changed, what is safe, and what they can do next. Match wording to actual product behavior and let tone vary appropriately with consequence.

Choose mode and scope

  • Audit — inventory and diagnose copy without editing unless asked.
  • Flow rewrite — repair one journey across all states and channels.
  • Generate — create a copy specification for new screens or behavior.
  • Implement — update source strings, localization resources, or content models and verify the running product.

Define in-scope surfaces, routes, flows, locales, channels, and states. For broad work, sample low-risk routine interactions and high-risk account, permission, payment, privacy, and destructive flows before expanding coverage.

Inspect the codebase and product evidence before asking questions. Recover the primary user, domain terminology, existing voice, product behavior, localization setup, content ownership, and design constraints. Ask only for unresolved product decisions or voice choices that materially alter the copy.

Read copy quality and state rules before the final writing pass or whenever errors, progress, localization, destructive actions, or voice consistency are in scope.

Build a copy manifest

Search components, route data, constants, locale files, CMS fixtures, server responses, form schemas, validation, toasts, notifications, emails, dialogs, empty states, accessible labels, and alt text.

Record each material source decision:

Surface/channel and flow:
Route/component and source location:
State and audience:
Rendered text:
Message ID, locale, variables, plural/select branches, fallback:
Actual system behavior or destination:
Claim/cause provenance when consequential:

Distinguish unique source strings from rendered instances. Exclude tests, logs, and non-user-facing examples unless the request includes documentation copy.

Model meaningful states

Use only states the product can reach, commonly including:

  • initial and first use;
  • populated;
  • filtered zero results;
  • permission-limited or unavailable;
  • loading and measurable progress;
  • validation and system error;
  • partial success or retry;
  • success and saved state;
  • disabled;
  • destructive confirmation and completion.

Do not write one generic empty state or error for semantically different conditions. State an error cause only when the system knows it. If the cause is unknown, name the failed action or object, what remains safe, and a useful recovery path.

Calibrate voice from evidence

Identify several existing lines that sound right and record formality, warmth, directness, technical density, contractions, casing, humor, and preferred domain terms. Preserve useful quirks and calibrated uncertainty.

Do not default to casual, minimal, playful, or lowercase copy. Marketing warmth should not leak into security, payment, privacy, or destructive flows. Conventional labels such as Back, Close, Done, Retry, or Continue are valid when the surrounding flow makes their consequence clear.

Write by job

Actions and confirmations

Name the action and object when consequence matters. Confirmation copy should state the object, consequence, reversibility, and any effect on collaborators or data. Button text and surrounding context work as one unit.

Errors and validation

State what failed, what remains safe, and what the user can do. Add a cause only when known and useful. Put field-specific validation beside the field and preserve entered data where the product does.

Empty and unavailable states

Distinguish first use, no matching results, no permission, deleted content, sync delay, and true absence. Explain what normally appears and offer a next step only when one exists.

Loading and progress

Describe progress only when the system can measure or truthfully identify it. Set expectations for long operations, safe navigation, cancellation, and completion notification when relevant. Skeletons and spinners are presentation choices, not substitutes for state copy.

Success and status

Show success only after confirmation. Name what changed and the next action only when users benefit from it. Avoid celebratory language for routine or sensitive events.

Onboarding and help

Guide the next useful action and reveal explanation at the point of need. Do not turn onboarding into a feature tour when the product can lead through a real first task.

Output contract

Audit

Deliver manifest coverage, prioritized findings, exact source locations, before/after repairs grounded in behavior, decisions to preserve, and states or channels that could not be inspected.

Generate or flow rewrite

Organize copy by flow and state rather than a fixed list of fields:

[Flow / screen / state]
Purpose and system behavior:
Visible copy:
Actions and destinations:
Accessible names or announcements:
Variables and localization notes:
Source/content owner:

Implement

Update the correct source of truth, preserve unrelated strings, and report files changed, migrations or message-ID changes, rendered states checked, and unverified channels.

Verify

  1. Compare every consequential line with actual action, destination, system state, and recovery behavior.
  2. Exercise representative states in the running product when feasible, including failures and destructive flows.
  3. Confirm causes, progress, success, security, privacy, and availability claims are known rather than inferred.
  4. Check terminology across navigation, forms, notifications, email, settings, documentation, and support surfaces in scope.
  5. Test interpolation, escaping, missing variables, plural/select branches, locale fallback, and pseudo-localized or long translations where available.
  6. Inspect wrapping, truncation, responsive overflow, focus order, accessible names, live announcements, and error associations.
  7. Run relevant build, typecheck, tests, and localization validation.
  8. Read key flows aloud and compare tone at routine versus high-stakes moments.
  9. Confirm placeholder copy, TODOs, and fictional proof do not reach production surfaces.
  10. Report exact coverage and limitations; do not imply a complete product audit from a partial string scan.
View on GitHub ↗
Claude app, ChatGPT and ZIP download

Claude app

This workflow can run in chat using the files and context you provide. Download its complete ZIP, then upload it from Claude's Skills settings.

ChatGPT Skills

This workflow is suitable for ChatGPT Skills. ChatGPT does not document the same upload archive format as Claude, so follow its uploader instead of reusing the Claude ZIP.

Package details
Package
ui-copy/SKILL.md
Author
@tushaarmehtaa
Added
22 Mar 2026
Tags
ui-copymicrocopyux-writingerrorsempty-statesvoice