用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/jeremylongshore/claude-code-plugins-plus-skills --skill lucidchart-sdk-patterns命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Implement user sign-up and sign-in flows with Clerk. Use when building authentication UI, customizing sign-in experience, or implementing OAuth social login. Trigger with phrases like "clerk sign-in", "clerk sign-up", "clerk login flow", "clerk OAuth", "clerk social login".
Implement session management and middleware with Clerk. Use when managing user sessions, configuring route protection, or implementing token refresh and custom JWT templates. Trigger with phrases like "clerk session", "clerk middleware", "clerk route protection", "clerk token", "clerk JWT".
Configure enterprise SSO, role-based access control, and organization management. Use when implementing SSO integration, configuring role-based permissions, or setting up organization-level controls. Trigger with phrases like "clerk SSO", "clerk RBAC", "clerk enterprise", "clerk roles", "clerk permissions", "clerk organizations".
正在显示 SKILL.md
基于 SOC 职业分类
| name | lucidchart-sdk-patterns |
| description | Sdk Patterns for Lucidchart. Trigger: "lucidchart sdk patterns". |
| allowed-tools | Read, Write, Edit |
| version | 1.7.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
| tags | ["saas","lucidchart","diagramming"] |
| compatibility | Designed for Claude Code |
Lucid's REST API uses OAuth 2.0 with versioned Lucid-Api-Version headers to manage documents, pages, shapes, data-linked fields, and collaborative comments. A structured SDK client is essential because the API requires version negotiation on every request, returns deeply nested shape tree hierarchies, and enforces document-level locking for concurrent edits. These patterns provide OAuth token lifecycle management, typed shape and document models, fluent query building for filtered shape searches, and mock factories for diagramming test scenarios.
LUCID_CLIENT_ID and LUCID_CLIENT_SECRET environment variables (OAuth 2.0 app credentials)LUCID_ACCESS_TOKEN or refresh token flow for per-user accessaxios or node-fetch for HTTP transportinterface LucidConfig {
clientId: string;
clientSecret: string;
accessToken: string;
apiVersion?: string;
baseUrl?: string;
}
let client: LucidClient | null = null;
export function getLucidClient(overrides?: Partial<LucidConfig>): LucidClient {
if (!client) {
const config: LucidConfig = {
clientId: process.env.LUCID_CLIENT_ID ?? '',
clientSecret: process.env.LUCID_CLIENT_SECRET ?? '',
accessToken: process.env.LUCID_ACCESS_TOKEN ?? '',
apiVersion: '2',
baseUrl: 'https://api.lucid.co',
...overrides,
};
if (!config.accessToken) throw new Error('LUCID_ACCESS_TOKEN is required');
client = new (config);
}
client;
}
interface LucidApiError { status: number; errorCode: string; message: string; documentId?: string; }
async function safeLucid<T>(fn: () => Promise<T>): Promise<T> {
try { return await fn(); }
catch (err: any) {
const parsed: LucidApiError = {
status: err.response?.status ?? 500,
errorCode: err.response?.data?.errorCode ?? 'INTERNAL',
message: err.response?.data?.message ?? err.message,
documentId: err.response?.data?.documentId,
};
if (parsed.status === 429) {
const wait = parseInt(err.response?.headers?.['x-ratelimit-reset'] ?? '10', );
( (r, wait * ));
();
}
(parsed. === ) ();
(parsed. === ) ();
();
}
}
class ShapeQueryBuilder {
private params: Record<string, string> = {};
inDocument(docId: string) { this.params.documentId = docId; return this; }
onPage(pageId: string) { this.params.pageId = pageId; return this; }
ofType(shapeType: string) { this.params.className = shapeType; return this; }
withDataField(key: string, value: string) { this.params[`data.${key}`] = value; return this; }
limit(n: number) { this.params.limit = String(Math.(n, )); ; }
() { .. = (n); ; }
(): { (.); }
}
interface LucidDocument { id: string; title: string; editUrl: string; pageCount: number; lastModified: string; owner: string; }
interface LucidPage { id: string; title: string; index: number; width: number; height: number; }
interface LucidShape { id: string; className: string; boundingBox: { x: number; y: number; w: number; h: number }; text: string; dataFields: Record<string, string>; }
interface LucidComment { id: string; author: string; body: string; shapeId?: ; : ; : ; }
type Middleware = (req: RequestInit, next: () => Promise<Response>) => Promise<Response>;
const versionMiddleware: Middleware = (req, next) => {
req.headers = { ...req.headers as Record<string, string>, 'Lucid-Api-Version': '2' };
return next();
};
const oauthRefreshMiddleware = (refreshToken: string): Middleware => async (req, next) => {
const res = await next();
if (res.status === 401) {
const tokens = await refreshOAuthToken(refreshToken);
(req.headers as Record<string, string>).Authorization = `Bearer ${tokens.access_token}`;
return next();
}
return res;
};
function mockDocument(overrides?: Partial<LucidDocument>): LucidDocument {
return { id: 'doc_abc123', title: 'Architecture Diagram', editUrl: 'https://lucid.app/documents/edit/doc_abc123', pageCount: 3, lastModified: '2025-06-01T12:00:00Z', owner: 'user@example.com', ...overrides };
}
function mockShape(overrides?: Partial<LucidShape>): LucidShape {
return { id: 'shape_001', className: 'ProcessBlock', boundingBox: { x: 100, y: 50, w: 200, h: 100 }, text: 'API Gateway', dataFields: {}, ...overrides };
}
function mockComment(shapeId: string): LucidComment {
return { id: 'cmt_xyz', author: , : , shapeId, : , : };
}
| Pattern | When to Use | Example |
|---|---|---|
| Version negotiation | API returns 400 on outdated version header | Catch version mismatch, retry with server-suggested version |
| Document lock retry | 409 DOCUMENT_LOCKED during shape updates | Exponential backoff up to 3 retries, then surface to user |
| OAuth token refresh | 401 on any endpoint | Use refresh token middleware, update stored access token |
| Permission escalation | 403 on shared document operations | Check document sharing settings before write operations |
| Shape tree validation | Creating shapes with invalid parent references | Validate page and container IDs exist before shape POST |
Apply in lucidchart-core-workflow-a.