figmanage 1.2.5 → 1.2.7

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.
@@ -287,13 +287,12 @@ export async function resolveAccountInfo(account) {
287
287
  'X-CSRF-Bypass': 'yes',
288
288
  'X-Figma-User-Id': account.userId,
289
289
  };
290
- const res = await axios.get('https://www.figma.com/api/user/state', {
290
+ const res = await axios.get(`https://www.figma.com/api/user/${account.userId}`, {
291
291
  headers,
292
292
  timeout: 5000,
293
293
  });
294
294
  const meta = res.data?.meta || {};
295
- const email = meta.email || meta.user?.email;
296
- return { profileName, figmaEmail: email };
295
+ return { profileName, figmaEmail: meta.email };
297
296
  }
298
297
  catch {
299
298
  return { profileName };
package/dist/cli/login.js CHANGED
@@ -2,15 +2,40 @@ import { createInterface } from 'node:readline';
2
2
  import { platform } from 'node:os';
3
3
  import { setActiveWorkspace, deleteConfig, getConfigPath } from '../config.js';
4
4
  import { extractCookies, validateSession, validatePat, resolveAccountInfo } from '../auth/cookie.js';
5
- async function prompt(question) {
6
- const rl = createInterface({ input: process.stdin, output: process.stdout });
7
- const answer = await new Promise(resolve => rl.question(question, resolve));
8
- rl.close();
9
- return answer.trim();
5
+ function createPrompt() {
6
+ if (process.stdin.isTTY) {
7
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
8
+ return {
9
+ ask: async (question) => {
10
+ const answer = await new Promise(resolve => rl.question(question, resolve));
11
+ return answer.trim();
12
+ },
13
+ close: () => rl.close(),
14
+ };
15
+ }
16
+ // Piped stdin: buffer all lines upfront since readline auto-closes on EOF
17
+ let lines = null;
18
+ let idx = 0;
19
+ const readAll = () => new Promise((resolve) => {
20
+ const rl = createInterface({ input: process.stdin });
21
+ const buf = [];
22
+ rl.on('line', (line) => buf.push(line));
23
+ rl.on('close', () => resolve(buf));
24
+ });
25
+ return {
26
+ ask: async (question) => {
27
+ if (!lines)
28
+ lines = await readAll();
29
+ process.stdout.write(question);
30
+ return (lines[idx++] || '').trim();
31
+ },
32
+ close: () => { },
33
+ };
10
34
  }
11
35
  export async function handleLogin(options = {}) {
12
36
  const workspace = {};
13
37
  const os = platform();
38
+ const io = createPrompt();
14
39
  // Cookie extraction (unless --pat-only)
15
40
  if (!options.patOnly) {
16
41
  if (os !== 'darwin' && os !== 'linux' && os !== 'win32') {
@@ -40,9 +65,10 @@ export async function handleLogin(options = {}) {
40
65
  const label = info.figmaEmail || `User ${accounts[i].userId}`;
41
66
  console.log(` [${i + 1}] ${label} (Chrome: ${info.profileName})`);
42
67
  }
43
- const answer = await prompt(`\n Select account [1-${accounts.length}]: `);
68
+ const answer = await io.ask(`\n Select account [1-${accounts.length}]: `);
44
69
  const idx = parseInt(answer, 10) - 1;
45
70
  if (idx < 0 || idx >= accounts.length) {
71
+ io.close();
46
72
  console.error(' Invalid selection.');
47
73
  process.exit(1);
48
74
  }
@@ -69,7 +95,7 @@ export async function handleLogin(options = {}) {
69
95
  const marker = o.id === orgId ? ' (current)' : '';
70
96
  console.log(` [${i + 1}] ${o.name} (${o.id})${marker}`);
71
97
  }
72
- const answer = await prompt(`\n Default workspace [1-${session.orgs.length}] (Enter for 1): `);
98
+ const answer = await io.ask(`\n Default workspace [1-${session.orgs.length}] (Enter for 1): `);
73
99
  if (answer) {
74
100
  const idx = parseInt(answer, 10) - 1;
75
101
  if (idx >= 0 && idx < session.orgs.length) {
@@ -108,7 +134,7 @@ export async function handleLogin(options = {}) {
108
134
  // PAT prompt
109
135
  console.log('\nA Personal Access Token enables comments, export, and version history.');
110
136
  console.log('Generate one at: https://www.figma.com/settings (Security > Personal access tokens)');
111
- const patInput = await prompt('Paste your PAT (or press Enter to skip): ');
137
+ const patInput = await io.ask('Paste your PAT (or press Enter to skip): ');
112
138
  if (patInput) {
113
139
  console.log('Validating PAT...');
114
140
  try {
@@ -120,6 +146,7 @@ export async function handleLogin(options = {}) {
120
146
  console.log(' PAT invalid or expired -- skipping.');
121
147
  }
122
148
  }
149
+ io.close();
123
150
  // Must have at least one credential
124
151
  if (!workspace.pat && !workspace.cookie) {
125
152
  console.error('\nNo credentials configured. Need at least a PAT or browser cookie.');
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.5",
4
+ "version": "1.2.7",
5
5
  "description": "MCP server for managing your Figma workspace from the terminal.",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",