figmanage 1.3.7 → 1.4.0
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 +181 -132
- package/dist/auth/client.d.ts +1 -0
- package/dist/auth/health.js +2 -1
- package/dist/cli/comments.js +79 -2
- package/dist/cli/components.js +66 -0
- package/dist/cli/compound-commands.js +2 -0
- package/dist/cli/org.js +143 -5
- package/dist/cli/teams.js +41 -1
- package/dist/cli/webhooks.js +20 -1
- package/dist/clients/internal-api.js +1 -1
- package/dist/clients/public-api.js +1 -1
- package/dist/mcp.d.ts +1 -0
- package/dist/mcp.js +10 -4
- package/dist/operations/comments.d.ts +25 -0
- package/dist/operations/comments.js +22 -0
- package/dist/operations/compound-manager.d.ts +1 -0
- package/dist/operations/compound-manager.js +17 -3
- package/dist/operations/dev-resources.d.ts +25 -0
- package/dist/operations/dev-resources.js +31 -0
- package/dist/operations/navigate.d.ts +5 -0
- package/dist/operations/navigate.js +20 -0
- package/dist/operations/org.d.ts +68 -1
- package/dist/operations/org.js +112 -1
- package/dist/operations/teams.d.ts +9 -0
- package/dist/operations/teams.js +23 -0
- package/dist/operations/webhooks.d.ts +14 -0
- package/dist/operations/webhooks.js +12 -0
- package/dist/tools/analytics.js +2 -0
- package/dist/tools/comments.js +99 -3
- package/dist/tools/compound-manager.js +7 -2
- package/dist/tools/compound.js +3 -0
- package/dist/tools/dev-resources.d.ts +2 -0
- package/dist/tools/dev-resources.js +78 -0
- package/dist/tools/org.js +203 -8
- package/dist/tools/permissions.js +3 -0
- package/dist/tools/register.d.ts +2 -1
- package/dist/tools/register.js +4 -1
- package/dist/tools/teams.js +53 -1
- package/dist/tools/webhooks.js +25 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,62 +1,55 @@
|
|
|
1
1
|
# figmanage
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Let agents manage your Figma workspace. Seats, teams, permissions, billing, offboarding, cleanup -- handled in conversation instead of clicking through admin panels.
|
|
4
|
+
|
|
5
|
+
Every Figma MCP is design-to-code. figmanage is the management layer: 102 tools that let agents operate on the workspace itself. Works with Claude Code, Cursor, OpenClaw, or as a standalone CLI.
|
|
4
6
|
|
|
5
7
|
[](https://www.npmjs.com/package/figmanage)
|
|
6
8
|
[](https://www.npmjs.com/package/figmanage)
|
|
7
|
-
[](https://github.com/dannykeane/figmanage)
|
|
8
10
|
[](LICENSE)
|
|
9
11
|
[](https://mcp-marketplace.io/server/io-github-dannykeane-figmanage)
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
## examples
|
|
14
|
+
|
|
15
|
+
### workspace management (admins)
|
|
16
|
+
|
|
13
17
|
```
|
|
18
|
+
"which paid seats haven't been active in 30 days? how much would we save?"
|
|
14
19
|
|
|
15
|
-
|
|
20
|
+
"offboard sarah@company.com -- show me everything she owns, then transfer it
|
|
21
|
+
to jake and remove her from the org"
|
|
16
22
|
|
|
17
|
-
|
|
18
|
-
|
|
23
|
+
"set up a new hire: invite alex@company.com to Design and Engineering as an editor"
|
|
24
|
+
|
|
25
|
+
"create a user group called Platform Design and add the three designers"
|
|
26
|
+
|
|
27
|
+
"run a quarterly design ops report for the org"
|
|
19
28
|
```
|
|
20
29
|
|
|
21
|
-
|
|
30
|
+
### everyday design work (everyone)
|
|
22
31
|
|
|
23
|
-
```bash
|
|
24
|
-
figmanage whoami # verify auth
|
|
25
|
-
figmanage logout # clear credentials
|
|
26
32
|
```
|
|
33
|
+
"clean up the Mobile App project -- find stale files and archive dead branches"
|
|
27
34
|
|
|
28
|
-
|
|
35
|
+
"what are the unresolved comments across the Platform project?"
|
|
29
36
|
|
|
30
|
-
|
|
37
|
+
"export all the icons from the Design System file as SVGs"
|
|
31
38
|
|
|
32
|
-
|
|
33
|
-
figmanage org seat-optimization # find inactive paid seats
|
|
34
|
-
figmanage org offboard sarah@co.com # audit what a user owns
|
|
35
|
-
figmanage org offboard sarah@co.com --execute \
|
|
36
|
-
--transfer-to jake@co.com # execute the offboarding
|
|
37
|
-
figmanage org onboard alex@co.com --teams 123,456 \
|
|
38
|
-
--role editor --seat full --confirm # set up a new hire
|
|
39
|
-
figmanage org quarterly-report # org-wide design ops snapshot
|
|
40
|
-
figmanage org members --search danny # find org members
|
|
41
|
-
figmanage navigate list-teams # list all teams
|
|
42
|
-
figmanage permissions get file abc123 # who has access to a file
|
|
43
|
-
figmanage permissions audit --scope team --id 789 # audit a team's permissions
|
|
44
|
-
figmanage branches cleanup 573408414 # find stale branches
|
|
45
|
-
figmanage files summary abc123 # pages, components, styles overview
|
|
46
|
-
```
|
|
39
|
+
"move the Q4 files into the Archive project"
|
|
47
40
|
|
|
48
|
-
|
|
41
|
+
"share the Homepage mockup with alex@company.com and set link access to view-only"
|
|
49
42
|
|
|
50
|
-
|
|
43
|
+
"summarize the Brand Guidelines file -- pages, components, styles"
|
|
44
|
+
```
|
|
51
45
|
|
|
52
|
-
|
|
46
|
+
## install
|
|
53
47
|
|
|
54
48
|
```bash
|
|
55
49
|
# Claude Code
|
|
56
50
|
claude mcp add figmanage -- npx -y figmanage
|
|
57
51
|
|
|
58
52
|
# Cursor / OpenClaw / other MCP clients
|
|
59
|
-
# Add to your MCP config:
|
|
60
53
|
{
|
|
61
54
|
"mcpServers": {
|
|
62
55
|
"figmanage": {
|
|
@@ -67,44 +60,83 @@ claude mcp add figmanage -- npx -y figmanage
|
|
|
67
60
|
}
|
|
68
61
|
```
|
|
69
62
|
|
|
70
|
-
On first run, figmanage walks you through setup
|
|
63
|
+
On first run, figmanage walks you through setup in the conversation -- extracts your Chrome session cookie, asks you to create a PAT, stores credentials locally. No env vars, no JSON editing.
|
|
64
|
+
|
|
65
|
+
Also works as a CLI:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npm install -g figmanage
|
|
69
|
+
figmanage login
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## how it works
|
|
71
73
|
|
|
72
|
-
|
|
74
|
+
Figma's public REST API covers design files but nothing on the management side -- no seats, no teams, no permissions, no billing. figmanage uses both APIs:
|
|
73
75
|
|
|
74
|
-
|
|
76
|
+
| API | Auth | What it covers |
|
|
77
|
+
|-----|------|---------------|
|
|
78
|
+
| Internal | Session cookie | Seats, teams, permissions, billing, user groups, org admin, search |
|
|
79
|
+
| Public | Personal Access Token | Files, comments, export, components, versions, webhooks, variables |
|
|
75
80
|
|
|
76
|
-
|
|
81
|
+
Both together unlock all 102 tools. Cookie-only or PAT-only works but limits available tools.
|
|
77
82
|
|
|
78
|
-
|
|
83
|
+
**Admin auto-detection.** At startup, figmanage checks whether you're an org admin. Admins see all 102 tools. Non-admins see 68 -- everything except org management, seat changes, billing, user groups, and offboarding. No configuration needed.
|
|
79
84
|
|
|
80
|
-
|
|
81
|
-
|
|
85
|
+
**Toolset presets.** Use `FIGMA_TOOLSETS` to expose only specific tool groups:
|
|
86
|
+
|
|
87
|
+
| Preset | What's included |
|
|
88
|
+
|--------|----------------|
|
|
82
89
|
| `starter` | navigate, reading, comments, export |
|
|
83
90
|
| `admin` | navigate, org, permissions, analytics, teams, libraries |
|
|
84
91
|
| `readonly` | navigate, reading, comments, export, components, versions |
|
|
85
92
|
| `full` | everything (default) |
|
|
86
93
|
|
|
87
|
-
##
|
|
94
|
+
## CLI
|
|
95
|
+
|
|
96
|
+
Commands use a noun-verb pattern: `figmanage <group> <action>`.
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
figmanage org seat-optimization # find inactive paid seats
|
|
100
|
+
figmanage org offboard sarah@co.com # audit what a user owns
|
|
101
|
+
figmanage org offboard sarah@co.com --execute \
|
|
102
|
+
--transfer-to jake@co.com # soft offboard
|
|
103
|
+
figmanage org offboard sarah@co.com --execute \
|
|
104
|
+
--transfer-to jake@co.com --remove-from-org # hard offboard (permanent)
|
|
105
|
+
figmanage org onboard alex@co.com --teams 123,456 \
|
|
106
|
+
--role editor --seat full --confirm # set up a new hire
|
|
107
|
+
figmanage org quarterly-report # org-wide design ops snapshot
|
|
108
|
+
figmanage org members --search danny # find org members
|
|
109
|
+
figmanage permissions audit --scope team --id 789 # audit a team's permissions
|
|
110
|
+
figmanage branches cleanup 573408414 # find stale branches
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
All commands output JSON when piped or when `--json` is passed. Run `figmanage <group> --help` for subcommands.
|
|
114
|
+
|
|
115
|
+
## setup
|
|
116
|
+
|
|
117
|
+
Log into figma.com in Chrome, then:
|
|
88
118
|
|
|
89
|
-
|
|
119
|
+
```bash
|
|
120
|
+
figmanage login # extract cookie, create PAT, store credentials
|
|
121
|
+
figmanage whoami # verify auth
|
|
122
|
+
figmanage logout # clear credentials
|
|
123
|
+
```
|
|
90
124
|
|
|
91
|
-
|
|
92
|
-
|--------|------|-------------|
|
|
93
|
-
| Internal API | Session cookie | Workspace management, search, permissions, org admin, seats, billing |
|
|
94
|
-
| Public API | Personal Access Token | Comments, export, file reading, components, versions, webhooks, variables |
|
|
125
|
+
Credentials stored at `~/.config/figmanage/` with 0o600 permissions.
|
|
95
126
|
|
|
96
|
-
|
|
127
|
+
Env vars (`FIGMA_PAT`, `FIGMA_AUTH_COOKIE`, etc.) override the config file. HTTP transport available via `--mcp --http <port>`.
|
|
97
128
|
|
|
98
|
-
|
|
129
|
+
## tool reference
|
|
99
130
|
|
|
100
|
-
|
|
131
|
+
<details>
|
|
132
|
+
<summary>All 102 tools across 17 groups (click to expand)</summary>
|
|
101
133
|
|
|
102
|
-
The tables below
|
|
134
|
+
The tables below show MCP tool names (snake_case). CLI equivalents use kebab-case: `list_recent_files` becomes `figmanage navigate list-recent-files`.
|
|
103
135
|
|
|
104
136
|
### navigate (10)
|
|
105
137
|
|
|
106
|
-
|
|
|
107
|
-
|
|
138
|
+
| Tool | Auth | Description |
|
|
139
|
+
|------|------|-------------|
|
|
108
140
|
| `check_auth` | either | Validate PAT and cookie authentication |
|
|
109
141
|
| `list_orgs` | cookie | List available Figma workspaces |
|
|
110
142
|
| `switch_org` | cookie | Switch active workspace for this session |
|
|
@@ -118,8 +150,8 @@ The tables below list all 85 commands. The Command column shows MCP tool names (
|
|
|
118
150
|
|
|
119
151
|
### files (10)
|
|
120
152
|
|
|
121
|
-
|
|
|
122
|
-
|
|
153
|
+
| Tool | Auth | Description |
|
|
154
|
+
|------|------|-------------|
|
|
123
155
|
| `create_file` | cookie | Create design, whiteboard, slides, or sites file |
|
|
124
156
|
| `rename_file` | cookie | Rename a file |
|
|
125
157
|
| `move_files` | cookie | Move files between projects (batch) |
|
|
@@ -133,8 +165,8 @@ The tables below list all 85 commands. The Command column shows MCP tool names (
|
|
|
133
165
|
|
|
134
166
|
### projects (8)
|
|
135
167
|
|
|
136
|
-
|
|
|
137
|
-
|
|
168
|
+
| Tool | Auth | Description |
|
|
169
|
+
|------|------|-------------|
|
|
138
170
|
| `create_project` | cookie | Create a project in a team |
|
|
139
171
|
| `rename_project` | cookie | Rename a project |
|
|
140
172
|
| `move_project` | cookie | Move a project to another team |
|
|
@@ -146,8 +178,8 @@ The tables below list all 85 commands. The Command column shows MCP tool names (
|
|
|
146
178
|
|
|
147
179
|
### permissions (8)
|
|
148
180
|
|
|
149
|
-
|
|
|
150
|
-
|
|
181
|
+
| Tool | Auth | Description |
|
|
182
|
+
|------|------|-------------|
|
|
151
183
|
| `get_permissions` | cookie | List who has access with roles |
|
|
152
184
|
| `set_permissions` | cookie | Change a user's access level |
|
|
153
185
|
| `share` | cookie | Invite someone by email |
|
|
@@ -157,127 +189,146 @@ The tables below list all 85 commands. The Command column shows MCP tool names (
|
|
|
157
189
|
| `deny_role_request` | cookie | Decline an access request |
|
|
158
190
|
| `permission_audit` | cookie | Team/project access audit with oversharing flags |
|
|
159
191
|
|
|
192
|
+
### org (24, admin-only)
|
|
193
|
+
|
|
194
|
+
| Tool | Auth | Description |
|
|
195
|
+
|------|------|-------------|
|
|
196
|
+
| `list_admins` | cookie | Org admins with permission levels |
|
|
197
|
+
| `list_org_teams` | cookie | All teams with member and project counts |
|
|
198
|
+
| `seat_usage` | cookie | Seat breakdown by type and activity |
|
|
199
|
+
| `list_team_members` | cookie | Team members with roles and activity |
|
|
200
|
+
| `list_org_members` | cookie | All org members with seats and activity |
|
|
201
|
+
| `contract_rates` | cookie | Per-seat pricing |
|
|
202
|
+
| `change_seat` | cookie | Change a user's seat type |
|
|
203
|
+
| `billing_overview` | cookie | Invoice history and billing status |
|
|
204
|
+
| `list_invoices` | cookie | Open and upcoming invoices |
|
|
205
|
+
| `list_payments` | cookie | Paid invoices / payment history |
|
|
206
|
+
| `org_domains` | cookie | Domain config and SSO/SAML |
|
|
207
|
+
| `ai_credit_usage` | cookie | AI credit usage (resolves plan from team) |
|
|
208
|
+
| `export_members` | cookie | Trigger CSV export of all members |
|
|
209
|
+
| `activity_log` | cookie | Org audit log with email filtering and pagination |
|
|
210
|
+
| `create_user_group` | cookie | Create a user group |
|
|
211
|
+
| `delete_user_groups` | cookie | Delete user groups |
|
|
212
|
+
| `add_user_group_members` | cookie | Add members to a user group by email |
|
|
213
|
+
| `remove_user_group_members` | cookie | Remove members from a user group |
|
|
214
|
+
| `remove_org_member` | cookie | Permanently remove a member from the org |
|
|
215
|
+
| `workspace_overview` | cookie | Org snapshot: teams, seats, billing |
|
|
216
|
+
| `seat_optimization` | cookie | Inactive seat detection with cost analysis |
|
|
217
|
+
| `offboard_user` | cookie | Audit + execute user departure (soft or hard) |
|
|
218
|
+
| `onboard_user` | cookie | Batch invite to teams, share files, set seat |
|
|
219
|
+
| `quarterly_design_ops_report` | cookie | Seat utilization, billing, teams, library adoption |
|
|
220
|
+
|
|
221
|
+
### teams (5, admin-only)
|
|
222
|
+
|
|
223
|
+
| Tool | Auth | Description |
|
|
224
|
+
|------|------|-------------|
|
|
225
|
+
| `create_team` | cookie | Create a team |
|
|
226
|
+
| `rename_team` | cookie | Rename a team |
|
|
227
|
+
| `delete_team` | cookie | Delete a team |
|
|
228
|
+
| `add_team_member` | cookie | Add a member by email |
|
|
229
|
+
| `remove_team_member` | cookie | Remove a member |
|
|
230
|
+
|
|
231
|
+
### analytics (2, admin-only)
|
|
232
|
+
|
|
233
|
+
| Tool | Auth | Description |
|
|
234
|
+
|------|------|-------------|
|
|
235
|
+
| `library_usage` | cookie | Team-level library adoption metrics |
|
|
236
|
+
| `component_usage` | cookie | Per-file component usage |
|
|
237
|
+
|
|
238
|
+
### comments (9)
|
|
239
|
+
|
|
240
|
+
| Tool | Auth | Description |
|
|
241
|
+
|------|------|-------------|
|
|
242
|
+
| `list_comments` | pat | Comments with thread structure |
|
|
243
|
+
| `post_comment` | pat | Post a comment |
|
|
244
|
+
| `delete_comment` | pat | Delete a comment |
|
|
245
|
+
| `resolve_comment` | cookie | Resolve or unresolve a comment thread |
|
|
246
|
+
| `edit_comment` | cookie | Edit the text of an existing comment |
|
|
247
|
+
| `list_comment_reactions` | pat | Emoji reactions on a comment |
|
|
248
|
+
| `add_comment_reaction` | pat | Add an emoji reaction |
|
|
249
|
+
| `remove_comment_reaction` | pat | Remove an emoji reaction |
|
|
250
|
+
| `open_comments` | pat | Unresolved comments across a project |
|
|
251
|
+
|
|
160
252
|
### versions (2)
|
|
161
253
|
|
|
162
|
-
|
|
|
163
|
-
|
|
254
|
+
| Tool | Auth | Description |
|
|
255
|
+
|------|------|-------------|
|
|
164
256
|
| `list_versions` | pat | Version history |
|
|
165
257
|
| `create_version` | cookie | Create a named version checkpoint |
|
|
166
258
|
|
|
167
259
|
### branches (4)
|
|
168
260
|
|
|
169
|
-
|
|
|
170
|
-
|
|
261
|
+
| Tool | Auth | Description |
|
|
262
|
+
|------|------|-------------|
|
|
171
263
|
| `list_branches` | either | List branches of a file |
|
|
172
264
|
| `create_branch` | cookie | Create a branch |
|
|
173
265
|
| `delete_branch` | cookie | Archive a branch |
|
|
174
266
|
| `branch_cleanup` | either | Stale branch detection with optional archival |
|
|
175
267
|
|
|
176
|
-
###
|
|
268
|
+
### reading (2)
|
|
177
269
|
|
|
178
|
-
|
|
|
179
|
-
|
|
180
|
-
| `
|
|
181
|
-
| `
|
|
182
|
-
| `delete_comment` | pat | Delete a comment |
|
|
183
|
-
| `list_comment_reactions` | pat | Emoji reactions on a comment |
|
|
184
|
-
| `open_comments` | pat | Unresolved comments across a project |
|
|
270
|
+
| Tool | Auth | Description |
|
|
271
|
+
|------|------|-------------|
|
|
272
|
+
| `get_file` | pat | Read file as a node tree with depth control |
|
|
273
|
+
| `get_nodes` | pat | Read specific nodes by ID |
|
|
185
274
|
|
|
186
275
|
### export (2)
|
|
187
276
|
|
|
188
|
-
|
|
|
189
|
-
|
|
277
|
+
| Tool | Auth | Description |
|
|
278
|
+
|------|------|-------------|
|
|
190
279
|
| `export_nodes` | pat | Export as PNG, SVG, PDF, or JPG |
|
|
191
280
|
| `get_image_fills` | pat | URLs for all images used as fills |
|
|
192
281
|
|
|
193
|
-
###
|
|
194
|
-
|
|
195
|
-
| Command | Auth | Description |
|
|
196
|
-
|---------|------|-------------|
|
|
197
|
-
| `get_file` | pat | Read file as a node tree with depth control |
|
|
198
|
-
| `get_nodes` | pat | Read specific nodes by ID |
|
|
199
|
-
|
|
200
|
-
### components (4)
|
|
282
|
+
### components (7)
|
|
201
283
|
|
|
202
|
-
|
|
|
203
|
-
|
|
284
|
+
| Tool | Auth | Description |
|
|
285
|
+
|------|------|-------------|
|
|
204
286
|
| `list_file_components` | pat | Components published from a file |
|
|
205
287
|
| `list_file_styles` | pat | Styles in a file |
|
|
206
288
|
| `list_team_components` | pat | Published components across a team |
|
|
207
289
|
| `list_team_styles` | pat | Published styles across a team |
|
|
290
|
+
| `list_dev_resources` | pat | Dev resources (links, annotations) on a file |
|
|
291
|
+
| `create_dev_resource` | pat | Attach a dev resource to a node |
|
|
292
|
+
| `delete_dev_resource` | pat | Remove a dev resource |
|
|
208
293
|
|
|
209
|
-
### webhooks (
|
|
294
|
+
### webhooks (5)
|
|
210
295
|
|
|
211
|
-
|
|
|
212
|
-
|
|
296
|
+
| Tool | Auth | Description |
|
|
297
|
+
|------|------|-------------|
|
|
213
298
|
| `list_webhooks` | pat | List webhooks for a team |
|
|
214
299
|
| `create_webhook` | pat | Create a webhook subscription |
|
|
215
300
|
| `update_webhook` | pat | Update a webhook |
|
|
216
301
|
| `delete_webhook` | pat | Delete a webhook |
|
|
302
|
+
| `webhook_requests` | pat | Delivery history (last 7 days) |
|
|
217
303
|
|
|
218
304
|
### variables (3, Enterprise)
|
|
219
305
|
|
|
220
|
-
|
|
|
221
|
-
|
|
306
|
+
| Tool | Auth | Description |
|
|
307
|
+
|------|------|-------------|
|
|
222
308
|
| `list_local_variables` | pat | Local variables and collections |
|
|
223
309
|
| `list_published_variables` | pat | Published variables from a library |
|
|
224
310
|
| `update_variables` | pat | Bulk create, update, or delete variables |
|
|
225
311
|
|
|
226
|
-
### analytics (2)
|
|
227
|
-
|
|
228
|
-
| Command | Auth | Description |
|
|
229
|
-
|---------|------|-------------|
|
|
230
|
-
| `library_usage` | cookie | Team-level library adoption metrics |
|
|
231
|
-
| `component_usage` | cookie | Per-file component usage |
|
|
232
|
-
|
|
233
|
-
### org (17)
|
|
234
|
-
|
|
235
|
-
| Command | Auth | Description |
|
|
236
|
-
|---------|------|-------------|
|
|
237
|
-
| `list_admins` | cookie | Org admins with permission levels |
|
|
238
|
-
| `list_org_teams` | cookie | All teams with member and project counts |
|
|
239
|
-
| `seat_usage` | cookie | Seat breakdown by type and activity |
|
|
240
|
-
| `list_team_members` | cookie | Team members with roles and activity |
|
|
241
|
-
| `list_org_members` | cookie | All org members with seats and activity |
|
|
242
|
-
| `contract_rates` | cookie | Per-seat pricing |
|
|
243
|
-
| `change_seat` | cookie | Change a user's seat type |
|
|
244
|
-
| `billing_overview` | cookie | Invoice history and billing status |
|
|
245
|
-
| `list_invoices` | cookie | Open and upcoming invoices |
|
|
246
|
-
| `org_domains` | cookie | Domain config and SSO/SAML |
|
|
247
|
-
| `ai_credit_usage` | cookie | AI credit usage summary |
|
|
248
|
-
| `export_members` | cookie | Trigger CSV export of all members |
|
|
249
|
-
| `workspace_overview` | cookie | Org snapshot: teams, seats, billing |
|
|
250
|
-
| `seat_optimization` | cookie | Inactive seat detection with cost analysis |
|
|
251
|
-
| `offboard_user` | cookie | Audit + execute user departure |
|
|
252
|
-
| `onboard_user` | cookie | Batch invite to teams, share files, set seat |
|
|
253
|
-
| `quarterly_design_ops_report` | cookie | Seat utilization, billing, teams, library adoption |
|
|
254
|
-
|
|
255
312
|
### libraries (1)
|
|
256
313
|
|
|
257
|
-
|
|
|
258
|
-
|
|
314
|
+
| Tool | Auth | Description |
|
|
315
|
+
|------|------|-------------|
|
|
259
316
|
| `list_org_libraries` | cookie | Design system libraries with sharing info |
|
|
260
317
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
| Command | Auth | Description |
|
|
264
|
-
|---------|------|-------------|
|
|
265
|
-
| `create_team` | cookie | Create a team |
|
|
266
|
-
| `rename_team` | cookie | Rename a team |
|
|
267
|
-
| `delete_team` | cookie | Delete a team |
|
|
318
|
+
</details>
|
|
268
319
|
|
|
269
320
|
## security
|
|
270
321
|
|
|
271
|
-
All parameters
|
|
322
|
+
All ID parameters validated against `/^[\w.:-]+$/`. Rate limit retries restricted to safe HTTP methods -- mutations never retried. Billing responses strip PII. Destructive operations default to dry-run mode. Org removal requires explicit double-confirmation. Config file stored with 0o600 permissions.
|
|
272
323
|
|
|
273
324
|
## known limitations
|
|
274
325
|
|
|
275
326
|
- **list_favorites**: Figma BigInt overflow bug on their server. `favorite_file` works fine.
|
|
276
|
-
- **Branch merging**:
|
|
327
|
+
- **Branch merging / version restore**: Require Figma's multiplayer protocol, no REST endpoint.
|
|
277
328
|
- **Cookie expiry**: ~30 days. Run `figmanage login --refresh` to renew.
|
|
278
329
|
- **Windows cookies**: Best-effort DPAPI extraction. Falls back to PAT-only.
|
|
279
330
|
- **Variables**: Enterprise-gated scopes.
|
|
280
|
-
- **
|
|
331
|
+
- **User groups**: Write-only (create, delete, add/remove members). No list endpoint -- Figma renders the page server-side.
|
|
281
332
|
|
|
282
333
|
## development
|
|
283
334
|
|
|
@@ -289,18 +340,16 @@ npm run build
|
|
|
289
340
|
npm test
|
|
290
341
|
```
|
|
291
342
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
Three-layer design: shared operations power both the CLI and MCP server.
|
|
343
|
+
Three-layer architecture: operations hold all business logic, tools and CLI are thin wrappers.
|
|
295
344
|
|
|
296
345
|
```
|
|
297
346
|
src/
|
|
298
347
|
index.ts Entry: --setup, --mcp, or CLI mode
|
|
299
|
-
mcp.ts MCP server setup, toolset presets
|
|
348
|
+
mcp.ts MCP server setup, admin detection, toolset presets
|
|
300
349
|
setup.ts Cross-platform Chrome cookie extraction
|
|
301
350
|
auth/ AuthConfig from env vars and config file
|
|
302
351
|
clients/ Axios clients for internal (cookie) and public (PAT) APIs
|
|
303
|
-
operations/ Shared business logic (
|
|
352
|
+
operations/ Shared business logic (19 modules)
|
|
304
353
|
tools/ MCP tool wrappers (thin, call operations)
|
|
305
354
|
cli/ CLI Commander wrappers (thin, call operations)
|
|
306
355
|
types/figma.ts Shared types including Toolset union
|
package/dist/auth/client.d.ts
CHANGED
package/dist/auth/health.js
CHANGED
|
@@ -73,7 +73,8 @@ export function formatAuthStatus(status, config) {
|
|
|
73
73
|
if (config.orgId) {
|
|
74
74
|
const currentOrg = config.orgs?.find(o => o.id === config.orgId);
|
|
75
75
|
const orgLabel = currentOrg ? `${currentOrg.name} (${config.orgId})` : config.orgId;
|
|
76
|
-
|
|
76
|
+
const role = config.isAdmin ? 'admin' : 'member';
|
|
77
|
+
lines.push(`\nWorkspace: ${orgLabel} (${role})`);
|
|
77
78
|
const others = (config.orgs || []).filter(o => o.id !== config.orgId);
|
|
78
79
|
if (others.length > 0) {
|
|
79
80
|
lines.push(`Other workspaces: ${others.map(o => `${o.name} (${o.id})`).join(', ')}`);
|
package/dist/cli/comments.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
import { listComments, formatCommentsAsMarkdown, postComment, deleteComment, listCommentReactions, } from '../operations/comments.js';
|
|
2
|
+
import { listComments, formatCommentsAsMarkdown, postComment, deleteComment, resolveComment, editComment, addCommentReaction, removeCommentReaction, listCommentReactions, } from '../operations/comments.js';
|
|
3
3
|
import { output, error } from './format.js';
|
|
4
4
|
import { formatApiError } from '../helpers.js';
|
|
5
|
-
import { requirePat } from './helpers.js';
|
|
5
|
+
import { requirePat, requireCookie } from './helpers.js';
|
|
6
6
|
export function commentsCommand() {
|
|
7
7
|
const comments = new Command('comments')
|
|
8
8
|
.description('Manage file comments');
|
|
@@ -87,6 +87,83 @@ export function commentsCommand() {
|
|
|
87
87
|
process.exit(1);
|
|
88
88
|
}
|
|
89
89
|
});
|
|
90
|
+
comments
|
|
91
|
+
.command('resolve <file-key> <comment-id>')
|
|
92
|
+
.description('Resolve a comment thread')
|
|
93
|
+
.option('--unresolve', 'Unresolve instead of resolve')
|
|
94
|
+
.option('--json', 'Force JSON output')
|
|
95
|
+
.action(async (fileKey, commentId, options) => {
|
|
96
|
+
try {
|
|
97
|
+
const config = requireCookie();
|
|
98
|
+
const msg = await resolveComment(config, {
|
|
99
|
+
file_key: fileKey,
|
|
100
|
+
comment_id: commentId,
|
|
101
|
+
resolved: !options.unresolve,
|
|
102
|
+
});
|
|
103
|
+
output({ message: msg }, options);
|
|
104
|
+
}
|
|
105
|
+
catch (e) {
|
|
106
|
+
error(formatApiError(e));
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
comments
|
|
111
|
+
.command('edit <file-key> <comment-id> <message>')
|
|
112
|
+
.description('Edit the text of an existing comment')
|
|
113
|
+
.option('--json', 'Force JSON output')
|
|
114
|
+
.action(async (fileKey, commentId, message, options) => {
|
|
115
|
+
try {
|
|
116
|
+
const config = requireCookie();
|
|
117
|
+
const msg = await editComment(config, {
|
|
118
|
+
file_key: fileKey,
|
|
119
|
+
comment_id: commentId,
|
|
120
|
+
message,
|
|
121
|
+
});
|
|
122
|
+
output({ message: msg }, options);
|
|
123
|
+
}
|
|
124
|
+
catch (e) {
|
|
125
|
+
error(formatApiError(e));
|
|
126
|
+
process.exit(1);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
comments
|
|
130
|
+
.command('react <file-key> <comment-id> <emoji>')
|
|
131
|
+
.description('Add an emoji reaction to a comment')
|
|
132
|
+
.option('--json', 'Force JSON output')
|
|
133
|
+
.action(async (fileKey, commentId, emoji, options) => {
|
|
134
|
+
try {
|
|
135
|
+
const config = requirePat();
|
|
136
|
+
const result = await addCommentReaction(config, {
|
|
137
|
+
file_key: fileKey,
|
|
138
|
+
comment_id: commentId,
|
|
139
|
+
emoji,
|
|
140
|
+
});
|
|
141
|
+
output(result, options);
|
|
142
|
+
}
|
|
143
|
+
catch (e) {
|
|
144
|
+
error(formatApiError(e));
|
|
145
|
+
process.exit(1);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
comments
|
|
149
|
+
.command('unreact <file-key> <comment-id> <emoji>')
|
|
150
|
+
.description('Remove an emoji reaction from a comment')
|
|
151
|
+
.option('--json', 'Force JSON output')
|
|
152
|
+
.action(async (fileKey, commentId, emoji, options) => {
|
|
153
|
+
try {
|
|
154
|
+
const config = requirePat();
|
|
155
|
+
await removeCommentReaction(config, {
|
|
156
|
+
file_key: fileKey,
|
|
157
|
+
comment_id: commentId,
|
|
158
|
+
emoji,
|
|
159
|
+
});
|
|
160
|
+
output({ removed: emoji, comment_id: commentId }, options);
|
|
161
|
+
}
|
|
162
|
+
catch (e) {
|
|
163
|
+
error(formatApiError(e));
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
90
167
|
return comments;
|
|
91
168
|
}
|
|
92
169
|
//# sourceMappingURL=comments.js.map
|
package/dist/cli/components.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { listFileComponents, listFileStyles, listTeamComponents, listTeamStyles, } from '../operations/components.js';
|
|
3
|
+
import { listDevResources, createDevResource, deleteDevResource, } from '../operations/dev-resources.js';
|
|
3
4
|
import { output, error } from './format.js';
|
|
4
5
|
import { formatApiError } from '../helpers.js';
|
|
5
6
|
import { requirePat } from './helpers.js';
|
|
@@ -94,6 +95,71 @@ export function componentsCommand() {
|
|
|
94
95
|
process.exit(1);
|
|
95
96
|
}
|
|
96
97
|
});
|
|
98
|
+
components
|
|
99
|
+
.command('list-dev-resources <file-key>')
|
|
100
|
+
.description('List dev resources (links, annotations) on a file')
|
|
101
|
+
.option('--node-ids <ids>', 'Comma-separated node IDs to filter')
|
|
102
|
+
.option('--json', 'Force JSON output')
|
|
103
|
+
.action(async (fileKey, options) => {
|
|
104
|
+
try {
|
|
105
|
+
const config = requirePat();
|
|
106
|
+
const result = await listDevResources(config, {
|
|
107
|
+
file_key: fileKey,
|
|
108
|
+
node_ids: options.nodeIds?.split(','),
|
|
109
|
+
});
|
|
110
|
+
if (result.length === 0) {
|
|
111
|
+
console.log('No dev resources found.');
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
output(result, options);
|
|
115
|
+
}
|
|
116
|
+
catch (e) {
|
|
117
|
+
error(formatApiError(e));
|
|
118
|
+
process.exit(1);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
components
|
|
122
|
+
.command('create-dev-resource <file-key> <node-id>')
|
|
123
|
+
.description('Create a dev resource on a node')
|
|
124
|
+
.requiredOption('--name <name>', 'Resource name/label')
|
|
125
|
+
.requiredOption('--url <url>', 'Resource URL')
|
|
126
|
+
.option('--json', 'Force JSON output')
|
|
127
|
+
.action(async (fileKey, nodeId, options) => {
|
|
128
|
+
try {
|
|
129
|
+
const config = requirePat();
|
|
130
|
+
const result = await createDevResource(config, {
|
|
131
|
+
file_key: fileKey,
|
|
132
|
+
node_id: nodeId,
|
|
133
|
+
name: options.name,
|
|
134
|
+
url: options.url,
|
|
135
|
+
});
|
|
136
|
+
output(result, options);
|
|
137
|
+
}
|
|
138
|
+
catch (e) {
|
|
139
|
+
error(formatApiError(e));
|
|
140
|
+
process.exit(1);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
components
|
|
144
|
+
.command('delete-dev-resource <file-key> <dev-resource-id>')
|
|
145
|
+
.description('Delete a dev resource')
|
|
146
|
+
.option('--json', 'Force JSON output')
|
|
147
|
+
.action(async (fileKey, devResourceId, options) => {
|
|
148
|
+
try {
|
|
149
|
+
const config = requirePat();
|
|
150
|
+
const { confirmAction } = await import('./helpers.js');
|
|
151
|
+
if (!await confirmAction(`Delete dev resource ${devResourceId}?`)) {
|
|
152
|
+
console.log('Cancelled.');
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
await deleteDevResource(config, { file_key: fileKey, dev_resource_id: devResourceId });
|
|
156
|
+
output({ deleted: devResourceId }, options);
|
|
157
|
+
}
|
|
158
|
+
catch (e) {
|
|
159
|
+
error(formatApiError(e));
|
|
160
|
+
process.exit(1);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
97
163
|
return components;
|
|
98
164
|
}
|
|
99
165
|
//# sourceMappingURL=components.js.map
|
|
@@ -219,6 +219,7 @@ export function offboardUserCommand() {
|
|
|
219
219
|
.argument('<user>', 'Email or user_id to offboard')
|
|
220
220
|
.option('--execute', 'Execute the offboarding (default: audit only)')
|
|
221
221
|
.option('--transfer-to <user>', 'Email or user_id to transfer file ownership to')
|
|
222
|
+
.option('--remove-from-org', 'Permanently remove from org after offboarding (cannot be undone)')
|
|
222
223
|
.option('--json', 'Force JSON output')
|
|
223
224
|
.action(async (user, options) => {
|
|
224
225
|
try {
|
|
@@ -227,6 +228,7 @@ export function offboardUserCommand() {
|
|
|
227
228
|
user_identifier: user,
|
|
228
229
|
execute: options.execute === true,
|
|
229
230
|
transfer_to: options.transferTo,
|
|
231
|
+
remove_from_org: options.removeFromOrg === true,
|
|
230
232
|
});
|
|
231
233
|
output(result, options);
|
|
232
234
|
}
|