hedgequantx 2.6.106 → 2.6.107

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.107",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -1029,17 +1029,65 @@ 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 45 seconds for automatic callback
1035
1038
  try {
1036
- await proxyManager.waitForAuth(authState, 300000, (status) => {
1039
+ await proxyManager.waitForAuth(authState, 45000, (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(' ⚠ Callback not received automatically.'));
1050
+ console.log(chalk.gray(' If you\'re on a remote server (VPS), the callback cannot reach this machine.'));
1051
+ console.log();
1052
+ console.log(chalk.white(' After authorizing, you should see a page with URL like:'));
1053
+ console.log(chalk.cyan(' http://localhost:54545/callback?code=xxx&state=yyy'));
1054
+ console.log();
1055
+ console.log(chalk.white(' Paste that full URL below (or press Enter to cancel):'));
1056
+ console.log();
1057
+
1058
+ const callbackUrl = await prompts.input(' Callback URL: ');
1059
+
1060
+ if (callbackUrl && callbackUrl.trim()) {
1061
+ const submitSpinner = ora({ text: 'Submitting callback...', color: 'cyan' }).start();
1062
+ try {
1063
+ await proxyManager.submitCallback(callbackUrl.trim());
1064
+ submitSpinner.text = 'Verifying authorization...';
1065
+
1066
+ // Wait a bit for the proxy to process the callback
1067
+ await new Promise(resolve => setTimeout(resolve, 2000));
1068
+
1069
+ // Verify auth status
1070
+ await proxyManager.waitForAuth(authState, 10000, () => {});
1071
+ authSuccess = true;
1072
+ submitSpinner.succeed('Authorization successful!');
1073
+ } catch (submitError) {
1074
+ submitSpinner.fail(`Failed: ${submitError.message}`);
1075
+ await prompts.waitForEnter();
1076
+ return await selectProviderOption(provider);
1077
+ }
1078
+ } else {
1079
+ console.log(chalk.gray(' Cancelled.'));
1080
+ await prompts.waitForEnter();
1081
+ return await selectProviderOption(provider);
1082
+ }
1083
+ } else {
1084
+ waitSpinner.fail(`Authorization failed: ${error.message}`);
1085
+ await prompts.waitForEnter();
1086
+ return await selectProviderOption(provider);
1087
+ }
1088
+ }
1089
+
1090
+ if (!authSuccess) {
1043
1091
  return await selectProviderOption(provider);
1044
1092
  }
1045
1093
 
@@ -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,