Skip to content

feat(custom-blocks): add deploy_custom_block copilot tool#5532

Open
TheodoreSpeaks wants to merge 2 commits into
stagingfrom
feat/custom-block-mothership
Open

feat(custom-blocks): add deploy_custom_block copilot tool#5532
TheodoreSpeaks wants to merge 2 commits into
stagingfrom
feat/custom-block-mothership

Conversation

@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator

Summary

  • new deploy_custom_block copilot tool handler: the deploy agent can publish a deployed workflow as an org-wide custom block, update it in place (re-deploy upserts), or unpublish with action: undeploy
  • same gates as the REST routes: workspace admin via ensureWorkflowAccess, deploy-as-block flag, enterprise plan; audit events recorded with source: copilot
  • iconUrl accepts a workspace file VFS path (files/icon.png) — bytes are copied into the public workspace-logos context (key prefixed so the serve route treats it as public) so the icon renders org-wide; external URLs pass through
  • synced tool catalog from the copilot repo (adds DeployCustomBlock, regen formatting churn in tool-schemas-v1.ts is from the current generator)
  • new getCustomBlockWithInputsByWorkflowId operation + shared row-hydration helper

Companion PR on the copilot repo adds the tool definition, deploy agent wiring, prompts, and skill — this handler is inert until that ships.

Type of Change

  • New feature

Testing

Tested manually end-to-end via Chat (published a block with a generated icon, verified render + upsert). 13 unit tests on the handler incl. icon ingestion paths. lint, type-check, and check:api-validation:strict pass.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

The dependency was pinned to a direct tarball on cdn.sheetjs.com, which
now returns 403 (Cloudflare bot-challenge) to automated clients, breaking
bun install in CI. npm's own xlsx is frozen at 0.18.5, so switch to the
@e965/xlsx mirror which republishes the identical 0.20.3 CDN build to the
npm registry. No code changes needed — all imports use bare 'xlsx'.
@TheodoreSpeaks TheodoreSpeaks requested a review from a team as a code owner July 9, 2026 02:58
@vercel

vercel Bot commented Jul 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jul 9, 2026 2:58am

Request Review

@cursor

cursor Bot commented Jul 9, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Admin-gated publishing and enterprise/feature flags limit exposure, but the tool mutates org-visible custom blocks and copies workspace files into public icon storage—worth careful review of validation and access checks.

Overview
Adds a deploy_custom_block copilot tool so the deploy agent can publish a workflow as an org-wide custom block, update an existing publication, or unpublish via action: 'undeploy'.

The new executeDeployCustomBlock handler mirrors the REST publish path: admin workflow access, deploy-as-block feature flag, enterprise plan, and audit events tagged source: 'copilot'. First publish requires a name and an already API-deployed workflow; republish upserts through updateCustomBlock. iconUrl can be an external URL or a workspace VFS path (files/...), which is copied into public workspace-logos storage so icons render org-wide.

Generated copilot catalog/schemas gain DeployCustomBlock and the generic deploy tool prompt now mentions custom_block. getCustomBlockWithInputsByWorkflowId plus shared hydrateCustomBlockRow support lookup-by-workflow for the tool. Unit tests cover publish, update, undeploy, gates, and icon ingestion.

Also switches the xlsx dependency from a SheetJS CDN tarball to npm:@e965/xlsx@0.20.3 (lockfile only).

Reviewed by Cursor Bugbot for commit 8f9771b. Bugbot is set up for automated code reviews on this repo. Configure here.

@greptile-apps

greptile-apps Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds copilot support for deploying workflows as custom blocks. The main changes are:

  • New deploy_custom_block tool catalog and runtime schema entries.
  • New handler for publish, update, undeploy, audit, and icon ingestion flows.
  • New workflow-id lookup helper for hydrated custom-block rows.
  • Tests for the new handler paths.
  • xlsx dependency source changed to a pinned npm alias.

Confidence Score: 4/5

The custom-block deploy path needs a validation fix before merging.

  • The handler follows the expected access, feature-flag, plan, and audit flow.
  • The update and publish branches can persist unbounded inputs and exposedOutputs arrays.
  • The operation helper and handler registration match the surrounding patterns.

apps/sim/lib/copilot/tools/handlers/deployment/custom-block.ts

Important Files Changed

Filename Overview
apps/sim/lib/copilot/tools/handlers/deployment/custom-block.ts Adds the custom-block deploy handler, including access checks, audit events, update/delete paths, and icon ingestion.
apps/sim/lib/workflows/custom-blocks/operations.ts Extracts shared row hydration and adds lookup by workflow id.
apps/sim/lib/copilot/tool-executor/register-handlers.ts Registers the new custom-block deploy handler.
apps/sim/lib/copilot/generated/tool-catalog-v1.ts Adds the generated catalog entry for deploy_custom_block.
apps/sim/lib/copilot/generated/tool-schemas-v1.ts Adds the generated runtime schema entry for deploy_custom_block.
apps/sim/package.json Changes the xlsx package source to npm:@e965/xlsx@0.20.3.

Reviews (1): Last reviewed commit: "feat(custom-blocks): add deploy_custom_b..." | Re-trigger Greptile

Comment on lines +180 to +186
if (existing) {
await updateCustomBlock(existing.id, {
name,
description,
iconUrl,
inputs: params.inputs,
exposedOutputs: params.exposedOutputs,

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.

P1 Unbounded Outputs Persisted

When a tool call sends a large inputs or exposedOutputs array, this path passes it directly into the custom-block row. The REST custom-block contract caps these arrays, but this new copilot path skips that bound, so one call can persist an oversized block definition that slows or breaks org-wide block loading.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 8f9771b. Configure here.

iconUrl,
inputs: params.inputs,
exposedOutputs: params.exposedOutputs,
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Whitespace name clears block title

Medium Severity

On republish, name is trimmed and passed to updateCustomBlock even when the result is empty. updateCustomBlock only skips fields that are undefined, so an empty string overwrites the stored display name. The REST update contract rejects empty names with min(1); this handler does not.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 8f9771b. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant