v0.6.96: pinned table columns, sequence number in copilot messages, tables UI improvements, new slack scopes, model-level denylists, object storage tracespans#4798
Conversation
* feat(tables): freeze columns * fix(tables): sticky meta-header row for frozen workflow groups, remove dead handleChangeType * fix(tables): scope frozenOffsets dep to frozen column widths only * fix(tables): restore frozenColumns on delete-column undo/redo * fix(tables): restore useMemo for isAllRowsSelected (O(n) computation) * fix(tables): use current frozenColumns on delete-column redo, not stale snapshot * fix(tables): clean up frozenColumns on create-column undo * fix(tables): merge frozen state on delete-column undo instead of overwriting * fix(tables): add previousFrozenColumns to test fixture for delete-column action * fix(tables): skip frozen state update on delete-column redo when column was not frozen * refactor(tables): rename frozen columns to pinned, fix sticky-zone UX - rename frozenColumns → pinnedColumns across types, contract, undo actions, grid state/refs/props, and dropdown labels - add Pin / PinOff emcn icons; use them in the column menu in place of Lock / Unlock - pinned body cells render at z-[6], above the cell selection border (z-[5]), so the blue selection border can't draw on top of the sticky-left zone - restrict column drag-reorder to within the pinned or unpinned zone in both handleColumnDragOver and handleScrollDragOver; cross-zone drop indicators are suppressed - on unpin, slide the column to the first unpinned slot so the sticky zone stays contiguous; consolidates pin and unpin into one branch that always re-enforces pinned-at-front Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(tables): biome formatting + tighten pinned-zone comments - collapse two onPinToggle JSX props that biome wanted on a single line - drop a WHAT comment in handleScrollDragOver; tighten the why-comments in handlePinToggle, handleColumnDragOver, and handleColumnDragEnd so they describe the invariant being protected instead of narrating the recent change Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(tables): re-sort reorder-columns undo to keep pinned-at-front If the user reordered, then pinned a column, then undid the reorder, the restored snapshot could leave a currently-pinned column in the middle of columnOrder. pinnedOffsets walks displayColumns left→right and assigns sticky `left` from checkboxColWidth — a pinned column in the middle gets a sticky offset as if it were at the front, causing it to jump over its left neighbors on horizontal scroll. Re-sort the restored order with pinned entries pulled to the front before applying. Mirrors the belt-and-suspenders re-sort in handleColumnDragEnd. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Theodore Li <theo@sim.ai> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(auth): block signup spam by denylisting shared MX backends Signup-spam bots rotate throwaway domains rapidly but funnel them through a small number of shared catch-all mail providers. Across the current wave, 85% of bot domains resolved to just two MX backends (smtp.215.im, email.gravityengine.cc), while every domain differed — so the resolved MX host is a far more durable signal than the domain itself. Add a server-only MX validator (validateSignupEmailMx) that resolves the domain's MX records during /sign-up/email and rejects: - domains with no MX record (no_mx) - domains whose MX backend is on the denylist (blocked_mx_backend) Seeded with the two observed backends; extend at runtime via BLOCKED_EMAIL_MX_HOSTS. Fail-open on DNS timeout/transient error so legitimate users are never blocked by a resolver blip; kill switch via DISABLE_SIGNUP_MX_VALIDATION. Returns a clean 403 (APIError), not a 500. * refactor(auth): make MX signup validation opt-in (SIGNUP_MX_VALIDATION_ENABLED) Aligns with the sibling feature SIGNUP_EMAIL_VALIDATION_ENABLED (disposable blocking via harmony), which is also opt-in. Default-off avoids adding a DNS dependency to the signup path and prevents surprise signup blocking on self-hosted deployments with non-standard mail setups (internal domains, or a too-broad MX entry catching legit shared infra like Cloudflare Email Routing). Enable on hosted/abuse-targeted deployments via SIGNUP_MX_VALIDATION_ENABLED; the flag doubles as the kill switch, so the separate DISABLE_ flag is removed. * fix(auth): clear MX-lookup timeout to avoid dangling timer on success * refactor(auth): remove hardcoded MX denylist defaults The MX-backend denylist is now entirely operator-supplied via BLOCKED_EMAIL_MX_HOSTS. Sim is open source, so no specific mail backends are named in the repo, the env example, or the tests — deployments configure their own list out of band (e.g. via secrets). The no-MX hygiene check is unchanged; with an empty denylist no backend is blocked.
…ng reads (#4791) copilot_messages had no column preserving message order: created_at (set from each message's timestamp) ties at millisecond granularity in 58% of chats, and some chats have out-of-order timestamps within their array. The only other tiebreaker, id, is a random UUID — so ORDER BY created_at, id renders same-timestamp user/assistant pairs swapped. This blocks the R+1 read cutover. Add an integer seq = the message's 0-based index within the chat's JSONB array (ground-truth order), backfilled inline in migration 0219 (no script for self-hosters or us). Reads will use ORDER BY seq NULLS LAST, created_at, id at cutover; reads still come from JSONB after this PR. Design: - seq is a tiebreaker, not the sole sort key (concurrent-append/NULL safety). - Nullable now; defer NOT NULL so rolling-deploy old pods don't fail inserts. - replace (update-messages snapshot) overwrites seq = array index (re-densifies after a mid-conversation delete); append preserves existing seq via COALESCE and assigns base+idx from a single MAX(seq) read (never MAX+i in SQL — multi-row batches would collide). The non-atomic read-then-insert window is documented and bounded by the read tiebreak + snapshot re-densify. - Dedupe message ids before insert (87 prod chats carry dup ids; a repeated id in one INSERT...ON CONFLICT would otherwise throw). - Backfill picks first-occurrence per (chat,id), gap-free via ROW_NUMBER; validated on staging data (0-based, contiguous, 0 bad ranges). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…xes (#4789) * fix(tables): resource-cell icons, embedded filters, run-count + queued fixes - table-grid: render in-workspace resource URLs (workflow/table/KB/file) as tagged-resource cells reusing ContextMentionIcon (colored square for workflows), matching @-mention chips; only the matching list is fetched. - table-grid: fix row-number sticky cell overflow — reserve the full run/stop button area (30px, not 16px) so wide row indices don't clip. - table-grid: show an infinite-scroll loading spinner while the next page loads instead of looking like the end of the table. - table: surface sort + filter (and run/stop via the options-bar extras slot) in the embedded mothership table resource view. - table-grid/utils: stop the dispatch overlay from optimistically painting autoRun=false cells Queued for auto-fire dispatches — the dispatcher skips those groups ('autoRun-off'); manual runs still show Queued (manual-bypass). - dispatcher: exclude orphan pre-stamps (pending + executionId null) from countRunningCells so the "X running" badge doesn't stick above zero. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(tables): single run/stop control, right-aligned row numbers, View-execution guard - table: de-duplicate the run/stop control in the embedded mothership view — drop TableGrid's own embedded run-status bar; it now lives only in the options bar (left-aligned next to Filter + Sort). Removes the orphaned RunStatusControl import + onStopAll/cancelRunsPending props. - data-row: right-align the row number within its box (hugs the right edge, no hover position jump) with a scaled right inset — 2px for ≤3-digit indices, 4px for 4+ so narrow columns don't look over-padded. - table-grid: require a real executionId in the action bar's canViewExecution flag so an error that never produced an execution (enqueue failure → status 'error', executionId null) doesn't offer "View execution". Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(tables): address review — drizzle operators for orphan filter, enabled flag for files query - dispatcher: replace the `not(and(...)) as SQL` cast in countRunningCells with `or(ne(status,'pending'), isNotNull(executionId))` — De Morgan equivalent, fully type-checked, no cast and no hand-written raw SQL. - workspace-files: add an `enabled` option to useWorkspaceFiles; sim-resource cell now passes the real workspaceId with `enabled` instead of '' so the query cache isn't polluted with an empty-key entry. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(tables): "X running" badge counts actual in-flight cells, not dispatch scope The badge derived from `runningCellCount` (the dispatch-scope estimate = rows-ahead × groupCount), which over-counts groups that already finished on rows still inside a dispatch's scope — a cascade where 3 of 4 workflow columns completed read "4 running" instead of "1". Derive `totalRunning` from the live `runningByRowId` map instead (the same per-row source the gutter and action-bar selection already sum), so it reflects cells actually in flight and updates per-cell via SSE rather than only on dispatch-window events. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* improvement(logs): obj storage backed tracespans * fix storage write context * fix tests * address comments * address comments * chore(db): remove migration 0219 to regenerate after staging merge Drops the 0219_robust_shard SQL, its snapshot, and the journal entry so the trace-spans/cost schema migration can be regenerated on top of the latest staging migration chain (avoids a number collision with staging's migrations). Co-authored-by: Cursor <cursoragent@cursor.com> * improvement(billing): accurate per-member usage via shared ledger helper Per-member/per-user usage in the org-member routes now adds the usage_log ledger to the currentPeriodCost baseline (which is no longer incremented), via a shared getOrgMemberLedgerByUser helper to avoid repeating the subscription→period→ledger lookup across the admin and member-facing routes. Co-authored-by: Cursor <cursoragent@cursor.com> * regen migrations * update migration * address comments * more code cleanup * incorrect type cast --------- Co-authored-by: Cursor <cursoragent@cursor.com>
#4796) * improvement(providers): harden OpenAI-compatible providers + add tests * fix(vllm): let tool-loop errors propagate instead of returning silent partial success * fix(litellm): force tool_choice 'none' on final structured-output call The deferred final call used tool_choice 'auto', so the model could emit another tool_calls round instead of the structured answer, leaving content stale. Use 'none' (matching vLLM/Fireworks) on both the streaming and non-streaming final calls so the model must return the structured response. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(providers/ollama): drop tools from post-tool streaming call Ollama ignores tool_choice (not in its supported fields), so vLLM/Fireworks' tool_choice:'none' guard is a no-op here. Omit tools from the final streaming payload instead so the summarization turn can't emit dropped tool calls. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(litellm): spread payload into deferred final call so reasoning_effort carries over The non-streaming deferred finalPayload hand-picked fields and dropped reasoning_effort (and any future payload field), diverging from the streaming path which spreads ...payload. Spread payload here too for consistency. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(providers/ollama): restore enrichment TSDoc block Keeps parity with sibling Chat Completions providers (cerebras/mistral/xai). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(fireworks): restore TSDoc on utils helpers Restore the TSDoc blocks on supportsNativeStructuredOutputs, createReadableStreamFromOpenAIStream, and checkForForcedToolUsage — TSDoc is the codebase documentation standard and should not have been stripped. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(litellm): remove inline rationale comments (codebase uses TSDoc) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(providers/ollama): drop orphaned enrichment TSDoc The block documented a function that now lives in trace-enrichment.ts, so it documents nothing in this file. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
* chore(copilot): deprecate mcp * update error codes * deprecate copilot api v1 route
PR SummaryHigh Risk Overview Copilot deprecation: Logs & billing data model: List, detail, export, v1, and workflow execution APIs read Product & policy: Model-level denylists surface as Reviewed by Cursor Bugbot for commit 704362d. Bugbot is set up for automated code reviews on this repo. Configure here. |
…4777) * feat(integrations): hosted API keys for Findymail, Prospeo, and Wiza Add hosted-key support across all credit-consuming Findymail, Prospeo, and Wiza operations so Sim provides the key when a workspace has not brought its own. Register the three BYOK providers, consolidate Wiza's two-step reveal into a single polling wiza_individual_reveal op, and hide the API key field on hosted Sim for hosted operations. * fix(integrations): harden Wiza reveal polling, soften enrichment getCost guards Address Greptile + Cursor Bugbot review on #4777: return explicit failures from the Wiza individual_reveal poller instead of throwing (thrown errors were swallowed into a false queued success), short-circuit when the initial reveal is already terminal, tolerate transient 5xx/429 during polling, and return 0 (not throw) from Findymail getCost when the contacts/employees array is absent. * chore(integrations): biome formatting after wiza merge resolution * fix(wiza): type isTerminalReveal param structurally for next build typecheck * feat(enrichments): add Findymail, Prospeo, Wiza to work-email waterfall * feat(enrichments): add Wiza + Prospeo phone reveal to phone-number waterfall * feat(enrichments): opportunistic identifiers + LinkedIn URL input across work-email & phone cascades
#4799) * feat(slack): add install + privacy section to integration landing page Adds a hand-authored, slug-keyed landing-content module (separate from the generated integrations.json so it survives regeneration) and renders an install walkthrough + privacy-policy link on integration pages when present. Also refreshes generated docs (data-enrichment entry, icon mappings, tool mdx). * fix(landing): render privacy section independently, align CTA analytics label * docs(landing): clarify the Slack install button is behind sign-in * refactor(landing): bake integration landing content into generated json via docs-gen Moves landing content (install walkthrough + privacy) out of a render-time augment and into the generation pipeline: generate-docs reads the pure-data content map and writes landingContent into integrations.json, so the page reads a single source (integration.landingContent). Canonical types live in integrations/data/types.ts.
#4801) * improvement(enrichments): align enrichments sidebar with design system * fix(enrichments): consistent close button pattern and fix url link hover
…ssue for workflow block agent usage (#4803) * fix(misc): upgrade path change for new better-auth version, double-billing for workflow block agent usage * fail loudly if stripe sub id missing
Uh oh!
There was an error while loading. Please reload this page.