@papercraneai/cli 1.4.3 → 1.5.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 +103 -29
- package/lib/axios-client.js +14 -0
- package/lib/cloud-client.js +8 -8
- package/lib/config.js +1 -1
- package/lib/environment-client.js +7 -7
- package/lib/facebook-auth.js +4 -4
- package/lib/function-client.js +3 -3
- package/lib/google-auth.js +3 -3
- package/package.json +3 -3
package/bin/papercrane.js
CHANGED
|
@@ -4,17 +4,59 @@ import { Command } from 'commander';
|
|
|
4
4
|
import chalk from 'chalk';
|
|
5
5
|
import readline from 'readline';
|
|
6
6
|
import fs from 'fs/promises';
|
|
7
|
-
import
|
|
7
|
+
import http from 'http';
|
|
8
|
+
import { http as httpClient } from '../lib/axios-client.js';
|
|
8
9
|
import { setApiKey, clearConfig, isLoggedIn, setDefaultWorkspace, getDefaultWorkspace } from '../lib/config.js';
|
|
9
10
|
import { validateApiKey } from '../lib/cloud-client.js';
|
|
10
11
|
import { listFunctions, getFunction, runFunction, formatDescribe, formatDescribeRoot, formatFlat, formatResult, formatUnconnected } from '../lib/function-client.js';
|
|
11
12
|
import { listWorkspaces, resolveWorkspaceId, getFileTree, readFile, writeFile, editFile, deleteFile, getLocalWorkspacePath, pullWorkspace, pushWorkspace } from '../lib/environment-client.js';
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Test if browser can actually open URLs by starting a local server and
|
|
16
|
+
* checking if we receive a request when we try to open it.
|
|
17
|
+
* @param {number} timeout - Max time to wait in ms
|
|
18
|
+
* @returns {Promise<boolean>} - true if browser can open URLs
|
|
19
|
+
*/
|
|
20
|
+
async function canOpenBrowser(timeout = 2500) {
|
|
21
|
+
return new Promise((resolve) => {
|
|
22
|
+
let resolved = false;
|
|
23
|
+
const done = (result) => {
|
|
24
|
+
if (!resolved) {
|
|
25
|
+
resolved = true;
|
|
26
|
+
resolve(result);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const server = http.createServer((req, res) => {
|
|
31
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
32
|
+
res.end('<html><body><script>window.close()</script>Checking browser... you can close this tab.</body></html>');
|
|
33
|
+
server.close();
|
|
34
|
+
done(true);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
server.on('error', () => done(false));
|
|
38
|
+
|
|
39
|
+
server.listen(0, '127.0.0.1', async () => {
|
|
40
|
+
const port = server.address().port;
|
|
41
|
+
const checkUrl = `http://127.0.0.1:${port}/browser-check`;
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
const open = (await import('open')).default;
|
|
45
|
+
await open(checkUrl);
|
|
46
|
+
} catch {
|
|
47
|
+
// open() threw an error
|
|
48
|
+
server.close();
|
|
49
|
+
done(false);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Wait for browser to hit our server
|
|
54
|
+
setTimeout(() => {
|
|
55
|
+
server.close();
|
|
56
|
+
done(false);
|
|
57
|
+
}, timeout);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
18
60
|
}
|
|
19
61
|
|
|
20
62
|
const program = new Command();
|
|
@@ -29,8 +71,8 @@ program
|
|
|
29
71
|
.description('Login to Papercrane. Opens browser for authentication, or use --api-key for direct login.')
|
|
30
72
|
.option('--api-key <key>', 'API key for direct login (skips browser)')
|
|
31
73
|
.option('--url <url>', 'API base URL (saves to config)')
|
|
32
|
-
.option('--
|
|
33
|
-
.option('--
|
|
74
|
+
.option('--print-url', 'Print auth URL and exit (use with --complete after authorizing)')
|
|
75
|
+
.option('--complete', 'Complete a pending login started with --print-url')
|
|
34
76
|
.action(async (options) => {
|
|
35
77
|
try {
|
|
36
78
|
const { getApiBaseUrl, setApiBaseUrl, getPendingSession, setPendingSession, clearPendingSession } = await import('../lib/config.js');
|
|
@@ -61,18 +103,20 @@ program
|
|
|
61
103
|
return;
|
|
62
104
|
}
|
|
63
105
|
|
|
64
|
-
// --
|
|
65
|
-
if (options.
|
|
106
|
+
// --complete: Check if pending login was completed
|
|
107
|
+
if (options.complete) {
|
|
66
108
|
const pending = await getPendingSession();
|
|
67
109
|
if (!pending) {
|
|
68
|
-
console.log(chalk.yellow('No pending login session. Run: papercrane login --
|
|
110
|
+
console.log(chalk.yellow('No pending login session. Run: papercrane login --print-url'));
|
|
69
111
|
process.exit(1);
|
|
70
112
|
}
|
|
71
113
|
|
|
72
|
-
const statusRes = await
|
|
114
|
+
const statusRes = await httpClient.get(`${pending.baseUrl}/api/cli-auth/status?session=${encodeURIComponent(pending.session)}`, {
|
|
115
|
+
validateStatus: () => true
|
|
116
|
+
});
|
|
73
117
|
|
|
74
|
-
if (statusRes.
|
|
75
|
-
const data =
|
|
118
|
+
if (statusRes.status >= 200 && statusRes.status < 300) {
|
|
119
|
+
const data = statusRes.data;
|
|
76
120
|
if (data.status === 'authorized') {
|
|
77
121
|
await setApiKey(data.key);
|
|
78
122
|
await setApiBaseUrl(pending.baseUrl);
|
|
@@ -83,7 +127,22 @@ program
|
|
|
83
127
|
}
|
|
84
128
|
}
|
|
85
129
|
|
|
86
|
-
console.log(chalk.yellow('Not yet authorized. Please click the login URL, then run: papercrane login --
|
|
130
|
+
console.log(chalk.yellow('Not yet authorized. Please click the login URL, then run: papercrane login --complete'));
|
|
131
|
+
process.exit(1);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Check server connectivity before starting auth flow
|
|
135
|
+
// Extract domain from baseUrl for allowlist message
|
|
136
|
+
const urlDomain = new URL(baseUrl).hostname;
|
|
137
|
+
try {
|
|
138
|
+
await httpClient.get(`${baseUrl}/api/cli-auth/status?session=connectivity-check`, { timeout: 5000 });
|
|
139
|
+
} catch (connectError) {
|
|
140
|
+
console.log(chalk.yellow('\n⚠️ Cannot reach Papercrane server.'));
|
|
141
|
+
console.log(chalk.dim(`\nCould not connect to: ${baseUrl}`));
|
|
142
|
+
console.log(chalk.dim('\nIf you\'re using Claude Desktop or Claude app:'));
|
|
143
|
+
console.log(chalk.dim(' 1. Go to Settings → Capabilities → Domain allowlist'));
|
|
144
|
+
console.log(chalk.dim(` 2. Add: ${urlDomain}`));
|
|
145
|
+
console.log(chalk.dim(' 3. Try again\n'));
|
|
87
146
|
process.exit(1);
|
|
88
147
|
}
|
|
89
148
|
|
|
@@ -93,39 +152,52 @@ program
|
|
|
93
152
|
const session = generateState();
|
|
94
153
|
|
|
95
154
|
// Initialize session on server
|
|
96
|
-
const initRes = await
|
|
97
|
-
method: 'POST',
|
|
155
|
+
const initRes = await httpClient.post(`${baseUrl}/api/cli-auth/init`, { session }, {
|
|
98
156
|
headers: { 'Content-Type': 'application/json' },
|
|
99
|
-
|
|
157
|
+
validateStatus: () => true
|
|
100
158
|
});
|
|
101
159
|
|
|
102
|
-
if (
|
|
160
|
+
if (initRes.status < 200 || initRes.status >= 300) {
|
|
103
161
|
throw new Error('Failed to initialize login session');
|
|
104
162
|
}
|
|
105
|
-
// Drain response body to avoid keeping the event loop alive (undici)
|
|
106
|
-
await initRes.arrayBuffer();
|
|
107
163
|
|
|
108
164
|
const authUrl = `${baseUrl}/cli-auth?session=${session}`;
|
|
109
165
|
|
|
110
|
-
// --
|
|
111
|
-
if (options.
|
|
166
|
+
// --print-url: Print URL and exit immediately (for AI assistants)
|
|
167
|
+
if (options.printUrl) {
|
|
112
168
|
await setPendingSession({ session, baseUrl });
|
|
113
169
|
console.log(chalk.cyan('\nOpen this URL to authenticate:\n'));
|
|
114
170
|
console.log(` ${authUrl}\n`);
|
|
115
|
-
console.log(chalk.dim('After authorizing, run: papercrane login --
|
|
171
|
+
console.log(chalk.dim('After authorizing, run: papercrane login --complete\n'));
|
|
116
172
|
process.exit(0);
|
|
117
173
|
}
|
|
118
174
|
|
|
175
|
+
// Test if browser can actually open URLs
|
|
176
|
+
console.log(chalk.dim('\nChecking browser availability...'));
|
|
177
|
+
const browserWorks = await canOpenBrowser();
|
|
178
|
+
|
|
119
179
|
console.log(chalk.cyan('\nOpen this URL to authenticate:\n'));
|
|
120
180
|
console.log(` ${authUrl}\n`);
|
|
121
181
|
|
|
122
|
-
|
|
182
|
+
if (!browserWorks) {
|
|
183
|
+
// Browser can't open - save session and exit (non-blocking)
|
|
184
|
+
await setPendingSession({ session, baseUrl });
|
|
185
|
+
console.log(chalk.yellow('Browser could not be opened automatically.'));
|
|
186
|
+
console.log(chalk.dim('\nPlease open the URL above manually, then run: papercrane login --complete\n'));
|
|
187
|
+
process.exit(0);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Browser works - open the auth URL and poll
|
|
123
191
|
try {
|
|
124
192
|
const open = (await import('open')).default;
|
|
125
193
|
await open(authUrl);
|
|
126
194
|
console.log(chalk.dim('(Browser opened automatically)'));
|
|
127
195
|
} catch {
|
|
128
|
-
|
|
196
|
+
// Shouldn't happen since canOpenBrowser passed, but handle it
|
|
197
|
+
await setPendingSession({ session, baseUrl });
|
|
198
|
+
console.log(chalk.yellow('Could not open browser.'));
|
|
199
|
+
console.log(chalk.dim('\nPlease open the URL above manually, then run: papercrane login --complete\n'));
|
|
200
|
+
process.exit(0);
|
|
129
201
|
}
|
|
130
202
|
|
|
131
203
|
console.log(chalk.dim('\nWaiting for authorization... (press Ctrl+C to cancel)\n'));
|
|
@@ -136,10 +208,12 @@ program
|
|
|
136
208
|
const startTime = Date.now();
|
|
137
209
|
|
|
138
210
|
while (Date.now() - startTime < timeout) {
|
|
139
|
-
const statusRes = await
|
|
211
|
+
const statusRes = await httpClient.get(`${baseUrl}/api/cli-auth/status?session=${encodeURIComponent(session)}`, {
|
|
212
|
+
validateStatus: () => true
|
|
213
|
+
});
|
|
140
214
|
|
|
141
|
-
if (statusRes.
|
|
142
|
-
const data =
|
|
215
|
+
if (statusRes.status >= 200 && statusRes.status < 300) {
|
|
216
|
+
const data = statusRes.data;
|
|
143
217
|
|
|
144
218
|
if (data.status === 'authorized') {
|
|
145
219
|
// Save the API key
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import axios from "axios"
|
|
2
|
+
import { HttpsProxyAgent } from "https-proxy-agent"
|
|
3
|
+
|
|
4
|
+
const proxyUrl = process.env.HTTPS_PROXY || process.env.HTTP_PROXY
|
|
5
|
+
|
|
6
|
+
const axiosConfig = proxyUrl
|
|
7
|
+
? {
|
|
8
|
+
httpAgent: new HttpsProxyAgent(proxyUrl),
|
|
9
|
+
httpsAgent: new HttpsProxyAgent(proxyUrl),
|
|
10
|
+
proxy: false
|
|
11
|
+
}
|
|
12
|
+
: {}
|
|
13
|
+
|
|
14
|
+
export const http = axios.create(axiosConfig)
|
package/lib/cloud-client.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { http } from './axios-client.js';
|
|
2
2
|
import { getApiKey, getApiBaseUrl } from './config.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -16,7 +16,7 @@ export async function fetchCloudCredentials(provider, instanceName = 'Default')
|
|
|
16
16
|
const baseUrl = await getApiBaseUrl();
|
|
17
17
|
|
|
18
18
|
try {
|
|
19
|
-
const response = await
|
|
19
|
+
const response = await http.get(`${baseUrl}/api/sdk/credentials/${provider}/${instanceName}`, {
|
|
20
20
|
headers: {
|
|
21
21
|
'Authorization': `Bearer ${apiKey}`
|
|
22
22
|
}
|
|
@@ -52,7 +52,7 @@ export async function listCloudCredentials() {
|
|
|
52
52
|
const baseUrl = await getApiBaseUrl();
|
|
53
53
|
|
|
54
54
|
try {
|
|
55
|
-
const response = await
|
|
55
|
+
const response = await http.get(`${baseUrl}/api/sdk/credentials`, {
|
|
56
56
|
headers: {
|
|
57
57
|
'Authorization': `Bearer ${apiKey}`
|
|
58
58
|
}
|
|
@@ -84,7 +84,7 @@ export async function validateApiKey() {
|
|
|
84
84
|
// We expect either a 404 (integration not found, but key is valid)
|
|
85
85
|
// or a 200 (key is valid and integration exists)
|
|
86
86
|
// A 401 means the key is invalid
|
|
87
|
-
await
|
|
87
|
+
await http.get(`${baseUrl}/api/sdk/credentials/google/Default`, {
|
|
88
88
|
headers: {
|
|
89
89
|
'Authorization': `Bearer ${apiKey}`
|
|
90
90
|
}
|
|
@@ -120,7 +120,7 @@ export async function refreshCloudCredentials(provider, instanceName = 'Default'
|
|
|
120
120
|
const baseUrl = await getApiBaseUrl();
|
|
121
121
|
|
|
122
122
|
try {
|
|
123
|
-
const response = await
|
|
123
|
+
const response = await http.post(`${baseUrl}/api/sdk/credentials/${provider}/${instanceName}/refresh`, {}, {
|
|
124
124
|
headers: {
|
|
125
125
|
'Authorization': `Bearer ${apiKey}`
|
|
126
126
|
}
|
|
@@ -155,7 +155,7 @@ export async function pushCredentials(provider, credentialId, credentials, scope
|
|
|
155
155
|
|
|
156
156
|
const baseUrl = await getApiBaseUrl();
|
|
157
157
|
|
|
158
|
-
const response = await
|
|
158
|
+
const response = await http.post(`${baseUrl}/api/sdk/credentials/push`, {
|
|
159
159
|
provider,
|
|
160
160
|
credential_id: credentialId,
|
|
161
161
|
credentials,
|
|
@@ -183,11 +183,11 @@ export async function pullCredentials() {
|
|
|
183
183
|
|
|
184
184
|
const baseUrl = await getApiBaseUrl();
|
|
185
185
|
|
|
186
|
-
const response = await
|
|
186
|
+
const response = await http.get(`${baseUrl}/api/sdk/credentials/pull`, {
|
|
187
187
|
headers: {
|
|
188
188
|
'Authorization': `Bearer ${apiKey}`
|
|
189
189
|
}
|
|
190
190
|
});
|
|
191
191
|
|
|
192
192
|
return response.data.credentials || [];
|
|
193
|
-
}
|
|
193
|
+
}
|
package/lib/config.js
CHANGED
|
@@ -125,7 +125,7 @@ export async function clearDefaultWorkspace() {
|
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
/**
|
|
128
|
-
* Get pending login session (for --
|
|
128
|
+
* Get pending login session (for --print-url / --complete flow)
|
|
129
129
|
* @returns {Promise<{session: string, baseUrl: string}|null>}
|
|
130
130
|
*/
|
|
131
131
|
export async function getPendingSession() {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { http } from './axios-client.js';
|
|
2
2
|
import { homedir } from 'os';
|
|
3
3
|
import { join } from 'path';
|
|
4
4
|
import { getApiKey, getApiBaseUrl, getDefaultWorkspace, setDefaultWorkspace } from './config.js';
|
|
@@ -62,7 +62,7 @@ export async function listWorkspaces() {
|
|
|
62
62
|
const headers = await getAuthHeaders();
|
|
63
63
|
const baseUrl = await getApiBaseUrl();
|
|
64
64
|
|
|
65
|
-
const response = await
|
|
65
|
+
const response = await http.get(`${baseUrl}/sdk/workspaces`, { headers });
|
|
66
66
|
return response.data.workspaces;
|
|
67
67
|
}
|
|
68
68
|
|
|
@@ -80,7 +80,7 @@ export async function getFileTree(workspaceId, path = '') {
|
|
|
80
80
|
? `${baseUrl}/sdk/workspaces/${workspaceId}/files?path=${encodeURIComponent(path)}`
|
|
81
81
|
: `${baseUrl}/sdk/workspaces/${workspaceId}/files`;
|
|
82
82
|
|
|
83
|
-
const response = await
|
|
83
|
+
const response = await http.get(url, { headers });
|
|
84
84
|
return response.data;
|
|
85
85
|
}
|
|
86
86
|
|
|
@@ -94,7 +94,7 @@ export async function readFile(workspaceId, path) {
|
|
|
94
94
|
const headers = await getAuthHeaders();
|
|
95
95
|
const baseUrl = await getApiBaseUrl();
|
|
96
96
|
|
|
97
|
-
const response = await
|
|
97
|
+
const response = await http.get(
|
|
98
98
|
`${baseUrl}/sdk/workspaces/${workspaceId}/files/read?path=${encodeURIComponent(path)}`,
|
|
99
99
|
{ headers }
|
|
100
100
|
);
|
|
@@ -112,7 +112,7 @@ export async function writeFile(workspaceId, path, content) {
|
|
|
112
112
|
const headers = await getAuthHeaders();
|
|
113
113
|
const baseUrl = await getApiBaseUrl();
|
|
114
114
|
|
|
115
|
-
const response = await
|
|
115
|
+
const response = await http.post(
|
|
116
116
|
`${baseUrl}/sdk/workspaces/${workspaceId}/files/write`,
|
|
117
117
|
{ path, content },
|
|
118
118
|
{ headers }
|
|
@@ -133,7 +133,7 @@ export async function editFile(workspaceId, path, oldString, newString, replaceA
|
|
|
133
133
|
const headers = await getAuthHeaders();
|
|
134
134
|
const baseUrl = await getApiBaseUrl();
|
|
135
135
|
|
|
136
|
-
const response = await
|
|
136
|
+
const response = await http.post(
|
|
137
137
|
`${baseUrl}/sdk/workspaces/${workspaceId}/files/edit`,
|
|
138
138
|
{ path, old_string: oldString, new_string: newString, replace_all: replaceAll },
|
|
139
139
|
{ headers }
|
|
@@ -151,7 +151,7 @@ export async function deleteFile(workspaceId, path) {
|
|
|
151
151
|
const headers = await getAuthHeaders();
|
|
152
152
|
const baseUrl = await getApiBaseUrl();
|
|
153
153
|
|
|
154
|
-
const response = await
|
|
154
|
+
const response = await http.delete(
|
|
155
155
|
`${baseUrl}/sdk/workspaces/${workspaceId}/files?path=${encodeURIComponent(path)}`,
|
|
156
156
|
{ headers }
|
|
157
157
|
);
|
package/lib/facebook-auth.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { http } from './axios-client.js';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
3
|
import { saveFacebookCredentials } from './storage.js';
|
|
4
4
|
|
|
@@ -46,7 +46,7 @@ export async function handleFacebookAuth(scopes, appId, clientToken) {
|
|
|
46
46
|
|
|
47
47
|
// Step 1: Request device code
|
|
48
48
|
console.log(chalk.cyan('📱 Requesting device code...'));
|
|
49
|
-
const deviceResponse = await
|
|
49
|
+
const deviceResponse = await http.post(DEVICE_LOGIN_URL, null, {
|
|
50
50
|
params: {
|
|
51
51
|
access_token: accessToken,
|
|
52
52
|
scope: scopeString
|
|
@@ -80,7 +80,7 @@ export async function handleFacebookAuth(scopes, appId, clientToken) {
|
|
|
80
80
|
await new Promise(resolve => setTimeout(resolve, pollInterval));
|
|
81
81
|
|
|
82
82
|
try {
|
|
83
|
-
const statusResponse = await
|
|
83
|
+
const statusResponse = await http.post(DEVICE_STATUS_URL, null, {
|
|
84
84
|
params: {
|
|
85
85
|
access_token: accessToken,
|
|
86
86
|
code: code
|
|
@@ -145,4 +145,4 @@ export async function handleFacebookAuth(scopes, appId, clientToken) {
|
|
|
145
145
|
throw error;
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
|
-
}
|
|
148
|
+
}
|
package/lib/function-client.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { http } from "./axios-client.js"
|
|
2
2
|
import chalk from "chalk"
|
|
3
3
|
import { getApiKey, getApiBaseUrl } from "./config.js"
|
|
4
4
|
|
|
@@ -55,7 +55,7 @@ async function functionRequest(
|
|
|
55
55
|
|
|
56
56
|
// For POST requests, use streaming to handle large/streaming responses
|
|
57
57
|
if (method === "POST") {
|
|
58
|
-
const response = await
|
|
58
|
+
const response = await http({
|
|
59
59
|
method,
|
|
60
60
|
url,
|
|
61
61
|
headers: {
|
|
@@ -125,7 +125,7 @@ async function functionRequest(
|
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
// GET requests - use regular axios behavior
|
|
128
|
-
const response = await
|
|
128
|
+
const response = await http({
|
|
129
129
|
method,
|
|
130
130
|
url,
|
|
131
131
|
headers: {
|
package/lib/google-auth.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { http } from './axios-client.js';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
3
|
import open from 'open';
|
|
4
4
|
import { generatePKCE } from './pkce.js';
|
|
@@ -88,7 +88,7 @@ export async function handleGoogleAuth(scopes, clientId, clientSecret) {
|
|
|
88
88
|
// Exchange authorization code for tokens
|
|
89
89
|
console.log(chalk.cyan('🔄 Exchanging authorization code for tokens...'));
|
|
90
90
|
|
|
91
|
-
const tokenResponse = await
|
|
91
|
+
const tokenResponse = await http.post(
|
|
92
92
|
GOOGLE_TOKEN_URL,
|
|
93
93
|
new URLSearchParams({
|
|
94
94
|
code,
|
|
@@ -131,4 +131,4 @@ export async function handleGoogleAuth(scopes, clientId, clientSecret) {
|
|
|
131
131
|
throw error;
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
|
-
}
|
|
134
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@papercraneai/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "CLI tool for managing OAuth credentials for LLM integrations",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"commander": "^12.0.0",
|
|
30
30
|
"axios": "^1.6.0",
|
|
31
31
|
"chalk": "^4.1.2",
|
|
32
|
+
"https-proxy-agent": "^7.0.4",
|
|
32
33
|
"inquirer": "^8.2.6",
|
|
33
|
-
"open": "^8.4.2"
|
|
34
|
-
"undici": "^6.0.0"
|
|
34
|
+
"open": "^8.4.2"
|
|
35
35
|
}
|
|
36
36
|
}
|