diff --git a/.claude/rules/global.md b/.claude/rules/global.md index 3a222b935d5..f38e09d9b07 100644 --- a/.claude/rules/global.md +++ b/.claude/rules/global.md @@ -51,7 +51,10 @@ Use shared helpers from `@sim/utils` instead of writing inline implementations: - `structuredClone(value)` — built-in deep clone, no import needed. Never write `JSON.parse(JSON.stringify(obj))` - `omit(obj, keys)` from `@sim/utils/object` — remove keys from object - `filterUndefined(obj)` from `@sim/utils/object` — strip undefined-valued keys. Never write `Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined))` +- `isRecordLike(value)` from `@sim/utils/object` — indexable-object guard. Never redeclare `typeof value === 'object' && value !== null && !Array.isArray(value)` - `truncate(str, maxLength, suffix?)` from `@sim/utils/string` — safe string truncation with ellipsis +- `escapeRegExp(value)` from `@sim/utils/string` — escape regex metacharacters. Never inline `replace(/[.*+?^${}()|[\]\\]/g, '\\$&')` +- `compareStrings(left, right)` from `@sim/utils/string` — code-unit string comparator for hashes, fingerprints, and values compared across processes. Never `localeCompare` there - `backoffWithJitter(attempt, retryAfterMs, options?)` from `@sim/utils/retry` — exponential backoff with jitter - `parseRetryAfter(header)` from `@sim/utils/retry` — parse HTTP `Retry-After` header to milliseconds diff --git a/.claude/rules/sim-imports.md b/.claude/rules/sim-imports.md index 3aeafa0dd2e..6757ecc1d43 100644 --- a/.claude/rules/sim-imports.md +++ b/.claude/rules/sim-imports.md @@ -13,8 +13,8 @@ paths: ```typescript // ✓ Good +import { Chip } from '@sim/emcn' import { useWorkflowStore } from '@/stores/workflows/store' -import { Button } from '@/components/ui/button' // ✗ Bad import { useWorkflowStore } from '../../../stores/workflows/store' diff --git a/.cursor/rules/global.mdc b/.cursor/rules/global.mdc index 1bf193b00ec..052ceead52d 100644 --- a/.cursor/rules/global.mdc +++ b/.cursor/rules/global.mdc @@ -54,7 +54,10 @@ Use shared helpers from `@sim/utils` instead of writing inline implementations: - `structuredClone(value)` — built-in deep clone, no import needed. Never write `JSON.parse(JSON.stringify(obj))` - `omit(obj, keys)` from `@sim/utils/object` — remove keys from object - `filterUndefined(obj)` from `@sim/utils/object` — strip undefined-valued keys. Never write `Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined))` +- `isRecordLike(value)` from `@sim/utils/object` — indexable-object guard. Never redeclare `typeof value === 'object' && value !== null && !Array.isArray(value)` - `truncate(str, maxLength, suffix?)` from `@sim/utils/string` — safe string truncation with ellipsis +- `escapeRegExp(value)` from `@sim/utils/string` — escape regex metacharacters. Never inline `replace(/[.*+?^${}()|[\]\\]/g, '\\$&')` +- `compareStrings(left, right)` from `@sim/utils/string` — code-unit string comparator for hashes, fingerprints, and values compared across processes. Never `localeCompare` there - `backoffWithJitter(attempt, retryAfterMs, options?)` from `@sim/utils/retry` — exponential backoff with jitter - `parseRetryAfter(header)` from `@sim/utils/retry` — parse HTTP `Retry-After` header to milliseconds diff --git a/.cursor/rules/sim-imports.mdc b/.cursor/rules/sim-imports.mdc index 19da378bccf..95d111c7747 100644 --- a/.cursor/rules/sim-imports.mdc +++ b/.cursor/rules/sim-imports.mdc @@ -13,8 +13,8 @@ globs: ["apps/sim/**/*.ts","apps/sim/**/*.tsx"] ```typescript // ✓ Good +import { Chip } from '@sim/emcn' import { useWorkflowStore } from '@/stores/workflows/store' -import { Button } from '@/components/ui/button' // ✗ Bad import { useWorkflowStore } from '../../../stores/workflows/store' diff --git a/.github/workflows/test-build.yml b/.github/workflows/test-build.yml index a890cd09d0b..08d1305a6c0 100644 --- a/.github/workflows/test-build.yml +++ b/.github/workflows/test-build.yml @@ -149,6 +149,18 @@ jobs: KNOWLEDGE_ACL_TEST_DATABASE_URL: postgresql://postgres:postgres@127.0.0.1:5432/sim_auth_scim run: bunx vitest run --mode integration lib/workspace-files/search/dispatcher.integration.ts + - name: Verify workspace file version history on PostgreSQL 17 + working-directory: apps/sim + env: + KNOWLEDGE_ACL_TEST_DATABASE_URL: postgresql://postgres:postgres@127.0.0.1:5432/sim_auth_scim + run: bunx vitest run --mode integration lib/uploads/contexts/workspace/__integration__/file-versions.integration.ts + + - name: Verify file search trigram estimate against pg_trgm + working-directory: apps/sim + env: + KNOWLEDGE_ACL_TEST_DATABASE_URL: postgresql://postgres:postgres@127.0.0.1:5432/sim_auth_scim + run: bunx vitest run --mode integration lib/workspace-files/search/index-plan.integration.ts + - name: Verify SCIM and administration over real HTTP working-directory: apps/sim env: @@ -219,6 +231,8 @@ jobs: bunx vitest run lib/table/rows/secret-provenance.postgres.test.ts lib/memory/message-provenance.postgres.test.ts + lib/memory/conversation-store.postgres.test.ts + lib/memory/summary-store.postgres.test.ts executor/handlers/agent/memory-harness.postgres.test.ts - name: Verify Search vector projection upgrade in PostgreSQL @@ -229,6 +243,7 @@ jobs: bunx vitest run script-migrations/0016_backfill_search_vectors.postgres.test.ts script-migrations/0018_repair_workspace_file_content_revision.postgres.test.ts + script-migrations/0019_tin_keyword_projection.postgres.test.ts - name: Verify Search progress, pagination, and outbox scheduling in PostgreSQL working-directory: apps/sim @@ -246,6 +261,8 @@ jobs: lib/knowledge/__integration__/stored-document-recovery.integration.ts lib/knowledge/__integration__/connector-partition-work.integration.ts lib/knowledge/__integration__/listing-continuation.integration.ts + lib/knowledge/__integration__/member-scope-renewal.integration.ts + lib/knowledge/__integration__/slack-empty-threads.integration.ts lib/knowledge/__integration__/kb-block-search.integration.ts lib/core/outbox/service.integration.ts lib/knowledge/__integration__/connector-upload.integration.ts diff --git a/CLAUDE.md b/CLAUDE.md index 09dabbc5d78..bc41ebfae0c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -16,7 +16,10 @@ You are a professional software engineer. All code must follow best practices: a - `getErrorMessage(e, fallback?)` from `@sim/utils/errors` — extract message string from unknown caught value; never write `e instanceof Error ? e.message : 'fallback'` - `structuredClone(value)` — built-in deep clone; never `JSON.parse(JSON.stringify(...))` - `omit(obj, keys)` / `filterUndefined(obj)` from `@sim/utils/object` — object trimming; never `Object.fromEntries(Object.entries(...).filter(...))` + - `isRecordLike(value)` from `@sim/utils/object` — never redeclare `typeof value === 'object' && value !== null && !Array.isArray(value)` - `truncate(str, maxLength, suffix?)` from `@sim/utils/string` — never inline slice + ellipsis + - `escapeRegExp(value)` from `@sim/utils/string` — never inline `replace(/[.*+?^${}()|[\]\\]/g, '\\$&')` + - `compareStrings(left, right)` from `@sim/utils/string` — code-unit ordering for hashes, fingerprints, and cross-process comparisons; never `localeCompare` there - `backoffWithJitter(attempt, retryAfterMs, options?)` / `parseRetryAfter(header)` from `@sim/utils/retry` — shared retry pacing; never reimplement exponential backoff inline - **Deployment flags in the browser**: client code inside a workspace, organization, or standalone settings surface reads `hosted`, `billingEnabled`, `chatEnabled`, and the enterprise feature set through `useDeploymentShape()` (components) or `getDeploymentShape()` (block conditions, stores, helpers) from `@/lib/core/config/deployment-shape`, never `isHosted`/`isBillingEnabled`/... from `env-flags`. The constants freeze at module init from the root layout's `NEXT_PUBLIC_*` transport, which Next's bare 404 shell and `global-error` never emit; the reader is seeded from the server-resolved workspace host context, organization layout, or standalone settings layout instead. Server code keeps reading `env-flags` - **Package Manager**: Use `bun` and `bunx`, not `npm` and `npx` diff --git a/README.md b/README.md index f25af677768..5a186532d0c 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@
diff --git a/apps/desktop/src/main/ipc.ts b/apps/desktop/src/main/ipc.ts index 78038098bbc..50c3d64efd2 100644 --- a/apps/desktop/src/main/ipc.ts +++ b/apps/desktop/src/main/ipc.ts @@ -27,7 +27,7 @@ import { type TerminalToolArgs, } from '@sim/terminal-protocol' import { getErrorMessage } from '@sim/utils/errors' -import { isRecordLike } from '@sim/utils/object' +import { isRecordLike, toRecord } from '@sim/utils/object' import { PASTE_LIMITS, utf8ByteLength } from '@sim/utils/paste' import type { BrowserWindow, IpcMainEvent, IpcMainInvokeEvent, WebContents } from 'electron' import { clipboard, ipcMain, shell } from 'electron' @@ -856,7 +856,7 @@ export function registerIpcHandlers(deps: IpcDeps): void { ) { return { ok: false, error: `Unknown browser tool: ${String(tool)}` } } - const toolParams = isRecordLike(params) ? params : {} + const toolParams = toRecord(params) return executeTool( scope, tool, @@ -1532,7 +1532,7 @@ export function registerIpcHandlers(deps: IpcDeps): void { ) { return { ok: false, error: `Unknown terminal tool: ${String(tool)}` } } - const call = isRecordLike(params) ? params : {} + const call = toRecord(params) if (!isTerminalOperation(call.operation)) { return { ok: false, error: `Unknown terminal operation: ${String(call.operation)}` } } diff --git a/apps/desktop/src/main/local-filesystem.ts b/apps/desktop/src/main/local-filesystem.ts index 573f5a8cb88..edf226d4592 100644 --- a/apps/desktop/src/main/local-filesystem.ts +++ b/apps/desktop/src/main/local-filesystem.ts @@ -19,6 +19,7 @@ import { } from '@sim/desktop-bridge/local-filesystem-limits' import { generateId } from '@sim/utils/id' import { isRecordLike } from '@sim/utils/object' +import { escapeRegExp } from '@sim/utils/string' import { app, dialog, shell } from 'electron' import micromatch from 'micromatch' import safeRegex from 'safe-regex2' @@ -1114,7 +1115,7 @@ export class LocalFilesystemService { regex = rawPattern !== undefined ? new RegExp(expression, ignoreCase ? 'i' : '') - : new RegExp(expression.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), ignoreCase ? 'i' : '') + : new RegExp(escapeRegExp(expression), ignoreCase ? 'i' : '') } catch { // An empty result set would tell the model the string appears nowhere in // the user's files — a factual claim it will act on, when in truth the diff --git a/apps/docs/content/docs/academy/agents/memory.mdx b/apps/docs/content/docs/academy/agents/memory.mdx index 48a11d441d7..f8908ae383e 100644 --- a/apps/docs/content/docs/academy/agents/memory.mdx +++ b/apps/docs/content/docs/academy/agents/memory.mdx @@ -16,7 +16,9 @@ import { AV_MEMORY_WORKFLOW } from '@/components/workflow-preview/academy-video-
+
Paused at {formatDate(selectedDetail.pausePoint.registeredAt)}
+
{selectedDetail.pausePoint.automaticResumeWaitingReason}
-+
Sim will retry automatically.
+
{field.description}
)} @@ -922,7 +922,7 @@ export default function ResumeExecutionPage({ rows={6} /> ) : ( -+
No input data provided
)} @@ -963,7 +963,7 @@ export default function ResumeExecutionPage({+
No display data configured
+
{field.description}
)} diff --git a/apps/sim/app/(landing)/comparisons/[provider]/page.test.tsx b/apps/sim/app/(landing)/comparisons/[provider]/page.test.tsx index 6798b467cf9..0237f09be38 100644 --- a/apps/sim/app/(landing)/comparisons/[provider]/page.test.tsx +++ b/apps/sim/app/(landing)/comparisons/[provider]/page.test.tsx @@ -38,6 +38,7 @@ vi.mock('@/app/(landing)/comparisons/components/comparison-cards', () => ({ ComparisonCards: () => null, })) +import { escapeRegExp } from '@sim/utils/string' import type { Prose } from '@/lib/compare/data' import { dustProfile } from '@/lib/compare/data' import ComparisonProviderPage from '@/app/(landing)/comparisons/[provider]/page' @@ -64,7 +65,7 @@ function countMatches(markup: string, pattern: RegExp): number { * against the wrong anchor. */ function anchorWrapping(markup: string, text: string): string { - const escaped = text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + const escaped = escapeRegExp(text) return markup.match(new RegExp(`]*>${escaped}`))?.[0] ?? '' } diff --git a/apps/sim/app/(landing)/components/hero/components/hero-platform-loop/hero-resource-panel.tsx b/apps/sim/app/(landing)/components/hero/components/hero-platform-loop/hero-resource-panel.tsx index bb8d64f5d8f..cc03a9ae5b5 100644 --- a/apps/sim/app/(landing)/components/hero/components/hero-platform-loop/hero-resource-panel.tsx +++ b/apps/sim/app/(landing)/components/hero/components/hero-platform-loop/hero-resource-panel.tsx @@ -9,6 +9,7 @@ import { DropdownMenuItem, DropdownMenuTrigger, TabStrip, + TabStripAction, type TabStripItem, Tooltip, } from '@sim/emcn' @@ -25,7 +26,6 @@ import type { LeadRecord } from '@/app/(landing)/tables/components/tables-record import { TablesRecordsTable } from '@/app/(landing)/tables/components/tables-records-preview/tables-records-table' import { RESOURCE_HEADER_CLASSES, - RESOURCE_TAB_ICON_BUTTON_CLASS, RESOURCE_TAB_ICON_CLASS, resourceTabWidthClass, } from '@/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-tabs/resource-tab-controls' @@ -133,15 +133,14 @@ export function HeroResourcePanel({ activeId === 'workflow' ? (
+
{content}
No data to display
+No data to display
Saving paused: the file changed elsewhere. Your local draft is preserved. Reload replaces it diff --git a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/file-viewer.tsx b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/file-viewer.tsx index f8d82bf4e27..52407bbf750 100644 --- a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/file-viewer.tsx +++ b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/file-viewer.tsx @@ -327,7 +327,7 @@ const ReadOnlyTextPreview = memo(function ReadOnlyTextPreview({ return (
+
{content}
+
{definition}
Failed to preview PDF
-{error}
+{error}
No data to display
+No data to display
Preview not available{ext ? ` for .${ext} files` : ' for this file'}
-+
Use the download button to view this file
Failed to preview {label}
-{error}
+{error}
Failed to load file content
+Failed to load file content
+
{currentSheet.rowTruncated && currentSheet.columnTruncated
? `Showing first ${XLSX_MAX_ROWS.toLocaleString()} rows and ${XLSX_MAX_COLUMNS.toLocaleString()} columns.`
: currentSheet.rowTruncated
diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/browser-agent-icon.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/browser-agent-icon.tsx
index a3811b418cd..5bf1c53ac4d 100644
--- a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/browser-agent-icon.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/browser-agent-icon.tsx
@@ -4,7 +4,7 @@ import { useState } from 'react'
import { isBrowserToolName } from '@sim/browser-protocol'
import { cn } from '@sim/emcn'
import { Globe } from '@sim/emcn/icons'
-import { isRecordLike } from '@sim/utils/object'
+import { isRecordLike, toRecordOrNull } from '@sim/utils/object'
import { isBrowserAgentAvailable } from '@/lib/browser-agent/transport'
import { useChatSurface } from '@/app/workspace/[workspaceId]/home/components/chat-surface-context'
import type { AgentGroupItem } from '@/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/agent-group-view'
@@ -40,7 +40,7 @@ export function getBrowserAgentFaviconUrl(items: AgentGroupItem[]): string | nul
return typeof params?.url === 'string' ? pageFaviconUrl(params.url) : null
}
- const output = result?.success && isRecordLike(result.output) ? result.output : null
+ const output = result?.success ? toRecordOrNull(result.output) : null
if (output) {
if (isRecordLike(output.activeTab) && typeof output.activeTab.url === 'string') {
return pageFaviconUrl(output.activeTab.url)
diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/index.ts b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/index.ts
index 7f8d6ef3cdd..0e87649b7f8 100644
--- a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/index.ts
+++ b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/index.ts
@@ -4,4 +4,3 @@ export type {
NestedAgentGroup,
} from '@/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/agent-group-view'
export { isAgentGroupResolved } from '@/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/agent-group-view'
-export { CircleStop } from '@/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-call-item'
diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/inline-markdown.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/inline-markdown.tsx
index 591745ef329..c5c9dc03bfe 100644
--- a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/inline-markdown.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/inline-markdown.tsx
@@ -40,7 +40,7 @@ function renderToken(part: string, key: number): ReactNode {
}
if (part.length > 2 && part.startsWith('`') && part.endsWith('`')) {
return (
-
+
{part.slice(1, -1)}
)
diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-call-item.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-call-item.tsx
index 7d2bec15dd5..886243b9584 100644
--- a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-call-item.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-call-item.tsx
@@ -26,22 +26,6 @@ import { BrandIcon } from '@/blocks/brand-icon'
import { useCustomBlockOverlayVersion } from '@/blocks/custom/client-overlay'
import { getBlockByToolName } from '@/blocks/registry'
-export function CircleStop({ className }: { className?: string }) {
- return (
-
- )
-}
-
export interface ToolCallItemProps {
toolName: string
displayTitle: string
diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/index.ts b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/index.ts
index 07f0139dc83..0bbe8af07fb 100644
--- a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/index.ts
+++ b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/index.ts
@@ -1,5 +1,5 @@
export type { AgentGroupItem, NestedAgentGroup } from './agent-group'
-export { AgentGroup, CircleStop, isAgentGroupResolved } from './agent-group'
+export { AgentGroup, isAgentGroupResolved } from './agent-group'
export { ChatContent } from './chat-content'
export { MessageSources } from './message-sources'
export { Options } from './options'
diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/special-tags/special-tags.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/special-tags/special-tags.tsx
index c96110df49f..1ade562dc71 100644
--- a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/special-tags/special-tags.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/special-tags/special-tags.tsx
@@ -2,7 +2,14 @@
import { lazy, Suspense, useCallback, useEffect, useMemo, useState } from 'react'
import { cn, Expandable, ExpandableContent, SecretReveal, Tooltip, toast } from '@sim/emcn'
-import { ArrowRight, Check, ChevronDown, SquareArrowUpRight, TerminalWindow } from '@sim/emcn/icons'
+import {
+ ArrowRight,
+ Check,
+ ChevronDown,
+ Lock,
+ SquareArrowUpRight,
+ TerminalWindow,
+} from '@sim/emcn/icons'
import { isRecordLike } from '@sim/utils/object'
import { useParams } from 'next/navigation'
import { useSession } from '@/lib/auth/auth-client'
@@ -1986,24 +1993,6 @@ function getCredentialProviderDisplayName(provider: string): string {
)
}
-const LockIcon = (props: { className?: string }) => (
-
-)
-
/**
* Inline "paste a secret" widget rendered for
* ` {data.message} {data.message}
+
Some sites apply theme changes after a reload.
No results yet
+No results yet
+{entry.streamingArgs})} {!entry.streamingArgs && entry.result?.output != null && ( -+{typeof entry.result.output === 'string' ? entry.result.output : JSON.stringify(entry.result.output, null, 2)})} {entry.result?.error && ( -{entry.result.error}
+{entry.result.error}
)}
Open workflow
@@ -480,11 +472,10 @@ export function EmbeddedWorkflowActions({ workspaceId, workflowId }: EmbeddedWor{isExecuting ? 'Stop' : 'Run workflow'}
@@ -520,14 +511,13 @@ export function EmbeddedKnowledgeBaseActions({ return (Open knowledge base
@@ -562,14 +552,9 @@ function EmbeddedTableActions({ workspaceId, tableId }: EmbeddedTableActionsProp <>Open table
@@ -577,14 +562,13 @@ function EmbeddedTableActions({ workspaceId, tableId }: EmbeddedTableActionsPropExport CSV
@@ -639,14 +623,9 @@ function EmbeddedFileActions({ <>Open in files
@@ -654,15 +633,14 @@ function EmbeddedFileActions({Download
@@ -818,7 +796,7 @@ function EmbeddedFolder({ workspaceId, folderId }: EmbeddedFolderProps) {No workflows in this folder
+No workflows in this folder
) : (Open in logs
diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-tabs/resource-tab-controls.ts b/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-tabs/resource-tab-controls.ts index 43931efbff9..8507e6beafb 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-tabs/resource-tab-controls.ts +++ b/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-tabs/resource-tab-controls.ts @@ -1,10 +1,3 @@ -/** - * Icon-only controls in the resource header — add, preview mode, the per-resource - * actions — fill the tab strip's control band, so they match the strip's own - * new-tab button and the panel's collapse toggle and the header reads as one row. - */ -export const RESOURCE_TAB_ICON_BUTTON_CLASS = 'size-[var(--tab-strip-band,30px)] shrink-0 p-0' - export const RESOURCE_TAB_ICON_CLASS = 'size-[16px] text-[var(--text-icon)]' /** Shared geometry for the resource header and controls positioned over it. */ diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-tabs/resource-tabs.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-tabs/resource-tabs.tsx index 71f94b3b37b..e3f73406f8c 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-tabs/resource-tabs.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-tabs/resource-tabs.tsx @@ -10,9 +10,9 @@ import { useState, } from 'react' import { - Button, cn, TabStrip, + TabStripAction, type TabStripDragContext, type TabStripItem, type TabStripSelectionSource, @@ -41,7 +41,6 @@ import { useTerminalCloseConfirmation } from '@/app/workspace/[workspaceId]/home import { getResourceConfig } from '@/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-registry' import { RESOURCE_HEADER_CLASSES, - RESOURCE_TAB_ICON_BUTTON_CLASS, RESOURCE_TAB_ICON_CLASS, resourceTabWidthClass, } from '@/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-tabs/resource-tab-controls' @@ -545,14 +544,13 @@ export function ResourceTabs({ previewMode && onCyclePreviewMode ? ({PREVIEW_MODE_LABELS[previewMode]}
diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/user-input/components/drop-overlay/drop-overlay.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/user-input/components/drop-overlay/drop-overlay.tsx index de2e1b93d9b..d281ad48d0b 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/user-input/components/drop-overlay/drop-overlay.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/user-input/components/drop-overlay/drop-overlay.tsx @@ -34,7 +34,7 @@ export const DropOverlay = memo(function DropOverlay({ imagesOnly = false }: Dro return (No variable assignments defined
Add variables in the Variables panel to get started
diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/workspace-folder-selector/workspace-folder-selector.test.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/workspace-folder-selector/workspace-folder-selector.test.tsx
index a4ce92a823d..54d0fc6d600 100644
--- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/workspace-folder-selector/workspace-folder-selector.test.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/workspace-folder-selector/workspace-folder-selector.test.tsx
@@ -20,7 +20,7 @@ vi.mock('next/navigation', () => ({
}))
vi.mock('@sim/emcn', () => ({
- ChipCombobox: ({
+ Combobox: ({
options,
disabled,
isLoading,
diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/workspace-folder-selector/workspace-folder-selector.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/workspace-folder-selector/workspace-folder-selector.tsx
index 45e74f7074e..bf16b037dca 100644
--- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/workspace-folder-selector/workspace-folder-selector.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/workspace-folder-selector/workspace-folder-selector.tsx
@@ -1,7 +1,7 @@
'use client'
import { useMemo } from 'react'
-import { ChipCombobox } from '@sim/emcn'
+import { Combobox } from '@sim/emcn'
import { useParams } from 'next/navigation'
import type { FolderResourceType } from '@/lib/api/contracts/folders'
import { parseFolderPath } from '@/lib/folders/paths'
@@ -58,7 +58,7 @@ export function WorkspaceFolderSelector({
}, [folders, isPlaceholderData, required, subBlock.multiSelect, subBlock.placeholder])
return (
-
- {installationId - ? 'Approve the updated permissions for' - : 'Choose your workspace and approve'}{' '} - {name} in Slack. -
+ {step === 'token' && ( + <> ++ Copy the Bot User OAuth Token from OAuth & Permissions in your installed Slack + app. If Slack requests updated permissions, approve them there first. +
+Must be a valid hex color (e.g. #33c482) @@ -288,17 +250,13 @@ function WhitelabelingForm({ initialSettings, orgId, uploadWorkspaceId }: Whitel >