@symbo.ls/mcp 1.0.14 → 1.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,440 @@
1
+ # Symbols SDK Reference (`@symbo.ls/sdk`)
2
+
3
+ Official SDK for the Symbols design platform. Manage projects, collaborate in real-time, handle branches, pull requests, and more.
4
+
5
+ **Install:** `npm install @symbo.ls/sdk`
6
+ **Version:** 3.7.3
7
+
8
+ ---
9
+
10
+ ## Initialization
11
+
12
+ ```javascript
13
+ import { SDK } from '@symbo.ls/sdk'
14
+
15
+ const sdk = new SDK({
16
+ apiUrl: 'https://api.symbols.app',
17
+ socketUrl: 'https://api.symbols.app',
18
+ timeout: 30000,
19
+ retryAttempts: 3,
20
+ debug: false
21
+ })
22
+
23
+ await sdk.initialize({
24
+ authToken: 'your-auth-token',
25
+ appKey: 'your-app-key'
26
+ })
27
+ ```
28
+
29
+ ### SDK Instance Methods
30
+ - `sdk.initialize(context)` — initialize all services
31
+ - `sdk.getService(name)` — get a service instance
32
+ - `sdk.updateContext(context)` — update context for all services
33
+ - `sdk.isReady()` — check if SDK is initialized
34
+ - `sdk.getStatus()` — get status of all services
35
+ - `sdk.destroy()` — cleanup all services and resources
36
+
37
+ All service methods are also available as direct proxy methods on the SDK instance (e.g., `sdk.login()`, `sdk.getProjects()`).
38
+
39
+ ---
40
+
41
+ ## AuthService
42
+
43
+ Authentication, user management, and permissions.
44
+
45
+ ### Authentication
46
+ - `register(userData, options?)` — register new user
47
+ - `login(email, password, options?)` — login with email/password
48
+ - `logout()` — logout current user
49
+ - `refreshToken(refreshToken)` — refresh auth token
50
+ - `googleAuth(idToken, inviteToken?, options?)` — Google OAuth
51
+ - `githubAuth(code, inviteToken?, options?)` — GitHub OAuth
52
+ - `googleAuthCallback(code, redirectUri, inviteToken?, options?)` — Google OAuth callback
53
+ - `requestPasswordReset(email)` — request password reset
54
+ - `confirmPasswordReset(token, password)` — confirm password reset
55
+ - `confirmRegistration(token)` — confirm registration
56
+ - `requestPasswordChange()` — request password change
57
+ - `confirmPasswordChange(currentPassword, newPassword, code)` — confirm password change
58
+
59
+ ### User Profile
60
+ - `getMe(options?)` — get current user profile
61
+ - `getUserProfile()` — get authenticated user's profile
62
+ - `updateUserProfile(profileData)` — update user profile
63
+ - `getUserProjects()` — get user's projects with icons
64
+ - `getUser(userId)` — get user by ID
65
+ - `getUserByEmail(email)` — get user by email
66
+
67
+ ### Token & State
68
+ - `getAuthToken()` — get current auth token
69
+ - `getStoredAuthState()` — get stored auth state
70
+ - `isAuthenticated()` — check if authenticated
71
+ - `hasValidTokens()` — check if tokens are valid
72
+ - `getCurrentUser()` — get current user
73
+
74
+ ### Permissions
75
+ - `getMyProjectRole(projectId)` — get role in project (cached)
76
+ - `getMyProjectRoleByKey(projectKey)` — get role by project key (cached)
77
+ - `clearProjectRoleCache(projectId?)` — clear role cache
78
+ - `hasPermission(requiredPermission)` — check global permission
79
+ - `hasGlobalPermission(globalRole, requiredPermission)` — check global role permission
80
+ - `checkProjectPermission(projectRole, requiredPermission)` — check project permission
81
+ - `checkProjectFeature(projectTier, feature)` — check if tier has feature
82
+ - `canPerformOperation(projectId, operation, options?)` — check if operation is allowed
83
+ - `withPermission(projectId, operation, action)` — execute action with permission check
84
+
85
+ ---
86
+
87
+ ## ProjectService
88
+
89
+ Project CRUD, members, libraries, versions, and environments.
90
+
91
+ ### Project CRUD
92
+ - `createProject(projectData)` — create new project
93
+ - `getProjects(params?)` — get projects with pagination
94
+ - `listProjects(params?)` — alias for getProjects
95
+ - `listPublicProjects(params?)` — get public projects (no auth)
96
+ - `getProject(projectId)` — get project by ID
97
+ - `getPublicProject(projectId)` — get public project (no auth)
98
+ - `getProjectByKey(key)` — get project by key
99
+ - `getProjectDataByKey(key, options?)` — get project data by key
100
+ - `updateProject(projectId, data)` — update project metadata
101
+ - `updateProjectName(projectId, name)` — update project name
102
+ - `duplicateProject(projectId, newName, newKey, targetUserId)` — duplicate project
103
+ - `removeProject(projectId)` — delete project
104
+ - `checkProjectKeyAvailability(key)` — check if key is available
105
+
106
+ ### Project Data
107
+ - `updateProjectComponents(projectId, components)` — update components
108
+ - `updateProjectSettings(projectId, settings)` — update settings
109
+ - `updateProjectPackage(projectId, pkg)` — update package
110
+ - `setProjectAccess(projectId, access)` — set access level (account/team/organization/public)
111
+ - `setProjectVisibility(projectId, visibility)` — set visibility (public/private/password-protected)
112
+
113
+ ### Members
114
+ - `getProjectMembers(projectId)` — get all members
115
+ - `inviteMember(projectId, email, role?, options?)` — invite member
116
+ - `createMagicInviteLink(projectId, options?)` — create shareable invite link
117
+ - `acceptInvite(token)` — accept invitation
118
+ - `updateMemberRole(projectId, memberId, role)` — change member role
119
+ - `removeMember(projectId, memberId)` — remove member
120
+
121
+ ### Permissions
122
+ - `getProjectRolePermissionsConfig(projectId, options?)` — get role-permissions mapping
123
+ - `updateProjectRolePermissionsConfig(projectId, rolePermissions, options?)` — update permissions
124
+
125
+ ### Libraries
126
+ - `getAvailableLibraries(params?)` — get available libraries
127
+ - `getProjectLibraries(projectId)` — get project's libraries
128
+ - `addProjectLibraries(projectId, libraryIds)` — add libraries
129
+ - `removeProjectLibraries(projectId, libraryIds)` — remove libraries
130
+
131
+ ### Versions & Changes
132
+ - `applyProjectChanges(projectId, changes, options?)` — apply changes (creates new version)
133
+ - `getProjectData(projectId, options?)` — get current project data for branch
134
+ - `getProjectVersions(projectId, options?)` — get version history with pagination
135
+ - `restoreProjectVersion(projectId, version, options?)` — restore to previous version
136
+
137
+ ### Environments
138
+ - `listEnvironments(projectId, options?)` — list all environments
139
+ - `activateMultipleEnvironments(projectId, options?)` — enable multi-environment support
140
+ - `upsertEnvironment(projectId, envKey, config, options?)` — create/update environment
141
+ - `updateEnvironment(projectId, envKey, updates, options?)` — update environment config
142
+ - `publishToEnvironment(projectId, envKey, payload, options?)` — publish to environment
143
+ - `deleteEnvironment(projectId, envKey, options?)` — delete environment
144
+ - `promoteEnvironment(projectId, fromEnvKey, toEnvKey, options?)` — promote between environments
145
+
146
+ ### Favorites & Recent
147
+ - `getFavoriteProjects()` — get favorites
148
+ - `addFavoriteProject(projectId)` — add to favorites
149
+ - `removeFavoriteProject(projectId)` — remove from favorites
150
+ - `getRecentProjects(options?)` — get recently accessed projects
151
+
152
+ ### Item-Level Operations
153
+ - `updateProjectItem(projectId, path, value, options?)` — update single item
154
+ - `deleteProjectItem(projectId, path, options?)` — delete item
155
+ - `setProjectValue(projectId, path, value, options?)` — set value
156
+ - `addProjectItems(projectId, items, options?)` — add multiple items
157
+ - `getProjectItemByPath(projectId, path, options?)` — get item by path
158
+
159
+ ---
160
+
161
+ ## BranchService
162
+
163
+ Version control branches.
164
+
165
+ ### Branch Management
166
+ - `listBranches(projectId)` — get all branches
167
+ - `createBranch(projectId, branchData)` — create branch from source
168
+ - `deleteBranch(projectId, branchName)` — delete branch (cannot delete main)
169
+ - `renameBranch(projectId, branchName, newName)` — rename branch
170
+ - `getBranchChanges(projectId, branchName?, options?)` — get diff for branch
171
+ - `mergeBranch(projectId, branchName, mergeData?)` — merge branch (preview or commit)
172
+ - `resetBranch(projectId, branchName)` — reset branch to clean state
173
+ - `publishVersion(projectId, publishData)` — publish version as live
174
+
175
+ ### Helpers
176
+ - `createBranchWithValidation(projectId, name, source?)` — create with validation
177
+ - `branchExists(projectId, branchName)` — check if branch exists
178
+ - `previewMerge(projectId, sourceBranch, targetBranch?)` — preview merge
179
+ - `commitMerge(projectId, sourceBranch, options?)` — commit after preview
180
+ - `createFeatureBranch(projectId, featureName)` — create feature branch
181
+ - `createHotfixBranch(projectId, hotfixName)` — create hotfix branch
182
+ - `getBranchStatus(projectId, branchName)` — get branch status
183
+ - `deleteBranchSafely(projectId, branchName, options?)` — delete with safety checks
184
+ - `getBranchesWithStatus(projectId)` — get all branches with status
185
+ - `validateBranchName(branchName)` — validate branch name
186
+ - `sanitizeBranchName(branchName)` — normalize branch name
187
+
188
+ ---
189
+
190
+ ## PullRequestService
191
+
192
+ Code review and merging.
193
+
194
+ ### Pull Request Operations
195
+ - `createPullRequest(projectId, pullRequestData)` — create PR (source, target, title required)
196
+ - `listPullRequests(projectId, options?)` — list PRs with filtering/pagination
197
+ - `getPullRequest(projectId, prId)` — get PR details
198
+ - `reviewPullRequest(projectId, prId, reviewData)` — submit review (approved/requested_changes/feedback)
199
+ - `addPullRequestComment(projectId, prId, commentData)` — add comment
200
+ - `mergePullRequest(projectId, prId)` — merge approved PR
201
+ - `getPullRequestDiff(projectId, prId)` — get PR diff
202
+ - `closePullRequest(projectId, prId)` — close without merging
203
+ - `reopenPullRequest(projectId, prId)` — reopen closed PR
204
+
205
+ ### Helpers
206
+ - `approvePullRequest(projectId, prId, comment?)` — approve PR
207
+ - `requestPullRequestChanges(projectId, prId, threads?)` — request changes
208
+ - `getOpenPullRequests(projectId, options?)` — filter open PRs
209
+ - `getClosedPullRequests(projectId, options?)` — filter closed PRs
210
+ - `getMergedPullRequests(projectId, options?)` — filter merged PRs
211
+ - `isPullRequestMergeable(projectId, prId)` — check if mergeable
212
+ - `getPullRequestStatusSummary(projectId, prId)` — get status overview
213
+ - `getPullRequestStats(projectId, options?)` — get PR statistics
214
+
215
+ ---
216
+
217
+ ## CollabService
218
+
219
+ Real-time collaboration via WebSocket.
220
+
221
+ - `connect(options?)` — connect to collaborative editing socket
222
+
223
+ Features:
224
+ - Real-time document synchronization via Yjs
225
+ - Undo/redo stack management
226
+ - Pending operations for offline mode
227
+ - Connection recovery
228
+ - Presence and cursor tracking
229
+
230
+ ---
231
+
232
+ ## FileService
233
+
234
+ File uploads and management.
235
+
236
+ - `uploadFile(file, options?)` — upload file with metadata/tags
237
+ - `updateProjectIcon(projectId, iconFile)` — upload project icon
238
+ - `uploadFileWithValidation(file, options?)` — upload with size/type validation
239
+ - `uploadImage(imageFile, options?)` — upload with image constraints
240
+ - `uploadDocument(documentFile, options?)` — upload with document constraints
241
+ - `getFileUrl(fileId)` — generate public file URL
242
+ - `validateFile(file, options?)` — validate file before upload
243
+ - `uploadMultipleFiles(files, options?)` — upload multiple files
244
+
245
+ ---
246
+
247
+ ## DnsService
248
+
249
+ Custom domain management.
250
+
251
+ ### DNS Records
252
+ - `createDnsRecord(domain, options?)` — create DNS record
253
+ - `getDnsRecord(domain)` — get DNS record
254
+ - `getCustomHost(hostname)` — get custom host info
255
+ - `removeDnsRecord(domain)` — delete DNS record
256
+
257
+ ### Project Domains
258
+ - `addProjectCustomDomains(projectId, customDomains, options?)` — add custom domains
259
+ - `getProjectDomains(projectId)` — get project's custom domains
260
+ - `removeProjectCustomDomain(projectId, domain)` — remove custom domain
261
+
262
+ ### Helpers
263
+ - `validateDomain(domain)` — validate domain format
264
+ - `isDomainAvailable(domain)` — check availability
265
+ - `getDomainStatus(domain)` — get domain status
266
+ - `verifyDomainOwnership(domain)` — verify ownership
267
+
268
+ ---
269
+
270
+ ## IntegrationService
271
+
272
+ Third-party integrations and API keys.
273
+
274
+ - `integrationWhoami(apiKey, options?)` — validate API key
275
+ - `listIntegrations(options?)` — list integrations
276
+ - `createIntegration(data)` — create integration
277
+ - `updateIntegration(integrationId, update)` — update integration
278
+ - `createIntegrationApiKey(integrationId, data?)` — create API key
279
+ - `listIntegrationApiKeys(integrationId)` — list API keys
280
+ - `revokeIntegrationApiKey(integrationId, keyId)` — revoke API key
281
+
282
+ ---
283
+
284
+ ## FeatureFlagService
285
+
286
+ Feature flag management.
287
+
288
+ ### User
289
+ - `getFeatureFlags(params?)` — get flags for current user
290
+ - `getFeatureFlag(key)` — get single flag
291
+
292
+ ### Admin
293
+ - `getAdminFeatureFlags(params?)` — get all flags
294
+ - `createFeatureFlag(flagData)` — create flag
295
+ - `updateFeatureFlag(id, patch)` — update flag
296
+ - `archiveFeatureFlag(id)` — delete flag
297
+
298
+ Flag format:
299
+ ```javascript
300
+ {
301
+ flags: {
302
+ "flag_key": {
303
+ enabled: boolean,
304
+ variant: string | null,
305
+ payload: any
306
+ }
307
+ }
308
+ }
309
+ ```
310
+
311
+ ---
312
+
313
+ ## MetricsService
314
+
315
+ Contribution statistics.
316
+
317
+ - `getContributions(options?)` — get contribution heat-map stats
318
+ - Options: `projectId`, `userId`, `from`, `to`
319
+
320
+ ---
321
+
322
+ ## ScreenshotService
323
+
324
+ Screenshot and thumbnail management.
325
+
326
+ ### Project-Level
327
+ - `createScreenshotProject(payload)` — create screenshot project
328
+ - `getProjectScreenshots(projectKey, params?)` — get screenshots
329
+ - `reprocessProjectScreenshots(projectKey, body?)` — reprocess screenshots
330
+ - `recreateProjectScreenshots(projectKey, body?)` — recreate all
331
+ - `deleteProjectScreenshots(projectKey)` — delete all
332
+
333
+ ### Thumbnails
334
+ - `getThumbnailCandidate(projectKey, options?)` — get best candidate
335
+ - `updateProjectThumbnail(projectKey, body?)` — update thumbnail
336
+ - `refreshThumbnail(projectKey, options?)` — debounced refresh (15s)
337
+
338
+ ### Individual
339
+ - `getPageScreenshot(screenshotId, format?)` — get page screenshot
340
+ - `getComponentScreenshot(screenshotId, format?)` — get component screenshot
341
+ - `getScreenshotByKey(projectKey, type, key, format?)` — get by key
342
+ - `getQueueStatistics()` — get queue stats
343
+
344
+ ---
345
+
346
+ ## TrackingService
347
+
348
+ Analytics via Grafana Faro.
349
+
350
+ - `configureTracking(options?)` — configure tracking
351
+ - `setUser(user, options?)` — set tracking user
352
+ - `setGlobalAttributes(attrs)` — set global attributes
353
+ - `trackEvent(name, attributes?)` — track custom event
354
+ - `trackPageView(name, attributes?)` — track page view
355
+ - `trackError(error, context?)` — track error
356
+
357
+ ---
358
+
359
+ ## BaseService (Foundation)
360
+
361
+ All services extend BaseService:
362
+
363
+ - `init(context)` — initialize service
364
+ - `updateContext(context)` — update context
365
+ - `getStatus()` — get service status
366
+ - `isReady()` — check if ready
367
+ - `destroy()` — cleanup
368
+
369
+ HTTP features:
370
+ - Automatic token management (refresh before expiration)
371
+ - Storage: localStorage, sessionStorage, or memory
372
+ - FormData support for uploads
373
+ - Error tracking integration
374
+
375
+ Methods that don't require auth: `register`, `login`, `googleAuth`, `githubAuth`, `requestPasswordReset`, `confirmPasswordReset`, `confirmRegistration`, `listPublicProjects`, `getPublicProject`.
376
+
377
+ ---
378
+
379
+ ## Usage Examples
380
+
381
+ ### Authenticate and list projects
382
+ ```javascript
383
+ import { SDK } from '@symbo.ls/sdk'
384
+
385
+ const sdk = new SDK({ apiUrl: 'https://api.symbols.app' })
386
+ await sdk.initialize({})
387
+
388
+ const result = await sdk.login('user@example.com', 'password')
389
+ const projects = await sdk.getProjects()
390
+ ```
391
+
392
+ ### Create a project and add a library
393
+ ```javascript
394
+ const project = await sdk.createProject({
395
+ name: 'My App',
396
+ key: 'pr_myapp',
397
+ visibility: 'private'
398
+ })
399
+
400
+ const libs = await sdk.getAvailableLibraries()
401
+ await sdk.addProjectLibraries(project.data._id, [libs.data[0]._id])
402
+ ```
403
+
404
+ ### Branch workflow
405
+ ```javascript
406
+ await sdk.createFeatureBranch(projectId, 'new-header')
407
+ // ... make changes ...
408
+ const preview = await sdk.previewMerge(projectId, 'feature/new-header')
409
+ await sdk.commitMerge(projectId, 'feature/new-header')
410
+ ```
411
+
412
+ ### Pull request workflow
413
+ ```javascript
414
+ const pr = await sdk.createPullRequest(projectId, {
415
+ source: 'feature/new-header',
416
+ target: 'main',
417
+ title: 'Add new header component'
418
+ })
419
+
420
+ await sdk.approvePullRequest(projectId, pr.data._id, 'Looks good!')
421
+ await sdk.mergePullRequest(projectId, pr.data._id)
422
+ ```
423
+
424
+ ### File upload
425
+ ```javascript
426
+ const file = new File(['content'], 'design.png', { type: 'image/png' })
427
+ const result = await sdk.uploadImage(file, {
428
+ tags: ['design', 'header'],
429
+ visibility: 'project'
430
+ })
431
+ const url = sdk.getFileUrl(result.data._id)
432
+ ```
433
+
434
+ ### CLI access via `smbls sdk`
435
+ ```bash
436
+ smbls sdk --list # List all methods
437
+ smbls sdk --list --service auth # Filter by service
438
+ smbls sdk getProjects # Call method
439
+ smbls sdk getProjectByKey '{"key":"myapp"}' # Call with JSON args
440
+ ```
@@ -19,8 +19,9 @@ export const MyCard = {
19
19
  theme: 'dialog',
20
20
  round: 'C',
21
21
 
22
- // HTML attributes
23
- attr: { role: 'region', 'aria-label': ({ props }) => props.label },
22
+ // HTML attributes (standard attrs are auto-detected by attrs-in-props)
23
+ role: 'region',
24
+ attr: { 'aria-label': ({ props }) => props.label },
24
25
 
25
26
  // State
26
27
  state: { open: false },
@@ -130,7 +131,7 @@ export const Card = {
130
131
  transitionProperty: 'opacity, transform',
131
132
  zIndex: 10,
132
133
  tag: 'section', // stays at root (REGISTRY)
133
- attr: { href: '...' } // stays at root (REGISTRY)
134
+ href: '...', // auto-detected as HTML attribute
134
135
  }
135
136
  ```
136
137
 
@@ -367,25 +368,29 @@ state: 'userProfile' // child inherits parent's userProfile key
367
368
 
368
369
  ## `attr` (HTML Attributes)
369
370
 
371
+ Standard HTML attributes (600+ recognized per tag) are auto-detected by the `attrs-in-props` module and can be placed directly at the element root or in props. Use `attr: {}` ONLY for `data-*`, `aria-*`, and custom non-standard attributes.
372
+
370
373
  ```js
371
374
  export const Input = {
372
375
  tag: 'input',
376
+ // Standard HTML attributes — placed directly (auto-detected)
377
+ type: 'text',
378
+ autocomplete: 'off',
379
+ placeholder: ({ props }) => props.placeholder,
380
+ name: ({ props }) => props.name,
381
+ disabled: ({ props }) => props.disabled || null, // null removes attr
382
+ value: (el) => el.call('exec', el.props.value, el),
383
+ required: ({ props }) => props.required,
384
+ role: 'button',
385
+ tabIndex: ({ props }) => props.tabIndex,
386
+ // Non-standard / ARIA — use attr: {}
373
387
  attr: {
374
- type: 'text',
375
- autocomplete: 'off',
376
- placeholder: ({ props }) => props.placeholder,
377
- name: ({ props }) => props.name,
378
- disabled: ({ props }) => props.disabled || null, // null removes attr
379
- value: (el) => el.call('exec', el.props.value, el),
380
- required: ({ props }) => props.required,
381
- role: 'button',
382
388
  'aria-label': ({ props }) => props.aria?.label || props.text,
383
- tabIndex: ({ props }) => props.tabIndex
384
389
  }
385
390
  }
386
391
  ```
387
392
 
388
- Return `null` or `undefined` from an attr function to remove the attribute.
393
+ Return `null` or `undefined` from a prop function to remove the attribute.
389
394
 
390
395
  ---
391
396
 
@@ -505,12 +510,10 @@ export const Page = { content: ({ props }) => props.page }
505
510
  // Pass (consumer side)
506
511
  { extends: 'Button', props: { text: 'Submit', href: '/dashboard', disabled: false } }
507
512
 
508
- // Access (definition side)
509
- attr: {
510
- placeholder: ({ props }) => props.placeholder,
511
- value: (el) => el.props.value,
512
- disabled: ({ props }) => props.disabled || null
513
- }
513
+ // Access (definition side) — standard attrs auto-detected
514
+ placeholder: ({ props }) => props.placeholder,
515
+ value: (el) => el.props.value,
516
+ disabled: ({ props }) => props.disabled || null,
514
517
  text: ({ props }) => props.label
515
518
  ```
516
519