improvement(platform): drop lucide-react for the in-house icon set, flatten the type and border scales, and retire scheduled tasks and workflow references - #6241
Conversation
…ght scale, and retire scheduled tasks and workflow references
… rule and skill docs Follow-up cleanup for the platform commit, which removed the workspace scheduled-tasks surface and migrated off lucide-react. Both left dead tails that type-check clean, so nothing flagged them. Six mutation hooks in hooks/queries/schedules.ts lost their only consumer when the scheduled-tasks page was deleted: useDisableSchedule, useResumeSchedule, useDeleteSchedule, useExcludeOccurrence, useUpdateSchedule, useCreateSchedule. They are removed along with the three contract objects that served only them — disableScheduleContract, excludeOccurrenceContract, deleteScheduleContract. disableScheduleBodySchema and excludeOccurrenceBodySchema are deliberately kept: both are members of scheduleUpdateSchema, the discriminated union the live PUT /api/schedules/[id] route parses. Dropping them would collapse the union and 400 the disable and exclude_occurrence actions. The schedule-calendar tree and its utils stay unmounted for later reuse. Its TSDoc now says so, since it has no importer and would otherwise read as dead code on the next sweep. The add-enrichment skill templated an import from lucide-react, a dependency the platform commit deleted, so running it produced an unresolvable import. It now points at @sim/emcn/icons, matching all five shipped enrichments. The emcn-design-review skill and several rule files still pointed at apps/sim/components/emcn/**, which moved to packages/emcn/**. Also corrects the documented Chip variant list — it advertised a ghost variant that never existed and omitted border — repoints the sim-url-state date-parser example at an inline snippet now that its source file is gone, and normalizes the one strokeWidth the icon migration left at 1.5 in bubble-chat-delay.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
PR SummaryHigh Risk Overview Design system: font weight collapses to Tailwind 400/500/600 (custom Scheduled tasks (product surface): workspace route, landing Scheduled Tasks page/hero loop, nav/footer links, and standalone Also removed: workflow references API ( Misc: sidebar expanded width 248→238; Reviewed by Cursor Bugbot for commit 1d4f4a0. Configure here. |
Resolved 47 conflicts, keeping staging's semantics and this branch's platform migration on top of them. - scheduled tasks: kept this branch's removal of the page, modals, hooks and search-params; kept schedule-calendar/ and utils/ for the agents module. Dropped staging's new task-modal/secret-access-section.tsx. - accepted staging's deletion of the deployed-chat voice mode and the knowledge base-card. - took staging's rewrites of chat input/message, the sidebar file list and the sidebar Chats section, then re-applied the icon and token migration on top (emcn icons, no strokeWidth, no font-base). - carried staging's NEXT_PUBLIC_CHAT_DISABLED gate onto the branch's SidebarSection-based Chats section. - migrated the five Globe imports staging added to @sim/emcn/icons, since lucide-react is no longer a dependency. - retargeted document-table.css off the retired --divider token onto --border-width/--border, and updated the test that guards it. - dropped `flush` from the chip call sites staging added; this branch removed the chip cluster margin the prop existed to cancel.
`skills/page.tsx` is a Server Component, and this branch moved its `IntegrationTabsHeader` import onto the `@/app/workspace/[workspaceId]/components` barrel. That barrel re-exports `SortDropdown` from `resource-options`, which calls `useState`, so the server graph now reaches a client-only module and `next build` fails. `resource-header` has the same latent problem (`useState`, `useEffect`, `useRef`). Both files are genuinely client components, so they get the directive rather than the page dropping the barrel import — local feature barrels are the convention here. Also drops a stale `lucide-react` mention now that the dependency is gone.
Scheduled tasks are retired. This removes the `sourceType = 'job'` half of `workflow_schedule` from the application, leaving the workflow Schedule trigger (`sourceType = 'workflow'`) untouched. Gone: - the job orchestration layer (`lib/workflows/schedules/orchestration.ts`) and the agent-job runner in `background/schedule-execution.ts` - the job claim/dispatch half of the schedules execute tick - POST /api/schedules (job creation) and the job branches of GET /api/schedules and PUT/DELETE /api/schedules/[id] - the copilot job tools and handlers, the `scheduledtask` resource type and chat-context kind, and the VFS `jobs/` materialization - the scheduled-task analytics events and the job variant of the schedule-disabled email Kept on purpose: `scheduled-tasks/components/schedule-calendar/**` and `scheduled-tasks/utils/**`, which the agents module will reuse. `packages/db/schema.ts` is deliberately untouched — the columns stay for now and come out in a follow-up with a proper expand/contract migration. The generated copilot catalog and VFS snapshot types are regenerated from the matching copilot PR, which removes the tools and the `jobs` snapshot field at the source. Verified: 23/23 type-check, biome, api-validation, production build, and the full vitest suite (18361 passing; the one failure in executor/handlers/pi/cloud-review-tools.test.ts predates this branch).
|
| GitGuardian id | GitGuardian status | Secret | Commit | Filename | |
|---|---|---|---|---|---|
| 35640005 | Triggered | Generic Password | 0b7e8d2 | apps/desktop/src/main/browser-import/import-service.test.ts | View secret |
🛠 Guidelines to remediate hardcoded secrets
- Understand the implications of revoking this secret by investigating where it is used in your code.
- Replace and store your secret safely. Learn here the best practices.
- Revoke and rotate this secret.
- If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.
To avoid such incidents in the future consider
- following these best practices for managing and storing secrets including API keys and other credentials
- install secret detection on pre-commit to catch secret before it leaves your machine and ease remediation.
🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.
Picks up the Next 16.2.12 revert (#6242). The earlier merge had taken staging's 16.3.0; this takes the revert in apps/docs, apps/sim and packages/emcn and regenerates the lockfile. lucide-react stays removed.
This branch moved `SIDEBAR_WIDTH.DEFAULT` from 248 to 238 but left two hardcoded `248px` chrome widths behind, so both sat 10px wider than the live sidebar: - the workspace-switcher menu, which is meant to line up with the sidebar column it drops out of - the standalone settings sidebar, whose own comment says to keep it in step with the in-workspace chrome Both now read `SIDEBAR_WIDTH.DEFAULT` directly rather than repeating the number, so the next change to the constant cannot leave them stale again.
|
@cursor review |
GitGuardian finding is a merge artifact — no code change neededGitGuardian flags incident 35640005 ("Generic Password") at The flagged line is a test fixture: expect(importCredentials).toHaveBeenCalledWith(
[expect.objectContaining({ password: 'new-local' })],
'replace'
)Three things confirm it is not introduced here:
It surfaced because a merge commit re-presents the merged-in branch's content as added lines, so the scanner re-scanned code that already lives on staging and passes there. GitGuardian passed on this PR's pre-merge head ( Nothing to rotate and nothing to change in code — this needs someone with GitGuardian dashboard access to mark the occurrence as a false positive so the check goes green. |
Greptile SummaryThis PR replaces Lucide with the in-house icon library, standardizes typography and border tokens, and retires the scheduled-task and workflow-reference surfaces.
Confidence Score: 5/5The PR appears safe to merge because no blocking failure remains within the available follow-up review scope. No blocking failure remains.
|
| Filename | Overview |
|---|---|
| packages/emcn/src/icons/index.ts | Expands and normalizes the public icon barrel used throughout the repository. |
| packages/emcn/src/index.ts | Explicitly preserves component exports for Calendar, Code, and Table while exposing icons. |
| apps/sim/app/_styles/globals.css | Flattens font-weight tokens and retunes neutral text, shadow, and border styling. |
| apps/sim/app/api/schedules/execute/route.ts | Retains the workflow-schedule cron claiming, queueing, fallback, and recovery path while scheduled-task functionality is retired. |
| apps/sim/background/schedule-execution.ts | Retains background execution and next-run advancement for workflow schedules. |
| apps/sim/lib/copilot/generated/tool-catalog-v1.ts | Removes retired scheduled-task tools from the generated Copilot catalog. |
| apps/sim/app/workspace/[workspaceId]/w/components/sidebar/sidebar.tsx | Reorganizes workspace sidebar composition and removes retired scheduled-task and reference entry points. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
Lucide[lucide-react consumers] --> Icons["@sim/emcn/icons"]
Icons --> Sim[apps/sim]
Icons --> Docs[apps/docs]
Icons --> Renderer[workflow-renderer]
Tokens[Typography and border tokens] --> Sim
Scheduled[Scheduled-task workspace surface] -->|removed| Cleanup[Hooks, contracts, and Copilot resources]
WorkflowSchedule[Workflow schedule execution] -->|retained| Cron[Cron and background execution]
Reviews (4): Last reviewed commit: "perf(chat): stop the resource picker fet..." | Re-trigger Greptile
Adversarial pass on the scheduled-task removal found a real regression in PUT /api/schedules/[id]. Removing the job-only `update` and `exclude_occurrence` handlers left them in `scheduleUpdateSchema`, so those bodies still parsed. The handler chain is `disable` first and then an unguarded fall-through to reactivate, so an `action: 'update'` request would have silently REACTIVATED the schedule instead of being rejected. Both actions are dropped from the discriminated union, so `parseRequest` now rejects them with a 400. Their bodies, response types and the orphaned `createScheduleContract` (its POST route is gone, and nothing imported it) go with them.
|
@cursor review |
The feature is gone from the product, so the marketing pages stop selling it. - deletes the `/scheduled-tasks` landing page and its calendar-loop hero, and the `LandingPreviewScheduledTasks` panel - drops the view from the landing preview: the `SidebarView` member, the nav entry and its now-unused Calendar icon, the callout label, both render branches, and the staged chat copy in `workflow-data` - removes the navbar and footer links and the sitemap entry - removes the route from `LANDING_ROUTES`, the COEP exemption list that must list every `app/(landing)` route `/scheduled-tasks` is indexed, so it 301s to `/workflows` rather than starting to 404 — that is the surface that still carries scheduled execution via the workflow Schedule trigger. Left alone deliberately: `demo-scheduler` is the Cal.com booking embed for the demo page, unrelated to this feature, and the scheduling library article is a generic SEO piece that never pitched it.
|
@cursor review |
…shows Dropping the `scheduledtask` group from the add-resource dropdown left `useWorkspaceSchedules` behind, so the picker still issued a workspace schedules request whose result never reached a group. Worse than a wasted request: `schedulesPending` was still in the hydration gate, so the whole picker waited on that response before it could settle, and `schedules` was still a `useMemo` dependency, re-running the group build when it resolved. The hook and its route stay — `/api/schedules?workspaceId=` still correctly lists workflow schedules, unlike `createScheduleContract`, whose route this branch removed.
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 1d4f4a0. Configure here.
|
An independent audit of the branch turned up dead code and stale docs that the compiler cannot see — nothing behavioural, but all of it rots silently. - README still sold the feature: the "Scheduled tasks" tile, the prose listing it as a workspace surface, and the now-unreferenced screenshot. The landing surface went in c61770a; this tile was missed. - `resource-content.tsx`: `SCHEDULE_STATUS_LABEL`, `formatScheduleInstant` and `ScheduledTaskField` were orphaned when the schedule render branch went. - `computeNextRunAt`: zero callers, including tests — its only consumer was the removed agent-job runner. - `applyScheduleUpdate`'s `allowCompleted` option: no call site passes it, and its comment described self-completion, which no longer exists. The guard stays (legacy `sourceType='job'` rows still carry `status='completed'` until the DB follow-up); it is simply unconditional now. - Three TSDoc blocks still described a create-job route and "opening a scheduled-task artifact". Type-check re-run with --force, since a cached turbo replay is not a check.
Follow-on within the same PR. A full comparison of every custom token docs rolls against the platform found three more classes of drift. Text scale — #6241 retuned these and docs kept the old values: - `--text-body` #3b3b3b -> #434343 (light), #cdcdcd -> #c1c1c1 (dark) - `--text-muted` #707070 -> #7a7a7a (light), #787878 -> #6e6e6e (dark) - `--text-icon` #525252 -> #5a5a5a (light), #a0a0a0 -> #969696 (dark) Docs and the app now agree on all 62 shared token names, with zero divergent values. Missing shared-component tokens. Docs renders `@sim/emcn` (Badge, Chip, ChipLink) and `@sim/workflow-renderer` (block, subflow and note views), but never defined 14 of the tokens those components reference — an undefined `var()` silently falls back to `currentColor`, so the failure is invisible until the branch that uses it renders. Several are live: `--warning` on an edited subflow, `--caution` on inline code inside a note, `--text-placeholder` on an empty note, `--border-success` on a successful run edge. Added with the app's values, along with `--text-icon-muted` (new in #6241) and the four Badge palettes docs lacked (teal, cyan, pink, blue-secondary), so any variant renders correctly rather than being one prop away from black. Type scale — docs declares micro/xs/caption/small/base/md in `@theme` but 20 call sites bypassed it with identical raw values (`text-[13px]`, `text-[0.8125rem]`, `text-[12px]`, `text-[15px]`, `text-[10px]`). Each now uses the token; every value is byte-identical, so this is a rename, not a restyle. The class reordering in the same files is biome's `useSortedClasses` reacting to the rename — verified as a pure permutation, with the class multiset unchanged in every file. Deliberately left alone: - `#33C482` / `#2FB3FF` — brand-mark SVG fills and default props in demo data, not styling. - The Ask AI button's inverted `#383838`/`#575757`/`#e0e0e0`/`#cfcfcf`. The platform's `--surface-inverted`/`--surface-inverted-hover` hold *different* values, so adopting them would restyle the control rather than tokenize it. Worth doing, but as a visual change with review.
…#6252) * improvement(docs): inherit the platform border and font-weight scales #6241 consolidated the app's neutral border tokens and flattened its font-weight scale. `apps/docs` was carrying an untouched copy of the pre-migration values, so the two have visibly drifted — the docs `@theme` block already declares it "mirrors apps/sim/tailwind.config.ts", so the drift is against stated intent rather than a deliberate divergence. Borders — same consolidation as the app: - `--border` #dedede -> #d8d8d8 (light), #333333 -> #444444 (dark) - `--border-1` and `--border-muted` become aliases of `--border`, so the 19 existing `var(--border-1)` consumers pick up the unified colour without being touched - `--divider` is retired; its single consumer moves to `--border` Font weights — the arbitrary values the app dropped: - `font-[480]`/`font-[470]`/`font-[500]` -> `font-medium`, `font-[430]` -> `font-normal`, `font-[600]` -> `font-semibold` The navbar's active tab and its invisible width-reserving ghost both used `font-[480]`; they move to `font-medium` together, so the anti-layout-shift trick still holds. Deliberately NOT ported: the app's `--border-width` hairline (0.5px on hi-dpi). The app wires it through `borderWidth.DEFAULT` in a Tailwind v3 JS config; docs is Tailwind v4 CSS-first, which hardcodes `border: 1px` in the utility with no theme key, so matching it means overriding a Tailwind utility. That is a site-wide visual change and wants its own PR with visual review. Also unchanged: the inline SVGs. `components/icons.tsx` (328) is the brand and integration set, `sim-logo` is a brand mark, and the handful of remaining shapes are bespoke and positioned by hand. Docs already consumes `@sim/emcn/icons` in the 15 places where a shared icon is the right call, and imports zero lucide. * improvement(docs): finish the platform token sweep Follow-on within the same PR. A full comparison of every custom token docs rolls against the platform found three more classes of drift. Text scale — #6241 retuned these and docs kept the old values: - `--text-body` #3b3b3b -> #434343 (light), #cdcdcd -> #c1c1c1 (dark) - `--text-muted` #707070 -> #7a7a7a (light), #787878 -> #6e6e6e (dark) - `--text-icon` #525252 -> #5a5a5a (light), #a0a0a0 -> #969696 (dark) Docs and the app now agree on all 62 shared token names, with zero divergent values. Missing shared-component tokens. Docs renders `@sim/emcn` (Badge, Chip, ChipLink) and `@sim/workflow-renderer` (block, subflow and note views), but never defined 14 of the tokens those components reference — an undefined `var()` silently falls back to `currentColor`, so the failure is invisible until the branch that uses it renders. Several are live: `--warning` on an edited subflow, `--caution` on inline code inside a note, `--text-placeholder` on an empty note, `--border-success` on a successful run edge. Added with the app's values, along with `--text-icon-muted` (new in #6241) and the four Badge palettes docs lacked (teal, cyan, pink, blue-secondary), so any variant renders correctly rather than being one prop away from black. Type scale — docs declares micro/xs/caption/small/base/md in `@theme` but 20 call sites bypassed it with identical raw values (`text-[13px]`, `text-[0.8125rem]`, `text-[12px]`, `text-[15px]`, `text-[10px]`). Each now uses the token; every value is byte-identical, so this is a rename, not a restyle. The class reordering in the same files is biome's `useSortedClasses` reacting to the rename — verified as a pure permutation, with the class multiset unchanged in every file. Deliberately left alone: - `#33C482` / `#2FB3FF` — brand-mark SVG fills and default props in demo data, not styling. - The Ask AI button's inverted `#383838`/`#575757`/`#e0e0e0`/`#cfcfcf`. The platform's `--surface-inverted`/`--surface-inverted-hover` hold *different* values, so adopting them would restyle the control rather than tokenize it. Worth doing, but as a visual change with review.
#6241 flattened the type scale by deleting the tailwind `fontWeight` override that remapped `font-medium` to 440/480. Nothing was restyled, but the utility's meaning changed: every one of ~505 call sites written when `font-medium` sat ~10 units above body snapped to a stock 500 against a body that also dropped 430 -> 400. The tab strip and table header Emir reported are two symptoms. The same PR added the "Font Weight" section to sim-styling.md declaring the end state (400 default, weight class only to step up) without migrating the codebase to it, so the rule and its violations shipped together and no gate could flag it. Removes the hardcoded weight from the ~20 pre-chip emcn primitives so they inherit 400, matching the chip family that was already correct. Deletes the three `font-normal` overrides that existed only to undo those defaults (`TabStrip`, `ChipCombobox`, `ChipModalField`) — their TSDoc said as much. `<th>` needed care in the other direction: Preflight resets h1-h6 but not `th`, so a header keeps the UA bold 700 and `font-medium` was holding it *down*. Deleting it made headers heavier. Rather than neutralize per call site — the codebase had already accumulated 12 such workarounds — globals.css completes Preflight with `th { font-weight: inherit }`, and the 8 now-dead `font-normal` workarounds come out. The rule keeps no element-level exceptions. Two width-measurement mirrors had to move with the text they measure: table-grid's auto-fit canvas and tag-input's hidden sizing span. Left stale, both would mis-measure. Also: drops an inline `font-weight:500` from the header drag ghost, normalizes `text-[13px]`/`text-[11px]` to `text-small`/`text-xs`, aligns the landing table previews that clone the product header, documents AvatarFallback's deliberate step-up, and corrects the stale AGENTS.md line claiming Button owns a weight. Verified: typecheck 0, lint clean, full vitest run identical to origin/staging across three runs (158 failed suites / 1 failed test / 16350 passing — all pre-existing: a PostCSS env error and a missing `rg` binary).
…ht (#6291) * improvement(emcn): let every primitive inherit the document font weight #6241 flattened the type scale by deleting the tailwind `fontWeight` override that remapped `font-medium` to 440/480. Nothing was restyled, but the utility's meaning changed: every one of ~505 call sites written when `font-medium` sat ~10 units above body snapped to a stock 500 against a body that also dropped 430 -> 400. The tab strip and table header Emir reported are two symptoms. The same PR added the "Font Weight" section to sim-styling.md declaring the end state (400 default, weight class only to step up) without migrating the codebase to it, so the rule and its violations shipped together and no gate could flag it. Removes the hardcoded weight from the ~20 pre-chip emcn primitives so they inherit 400, matching the chip family that was already correct. Deletes the three `font-normal` overrides that existed only to undo those defaults (`TabStrip`, `ChipCombobox`, `ChipModalField`) — their TSDoc said as much. `<th>` needed care in the other direction: Preflight resets h1-h6 but not `th`, so a header keeps the UA bold 700 and `font-medium` was holding it *down*. Deleting it made headers heavier. Rather than neutralize per call site — the codebase had already accumulated 12 such workarounds — globals.css completes Preflight with `th { font-weight: inherit }`, and the 8 now-dead `font-normal` workarounds come out. The rule keeps no element-level exceptions. Two width-measurement mirrors had to move with the text they measure: table-grid's auto-fit canvas and tag-input's hidden sizing span. Left stale, both would mis-measure. Also: drops an inline `font-weight:500` from the header drag ghost, normalizes `text-[13px]`/`text-[11px]` to `text-small`/`text-xs`, aligns the landing table previews that clone the product header, documents AvatarFallback's deliberate step-up, and corrects the stale AGENTS.md line claiming Button owns a weight. Verified: typecheck 0, lint clean, full vitest run identical to origin/staging across three runs (158 failed suites / 1 failed test / 16350 passing — all pre-existing: a PostCSS env error and a missing `rg` binary). * fix(tables): align the workflow-group drag ghost with the label it previews Cursor Bugbot caught the sibling of the ghost fixed in column-header-menu: this one kept an inline `font-weight:500` after the band label dropped to the inherited 400, so the drag preview no longer matched the text it represents — the same mirror drift this PR fixes for the width-measurement spans. It was drifted on size too: hardcoded `font-size:13px` against a label that is `text-xs` (11px), so it never matched. Both now come from the token the label uses, which also clears the inline fontWeight the styling rule bans. * fix(toolbar): stop the block drag preview hardcoding a weight its label does not use Third instance of the same mirror drift, found by sweeping rather than waiting for it to be reported. The toolbar item label renders at the inherited 400 (its container is `chipVariants`, which is weight-free), but the drag preview hardcoded `font-weight: 500` — so the preview never matched the item it previews, before or after this PR. Drops the weight only. The 16px is left alone: a drag preview reading larger than its source is a deliberate affordance, not a mismatch. Not fixed here, deliberately: the `font-weight: 500` in code-editor.tsx's highlight layer. That HTML is rendered in registration with a transparent textarea, so weight affects glyph advance widths and the caret alignment — it needs live in-editor verification, unlike a detached drag ghost. Its two placeholder branches already disagree on weight, so it wants its own change. * revert(canvas): drop the workflow-editor panel changes from this PR The canvas panel is under active modification elsewhere, so this PR stays out of it. Reverts the toolbar search input, the sub-block table cell and its overlay mirror, the messages-input textarea and its mirror, and the block drag preview — all back to staging verbatim. Cursor Bugbot was right about that last one and I was wrong: the preview mirrors the drag DESTINATION (its TSDoc says "looks like a workflow block", and 250px/16px are block-card dimensions), not the toolbar chip I had compared it against. workflow-block-view renders the title `font-medium text-md`, so its 500 was correct. Moot now that the file is reverted, but worth recording so the next sweep does not repeat the mistake. The globals `th` rule still covers the sub-block table header without a call-site class; the explicit font-medium there simply wins over it, exactly as staging renders today.
…ss the panel (#6297) * fix(editor): restore caret alignment and the intended type scale across the panel Four distinct defects, all surfaced while testing the workflow editor. **Caret drift in the Start block's Description field.** Its overlay mirror was built differently from every sibling field: `overflow-hidden` + `truncate` and no scroll synchronisation, where the working fields use `overflow-x-auto` + `whitespace-pre` + `syncOverlayScroll`. Once the value passed the visible width the input scrolled and carried the caret with it while the overlay stayed pinned at the first character, so the gap grew as you typed. It now has the same plumbing as its siblings, on its own ref maps so it cannot collide with the value overlay. **Overlay mirrors left at 500 over 400 inputs.** #6291 dropped emcn Input and Textarea to the inherited weight, but the canvas files that mirror them were reverted from that PR, so 11 overlays kept a hardcoded `font-medium`. A mirror that renders heavier than the input beneath it misaligns by the weight delta on every character. All 11 realigned. **Input text tracking differently from its label.** The UA stylesheet resets form controls to `letter-spacing: normal`, so inside `.workspace-root` (0.02em) an input diverged from surrounding text — and from its own overlay — by 0.28px per character. emcn Input and Textarea now carry `[letter-spacing:inherit]`, which fixes every mirrored input at the source rather than per call site. **Weights and type sizes that changed meaning under #6241.** That PR deleted the tailwind remap of `font-medium` (440 light / 480 dark) without migrating the ~505 call sites written against it, so untouched code jumped to a stock 500. The panel's editor, toolbar, chat and connections surfaces are swept back to the inherited weight. The Chat header was also visibly taller than Toolbar and Editor purely because it used `text-[14px]` — font-size with no paired line-height — against otherwise byte-identical containers; it and the panel's two other arbitrary sizes now use named tokens. Also fixes five JSX conditionals in the workflow MCP settings page that had lost their braces, so `canManage && ()` rendered as literal text under the server detail tab. Verified: typecheck 0, biome clean, 18644/18645 vitest passing (the one failure is a missing `rg` binary and predates this branch). * fix(emcn): give chip text fields the same tracking as their mirrors An audit of the previous commit found the letter-spacing fix was incomplete: it landed on `Input`/`Textarea` but not on the chip family, so `ChipInput` and `ChipTextarea` kept the UA `letter-spacing: normal` while any overlay mirroring them inherited the ambient tracking. The MCP server form modal is a live instance — its shared `FormattedInput` layers a transparent `ChipInput` under a visible div, across the server URL and both header fields, whose values are long by nature. The caret separated from the text by roughly 0.28px per character. Fixed on `chipFieldTextClass` rather than the call site, so every chip field matches its mirror the way `Input`/`Textarea` already do. * fix(editor): restore the strong-text variant a class sweep welded together The font-weight sweep in 94c9f1f used a blanket sed, which turned [&_strong]:font-medium [&_strong]:text-[var(--text-primary)] into [&_strong]:[&_strong]:text-[var(--text-primary)] — a chained variant matching a <strong> inside a <strong>, so ordinary strong text in trigger setup instructions lost its color. The removed weight was also load-bearing rather than decorative. Preflight sets b/strong to font-weight: bolder, so against a 400 body a bare <strong> lands near 700; the class was holding it down to 500. Deleting it made that text heavier, the inverse of the sweep's intent — the same UA-default trap as <th>. Both variants are restored. Swept for the same damage: no chained [&…]:[&…] variants remain across apps/sim or packages, and this was the only variant-scoped weight the sed touched. Found independently by Greptile and Cursor Bugbot.
Summary
Four platform-wide passes, plus a cleanup commit that removes the dead tails the first two left behind.
lucide-react. The dependency is dropped fromapps/sim,apps/docs,packages/emcnandpackages/workflow-renderer, and ~208 files move to@sim/emcn/icons. 46 new icons are added, drawn on the set's own-1 -2 24 24grid atstrokeWidth 1.55rather than ported from lucide, and 11 existing ones are normalized to match.trash-outlineandtrash2collapse into a redrawntrash--font-weight-base/medium/semiboldcustom properties (which remappedfont-mediumto 440/480) are deleted along with 36 arbitraryfont-[NNN]values clustered between 380 and 500 — nothing in that range read as hierarchical. Headings now inherit 400 by design--text-body,--text-iconand--text-mutedshift in both modes;--text-icon-mutedand--shadow-ambientare new. Every hand-rolledshadow-[inset_0_-1px_0_…]bottom border becomes a realborder-b, andring-1becomesring-[length:var(--border-width)]where the line should follow the token — a box-shadow has its own width and silently renders at double weight against neighbors on hidpi/api/workflows/[id]/referencesroute and its contract, hook and libCodenow needs an explicit re-export from the@sim/emcnbarrel, joiningCalendarandTable— it exists as both a component (the editor) and an icon, and the star export would otherwise resolve to the glyph.The calendar UI is retained on purpose
app/workspace/[workspaceId]/scheduled-tasks/components/schedule-calendar/**and itsutils/**survive with no importer. That is deliberate — the UI will be repurposed on a future surface — and its TSDoc now says so, since a directory under a route segment with nopage.tsxand no importer otherwise reads as dead code on the next sweep.What the cleanup commit removes
The removals above type-checked clean, which is why nothing flagged what they orphaned. Six mutation hooks in
hooks/queries/schedules.tslost their only consumer when the scheduled-tasks page was deleted, along with the three contract objects that served only them.disableScheduleBodySchemaandexcludeOccurrenceBodySchemaare kept even though their contracts go: both are members ofscheduleUpdateSchema, the discriminated union the livePUT /api/schedules/[id]route parses. Removing them with their contracts would collapse the union and 400 thedisableandexclude_occurrenceactions.The
add-enrichmentskill also templatedimport { SomeIcon } from 'lucide-react', so it generated an unresolvable import the moment the dependency left. It now points at@sim/emcn/icons, matching all five shipped enrichments.Type of Change
Testing
apps/sim,apps/docs,packages/emcn,packages/workflow-renderer)cloud-review-tools.test.ts,FileNotFoundError: 'rg') is environmental — apython3subprocess resolvingrg, which CI installs explicitly — and reproduces identically on the pre-change baselinebun run check:api-validationandbun run check:react-querypass; biome clean on every changed file@sim/emcn/iconsimport across 13,906 files against the barrel's exports, both directions: zero imports without an export, zero new icons unusedTwo things reviewers should weigh, both judgment calls rather than defects:
--text-mutedmoved from 4.91:1 to 4.26:1 on white, under the 4.5:1 WCAG AA floor for normal-size text. It is the token for placeholders andChipModalFieldlabels (13px), so ~760 usages across 327 files are affected.#747474would restore ~4.5:1 while keeping most of the intended lightening. The other retuned tokens keep headroom —--text-bodybottoms out at 5.33:1 and--text-iconat 3.24:1 against the 3:1 non-text barapps/docs/app/global.cssdeclares itself a mirror of the app tokens and now drifts on 9 values, and lacks the two new ones. The missing tokens are latent rather than live — docs imports no emcn component that reads them — but the value drift is visible today on docs chip chromeAlso worth knowing:
POST /api/schedulesandDELETE /api/schedules/[id]now have no first-party caller, since copilot reachesperformCreateJob/performDeleteJobserver-side and skips HTTP. The routes are left in place.Checklist
Companion: simstudioai/mothership#397
Merge order: merge the companion first.
apps/sim/lib/copilot/generated/tool-catalog-v1.tsis generated from that PR's contract. If this merges first, sim staging drops the four scheduled-task tool ids fromTOOL_CATALOGwhile mothership staging is still emitting them, andpartitionToolBatchroutes them into theunknownbucket.