feat(composio): format trigger slugs into human-readable labels (#1129)#1179
Conversation
- Added `formatTriggerLabel` utility to handle slug humanization. - Implemented prefix deduplication (e.g., GOOGLECALENDAR_GOOGLE_CALENDAR -> Google Calendar). - Enforced "GitHub" casing for tokens. - Updated TriggerToggles and ComposeioTriggerHistory to use the formatter. - Updated relevant tests to reflect formatted labels. Co-authored-by: oxoxDev <164490987+oxoxDev@users.noreply.github.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
✅ Files skipped from review due to trivial changes (2)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughA new utility, ChangesTrigger Label Formatting
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Review rate limit: 4/5 reviews remaining, refill in 12 minutes. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
app/src/components/composio/TriggerToggles.tsx (1)
180-204: ⚡ Quick winInclude repo context in switch
aria-labelforgithub_repoentries.When multiple repos share the same trigger slug, labels like “Enable GitHub Push Event” become indistinguishable to screen-reader users.
Proposed refactor
const sub = entry.scope === 'github_repo' ? formatTriggerLabel(entry.slug) : requiresConfig ? 'Needs configuration' : ''; + const action = enabled ? 'Disable' : 'Enable'; + const triggerName = formatTriggerLabel(entry.slug); + const ariaLabel = + entry.scope === 'github_repo' && entry.repo + ? `${action} ${triggerName} for ${entry.repo.owner}/${entry.repo.repo}` + : `${action} ${triggerName}`; ... - aria-label={`${enabled ? 'Disable' : 'Enable'} ${formatTriggerLabel(entry.slug)}`} + aria-label={ariaLabel}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/components/composio/TriggerToggles.tsx` around lines 180 - 204, The switch aria-label is ambiguous for github_repo entries; change the aria-label construction in TriggerToggles (where formatTriggerLabel(entry.slug) is used) to include repo context when entry.scope === 'github_repo' (e.g., owner/repo or the already-computed label variable) so screen readers read "Enable/Disable <trigger> for <owner/repo>" instead of just the trigger name; update the aria-label prop on the button (role="switch") to conditionally append the repo owner/repo from entry.repo for github_repo entries.app/src/lib/composio/formatters.ts (1)
16-16: ⚡ Quick winExtract the formatter options shape into an
interface.Using an inline object type here goes against the repo typing convention and makes reuse harder.
Proposed refactor
+interface FormatTriggerLabelOptions { + overrides?: Record<string, string>; +} + export function formatTriggerLabel( slug: string | null | undefined, - opts?: { overrides?: Record<string, string> } + opts?: FormatTriggerLabelOptions ): string {As per coding guidelines: "
**/*.{ts,tsx}: Preferinterfacefor defining object shapes in TypeScript".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/lib/composio/formatters.ts` at line 16, The inline object type for formatter options should be extracted into a named interface (e.g., FormatterOptions) and used instead of the inline type; change the parameter declaration from opts?: { overrides?: Record<string,string> } to opts?: FormatterOptions, define interface FormatterOptions { overrides?: Record<string,string> } near the top of app/src/lib/composio/formatters.ts, and export the interface if it will be reused elsewhere (update any references to opts, overrides, or functions/methods in this file such as the formatter function that accepts opts to use the new interface).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/src/lib/composio/formatters.test.ts`:
- Around line 39-41: The test in formatters.test.ts named that checks "handles
tokens with multiple underscores correctly" uses 'LINEAR_ISSUE_CREATED' which
only has single underscores; update the test to use a token with consecutive
underscores (e.g., include a segment like 'FOO__BAR' or
'LINEAR__ISSUE__CREATED') so formatTriggerLabel is exercised with multiple
underscores and the expected output reflects collapsed/handled spacing
accordingly; locate the test case referencing formatTriggerLabel and change the
input string and expected result to match the intended behavior.
In `@app/src/lib/composio/formatters.ts`:
- Line 19: The current check in the formatter uses truthiness on
opts.overrides[slug], which ignores explicit falsy overrides (e.g., empty
string); change the condition to test property existence instead so mapped
values are honored: locate the conditional that references
opts?.overrides?.[slug] and replace the truthy check with a key-existence check
(e.g., using Object.prototype.hasOwnProperty.call(opts.overrides, slug) or slug
in opts.overrides) and then return opts.overrides[slug] when the key exists;
ensure you reference the same variables slug and opts.overrides in the updated
condition.
- Around line 42-48: The current tokens -> map -> join pipeline can produce
extra spaces when tokens contain empty strings; update the logic in the
formatter (the tokens handling in this function in formatters.ts) to filter out
empty/falsy tokens before mapping/joining (e.g., use tokens.filter(...) or
filter the mapped results) so that repeated, leading, or trailing underscores
that produce empty tokens are removed and do not render double spaces; keep the
existing capitalization logic (the token.toUpperCase() === 'GITHUB' check and
charAt(0).toUpperCase() + slice(1).toLowerCase()) but operate only on non-empty
tokens.
---
Nitpick comments:
In `@app/src/components/composio/TriggerToggles.tsx`:
- Around line 180-204: The switch aria-label is ambiguous for github_repo
entries; change the aria-label construction in TriggerToggles (where
formatTriggerLabel(entry.slug) is used) to include repo context when entry.scope
=== 'github_repo' (e.g., owner/repo or the already-computed label variable) so
screen readers read "Enable/Disable <trigger> for <owner/repo>" instead of just
the trigger name; update the aria-label prop on the button (role="switch") to
conditionally append the repo owner/repo from entry.repo for github_repo
entries.
In `@app/src/lib/composio/formatters.ts`:
- Line 16: The inline object type for formatter options should be extracted into
a named interface (e.g., FormatterOptions) and used instead of the inline type;
change the parameter declaration from opts?: { overrides?: Record<string,string>
} to opts?: FormatterOptions, define interface FormatterOptions { overrides?:
Record<string,string> } near the top of app/src/lib/composio/formatters.ts, and
export the interface if it will be reused elsewhere (update any references to
opts, overrides, or functions/methods in this file such as the formatter
function that accepts opts to use the new interface).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: f5c66926-7bb3-4d2b-94cd-0079f82c7d0b
📒 Files selected for processing (5)
app/src/components/composio/TriggerToggles.test.tsxapp/src/components/composio/TriggerToggles.tsxapp/src/components/webhooks/ComposeioTriggerHistory.tsxapp/src/lib/composio/formatters.test.tsapp/src/lib/composio/formatters.ts
…ilter empty tokens (tinyhumansai#1129) CodeRabbit feedback: explicit empty-string overrides were being skipped by the truthy check. Switch to hasOwnProperty so mapped values are always honored. Also filter empty tokens from split() so consecutive underscores (e.g. LINEAR__ISSUE___CREATED) collapse to single spaces. Co-authored-by: oxoxDev <164490987+oxoxDev@users.noreply.github.com>
…inyhumansai#1129) CodeRabbit feedback: prior multi-underscore test only had single underscores. Replaced with LINEAR__ISSUE___CREATED. Also added a test asserting the hasOwnProperty path returns explicit empty-string overrides. Co-authored-by: oxoxDev <164490987+oxoxDev@users.noreply.github.com>
…tinyhumansai#1129) CodeRabbit feedback: when multiple repos share the same trigger slug, the plain 'Enable GitHub Push Event' label was indistinguishable to screen-reader users. Now appends 'for <owner>/<repo>' for github_repo scope. Co-authored-by: oxoxDev <164490987+oxoxDev@users.noreply.github.com>
* feat(remotion): Ghosty character library with transparent MOV variants (tinyhumansai#1059) Co-authored-by: WOZCODE <contact@withwoz.com> * feat(composio/gmail): sync into memory tree (Slack-parity) (tinyhumansai#1056) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(scheduler-gate): throttle background AI on battery / busy CPU (tinyhumansai#1062) * fix(core,cef): run core in-process and stop orphaning CEF helpers on Cmd+Q (tinyhumansai#1061) * ci: add dedicated staging release workflow (tinyhumansai#1066) * fix(sentry): Rust source context + per-release deploy marker (tinyhumansai#405) (tinyhumansai#1067) * fix(welcome): re-enable OAuth buttons with focus/timeout recovery (tinyhumansai#1049) (tinyhumansai#1069) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(dependencies): update pnpm-lock.yaml and Cargo.lock for package… (tinyhumansai#1082) * fix(onboarding): personalize welcome agent greeting with user identity (tinyhumansai#1078) * fix(chat): make agent message bubbles fit content width (tinyhumansai#1083) * Feat/dmg checks (tinyhumansai#1084) * fix(linux): Add X11 platform flags to .deb package launcher (tinyhumansai#1087) Co-authored-by: unn-Known1 <unn-known1@users.noreply.github.com> * fix(sentry): auto-send React events; collapse core→tauri for desktop (tinyhumansai#1086) Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai> * fix(cef): run blank reload guard on the CEF UI thread (tinyhumansai#1092) * fix(app): reload webview instead of restart_app in dev mode (tinyhumansai#1068) (tinyhumansai#1071) * fix(linux): deliver X11 ozone flags via custom .desktop template (tinyhumansai#1091) * fix(webview-accounts): retry data-dir purge so CEF handle race doesn't leak cookies (tinyhumansai#1076) (tinyhumansai#1081) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai> * fix(webview/slack): media perms + deep-link isolation (tinyhumansai#1074) (tinyhumansai#1080) Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai> * ci(release): split staging vs production workflows; promote staging tags (tinyhumansai#1094) * Update release-staging.yml (tinyhumansai#1097) * chore(staging): v0.53.5 * chore(staging): v0.53.6 * ci(staging): cut staging from main; add act local-debug helper (tinyhumansai#1099) * chore(staging): v0.53.7 * fix(ci): correct sentry-cli download URL and trap scope (tinyhumansai#1100) * chore(staging): v0.53.8 * feat(chat): forward thread_id to backend for KV cache locality (tinyhumansai#1095) * fix(ci): bump pinned sentry-cli to 3.4.1 (2.34.2 was never published) (tinyhumansai#1102) * chore(staging): v0.53.9 * fix(ci): drop bash trap in upload_sentry_symbols.sh; inline cleanup (tinyhumansai#1103) * chore(staging): v0.53.10 * refactor(session): flatten session_raw/, switch md to YYYY_MM_DD (tinyhumansai#1098) * Add full Composio managed-auth toolkit catalog (tinyhumansai#1093) * ci: add diff-aware 80% coverage gate (Vitest + cargo-llvm-cov) (tinyhumansai#1104) * feat(scripts): pnpm work + pnpm debug for agent-driven workflows (tinyhumansai#1105) * ci: pull pnpm into CI image, drop redundant setup steps (tinyhumansai#1107) * docs: add Cursor Cloud specific instructions to AGENTS.md (tinyhumansai#1106) Co-authored-by: Cursor Agent <cursoragent@cursor.com> * chore(staging): v0.53.11 * docs: surface 80% coverage gate and scripts/debug runners (tinyhumansai#1108) * feat(app): show Composio integrations as sorted icon grid on Skills (tinyhumansai#1109) Co-authored-by: Cursor Agent <cursoragent@cursor.com> * feat(composio): client-side trigger enable/disable toggles (tinyhumansai#1110) * feat(skills): channels grid + integrations card polish; tolerant Composio trigger decode (tinyhumansai#1112) * chore(staging): v0.53.12 * feat(home): early-bird banner + assistant→agent terminology (tinyhumansai#1113) * feat(updater): in-app auto-update with auto-download + restart prompt (tinyhumansai#677) (tinyhumansai#1114) * chore(claude): add ship-and-babysit slash command (tinyhumansai#1115) * feat(home): EarlyBirdyBanner + agent terminology + LinkedIn enrichment model pin (tinyhumansai#1118) * fix(chat): single onboarding thread in sidebar after wizard (tinyhumansai#1116) Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Steven Enamakel <senamakel@users.noreply.github.com> * fix: filter out global namespace from citation chips (tinyhumansai#1124) Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: senamakel-droid <281415773+senamakel-droid@users.noreply.github.com> * feat(nav): enable Memory tab in BottomTabBar (tinyhumansai#1125) * feat(memory): singleton ingestion + status RPC + UI pill (tinyhumansai#1126) * feat(human): mascot tab with viseme-driven lipsync (staging only) (tinyhumansai#1127) * Fix CEF zombie processes on full app close and restart (tinyhumansai#1128) Co-authored-by: senamakel-droid <281415773+senamakel-droid@users.noreply.github.com> Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai> * Update issue templates for GitHub issue types (tinyhumansai#1146) * feat(human): expand mascot expressions and tighten reply-speech state machine (tinyhumansai#1147) * feat(memory): ingestion pipeline + tree-architecture docs + ops/schemas split (tinyhumansai#1142) * feat(threads): surface live subagent work in parent thread (tinyhumansai#1122) (tinyhumansai#1159) * fix(human): keep mascot mouth animating when TTS ships no viseme data (tinyhumansai#1160) * feat(composio): consume backend markdownFormatted for LLM output (tinyhumansai#1165) * fix(subagent): lazy-register toolkit actions filtered out of fuzzy top-K (tinyhumansai#1162) * feat(memory): user-facing long-term memory window preset (tinyhumansai#1137) (tinyhumansai#1161) * fix(tauri-shell): proactively kill stale openhuman RPC on startup (tinyhumansai#1166) * chore(staging): v0.53.13 * fix(composio): per-action tool consumes backend markdownFormatted (tinyhumansai#1167) * fix(threads): persist selectedThreadId across reloads (tinyhumansai#1168) * feat(memory_tree): switch embed model to bge-m3 (1024-dim, 8K context) (tinyhumansai#1174) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(agent): drop redundant [Memory context] recall injection (tinyhumansai#1173) * chore(memory_tree): drop body-read timeouts on Ollama HTTP calls (tinyhumansai#1171) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(transcript): emit thread_id + fix orchestrator missing cost (tinyhumansai#1169) * fix(composio/gmail): phase out html2md, prefer text/plain MIME part (tinyhumansai#1170) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(tools): markdown output for internal tool results (tinyhumansai#1172) * feat(security): enforce prompt-injection guard before model and tool execution (tinyhumansai#1175) * fix(cef): popup paint dies after first frame — skip blank-page guard for popups (tinyhumansai#1079) (tinyhumansai#1182) Co-authored-by: Steven Enamakel <31011319+senamakel@users.noreply.github.com> * chore(sentry): rename OPENHUMAN_SENTRY_DSN → OPENHUMAN_CORE_SENTRY_DSN (tinyhumansai#1186) * feat(remotion): add yellow mascot character with all animation variants (tinyhumansai#1193) Co-authored-by: Neel Mistry <neelmistry@Neels-MacBook-Pro.local> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(composio): hide raw connection ID, derive friendly label (tinyhumansai#1153) (tinyhumansai#1185) Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> * fix(windows): align install.ps1 MSI with per-machine scope (tinyhumansai#913) (tinyhumansai#1187) Co-authored-by: Cursor <cursoragent@cursor.com> * fix(tauri): deterministic CEF teardown on full app close (tinyhumansai#1120) (tinyhumansai#1189) Co-authored-by: Cursor <cursoragent@cursor.com> * fix(composio): cap Gmail HTML body before strip (crash mitigation) (tinyhumansai#1191) Co-authored-by: Cursor <cursoragent@cursor.com> * fix(auth): stop stale chat threads after signup (tinyhumansai#1192) Co-authored-by: Cursor <cursoragent@cursor.com> * feat(sentry): staging-only "Trigger Sentry Test" button (tinyhumansai#1072) (tinyhumansai#1183) * chore(staging): v0.53.14 * chore(staging): v0.53.15 * feat(composio): format trigger slugs into human-readable labels (tinyhumansai#1129) (tinyhumansai#1179) Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> * fix(ui): hide unsupported permission UI on non-macOS for Screen Intelligence (tinyhumansai#1194) Co-authored-by: Cursor <cursoragent@cursor.com> * chore(tauri-shell): retire embedded Gmail webview-account flow (tinyhumansai#1181) * feat(onboarding): replace welcome-agent bot with react-joyride walkthrough (tinyhumansai#1180) * chore(release): v0.53.16 * fix(threads): preserve selectedThreadId on cold-boot identity hydration (tinyhumansai#1196) * feat(core): version/shutdown/update RPCs + mid-thread integration refresh (tinyhumansai#1195) * fix(mascot): swap to yellow mascot via @remotion/player (tinyhumansai#1200) * feat(memory_tree): cloud-default LLM, queue priority, entity filter, Memory tab UI (tinyhumansai#1198) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Persist turn state + restore conversation history on cold-boot (tinyhumansai#1202) * feat(mascot): floating desktop mascot via native NSPanel + WKWebView (macOS) (tinyhumansai#1203) * fix(memory/tree): emit summary children as Obsidian wikilinks (tinyhumansai#1210) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(tools): coding-harness baseline primitives (tinyhumansai#1205) (tinyhumansai#1208) * docs: add Codex PR checklist for remote agents --------- Co-authored-by: Steven Enamakel <31011319+senamakel@users.noreply.github.com> Co-authored-by: WOZCODE <contact@withwoz.com> Co-authored-by: sanil-23 <sanil@vezures.xyz> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Cyrus Gray <144336577+graycyrus@users.noreply.github.com> Co-authored-by: CodeGhost21 <164498022+CodeGhost21@users.noreply.github.com> Co-authored-by: oxoxDev <164490987+oxoxDev@users.noreply.github.com> Co-authored-by: Mega Mind <146339422+M3gA-Mind@users.noreply.github.com> Co-authored-by: Gaurang Patel <ptelgm.yt@gmail.com> Co-authored-by: unn-Known1 <unn-known1@users.noreply.github.com> Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Steven Enamakel <senamakel@users.noreply.github.com> Co-authored-by: Steven Enamakel's Droid <enamakel.agent@tinyhumans.ai> Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: senamakel-droid <281415773+senamakel-droid@users.noreply.github.com> Co-authored-by: YellowSnnowmann <167776381+YellowSnnowmann@users.noreply.github.com> Co-authored-by: Neil <neil@maha.xyz> Co-authored-by: Neel Mistry <neelmistry@Neels-MacBook-Pro.local> Co-authored-by: obchain <167975049+obchain@users.noreply.github.com> Co-authored-by: Jwalin Shah <jshah1331@gmail.com>
Summary
Add a shared
formatTriggerLabelutil and route every Composio trigger render through it. Stops leaking raw provider enum slugs (GOOGLECALENDAR_GOOGLE_CALENDAR_EVENT_CREATED_TRIGGER) to users.Problem
Composio trigger labels currently render as raw all-caps slugs in two surfaces:
app/src/components/composio/TriggerToggles.tsx— primary label, github sub-label, aria-label, error toast (4 sites)app/src/components/webhooks/ComposeioTriggerHistory.tsx— history badge textUsers see strings like
GOOGLECALENDAR_GOOGLE_CALENDAR_EVENT_CREATED_TRIGGERinstead ofGoogle Calendar Event Created. Looks unfinished, leaks implementation detail, hurts readability.Solution
app/src/lib/composio/formatters.tsexportingformatTriggerLabel(slug, { overrides? }):''overrides[slug]shortcuts past the heuristic for custom mappings_TRIGGERsuffix (case-insensitive)GOOGLECALENDAR_GOOGLE_CALENDAR_*→ drops the leadingGOOGLECALENDAR_because the next two tokens concatenate to it; also handlesSLACK_SLACK_*form)GITHUB→GitHubTriggerToggles.tsx(lines 125 / 180 / 183 / 201) and 1 inComposeioTriggerHistory.tsx:55app/src/lib/composio/formatters.test.tscovering provider-prefix dedup,_TRIGGERstripping, override map, empty/undefined input, GitHub casing, multi-underscore, case-insensitive_triggerTriggerToggles.test.tsxupdated to assert formatted labels in the rendered outputSubmission Checklist
formatters.test.tscovers 8 representative cases;TriggerToggles.test.tsxupdated to assert formatted outputpnpm typecheck,pnpm lint(0 errors),pnpm format:checkpnpm test:unit1282 pass / 4 skipped / 1 todocargo checkimpactImpact
User-facing trigger labels become readable across Composio toggle UI and trigger-history badge. No data-model, RPC, or backend change. Raw slug still backs all signature/enable-disable logic — zero risk of toggle regression.
Related
Closes #1129.
Co-authored by Google Jules; reviewed locally by oxoxDev (commit re-signed with GPG before force-push).
Summary by CodeRabbit
Improvements
Tests