Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
Task,
TerminalWindow,
Workflow,
Workspaces,
} from '@sim/emcn/icons'
import { AgentSkillsIcon, McpIcon } from '@/components/icons'
import { getDocumentIcon } from '@/components/icons/document-icons'
Expand Down Expand Up @@ -54,6 +55,10 @@ function renderIntegrationTile({ context, className }: RenderIconArgs): ReactNod
* without an icon.
*/
export const CHAT_CONTEXT_KIND_REGISTRY: Record<ChatContextKind, ChatContextKindConfig> = {
workspace: {
label: 'Workspace',
renderIcon: ({ className }) => <Workspaces className={className} />,
},
browser_tab: {
label: 'Browser tab',
renderIcon: ({ className }) => <Globe className={className} />,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,9 @@ export function useResourceTreeSections({
}

interface ResourceMenuSectionsProps {
flat?: boolean
/** Organization chat combines two selectable resource kinds under Files. */
combineFileFolders?: boolean
/** Foldered families, from {@link useResourceTreeSections}. */
sections: ResourceTreeSection[]
/** Every available family. Foldered ones are taken from `sections` instead. */
Expand All @@ -225,16 +228,21 @@ interface ResourceMenuSectionsProps {
* canonical order.
*/
export function ResourceMenuSections({
flat = false,
combineFileFolders = false,
sections,
groups,
onSelect,
subContentClassName,
}: ResourceMenuSectionsProps) {
const sectionByType = new Map(sections.map((section) => [section.type, section]))
const fileFolderItems = groups.find((group) => group.type === 'filefolder')?.items ?? []
const entries = groups
.filter(({ type, items }) =>
FOLDERED_RESOURCE_TYPES.has(type) ? sectionByType.has(type) : items.length > 0
)
.filter(({ type, items }) => {
if (combineFileFolders && type === 'filefolder') return false
if (combineFileFolders && type === 'file') return items.length + fileFolderItems.length > 0
return !flat && FOLDERED_RESOURCE_TYPES.has(type) ? sectionByType.has(type) : items.length > 0
})
.sort(byResourceMenuOrder)

return (
Expand All @@ -243,6 +251,13 @@ export function ResourceMenuSections({
const config = getResourceConfig(type)
const Icon = config.icon
const section = sectionByType.get(type)
const rows =
combineFileFolders && type === 'file'
? [
...fileFolderItems.map((item) => ({ type: 'filefolder' as const, item })),
...items.map((item) => ({ type: 'file' as const, item })),
]
: items.map((item) => ({ type, item }))

// The Browser and Terminal launchers are flat rows that open a new page
// or shell. Live pages and shells offered as context are an ordinary
Expand Down Expand Up @@ -275,12 +290,12 @@ export function ResourceMenuSections({
onSelect={onSelect}
/>
) : (
items.map((item) => (
rows.map(({ type: itemType, item }) => (
<DropdownMenuItem
key={`${item.workspaceId ?? ''}:${item.id}`}
onClick={() => onSelect(resourceFromItem(type, item))}
key={`${itemType}:${item.workspaceId ?? ''}:${item.id}`}
onClick={() => onSelect(resourceFromItem(itemType, item))}
>
{config.renderDropdownItem({ item })}
{getResourceConfig(itemType).renderDropdownItem({ item })}
{typeof item.workspaceName === 'string' && (
<span className='ml-auto text-[var(--text-muted)] text-xs'>
{item.workspaceName}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const CHIP_LINK_SCHEME = 'sim'
* no single portable id (an array / two ids / none) and degrade to plain text.
*/
const PORTABLE_KIND_TO_ID_FIELD = {
workspace: 'workspaceId',

@cubic-dev-ai cubic-dev-ai Bot Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This global addition lets organization workspace links become active contexts in ordinary workspace chats, where workspace-context processing is not supported and send-time errors are rethrown. Scope workspace-link rehydration to organization composers, or explicitly discard unsupported workspace links before sending.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/sim/app/workspace/[workspaceId]/home/components/user-input/components/chip-clipboard-codec.ts, line 26:

<comment>This global addition lets organization workspace links become active contexts in ordinary workspace chats, where workspace-context processing is not supported and send-time errors are rethrown. Scope workspace-link rehydration to organization composers, or explicitly discard unsupported workspace links before sending.</comment>

<file context>
@@ -23,6 +23,7 @@ const CHIP_LINK_SCHEME = 'sim'
  * no single portable id (an array / two ids / none) and degrade to plain text.
  */
 const PORTABLE_KIND_TO_ID_FIELD = {
+  workspace: 'workspaceId',
   table: 'tableId',
   file: 'fileId',
</file context>
Fix with cubic

table: 'tableId',
file: 'fileId',
folder: 'folderId',
Expand Down Expand Up @@ -235,6 +236,8 @@ export function parseChipLinks(text: string): ParsedChipLink[] {
*/
export function chipLinkToContext(link: ParsedChipLink): ChatContext {
switch (link.kind) {
case 'workspace':
return { kind: 'workspace', workspaceId: link.id, label: link.label }
case 'table':
return { kind: 'table', tableId: link.id, label: link.label }
case 'file':
Expand Down
Loading
Loading