figmanage 1.0.1 → 1.2.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.
Files changed (98) hide show
  1. package/README.md +74 -59
  2. package/dist/cli/analytics.d.ts +3 -0
  3. package/dist/cli/analytics.js +48 -0
  4. package/dist/cli/branching.d.ts +3 -0
  5. package/dist/cli/branching.js +56 -0
  6. package/dist/cli/comments.d.ts +3 -0
  7. package/dist/cli/comments.js +86 -0
  8. package/dist/cli/completion.d.ts +7 -0
  9. package/dist/cli/completion.js +160 -0
  10. package/dist/cli/components.d.ts +3 -0
  11. package/dist/cli/components.js +82 -0
  12. package/dist/cli/compound-commands.d.ts +14 -0
  13. package/dist/cli/compound-commands.js +291 -0
  14. package/dist/cli/export.d.ts +3 -0
  15. package/dist/cli/export.js +51 -0
  16. package/dist/cli/files.d.ts +3 -0
  17. package/dist/cli/files.js +156 -0
  18. package/dist/cli/format.js +147 -2
  19. package/dist/cli/helpers.d.ts +7 -0
  20. package/dist/cli/helpers.js +43 -0
  21. package/dist/cli/index.js +68 -89
  22. package/dist/cli/libraries.d.ts +3 -0
  23. package/dist/cli/libraries.js +26 -0
  24. package/dist/cli/navigate.d.ts +3 -0
  25. package/dist/cli/navigate.js +192 -0
  26. package/dist/cli/org.d.ts +3 -0
  27. package/dist/cli/org.js +227 -0
  28. package/dist/cli/permissions.d.ts +3 -0
  29. package/dist/cli/permissions.js +133 -0
  30. package/dist/cli/projects.d.ts +3 -0
  31. package/dist/cli/projects.js +110 -0
  32. package/dist/cli/reading.d.ts +3 -0
  33. package/dist/cli/reading.js +51 -0
  34. package/dist/cli/teams.d.ts +3 -0
  35. package/dist/cli/teams.js +56 -0
  36. package/dist/cli/variables.d.ts +3 -0
  37. package/dist/cli/variables.js +80 -0
  38. package/dist/cli/versions.d.ts +3 -0
  39. package/dist/cli/versions.js +46 -0
  40. package/dist/cli/webhooks.d.ts +3 -0
  41. package/dist/cli/webhooks.js +100 -0
  42. package/dist/operations/analytics.d.ts +10 -0
  43. package/dist/operations/analytics.js +15 -0
  44. package/dist/operations/branching.d.ts +24 -0
  45. package/dist/operations/branching.js +41 -0
  46. package/dist/operations/comments.d.ts +43 -0
  47. package/dist/operations/comments.js +65 -0
  48. package/dist/operations/components.d.ts +24 -0
  49. package/dist/operations/components.js +30 -0
  50. package/dist/operations/compound-manager.d.ts +101 -0
  51. package/dist/operations/compound-manager.js +629 -0
  52. package/dist/operations/compound.d.ts +102 -0
  53. package/dist/operations/compound.js +595 -0
  54. package/dist/operations/export.d.ts +19 -0
  55. package/dist/operations/export.js +27 -0
  56. package/dist/operations/files.d.ts +55 -0
  57. package/dist/operations/files.js +89 -0
  58. package/dist/operations/libraries.d.ts +5 -0
  59. package/dist/operations/libraries.js +10 -0
  60. package/dist/operations/navigate.d.ts +99 -0
  61. package/dist/operations/navigate.js +266 -0
  62. package/dist/operations/org.d.ts +95 -0
  63. package/dist/operations/org.js +205 -0
  64. package/dist/operations/permissions.d.ts +59 -0
  65. package/dist/operations/permissions.js +112 -0
  66. package/dist/operations/projects.d.ts +29 -0
  67. package/dist/operations/projects.js +40 -0
  68. package/dist/operations/reading.d.ts +12 -0
  69. package/dist/operations/reading.js +20 -0
  70. package/dist/operations/teams.d.ts +17 -0
  71. package/dist/operations/teams.js +17 -0
  72. package/dist/operations/variables.d.ts +17 -0
  73. package/dist/operations/variables.js +39 -0
  74. package/dist/operations/versions.d.ts +23 -0
  75. package/dist/operations/versions.js +27 -0
  76. package/dist/operations/webhooks.d.ts +25 -0
  77. package/dist/operations/webhooks.js +38 -0
  78. package/dist/tools/analytics.js +6 -16
  79. package/dist/tools/branching.js +7 -36
  80. package/dist/tools/comments.js +9 -56
  81. package/dist/tools/components.js +7 -19
  82. package/dist/tools/compound-manager.js +21 -644
  83. package/dist/tools/compound.js +32 -566
  84. package/dist/tools/export.js +4 -23
  85. package/dist/tools/files.js +21 -68
  86. package/dist/tools/libraries.js +4 -11
  87. package/dist/tools/navigate.js +23 -246
  88. package/dist/tools/org.js +29 -245
  89. package/dist/tools/permissions.js +18 -97
  90. package/dist/tools/projects.js +8 -27
  91. package/dist/tools/reading.js +5 -15
  92. package/dist/tools/teams.js +8 -16
  93. package/dist/tools/variables.js +13 -30
  94. package/dist/tools/versions.js +6 -24
  95. package/dist/tools/webhooks.js +7 -24
  96. package/package.json +1 -1
  97. package/dist/cli/commands.d.ts +0 -47
  98. package/dist/cli/commands.js +0 -1204
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # figmanage
2
2
 
