OUT-4014 | Capitalize actionLabel verb usage - #225
Conversation
App builders register `actionLabel.verb` with no casing rule enforced, so it
arrives in whatever shape the app author typed ("review", "reView", "REVIEW").
Normalize it to sentence case in `toDynamicActionDefinition`, the single funnel
for Studio app action labels into the render path.
Nouns pass through verbatim since they render mid-phrase. Pre-existing built-in
actions keep their hardcoded verbs.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| // rendered row, so normalize it to sentence case: first letter up, remainder down. | ||
| export const capitalizeVerb = (verb: string) => { | ||
| const trimmed = verb.trim() | ||
| return trimmed.charAt(0).toUpperCase() + trimmed.slice(1).toLowerCase() |
There was a problem hiding this comment.
When a Studio app registers a valid verb with meaningful internal capitalization, such as eSign, PDF, or logToCRM, lowercasing the entire suffix produces Esign, Pdf, or Logtocrm, which ActionItem displays verbatim as a misspelled action label.
| return trimmed.charAt(0).toUpperCase() + trimmed.slice(1).toLowerCase() | |
| return trimmed.charAt(0).toUpperCase() + trimmed.slice(1) |
There was a problem hiding this comment.
I think verb should not be logToCRM or eSign, it should be a valid english verb and we are enforcing it. Dont be stupid @greptile.
There was a problem hiding this comment.
Fair point — if the builder side enforces valid English verbs, then inputs like eSign or logToCRM are invalid by contract and the normalization behavior is correct as written. I'll withdraw the concern.
Greptile SummaryThis PR normalizes dynamic Studio-app action verbs before rendering.
Confidence Score: 3/5The PR should not merge until capitalization preserves meaningful internal casing in valid Studio-app action labels. The mapper accepts unrestricted nonblank verbs and now rewrites their suffix before a downstream component renders them verbatim, so labels such as "eSign" and "PDF" are displayed incorrectly. Files Needing Attention: src/features/installed-apps/lib/dynamic-action.ts Important Files Changed
Reviews (1): Last reviewed commit: "feat(OUT-4014): capitalize actionLabel v..." | Re-trigger Greptile |
OUT-4014
Changes
capitalizeVerbinsrc/features/installed-apps/lib/dynamic-action.ts— trims, uppercases the first character, lowercases the remainder.toDynamicActionDefinitionnow runs the registeredactionLabel.verbthrough it, so"review","reView", and"REVIEW"all render as"Review".tests/unit/dynamic-action.test.tscovering the casing variants and the mapper.App builders register
actionLabel.verbwith no casing rule enforced, so it arrives in whatever shape the app author typed.toDynamicActionDefinitionis the single funnel for Studio app action labels into the render path (ActionItemreadsaction.verb), so normalizing there covers both editor and preview modes and any future dynamic-row consumer.Nouns (
singularNoun/pluralNoun) pass through verbatim — they render mid-phrase ("Review 3 documents"), so capitalizing them would be wrong.Pre-existing built-in actions in
src/features/editor/components/Sidebar/Actions/constant.tsare untouched — their verbs are already hardcoded asPay/Sign/Complete/Submit.Testing Criteria
pnpm test— 8 new unit cases pass (lowercase,reView,REVIEW, already-capitalized, multi-wordsign off, surrounding whitespace, empty verb, plus the mapper end-to-end).pnpm typecheckandpnpm lintclean.actionLabel.verbis lowercase, confirm the "Your Actions" row renders the verb capitalized in both the editor sidebar preview and the client-facing view. Loom to follow.Notes
feature/studio-apps-action(same base as OUT-3980 | API: per-app unread notification counts #222), which carries the OUT-3979/3980/3981/3982 Studio-app work this depends on.reViewintoReview, but it also flattens intentional inner caps — an app registeringeSignrenders asEsign, andPDFasPdf. Dropping the.toLowerCase()would preserve author casing but leavereViewasReView. The Slack thread suggested keeping lowercase in the builder instructions and capitalizing at render time; if the builder side also constrains the field, the two rules would agree instead of the renderer guessing.Impact & Surface Area of Change
ActionItem/ActionsCard). Display-only change; nothing is persisted and no API contract changes.🤖 Generated with Claude Code