byterover-cli 2.3.4 → 2.4.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/dist/server/infra/auth/oauth-service.js +6 -0
- package/dist/server/infra/auth/oidc-discovery-service.js +3 -0
- package/dist/server/infra/cogit/http-cogit-push-service.js +3 -0
- package/dist/server/infra/http/authenticated-http-client.js +19 -4
- package/dist/server/infra/http/models-dev-client.js +3 -0
- package/dist/server/infra/http/openrouter-api-client.js +3 -0
- package/dist/server/infra/http/provider-model-fetchers.js +7 -0
- package/dist/server/infra/http/proxy-config.d.ts +5 -0
- package/dist/server/infra/http/proxy-config.js +10 -0
- package/dist/server/infra/hub/hub-install-service.js +3 -0
- package/dist/server/infra/hub/hub-registry-service.js +3 -0
- package/dist/server/infra/memory/http-memory-storage-service.js +3 -0
- package/dist/server/infra/provider-oauth/refresh-token-exchange.js +3 -0
- package/dist/server/infra/provider-oauth/token-exchange.js +3 -0
- package/oclif.manifest.json +1 -1
- package/package.json +2 -1
|
@@ -3,6 +3,7 @@ import axios, { isAxiosError } from 'axios';
|
|
|
3
3
|
import crypto from 'node:crypto';
|
|
4
4
|
import { OAuthTokenData } from '../../core/domain/entities/oauth-token-data.js';
|
|
5
5
|
import { AuthenticationError } from '../../core/domain/errors/auth-error.js';
|
|
6
|
+
import { ProxyConfig } from '../http/proxy-config.js';
|
|
6
7
|
export const NETWORK_ERROR_CODE = {
|
|
7
8
|
EAI_AGAIN: 'EAI_AGAIN',
|
|
8
9
|
ECONNABORTED: 'ECONNABORTED',
|
|
@@ -49,6 +50,8 @@ export class OAuthService {
|
|
|
49
50
|
headers: {
|
|
50
51
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
51
52
|
},
|
|
53
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
54
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
52
55
|
});
|
|
53
56
|
return this.parseTokenResponse(response.data);
|
|
54
57
|
}
|
|
@@ -91,6 +94,9 @@ export class OAuthService {
|
|
|
91
94
|
client_secret: this.config.clientSecret,
|
|
92
95
|
grant_type: 'refresh_token',
|
|
93
96
|
refresh_token: refreshToken,
|
|
97
|
+
}, {
|
|
98
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
99
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
94
100
|
});
|
|
95
101
|
return this.parseTokenResponse(response.data);
|
|
96
102
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import axios, { isAxiosError } from 'axios';
|
|
2
2
|
import { DiscoveryError, DiscoveryNetworkError, DiscoveryTimeoutError } from '../../core/domain/errors/discovery-error.js';
|
|
3
|
+
import { ProxyConfig } from '../http/proxy-config.js';
|
|
3
4
|
/**
|
|
4
5
|
* OIDC discovery service implementation.
|
|
5
6
|
* Fetches OIDC configuration from the well-known endpoint with in-memory caching.
|
|
@@ -76,6 +77,8 @@ export class OidcDiscoveryService {
|
|
|
76
77
|
try {
|
|
77
78
|
const wellKnownUrl = `${issuerUrl}/.well-known/openid-configuration`;
|
|
78
79
|
const response = await axios.get(wellKnownUrl, {
|
|
80
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
81
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
79
82
|
timeout: this.timeoutMs,
|
|
80
83
|
});
|
|
81
84
|
// Validate required fields
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import axios from 'axios';
|
|
3
3
|
import { CogitPushResponse } from '../../core/domain/entities/cogit-push-response.js';
|
|
4
4
|
import { getErrorMessage } from '../../utils/error-helpers.js';
|
|
5
|
+
import { ProxyConfig } from '../http/proxy-config.js';
|
|
5
6
|
/**
|
|
6
7
|
* Extracts the current SHA from an error response details field.
|
|
7
8
|
* Error format: "...Expected SHA 'xxx' but current SHA is 'yyy'..."
|
|
@@ -96,6 +97,8 @@ export class HttpCogitPushService {
|
|
|
96
97
|
headers: {
|
|
97
98
|
'x-byterover-session-id': params.sessionKey,
|
|
98
99
|
},
|
|
100
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
101
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
99
102
|
timeout: this.config.timeout,
|
|
100
103
|
});
|
|
101
104
|
return CogitPushResponse.fromJson(response.data);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import axios, { isAxiosError } from 'axios';
|
|
2
|
+
import { ProxyConfig } from './proxy-config.js';
|
|
2
3
|
/**
|
|
3
4
|
* HTTP client implementation that automatically adds authentication headers to all requests.
|
|
4
5
|
*
|
|
@@ -27,6 +28,8 @@ export class AuthenticatedHttpClient {
|
|
|
27
28
|
try {
|
|
28
29
|
const axiosConfig = {
|
|
29
30
|
headers: this.buildHeaders(config?.headers),
|
|
31
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
32
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
30
33
|
timeout: config?.timeout,
|
|
31
34
|
};
|
|
32
35
|
const response = await axios.get(url, axiosConfig);
|
|
@@ -48,6 +51,8 @@ export class AuthenticatedHttpClient {
|
|
|
48
51
|
try {
|
|
49
52
|
const axiosConfig = {
|
|
50
53
|
headers: this.buildHeaders(config?.headers),
|
|
54
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
55
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
51
56
|
timeout: config?.timeout,
|
|
52
57
|
};
|
|
53
58
|
const response = await axios.post(url, data, axiosConfig);
|
|
@@ -69,6 +74,8 @@ export class AuthenticatedHttpClient {
|
|
|
69
74
|
try {
|
|
70
75
|
const axiosConfig = {
|
|
71
76
|
headers: this.buildHeaders(config?.headers),
|
|
77
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
78
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
72
79
|
timeout: config?.timeout,
|
|
73
80
|
};
|
|
74
81
|
const response = await axios.put(url, data, axiosConfig);
|
|
@@ -107,13 +114,21 @@ export class AuthenticatedHttpClient {
|
|
|
107
114
|
// Server responded with error status
|
|
108
115
|
return new Error(`HTTP ${error.response.status}: ${error.response.statusText}`);
|
|
109
116
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
return new Error(`
|
|
117
|
+
// Enterprise Proxy / SSL Checks
|
|
118
|
+
if (error.code === 'SELF_SIGNED_CERT_IN_CHAIN' || error.code === 'UNABLE_TO_VERIFY_LEAF_SIGNATURE' || error.code === 'CERT_HAS_EXPIRED') {
|
|
119
|
+
return new Error(`SSL Certificate Validation Failed (${error.code}). Your company may be using SSL Inspection.\n` +
|
|
120
|
+
`Solution: Set the NODE_EXTRA_CA_CERTS environment variable to your corporate CA certificate path.\n` +
|
|
121
|
+
`Example: export NODE_EXTRA_CA_CERTS=/path/to/corporate-ca.pem`);
|
|
122
|
+
}
|
|
123
|
+
const isTimeout = error.code === 'ECONNABORTED' || error.code === 'ETIMEDOUT' || error.message.includes('timeout');
|
|
124
|
+
const isRefused = error.code === 'ECONNREFUSED';
|
|
125
|
+
if (isTimeout || isRefused) {
|
|
126
|
+
return new Error(`Connection Failed (${error.code || 'TIMEOUT'}). If you are behind a corporate firewall, configure your proxy:\n` +
|
|
127
|
+
` export HTTPS_PROXY=http://proxy-host:port`);
|
|
113
128
|
}
|
|
114
129
|
if (error.request) {
|
|
115
130
|
// Request was made but no response received
|
|
116
|
-
return new Error('Network error: No response received from server');
|
|
131
|
+
return new Error('Network error: No response received from server. Check your proxy or internet connection.');
|
|
117
132
|
}
|
|
118
133
|
}
|
|
119
134
|
// Generic error
|
|
@@ -10,6 +10,7 @@ import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
|
10
10
|
import { dirname, join } from 'node:path';
|
|
11
11
|
import { z } from 'zod';
|
|
12
12
|
import { getGlobalDataDir } from '../../utils/global-data-path.js';
|
|
13
|
+
import { ProxyConfig } from './proxy-config.js';
|
|
13
14
|
const CacheEnvelopeSchema = z.object({
|
|
14
15
|
data: z.record(z.unknown()),
|
|
15
16
|
timestamp: z.number(),
|
|
@@ -57,6 +58,8 @@ export class ModelsDevClient {
|
|
|
57
58
|
}
|
|
58
59
|
async fetchAndCache() {
|
|
59
60
|
const response = await axios.get(MODELS_DEV_URL, {
|
|
61
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
62
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
60
63
|
timeout: FETCH_TIMEOUT_MS,
|
|
61
64
|
});
|
|
62
65
|
const { data } = response;
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* Uses the OpenRouter REST API: https://openrouter.ai/api/v1
|
|
9
9
|
*/
|
|
10
10
|
import axios, { isAxiosError } from 'axios';
|
|
11
|
+
import { ProxyConfig } from './proxy-config.js';
|
|
11
12
|
const DEFAULT_BASE_URL = 'https://openrouter.ai/api/v1';
|
|
12
13
|
const DEFAULT_CACHE_TTL = 60 * 60 * 1000; // 1 hour
|
|
13
14
|
/**
|
|
@@ -100,6 +101,8 @@ export class OpenRouterApiClient {
|
|
|
100
101
|
'HTTP-Referer': this.httpReferer,
|
|
101
102
|
'X-Title': this.xTitle,
|
|
102
103
|
},
|
|
104
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
105
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
103
106
|
timeout: 30_000,
|
|
104
107
|
});
|
|
105
108
|
return response.data.data.map((model) => this.normalizeModel(model));
|
|
@@ -16,6 +16,7 @@ import { APICallError, generateText } from 'ai';
|
|
|
16
16
|
import axios, { isAxiosError } from 'axios';
|
|
17
17
|
import OpenAI from 'openai';
|
|
18
18
|
import { getModelsDevClient as getModelsDevClientDefault } from './models-dev-client.js';
|
|
19
|
+
import { ProxyConfig } from './proxy-config.js';
|
|
19
20
|
const DEFAULT_CACHE_TTL = 60 * 60 * 1000; // 1 hour
|
|
20
21
|
const ANTHROPIC_KNOWN_MODELS = {
|
|
21
22
|
'claude-3-5-haiku-20241022': { contextLength: 200_000, inputPerM: 0.8, outputPerM: 4 },
|
|
@@ -346,6 +347,8 @@ export class OpenAICompatibleModelFetcher {
|
|
|
346
347
|
}
|
|
347
348
|
const response = await axios.get(`${this.baseUrl}/models`, {
|
|
348
349
|
headers: { Authorization: `Bearer ${apiKey}` },
|
|
350
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
351
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
349
352
|
timeout: 30_000,
|
|
350
353
|
});
|
|
351
354
|
// Handle different response formats:
|
|
@@ -376,6 +379,8 @@ export class OpenAICompatibleModelFetcher {
|
|
|
376
379
|
try {
|
|
377
380
|
await axios.get(`${this.baseUrl}/models`, {
|
|
378
381
|
headers: { Authorization: `Bearer ${apiKey}` },
|
|
382
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
383
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
379
384
|
timeout: 15_000,
|
|
380
385
|
});
|
|
381
386
|
return { isValid: true };
|
|
@@ -431,6 +436,8 @@ export class ChatBasedModelFetcher {
|
|
|
431
436
|
Authorization: `Bearer ${apiKey}`,
|
|
432
437
|
'Content-Type': 'application/json',
|
|
433
438
|
},
|
|
439
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
440
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
434
441
|
timeout: 15_000,
|
|
435
442
|
});
|
|
436
443
|
return { isValid: true };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import axios, { isAxiosError } from 'axios';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { BRV_DIR, CONTEXT_TREE_DIR } from '../../constants.js';
|
|
4
|
+
import { ProxyConfig } from '../http/proxy-config.js';
|
|
4
5
|
import { buildAuthHeaders } from './hub-auth-headers.js';
|
|
5
6
|
export class HubInstallService {
|
|
6
7
|
fileService;
|
|
@@ -30,6 +31,8 @@ export class HubInstallService {
|
|
|
30
31
|
const headers = buildAuthHeaders(auth ?? {});
|
|
31
32
|
const response = await axios.get(url, {
|
|
32
33
|
headers,
|
|
34
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
35
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
33
36
|
responseType: 'text',
|
|
34
37
|
timeout: 15_000,
|
|
35
38
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* eslint-disable camelcase */
|
|
2
2
|
import axios, { isAxiosError } from 'axios';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
+
import { ProxyConfig } from '../http/proxy-config.js';
|
|
4
5
|
import { buildAuthHeaders } from './hub-auth-headers.js';
|
|
5
6
|
const CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes
|
|
6
7
|
const HubEntrySchema = z.object({
|
|
@@ -69,6 +70,8 @@ export class HubRegistryService {
|
|
|
69
70
|
});
|
|
70
71
|
const response = await axios.get(this.registryUrl, {
|
|
71
72
|
headers,
|
|
73
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
74
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
72
75
|
timeout: this.timeoutMs,
|
|
73
76
|
});
|
|
74
77
|
const validated = this.parseRegistryResponse(response.data);
|
|
@@ -4,6 +4,7 @@ import { PresignedUrl } from '../../core/domain/entities/presigned-url.js';
|
|
|
4
4
|
import { PresignedUrlsResponse } from '../../core/domain/entities/presigned-urls-response.js';
|
|
5
5
|
import { getErrorMessage } from '../../utils/error-helpers.js';
|
|
6
6
|
import { AuthenticatedHttpClient } from '../http/authenticated-http-client.js';
|
|
7
|
+
import { ProxyConfig } from '../http/proxy-config.js';
|
|
7
8
|
/**
|
|
8
9
|
* HTTP implementation of IMemoryStorageService for ByteRover CoGit service.
|
|
9
10
|
* Handles uploading playbooks to blob storage.
|
|
@@ -55,6 +56,8 @@ export class HttpMemoryStorageService {
|
|
|
55
56
|
headers: {
|
|
56
57
|
'Content-Type': 'application/json',
|
|
57
58
|
},
|
|
59
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
60
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
58
61
|
timeout: this.config.timeout,
|
|
59
62
|
});
|
|
60
63
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* eslint-disable camelcase */
|
|
2
2
|
import axios, { isAxiosError } from 'axios';
|
|
3
|
+
import { ProxyConfig } from '../http/proxy-config.js';
|
|
3
4
|
import { extractOAuthErrorFields, ProviderTokenExchangeError } from './errors.js';
|
|
4
5
|
import { ProviderTokenResponseSchema } from './types.js';
|
|
5
6
|
/**
|
|
@@ -20,6 +21,8 @@ export async function exchangeRefreshToken(params) {
|
|
|
20
21
|
headers: {
|
|
21
22
|
'Content-Type': params.contentType,
|
|
22
23
|
},
|
|
24
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
25
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
23
26
|
timeout: 30_000,
|
|
24
27
|
});
|
|
25
28
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* eslint-disable camelcase */
|
|
2
2
|
import axios, { isAxiosError } from 'axios';
|
|
3
|
+
import { ProxyConfig } from '../http/proxy-config.js';
|
|
3
4
|
import { extractOAuthErrorFields, ProviderTokenExchangeError } from './errors.js';
|
|
4
5
|
import { ProviderTokenResponseSchema } from './types.js';
|
|
5
6
|
/**
|
|
@@ -25,6 +26,8 @@ export async function exchangeCodeForTokens(params) {
|
|
|
25
26
|
headers: {
|
|
26
27
|
'Content-Type': params.contentType,
|
|
27
28
|
},
|
|
29
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
30
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
28
31
|
timeout: 30_000,
|
|
29
32
|
});
|
|
30
33
|
}
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "byterover-cli",
|
|
3
3
|
"description": "ByteRover's CLI",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.4.0",
|
|
5
5
|
"author": "ByteRover",
|
|
6
6
|
"bin": {
|
|
7
7
|
"brv": "./bin/run.js"
|
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
"officeparser": "^6.0.4",
|
|
56
56
|
"open": "^10.2.0",
|
|
57
57
|
"openai": "^6.9.1",
|
|
58
|
+
"proxy-agent": "^7.0.0",
|
|
58
59
|
"react": "^19.2.1",
|
|
59
60
|
"react-router-dom": "^7.13.0",
|
|
60
61
|
"remark-parse": "^11.0.0",
|