Skip to content

Commit 36f060b

Browse files
authored
v0.9.13: code hygiene, security hardening
2 parents 165e117 + 825e7e7 commit 36f060b

338 files changed

Lines changed: 2579 additions & 5590 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.agents/skills/add-integration/SKILL.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,15 @@ export interface {Service}{Action}Params {
8585
optionalParam?: string
8686
}
8787

88-
export interface {Service}Response extends ToolResponse {
88+
export interface {Service}{Action}Response extends ToolResponse {
8989
output: {
9090
// Define output structure
9191
}
9292
}
9393
```
9494

95+
Declare one response interface per tool, imported by that tool's `ToolConfig<Params, Response>` (or `InternalToolConfig` for in-process work). Never add an umbrella `{Service}Response` union: nothing imports it.
96+
9597
**Tool file pattern:** an external provider API uses `ToolConfig` with `request` (absolute `https://` URL, headers, body, `transformResponse`); same-process Sim work uses `InternalToolConfig` with `operation`. Both full templates, param visibility rules, and output typing live in `.agents/skills/add-tools/SKILL.md` — read it before writing the first tool.
9698

9799
### Critical Rules

‎.agents/skills/add-tools/SKILL.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,8 @@ export interface {Service}{Action}Response extends ToolResponse {
423423
}
424424
```
425425

426+
Each response interface is imported by its tool's config: `ToolConfig<Params, Response>` for an external API, `InternalToolConfig<Params, Response>` for in-process work. Never add an umbrella `{Service}Response` union of them: nothing imports it.
427+
426428
## Index.ts Barrel Export Pattern
427429

428430
```typescript

‎.agents/skills/db-migrate/SKILL.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@ The lint flags risky *shapes*; it cannot know whether a given drop is *safe righ
8383
```
8484
The reason must be specific and name the PR/version that removed the dependency. An empty reason fails the lint.
8585
- **Warnings** (`data-backfill`): non-blocking, but confirm the batching/idempotency before merging.
86-
4. Verify locally: `cd packages/db && bun run db:migrate` against a dev DB.
86+
4. Regenerate the test schema mock: `bun run scripts/generate-schema-mock.ts` (`check:schema-mock` in `check:audits` fails after any `schema.ts` change until you do).
87+
5. Re-run `(cd packages/db && bunx drizzle-kit generate)` once your migration is written: it must report no schema changes and write no new file, or CI fails on the schema and migrations disagreeing.
88+
6. Verify locally: `cd packages/db && bun run db:migrate` against a dev DB.
8789

8890
## Hard rule
8991

‎.claude/rules/constitution.md‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
---
22
description: Sim product language, positioning, and tone guidelines
3+
paths:
4+
- "apps/sim/app/(landing)/**"
5+
- "apps/sim/lib/landing/**"
6+
- "apps/sim/content/**"
7+
- "apps/sim/emails/broadcasts/**"
8+
- "apps/sim/app/layout.tsx"
9+
- "apps/sim/app/manifest.ts"
10+
- "apps/sim/app/llms*.txt/**"
11+
- "apps/sim/app/changelog.xml/**"
12+
- "apps/docs/**"
313
---
414

515
# Sim — Language & Positioning

‎.claude/rules/emcn-components.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ paths:
66

77
# EMCN Components
88

9-
Import components, `cn`, and tokens from the `@sim/emcn` barrel; icons come from the `@sim/emcn/icons` subpath, and CSS modules from their file path. Never deep-import other component subpaths. The **chip family** is the platform's primary chrome — always reach for it over the legacy primitives it is progressively replacing (`Input`→`ChipInput`, `Textarea`→`ChipTextarea`, `Modal`→`ChipModal`, `Select`/`Combobox`→`ChipSelect`/`ChipCombobox`/`ChipDropdown`, `Switch`→`ChipSwitch`, date field→`ChipDatePicker`). For context/action menus the canonical control is `DropdownMenu` — the standard menu (not a chip, and never a hand-rolled popover).
9+
Import components, `cn`, and tokens from the `@sim/emcn` barrel; icons come from the `@sim/emcn/icons` subpath, and CSS modules from their file path. Never deep-import other component subpaths. The **chip family** is the platform's primary chrome — always reach for it over the legacy primitives it is progressively replacing (`Input`→`ChipInput`, `Textarea`→`ChipTextarea`, `Modal`→`ChipModal`, `Select`/`Combobox`→`ChipSelect`/`ChipCombobox`/`ChipDropdown`, date field→`ChipDatePicker`). `ChipSwitch` is a segmented choice between options, not a replacement for `Switch`: a boolean on/off toggle stays `Switch`. For context/action menus the canonical control is `DropdownMenu` — the standard menu (not a chip, and never a hand-rolled popover).
1010

1111
## Chip chrome — single source of truth
1212

1313
Never hand-roll the chip pill from raw class strings (they go stale). Compose from the canonical sources:
1414

15-
- **Surface, typography + content tokens:** `chip/chip-chrome.ts` — `chipFilledSurfaceTokens`, `chipFieldSurfaceClass`, `chipFieldTextClass` (text fields and the dropdown search box build on these), plus the chip-content chrome `chipContentGap`, `chipGeometryClass`, `chipContentIconClass`, `chipContentLabelClass`, `cellIconNodeClass` (non-chip surfaces that must visually match chip content, e.g. resource table cells), and the row-state pair `chipHoverSurfaceClass` / `chipActiveSurfaceClass` (hover vs. selected — mutually exclusive, so a selected row holds its surface through hover; every hand-rolled row imports these rather than restating the literals). All are re-exported from the `@sim/emcn` barrel — no subpath import needed.
15+
- **Surface, typography + content tokens:** `chip/chip-chrome.ts` — `chipFieldSurfaceClass`, `chipFieldTextClass` (text fields and the dropdown search box build on these), plus the chip-content chrome `chipContentGap`, `chipGeometryClass`, `chipContentIconClass`, `chipContentLabelClass`, `cellIconNodeClass` (non-chip surfaces that must visually match chip content, e.g. resource table cells), and the row-state pair `chipHoverSurfaceClass` / `chipActiveSurfaceClass` (hover vs. selected — mutually exclusive, so a selected row holds its surface through hover; every hand-rolled row imports these rather than restating the literals). All are re-exported from the `@sim/emcn` barrel — no subpath import needed.
1616
- **Pill geometry:** `chip/chip.tsx` — `chipVariants` (30px tall, `rounded-lg`, `px-2`, icon↔text `gap-1.5`). Every pill-shaped trigger (`ChipDropdown`, `ChipSelect`, `ChipSwitch`) reuses it for visual parity.
1717

1818
Canonical look: normal font-weight (never `font-medium`/`font-semibold`), value text `--text-body`, icons `--text-icon` at `size-[14px]`, placeholder `--text-muted`, `transition-colors`, **no focus ring** (the caret marks focus). Filled surface is `--surface-5` light / `--surface-4` dark with a `--border` border (`chip-chrome.ts` still spells it through the legacy alias `--border-1`; new code writes `--border`).
@@ -54,6 +54,6 @@ Declare keyboard intent on the action-owning primitive; never add document-level
5454
- **Discriminated-union props for modes** (e.g. `multiple`, the modal field `type`) instead of near-duplicate components.
5555
- **Delete legacy variants after migration** — leave no dead paths.
5656
- **Verify CSS vars exist.** An undefined var resolves to `currentColor`, which draws black borders. Align to the canonical tokens: normal weight, `--text-body`, `--text-icon`.
57-
- Use Radix UI primitives for accessibility. Export the component and its `variants` (when using CVA). Document with TSDoc + a usage example.
57+
- Use Radix UI primitives for accessibility. Export the component; export its CVA `variants` once another module composes them (`check:unused-exports` flags an export nothing imports). Document with TSDoc + a usage example.
5858

5959
Color tokens and icon-size conventions are canonical in `.claude/rules/sim-styling.md` — follow it rather than restating.

‎.claude/rules/sim-queries.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,4 +172,4 @@ Hooks import named type aliases from `@/lib/api/contracts/**` and never import `
172172

173173
## Enforcement
174174

175-
`scripts/check-react-query-patterns.ts` (`bun run check:react-query`, run in CI) statically enforces these conventions: every `useQuery`/`useInfiniteQuery`/`useSuspenseQuery` declares an explicit `staleTime`, inline `queryFn`s destructure `signal`, `queryKey`s reference a colocated factory rather than an inline literal, every `*Keys` factory in `hooks/queries/**` exposes an `all` root key, and every identifier the `queryFn` forwards into the fetch also appears in the `queryKey` (`key-fetch-arg-drift`). `hooks/queries/**` is a zero-tolerance zone; the rest of `apps/sim/**` is ratcheted against `scripts/check-react-query-patterns.baseline.json`. For a genuine exception, put `// rq-lint-allow: <reason>` on the line directly above the flagged construct.
175+
`scripts/check-react-query-patterns.ts` (`bun run check:react-query`, run in CI) statically enforces these conventions: every `useQuery`/`useInfiniteQuery`/`useSuspenseQuery` declares an explicit `staleTime`, inline `queryFn`s destructure `signal`, `queryKey`s reference a colocated factory rather than an inline literal, every `*Keys` factory in `hooks/queries/**` exposes an `all` root key, and every identifier the `queryFn` forwards into the fetch also appears in the `queryKey` (`key-fetch-arg-drift`). Any violation under `apps/sim/**` fails. For a genuine exception, put `// rq-lint-allow: <reason>` on the line directly above the flagged construct.

‎.claude/rules/sim-react-performance.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
---
22
description: Behavior-preserving React render-performance idioms
3+
paths:
4+
- "apps/sim/**/*.ts"
5+
- "apps/sim/**/*.tsx"
6+
- "packages/emcn/**"
7+
- "packages/workflow-renderer/**"
38
---
49

510
# React & Render Performance

‎.claude/rules/sim-settings-pages.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,9 @@ and — on activatable rows only — the hover band. Never hand-roll any of it,
224224
divider, body. Also carries `headerAccessory` and `action` slots. Never
225225
re-derive the label/divider chrome; `sim-styling.md` owns those tokens.
226226
- **`SettingsField`** (`…/components/settings-field`) — a read-only label/value
227-
pair in a detail body: muted caption over the value. Pair it with
228-
`SETTINGS_FIELD_VALUE_CLASSES` for the value text.
227+
pair in a detail body: muted caption over the value. Pass the value as text and it
228+
renders the value paragraph itself; pass a node when the value needs its own
229+
presentation (a control, an icon beside the value, status styling).
229230
- **`SettingsEmptyState`** (`…/components/settings-empty-state`) — the canonical
230231
muted status message, for empty lists, "no results", loading gates, **and
231232
failed loads** (`tone='error'`). `variant='fill'` (default) centers in the

‎.claude/rules/sim-styling.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ Layout/sizing ONLY: `flex-1`, `w-full`, `w-[Npx]`, `min-w-0`, `max-w-*`, margins
108108
- **Modal body** (`ChipModalBody`): `gap-4` between fields, padding `px-2 pt-4 pb-4.5`.
109109
- **Header/footer**: horizontal gutter `px-4` (header `pt-3`; footer `px-4 pt-2 pb-2`, tinted bar).
110110
- **Every body field MUST be a `ChipModalField`** — NEVER hand-roll a field row (raw `<div>` + hand-rolled `<p>`/`<label>` title + bare `ChipInput`/`ChipTextarea`). WHY: body `px-2` + field `px-2` = effective `px-4`, exactly matching the `px-4` header/footer. A hand-rolled row skips the field gutter, sits at `px-2`, and is visibly misaligned. Inline errors go through the `error` prop, not a hand-rolled `<p>`.
111-
- **Uncovered controls** (`ChipCombobox`, `ChipSelect`, `DatePicker`, `TimePicker`, `ButtonGroup`, arbitrary JSX) → `ChipModalField type='custom'` with a `title`. It still applies the `px-2` gutter and renders the canonical `Label`, so it stays aligned. Never drop such a control into a raw `<div>`, and never add a body-level wrapper `<div>` with a custom `gap-*` that fights `gap-4`.
111+
- **Uncovered controls** (`ChipCombobox`, `ChipSelect`, `ChipDatePicker`, `ChipTimePicker`, `ChipButtonGroup`, arbitrary JSX) → `ChipModalField type='custom'` with a `title`. It still applies the `px-2` gutter and renders the canonical `Label`, so it stays aligned. Never drop such a control into a raw `<div>`, and never add a body-level wrapper `<div>` with a custom `gap-*` that fights `gap-4`.
112112
- **Page section rhythm** (integrations/skills/settings): muted `text-small` label + `mt-[9px] mb-3 h-px bg-[var(--border)]` divider, sections stacked `gap-7`. Reuse `SettingsSection` (`app/workspace/[workspaceId]/settings/components/settings-section/settings-section.tsx`) rather than re-deriving it.
113113

114114
When a standalone labeled field outside a `ChipModal` needs the same look (e.g. `SkillImport`), match the field rhythm by hand: `flex flex-col gap-[9px]`, muted label, `ChipInput`/`ChipTextarea` control, `text-caption` error below.

‎.claude/rules/sim-url-state.md‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@
22
description: Shareable client view-state lives in the URL via nuqs
33
paths:
44
- "apps/sim/app/**/*.tsx"
5-
- "apps/sim/app/**/*.ts"
6-
- "apps/sim/app/**/search-params.ts"
7-
- "apps/sim/ee/**/*.tsx"
8-
- "apps/sim/ee/**/*.ts"
5+
- "apps/sim/app/workspace/**/*.ts"
6+
- "apps/sim/app/o/**/*.ts"
7+
- "apps/sim/ee/**"
8+
- "apps/sim/hooks/**"
9+
- "apps/sim/stores/**"
10+
- "apps/sim/lib/url-state/**"
11+
- "apps/sim/**/search-params.ts"
12+
- "apps/sim/**/*navigation.ts"
913
---
1014

1115
# URL / Query-Param State (nuqs)

0 commit comments

Comments
 (0)