figmanage 1.2.9 → 1.3.1
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 +10 -8
- package/dist/cli/analytics.js +3 -2
- package/dist/cli/branching.js +9 -3
- package/dist/cli/comments.js +10 -4
- package/dist/cli/components.js +21 -4
- package/dist/cli/compound-commands.js +13 -12
- package/dist/cli/export.js +3 -2
- package/dist/cli/files.js +14 -8
- package/dist/cli/helpers.d.ts +1 -0
- package/dist/cli/helpers.js +10 -0
- package/dist/cli/libraries.js +2 -1
- package/dist/cli/navigate.js +11 -10
- package/dist/cli/org.js +13 -12
- package/dist/cli/permissions.js +13 -7
- package/dist/cli/projects.js +12 -6
- package/dist/cli/reading.js +3 -2
- package/dist/cli/teams.js +9 -3
- package/dist/cli/variables.js +29 -7
- package/dist/cli/versions.js +3 -2
- package/dist/cli/webhooks.js +14 -4
- package/dist/helpers.d.ts +11 -0
- package/dist/helpers.js +41 -0
- package/dist/mcp.js +18 -6
- package/dist/operations/analytics.js +1 -1
- package/dist/operations/components.d.ts +8 -2
- package/dist/operations/components.js +4 -2
- package/dist/operations/compound-manager.js +8 -9
- package/dist/operations/compound.d.ts +3 -0
- package/dist/operations/compound.js +14 -8
- package/dist/operations/files.js +1 -1
- package/dist/operations/libraries.js +1 -1
- package/dist/operations/org.js +1 -1
- package/dist/operations/reading.js +2 -0
- package/dist/operations/teams.js +1 -1
- package/dist/operations/variables.js +11 -0
- package/dist/operations/webhooks.d.ts +4 -1
- package/dist/operations/webhooks.js +2 -1
- package/dist/tools/analytics.js +6 -5
- package/dist/tools/branching.js +7 -6
- package/dist/tools/comments.js +14 -9
- package/dist/tools/components.js +24 -15
- package/dist/tools/compound-manager.js +10 -7
- package/dist/tools/compound.js +34 -22
- package/dist/tools/export.js +6 -5
- package/dist/tools/files.js +13 -12
- package/dist/tools/libraries.js +6 -3
- package/dist/tools/navigate.js +29 -18
- package/dist/tools/org.js +25 -24
- package/dist/tools/permissions.js +14 -11
- package/dist/tools/projects.js +10 -9
- package/dist/tools/reading.js +11 -7
- package/dist/tools/register.d.ts +8 -2
- package/dist/tools/register.js +9 -14
- package/dist/tools/setup.d.ts +10 -0
- package/dist/tools/setup.js +181 -0
- package/dist/tools/teams.js +7 -6
- package/dist/tools/variables.js +12 -8
- package/dist/tools/versions.js +6 -5
- package/dist/tools/webhooks.js +15 -12
- package/package.json +1 -1
package/dist/tools/compound.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { defineTool,
|
|
2
|
+
import { defineTool, toolError, toolSummary, figmaId } from './register.js';
|
|
3
|
+
import { formatApiError } from '../helpers.js';
|
|
3
4
|
import { fileSummary, workspaceOverview, openComments, cleanupStaleFiles, organizeProject, setupProjectStructure, seatOptimization, permissionAudit, branchCleanup, } from '../operations/compound.js';
|
|
4
5
|
// -- file_summary --
|
|
5
6
|
defineTool({
|
|
@@ -14,10 +15,10 @@ defineTool({
|
|
|
14
15
|
}, async ({ file_key }) => {
|
|
15
16
|
try {
|
|
16
17
|
const result = await fileSummary(config, { file_key });
|
|
17
|
-
return
|
|
18
|
+
return toolSummary(`${result.name}: ${result.pages?.length || 0} pages, ${result.component_count} components, ${result.unresolved_comment_count} unresolved comments.`, result);
|
|
18
19
|
}
|
|
19
20
|
catch (e) {
|
|
20
|
-
return toolError(`Failed to summarize file: ${e
|
|
21
|
+
return toolError(`Failed to summarize file: ${formatApiError(e)}`);
|
|
21
22
|
}
|
|
22
23
|
});
|
|
23
24
|
},
|
|
@@ -35,10 +36,11 @@ defineTool({
|
|
|
35
36
|
}, async ({ org_id }) => {
|
|
36
37
|
try {
|
|
37
38
|
const result = await workspaceOverview(config, { org_id });
|
|
38
|
-
|
|
39
|
+
const teamCount = result.teams?.length || 0;
|
|
40
|
+
return toolSummary(`${teamCount} team(s). Seats and billing included.`, result);
|
|
39
41
|
}
|
|
40
42
|
catch (e) {
|
|
41
|
-
return toolError(`Failed to fetch workspace overview: ${e
|
|
43
|
+
return toolError(`Failed to fetch workspace overview: ${formatApiError(e)}`);
|
|
42
44
|
}
|
|
43
45
|
});
|
|
44
46
|
},
|
|
@@ -56,10 +58,12 @@ defineTool({
|
|
|
56
58
|
}, async ({ project_id }) => {
|
|
57
59
|
try {
|
|
58
60
|
const result = await openComments(config, { project_id });
|
|
59
|
-
|
|
61
|
+
const total = result.total_unresolved || 0;
|
|
62
|
+
const fileCount = result.files?.length || 0;
|
|
63
|
+
return toolSummary(`${total} unresolved comment(s) across ${fileCount} file(s).`, result, 'Use post_comment with file_key and parent_id to reply.');
|
|
60
64
|
}
|
|
61
65
|
catch (e) {
|
|
62
|
-
return toolError(`Failed to fetch open comments: ${e
|
|
66
|
+
return toolError(`Failed to fetch open comments: ${formatApiError(e)}`);
|
|
63
67
|
}
|
|
64
68
|
});
|
|
65
69
|
},
|
|
@@ -72,7 +76,7 @@ defineTool({
|
|
|
72
76
|
destructive: true,
|
|
73
77
|
register(server, config) {
|
|
74
78
|
server.registerTool('cleanup_stale_files', {
|
|
75
|
-
description: 'Find files not modified in N days and optionally trash them.
|
|
79
|
+
description: 'Find files not modified in N days and optionally trash them. dry_run=true (default) previews which files would be trashed without trashing them. Set dry_run=false to execute.',
|
|
76
80
|
inputSchema: {
|
|
77
81
|
project_id: figmaId.describe('Project ID'),
|
|
78
82
|
days_stale: z.number().optional().default(90).describe('Days since last modification (default: 90)'),
|
|
@@ -85,10 +89,12 @@ defineTool({
|
|
|
85
89
|
days_stale: days_stale ?? 90,
|
|
86
90
|
dry_run: rawDryRun ?? true,
|
|
87
91
|
});
|
|
88
|
-
|
|
92
|
+
const count = result.stale_files?.length || 0;
|
|
93
|
+
const action = result.dry_run ? `${count} stale file(s) found. Set dry_run=false to trash them.` : `Trashed ${result.trashed_count || 0} file(s).`;
|
|
94
|
+
return toolSummary(action, result);
|
|
89
95
|
}
|
|
90
96
|
catch (e) {
|
|
91
|
-
return toolError(`Failed to cleanup stale files: ${e
|
|
97
|
+
return toolError(`Failed to cleanup stale files: ${formatApiError(e)}`);
|
|
92
98
|
}
|
|
93
99
|
});
|
|
94
100
|
},
|
|
@@ -100,7 +106,7 @@ defineTool({
|
|
|
100
106
|
mutates: true,
|
|
101
107
|
register(server, config) {
|
|
102
108
|
server.registerTool('organize_project', {
|
|
103
|
-
description: 'Move
|
|
109
|
+
description: 'Move files into a target project in a single batch. Files are moved (not copied) from their current project.',
|
|
104
110
|
inputSchema: {
|
|
105
111
|
file_keys: z.array(figmaId).min(1).describe('File keys to move'),
|
|
106
112
|
target_project_id: figmaId.describe('Destination project ID'),
|
|
@@ -108,10 +114,10 @@ defineTool({
|
|
|
108
114
|
}, async ({ file_keys, target_project_id }) => {
|
|
109
115
|
try {
|
|
110
116
|
const result = await organizeProject(config, { file_keys, target_project_id });
|
|
111
|
-
return
|
|
117
|
+
return toolSummary(`Moved ${result.moved} file(s) to project ${result.target_project_id}.`, result);
|
|
112
118
|
}
|
|
113
119
|
catch (e) {
|
|
114
|
-
return toolError(`Failed to organize project: ${e
|
|
120
|
+
return toolError(`Failed to organize project: ${formatApiError(e)}`);
|
|
115
121
|
}
|
|
116
122
|
});
|
|
117
123
|
},
|
|
@@ -134,10 +140,10 @@ defineTool({
|
|
|
134
140
|
}, async ({ team_id, projects }) => {
|
|
135
141
|
try {
|
|
136
142
|
const result = await setupProjectStructure(config, { team_id, projects });
|
|
137
|
-
return
|
|
143
|
+
return toolSummary(`Created ${result.created?.length || 0} project(s).`, result);
|
|
138
144
|
}
|
|
139
145
|
catch (e) {
|
|
140
|
-
return toolError(`Failed to setup project structure: ${e
|
|
146
|
+
return toolError(`Failed to setup project structure: ${formatApiError(e)}`);
|
|
141
147
|
}
|
|
142
148
|
});
|
|
143
149
|
},
|
|
@@ -161,10 +167,13 @@ defineTool({
|
|
|
161
167
|
days_inactive: days_inactive ?? 90,
|
|
162
168
|
include_cost: include_cost ?? true,
|
|
163
169
|
});
|
|
164
|
-
|
|
170
|
+
const inactive = result.summary?.inactive_paid || 0;
|
|
171
|
+
const savingsCents = result.summary?.monthly_waste_cents || 0;
|
|
172
|
+
const savingsStr = savingsCents > 0 ? ` Potential savings: $${(savingsCents / 100).toFixed(2)}/mo.` : '';
|
|
173
|
+
return toolSummary(`${inactive} inactive paid seat(s).${savingsStr}`, result, 'Use change_seat to downgrade inactive users, or offboard_user for full removal.');
|
|
165
174
|
}
|
|
166
175
|
catch (e) {
|
|
167
|
-
return toolError(`Failed to analyze seat optimization: ${e
|
|
176
|
+
return toolError(`Failed to analyze seat optimization: ${formatApiError(e)}`);
|
|
168
177
|
}
|
|
169
178
|
});
|
|
170
179
|
},
|
|
@@ -190,10 +199,11 @@ defineTool({
|
|
|
190
199
|
flag_external: flag_external ?? true,
|
|
191
200
|
org_id,
|
|
192
201
|
});
|
|
193
|
-
|
|
202
|
+
const flagCount = result.flags?.length || 0;
|
|
203
|
+
return toolSummary(`${flagCount} issue(s) flagged.`, result, flagCount > 0 ? 'Use revoke_access or set_permissions to address flagged issues.' : undefined);
|
|
194
204
|
}
|
|
195
205
|
catch (e) {
|
|
196
|
-
return toolError(`Failed to audit permissions: ${e
|
|
206
|
+
return toolError(`Failed to audit permissions: ${formatApiError(e)}`);
|
|
197
207
|
}
|
|
198
208
|
});
|
|
199
209
|
},
|
|
@@ -206,7 +216,7 @@ defineTool({
|
|
|
206
216
|
destructive: true,
|
|
207
217
|
register(server, config) {
|
|
208
218
|
server.registerTool('branch_cleanup', {
|
|
209
|
-
description: 'Find stale branches across a project and optionally archive them.
|
|
219
|
+
description: 'Find stale branches across a project and optionally archive them. dry_run=true (default) previews which branches would be archived. Archives move branch files to trash (recoverable).',
|
|
210
220
|
inputSchema: {
|
|
211
221
|
project_id: figmaId.describe('Project ID'),
|
|
212
222
|
days_stale: z.number().min(1).max(365).optional().default(60).describe('Days since last modification to flag as stale (default: 60)'),
|
|
@@ -219,10 +229,12 @@ defineTool({
|
|
|
219
229
|
days_stale: days_stale ?? 60,
|
|
220
230
|
dry_run: rawDryRun ?? true,
|
|
221
231
|
});
|
|
222
|
-
|
|
232
|
+
const stale = result.stale_branches?.length || 0;
|
|
233
|
+
const action = result.dry_run ? `${stale} stale branch(es) found. Set dry_run=false to archive.` : `Archived ${result.archived_count || 0} branch(es).`;
|
|
234
|
+
return toolSummary(action, result);
|
|
223
235
|
}
|
|
224
236
|
catch (e) {
|
|
225
|
-
return toolError(`Failed to cleanup branches: ${e
|
|
237
|
+
return toolError(`Failed to cleanup branches: ${formatApiError(e)}`);
|
|
226
238
|
}
|
|
227
239
|
});
|
|
228
240
|
},
|
package/dist/tools/export.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { defineTool, toolResult, toolError, figmaId } from './register.js';
|
|
2
|
+
import { defineTool, toolResult, toolError, toolSummary, figmaId } from './register.js';
|
|
3
|
+
import { formatApiError } from '../helpers.js';
|
|
3
4
|
import { exportNodes, getImageFills } from '../operations/export.js';
|
|
4
5
|
// -- export_nodes --
|
|
5
6
|
defineTool({
|
|
@@ -17,10 +18,10 @@ defineTool({
|
|
|
17
18
|
}, async ({ file_key, node_ids, format, scale }) => {
|
|
18
19
|
try {
|
|
19
20
|
const result = await exportNodes(config, { file_key, node_ids, format, scale });
|
|
20
|
-
return
|
|
21
|
+
return toolSummary(`Exported ${result.length} node(s). URLs valid ~14 days.`, result);
|
|
21
22
|
}
|
|
22
23
|
catch (e) {
|
|
23
|
-
return toolError(`Failed to export nodes: ${e
|
|
24
|
+
return toolError(`Failed to export nodes: ${formatApiError(e)}`);
|
|
24
25
|
}
|
|
25
26
|
});
|
|
26
27
|
},
|
|
@@ -40,10 +41,10 @@ defineTool({
|
|
|
40
41
|
const results = await getImageFills(config, { file_key });
|
|
41
42
|
if (results.length === 0)
|
|
42
43
|
return toolResult('No image fills in this file.');
|
|
43
|
-
return
|
|
44
|
+
return toolSummary(`${results.length} image fill(s).`, results);
|
|
44
45
|
}
|
|
45
46
|
catch (e) {
|
|
46
|
-
return toolError(`Failed to get image fills: ${e
|
|
47
|
+
return toolError(`Failed to get image fills: ${formatApiError(e)}`);
|
|
47
48
|
}
|
|
48
49
|
});
|
|
49
50
|
},
|
package/dist/tools/files.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { defineTool, toolResult, toolError, figmaId } from './register.js';
|
|
2
|
+
import { defineTool, toolResult, toolError, toolSummary, figmaId } from './register.js';
|
|
3
|
+
import { formatApiError } from '../helpers.js';
|
|
3
4
|
import { createFile, renameFile, moveFiles, duplicateFile, trashFiles, restoreFiles, favoriteFile, setLinkAccess, } from '../operations/files.js';
|
|
4
5
|
// -- create_file --
|
|
5
6
|
defineTool({
|
|
@@ -17,10 +18,10 @@ defineTool({
|
|
|
17
18
|
}, async ({ project_id, editor_type, org_id }) => {
|
|
18
19
|
try {
|
|
19
20
|
const result = await createFile(config, { project_id, editor_type, org_id });
|
|
20
|
-
return
|
|
21
|
+
return toolSummary(`Created ${result.editor_type || 'design'} file.`, result);
|
|
21
22
|
}
|
|
22
23
|
catch (e) {
|
|
23
|
-
return toolError(`Failed to create file: ${e
|
|
24
|
+
return toolError(`Failed to create file: ${formatApiError(e)}`);
|
|
24
25
|
}
|
|
25
26
|
});
|
|
26
27
|
},
|
|
@@ -43,7 +44,7 @@ defineTool({
|
|
|
43
44
|
return toolResult(`Renamed to "${name}"`);
|
|
44
45
|
}
|
|
45
46
|
catch (e) {
|
|
46
|
-
return toolError(`Failed to rename file: ${e
|
|
47
|
+
return toolError(`Failed to rename file: ${formatApiError(e)}`);
|
|
47
48
|
}
|
|
48
49
|
});
|
|
49
50
|
},
|
|
@@ -69,7 +70,7 @@ defineTool({
|
|
|
69
70
|
return toolResult(msg);
|
|
70
71
|
}
|
|
71
72
|
catch (e) {
|
|
72
|
-
return toolError(`Failed to move files: ${e
|
|
73
|
+
return toolError(`Failed to move files: ${formatApiError(e)}`);
|
|
73
74
|
}
|
|
74
75
|
});
|
|
75
76
|
},
|
|
@@ -89,10 +90,10 @@ defineTool({
|
|
|
89
90
|
}, async ({ file_key, project_id }) => {
|
|
90
91
|
try {
|
|
91
92
|
const result = await duplicateFile(config, { file_key, project_id });
|
|
92
|
-
return
|
|
93
|
+
return toolSummary(`Duplicated file.`, result);
|
|
93
94
|
}
|
|
94
95
|
catch (e) {
|
|
95
|
-
return toolError(`Failed to duplicate file: ${e
|
|
96
|
+
return toolError(`Failed to duplicate file: ${formatApiError(e)}`);
|
|
96
97
|
}
|
|
97
98
|
});
|
|
98
99
|
},
|
|
@@ -105,7 +106,7 @@ defineTool({
|
|
|
105
106
|
destructive: true,
|
|
106
107
|
register(server, config) {
|
|
107
108
|
server.registerTool('trash_files', {
|
|
108
|
-
description: 'Move files to trash. Supports batch operations.',
|
|
109
|
+
description: 'Move files to trash (recoverable via restore_files). Supports batch operations.',
|
|
109
110
|
inputSchema: {
|
|
110
111
|
file_keys: z.array(figmaId).min(1).describe('Array of file keys to trash'),
|
|
111
112
|
},
|
|
@@ -115,7 +116,7 @@ defineTool({
|
|
|
115
116
|
return toolResult(`Trashed ${result.succeeded} file(s)`);
|
|
116
117
|
}
|
|
117
118
|
catch (e) {
|
|
118
|
-
return toolError(`Failed to trash files: ${e
|
|
119
|
+
return toolError(`Failed to trash files: ${formatApiError(e)}`);
|
|
119
120
|
}
|
|
120
121
|
});
|
|
121
122
|
},
|
|
@@ -140,7 +141,7 @@ defineTool({
|
|
|
140
141
|
return toolResult(msg);
|
|
141
142
|
}
|
|
142
143
|
catch (e) {
|
|
143
|
-
return toolError(`Failed to restore files: ${e
|
|
144
|
+
return toolError(`Failed to restore files: ${formatApiError(e)}`);
|
|
144
145
|
}
|
|
145
146
|
});
|
|
146
147
|
},
|
|
@@ -163,7 +164,7 @@ defineTool({
|
|
|
163
164
|
return toolResult(`${result.favorited ? 'Favorited' : 'Unfavorited'} file ${file_key}`);
|
|
164
165
|
}
|
|
165
166
|
catch (e) {
|
|
166
|
-
return toolError(`Failed to toggle favorite: ${e
|
|
167
|
+
return toolError(`Failed to toggle favorite: ${formatApiError(e)}`);
|
|
167
168
|
}
|
|
168
169
|
});
|
|
169
170
|
},
|
|
@@ -186,7 +187,7 @@ defineTool({
|
|
|
186
187
|
return toolResult(`Set link access to "${result.link_access}" on file ${file_key}`);
|
|
187
188
|
}
|
|
188
189
|
catch (e) {
|
|
189
|
-
return toolError(`Failed to set link access: ${e
|
|
190
|
+
return toolError(`Failed to set link access: ${formatApiError(e)}`);
|
|
190
191
|
}
|
|
191
192
|
});
|
|
192
193
|
},
|
package/dist/tools/libraries.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { defineTool, toolResult, toolError, figmaId } from './register.js';
|
|
1
|
+
import { defineTool, toolResult, toolError, toolSummary, figmaId } from './register.js';
|
|
2
|
+
import { formatApiError } from '../helpers.js';
|
|
2
3
|
import { listOrgLibraries } from '../operations/libraries.js';
|
|
3
4
|
// -- list_org_libraries --
|
|
4
5
|
defineTool({
|
|
@@ -13,10 +14,12 @@ defineTool({
|
|
|
13
14
|
}, async ({ org_id }) => {
|
|
14
15
|
try {
|
|
15
16
|
const result = await listOrgLibraries(config, { org_id });
|
|
16
|
-
|
|
17
|
+
if (result.length === 0)
|
|
18
|
+
return toolResult('No libraries found.');
|
|
19
|
+
return toolSummary(`${result.length} library/libraries.`, result, 'Use library_usage to see adoption metrics.');
|
|
17
20
|
}
|
|
18
21
|
catch (e) {
|
|
19
|
-
return toolError(`Failed to list org libraries: ${e
|
|
22
|
+
return toolError(`Failed to list org libraries: ${formatApiError(e)}`);
|
|
20
23
|
}
|
|
21
24
|
});
|
|
22
25
|
},
|
package/dist/tools/navigate.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { defineTool, toolResult, toolError, figmaId } from './register.js';
|
|
2
|
+
import { defineTool, toolResult, toolError, toolSummary, figmaId } from './register.js';
|
|
3
|
+
import { formatApiError } from '../helpers.js';
|
|
3
4
|
import { checkAuthStatus, listOrgs, switchOrg, listTeams, listProjects, listFiles, listRecentFiles, search, getFileInfo, listFavorites, } from '../operations/navigate.js';
|
|
4
5
|
// -- check_auth --
|
|
5
6
|
defineTool({
|
|
@@ -34,10 +35,10 @@ defineTool({
|
|
|
34
35
|
if (orgs.length === 0) {
|
|
35
36
|
return toolResult('No workspaces found. You may be on a free/starter plan.');
|
|
36
37
|
}
|
|
37
|
-
return
|
|
38
|
+
return toolSummary(`Found ${orgs.length} workspace(s).`, orgs, 'Use switch_org to change workspace, or list_teams to browse.');
|
|
38
39
|
}
|
|
39
40
|
catch (e) {
|
|
40
|
-
return toolError(`Failed to list orgs: ${e
|
|
41
|
+
return toolError(`Failed to list orgs: ${formatApiError(e)}`);
|
|
41
42
|
}
|
|
42
43
|
});
|
|
43
44
|
},
|
|
@@ -60,7 +61,7 @@ defineTool({
|
|
|
60
61
|
return toolResult(`Switched workspace: ${result.previous} -> ${result.current.name} (${result.current.id})`);
|
|
61
62
|
}
|
|
62
63
|
catch (e) {
|
|
63
|
-
return toolError(`Failed to switch org: ${e
|
|
64
|
+
return toolError(`Failed to switch org: ${formatApiError(e)}`);
|
|
64
65
|
}
|
|
65
66
|
});
|
|
66
67
|
},
|
|
@@ -75,10 +76,12 @@ defineTool({
|
|
|
75
76
|
}, async () => {
|
|
76
77
|
try {
|
|
77
78
|
const teams = await listTeams(config);
|
|
78
|
-
|
|
79
|
+
if (teams.length === 0)
|
|
80
|
+
return toolResult('No teams found.');
|
|
81
|
+
return toolSummary(`Found ${teams.length} team(s).`, teams, 'Use list_projects with a team_id to browse projects.');
|
|
79
82
|
}
|
|
80
83
|
catch (e) {
|
|
81
|
-
return toolError(`Failed to list teams: ${e
|
|
84
|
+
return toolError(`Failed to list teams: ${formatApiError(e)}`);
|
|
82
85
|
}
|
|
83
86
|
});
|
|
84
87
|
},
|
|
@@ -96,10 +99,12 @@ defineTool({
|
|
|
96
99
|
}, async ({ team_id }) => {
|
|
97
100
|
try {
|
|
98
101
|
const projects = await listProjects(config, { team_id });
|
|
99
|
-
|
|
102
|
+
if (projects.length === 0)
|
|
103
|
+
return toolResult('No projects found.');
|
|
104
|
+
return toolSummary(`Found ${projects.length} project(s).`, projects, 'Use list_files with a project_id to see files.');
|
|
100
105
|
}
|
|
101
106
|
catch (e) {
|
|
102
|
-
return toolError(`Failed to list projects: ${e
|
|
107
|
+
return toolError(`Failed to list projects: ${formatApiError(e)}`);
|
|
103
108
|
}
|
|
104
109
|
});
|
|
105
110
|
},
|
|
@@ -119,10 +124,12 @@ defineTool({
|
|
|
119
124
|
}, async ({ project_id, page_size, page_token }) => {
|
|
120
125
|
try {
|
|
121
126
|
const result = await listFiles(config, { project_id, page_size, page_token });
|
|
122
|
-
|
|
127
|
+
const count = result.files.length;
|
|
128
|
+
const summary = `${count} file(s).` + (result.pagination?.has_more ? ' More pages available.' : '');
|
|
129
|
+
return toolSummary(summary, result, 'Use get_file_info or get_file for details.');
|
|
123
130
|
}
|
|
124
131
|
catch (e) {
|
|
125
|
-
return toolError(`Failed to list files: ${e
|
|
132
|
+
return toolError(`Failed to list files: ${formatApiError(e)}`);
|
|
126
133
|
}
|
|
127
134
|
});
|
|
128
135
|
},
|
|
@@ -137,10 +144,12 @@ defineTool({
|
|
|
137
144
|
}, async () => {
|
|
138
145
|
try {
|
|
139
146
|
const files = await listRecentFiles(config);
|
|
140
|
-
|
|
147
|
+
if (files.length === 0)
|
|
148
|
+
return toolResult('No recent files.');
|
|
149
|
+
return toolSummary(`${files.length} recently accessed file(s).`, files, 'Use get_file_info for details.');
|
|
141
150
|
}
|
|
142
151
|
catch (e) {
|
|
143
|
-
return toolError(`Failed to list recent files: ${e
|
|
152
|
+
return toolError(`Failed to list recent files: ${formatApiError(e)}`);
|
|
144
153
|
}
|
|
145
154
|
});
|
|
146
155
|
},
|
|
@@ -163,10 +172,10 @@ defineTool({
|
|
|
163
172
|
if (results.length === 0) {
|
|
164
173
|
return toolResult('No results. Try list_recent_files or browse via list_projects + list_files.');
|
|
165
174
|
}
|
|
166
|
-
return
|
|
175
|
+
return toolSummary(`Found ${results.length} result(s).`, results, 'Use get_file_info for file details.');
|
|
167
176
|
}
|
|
168
177
|
catch (e) {
|
|
169
|
-
return toolError(`Search failed: ${e
|
|
178
|
+
return toolError(`Search failed: ${formatApiError(e)}`);
|
|
170
179
|
}
|
|
171
180
|
});
|
|
172
181
|
},
|
|
@@ -184,10 +193,10 @@ defineTool({
|
|
|
184
193
|
}, async ({ file_key }) => {
|
|
185
194
|
try {
|
|
186
195
|
const info = await getFileInfo(config, { file_key });
|
|
187
|
-
return
|
|
196
|
+
return toolSummary(`${info.name} (${info.editor_type || 'design'})`, info);
|
|
188
197
|
}
|
|
189
198
|
catch (e) {
|
|
190
|
-
return toolError(`Failed to get file info: ${e
|
|
199
|
+
return toolError(`Failed to get file info: ${formatApiError(e)}`);
|
|
191
200
|
}
|
|
192
201
|
});
|
|
193
202
|
},
|
|
@@ -202,10 +211,12 @@ defineTool({
|
|
|
202
211
|
}, async () => {
|
|
203
212
|
try {
|
|
204
213
|
const favorites = await listFavorites(config);
|
|
205
|
-
|
|
214
|
+
if (favorites.length === 0)
|
|
215
|
+
return toolResult('No favorites found.');
|
|
216
|
+
return toolSummary(`${favorites.length} favorited file(s).`, favorites, 'Use get_file_info for details.');
|
|
206
217
|
}
|
|
207
218
|
catch (e) {
|
|
208
|
-
return toolError(`Failed to list favorites: ${e
|
|
219
|
+
return toolError(`Failed to list favorites: ${formatApiError(e)}`);
|
|
209
220
|
}
|
|
210
221
|
});
|
|
211
222
|
},
|
package/dist/tools/org.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { defineTool, toolResult, toolError, figmaId } from './register.js';
|
|
2
|
+
import { defineTool, toolResult, toolError, toolSummary, figmaId } from './register.js';
|
|
3
|
+
import { formatApiError } from '../helpers.js';
|
|
3
4
|
import { listAdmins, listOrgTeams, seatUsage, listTeamMembers, billingOverview, listInvoices, orgDomains, aiCreditUsage, exportMembers, listOrgMembers, contractRates, changeSeat, } from '../operations/org.js';
|
|
4
5
|
// -- list_admins --
|
|
5
6
|
defineTool({
|
|
@@ -15,10 +16,10 @@ defineTool({
|
|
|
15
16
|
}, async ({ org_id, include_license_admins }) => {
|
|
16
17
|
try {
|
|
17
18
|
const result = await listAdmins(config, { org_id, include_license_admins });
|
|
18
|
-
return
|
|
19
|
+
return toolSummary(`${result.length} admin(s).`, result);
|
|
19
20
|
}
|
|
20
21
|
catch (e) {
|
|
21
|
-
return toolError(`Failed to list admins: ${e
|
|
22
|
+
return toolError(`Failed to list admins: ${formatApiError(e)}`);
|
|
22
23
|
}
|
|
23
24
|
});
|
|
24
25
|
},
|
|
@@ -37,10 +38,10 @@ defineTool({
|
|
|
37
38
|
}, async ({ org_id, include_secret_teams }) => {
|
|
38
39
|
try {
|
|
39
40
|
const result = await listOrgTeams(config, { org_id, include_secret_teams });
|
|
40
|
-
return
|
|
41
|
+
return toolSummary(`${result.length} team(s) in the org.`, result, 'Use list_team_members for member details.');
|
|
41
42
|
}
|
|
42
43
|
catch (e) {
|
|
43
|
-
return toolError(`Failed to list org teams: ${e
|
|
44
|
+
return toolError(`Failed to list org teams: ${formatApiError(e)}`);
|
|
44
45
|
}
|
|
45
46
|
});
|
|
46
47
|
},
|
|
@@ -59,10 +60,10 @@ defineTool({
|
|
|
59
60
|
}, async ({ org_id, search_query }) => {
|
|
60
61
|
try {
|
|
61
62
|
const result = await seatUsage(config, { org_id, search_query });
|
|
62
|
-
return
|
|
63
|
+
return toolSummary('Seat usage breakdown:', result);
|
|
63
64
|
}
|
|
64
65
|
catch (e) {
|
|
65
|
-
return toolError(`Failed to fetch seat usage: ${e
|
|
66
|
+
return toolError(`Failed to fetch seat usage: ${formatApiError(e)}`);
|
|
66
67
|
}
|
|
67
68
|
});
|
|
68
69
|
},
|
|
@@ -80,10 +81,10 @@ defineTool({
|
|
|
80
81
|
}, async ({ team_id }) => {
|
|
81
82
|
try {
|
|
82
83
|
const result = await listTeamMembers(config, { team_id });
|
|
83
|
-
return
|
|
84
|
+
return toolSummary(`${result.length} member(s).`, result);
|
|
84
85
|
}
|
|
85
86
|
catch (e) {
|
|
86
|
-
return toolError(`Failed to list team members: ${e
|
|
87
|
+
return toolError(`Failed to list team members: ${formatApiError(e)}`);
|
|
87
88
|
}
|
|
88
89
|
});
|
|
89
90
|
},
|
|
@@ -101,10 +102,10 @@ defineTool({
|
|
|
101
102
|
}, async ({ org_id }) => {
|
|
102
103
|
try {
|
|
103
104
|
const result = await billingOverview(config, { org_id });
|
|
104
|
-
return
|
|
105
|
+
return toolSummary('Billing overview:', result);
|
|
105
106
|
}
|
|
106
107
|
catch (e) {
|
|
107
|
-
return toolError(`Failed to fetch billing overview: ${e
|
|
108
|
+
return toolError(`Failed to fetch billing overview: ${formatApiError(e)}`);
|
|
108
109
|
}
|
|
109
110
|
});
|
|
110
111
|
},
|
|
@@ -122,10 +123,10 @@ defineTool({
|
|
|
122
123
|
}, async ({ org_id }) => {
|
|
123
124
|
try {
|
|
124
125
|
const result = await listInvoices(config, { org_id });
|
|
125
|
-
return
|
|
126
|
+
return toolSummary(`${result.length} invoice(s).`, result);
|
|
126
127
|
}
|
|
127
128
|
catch (e) {
|
|
128
|
-
return toolError(`Failed to list invoices: ${e
|
|
129
|
+
return toolError(`Failed to list invoices: ${formatApiError(e)}`);
|
|
129
130
|
}
|
|
130
131
|
});
|
|
131
132
|
},
|
|
@@ -143,10 +144,10 @@ defineTool({
|
|
|
143
144
|
}, async ({ org_id }) => {
|
|
144
145
|
try {
|
|
145
146
|
const result = await orgDomains(config, { org_id });
|
|
146
|
-
return
|
|
147
|
+
return toolSummary('Domain configuration:', result);
|
|
147
148
|
}
|
|
148
149
|
catch (e) {
|
|
149
|
-
return toolError(`Failed to fetch org domains: ${e
|
|
150
|
+
return toolError(`Failed to fetch org domains: ${formatApiError(e)}`);
|
|
150
151
|
}
|
|
151
152
|
});
|
|
152
153
|
},
|
|
@@ -164,10 +165,10 @@ defineTool({
|
|
|
164
165
|
}, async ({ plan_id }) => {
|
|
165
166
|
try {
|
|
166
167
|
const result = await aiCreditUsage(config, { plan_id });
|
|
167
|
-
return
|
|
168
|
+
return toolSummary('AI credit usage:', result);
|
|
168
169
|
}
|
|
169
170
|
catch (e) {
|
|
170
|
-
return toolError(`Failed to fetch AI credit usage: ${e
|
|
171
|
+
return toolError(`Failed to fetch AI credit usage: ${formatApiError(e)}`);
|
|
171
172
|
}
|
|
172
173
|
});
|
|
173
174
|
},
|
|
@@ -189,7 +190,7 @@ defineTool({
|
|
|
189
190
|
return toolResult(msg);
|
|
190
191
|
}
|
|
191
192
|
catch (e) {
|
|
192
|
-
return toolError(`Failed to export members: ${e
|
|
193
|
+
return toolError(`Failed to export members: ${formatApiError(e)}`);
|
|
193
194
|
}
|
|
194
195
|
});
|
|
195
196
|
},
|
|
@@ -208,10 +209,10 @@ defineTool({
|
|
|
208
209
|
}, async ({ org_id, search_query }) => {
|
|
209
210
|
try {
|
|
210
211
|
const result = await listOrgMembers(config, { org_id, search_query });
|
|
211
|
-
return
|
|
212
|
+
return toolSummary(`${result.length} member(s).`, result, 'Use change_seat to modify seat types.');
|
|
212
213
|
}
|
|
213
214
|
catch (e) {
|
|
214
|
-
return toolError(`Failed to list org members: ${e
|
|
215
|
+
return toolError(`Failed to list org members: ${formatApiError(e)}`);
|
|
215
216
|
}
|
|
216
217
|
});
|
|
217
218
|
},
|
|
@@ -229,10 +230,10 @@ defineTool({
|
|
|
229
230
|
}, async ({ org_id }) => {
|
|
230
231
|
try {
|
|
231
232
|
const result = await contractRates(config, { org_id });
|
|
232
|
-
return
|
|
233
|
+
return toolSummary('Seat pricing:', result);
|
|
233
234
|
}
|
|
234
235
|
catch (e) {
|
|
235
|
-
return toolError(`Failed to fetch contract rates: ${e
|
|
236
|
+
return toolError(`Failed to fetch contract rates: ${formatApiError(e)}`);
|
|
236
237
|
}
|
|
237
238
|
});
|
|
238
239
|
},
|
|
@@ -257,10 +258,10 @@ defineTool({
|
|
|
257
258
|
const result = await changeSeat(config, { user_id, seat_type, org_id, confirm });
|
|
258
259
|
if (typeof result === 'string')
|
|
259
260
|
return toolResult(result);
|
|
260
|
-
return
|
|
261
|
+
return toolSummary('Seat change requires confirmation.', result);
|
|
261
262
|
}
|
|
262
263
|
catch (e) {
|
|
263
|
-
return toolError(
|
|
264
|
+
return toolError(`Failed to change seat: ${formatApiError(e)}`);
|
|
264
265
|
}
|
|
265
266
|
});
|
|
266
267
|
},
|