3
- Figma workspace management from the command line. 85 commands for seats, teams, permissions, billing, onboarding, and org admin. Also works as an MCP server for AI assistants.
3
+ Figma workspace management from the command line. 85 CLI commands and MCP tools for seats, teams, permissions, billing, onboarding, and org admin. Also works as an MCP server for AI assistants.
4
4
 
5
5
  ## install
6
6
 
@@ -23,22 +23,25 @@ figmanage logout # clear credentials
23
23
 
24
24
  ## usage
25
25
 
26
+ Commands use a noun-verb pattern: `figmanage <group> <action>`.
27
+
26
28
  ```bash
27
- figmanage seat-optimization # find inactive paid seats
28
- figmanage offboard sarah@co.com # audit what a user owns
29
- figmanage offboard sarah@co.com --execute \
30
- --transfer-to jake@co.com # execute the offboarding
31
- figmanage onboard alex@co.com --teams 123,456 \
32
- --role editor --seat full --confirm # set up a new hire
33
- figmanage quarterly-report # org-wide design ops snapshot
34
- figmanage members --search danny # find org members
35
- figmanage teams # list all teams
36
- figmanage permissions file abc123 # who has access to a file
37
- figmanage permission-audit --scope team --id 789 # audit a team's permissions
38
- figmanage branch-cleanup 573408414 # find stale branches
29
+ figmanage org seat-optimization # find inactive paid seats
30
+ figmanage org offboard sarah@co.com # audit what a user owns
31
+ figmanage org offboard sarah@co.com --execute \
32
+ --transfer-to jake@co.com # execute the offboarding
33
+ figmanage org onboard alex@co.com --teams 123,456 \
34
+ --role editor --seat full --confirm # set up a new hire
35
+ figmanage org quarterly-report # org-wide design ops snapshot
36
+ figmanage org members --search danny # find org members
37
+ figmanage navigate list-teams # list all teams
38
+ figmanage permissions get file abc123 # who has access to a file
39
+ figmanage permissions audit --scope team --id 789 # audit a team's permissions
40
+ figmanage branches cleanup 573408414 # find stale branches
41
+ figmanage files summary abc123 # pages, components, styles overview
39
42
  ```
40
43
 
41
- All commands output JSON when piped or when `--json` is passed.
44
+ Run `figmanage <group> --help` for available subcommands. All commands output JSON when piped or when `--json` is passed.
42
45
 
