@papercraneai/cli 1.4.3 → 1.4.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.
- package/bin/papercrane.js +14 -20
- package/lib/axios-client.js +14 -0
- package/lib/cloud-client.js +8 -8
- 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,19 +4,12 @@ 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 '../lib/axios-client.js';
|
|
8
8
|
import { setApiKey, clearConfig, isLoggedIn, setDefaultWorkspace, getDefaultWorkspace } from '../lib/config.js';
|
|
9
9
|
import { validateApiKey } from '../lib/cloud-client.js';
|
|
10
10
|
import { listFunctions, getFunction, runFunction, formatDescribe, formatDescribeRoot, formatFlat, formatResult, formatUnconnected } from '../lib/function-client.js';
|
|
11
11
|
import { listWorkspaces, resolveWorkspaceId, getFileTree, readFile, writeFile, editFile, deleteFile, getLocalWorkspacePath, pullWorkspace, pushWorkspace } from '../lib/environment-client.js';
|
|
12
12
|
|
|
13
|
-
// Configure proxy support for environments like Claude's container
|
|
14
|
-
// Node.js native fetch() doesn't respect HTTP_PROXY/HTTPS_PROXY env vars
|
|
15
|
-
const proxyUrl = process.env.HTTPS_PROXY || process.env.HTTP_PROXY;
|
|
16
|
-
if (proxyUrl) {
|
|
17
|
-
setGlobalDispatcher(new ProxyAgent(proxyUrl));
|
|
18
|
-
}
|
|
19
|
-
|
|
20
13
|
const program = new Command();
|
|
21
14
|
|
|
22
15
|
program
|
|
@@ -69,10 +62,12 @@ program
|
|
|
69
62
|
process.exit(1);
|
|
70
63
|
}
|
|
71
64
|
|
|
72
|
-
const statusRes = await
|
|
65
|
+
const statusRes = await http.get(`${pending.baseUrl}/api/cli-auth/status?session=${encodeURIComponent(pending.session)}`, {
|
|
66
|
+
validateStatus: () => true
|
|
67
|
+
});
|
|
73
68
|
|
|
74
|
-
if (statusRes.
|
|
75
|
-
const data =
|
|
69
|
+
if (statusRes.status >= 200 && statusRes.status < 300) {
|
|
70
|
+
const data = statusRes.data;
|
|
76
71
|
if (data.status === 'authorized') {
|
|
77
72
|
await setApiKey(data.key);
|
|
78
73
|
await setApiBaseUrl(pending.baseUrl);
|
|
@@ -93,17 +88,14 @@ program
|
|
|
93
88
|
const session = generateState();
|
|
94
89
|
|
|
95
90
|
// Initialize session on server
|
|
96
|
-
const initRes = await
|
|
97
|
-
method: 'POST',
|
|
91
|
+
const initRes = await http.post(`${baseUrl}/api/cli-auth/init`, { session }, {
|
|
98
92
|
headers: { 'Content-Type': 'application/json' },
|
|
99
|
-
|
|
93
|
+
validateStatus: () => true
|
|
100
94
|
});
|
|
101
95
|
|
|
102
|
-
if (
|
|
96
|
+
if (initRes.status < 200 || initRes.status >= 300) {
|
|
103
97
|
throw new Error('Failed to initialize login session');
|
|
104
98
|
}
|
|
105
|
-
// Drain response body to avoid keeping the event loop alive (undici)
|
|
106
|
-
await initRes.arrayBuffer();
|
|
107
99
|
|
|
108
100
|
const authUrl = `${baseUrl}/cli-auth?session=${session}`;
|
|
109
101
|
|
|
@@ -136,10 +128,12 @@ program
|
|
|
136
128
|
const startTime = Date.now();
|
|
137
129
|
|
|
138
130
|
while (Date.now() - startTime < timeout) {
|
|
139
|
-
const statusRes = await
|
|
131
|
+
const statusRes = await http.get(`${baseUrl}/api/cli-auth/status?session=${encodeURIComponent(session)}`, {
|
|
132
|
+
validateStatus: () => true
|
|
133
|
+
});
|
|
140
134
|
|
|
141
|
-
if (statusRes.
|
|
142
|
-
const data =
|
|
135
|
+
if (statusRes.status >= 200 && statusRes.status < 300) {
|
|
136
|
+
const data = statusRes.data;
|
|
143
137
|
|
|
144
138
|
if (data.status === 'authorized') {
|
|
145
139
|
// 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
|
+
}
|
|
@@ -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.4.
|
|
3
|
+
"version": "1.4.4",
|
|
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
|
}
|