byterover-cli 2.3.4 → 2.4.1

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.
@@ -55,7 +55,7 @@ export declare const SHUTDOWN_FORCE_EXIT_MS = 5000;
55
55
  export declare const AUTH_STATE_POLL_INTERVAL_MS = 5000;
56
56
  export declare const AGENT_MAX_CONCURRENT_TASKS = 5;
57
57
  export declare const AGENT_POOL_MAX_SIZE = 10;
58
- export declare const AGENT_PROCESS_READY_TIMEOUT_MS = 15000;
58
+ export declare const AGENT_PROCESS_READY_TIMEOUT_MS = 30000;
59
59
  export declare const AGENT_PROCESS_STOP_TIMEOUT_MS = 5000;
60
60
  export declare const CURATE_LOG_DIR = "curate-log";
61
61
  export declare const CURATE_LOG_ID_PREFIX = "cur";
@@ -75,7 +75,7 @@ export const AUTH_STATE_POLL_INTERVAL_MS = 5000; // Poll token store every 5s
75
75
  // Agent Pool (T6)
76
76
  export const AGENT_MAX_CONCURRENT_TASKS = 5; // Max parallel curate/query tasks per agent process
77
77
  export const AGENT_POOL_MAX_SIZE = 10;
78
- export const AGENT_PROCESS_READY_TIMEOUT_MS = 15_000; // 15s max wait for child process to register
78
+ export const AGENT_PROCESS_READY_TIMEOUT_MS = 30_000; // 30s max wait for child process to register
79
79
  export const AGENT_PROCESS_STOP_TIMEOUT_MS = 5000; // 5s max wait for child process to stop gracefully
80
80
  // Curate log
81
81
  export const CURATE_LOG_DIR = 'curate-log';
