refactor: replace hand-rolled utilities and dead code with the shared forms - #7021
Conversation
… forms Each of these has a mandated helper or an established accessor in the repo that the site predates or missed. All are behavior-preserving: - `omit()` for the three `Object.fromEntries(Object.entries(x).filter(...))` block-input filters, which also recovers the `Omit<T, K>` typing that `Object.fromEntries` erases to an index signature. - `getErrorMessage()` for the inline `instanceof Error` message ternary. - `getBlock()` for two `getAllBlocks().find((b) => b.type === x)` scans, one of them inside a loop over selected tools. The same file already resolves the same values through `getBlock`. - A memoised `Map` for three `.find()`-by-id scans over the workspace skill list, one of them inside a render `.map()`. - `SELECTOR_SEARCH_STALE` for three copy-pasted `15 * 1000` literals. They are deliberately shorter than `SELECTOR_STALE`, so this is a new named constant rather than a fold into the existing one. - Tailwind classes for the static half of two duplicated anchor styles, keeping only the genuinely dynamic `left`/`top` inline. - Dropped the unused `catch` bindings on three intentional JSON-parse swallows. `panel.tsx`'s run-button gate loses a `TODO`-stubbed `hasValidationErrors = false` and the `isWorkflowBlocked` term built on it. That term was dead twice over: it reduced to `isExecuting`, and the enclosing expression is already guarded by `!isExecuting`.
…s callers `getBlock` normalizes its argument with `type.replace(...)`, so it throws on `undefined` where the `getAllBlocks().find(...)` it replaced returned `undefined` harmlessly. Both call sites can be reached without a type: `tool-input` reads `state.blocks[blockId]?.type`, which is undefined once the block is deleted while the panel is mounted — and `Record` indexing hides that from the compiler, so it would have thrown during render. `agent-handler`'s `tool.type` is optional and the compiler did catch it. Also index the skill lookup in `resolveSkillsLabel`, which runs a `.find()` inside a `.map()` for every block on the canvas — the case the memoised map in `skill-input` addressed for one component while leaving the hot path. `providers/utils.ts` keeps its `getAllBlocks().find(...)`: it takes the registry as an injected dependency precisely so a client-reachable module never imports it, and reaching for `getBlock` there would cross that boundary. The new constant's doc claimed search-backed selectors take a shorter window. Several still sit on `SELECTOR_STALE`, so it now describes the value its three callers share rather than asserting a rule the tree does not follow.
`selectedTools` validates only `value[0]?.type` and then casts the whole array, so a persisted workflow whose later rows lost their `type` yields `undefined` here — the cast is what makes the compiler believe otherwise. `getBlock` normalizes with `type.replace`, so that throws during render.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview Skill name resolution now uses a
Reviewed by Cursor Bugbot for commit af05283. Configure here. |
Greptile SummaryThis PR consolidates equivalent utility, lookup, constant, styling, and error-handling patterns while removing dead workflow-run state.
Confidence Score: 5/5The PR appears safe to merge with no actionable correctness, security, or maintainability issues identified. The changed lookups are guarded where missing types can occur, and the remaining helper, constant, styling, indexing, catch-binding, and dead-code substitutions preserve the behavior of their replaced forms.
|
| Filename | Overview |
|---|---|
| apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tool-input/tool-input.tsx | Replaces repeated catalog scans with guarded registry lookups while preserving missing-type handling. |
| apps/sim/executor/handlers/agent/agent-handler.ts | Uses the indexed block registry when resolving input definitions for agent tool projection. |
| apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/skill-input/skill-input.tsx | Builds a memoized skill-ID index and reuses it for modal, display-name, and selected-skill resolution. |
| apps/sim/blocks/blocks/fireflies.ts | Uses the shared non-mutating omit helper to derive the v2 input definition. |
| apps/sim/blocks/blocks/grain.ts | Uses the shared omit helper when deriving Grain v2 inputs. |
| apps/sim/blocks/blocks/stt.ts | Uses the shared omit helper to remove the legacy audio URL input from the v2 definition. |
| apps/sim/executor/utils/errors.ts | Replaces local Error/string message normalization with the equivalent shared helper. |
| apps/sim/hooks/selectors/providers/shared.ts | Names and centralizes the existing 15-second stale window shared by three selectors. |
| apps/sim/lib/workflows/subblocks/display.ts | Indexes skills by ID once before resolving stored skill labels. |
| apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/panel.tsx | Removes validation placeholders that could not affect the run-button disabled expression. |
Reviews (1): Last reviewed commit: "fix: guard the second registry lookup in..." | Re-trigger Greptile
What
Sites that hand-roll something the repo already mandates, plus the dead code around them. Each was verified equivalent before changing, not pattern-matched:
Object.fromEntries(Object.entries(x).filter(...))omit()blocks/blocks/{stt,fireflies,grain}.tserror instanceof Error ? error.message : String(error)getErrorMessage()executor/utils/errors.ts:53getAllBlocks().find((b) => b.type === x)getBlock()tool-input.tsx×2,agent-handler.ts.find()-by-id in a loopMapindexskill-input.tsx×3,display.ts15 * 1000×3SELECTOR_SEARCH_STALE{jira,google,webflow}/selectors.tsstyle{plus,skills}-menu-dropdown.tsxcatch (e) {}catch {}api-handler.ts,executor/utils.ts×2omit()also recovers theOmit<T, K>typing thatObject.fromEntrieserases to a bare index signature.getAllBlocks()is not memoised — each call built a fresh 336-element array before scanning it.getBlockis an O(1) registry index.agent-handler's call ran per tool during execution;tool-input's ran inside a loop over selected tools.panel.tsxloses aTODO-stubbedconst hasValidationErrors = falseand theisWorkflowBlockedterm built on it. That term was dead twice over — it reduced toisExecuting, and the enclosing expression is already guarded by!isExecuting.Two things review caught
getBlockis not a drop-in for.find(). It normalizes viatype.replace(...), so it throws onundefinedwhere.find()returnedundefinedharmlessly. Both call sites are reachable without a type —tool-inputreadsstate.blocks[blockId]?.type, undefined once the block is deleted while the panel is mounted, andselectedToolsvalidates onlyvalue[0]?.typebefore casting the whole array.Recordindexing hid both from the compiler. All guarded now.providers/utils.ts:683deliberately keeps itsgetAllBlocks().find(...). It takes the registry as an injected dependency so a client-reachable module never imports it; reaching forgetBlockthere would cross that boundary.Testing
executor,blocks,hooks,lib/workflows/subblocks,app/workspacebun run type-checkclean;bun run check:api-validationpasses