Skip to content

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

Merged
waleedlatif1 merged 12 commits into
stagingfrom
improvement/platform
Aug 4, 2026
Merged

Conversation

@emir-karabeg

@emir-karabegemir-karabeg commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Summary

Four platform-wide passes, plus a cleanup commit that removes the dead tails the first two left behind.

  • Retires lucide-react. The dependency is dropped from apps/sim, apps/docs, packages/emcn and packages/workflow-renderer, and ~208 files move to @sim/emcn/icons. 46 new icons are added, drawn on the set's own -1 -2 24 24 grid at strokeWidth 1.55 rather than ported from lucide, and 11 existing ones are normalized to match. trash-outline and trash2 collapse into a redrawn trash
  • Flattens the font-weight scale to Tailwind's stock 400/500/600. The --font-weight-base/medium/semibold custom properties (which remapped font-medium to 440/480) are deleted along with 36 arbitrary font-[NNN] values clustered between 380 and 500 — nothing in that range read as hierarchical. Headings now inherit 400 by design
  • Retunes the neutral tokens and unifies line weight.--text-body, --text-icon and --text-muted shift in both modes; --text-icon-muted and --shadow-ambient are new. Every hand-rolled shadow-[inset_0_-1px_0_…] bottom border becomes a real border-b, and ring-1 becomes ring-[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
  • Removes the workspace scheduled-tasks surface and the workflow-references feature, including the sidebar and search-modal entries, the /api/workflows/[id]/references route and its contract, hook and lib

Code now needs an explicit re-export from the @sim/emcn barrel, joining Calendar and Table — 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 its utils/** 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 no page.tsx and 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.ts lost their only consumer when the scheduled-tasks page was deleted, along with the three contract objects that served only them.

disableScheduleBodySchema and excludeOccurrenceBodySchema are kept even though their contracts go: both are members of scheduleUpdateSchema, the discriminated union the live PUT /api/schedules/[id] route parses. Removing them with their contracts would collapse the union and 400 the disable and exclude_occurrence actions.

The add-enrichment skill also templated import { 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

  • Other: platform-wide refactor + feature removal

Testing

  • 4/4 affected packages type-check clean (apps/sim, apps/docs, packages/emcn, packages/workflow-renderer)
  • 16895/16896 tests pass. The single failure (cloud-review-tools.test.ts, FileNotFoundError: 'rg') is environmental — a python3 subprocess resolving rg, which CI installs explicitly — and reproduces identically on the pre-change baseline
  • bun run check:api-validation and bun run check:react-query pass; biome clean on every changed file
  • Icon migration verified by set-diffing every @sim/emcn/icons import across 13,906 files against the barrel's exports, both directions: zero imports without an export, zero new icons unused

Two things reviewers should weigh, both judgment calls rather than defects:

  1. Light-mode --text-muted moved 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 and ChipModalField labels (13px), so ~760 usages across 327 files are affected. #747474 would restore ~4.5:1 while keeping most of the intended lightening. The other retuned tokens keep headroom — --text-body bottoms out at 5.33:1 and --text-icon at 3.24:1 against the 3:1 non-text bar
  2. apps/docs/app/global.css declares 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 chrome

Also worth knowing: POST /api/schedules and DELETE /api/schedules/[id] now have no first-party caller, since copilot reaches performCreateJob/performDeleteJob server-side and skips HTTP. The routes are left in place.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

Companion: simstudioai/mothership#397

Merge order: merge the companion first.apps/sim/lib/copilot/generated/tool-catalog-v1.ts is generated from that PR's contract. If this merges first, sim staging drops the four scheduled-task tool ids from TOOL_CATALOG while mothership staging is still emitting them, and partitionToolBatch routes them into the unknown bucket.

…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.
@vercel

vercelBot commented Aug 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
docsReadyReadyPreviewAug 4, 2026 5:30pm

Request Review

@cursor

cursorBot commented Aug 4, 2026

Copy link
Copy Markdown

PR Summary

High Risk
Large cross-surface visual and icon migration plus removal of scheduled-task and workflow-references features and schedule job execution paths; schedule cron and billing-adjacent behavior need careful regression review.

Overview
This PR drops lucide-react across sim, docs, and emcn consumers and standardizes on @sim/emcn/icons, with new/normalized glyphs and agent/docs/rules updated to point at packages/emcn.

Design system: font weight collapses to Tailwind 400/500/600 (custom --font-weight-* and scattered font-[NNN] removed). Neutral text and --border tokens are retuned; --border-width drives hairlines on hidpi; inset shadow “borders” become real border-b / divide-*. Chip flush and some variant docs are aligned with current emcn behavior.

Scheduled tasks (product surface): workspace route, landing Scheduled Tasks page/hero loop, nav/footer links, and standalone sourceType: 'job' schedule APIs (create/update/delete inline mothership jobs, executeJobInline, complete_scheduled_task in mothership responses) are removed. Workflow schedule execution via the cron tick remains; the schedule-calendar components under workspace are kept without a page for future reuse.

Also removed: workflow references API (GET /api/workflows/[id]/references) and related UI/hooks.

Misc: sidebar expanded width 248→238; --shadow-ambient added; docs lucide-react dependency removed.

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

Copy link
Copy Markdown

⚠️ GitGuardian has uncovered 1 secret following the scan of your pull request.

Please consider investigating the findings and remediating the incidents. Failure to do so may lead to compromising the associated services or software components.

🔎 Detected hardcoded secret in your pull request
GitGuardian idGitGuardian statusSecretCommitFilename
35640005TriggeredGeneric Password0b7e8d2apps/desktop/src/main/browser-import/import-service.test.tsView secret
🛠 Guidelines to remediate hardcoded secrets
  1. Understand the implications of revoking this secret by investigating where it is used in your code.
  2. Replace and store your secret safely. Learn here the best practices.
  3. Revoke and rotate this secret.
  4. 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


🦉 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.
@waleedlatif1

Copy link
Copy Markdown
Collaborator

@greptile-apps

@waleedlatif1

Copy link
Copy Markdown
Collaborator

@cursor review

Comment threadapps/sim/app/api/schedules/[id]/route.ts
@waleedlatif1

Copy link
Copy Markdown
Collaborator

GitGuardian finding is a merge artifact — no code change needed

GitGuardian flags incident 35640005 ("Generic Password") at apps/desktop/src/main/browser-import/import-service.test.ts:559, attributed to merge commit 0b7e8d202.

The flagged line is a test fixture:

expect(importCredentials).toHaveBeenCalledWith([expect.objectContaining({password: 'new-local'})],'replace')

Three things confirm it is not introduced here:

  • the file is byte-identical to origin/staging (git diff --quiet origin/staging HEAD -- <file> passes)
  • it was added by staging's own 1d64b92b4 feat(desktop): desktop app (#5998), not by this branch
  • 'new-local' is a 9-character placeholder in a unit-test assertion, not a credential

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 (ea94cdfa9) and fails only from the staging merge onward.

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-apps

greptile-appsBot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR replaces Lucide with the in-house icon library, standardizes typography and border tokens, and retires the scheduled-task and workflow-reference surfaces.

  • Adds and normalizes the EMCN icon set while updating consumers and package dependencies.
  • Flattens font weights and introduces token-aware hairline borders.
  • Removes scheduled-task UI, workflow-reference APIs, hooks, contracts, and associated Copilot resources.
  • Preserves the workflow-schedule execution pipeline and the intentionally retained calendar components.

Confidence Score: 5/5

The PR appears safe to merge because no blocking failure remains within the available follow-up review scope.

No blocking failure remains.

Important Files Changed

FilenameOverview
packages/emcn/src/icons/index.tsExpands and normalizes the public icon barrel used throughout the repository.
packages/emcn/src/index.tsExplicitly preserves component exports for Calendar, Code, and Table while exposing icons.
apps/sim/app/_styles/globals.cssFlattens font-weight tokens and retunes neutral text, shadow, and border styling.
apps/sim/app/api/schedules/execute/route.tsRetains the workflow-schedule cron claiming, queueing, fallback, and recovery path while scheduled-task functionality is retired.
apps/sim/background/schedule-execution.tsRetains background execution and next-run advancement for workflow schedules.
apps/sim/lib/copilot/generated/tool-catalog-v1.tsRemoves retired scheduled-task tools from the generated Copilot catalog.
apps/sim/app/workspace/[workspaceId]/w/components/sidebar/sidebar.tsxReorganizes 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]
Loading

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.
@waleedlatif1

Copy link
Copy Markdown
Collaborator

@greptile-apps

@waleedlatif1

Copy link
Copy Markdown
Collaborator

@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.
@waleedlatif1

Copy link
Copy Markdown
Collaborator

@greptile-apps

@waleedlatif1

Copy link
Copy Markdown
Collaborator

@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.
@waleedlatif1

Copy link
Copy Markdown
Collaborator

@greptile-apps

@waleedlatif1

Copy link
Copy Markdown
Collaborator

@cursor review

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ 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.

@github-actionsgithub-actionsBot added the requires-mothership-merge Has a companion PR on the mothership/copilot side — merge in lockstep label Aug 4, 2026
@github-actions

Copy link
Copy Markdown

⚠️ Cross-repo companion check

One or more companion PRs aren't merged into staging yet. Merging this without them will leave copilot and sim out of sync — merge them in lockstep.

  • simstudioai/mothership#397OPEN, not merged (targets staging) — chore(agents): retire the scheduled_task subagent and its tools

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.
@waleedlatif1
waleedlatif1 merged commit 9b9da81 into stagingAug 4, 2026
21 of 22 checks passed
@waleedlatif1
waleedlatif1 deleted the improvement/platform branch August 4, 2026 17:28
waleedlatif1 added a commit that referenced this pull request Aug 4, 2026
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.
waleedlatif1 added a commit that referenced this pull request Aug 4, 2026
…#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.
waleedlatif1 added a commit that referenced this pull request Aug 5, 2026
#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).
waleedlatif1 added a commit that referenced this pull request Aug 5, 2026
…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.
waleedlatif1 added a commit that referenced this pull request Aug 5, 2026
…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.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

requires-mothership-mergeHas a companion PR on the mothership/copilot side — merge in lockstep

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@emir-karabeg@waleedlatif1