d25d482dc2
Publish CLI Package / publish-npm (push) Waiting to run
Publish Python SDK / publish-pypi (push) Waiting to run
Publish TypeScript SDK / publish-npm (push) Waiting to run
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
5.3 KiB
5.3 KiB
name, description
| name | description |
|---|---|
| add-settings-page | Add a new Sim settings page, or audit existing settings pages for design-system compliance with the shared SettingsPanel layout. Use when creating a settings tab, or when asked to check/clean up settings pages so they match the design system (consistent title, header, search, spacing). |
Settings Page (add / audit)
Sim settings pages all render through the shared SettingsPanel primitive,
which owns the page chrome and renders a nav-driven title + description. The full
convention lives in .claude/rules/sim-settings-pages.md — read it first; this
skill is the procedure.
Key paths:
- Layout primitive:
apps/sim/app/workspace/[workspaceId]/settings/components/settings-panel/settings-panel.tsx - Nav metadata (titles + descriptions):
apps/sim/app/workspace/[workspaceId]/settings/navigation.ts - Section switch + provider:
apps/sim/app/workspace/[workspaceId]/settings/[section]/settings.tsx - Pages:
apps/sim/app/workspace/[workspaceId]/settings/components/<name>/<name>.tsxand EE pages underapps/sim/ee/<feature>/components/
Mode A — Add a new settings page
- Navigation. In
navigation.ts: add the id to theSettingsSectionunion, then aNavigationItemwithlabelAND a one-linedescription(verb-first, ~40–55 chars, product voice per.claude/rules/constitution.md). Place it in the rightsectiongroup and set any gating flags (requiresHosted,requiresEnterprise, etc.). - Wire the switch. Add the component to the
effectiveSectionrender switch insettings/[section]/settings.tsx(lazydynamic(...)like its siblings). - Build the body inside
SettingsPanel. Never hand-roll the shell, header bar, scroll region, content column, or title block. Put header buttons inactions, a standalone search insearch={{ value, onChange, placeholder }}, and the page content aschildren. Modals go beside the panel inside a<>. - If the page has editable state, wire the shared save/discard stack — put
SaveDiscardActions(dirty-gated Discard+Save chips) inactions, and calluseSettingsUnsavedGuard({ isDirty })before any early-return gate. Detail sub-views additionally route the back chip throughguard.guardBack(closeFn)and render the sharedUnsavedChangesModal. Never hand-roll a Save button, abeforeunload, or an "Unsaved changes" modal — they're centralized. See the "Save / Discard + unsaved-changes guard" section in.claude/rules/sim-settings-pages.md. - Verify:
cd apps/sim && bunx tsc --noEmit;bunx biome check --write <file>.
Mode B — Audit existing settings pages
For each page component, confirm the checklist in .claude/rules/sim-settings-pages.md:
- Find hand-rolled shells that should be
SettingsPanel:git grep -n "flex h-full flex-col bg-\[var(--bg)\]" -- 'apps/sim/**/settings/' 'apps/sim/ee/'— every match should be eithersettings-panel.tsx, a detail sub-view (has a<Chip leftIcon={ArrowLeft}>back button), or an entitlement/loading gate early-return. Anything else is a page that still needs migrating. - Find hand-rolled title blocks (should be 0 outside detail views):
git grep -n "text-\[var(--text-body)\] text-lg" -- 'apps/sim/**/settings/' 'apps/sim/ee/' - Find literal pixel text sizes (should be 0 — see "Text-scale tokens" in
.claude/rules/sim-settings-pages.mdfor the token map and the row title/subtitle pairing convention):git grep -n "text-\[1[0-8]px\]" -- 'apps/sim/**/settings/' 'apps/sim/ee/' - Confirm each page imports
SettingsPaneland that itsNavigationItemhas an accuratedescriptionof consistent length with its peers.- Editable pages: confirm Save/Discard go through
SaveDiscardActionsand dirty is wired viauseSettingsUnsavedGuard(called before early-return gates) — flag any hand-rolled Save button,beforeunload, or unsaved modal.git grep -n "beforeunload" -- 'apps/sim/**/settings/' 'apps/sim/ee/'should only hit the centralizeduse-settings-before-unload.ts.
- Editable pages: confirm Save/Discard go through
- When migrating a page, change ONLY the structural shell→
SettingsPanelswap: move header chips toactions, the standalone search tosearch, delete the<h1>title block, replace the three closing</div>(column/scroll/shell) with</SettingsPanel>, and keep modal siblings in a<>fragment. Do NOT touch handlers, state, queries, conditional rendering, or detail/gate returns. Drop per-pagegap-*/pt-*on the content column in favor of the panel default. - When fixing literal pixel text sizes, replace ONLY the size class with its
exact-pixel-equivalent named token (e.g.
text-[12px]→text-caption, never a different size) — this must render pixel-identical, not restyle the page. Leave color tokens (--text-primaryvs--text-body, etc.) untouched unless they're also being changed for an unrelated, deliberate reason. - Remove now-unused imports (
ChipInput/Search) ONLY after grepping that they are not still used elsewhere in the file (e.g. by a detail view). - Verify the whole sweep:
tsc --noEmit,biome checkon every touched file, and run the affected pages' tests. Diff each file against the base and confirm the change is purely structural before shipping.