@papercraneai/cli 1.2.0 → 1.3.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/bin/papercrane.js +47 -20
- package/package.json +1 -1
package/bin/papercrane.js
CHANGED
|
@@ -51,40 +51,67 @@ program
|
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
// Browser-based login flow
|
|
55
|
-
const {
|
|
54
|
+
// Browser-based login flow (polling)
|
|
55
|
+
const { generateState } = await import('../lib/auth-server.js');
|
|
56
56
|
const open = (await import('open')).default;
|
|
57
57
|
|
|
58
|
-
const
|
|
59
|
-
const authServer = await createAuthServer(state, baseUrl, 120000);
|
|
58
|
+
const session = generateState();
|
|
60
59
|
|
|
61
|
-
|
|
60
|
+
// Initialize session on server
|
|
61
|
+
const initRes = await fetch(`${baseUrl}/api/cli-auth/init`, {
|
|
62
|
+
method: 'POST',
|
|
63
|
+
headers: { 'Content-Type': 'application/json' },
|
|
64
|
+
body: JSON.stringify({ session })
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
if (!initRes.ok) {
|
|
68
|
+
throw new Error('Failed to initialize login session');
|
|
69
|
+
}
|
|
62
70
|
|
|
63
|
-
|
|
64
|
-
console.log(chalk.dim(` ${authUrl}\n`));
|
|
71
|
+
const authUrl = `${baseUrl}/cli-auth?session=${session}`;
|
|
65
72
|
|
|
66
|
-
|
|
73
|
+
console.log(chalk.cyan('\nOpen this URL to authenticate:\n'));
|
|
74
|
+
console.log(` ${authUrl}\n`);
|
|
75
|
+
|
|
76
|
+
// Try to open browser automatically
|
|
67
77
|
try {
|
|
68
78
|
await open(authUrl);
|
|
79
|
+
console.log(chalk.dim('(Browser opened automatically)'));
|
|
69
80
|
} catch {
|
|
70
|
-
console.log(chalk.yellow('Could not open browser automatically.'));
|
|
71
|
-
console.log(chalk.yellow('Please open this URL manually:\n'));
|
|
72
|
-
console.log(chalk.cyan(` ${authUrl}\n`));
|
|
81
|
+
console.log(chalk.yellow('Could not open browser automatically. Please click or copy the URL above.'));
|
|
73
82
|
}
|
|
74
83
|
|
|
75
|
-
console.log(chalk.dim('
|
|
84
|
+
console.log(chalk.dim('\nWaiting for authorization... (press Ctrl+C to cancel)\n'));
|
|
85
|
+
|
|
86
|
+
// Poll for authorization
|
|
87
|
+
const pollInterval = 2000; // 2 seconds
|
|
88
|
+
const timeout = 120000; // 2 minutes
|
|
89
|
+
const startTime = Date.now();
|
|
76
90
|
|
|
77
|
-
|
|
78
|
-
|
|
91
|
+
while (Date.now() - startTime < timeout) {
|
|
92
|
+
const statusRes = await fetch(`${baseUrl}/api/cli-auth/status?session=${encodeURIComponent(session)}`);
|
|
79
93
|
|
|
80
|
-
|
|
81
|
-
|
|
94
|
+
if (statusRes.ok) {
|
|
95
|
+
const data = await statusRes.json();
|
|
82
96
|
|
|
83
|
-
|
|
84
|
-
|
|
97
|
+
if (data.status === 'authorized') {
|
|
98
|
+
// Save the API key
|
|
99
|
+
await setApiKey(data.key);
|
|
100
|
+
await setApiBaseUrl(baseUrl);
|
|
101
|
+
|
|
102
|
+
console.log(chalk.green(`✓ Logged in as ${data.email}`));
|
|
103
|
+
console.log(chalk.dim(` API key saved to ~/.papercrane/config.json\n`));
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
} else if (statusRes.status === 404) {
|
|
107
|
+
throw new Error('Session expired. Please try again.');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Wait before next poll
|
|
111
|
+
await new Promise(resolve => setTimeout(resolve, pollInterval));
|
|
112
|
+
}
|
|
85
113
|
|
|
86
|
-
|
|
87
|
-
console.log(chalk.dim(` API key saved to ~/.papercrane/config.json\n`));
|
|
114
|
+
throw new Error('Authentication timed out');
|
|
88
115
|
} catch (error) {
|
|
89
116
|
if (error.message.includes('timed out')) {
|
|
90
117
|
console.error(chalk.red('\nAuthentication timed out. Please try again.'));
|