@@ -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);
@@ -204,7 +204,11 @@ async function main() {
204
204
  agentPool = new AgentPool({
205
205
  agentIdleTimeoutPolicy,
206
206
  agentProcessFactory(projectPath) {
207
- return fork(agentProcessPath, [], {
207
+ // Prevent console window flash on Windows when forking agent processes.
208
+ // windowsHide is supported at runtime (fork delegates to spawn) but not in ForkOptions types,
209
+ // so we extract the options to a variable to bypass excess property checking.
210
+ const e2eStdio = ['ignore', 'inherit', 'inherit', 'ipc'];
211
+ const forkOptions = {
208
212
  cwd: projectPath,
209
213
  env: {
210
214
  ...process.env,
@@ -212,8 +216,10 @@ async function main() {
212
216
  BRV_AGENT_PROJECT_PATH: projectPath,
213
217
  },
214
218
  // In E2E mode, inherit stderr to see agent errors
215
- stdio: process.env.BRV_E2E_MODE === 'true' ? ['ignore', 'inherit', 'inherit', 'ipc'] : undefined,
216
- });
219
+ stdio: process.env.BRV_E2E_MODE === 'true' ? e2eStdio : undefined,
220
+ windowsHide: true,
221
+ };
222
+ return fork(agentProcessPath, [], forkOptions);
217
223
  },
218
224
  log,
219
225
  transportServer,
@@ -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
- if (error.code === 'ECONNABORTED' || error.message.includes('timeout')) {
111
- // Request timeout
112
- return new Error(`Request timeout: ${error.message}`);
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 };
@@ -0,0 +1,5 @@
1
+ import { ProxyAgent } from 'proxy-agent';
2
+ export declare class ProxyConfig {
3
+ private static agent;
4
+ static getProxyAgent(): ProxyAgent;
5
+ }
@@ -0,0 +1,10 @@
1
+ import { ProxyAgent } from 'proxy-agent';
2
+ export class ProxyConfig {
3
+ static agent;
4
+ static getProxyAgent() {
5
+ if (!this.agent) {
6
+ this.agent = new ProxyAgent();
7
+ }
8
+ return this.agent;
9
+ }
10
+ }
@@ -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
  }
@@ -1083,6 +1083,104 @@
1083
1083
  "switch.js"
1084
1084
  ]
1085
1085
  },
1086
+ "space:list": {
1087
+ "aliases": [],
1088
+ "args": {},
1089
+ "description": "List all teams and spaces",
1090
+ "examples": [
1091
+ "<%= config.bin %> space list",
1092
+ "<%= config.bin %> space list --format json"
1093
+ ],
1094
+ "flags": {
1095
+ "format": {
1096
+ "char": "f",
1097
+ "description": "Output format",
1098
+ "name": "format",
1099
+ "default": "text",
1100
+ "hasDynamicHelp": false,
1101
+ "multiple": false,
1102
+ "options": [
1103
+ "text",
1104
+ "json"
1105
+ ],
1106
+ "type": "option"
1107
+ }
1108
+ },
1109
+ "hasDynamicHelp": false,
1110
+ "hiddenAliases": [],
1111
+ "id": "space:list",
1112
+ "pluginAlias": "byterover-cli",
1113
+ "pluginName": "byterover-cli",
1114
+ "pluginType": "core",
1115
+ "strict": true,
1116
+ "enableJsonFlag": false,
1117
+ "isESM": true,
1118
+ "relativePath": [
1119
+ "dist",
1120
+ "oclif",
1121
+ "commands",
1122
+ "space",
1123
+ "list.js"
1124
+ ]
1125
+ },
1126
+ "space:switch": {
1127
+ "aliases": [],
1128
+ "args": {},
1129
+ "description": "Switch to a different space",
1130
+ "examples": [
1131
+ "<%= config.bin %> space switch --team acme --name my-space",
1132
+ "<%= config.bin %> space switch --team acme --name my-space --format json"
1133
+ ],
1134
+ "flags": {
1135
+ "format": {
1136
+ "char": "f",
1137
+ "description": "Output format",
1138
+ "name": "format",
1139
+ "default": "text",
1140
+ "hasDynamicHelp": false,
1141
+ "multiple": false,
1142
+ "options": [
1143
+ "text",
1144
+ "json"
1145
+ ],
1146
+ "type": "option"
1147
+ },
1148
+ "name": {
1149
+ "char": "n",
1150
+ "description": "Name of the space to switch to",
1151
+ "name": "name",
1152
+ "required": true,
1153
+ "hasDynamicHelp": false,
1154
+ "multiple": false,
1155
+ "type": "option"
1156
+ },
1157
+ "team": {
1158
+ "char": "t",
1159
+ "description": "Team name",
1160
+ "name": "team",
1161
+ "required": true,
1162
+ "hasDynamicHelp": false,
1163
+ "multiple": false,
1164
+ "type": "option"
1165
+ }
1166
+ },
1167
+ "hasDynamicHelp": false,
1168
+ "hiddenAliases": [],
1169
+ "id": "space:switch",
1170
+ "pluginAlias": "byterover-cli",
1171
+ "pluginName": "byterover-cli",
1172
+ "pluginType": "core",
1173
+ "strict": true,
1174
+ "enableJsonFlag": false,
1175
+ "isESM": true,
1176
+ "relativePath": [
1177
+ "dist",
1178
+ "oclif",
1179
+ "commands",
1180
+ "space",
1181
+ "switch.js"
1182
+ ]
1183
+ },
1086
1184
  "providers:connect": {
1087
1185
  "aliases": [],
1088
1186
  "args": {
@@ -1339,104 +1437,6 @@
1339
1437
  "switch.js"
1340
1438
  ]
1341
1439
  },
1342
- "space:list": {
1343
- "aliases": [],
1344
- "args": {},
1345
- "description": "List all teams and spaces",
1346
- "examples": [
1347
- "<%= config.bin %> space list",
1348
- "<%= config.bin %> space list --format json"
1349
- ],
1350
- "flags": {
1351
- "format": {
1352
- "char": "f",
1353
- "description": "Output format",
1354
- "name": "format",
1355
- "default": "text",
1356
- "hasDynamicHelp": false,
1357
- "multiple": false,
1358
- "options": [
1359
- "text",
1360
- "json"
1361
- ],
1362
- "type": "option"
1363
- }
1364
- },
1365
- "hasDynamicHelp": false,
1366
- "hiddenAliases": [],
1367
- "id": "space:list",
1368
- "pluginAlias": "byterover-cli",
1369
- "pluginName": "byterover-cli",
1370
- "pluginType": "core",
1371
- "strict": true,
1372
- "enableJsonFlag": false,
1373
- "isESM": true,
1374
- "relativePath": [
1375
- "dist",
1376
- "oclif",
1377
- "commands",
1378
- "space",
1379
- "list.js"
1380
- ]
1381
- },
1382
- "space:switch": {
1383
- "aliases": [],
1384
- "args": {},
1385
- "description": "Switch to a different space",
1386
- "examples": [
1387
- "<%= config.bin %> space switch --team acme --name my-space",
1388
- "<%= config.bin %> space switch --team acme --name my-space --format json"
1389
- ],
1390
- "flags": {
1391
- "format": {
1392
- "char": "f",
1393
- "description": "Output format",
1394
- "name": "format",
1395
- "default": "text",
1396
- "hasDynamicHelp": false,
1397
- "multiple": false,
1398
- "options": [
1399
- "text",
1400
- "json"
1401
- ],
1402
- "type": "option"
1403
- },
1404
- "name": {
1405
- "char": "n",
1406
- "description": "Name of the space to switch to",
1407
- "name": "name",
1408
- "required": true,
1409
- "hasDynamicHelp": false,
1410
- "multiple": false,
1411
- "type": "option"
1412
- },
1413
- "team": {
1414
- "char": "t",
1415
- "description": "Team name",
1416
- "name": "team",
1417
- "required": true,
1418
- "hasDynamicHelp": false,
1419
- "multiple": false,
1420
- "type": "option"
1421
- }
1422
- },
1423
- "hasDynamicHelp": false,
1424
- "hiddenAliases": [],
1425
- "id": "space:switch",
1426
- "pluginAlias": "byterover-cli",
1427
- "pluginName": "byterover-cli",
1428
- "pluginType": "core",
1429
- "strict": true,
1430
- "enableJsonFlag": false,
1431
- "isESM": true,
1432
- "relativePath": [
1433
- "dist",
1434
- "oclif",
1435
- "commands",
1436
- "space",
1437
- "switch.js"
1438
- ]
1439
- },
1440
1440
  "hub:registry:add": {
1441
1441
  "aliases": [],
1442
1442
  "args": {
@@ -1636,5 +1636,5 @@
1636
1636
  ]
1637
1637
  }
1638
1638
  },
1639
- "version": "2.3.4"
1639
+ "version": "2.4.1"
1640
1640
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "byterover-cli",
3
3
  "description": "ByteRover's CLI",
4
- "version": "2.3.4",
4
+ "version": "2.4.1",
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",