hedgequantx 1.2.143 → 1.2.144
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 +1 -1
- package/src/app.js +111 -77
package/package.json
CHANGED
package/src/app.js
CHANGED
|
@@ -46,6 +46,27 @@ const restoreTerminal = () => {
|
|
|
46
46
|
}
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Ensure stdin is ready for inquirer prompts
|
|
51
|
+
* This fixes input leaking to bash after session restore
|
|
52
|
+
*/
|
|
53
|
+
const prepareStdin = () => {
|
|
54
|
+
try {
|
|
55
|
+
// Remove any raw mode that might be left from previous operations
|
|
56
|
+
if (process.stdin.isTTY && process.stdin.isRaw) {
|
|
57
|
+
process.stdin.setRawMode(false);
|
|
58
|
+
}
|
|
59
|
+
// Remove any lingering keypress listeners
|
|
60
|
+
process.stdin.removeAllListeners('keypress');
|
|
61
|
+
process.stdin.removeAllListeners('data');
|
|
62
|
+
// Pause stdin so inquirer can take control
|
|
63
|
+
process.stdin.pause();
|
|
64
|
+
// Small delay to let event loop settle
|
|
65
|
+
} catch (e) {
|
|
66
|
+
// Ignore errors
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
49
70
|
// Register global handlers to restore terminal on exit/crash
|
|
50
71
|
process.on('exit', restoreTerminal);
|
|
51
72
|
process.on('SIGINT', () => { restoreTerminal(); process.exit(0); });
|
|
@@ -802,89 +823,102 @@ const handleUpdate = async () => {
|
|
|
802
823
|
* Main application loop
|
|
803
824
|
*/
|
|
804
825
|
const run = async () => {
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
// Try to restore session
|
|
808
|
-
const spinner = ora('Restoring session...').start();
|
|
809
|
-
const restored = await connections.restoreFromStorage();
|
|
810
|
-
|
|
811
|
-
if (restored) {
|
|
812
|
-
spinner.succeed('Session restored');
|
|
813
|
-
currentService = connections.getAll()[0].service;
|
|
814
|
-
} else {
|
|
815
|
-
spinner.info('No active session');
|
|
816
|
-
}
|
|
817
|
-
|
|
818
|
-
// Main loop
|
|
819
|
-
while (true) {
|
|
820
|
-
// Refresh banner with stats
|
|
826
|
+
try {
|
|
821
827
|
await banner();
|
|
822
828
|
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
if (choice === 'projectx') {
|
|
832
|
-
const service = await projectXMenu();
|
|
833
|
-
if (service) currentService = service;
|
|
834
|
-
}
|
|
835
|
-
|
|
836
|
-
if (choice === 'rithmic') {
|
|
837
|
-
const service = await rithmicMenu();
|
|
838
|
-
if (service) currentService = service;
|
|
839
|
-
}
|
|
840
|
-
|
|
841
|
-
if (choice === 'tradovate') {
|
|
842
|
-
const service = await tradovateMenu();
|
|
843
|
-
if (service) currentService = service;
|
|
844
|
-
}
|
|
829
|
+
// Try to restore session
|
|
830
|
+
const spinner = ora('Restoring session...').start();
|
|
831
|
+
const restored = await connections.restoreFromStorage();
|
|
832
|
+
|
|
833
|
+
if (restored) {
|
|
834
|
+
spinner.succeed('Session restored');
|
|
835
|
+
currentService = connections.getAll()[0].service;
|
|
845
836
|
} else {
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
837
|
+
spinner.info('No active session');
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
// Main loop
|
|
841
|
+
while (true) {
|
|
842
|
+
try {
|
|
843
|
+
// Ensure stdin is ready for prompts (fixes input leaking to bash)
|
|
844
|
+
prepareStdin();
|
|
845
|
+
|
|
846
|
+
// Refresh banner with stats
|
|
847
|
+
await banner();
|
|
848
|
+
|
|
849
|
+
if (!connections.isConnected()) {
|
|
850
|
+
const choice = await mainMenu();
|
|
851
|
+
|
|
852
|
+
if (choice === 'exit') {
|
|
853
|
+
console.log(chalk.gray('Goodbye!'));
|
|
854
|
+
process.exit(0);
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
if (choice === 'projectx') {
|
|
858
|
+
const service = await projectXMenu();
|
|
859
|
+
if (service) currentService = service;
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
if (choice === 'rithmic') {
|
|
863
|
+
const service = await rithmicMenu();
|
|
864
|
+
if (service) currentService = service;
|
|
868
865
|
}
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
866
|
+
|
|
867
|
+
if (choice === 'tradovate') {
|
|
868
|
+
const service = await tradovateMenu();
|
|
869
|
+
if (service) currentService = service;
|
|
870
|
+
}
|
|
871
|
+
} else {
|
|
872
|
+
const action = await dashboardMenu(currentService);
|
|
873
|
+
|
|
874
|
+
switch (action) {
|
|
875
|
+
case 'accounts':
|
|
876
|
+
await showAccounts(currentService);
|
|
877
|
+
break;
|
|
878
|
+
|
|
879
|
+
case 'stats':
|
|
880
|
+
await showStats(currentService);
|
|
881
|
+
break;
|
|
882
|
+
case 'add_prop_account':
|
|
883
|
+
// Show platform selection menu
|
|
884
|
+
const platformChoice = await addPropAccountMenu();
|
|
885
|
+
if (platformChoice === 'projectx') {
|
|
886
|
+
const newService = await projectXMenu();
|
|
887
|
+
if (newService) currentService = newService;
|
|
888
|
+
} else if (platformChoice === 'rithmic') {
|
|
889
|
+
const newService = await rithmicMenu();
|
|
890
|
+
if (newService) currentService = newService;
|
|
891
|
+
} else if (platformChoice === 'tradovate') {
|
|
892
|
+
const newService = await tradovateMenu();
|
|
893
|
+
if (newService) currentService = newService;
|
|
894
|
+
}
|
|
895
|
+
break;
|
|
896
|
+
case 'algotrading':
|
|
897
|
+
await algoTradingMenu(currentService);
|
|
898
|
+
break;
|
|
899
|
+
case 'update':
|
|
900
|
+
const updateResult = await handleUpdate();
|
|
901
|
+
if (updateResult === 'restart') return; // Stop loop, new process spawned
|
|
902
|
+
break;
|
|
903
|
+
case 'disconnect':
|
|
904
|
+
const connCount = connections.count();
|
|
905
|
+
connections.disconnectAll();
|
|
906
|
+
currentService = null;
|
|
907
|
+
console.log(chalk.yellow(`Disconnected ${connCount} connection${connCount > 1 ? 's' : ''}`));
|
|
908
|
+
break;
|
|
909
|
+
case 'exit':
|
|
910
|
+
console.log(chalk.gray('Goodbye!'));
|
|
911
|
+
process.exit(0);
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
} catch (loopError) {
|
|
915
|
+
console.error(chalk.red('Error in main loop:'), loopError.message);
|
|
916
|
+
// Continue the loop
|
|
886
917
|
}
|
|
887
918
|
}
|
|
919
|
+
} catch (error) {
|
|
920
|
+
console.error(chalk.red('Fatal error:'), error.message);
|
|
921
|
+
process.exit(1);
|
|
888
922
|
}
|
|
889
923
|
};
|
|
890
924
|
|