@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.
- package/README.md +86 -32
- package/bin/symbols-mcp.js +846 -9
- package/package.json +2 -2
- package/symbols_mcp/skills/AUDIT.md +2 -0
- package/symbols_mcp/skills/CLI.md +374 -0
- package/symbols_mcp/skills/COMMON_MISTAKES.md +225 -0
- package/symbols_mcp/skills/DEFAULT_COMPONENTS.md +6 -22
- package/symbols_mcp/skills/LEARNINGS.md +1 -1
- package/symbols_mcp/skills/PATTERNS.md +14 -12
- package/symbols_mcp/skills/PROJECT_STRUCTURE.md +148 -37
- package/symbols_mcp/skills/RULES.md +685 -31
- package/symbols_mcp/skills/SDK.md +440 -0
- package/symbols_mcp/skills/SYNTAX.md +22 -19
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
510
|
-
|
|
511
|
-
|
|
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
|
|