43
46
  ## AI integration (MCP)
44
47
 
@@ -90,6 +93,8 @@ Auth resolution: env vars > config file > prompt to run `figmanage login`.
90
93
 
91
94
  ## commands
92
95
 
96
+ The tables below list all 85 commands. The Command column shows MCP tool names (snake_case). The CLI equivalent is the noun-verb form: `figmanage <group> <action>` where `<action>` is the kebab-case version of the tool name without the group prefix (e.g. `list_recent_files` becomes `figmanage navigate list-recent-files`).
97
+
93
98
  ### navigate (10)
94
99
 
95
100
  | Command | Auth | Description |
@@ -105,7 +110,7 @@ Auth resolution: env vars > config file > prompt to run `figmanage login`.
105
110
  | `get_file_info` | either | File metadata: name, project, team, link access |
106
111
  | `list_favorites` | cookie | Favorited files (broken -- Figma BigInt bug) |
107
112
 
108
- ### files (8)
113
+ ### files (10)
109
114
 
110
115
  | Command | Auth | Description |
111
116
  |---------|------|-------------|
@@ -117,8 +122,10 @@ Auth resolution: env vars > config file > prompt to run `figmanage login`.
117
122
  | `restore_files` | cookie | Restore files from trash (batch) |
118
123
  | `favorite_file` | cookie | Add/remove from favorites |
119
124
  | `set_link_access` | cookie | Set link sharing level |
125
+ | `file_summary` | pat | Pages, components, styles, comment counts |
126
+ | `cleanup_stale_files` | either | Find old files, optionally trash (dry run default) |
120
127
 
121
- ### projects (6)
128
+ ### projects (8)
122
129
 
123
130
  | Command | Auth | Description |
124
131
  |---------|------|-------------|
@@ -128,8 +135,10 @@ Auth resolution: env vars > config file > prompt to run `figmanage login`.
128
135
  | `trash_project` | cookie | Move a project to trash |
129
136
  | `restore_project` | cookie | Restore a project from trash |
130
137
  | `set_project_description` | cookie | Set or update project description |
138
+ | `organize_project` | cookie | Batch-move files into a project |
139
+ | `setup_project_structure` | cookie | Create multiple projects from a plan |
131
140
 
132
- ### permissions (7)
141
+ ### permissions (8)
133
142
 
134
143
  | Command | Auth | Description |
135
144
  |---------|------|-------------|
@@ -140,22 +149,7 @@ Auth resolution: env vars > config file > prompt to run `figmanage login`.
140
149
  | `list_role_requests` | cookie | List pending access requests |
141
150
  | `approve_role_request` | cookie | Accept an access request |
142
151
  | `deny_role_request` | cookie | Decline an access request |
143
-
144
- ### reading (2)
145
-
146
- | Command | Auth | Description |
147
- |---------|------|-------------|
148
- | `get_file` | pat | Read file as a node tree with depth control |
149
- | `get_nodes` | pat | Read specific nodes by ID |
150
-
151
- ### components (4)
152
-
153
- | Command | Auth | Description |
154
- |---------|------|-------------|
155
- | `list_file_components` | pat | Components published from a file |
156
- | `list_file_styles` | pat | Styles in a file |
157
- | `list_team_components` | pat | Published components across a team |
158
- | `list_team_styles` | pat | Published styles across a team |
152
+ | `permission_audit` | cookie | Team/project access audit with oversharing flags |
159
153
 
160
154
  ### versions (2)
161
155
 
@@ -164,15 +158,16 @@ Auth resolution: env vars > config file > prompt to run `figmanage login`.
164
158
  | `list_versions` | pat | Version history |
165
159
  | `create_version` | cookie | Create a named version checkpoint |
166
160
 
167
- ### branching (3)
161
+ ### branches (4)
168
162
 
169
163
  | Command | Auth | Description |
170
164
  |---------|------|-------------|
171
165
  | `list_branches` | either | List branches of a file |
172
166
  | `create_branch` | cookie | Create a branch |
