agentskills.codes
LU

lucid-extensions

**Note:** This skill explicitly excludes Custom Shapes and Formulas functionality.

Install

mkdir -p .claude/skills/lucid-extensions && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/14572" && unzip -o skill.zip -d .claude/skills/lucid-extensions && rm skill.zip

Installs to .claude/skills/lucid-extensions

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

**Note:** This skill explicitly excludes Custom Shapes and Formulas functionality.
82 chars · catalog descriptionno explicit “when” trigger

About this skill

Lucid Extension Development Skill

Overview

This skill provides comprehensive guidance for building Lucid Extension Packages using the Lucid Extension API. It covers editor extensions, data connectors, OAuth providers, link unfurling, and Lucid Cards integrations for Lucidchart and Lucidspark.

Note: This skill explicitly excludes Custom Shapes and Formulas functionality.

Table of Contents

  1. Getting Started
  2. Extension Package Structure
  3. Editor Extensions
  4. Data Connectors
  5. OAuth Configuration
  6. Link Unfurling
  7. Lucid Cards
  8. Testing & Debugging
  9. Publishing
  10. Best Practices

Getting Started

Prerequisites

  1. Unlock Developer Tools: Access to the Developer Menu and Developer Portal

    • For Team/Enterprise accounts: Enable through user settings or contact admin
    • Developer tools required to test and distribute extensions
    • Not needed to use published extensions from Lucid Marketplace
  2. Required Tools:

    • Node.js and npm installed
    • lucid-package CLI: npm install lucid-package
    • lucid-extension-sdk: Automatically installed with package creation
  3. Important Resources:

Creating a New Extension Package

# Create a new extension package
npx lucid-package@latest create

# Follow the prompts to configure:
# - Package name
# - Extension type (editor extension, data connector, etc.)
# - Target products (Lucidchart, Lucidspark, or both)

The CLI will generate a complete package structure with:

  • manifest.json - Package configuration
  • editorextensions/ - Editor extension code
  • data-connectors/ - Data connector implementations (optional)
  • TypeScript configurations
  • Webpack configuration

Extension Package Structure

Manifest File (manifest.json)

The manifest is the central configuration file for your extension package:

{
  "id": "your-package-uuid-from-developer-portal",
  "version": "1.0.0",
  "extensions": [
    {
      "name": "my-editor-extension",
      "title": "My Editor Extension",
      "products": ["chart", "spark"],
      "codePath": "editorextensions/my-editor-extension/bin/extension.js",
      "scopes": [
        "READ",
        "WRITE",
        "SHOW_MODAL",
        "CUSTOM_UI",
        "NETWORK"
      ]
    }
  ],
  "oauthProviders": [],
  "dataConnectors": []
}

Key Manifest Fields

Package Level:

  • id: UUID from Developer Portal (get after creating application)
  • version: Semantic version (must increment for each upload)

Extension Entry:

  • name: Internal identifier (matches folder name)
  • title: User-facing display name
  • products: Array of ["chart", "spark", "teamspaces"]
  • codePath: Path to compiled JavaScript entry point
  • scopes: Permission scopes required

Directory Structure

my-extension-package/
├── manifest.json
├── editorextensions/
│   └── my-extension/
│       ├── src/
│       │   ├── extension.ts          # Entry point
│       │   └── importmodal.ts        # Example modal
│       ├── resources/
│       │   ├── import.html           # Modal HTML
│       │   └── resource.d.ts         # Resource types
│       ├── public/                   # Static assets (served via URL)
│       ├── bin/                      # Compiled output
│       ├── package.json
│       ├── tsconfig.json
│       └── webpack.config.js
├── data-connectors/                  # Optional
│   └── my-connector/
│       ├── actions/                  # Action handlers
│       ├── src/
│       │   └── index.ts
│       └── debug-server.ts
└── package.json

Editor Extensions

Core Concepts

Editor extensions run custom code directly inside Lucid editors, enabling:

  • Custom menus and actions
  • Data import and manipulation
  • Custom UI panels
  • Document automation
  • External API integration

Entry Point (extension.ts)

import {
  EditorClient,
  Menu,
  MenuType,
  Viewport,
  Panel,
  PanelLocation
} from 'lucid-extension-sdk';

// Initialize the editor client
const client = new EditorClient();
const menu = new Menu(client);
const viewport = new Viewport(client);

// Register custom actions
client.registerAction('my-action', async () => {
  const selection = viewport.getSelectedItems();
  // Perform operations on selected items
});

// Add menu items
menu.addDropdownMenuItem({
  label: 'My Custom Action',
  action: 'my-action',
  menuType: MenuType.Main
});

Permission Scopes

Scopes control what your extension can access. Always request minimum scopes needed.

