Skip to content

Commit 103ff7c

Browse files
fix(mothership): hide preview-block-owned triggers from copilot VFS (#5676)
1 parent db2fb3c commit 103ff7c

1 file changed

Lines changed: 42 additions & 6 deletions

File tree

apps/sim/lib/copilot/vfs/workspace-vfs.ts

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,17 @@ let staticComponentFiles: Map<string, string> | null = null
156156
*/
157157
const integrationPathOwners = new Map<string, Pick<BlockConfig, 'type' | 'preview'>>()
158158

159+
/**
160+
* Owning block(s) for each `components/triggers/{provider}/{id}.json` file,
161+
* recorded at build time by inverting each block's `triggers.available`.
162+
* External-trigger paths are keyed on the trigger id + provider (not a block
163+
* type), so — like integration paths — they need this lookup for the stamp-time
164+
* visibility filter. A trigger can be reachable from more than one block (e.g. a
165+
* GA block and its preview successor), so this holds an array and the trigger is
166+
* hidden only when EVERY owning block is hidden.
167+
*/
168+
const triggerPathOwners = new Map<string, Array<Pick<BlockConfig, 'type' | 'preview'>>>()
169+
159170
/**
160171
* Per-request visibility filter for the shared static files: hides files whose
161172
* owning block is gated for this viewer (unrevealed preview blocks — the
@@ -168,6 +179,10 @@ function isStaticFileHidden(path: string, vis: BlockVisibilityState | null): boo
168179
const config = BLOCK_REGISTRY[blockMatch[1]!]
169180
return config ? isHiddenUnder(vis, config) : false
170181
}
182+
const triggerOwners = triggerPathOwners.get(path)
183+
if (triggerOwners) {
184+
return triggerOwners.length > 0 && triggerOwners.every((owner) => isHiddenUnder(vis, owner))
185+
}
171186
const owner = integrationPathOwners.get(path)
172187
return owner ? isHiddenUnder(vis, owner) : false
173188
}
@@ -353,6 +368,21 @@ function getStaticComponentFiles(): Map<string, string> {
353368
files.set(`components/triggers/sim/${block.type}.json`, serializeBuiltinTriggerSchema(block))
354369
}
355370

371+
// Attribute each external trigger to its owning block(s) by inverting
372+
// `triggers.available` — the same block-visibility rules that gate a block's
373+
// schema file then gate its triggers' schema files at stamp time.
374+
for (const block of allBlocks) {
375+
for (const triggerId of block.triggers?.available ?? []) {
376+
const trigger = TRIGGER_REGISTRY[triggerId]
377+
if (!trigger) continue
378+
const path = `components/triggers/${trigger.provider}/${triggerId}.json`
379+
const owners = triggerPathOwners.get(path)
380+
const owner = { type: block.type, preview: block.preview }
381+
if (owners) owners.push(owner)
382+
else triggerPathOwners.set(path, [owner])
383+
}
384+
}
385+
356386
let externalTriggerCount = 0
357387
for (const [triggerId, trigger] of Object.entries(TRIGGER_REGISTRY)) {
358388
const path = `components/triggers/${trigger.provider}/${triggerId}.json`
@@ -373,12 +403,18 @@ function getStaticComponentFiles(): Map<string, string> {
373403
provider: 'sim',
374404
description: b.description,
375405
})),
376-
Object.entries(TRIGGER_REGISTRY).map(([id, t]) => ({
377-
id,
378-
name: t.name,
379-
provider: t.provider,
380-
description: t.description,
381-
}))
406+
// Same for external triggers: a trigger owned solely by preview blocks is
407+
// hidden under the null (no-viewer) state this shared file is built with.
408+
Object.entries(TRIGGER_REGISTRY)
409+
.filter(
410+
([id, t]) => !isStaticFileHidden(`components/triggers/${t.provider}/${id}.json`, null)
411+
)
412+
.map(([id, t]) => ({
413+
id,
414+
name: t.name,
415+
provider: t.provider,
416+
description: t.description,
417+
}))
382418
)
383419
)
384420

0 commit comments

Comments
 (0)