173
167
  | `delete_branch` | cookie | Archive a branch |
168
+ | `branch_cleanup` | either | Stale branch detection with optional archival |
174
169
 
175
- ### comments (4)
170
+ ### comments (5)
176
171
 
177
172
  | Command | Auth | Description |
178
173
  |---------|------|-------------|
@@ -180,6 +175,7 @@ Auth resolution: env vars > config file > prompt to run `figmanage login`.
180
175
  | `post_comment` | pat | Post a comment |
181
176
  | `delete_comment` | pat | Delete a comment |
182
177
  | `list_comment_reactions` | pat | Emoji reactions on a comment |
178
+ | `open_comments` | pat | Unresolved comments across a project |
183
179
 
184
180
  ### export (2)
185
181
 
@@ -188,6 +184,22 @@ Auth resolution: env vars > config file > prompt to run `figmanage login`.
188
184
  | `export_nodes` | pat | Export as PNG, SVG, PDF, or JPG |
189
185
  | `get_image_fills` | pat | URLs for all images used as fills |
190
186
 
187
+ ### reading (2)
188
+
189
+ | Command | Auth | Description |
190
+ |---------|------|-------------|
191
+ | `get_file` | pat | Read file as a node tree with depth control |
192
+ | `get_nodes` | pat | Read specific nodes by ID |
193
+
194
+ ### components (4)
195
+
196
+ | Command | Auth | Description |
197
+ |---------|------|-------------|
198
+ | `list_file_components` | pat | Components published from a file |
199
+ | `list_file_styles` | pat | Styles in a file |
200
+ | `list_team_components` | pat | Published components across a team |
201
+ | `list_team_styles` | pat | Published styles across a team |
202
+
191
203
  ### webhooks (4)
192
204
 
193
205
  | Command | Auth | Description |
@@ -212,7 +224,7 @@ Auth resolution: env vars > config file > prompt to run `figmanage login`.
212
224
  | `library_usage` | cookie | Team-level library adoption metrics |
213
225
  | `component_usage` | cookie | Per-file component usage |
214
226
 
215
- ### org (12)
227
+ ### org (17)
216
228
 
217
229
  | Command | Auth | Description |
218
230
  |---------|------|-------------|
@@ -228,14 +240,11 @@ Auth resolution: env vars > config file > prompt to run `figmanage login`.
228
240
  | `org_domains` | cookie | Domain config and SSO/SAML |
229
241
  | `ai_credit_usage` | cookie | AI credit usage summary |
230
242
  | `export_members` | cookie | Trigger CSV export of all members |
231
-
232
- ### teams (3)
233
-
234
- | Command | Auth | Description |
235
- |---------|------|-------------|
236
- | `create_team` | cookie | Create a team |
237
- | `rename_team` | cookie | Rename a team |
238
- | `delete_team` | cookie | Delete a team |
243
+ | `workspace_overview` | cookie | Org snapshot: teams, seats, billing |
244
+ | `seat_optimization` | cookie | Inactive seat detection with cost analysis |
245
+ | `offboard_user` | cookie | Audit + execute user departure |
246
+ | `onboard_user` | cookie | Batch invite to teams, share files, set seat |
247
+ | `quarterly_design_ops_report` | cookie | Seat utilization, billing, teams, library adoption |
239
248
 
240
249
  ### libraries (1)
241
250
 
@@ -243,24 +252,13 @@ Auth resolution: env vars > config file > prompt to run `figmanage login`.
243
252
  |---------|------|-------------|
244
253
  | `list_org_libraries` | cookie | Design system libraries with sharing info |
245
254
 
246
- ### compound (12)
247
-
248
- Multi-step operations that aggregate data from several API calls.
255
+ ### teams (3)
249
256
 
250
257
  | Command | Auth | Description |
251
258
  |---------|------|-------------|