ScopePurposeUse When
READRead document contentsAnalyzing shapes, reading data
WRITEModify document contentsCreating/updating shapes
DOWNLOADDownload document dataExporting content
SHOW_MODALDisplay modal dialogsUser interactions, forms
CUSTOM_UICreate custom panelsBuilding right-dock panels
NETWORKMake network requestsAPI calls, data fetching

Example scope configuration:

{
  "scopes": ["READ", "WRITE", "SHOW_MODAL", "NETWORK"]
}

Custom UI Panels

Create custom panels in the right dock or left toolbox:

import { Panel, PanelLocation, EditorClient } from 'lucid-extension-sdk';

class MyPanel extends Panel {
  constructor(client: EditorClient) {
    super(client, {
      title: 'My Panel',
      iconUrl: 'https://example.com/icon.png',
      location: PanelLocation.RightDock, // or PanelLocation.ContentDock
      url: 'public/panel.html' // Serve from public/ directory
    });
  }
}

// Create panel instance
const myPanel = new MyPanel(client);

Requirements:

  • Must add CUSTOM_UI scope to manifest
  • Can use HTML + JavaScript or React
  • Panel HTML can use iframe with relative URLs
  • Static assets go in public/ directory at package root

Modals

Display modal dialogs for user input:

import { Modal } from 'lucid-extension-sdk';

const modal = new Modal(client, {
  title: 'Import Data',
  url: 'public/import-modal.html',
  width: 600,
  height: 400
});

modal.show();

Working with Document Elements

Get selected items:

const selection = viewport.getSelectedItems();
for (const item of selection) {
  if (item instanceof BlockProxy) {
    // Work with shapes
    console.log(item.boundingBox);
  }
}

Create shapes:

const page = viewport.getCurrentPage();
const block = page?.addBlock({
  boundingBox: { x: 0, y: 0, w: 100, h: 100 },
  style: {
    fill: { color: '#ff0000' }
  }
});

Modify shapes:

block.setStyle({
  fill: { color: '#00ff00' },
  stroke: { color: '#0000ff', width: 2 }
});

Data Management

Create data collections:

const dataSource = client.getDataSourceProxy();
const collection = dataSource.addCollection('my-collection', {
  primaryKey: 'id',
  fields: [
    { name: 'id', type: 'string' },
    { name: 'title', type: 'string' },
    { name: 'status', type: 'string' }
  ]
});

// Add data items
collection.addItem({
  id: '1',
  title: 'Task 1',
  status: 'In Progress'
});

Link data to shapes:

block.shapeData.set('customField', 'value');
const value = block.shapeData.get('customField');

Data Connectors

When to Use Data Connectors

Use data connectors when you need:

  • Bidirectional sync between Lucid and external systems
  • Automatic updates from external data sources
  • Push changes from Lucid back to external systems
  • Server-side processing of data actions

Alternative: For simple data imports without bidirectional sync, use EditorClient.oauthXhr() directly in your editor extension.

Data Connector Architecture

Data connectors run on a separate server (not in the Lucid editor):

  1. Editor extension calls client.performDataAction()
  2. Lucid servers make POST request to your data connector
  3. Data connector processes request, fetches external data
  4. Data connector sends formatted data back to Lucid
  5. Lucid updates the document

Creating a Data Connector

# Create data connector
npm run create-data-connector my-connector

Manifest Configuration

{
  "dataConnectors": [
    {
      "name": "my-connector",
      "oauthProviderName": "my-oauth-provider",
      "callbackBaseUrl": "https://myserver.com/connector/",
      "dataActions": {
        "import": "import",
        "sync": "sync",
        "create": "create"
      }
    }
  ]
}

Fields:

  • name: Internal identifier
  • oauthProviderName: Associated OAuth provider for authentication
  • callbackBaseUrl: Base URL where your connector is hosted
  • dataActions: Maps action names to URL suffixes

Implementing Data Actions

Editor Extension Trigger:

client.performDataAction({
  dataConnectorName: 'my-connector',
  actionName: 'import',
  actionData: { requestedItems: ['id-1', 'id-2'] },
  asynchronous: true
});

Data Connector Handler (actions/import.ts):

import { DataConnectorClient } from 'lucid-extension-sdk';

export async function handleImport(
  request: DataAction,
  client: DataConnectorClient
) {
  const { actionData, oauthToken } = request;
  
  // Fetch data from external API using OAuth token
  const externalData = await fetchFromExternalAPI(
    oauthToken,
    actionData.requestedItems
  );
  
  // Transform to Lucid format
  const lucidData = transformData(externalData);
  
  // Send to Lucid
  await client.sendDataUpdate(request.dataUpda

---

*Content truncated.*

Search skills

Search the agent skills registry