Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
776f148
feat(helm): publish the chart to GHCR as a signed OCI artifact (#7563)
waleedlatif1 Sep 7, 2026
04322e0
fix(slack): paginate v2 conversation listing (#7396)
TheodoreSpeaks Sep 7, 2026
599654b
fix(slack): harden native webhook configuration (#7566)
waleedlatif1 Sep 7, 2026
249a7e8
fix(billing): classify permanent callback conflicts (#7569)
icecrasher321 Sep 7, 2026
c72fbdc
docs(library): update what-is-an-mcp-server (#7570)
icecrasher321 Sep 7, 2026
99d69af
feat(library): Can AI Agents Talk to Each Other? Multi-Agent Communic…
icecrasher321 Sep 7, 2026
a69f416
fix(redis): bound the three unbudgeted stream writers by bytes (#7568)
waleedlatif1 Sep 7, 2026
d037966
fix(browser): preserve omnibox focus and suggestions (#7572)
waleedlatif1 Sep 7, 2026
c762c57
fix(files): keep file extensions on extensionless downloads (#7573)
waleedlatif1 Sep 7, 2026
ea3f6ba
feat(files): improve editor recovery and editing controls (#7519)
waleedlatif1 Sep 8, 2026
8adb986
feat(auth): add scoped OAuth access and browser-based CLI login (#7488)
waleedlatif1 Sep 8, 2026
f52da15
fix(auth): move OAuth account controls below consent actions (#7575)
waleedlatif1 Sep 8, 2026
d7124cd
feat(scim): directory provisioning (SCIM 2.0) (#7567)
waleedlatif1 Sep 8, 2026
83544b1
fix(settings): move authorized apps into General (#7577)
waleedlatif1 Sep 8, 2026
651586e
fix(cli): clarify login method selection (#7578)
TheodoreSpeaks Sep 8, 2026
15fc6ab
fix(workflows): keep long-running calls active (#7579)
waleedlatif1 Sep 8, 2026
d594a9e
fix(api): clarify and standardize endpoint descriptions (#7580)
waleedlatif1 Sep 8, 2026
d482526
fix(identity): streamline SSO settings and harden SCIM provisioning (…
waleedlatif1 Sep 8, 2026
3c909b3
fix(privacy): honor browser telemetry preferences (#7583)
waleedlatif1 Sep 8, 2026
8cd51d4
fix(files): preserve editor content and isolate shared image reads (#…
waleedlatif1 Sep 8, 2026
a9fd694
fix(scim): sync provider display names and document Okta setup (#7585)
waleedlatif1 Sep 8, 2026
236eb53
fix(provenance): close durable writer and reader gaps (#7584)
icecrasher321 Sep 8, 2026
443b6c1
improvement(docs): add validated Entra SCIM setup guide (#7587)
waleedlatif1 Sep 8, 2026
13bdb0d
feat(auth): enable OAuth with permission-group controls (#7588)
waleedlatif1 Sep 8, 2026
888d4a0
improvement(docs): clarify Entra deprovisioning and validation (#7589)
waleedlatif1 Sep 8, 2026
ebf85f3
fix(cli): expose pagination cursors and fetch complete inventories (#…
TheodoreSpeaks Sep 8, 2026
3a23820
feat(search): add organization search and private assistant (#7477)
waleedlatif1 Sep 8, 2026
1f6eef3
fix(build): avoid Turbopack chunk collision with GCS path rename (#7593)
waleedlatif1 Sep 8, 2026
9c544a0
feat(library): How AI Agents Make Decisions (vs. Rule-Based Systems) …
icecrasher321 Sep 8, 2026
90adc4e
fix(db): recover failed credential group index on migration retry (#7…
TheodoreSpeaks Sep 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
21 changes: 17 additions & 4 deletions .agents/skills/v2-api-conventions/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,16 @@ Order matters because each layer is checked against the one before it.
3. **Route** with `defineV2JsonRoute`, declaring `contract`, `auth: v2ApiKeyAuth`, `operation`, `rateLimit`, `errorPolicy`, `mapInput`, `useCase`, `present`. Auth and rate limiting run before parsing.
4. **OpenAPI description** in `lib/api/contracts/v2/openapi/<domain>.ts`, then `bun run generate:openapi`. A description that claims behaviour the route does not have is the same class of bug as a wrong schema.

### Public descriptions

Use the [API description conventions](../../../apps/sim/lib/api/contracts/v2/openapi/README.md) when writing or auditing endpoint and field descriptions. Keep a short action-and-resource summary; use the description for behavior that changes the caller's choice, input, interpretation, or next action. Ordinary operations usually need one to three sentences, with no mandatory minimum.

Keep archive versus permanent-delete behavior, replacement versus partial-update semantics, partial success, retry safety, redaction, and asynchronous completion explicit. Verify these claims against the implementation. Describe observable behavior without exposing storage formats, locking mechanisms, internal identifiers, deployment architecture, or implementation history unless that detail changes how the caller must use the API.

Reuse wording across resource families when behavior matches: “Omitted fields remain unchanged,” “Archive,” and “permanently delete.” Prefer “during the request” or “asynchronously” to “settled inline.” Preserve real semantic differences; do not standardize them away.

Put field-specific rules in the source schema and reuse shared authentication and pagination wording. Shared schema descriptions also feed CLI help, so refer to related operation names rather than HTTP paths. Regenerate OpenAPI, CLI metadata, and CLI docs after changing their source descriptions; never hand-edit generated output.

## Rule 6 — a transient failure says when to come back

A response the caller is *expected* to retry must say how long to wait. Two statuses qualify, and both are wired:
Expand Down Expand Up @@ -186,11 +196,14 @@ Audited against the primary specs and against Stripe, GitHub, and Google's AIPs.

## Idempotency: at-most-once, not replay

`POST /workflows/{id}/execute` accepts `X-Run-Id`, a caller-supplied run identifier claimed through the `idempotency_key` table (`execution-id-claim.ts`). It is a **uniqueness claim, not an idempotency key**, and the distinction is deliberate and already published in the operation description:
`POST /workflows/{id}/execute` accepts `X-Run-Id` from API-key and OAuth callers; anonymous requests ignore it. It is a **uniqueness claim, not an idempotency key**:

- An available ID is claimed before execution starts.
- An already claimed ID returns **409** with `error.details.code: "RUN_ID_CONFLICT"`, the run id in `error.details.runId`, and an `X-Run-Id` response header. It never replays the earlier run's result. Get Workflow Run can retrieve an existing run, but a claim does not guarantee a retrievable run.
- IDs of runs that started remain reserved after their execution logs are deleted.
- An ambiguous enqueue can retain the claim indefinitely without creating a retrievable run. A **409** followed by **404** is an unresolved outcome, not proof that execution never started or that the ID will become reusable.

- First use wins and runs.
- Any reuse returns **409** with `error.details.code: "RUN_ID_CONFLICT"`, the run id in `error.details.runId`, and an `X-Run-Id` response header. It never replays the earlier run's result — the client recovers it by polling the runs resource.
- Claims are durable tombstones, so deleting execution logs cannot make an id reusable.
For an uncertain execution outcome, reuse the same run ID if retrying and check Get Workflow Run. Do not promise polling will eventually find a run. If the outcome cannot be verified, do not automatically restart with a fresh ID or an omitted header: either can start another execution. Failures before a run starts can release the claim, so phrase the conflict rule as an ID that is already claimed.

That makes the money path safe against double-execution **for callers that opt in**. What it is not: a Stripe-style `Idempotency-Key` that stores and replays the original status and body. Building that means a request fingerprint, a retention window, an in-flight-vs-completed distinction (the expired IETF draft would have these be 422 and 409 respectively), and somewhere to put a large synchronous execution body. It is a designed piece of work, not an increment — do not half-build it by aliasing the header name, which would invite clients written against Stripe semantics to treat our 409 as a hard failure.

Expand Down
1 change: 1 addition & 0 deletions .claude/rules/emcn-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ The menu surface intentionally diverges from the pill: `dropdown-menu.tsx` items
- **`ChipDatePicker`** — chip-styled date field.
- **`ChipTimePicker`** — minute-granular time sibling of `ChipDatePicker`, a `ChipInput` that leniently parses typed input (`9:47`, `947`, `2:05pm`, `14:30`), commits on Enter/blur, and re-renders the canonical `9:47 AM` label.
- **`DropdownMenu`** — the canonical context/action menu (Radix-backed). Not a chip, but the standard menu for command/action lists; reach for it instead of a hand-rolled popover. Its surface intentionally diverges from the chip pill (`text-small`, `gap-2`) — keep them distinct. For a pill that opens a value picker, use `ChipDropdown`/`ChipSelect` instead.
- **`useScrollEdges` + `scrollFadeClass` / `scrollFadeAttributes`** — the canonical scroll-region edge treatment. The hook reports which edges hide content (tracking scroll and resizes; pass the element itself, held in state, when the region mounts after its owner, e.g. inside a Radix portal); the class and attributes fade a fixed 12px band at an active edge only, so a list that fits or sits at its top is never fogged. A floating control over the top edge sets `--scroll-fade-inset` to its height. A region that scrolls sideways (a tab row, a chip strip) uses `useScrollEdges(ref, { axis: 'x' })` with `scrollFadeXClass`; the attributes helper is shared. Any divider beside the region belongs to the neighboring block (`border-b` above, `border-t` below), never to the masked element, and shows only while that edge is active. Never hand-roll a `mask-image` gradient for a scroll region.
- **`OverflowText`** — the canonical single-line overflow treatment for read-only human labels and titles. It owns `min-w-0`, fade-only clipping (never an ellipsis), the conditional 18px edge mask, and the full-value floating tooltip; consumers pass only layout/typography through `className`. `overflowTextClipClass` and `overflowTextFadeClass` are the complete base/faded treatments for the rare component that must own measurement itself; never pair either with `truncate`, `text-ellipsis`, or hover-time mask removal. Use `DropdownMenuItemLabel` for a menu label beside icons, checks, or actions. A non-editable `Combobox` passes the full visual value through `overlayLabel`; the combobox owns the visual overlay's fade and keeps its one accessible tooltip on the interactive layer. Keep ordinary `truncate` only for editable values, code/log/path content, dense or virtualized grids, and rich composite content that cannot supply a plain tooltip label. Multiline copy uses an intentional `line-clamp-*` treatment instead.

## Modal keyboard defaults
Expand Down
6 changes: 5 additions & 1 deletion .claude/rules/sim-styling.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ Use `DropdownMenuItemLabel` for a human label beside menu icons, checks, shortcu

Do not apply the fade universally to editable or mirrored input values, code, logs, paths, filenames that use intentional middle truncation, dense or virtualized grids, or a composite container that also holds icons/actions. Those keep their purpose-built overflow behavior. Multiline copy uses an intentional `line-clamp-*` treatment.

## Scroll Edges

A scroll region that can hide rows past an edge uses `useScrollEdges` with `scrollFadeClass` + `scrollFadeAttributes` from `@sim/emcn`: a 12px fade at an edge only while content is hidden beyond it, never at rest. The region's baseline padding lives on the scroll box itself (so rows pass through it under the fade), and the divider at that edge is drawn by the neighboring block, conditional on the same edge. Never hand-roll a `mask-image` gradient or a `scrollTop > 0` effect for this.

## Font Weight

Three steps, Tailwind's stock scale, nothing else: **`font-normal` (400)**, **`font-medium` (500)**, **`font-semibold` (600)**. 400 is the document default, so body text, chip labels, sidebar items, and headings carry **no weight class at all** — they inherit. Reach for a class only to step *up* from body.
Expand All @@ -70,7 +74,7 @@ Headings inherit their weight. Tailwind preflight resets `h1`–`h6` to `font-we

## Color Tokens

Value text `--text-body`; muted/placeholder/labels `--text-muted`; icons `--text-icon`; neutral borders and dividers `--border` (`--border-1` and `--border-muted` are legacy aliases resolving to it; `--divider` is retired); surfaces `--surface-5` (light) / `--surface-4` (dark); active row `--surface-active`; error `--text-error`. No focus rings on chip surfaces.
Value text `--text-body`; muted/placeholder/labels `--text-muted`; icons `--text-icon`; progress and completion (a checked step, a done state) `--brand-blue` — `--selection` stays the interactive highlight; neutral borders and dividers `--border` (`--border-1` and `--border-muted` are legacy aliases resolving to it; `--divider` is retired); surfaces `--surface-5` (light) / `--surface-4` (dark); active row `--surface-active`; error `--text-error`. No focus rings on chip surfaces.

### Line weight

Expand Down
Loading
Loading