Skip to content

Commit 5dad616

Browse files
committed
Merge platform-core-chat into the integration center
Bring the latest organization wiring (embedded and shared trees, chat steering, multi-account Search) under the integration-center work, ahead of the EMCN package split. Upstream tip: d375b0c. - Integrations: the fixture integration center keeps its redesign; the live route keeps multi-account Search. Imports follow the eleven modules that moved from lib/ into shared/. - Chat: the conversation keeps PageColumn and MessageBubble and drops the queued-message recall that steering replaced; user messages show delivery status. - ActivityRow combines textMetadata/people/disabled with density, readOnly, render, wrapDetail and metadataLeading; embedded callers use textMetadata. Field styles absorb the ellipsis, masked-input and autofill-decoy rules. RangePicker callers move to ChoiceMenu, without the trigger chevron, since toolbar choices have none. - Embedded views supply the required placeholders, the book glyph for documentation and TextArea defaultSize. - The variant-usage walk defaults entry() to the default export, so dynamically loaded embedded sections count as product consumers. - Regenerated integration metadata (category for the new providers), refreshed the embedded snapshot and shrank the convergence baseline.
2 parents cf841e5 + d375b0c commit 5dad616

1,895 files changed

Lines changed: 170672 additions & 28379 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-trigger/SKILL.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ export const {service}PollingHandler: PollingProviderHandler = {
411411
await markWebhookSuccess(webhookId, logger)
412412
return 'success'
413413
} catch (error) {
414-
logger.error(`[${requestId}] Error processing {service} webhook ${webhookId}:`, error)
414+
logger.error('Error processing {service} webhook:', error)
415415
await markWebhookFailed(webhookId, logger)
416416
return 'failure'
417417
}
@@ -423,6 +423,7 @@ export const {service}PollingHandler: PollingProviderHandler = {
423423
- First poll seeds state and emits nothing (avoids flooding with existing data)
424424
- Use `pollingIdempotency.executeWithIdempotency(provider, key, callback)` for dedup
425425
- Use `processPolledWebhookEvent(webhookData, workflowData, payload, requestId)` to fire the workflow
426+
- Log through `ctx.logger` (already bound with `webhookId` and `pollId`, which equals `ctx.requestId`). Never add `{ requestId }` to a log line; the poll route's request context owns that field and overwrites it
426427
- Use `updateWebhookProviderConfig(webhookId, partialConfig, logger)` for read-merge-write on state
427428
- Use the latest server-side timestamp from API responses (not wall clock) to avoid clock skew
428429

‎.agents/skills/emil-design-eng/SKILL.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ description: This skill encodes Emil Kowalski's philosophy on UI polish, compone
66

77
# Design Engineering
88

9-
> **In this repo:** emcn owns component chrome (press states, tooltip/popover/menu animation, easing): apply these principles by proposing changes in `packages/emcn`, not per call site, and add no global CSS variables or keyframes (CLAUDE.md "Styling and EMCN"). Animation uses `import { motion } from 'framer-motion'`. Gate touch-unsafe hover with the `hover-hover:` Tailwind variant (plain `hover:` is intentionally ungated). `.claude/rules/sim-styling.md` and `.claude/rules/emcn-components.md` win on any conflict.
9+
> **In this repo:** emcn owns component chrome (press states, tooltip/popover/menu animation, easing): apply these principles by proposing changes in `packages/emcn`, not per call site, and add no global CSS variables or keyframes (`.claude/rules/sim-styling.md`). Animation uses `import { motion } from 'framer-motion'`. Gate touch-unsafe hover with the `hover-hover:` Tailwind variant (plain `hover:` is intentionally ungated). `.claude/rules/sim-styling.md` and `.claude/rules/emcn-components.md` win on any conflict.
1010
1111
You are a design engineer with the craft sensibility. You build interfaces where every detail compounds into something that feels right. You understand that in a world where everyone's software is good enough, taste is the differentiator.
1212

‎.agents/skills/implement-platform/SKILL.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ Start in the Sim checkout containing the requested product work. Read the [Platf
1313
3. **Choose or change the owner.** Start with the behavior. An action, navigation row, value picker, or disclosure has an existing keyboard and pointer contract. Different interactions may share visual roles while retaining different semantics. Use the existing family and named props for a change in size, intent, icon, or content. Toolbar choices use ChoiceMenu, as Home's period does; Select/SelectField belong to forms and settings. Compare the rendered trigger, not just its variant name. Put unique anatomy and its CSS together in `_components/<component>/<component>.tsx` and `<component>.module.css`. Match an existing semantic rhythm, such as Home's ActivityRow, for a custom composition. Keep page files free of styling. Only EMCN owns the appearance of its controls. Use Base UI there for complex keyboard, floating, and dismissal behavior.
1414
4. **Trace the full change.** On a second independent feature use, promote the original implementation and migrate both callers. For consolidation, compare semantics, map every consumer to its replacement, then remove the obsolete implementation, export, variant styles, and unused registrations. For deletion, also check menus, preferences, fixture data, workbench references, and tests that existed only for the removed feature. Preserve unrelated consumers and historical Paper evidence. Before adding a shared visual variant, name at least two independent real consumers. A single feature composes the existing primitives in its local owner; a label, icon, data value or responsive arrangement does not justify another variant. Keep the public API small enough to understand at the call site. Edit the source or compiler for generated foundations and recipes.
1515
5. **Verify where people use it.** Run the design audit and applicable checks from the README. Render the changed product route with empty, full, stress, and fixture-off data as relevant. Check both themes, widths between artboards, long content, text scaling, keyboard, and pointer states. Compare shared controls in their actual consumers. Check the actual scroll edge and the open popup when space is tight. For shell, panel, or desktop work, exercise the real Electron renderer. For substantial implementations and consolidations, use an independent agent during design or implementation and for a final review of the changed owners and routes. Reuse the single review server at localhost:3125. Check its process working directory and branch before starting a server or moving work. Separate task worktrees do not update that preview until reconciled into its checkout. Provide the working route for visual review.
16-
6. **Keep decisions durable.** Follow the contract’s maintenance guidance when an approved correction changes a shared rule. Record feature-specific decisions with their feature. For sustained work, keep a task checkpoint with the code revision, verified states, evidence, and outstanding work. Include the branch or PR, checkpoint path, and localhost route in a handoff. On resumption, compare the checkpoint with the current branch, working tree, and relevant live sources before acting.
16+
6. **Keep non-UI code in one place.** When work touches both the zone and `apps/sim/platform/embedded`, converge first rather than porting: only markup may differ. Follow "Converging a domain" in `apps/sim/platform/AGENTS.md`; `bun run check:platform-convergence` fails a new parallel file.
17+
7. **Keep decisions durable.** Follow the contract’s maintenance guidance when an approved correction changes a shared rule. Record feature-specific decisions with their feature. For sustained work, keep a task checkpoint with the code revision, verified states, evidence, and outstanding work. Include the branch or PR, checkpoint path, and localhost route in a handoff. On resumption, compare the checkpoint with the current branch, working tree, and relevant live sources before acting.

‎.agents/skills/make-interfaces-feel-better/SKILL.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ Animate contextual icons with opacity, scale, and blur instead of toggling visib
4949

5050
### 8. Font Smoothing
5151

52-
Apply `-webkit-font-smoothing: antialiased` to the root layout on macOS for crisper text. In this repo, do not add root-level smoothing or other global styles (CLAUDE.md "Styling and EMCN"); raise it as a design-system proposal instead.
52+
Apply `-webkit-font-smoothing: antialiased` to the root layout on macOS for crisper text. In this repo, do not add root-level smoothing or other global styles (`.claude/rules/sim-styling.md`); raise it as a design-system proposal instead.
5353

5454
### 9. Tabular Numbers
5555

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
---
2+
description: One pattern per job across the organization views (Settings, People, Integrations, Links, Home)
3+
paths:
4+
- "apps/sim/platform/embedded/app/(shell)/{settings,people,integrations,links,home}/**"
5+
- "apps/sim/platform/embedded/lib/**"
6+
- "apps/sim/platform/shared/**"
7+
- "apps/sim/platform/design-system/components/{status,modal,picker,settings-section,search-field,activity-row}/**"
8+
- "apps/sim/app/o/*/**"
9+
- "apps/sim/app/o/*/settings/**"
10+
---
11+
12+
# Organization Views
13+
14+
The organization views live in `apps/sim/platform/embedded/app/(shell)/` and take everything shared from
15+
`@/platform/design-system/components`. Each job below has one pattern. A view that differs needs a
16+
reason written where it differs; "it was already like that" is not one.
17+
18+
| Job | Use | Never |
19+
| --- | --- | --- |
20+
| First read of a view | `QueryBoundary` (`query`, `failure`, `loadingLabel`, optional `empty`, `loading`), which renders `LoadingRows`, then `FailureNotice`, then `empty`, then `children(data)` | Inline `isPending ? … : error ? …`, a raw `<p>Loading…</p>`, a loading `InlineNotice` |
21+
| Loading | `LoadingRows` by default. A placeholder shaped like its content (`WidgetSkeleton`, usage charts) only where rows would misrepresent it | A second generic skeleton |
22+
| Failed read | `FailureNotice`, labelled Retry. `intent='warning'` where the read partly answered | A hand-built retry button or `InlineNotice` + `Button` |
23+
| Failed background refresh | `FailureNotice` outside the boundary, over the content it keeps | Replacing content already on screen |
24+
| Empty | `EmptyState`, with no create button when the page already has one. A picker's no-match line inside a dialog stays `Muted`, since a block would take over the dialog | `Muted` or a raw `<p>` anywhere else |
25+
| Confirm | `ConfirmDialog` (`target`, `title`, `confirmLabel`, `pendingLabel`, `onConfirm`, `safe` when nothing is lost). Removing a person, revoking an invite and any destructive row action always ask first | `Modal variant='confirm'`, `window.confirm`, an unconfirmed destructive action |
26+
| Save | `SaveActions`, end-aligned in the page flow under the fields it commits: Discard while dirty, then Save. Save is visible and disabled while clean | Save in a header, Save before Discard, a Cancel beside Discard |
27+
| Editing a server value | `useServerDraft`. Adopts a newer value while clean; while dirty it keeps the edits and sets `conflict`. Show `DraftConflictNotice`, and block Save until the viewer chooses | Seeding `useState` from a query once |
28+
| Autosave vs Save | One or the other per page. A page with `SaveActions` holds every field in one draft and writes it in one request. List actions with their own dialog, such as adding or removing a member, are not field edits | A page mixing both |
29+
| Create | A primary compact button in `SectionToolbar`, or in the page header on a page with one | Create in both the toolbar and the empty state |
30+
| Search over a section's rows | `SectionSearch subject='members'` | `SearchField` with its own copy, unless the search covers more than the subject's name |
31+
| Row | `ActivityRow` for a row that opens something, `SettingsRow` for a row holding a control | A hand-built row |
32+
| List of rows | `RowList` (`dividers` for a list read as one block). `ActivityRow density='comfortable'` in settings | `calc(-1 * var(--ui-row-inset))` around a list; styling a row's height from outside |
33+
| Row actions | `ActionMenu` with icon `I108`, destructive item last with a separator | The same action in the row and its menu |
34+
| Section heading | `SettingsSection title` (h2), `DetailHeader` for a sub-view's way back | A hand-written heading |
35+
| Toolbar | `SectionToolbar grow={<SectionSearch />}` with its actions as children | A hand-built flex row |
36+
37+
## Failure feedback
38+
39+
- Form validation is inline, on the field (`error`), once a save has been attempted.
40+
- A dialog's own action failing stays in the dialog: `Modal` shows a rejected `onConfirm`'s message and keeps the draft.
41+
- Any other action failing is a toast. Nothing fails silently.
42+
43+
## Page gates
44+
45+
Every page under `app/o/[organizationId]` calls
46+
`requireOrganizationViewer(organizationId, callbackUrl)` from `@/app/o/[organizationId]/viewer`. It
47+
redirects a signed-out viewer to sign-in and back, 404s a viewer with no access, and returns
48+
`{ userId, principal, surface }`. Never write `{ kind: 'session', ... }` in a page.
49+
50+
## Dialogs
51+
52+
`Modal` holds itself open while `onConfirm`'s promise or its `pending` prop runs. Escape, the backdrop
53+
and Close do nothing until it settles, including when the browser closes the `<dialog>` itself: once
54+
user activation is spent, `cancel` cannot be prevented, so `OverlayDialog` reopens from `close`.
55+
56+
## Files
57+
58+
- A section with more than one job splits by job: `group-detail.tsx` is the shell, `group-general-tab.tsx`
59+
and `group-catalog-tabs.tsx` its bodies, `use-group-draft.ts` its write.
60+
- Merge logic worth a test is a pure module next to the view, such as `secrets-draft.ts`.
61+
- `(shell)/_components/section-parts/` holds what settings and the secrets page share: `SectionStack`, `FieldStack`, `SectionToolbar`,
62+
`DetailHeader`, `HeadingRow`, `Muted`, `SectionSkeleton`, `DraftConflictNotice`. `useServerDraft` is in `_components/`, since Integrations uses it too.
63+
64+
## Non-UI code lives once
65+
66+
A view's data and logic belong in `apps/sim/platform/embedded/lib/data` when only these views use them, and in `apps/sim/platform/shared` when the zone has the same thing. A view reads hooks through that layer; a real adapter owns the mutation, its toasts and any mapping, and is never a re-export. Before adding a file to `embedded/`, look for its counterpart under `apps/sim/platform/lib` and follow "Converging a domain" in `apps/sim/platform/AGENTS.md`. `check:platform-convergence` fails a new file here or a new path both trees hold.
67+
68+
## Legacy workspace settings
69+
70+
`apps/sim/app/workspace/*/settings/**` keeps `SettingsPanel` from `@/components/settings/settings-panel`,
71+
which owns chrome through `settings/[section]/layout.tsx`. The `add-settings-page` skill describes it.
72+
New organization work never imports it.

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
description: Settings page layout and SettingsPanel design-system compliance
33
paths:
44
- "apps/sim/app/workspace/*/settings/**"
5-
- "apps/sim/app/o/*/settings/**"
65
- "apps/sim/app/workspace/*/{integrations,skills,upgrade}/**"
76
- "apps/sim/app/workspace/*/components/{resource-tile,credential-detail}/**"
87
- "apps/sim/components/{settings,permissions}/**"

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ description: Tailwind CSS and styling conventions
33
paths:
44
- "apps/sim/**/*.tsx"
55
- "apps/sim/**/*.css"
6+
- "packages/workflow-renderer/**/*.tsx"
67
---
78

89
# Styling Rules
@@ -91,6 +92,8 @@ Draw a line with a real `border-*` utility. Never hand-roll one as `shadow-[inse
9192

9293
## Chip Components (consumer usage)
9394

95+
The chip family is the canonical chrome: `ChipInput`, `ChipTextarea`, `ChipModal`/`ChipModalField`, `ChipSelect`/`ChipCombobox`/`ChipDropdown`, `ChipSwitch` (a segmented choice; a boolean toggle stays `Switch`), `ChipDatePicker`, `Chip`/`ChipLink`, `ChipTag`; `DropdownMenu` for context/action menus. Import components, `cn`, and tokens from the `@sim/emcn` barrel and icons from `@sim/emcn/icons`; never deep-import other component subpaths. Never update global styles; keep styling local to the component.
96+
9497
`ChipInput`, `ChipTextarea`, `ChipModal*` own their full chrome. Consumers describe intent through PROPS; they never re-style the chrome. The canonical chrome lives in `packages/emcn/src/components/chip/chrome.ts` (all tokens are re-exported from the `@sim/emcn` barrel — no subpath import needed) — never hand-roll `rounded-lg`/`border`/`bg-[var(--surface-5)]`/`h-[30px]`/`px-2`/`text-sm`/focus rings.
9598

9699
### Props over className

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ paths:
55
- "**/*.test.tsx"
66
- "**/*.integration.ts"
77
- "**/e2e/**"
8+
- "apps/sim/scripts/test-*-e2e.ts"
89
---
910

1011
# Testing

0 commit comments

Comments
 (0)