v0.8.18: table ttls, perf improvements, egress management, desktop app improvements, tools APIs, permission groups enhancements, sailpoint integration, files keyword search by waleedlatif1 · Pull Request #7381 · simstudioai/sim · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
62d0800
fix(credential-groups): stop requiring a human subject on workflow op…
TheodoreSpeaks Aug 29, 2026
4e78409
feat(function): mount referenced files into the code sandbox (#7251)
icecrasher321 Aug 29, 2026
bc07d2d
feat(admin): move a workspace between organizations (#7254)
mzxchandra Aug 29, 2026
d7c9f51
feat(library): AI Agents for Marketing Automation: Building Agentic W…
icecrasher321 Aug 29, 2026
95d1969
fix(provenance): let a run that never started report why it failed (#…
icecrasher321 Aug 29, 2026
f607c01
feat(billing): track E2B and Daytona Function sandbox usage (#7184)
BillLeoutsakosvl346 Aug 29, 2026
029ded6
refactor(tables): add column type extension points (#7119)
j15z Aug 29, 2026
7353b7c
feat(tables): add automatic row expiration with TTL (#7071)
j15z Aug 29, 2026
674ca8d
fix(timezone): consolidate table wall-clock conversion (#7072)
j15z Aug 29, 2026
f8f2d5f
feat(tables): trigger workflows on row deletes (#7161)
j15z Aug 29, 2026
2b00d96
fix(elasticsearch): resolve Cloud IDs to the real host and correct th…
waleedlatif1 Aug 30, 2026
c53837f
improvement(integrations): refresh Slack integration page SEO copy (#…
waleedlatif1 Aug 30, 2026
4851ae3
fix(helm): bump chart appVersion to the release it ships with (#7285)
waleedlatif1 Aug 30, 2026
cd42dce
fix(charts): strip ECharts navigation sinks from .chart documents (#7…
waleedlatif1 Aug 30, 2026
553849a
fix(sandbox): spend each file ceiling once across every source (#7288)
icecrasher321 Aug 30, 2026
faec125
fix(admin): report a completed workspace move's true source and its c…
icecrasher321 Aug 30, 2026
a996881
feat(files): add workspace content search (#7289)
icecrasher321 Aug 31, 2026
ba3cf4d
fix(files): dispatch search indexing from Trigger workers (#7293)
icecrasher321 Aug 31, 2026
27d7926
feat(library): Best AI Agents for Lead Enrichment in 2026 (#7292)
icecrasher321 Aug 31, 2026
ddab4a9
fix(github): wire the block fields whose ids do not match their tool …
waleedlatif1 Aug 31, 2026
f41e27a
fix(tables): harden timezone and expiration handling (#7291)
j15z Aug 31, 2026
eefbb20
fix(tables): run workflow groups from deployments (#7240)
TheodoreSpeaks Aug 31, 2026
b19553e
feat(files): add an overwrite option to file write (#7295)
TheodoreSpeaks Aug 31, 2026
d99fe97
fix(connectors): keep rate limits out of failure breaker (#7302)
waleedlatif1 Aug 31, 2026
9b0c62f
fix(chat): scope selection clipboard chips to workspace (#7298)
BillLeoutsakosvl346 Aug 31, 2026
2a8fa38
fix(workflows): authorize paused execution reads (#7303)
waleedlatif1 Aug 31, 2026
f3fb445
fix(incidentio): align declared outputs and enum hints with the v2 AP…
waleedlatif1 Aug 31, 2026
bd49a7e
fix(okta): describe each user param the way its endpoint accepts it (…
waleedlatif1 Aug 31, 2026
158214a
fix(github): make branch protection usable and wire workflow_id to it…
waleedlatif1 Aug 31, 2026
d6ef784
feat(sso): add safe member provisioning (#7309)
waleedlatif1 Aug 31, 2026
afccb72
fix(egress): unify SSRF/egress behind one policy with named provenanc…
waleedlatif1 Aug 31, 2026
27e4632
improvement(selectors): unify server-side selector execution (#7185)
BillLeoutsakosvl346 Aug 31, 2026
cb4a84d
improvement(ui): move secret visibility below description (#7315)
waleedlatif1 Aug 31, 2026
f9c22fd
fix(auth): revoke stale email share access (#7314)
waleedlatif1 Aug 31, 2026
70783dc
improvement(settings): accelerate navigation and data loading (#7299)
waleedlatif1 Aug 31, 2026
8e9aeb9
fix(executor): stop resolved data from breaking out of generated cond…
icecrasher321 Aug 31, 2026
b64a138
fix(settings): restore SSO recovery and lifecycle test isolation (#7317)
waleedlatif1 Aug 31, 2026
d8a6b6b
improvement(desktop): harden browser agent (#7311)
waleedlatif1 Aug 31, 2026
19e4570
chore(security): add proxy rate-limit regression coverage (#7318)
waleedlatif1 Aug 31, 2026
8309ad5
chore(copilot): sync mothership contracts (#7316)
j15z Aug 31, 2026
bd75254
feat(workspace): support GIF logos (#7322)
waleedlatif1 Sep 1, 2026
bd7995e
fix(selectors): normalize Bitbucket workspace UUIDs (#7320)
BillLeoutsakosvl346 Sep 1, 2026
04f7cd2
fix(notion): resolve custom page title properties (#7323)
BillLeoutsakosvl346 Sep 1, 2026
898ecdb
chore(analytics): remove Profound request tracking (#7326)
waleedlatif1 Sep 1, 2026
f4f1850
feat(library): Sim vs. Dedicated Chatbot Builders (#7325)
icecrasher321 Sep 1, 2026
616d5e9
fix(selectors): paginate HubSpot list options (#7327)
BillLeoutsakosvl346 Sep 1, 2026
e100c5a
fix(files): bound YAML expansion and buffered reads on the file-serve…
icecrasher321 Sep 1, 2026
e5e67b3
feat(circleback): add API tools, expanded block, and knowledge base c…
waleedlatif1 Sep 1, 2026
2173a70
feat(slack): add agent sessions and streaming (#7296)
TheodoreSpeaks Sep 1, 2026
fde8cf9
fix(cron): derive async job retention cutoffs from one clock read (#7…
TheodoreSpeaks Sep 1, 2026
8430f0f
fix(tables): make the agent tool picker version-aware and enrich the …
mzxchandra Sep 1, 2026
2598f44
fix(workflows): preserve contrast on gradient tiles (#7332)
waleedlatif1 Sep 1, 2026
507663f
fix(selectors): paginate SharePoint sites and lists (#7335)
BillLeoutsakosvl346 Sep 1, 2026
dcaaf8e
feat(sailpoint): add SailPoint (IGA) integration (#6092)
mzxchandra Sep 1, 2026
1c197c1
fix(selectors): paginate BigQuery resources (#7334)
BillLeoutsakosvl346 Sep 1, 2026
f2e20aa
fix(execution): stop treating the workflow owner as a live execution …
icecrasher321 Sep 1, 2026
27734f5
fix(webflow): paginate collection item selectors (#7337)
BillLeoutsakosvl346 Sep 1, 2026
b1b5de7
improvement(integrations): add Twilio SMS AEO content (#7342)
waleedlatif1 Sep 1, 2026
beef0ea
improvement(oauth): resolve credential tokens in-process instead of h…
waleedlatif1 Sep 1, 2026
694c34b
improvement(integrations): refine Slack AEO content (#7344)
waleedlatif1 Sep 1, 2026
1404e65
fix(slack): restore assistant operation compatibility (#7339)
TheodoreSpeaks Sep 1, 2026
48f72a2
feat(copilot): let Run agent cancel workflow runs (#7151)
j15z Sep 1, 2026
b4bc9b9
fix(sailpoint): complete integration validation (#7345)
waleedlatif1 Sep 1, 2026
fd061f5
improvement(deps): harden dependency graph (#7343)
waleedlatif1 Sep 1, 2026
4941c73
feat(streaming): support nested workflow outputs (#7346)
TheodoreSpeaks Sep 1, 2026
3de31cb
feat(slack): list DMs for managed credentials (#7349)
TheodoreSpeaks Sep 1, 2026
358af42
fix(docker): allow pruned lockfile normalization (#7350)
TheodoreSpeaks Sep 1, 2026
d7b31a8
feat(permission-groups): enforce every config key server-side (#7347)
waleedlatif1 Sep 1, 2026
36a4b6a
fix(canvas): repair React Flow v12 and dependency upgrade regressions…
waleedlatif1 Sep 1, 2026
9c35e18
fix(tool-input): render every tool param through the canonical sub-bl…
icecrasher321 Sep 1, 2026
349f40a
feat(sidebar): live workflow and folder registry updates via workspac…
waleedlatif1 Sep 1, 2026
11b10fb
fix(selectors): drain Snowflake result partitions (#7357)
BillLeoutsakosvl346 Sep 1, 2026
9d8d595
fix(cloudwatch): paginate log selectors (#7360)
BillLeoutsakosvl346 Sep 1, 2026
69d7266
fix(selectors): close residual cancellation gaps (#7358)
BillLeoutsakosvl346 Sep 1, 2026
4c20ff6
improvement(audits): eliminate repeated parsing and scans (#7361)
waleedlatif1 Sep 1, 2026
2ce2bec
chore(api): remove unused and superseded API routes (#7364)
waleedlatif1 Sep 1, 2026
83e5f5f
feat(library): Sim: The Open Source Zapier Alternative for AI Agents …
icecrasher321 Sep 1, 2026
e7cfef9
fix(selectors): paginate HubSpot owner options (#7359)
BillLeoutsakosvl346 Sep 1, 2026
f59c69f
fix(confluence): normalize space identifiers (#7324)
BillLeoutsakosvl346 Sep 1, 2026
df833ef
feat(ashby): expand hiring operations and webhooks (#7341)
waleedlatif1 Sep 1, 2026
d8ecc5b
perf(tests): cut per-file import graphs in apps/sim and shard the sui…
waleedlatif1 Sep 1, 2026
9acf0f8
perf(tests): drop dead upload-context re-exports and unify the CI dum…
waleedlatif1 Sep 1, 2026
23e1663
fix(deps): preserve runtime and canvas behavior (#7366)
waleedlatif1 Sep 1, 2026
1c2f708
chore(skills): teach babysit about cubic, not just Greptile (#7372)
icecrasher321 Sep 1, 2026
c43e842
fix(slack): paginate selector resources (#7362)
BillLeoutsakosvl346 Sep 1, 2026
e5a8852
feat(file): search workspace files by regular expression (#7370)
icecrasher321 Sep 1, 2026
78780c9
fix(selectors): expose incomplete loaded catalogs (#7338)
BillLeoutsakosvl346 Sep 2, 2026
150bff4
perf(tests): trim sweep, copilot, and timer-bound suites; run three C…
waleedlatif1 Sep 2, 2026
b2b4d0e
feat(models): add Claude Fable 5.1 and align Anthropic prompt-cache m…
waleedlatif1 Sep 2, 2026
4f42c61
feat(credential-groups): add event trigger (#7379)
TheodoreSpeaks Sep 2, 2026
452e542
feat(resources): remember list preferences (#7371)
j15z Sep 2, 2026
51d2118
feat(tools): run one integration tool over v2, and fix the ones that …
icecrasher321 Sep 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
refactor(tables): add column type extension points (#7119)
* refactor(tables): add column type extension points

* Address PR review feedback (#7119)

- preserve explicit nulls from source-owned conversion normalization
- normalize hooked values before select migration
- cover null and select conversion rewrites

* refactor(tables): short-circuit unlimited column types

* refactor(tables): keep CSV coercion in import switch

* test(tables): cover rebased column dropdown
  • Loading branch information
j15z authored Aug 29, 2026
commit 029ded66976b2c63d2ef7f031e4dcd0382d99b4e
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* @vitest-environment node
*/
import { afterEach, describe, expect, it } from 'vitest'
import { COLUMN_TYPE_REGISTRY } from '@/lib/table/column-types'
import {
COLUMN_TYPE_OPTIONS,
columnTypeOptionsForTable,
} from '@/app/workspace/[workspaceId]/tables/[tableId]/components/column-config-sidebar/column-types'

const option = COLUMN_TYPE_OPTIONS.find((candidate) => candidate.type === 'string')
if (!option) throw new Error('String column type option is missing')
const originalMaxPerTable = option.maxPerTable
const definition = COLUMN_TYPE_REGISTRY.string
const originalDefinitionMaxPerTable = definition.maxPerTable

afterEach(() => {
if (originalMaxPerTable === undefined) {
Reflect.deleteProperty(option, 'maxPerTable')
} else {
option.maxPerTable = originalMaxPerTable
}

if (originalDefinitionMaxPerTable === undefined) {
Reflect.deleteProperty(definition, 'maxPerTable')
} else {
Object.assign(definition, { maxPerTable: originalDefinitionMaxPerTable })
}
})

describe('column type picker limits', () => {
it('keeps a limited type visible but disables it once the limit is reached', () => {
option.maxPerTable = 1
Object.assign(definition, { maxPerTable: 1 })

const result = columnTypeOptionsForTable([{ name: 'first', type: 'string' }])
const stringOption = result.find((candidate) => candidate.type === 'string')

expect(stringOption?.disabledReason).toBe('Only one Text column allowed per table')
})

it('keeps the current type selectable while editing its existing column', () => {
option.maxPerTable = 1
Object.assign(definition, { maxPerTable: 1 })
const currentColumn = { name: 'first', type: 'string' } as const

const result = columnTypeOptionsForTable([currentColumn], currentColumn)
const stringOption = result.find((candidate) => candidate.type === 'string')

expect(stringOption?.disabledReason).toBeUndefined()
})
})
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import type React from 'react'
import { PlayOutline } from '@sim/emcn/icons'
import type { ColumnDefinition } from '@/lib/table'
import { ALL_COLUMN_TYPES } from '@/lib/table/column-types'
import { ALL_COLUMN_TYPES, wouldExceedColumnTypeLimit } from '@/lib/table/column-types'

/**
* UI-only column type. `'workflow'` is the virtual entry users pick from the
* "+ New column" dropdown to spawn a workflow group; the resulting columns are
* stored as scalar types under the hood (none carry `'workflow'`).
*/
type SidebarColumnType = ColumnDefinition['type'] | 'workflow'
export type SidebarColumnType = ColumnDefinition['type'] | 'workflow'

interface ColumnTypeOption {
export interface ColumnTypeOption {
type: SidebarColumnType
label: string
icon: React.ComponentType<{ className?: string }>
maxPerTable?: number
disabledReason?: string
}

/**
Expand All @@ -26,9 +28,35 @@ export const COLUMN_TYPE_OPTIONS: ColumnTypeOption[] = [
type: definition.id,
label: definition.label,
icon: definition.icon,
maxPerTable: definition.maxPerTable,
})),
{ type: 'workflow', label: 'Workflow', icon: PlayOutline },
]

/** Plain column types (no workflow). Used by `<ColumnConfigSidebar>`'s type combobox in edit mode. */
export const PLAIN_COLUMN_TYPE_OPTIONS = COLUMN_TYPE_OPTIONS.filter((o) => o.type !== 'workflow')
/** Plain column types (no workflow). Used by the column type combobox in edit mode. */
export const PLAIN_COLUMN_TYPE_OPTIONS = COLUMN_TYPE_OPTIONS.filter(
(option) => option.type !== 'workflow'
)

function columnTypeLimitMessage(label: string, maxPerTable: number): string {
return maxPerTable === 1
? `Only one ${label} column allowed per table`
: `Only ${maxPerTable} ${label} columns allowed per table`
}

/** Picker entries with unavailable cardinality-limited types marked as disabled. */
export function columnTypeOptionsForTable(
columns: readonly ColumnDefinition[],
currentColumn?: ColumnDefinition | null
): ColumnTypeOption[] {
return COLUMN_TYPE_OPTIONS.map((option) => {
if (option.type === 'workflow') return option
if (currentColumn?.type === option.type) return option
if (option.maxPerTable === undefined) return option
if (!wouldExceedColumnTypeLimit(columns, option.type, 1)) return option
return {
...option,
disabledReason: columnTypeLimitMessage(option.label, option.maxPerTable),
}
})
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
export type { ColumnConfig } from './column-config-sidebar'
export { ColumnConfigSidebar } from './column-config-sidebar'
export { COLUMN_TYPE_OPTIONS, PLAIN_COLUMN_TYPE_OPTIONS } from './column-types'
export {
COLUMN_TYPE_OPTIONS,
type ColumnTypeOption,
columnTypeOptionsForTable,
PLAIN_COLUMN_TYPE_OPTIONS,
type SidebarColumnType,
} from './column-types'
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ describe('ColumnDropdown', () => {
act(() => {
root.render(
<ColumnDropdown
columns={[]}
trigger='header'
disabled={false}
onPickType={vi.fn()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,17 @@ import {
DropdownMenuItem,
DropdownMenuTrigger,
Plus,
Tooltip,
} from '@sim/emcn'
import { Sparkles } from '@sim/emcn/icons'
import type { ColumnDefinition } from '@/lib/table'
import { COLUMN_TYPE_OPTIONS } from '../column-config-sidebar'
import { type ColumnTypeOption, columnTypeOptionsForTable } from '../column-config-sidebar'

const CELL_HEADER =
'border-[var(--border)] border-r border-b bg-[var(--bg)] px-2 py-[7px] text-left align-middle'

interface ColumnDropdownProps {
columns: readonly ColumnDefinition[]
/** `'header'` renders the page-header trigger (subtle Button); `'inline-header'` renders
* the in-table column-header `<th>` trigger. Same dropdown content either way. */
trigger: 'header' | 'inline-header'
Expand All @@ -36,12 +38,49 @@ interface ColumnDropdownProps {
onBlocked: () => void
}

interface ColumnTypeMenuItemProps {
option: ColumnTypeOption
onSelect: () => void
}

function ColumnTypeMenuItem({ option, onSelect }: ColumnTypeMenuItemProps) {
const Icon = option.icon
const item = (
<DropdownMenuItem
aria-disabled={option.disabledReason ? true : undefined}
className={
option.disabledReason ? 'cursor-not-allowed opacity-50 focus:bg-transparent' : undefined
}
onSelect={(event) => {
if (option.disabledReason) {
event.preventDefault()
return
}
onSelect()
}}
>
<Icon className='size-[14px] text-[var(--text-icon)]' />
{option.label}
</DropdownMenuItem>
)

if (!option.disabledReason) return item

return (
<Tooltip.Root>
<Tooltip.Trigger asChild>{item}</Tooltip.Trigger>
<Tooltip.Content>{option.disabledReason}</Tooltip.Content>
</Tooltip.Root>
)
}

/**
* "+ New column" dropdown — the single entry point for creating a column.
* Lists every column type plus "Workflow" and "Enrichments"; picking a type
* opens the right sidebar pre-seeded.
*/
export function ColumnDropdown({
columns,
trigger,
disabled,
onPickType,
Expand Down Expand Up @@ -86,18 +125,12 @@ export function ColumnDropdown({
<DropdownMenu>
<DropdownMenuTrigger asChild>{triggerButton}</DropdownMenuTrigger>
<DropdownMenuContent align='start' side='bottom' sideOffset={4}>
{COLUMN_TYPE_OPTIONS.map((option) => {
const Icon = option.icon
{columnTypeOptionsForTable(columns).map((option) => {
const onSelect =
option.type === 'workflow'
? onPickWorkflow
: () => onPickType(option.type as ColumnDefinition['type'])
return (
<DropdownMenuItem key={option.type} onSelect={onSelect}>
<Icon className='size-[14px] text-[var(--text-icon)]' />
{option.label}
</DropdownMenuItem>
)
return <ColumnTypeMenuItem key={option.type} option={option} onSelect={onSelect} />
})}
<DropdownMenuItem onSelect={onPickEnrichment}>
<Sparkles className='size-[14px] text-[var(--text-icon)]' />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4864,6 +4864,7 @@ export function TableGrid({
})}
{userPermissions.canEdit && (
<ColumnDropdown
columns={columns}
trigger='inline-header'
disabled={addColumnMutation.isPending}
blocked={!canMutateSchema}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1373,6 +1373,7 @@ export function Table({
const canMutateSchema = userPermissions.canEdit && !tableData?.locks.schemaLocked
const createTrigger = userPermissions.canEdit ? (
<ColumnDropdown
columns={columns}
trigger='header'
disabled={false}
blocked={!canMutateSchema}
Expand Down Expand Up @@ -1645,6 +1646,7 @@ export function Table({
<ColumnConfigSidebar
config={columnConfig}
onClose={onCloseSlideout}
allColumns={columns}
existingColumn={
columnConfig?.mode === 'edit'
? (columns.find((c) => getColumnId(c) === columnConfig.columnName) ?? null)
Expand Down
79 changes: 79 additions & 0 deletions apps/sim/lib/table/column-types/extension-points.test.ts
Loading