hedgequantx 2.6.106 → 2.6.108

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hedgequantx",
3
- "version": "2.6.106",
3
+ "version": "2.6.108",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -1029,17 +1029,60 @@ const setupProxyOAuth = async (provider, config) => {
1029
1029
  }
1030
1030
  console.log();
1031
1031
 
1032
- // Step 4: Wait for OAuth callback
1032
+ // Step 4: Wait for OAuth callback (with manual fallback for VPS/remote)
1033
1033
  const waitSpinner = ora({ text: 'Waiting for authorization...', color: 'cyan' }).start();
1034
1034
 
1035
+ let authSuccess = false;
1036
+
1037
+ // First try: wait 10 seconds for automatic callback (quick for local, fast fallback for VPS)
1035
1038
  try {
1036
- await proxyManager.waitForAuth(authState, 300000, (status) => {
1039
+ await proxyManager.waitForAuth(authState, 10000, (status) => {
1037
1040
  waitSpinner.text = status;
1038
1041
  });
1042
+ authSuccess = true;
1039
1043
  waitSpinner.succeed('Authorization successful!');
1040
1044
  } catch (error) {
1041
- waitSpinner.fail(`Authorization failed: ${error.message}`);
1042
- await prompts.waitForEnter();
1045
+ // Timeout - offer manual callback entry
1046
+ if (error.message === 'Authentication timeout') {
1047
+ waitSpinner.stop();
1048
+ console.log();
1049
+ console.log(chalk.yellow(' Paste the callback URL from your browser:'));
1050
+ console.log(chalk.gray(' (The page showing http://localhost:54545/callback?code=...)'));
1051
+ console.log();
1052
+
1053
+ const callbackUrl = await prompts.input(' Callback URL: ');
1054
+
1055
+ if (callbackUrl && callbackUrl.trim()) {
1056
+ const submitSpinner = ora({ text: 'Submitting callback...', color: 'cyan' }).start();
1057
+ try {
1058
+ await proxyManager.submitCallback(callbackUrl.trim());
1059
+ submitSpinner.text = 'Verifying authorization...';
1060
+
1061
+ // Wait a bit for the proxy to process the callback
1062
+ await new Promise(resolve => setTimeout(resolve, 2000));
1063
+
1064
+ // Verify auth status
1065
+ await proxyManager.waitForAuth(authState, 10000, () => {});
1066
+ authSuccess = true;
1067
+ submitSpinner.succeed('Authorization successful!');
1068
+ } catch (submitError) {
1069
+ submitSpinner.fail(`Failed: ${submitError.message}`);
1070
+ await prompts.waitForEnter();
1071
+ return await selectProviderOption(provider);
1072
+ }
1073
+ } else {
1074
+ console.log(chalk.gray(' Cancelled.'));
1075
+ await prompts.waitForEnter();
1076
+ return await selectProviderOption(provider);
1077
+ }
1078
+ } else {
1079
+ waitSpinner.fail(`Authorization failed: ${error.message}`);
1080
+ await prompts.waitForEnter();
1081
+ return await selectProviderOption(provider);
1082
+ }
1083
+ }
1084
+
1085
+ if (!authSuccess) {
1043
1086
  return await selectProviderOption(provider);
1044
1087
  }
1045
1088
 
@@ -530,6 +530,64 @@ const waitForAuth = async (state, timeoutMs = 300000, onStatus = () => {}) => {
530
530
  throw new Error('Authentication timeout');
531
531
  };
532
532
 
533
+ /**
534
+ * Submit OAuth callback URL manually (for remote/VPS use)
535
+ * Extracts code and state from callback URL and submits to local proxy
536
+ * @param {string} callbackUrl - Full callback URL (http://localhost:54545/callback?code=xxx&state=yyy)
537
+ * @returns {Promise<boolean>}
538
+ */
539
+ const submitCallback = async (callbackUrl) => {
540
+ // Parse the callback URL
541
+ let url;
542
+ try {
543
+ url = new URL(callbackUrl);
544
+ } catch (e) {
545
+ throw new Error('Invalid callback URL format');
546
+ }
547
+
548
+ const code = url.searchParams.get('code');
549
+ const state = url.searchParams.get('state');
550
+
551
+ if (!code || !state) {
552
+ throw new Error('Missing code or state in callback URL');
553
+ }
554
+
555
+ // Submit to local callback server
556
+ return new Promise((resolve, reject) => {
557
+ const callbackPath = `/callback?code=${encodeURIComponent(code)}&state=${encodeURIComponent(state)}`;
558
+
559
+ const req = http.request({
560
+ hostname: '127.0.0.1',
561
+ port: 54545,
562
+ path: callbackPath,
563
+ method: 'GET',
564
+ timeout: 30000
565
+ }, (res) => {
566
+ let data = '';
567
+ res.on('data', chunk => data += chunk);
568
+ res.on('end', () => {
569
+ // Success if we get a redirect or success page
570
+ if (res.statusCode === 200 || res.statusCode === 302 || res.statusCode === 301) {
571
+ resolve(true);
572
+ } else {
573
+ reject(new Error(`Callback failed with status ${res.statusCode}`));
574
+ }
575
+ });
576
+ });
577
+
578
+ req.on('error', (e) => {
579
+ reject(new Error(`Failed to submit callback: ${e.message}`));
580
+ });
581
+
582
+ req.on('timeout', () => {
583
+ req.destroy();
584
+ reject(new Error('Callback request timeout'));
585
+ });
586
+
587
+ req.end();
588
+ });
589
+ };
590
+
533
591
  /**
534
592
  * Get available models from the proxy
535
593
  * @returns {Promise<Array<string>>}
@@ -766,6 +824,7 @@ module.exports = {
766
824
  getAuthUrl,
767
825
  pollAuthStatus,
768
826
  waitForAuth,
827
+ submitCallback,
769
828
  getModels,
770
829
  getAuthFiles,
771
830
  chatCompletion,