252
- | `file_summary` | pat | Pages, components, styles, comment counts |
253
- | `workspace_overview` | cookie | Org snapshot: teams, seats, billing |
254
- | `open_comments` | pat | Unresolved comments across a project |
255
- | `cleanup_stale_files` | either | Find old files, optionally trash (dry run default) |
256
- | `organize_project` | cookie | Batch-move files into a project |
257
- | `setup_project_structure` | cookie | Create multiple projects from a plan |
258
- | `seat_optimization` | cookie | Inactive seat detection with cost analysis |
259
- | `permission_audit` | cookie | Team/project access audit with oversharing flags |
260
- | `branch_cleanup` | either | Stale branch detection with optional archival |
261
- | `offboard_user` | cookie | Audit + execute user departure |
262
- | `onboard_user` | cookie | Batch invite to teams, share files, set seat |
263
- | `quarterly_design_ops_report` | cookie | Seat utilization, billing, teams, library adoption |
259
+ | `create_team` | cookie | Create a team |
260
+ | `rename_team` | cookie | Rename a team |
261
+ | `delete_team` | cookie | Delete a team |
264
262
 
265
263
  ## security
266
264
 
@@ -285,6 +283,23 @@ npm run build
285
283
  npm test
286
284
  ```
287
285
 
286
+ ### architecture
287
+
288
+ Three-layer design: shared operations power both the CLI and MCP server.
289
+
290
+ ```
291
+ src/
292
+ index.ts Entry: --setup, --mcp, or CLI mode
293
+ mcp.ts MCP server setup, toolset presets
294
+ setup.ts Cross-platform Chrome cookie extraction
295
+ auth/ AuthConfig from env vars and config file
296
+ clients/ Axios clients for internal (cookie) and public (PAT) APIs
297
+ operations/ Shared business logic (18 modules)
298
+ tools/ MCP tool wrappers (thin, call operations)
299
+ cli/ CLI Commander wrappers (thin, call operations)
300
+ types/figma.ts Shared types including Toolset union
301
+ ```
302
+
288
303
  ## license
289
304
 
290
305
  MIT
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function analyticsCommand(): Command;
3
+ //# sourceMappingURL=analytics.d.ts.map
@@ -0,0 +1,48 @@
1
+ import { Command } from 'commander';
2
+ import { libraryUsage, componentUsage } from '../operations/analytics.js';
3
+ import { output, error } from './format.js';
4
+ import { requireCookie } from './helpers.js';
5
+ export function analyticsCommand() {
6
+ const analytics = new Command('analytics')
7
+ .description('Design system analytics');
8
+ analytics
9
+ .command('library-usage <library-file-key>')
10
+ .description('Team-level library adoption metrics')
11
+ .option('--days <n>', 'Lookback period in days (default: 30)')
12
+ .option('--json', 'Force JSON output')
13
+ .action(async (libraryFileKey, options) => {
14
+ try {
15
+ const config = requireCookie();
16
+ const result = await libraryUsage(config, {
17
+ library_file_key: libraryFileKey,
18
+ days: options.days ? parseInt(options.days, 10) : undefined,
19
+ });
20
+ output(result, options);
21
+ }
22
+ catch (e) {
23
+ error(e.response?.status ? `API error: ${e.response.status}` : e.message);
24
+ process.exit(1);
25
+ }
26
+ });
27
+ analytics
28
+ .command('component-usage <component-key>')
29
+ .description('Per-file component usage analytics')
30
+ .option('--org-id <id>', 'Org ID override (defaults to current workspace)')
31
+ .option('--json', 'Force JSON output')
32
+ .action(async (componentKey, options) => {
33
+ try {
34
+ const config = requireCookie();
35
+ const result = await componentUsage(config, {
36
+ component_key: componentKey,
37
+ org_id: options.orgId,
38
+ });
39
+ output(result, options);
40
+ }
41
+ catch (e) {
42
+ error(e.response?.status ? `API error: ${e.response.status}` : e.message);
43
+ process.exit(1);
44
+ }
45
+ });
46
+ return analytics;
47
+ }
48
+ //# sourceMappingURL=analytics.js.map
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function branchingCommand(): Command;
3
+ //# sourceMappingURL=branching.d.ts.map
@@ -0,0 +1,56 @@
1
+ import { Command } from 'commander';
2
+ import { listBranches, createBranch, deleteBranch } from '../operations/branching.js';
3
+ import { output, error } from './format.js';
4
+ import { requireAuth, requireCookie } from './helpers.js';
5
+ export function branchingCommand() {
6
+ const branching = new Command('branches')
7
+ .description('Manage file branches');
8
+ branching
9
+ .command('list <file-key>')
10
+ .description('List branches of a file')
11
+ .option('--json', 'Force JSON output')
12
+ .action(async (fileKey, options) => {
13
+ try {
14
+ const config = requireAuth();
15
+ const result = await listBranches(config, { file_key: fileKey });
16
+ output(result, options);
17
+ }
18
+ catch (e) {
19
+ error(e.response?.status ? `API error: ${e.response.status}` : e.message);
20
+ process.exit(1);
21
+ }
22
+ });
23
+ branching
24
+ .command('create <file-key>')
25
+ .description('Create a branch from a file')
26
+ .requiredOption('--name <name>', 'Branch name')
27
+ .option('--json', 'Force JSON output')
28
+ .action(async (fileKey, options) => {
29
+ try {
30
+ const config = requireCookie();
31
+ const result = await createBranch(config, { file_key: fileKey, name: options.name });
32
+ output(result, options);
33
+ }
34
+ catch (e) {
35
+ error(e.response?.status ? `API error: ${e.response.status}` : e.message);
36
+ process.exit(1);
37
+ }
38
+ });
39
+ branching
40
+ .command('delete <branch-key>')
41
+ .description('Archive (delete) a branch')
42
+ .option('--json', 'Force JSON output')
43
+ .action(async (branchKey, options) => {
44
+ try {
45
+ const config = requireCookie();
46
+ await deleteBranch(config, { branch_key: branchKey });
47
+ output({ archived: branchKey }, options);
48
+ }
49
+ catch (e) {
50
+ error(e.response?.status ? `API error: ${e.response.status}` : e.message);
51
+ process.exit(1);
52
+ }
53
+ });
54
+ return branching;
55
+ }
56
+ //# sourceMappingURL=branching.js.map
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function commentsCommand(): Command;
3
+ //# sourceMappingURL=comments.d.ts.map
@@ -0,0 +1,86 @@
1
+ import { Command } from 'commander';
2
+ import { listComments, formatCommentsAsMarkdown, postComment, deleteComment, listCommentReactions, } from '../operations/comments.js';
3
+ import { output, error } from './format.js';
4
+ import { requirePat } from './helpers.js';
5
+ export function commentsCommand() {
6
+ const comments = new Command('comments')
7
+ .description('Manage file comments');
8
+ comments
9
+ .command('list <file-key>')
10
+ .description('List comments on a file')
11
+ .option('--md', 'Format as markdown threads')
12
+ .option('--json', 'Force JSON output')
13
+ .action(async (fileKey, options) => {
14
+ try {
15
+ const config = requirePat();
16
+ const result = await listComments(config, { file_key: fileKey });
17
+ if (options.md) {
18
+ console.log(formatCommentsAsMarkdown(result));
19
+ return;
20
+ }
21
+ output(result, options);
22
+ }
23
+ catch (e) {
24
+ error(e.response?.status ? `API error: ${e.response.status}` : e.message);
25
+ process.exit(1);
26
+ }
27
+ });
28
+ comments
29
+ .command('post <file-key>')
30
+ .description('Post a comment on a file')
31
+ .requiredOption('--message <text>', 'Comment text')
32
+ .option('--reply-to <comment-id>', 'Parent comment ID to reply to')
33
+ .option('--node <node-id>', 'Node ID to pin the comment to')
34
+ .option('--json', 'Force JSON output')
35
+ .action(async (fileKey, options) => {
36
+ try {
37
+ const config = requirePat();
38
+ const result = await postComment(config, {
39
+ file_key: fileKey,
40
+ message: options.message,
41
+ comment_id: options.replyTo,
42
+ node_id: options.node,
43
+ });
44
+ output(result, options);
45
+ }
46
+ catch (e) {
47
+ error(e.response?.status ? `API error: ${e.response.status}` : e.message);
48
+ process.exit(1);
49
+ }
50
+ });
51
+ comments
52
+ .command('delete <file-key> <comment-id>')
53
+ .description('Delete a comment (removes entire thread if top-level)')
54
+ .option('--json', 'Force JSON output')
55
+ .action(async (fileKey, commentId, options) => {
56
+ try {
57
+ const config = requirePat();
58
+ await deleteComment(config, { file_key: fileKey, comment_id: commentId });
59
+ output({ deleted: commentId }, options);
60
+ }
61
+ catch (e) {
62
+ error(e.response?.status ? `API error: ${e.response.status}` : e.message);
63
+ process.exit(1);
64
+ }
65
+ });
66
+ comments
67
+ .command('reactions <file-key> <comment-id>')
68
+ .description('List emoji reactions on a comment')
69
+ .option('--json', 'Force JSON output')
70
+ .action(async (fileKey, commentId, options) => {
71
+ try {
72
+ const config = requirePat();
73
+ const result = await listCommentReactions(config, {
74
+ file_key: fileKey,
75
+ comment_id: commentId,
76
+ });
77
+ output(result, options);
78
+ }
79
+ catch (e) {
80
+ error(e.response?.status ? `API error: ${e.response.status}` : e.message);
81
+ process.exit(1);
82
+ }
83
+ });
84
+ return comments;
85
+ }
86
+ //# sourceMappingURL=comments.js.map
@@ -0,0 +1,7 @@
1
+ import { Command } from 'commander';
2
+ /**
3
+ * Create the `completion` command. Needs the parent program reference
4
+ * so it can introspect the full command tree at runtime.
5
+ */
6
+ export declare function completionCommand(program: Command): Command;
7
+ //# sourceMappingURL=completion.d.ts.map
@@ -0,0 +1,160 @@
1
+ import { Command } from 'commander';
2
+ /**
3
+ * Introspect a Commander program and extract its command tree.
4
+ * Returns a map of command names to their subcommand names.
5
+ * Top-level commands without subcommands (like login, whoami) get an empty array.
6
+ */
7
+ function extractCommandTree(program) {
8
+ const tree = new Map();
9
+ for (const cmd of program.commands) {
10
+ const subs = cmd.commands.map((sub) => sub.name());
11
+ tree.set(cmd.name(), subs);
12
+ }
13
+ return tree;
14
+ }
15
+ /**
16
+ * Extract all option flags from a command (including inherited ones).
17
+ * Returns long-form flags like --json, --help.
18
+ */
19
+ function extractOptions(cmd) {
20
+ const flags = [];
21
+ for (const opt of cmd.options) {
22
+ if (opt.long)
23
+ flags.push(opt.long);
24
+ }
25
+ return flags;
26
+ }
27
+ /**
28
+ * Collect global options that appear across most commands.
29
+ * These get offered at every completion point.
30
+ */
31
+ function extractGlobalOptions(program) {
32
+ const flags = new Set();
33
+ // Program-level options (--version, etc.)
34
+ for (const opt of program.options) {
35
+ if (opt.long)
36
+ flags.add(opt.long);
37
+ }
38
+ // Common flags present on subcommands
39
+ flags.add('--help');
40
+ flags.add('--json');
41
+ return [...flags];
42
+ }
43
+ function generateZshScript(program) {
44
+ const tree = extractCommandTree(program);
45
+ const globalOpts = extractGlobalOptions(program);
46
+ const topLevelCmds = [...tree.keys()];
47
+ // Build case arms for subcommand completion
48
+ const caseArms = [];
49
+ for (const [group, subs] of tree) {
50
+ if (subs.length > 0) {
51
+ caseArms.push(` ${group})\n local subcmds=(${subs.join(' ')})\n _describe 'subcommand' subcmds\n ;;`);
52
+ }
53
+ }
54
+ return `#compdef figmanage
55
+
56
+ # Shell completion for figmanage
57
+ # Add to ~/.zshrc: eval "$(figmanage completion)"
58
+
59
+ _figmanage() {
60
+ local -a commands
61
+ commands=(${topLevelCmds.join(' ')})
62
+
63
+ local global_opts=(${globalOpts.join(' ')})
64
+
65
+ _arguments -C \\
66
+ '1:command:->cmd' \\
67
+ '2:subcommand:->sub' \\
68
+ '*::options:->opts'
69
+
70
+ case $state in
71
+ cmd)
72
+ _describe 'command' commands
73
+ ;;
74
+ sub)
75
+ case $words[1] in
76
+ ${caseArms.join('\n')}
77
+ *)
78
+ _describe 'option' global_opts
79
+ ;;
80
+ esac
81
+ ;;
82
+ opts)
83
+ _values 'options' $global_opts
84
+ ;;
85
+ esac
86
+ }
87
+
88
+ compdef _figmanage figmanage
89
+ `;
90
+ }
91
+ function generateBashScript(program) {
92
+ const tree = extractCommandTree(program);
93
+ const globalOpts = extractGlobalOptions(program);
94
+ const topLevelCmds = [...tree.keys()];
95
+ // Build case arms for subcommand completion
96
+ const caseArms = [];
97
+ for (const [group, subs] of tree) {
98
+ if (subs.length > 0) {
99
+ caseArms.push(` ${group})\n COMPREPLY=($(compgen -W "${subs.join(' ')}" -- "$cur"))\n ;;`);
100
+ }
101
+ }
102
+ return `# Shell completion for figmanage
103
+ # Add to ~/.bashrc: eval "$(figmanage completion)"
104
+
105
+ _figmanage() {
106
+ local cur prev words cword
107
+ _init_completion || return
108
+
109
+ local commands="${topLevelCmds.join(' ')}"
110
+ local global_opts="${globalOpts.join(' ')}"
111
+
112
+ case $cword in
113
+ 1)
114
+ COMPREPLY=($(compgen -W "$commands" -- "$cur"))
115
+ ;;
116
+ 2)
117
+ case "\${words[1]}" in
118
+ ${caseArms.join('\n')}
119
+ *)
120
+ COMPREPLY=($(compgen -W "$global_opts" -- "$cur"))
121
+ ;;
122
+ esac
123
+ ;;
124
+ *)
125
+ COMPREPLY=($(compgen -W "$global_opts" -- "$cur"))
126
+ ;;
127
+ esac
128
+ }
129
+
130
+ complete -F _figmanage figmanage
131
+ `;
132
+ }
133
+ function detectShell() {
134
+ const shell = process.env.SHELL ?? '';
135
+ if (shell.endsWith('/zsh'))
136
+ return 'zsh';
137
+ return 'bash';
138
+ }
139
+ /**
140
+ * Create the `completion` command. Needs the parent program reference
141
+ * so it can introspect the full command tree at runtime.
142
+ */
143
+ export function completionCommand(program) {
144
+ const cmd = new Command('completion')
145
+ .description('Output shell completion script')
146
+ .option('--shell <shell>', 'Shell type (bash or zsh)')
147
+ .action((options) => {
148
+ const shell = options.shell ?? detectShell();
149
+ if (shell !== 'bash' && shell !== 'zsh') {
150
+ console.error(`Unsupported shell: ${shell}. Use --shell bash or --shell zsh.`);
151
+ process.exit(1);
152
+ }
153
+ const script = shell === 'zsh'
154
+ ? generateZshScript(program)
155
+ : generateBashScript(program);
156
+ process.stdout.write(script);
157
+ });
158
+ return cmd;
159
+ }
160
+ //# sourceMappingURL=completion.js.map
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function componentsCommand(): Command;
3
+ //# sourceMappingURL=components.d.ts.map