figmanage 1.2.3 → 1.2.4

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.
@@ -23,10 +23,20 @@ export interface SessionInfo {
23
23
  }
24
24
  export declare function validateSession(cookieValue: string, userId: string): Promise<SessionInfo>;
25
25
  export declare function validatePat(pat: string): Promise<string>;
26
+ export interface ProfileInfo {
27
+ profileName: string;
28
+ figmaEmail?: string;
29
+ }
30
+ /**
31
+ * Resolve display info for a Figma account: Figma email via API + Chrome profile name.
32
+ * The API call is best-effort -- falls back to userId if it fails.
33
+ */
34
+ export declare function resolveAccountInfo(account: FigmaAccount): Promise<ProfileInfo>;
26
35
  export interface FigmaAccount {
27
36
  userId: string;
28
37
  cookieValue: string;
29
38
  profile: string;
39
+ profilePath: string;
30
40
  }
31
41
  /**
32
42
  * Extract Figma auth cookies from all Chrome profiles.
@@ -263,6 +263,42 @@ export async function validatePat(pat) {
263
263
  });
264
264
  return res.data.handle || res.data.email || 'valid';
265
265
  }
266
+ function readChromeProfileName(profilePath) {
267
+ try {
268
+ const prefsPath = join(profilePath, 'Preferences');
269
+ if (!existsSync(prefsPath))
270
+ return profilePath.split(/[/\\]/).pop();
271
+ const prefs = JSON.parse(readFileSync(prefsPath, 'utf-8'));
272
+ return prefs?.profile?.name || profilePath.split(/[/\\]/).pop();
273
+ }
274
+ catch {
275
+ return profilePath.split(/[/\\]/).pop();
276
+ }
277
+ }
278
+ /**
279
+ * Resolve display info for a Figma account: Figma email via API + Chrome profile name.
280
+ * The API call is best-effort -- falls back to userId if it fails.
281
+ */
282
+ export async function resolveAccountInfo(account) {
283
+ const profileName = readChromeProfileName(account.profilePath);
284
+ try {
285
+ const headers = {
286
+ 'Cookie': `${COOKIE_NAME}=${account.cookieValue}`,
287
+ 'X-CSRF-Bypass': 'yes',
288
+ 'X-Figma-User-Id': account.userId,
289
+ };
290
+ const res = await axios.get('https://www.figma.com/api/user/state', {
291
+ headers,
292
+ timeout: 5000,
293
+ });
294
+ const meta = res.data?.meta || {};
295
+ const email = meta.email || meta.user?.email;
296
+ return { profileName, figmaEmail: email };
297
+ }
298
+ catch {
299
+ return { profileName };
300
+ }
301
+ }
266
302
  /**
267
303
  * Extract Figma auth cookies from all Chrome profiles.
268
304
  * Returns an array of accounts found (may be empty on Windows failure).
@@ -275,7 +311,7 @@ export function extractCookies() {
275
311
  try {
276
312
  const rawCookie = extractCookieFromProfile(profilePath);
277
313
  const { userId, cookieValue } = parseCookieValue(rawCookie);
278
- accounts.push({ userId, cookieValue, profile: profilePath.split(/[/\\]/).pop() });
314
+ accounts.push({ userId, cookieValue, profile: profilePath.split(/[/\\]/).pop(), profilePath });
279
315
  }
280
316
  catch {
281
317
  // Profile doesn't have a Figma cookie
package/dist/setup.js CHANGED
@@ -3,7 +3,7 @@ import { execFileSync } from 'child_process';
3
3
  import { mkdirSync, existsSync, readFileSync, writeFileSync } from 'fs';
4
4
  import { join } from 'path';
5
5
  import { homedir, platform } from 'os';
6
- import { extractCookies, validateSession, validatePat } from './auth/cookie.js';
6
+ import { extractCookies, validateSession, validatePat, resolveAccountInfo } from './auth/cookie.js';
7
7
  // --- MCP client detection and registration ---
8
8
  function claudeCliAvailable() {
9
9
  try {
@@ -187,10 +187,12 @@ async function setup() {
187
187
  // If multiple accounts, let user pick
188
188
  let selected = accounts[0];
189
189
  if (accounts.length > 1) {
190
- console.log(`\n Found ${accounts.length} Figma accounts:\n`);
190
+ console.log(`\n Found ${accounts.length} Figma accounts. Identifying...\n`);
191
+ const infos = await Promise.all(accounts.map(a => resolveAccountInfo(a)));
191
192
  for (let i = 0; i < accounts.length; i++) {
192
- const a = accounts[i];
193
- console.log(` [${i + 1}] User ${a.userId} (${a.profile})`);
193
+ const info = infos[i];
194
+ const label = info.figmaEmail || `User ${accounts[i].userId}`;
195
+ console.log(` [${i + 1}] ${label} (Chrome: ${info.profileName})`);
194
196
  }
195
197
  const { createInterface } = await import('readline');
196
198
  const rl = createInterface({ input: process.stdin, output: process.stdout });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "figmanage",
3
3
  "mcpName": "io.github.dannykeane/figmanage",
4
- "version": "1.2.3",
4
+ "version": "1.2.4",
5
5
  "description": "MCP server for managing your Figma workspace from the terminal.",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",