hedgequantx 1.2.147 → 1.3.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.
- package/README.md +115 -71
- package/package.json +1 -1
- package/src/app.js +1 -22
- package/src/menus/connect.js +2 -1
- package/src/menus/dashboard.js +135 -31
- package/src/services/index.js +1 -1
- package/src/services/projectx/index.js +345 -0
- package/src/services/projectx/market.js +145 -0
- package/src/services/projectx/stats.js +110 -0
- package/src/services/rithmic/accounts.js +183 -0
- package/src/services/rithmic/handlers.js +191 -0
- package/src/services/rithmic/index.js +69 -673
- package/src/services/rithmic/orders.js +192 -0
- package/src/ui/index.js +23 -1
- package/src/services/projectx.js +0 -771
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
**Prop Futures Algo Trading CLI**
|
|
13
13
|
|
|
14
|
-
A powerful command-line interface for connecting to prop trading firms and managing your futures trading accounts.
|
|
14
|
+
A powerful command-line interface for connecting to prop trading firms and managing your futures trading accounts with automated algo trading capabilities.
|
|
15
15
|
|
|
16
16
|
[](https://www.npmjs.com/package/hedgequantx)
|
|
17
17
|
[](https://www.npmjs.com/package/hedgequantx)
|
|
@@ -20,12 +20,14 @@ A powerful command-line interface for connecting to prop trading firms and manag
|
|
|
20
20
|
|
|
21
21
|
## Features
|
|
22
22
|
|
|
23
|
-
- Multi-platform support
|
|
24
|
-
- 37 supported prop firms
|
|
25
|
-
- Multi-account connections
|
|
26
|
-
- Real-time stats
|
|
27
|
-
-
|
|
28
|
-
-
|
|
23
|
+
- **Multi-platform support** - ProjectX, Rithmic, Tradovate
|
|
24
|
+
- **37+ supported prop firms**
|
|
25
|
+
- **Multi-account connections** - Connect multiple accounts simultaneously
|
|
26
|
+
- **Real-time stats** - Balance, P&L, positions, orders
|
|
27
|
+
- **Algo Trading** - One Account & Copy Trading modes
|
|
28
|
+
- **HQX Server** - Cloud-based execution engine
|
|
29
|
+
- **Secure sessions** - AES-256-GCM encrypted storage
|
|
30
|
+
- **Auto-update** - Built-in update with restart
|
|
29
31
|
|
|
30
32
|
---
|
|
31
33
|
|
|
@@ -63,11 +65,33 @@ hedgequantx version
|
|
|
63
65
|
|
|
64
66
|
---
|
|
65
67
|
|
|
66
|
-
##
|
|
68
|
+
## Algo Trading Modes
|
|
69
|
+
|
|
70
|
+
### One Account Mode
|
|
71
|
+
Trade on a single account with automated signals and risk management.
|
|
72
|
+
|
|
73
|
+
- Symbol selection (ES, NQ, MNQ, etc.)
|
|
74
|
+
- Configurable contracts quantity
|
|
75
|
+
- Daily target and max risk limits
|
|
76
|
+
- Real-time P&L tracking
|
|
77
|
+
- Activity log with trade history
|
|
78
|
+
|
|
79
|
+
### Copy Trading Mode
|
|
80
|
+
Mirror trades from a Lead account to Follower accounts.
|
|
81
|
+
|
|
82
|
+
- Lead -> Follower trade copying
|
|
83
|
+
- Different symbols per account
|
|
84
|
+
- Configurable contract ratios
|
|
85
|
+
- Privacy mode (hide account names)
|
|
86
|
+
- Low-latency execution via HQX Server
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Supported Prop Firms (37+)
|
|
67
91
|
|
|
68
92
|
| ProjectX (19) | Rithmic (16) | Tradovate (2) |
|
|
69
93
|
|---------------|--------------|---------------|
|
|
70
|
-
| TopStep | Apex | Apex |
|
|
94
|
+
| TopStep | Apex Trader Funding | Apex |
|
|
71
95
|
| Alpha Futures | TopstepTrader | TakeProfitTrader |
|
|
72
96
|
| TickTickTrader | MES Capital | |
|
|
73
97
|
| Bulenox | Bulenox | |
|
|
@@ -87,51 +111,46 @@ hedgequantx version
|
|
|
87
111
|
| Lucid Trading | | |
|
|
88
112
|
| Tradeify | | |
|
|
89
113
|
|
|
90
|
-
> **Note:** ProjectX firms are fully supported. Rithmic and Tradovate coming soon.
|
|
91
|
-
|
|
92
114
|
---
|
|
93
115
|
|
|
94
116
|
## Dashboard Features
|
|
95
117
|
|
|
96
118
|
- **View Accounts** - List all trading accounts with balance and status
|
|
97
|
-
- **View Positions** - Open positions with P&L
|
|
98
|
-
- **View Orders** - Pending and filled orders
|
|
99
119
|
- **View Stats** - Trading metrics, equity curve, P&L calendar
|
|
100
|
-
- **User Info** - Account details
|
|
101
120
|
- **Add Prop-Account** - Connect multiple prop firms
|
|
102
|
-
- **Algo-Trading** -
|
|
103
|
-
- **Update HQX** - Auto-update with restart
|
|
121
|
+
- **Algo-Trading** - One Account & Copy Trading modes
|
|
122
|
+
- **Update HQX** - Auto-update with confirmation and restart
|
|
104
123
|
|
|
105
124
|
---
|
|
106
125
|
|
|
107
126
|
## Screenshots
|
|
108
127
|
|
|
128
|
+
### Main Dashboard
|
|
109
129
|
```
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
║
|
|
119
|
-
|
|
120
|
-
║ Connections:
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
Disconnect
|
|
130
|
+
╔════════════════════════════════════════════════════════════════════════════════════════════════╗
|
|
131
|
+
║ ██╗ ██╗███████╗██████╗ ██████╗ ███████╗ ██████╗ ██╗ ██╗ █████╗ ███╗ ██╗████████╗██╗ ██╗ ║
|
|
132
|
+
║ ██║ ██║██╔════╝██╔══██╗██╔════╝ ██╔════╝██╔═══██╗██║ ██║██╔══██╗████╗ ██║╚══██╔══╝╚██╗██╔╝ ║
|
|
133
|
+
║ ███████║█████╗ ██║ ██║██║ ███╗█████╗ ██║ ██║██║ ██║███████║██╔██╗ ██║ ██║ ╚███╔╝ ║
|
|
134
|
+
║ ██╔══██║██╔══╝ ██║ ██║██║ ██║██╔══╝ ██║▄▄ ██║██║ ██║██╔══██║██║╚██╗██║ ██║ ██╔██╗ ║
|
|
135
|
+
║ ██║ ██║███████╗██████╔╝╚██████╔╝███████╗╚██████╔╝╚██████╔╝██║ ██║██║ ╚████║ ██║ ██╔╝ ██╗ ║
|
|
136
|
+
║ ╚═╝ ╚═╝╚══════╝╚═════╝ ╚═════╝ ╚══════╝ ╚══▀▀═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝ ║
|
|
137
|
+
╠════════════════════════════════════════════════════════════════════════════════════════════════╣
|
|
138
|
+
║ Prop Futures Algo Trading v1.3.0 ║
|
|
139
|
+
╠════════════════════════════════════════════════════════════════════════════════════════════════╣
|
|
140
|
+
║ Connections: 2 Accounts: 3 Balance: $601,526 P&L: +$1,526 (+0.3%) ║
|
|
141
|
+
╚════════════════════════════════════════════════════════════════════════════════════════════════╝
|
|
142
|
+
|
|
143
|
+
╔════════════════════════════════════════════════════════════════════════════════════════════════╗
|
|
144
|
+
║ Welcome, HQX Trader! ║
|
|
145
|
+
╠════════════════════════════════════════════════════════════════════════════════════════════════╣
|
|
146
|
+
║ ┌────────────────────────────────────────────┐ ┌────────────────────────────────────────────┐ ║
|
|
147
|
+
║ │ TopStep │ │ Apex Trader Funding │ ║
|
|
148
|
+
║ └────────────────────────────────────────────┘ └────────────────────────────────────────────┘ ║
|
|
149
|
+
╠════════════════════════════════════════════════════════════════════════════════════════════════╣
|
|
150
|
+
║ [1] View Accounts [2] View Stats ║
|
|
151
|
+
║ [+] Add Prop-Account [A] Algo-Trading ║
|
|
152
|
+
║ [U] Update HQX [X] Disconnect ║
|
|
153
|
+
╚════════════════════════════════════════════════════════════════════════════════════════════════╝
|
|
135
154
|
```
|
|
136
155
|
|
|
137
156
|
---
|
|
@@ -141,27 +160,32 @@ hedgequantx version
|
|
|
141
160
|
```
|
|
142
161
|
HQX-CLI/
|
|
143
162
|
├── bin/
|
|
144
|
-
│ └── cli.js
|
|
163
|
+
│ └── cli.js # Entry point
|
|
145
164
|
├── src/
|
|
146
|
-
│ ├── app.js
|
|
165
|
+
│ ├── app.js # Main router (380 lines)
|
|
147
166
|
│ ├── config/
|
|
148
|
-
│ │ ├──
|
|
149
|
-
│ │
|
|
150
|
-
│
|
|
167
|
+
│ │ ├── constants.js # Futures symbols
|
|
168
|
+
│ │ └── propfirms.js # 37+ PropFirms config
|
|
169
|
+
│ ├── menus/
|
|
170
|
+
│ │ ├── connect.js # Connection menus
|
|
171
|
+
│ │ └── dashboard.js # Dashboard & update
|
|
151
172
|
│ ├── pages/
|
|
173
|
+
│ │ ├── algo/
|
|
174
|
+
│ │ │ ├── ui.js # Algo trading UI
|
|
175
|
+
│ │ │ ├── one-account.js # One Account mode
|
|
176
|
+
│ │ │ └── copy-trading.js # Copy Trading mode
|
|
152
177
|
│ │ ├── accounts.js
|
|
153
|
-
│ │
|
|
154
|
-
│ │ ├── positions.js
|
|
155
|
-
│ │ ├── stats.js
|
|
156
|
-
│ │ └── user.js
|
|
178
|
+
│ │ └── stats.js
|
|
157
179
|
│ ├── security/
|
|
158
|
-
│ │ ├── encryption.js
|
|
159
|
-
│ │ ├── validation.js
|
|
160
|
-
│ │ └── rateLimit.js
|
|
180
|
+
│ │ ├── encryption.js # AES-256-GCM
|
|
181
|
+
│ │ ├── validation.js # Input sanitization
|
|
182
|
+
│ │ └── rateLimit.js # API rate limiting
|
|
161
183
|
│ ├── services/
|
|
162
|
-
│ │ ├── projectx
|
|
163
|
-
│ │ ├──
|
|
164
|
-
│ │
|
|
184
|
+
│ │ ├── projectx/ # ProjectX API
|
|
185
|
+
│ │ ├── rithmic/ # Rithmic API
|
|
186
|
+
│ │ ├── tradovate/ # Tradovate API
|
|
187
|
+
│ │ ├── hqx-server.js # HQX Server API
|
|
188
|
+
│ │ └── session.js # Encrypted sessions
|
|
165
189
|
│ └── ui/
|
|
166
190
|
│ ├── box.js
|
|
167
191
|
│ ├── table.js
|
|
@@ -179,6 +203,7 @@ HQX-CLI/
|
|
|
179
203
|
- Input validation and sanitization
|
|
180
204
|
- API rate limiting
|
|
181
205
|
- Secure file permissions (0600)
|
|
206
|
+
- No credentials stored in plain text
|
|
182
207
|
|
|
183
208
|
---
|
|
184
209
|
|
|
@@ -186,34 +211,53 @@ HQX-CLI/
|
|
|
186
211
|
|
|
187
212
|
The CLI has a built-in update feature:
|
|
188
213
|
|
|
189
|
-
1. Select **Update HQX** from the dashboard
|
|
190
|
-
2. CLI
|
|
191
|
-
3.
|
|
192
|
-
4.
|
|
214
|
+
1. Select **[U] Update HQX** from the dashboard
|
|
215
|
+
2. CLI checks npm registry for latest version
|
|
216
|
+
3. Prompts for confirmation before updating
|
|
217
|
+
4. Installs new version globally
|
|
218
|
+
5. Auto-restarts with new version
|
|
193
219
|
|
|
194
220
|
Or manually:
|
|
195
221
|
|
|
196
222
|
```bash
|
|
197
|
-
|
|
223
|
+
npm install -g hedgequantx@latest
|
|
198
224
|
```
|
|
199
225
|
|
|
200
226
|
---
|
|
201
227
|
|
|
228
|
+
## Changelog
|
|
229
|
+
|
|
230
|
+
### v1.3.0
|
|
231
|
+
- Major refactoring for maintainability
|
|
232
|
+
- Robust update function with confirmation
|
|
233
|
+
- Fixed stdin leak in menus
|
|
234
|
+
- Split services into modules
|
|
235
|
+
- Algo UI: logs now show newest at bottom
|
|
236
|
+
|
|
237
|
+
### v1.2.x
|
|
238
|
+
- Algo Trading: One Account & Copy Trading modes
|
|
239
|
+
- HQX Server integration
|
|
240
|
+
- Rithmic full support
|
|
241
|
+
- Multi-account dashboard
|
|
242
|
+
- Privacy mode for account names
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
202
246
|
## Roadmap
|
|
203
247
|
|
|
204
248
|
- [x] ProjectX integration
|
|
205
|
-
- [x]
|
|
206
|
-
- [x]
|
|
207
|
-
- [x]
|
|
208
|
-
- [x] Order viewing
|
|
249
|
+
- [x] Rithmic integration
|
|
250
|
+
- [x] Multi-propfirm support (37+ firms)
|
|
251
|
+
- [x] Multi-account connections
|
|
209
252
|
- [x] Stats with equity curve
|
|
210
253
|
- [x] Encrypted sessions
|
|
211
|
-
- [x]
|
|
212
|
-
- [
|
|
213
|
-
- [
|
|
214
|
-
- [ ]
|
|
215
|
-
- [ ] Real-time market data
|
|
216
|
-
- [ ]
|
|
254
|
+
- [x] Algo Trading - One Account mode
|
|
255
|
+
- [x] Algo Trading - Copy Trading mode
|
|
256
|
+
- [x] HQX Server integration
|
|
257
|
+
- [ ] Tradovate full integration
|
|
258
|
+
- [ ] Real-time market data streaming
|
|
259
|
+
- [ ] Advanced order types
|
|
260
|
+
- [ ] Mobile companion app
|
|
217
261
|
|
|
218
262
|
---
|
|
219
263
|
|
package/package.json
CHANGED
package/src/app.js
CHANGED
|
@@ -8,7 +8,7 @@ const inquirer = require('inquirer');
|
|
|
8
8
|
const ora = require('ora');
|
|
9
9
|
|
|
10
10
|
const { connections } = require('./services');
|
|
11
|
-
const { getLogoWidth, centerText } = require('./ui');
|
|
11
|
+
const { getLogoWidth, centerText, prepareStdin } = require('./ui');
|
|
12
12
|
|
|
13
13
|
// Pages
|
|
14
14
|
const { showStats } = require('./pages/stats');
|
|
@@ -42,27 +42,6 @@ const restoreTerminal = () => {
|
|
|
42
42
|
}
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
-
/**
|
|
46
|
-
* Ensure stdin is ready for inquirer prompts
|
|
47
|
-
* This fixes input leaking to bash after session restore
|
|
48
|
-
*/
|
|
49
|
-
const prepareStdin = () => {
|
|
50
|
-
try {
|
|
51
|
-
// Remove any raw mode that might be left from previous operations
|
|
52
|
-
if (process.stdin.isTTY && process.stdin.isRaw) {
|
|
53
|
-
process.stdin.setRawMode(false);
|
|
54
|
-
}
|
|
55
|
-
// Remove any lingering keypress listeners
|
|
56
|
-
process.stdin.removeAllListeners('keypress');
|
|
57
|
-
process.stdin.removeAllListeners('data');
|
|
58
|
-
// Pause stdin so inquirer can take control
|
|
59
|
-
process.stdin.pause();
|
|
60
|
-
// Small delay to let event loop settle
|
|
61
|
-
} catch (e) {
|
|
62
|
-
// Ignore errors
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
|
|
66
45
|
// Register global handlers to restore terminal on exit/crash
|
|
67
46
|
process.on('exit', restoreTerminal);
|
|
68
47
|
process.on('SIGINT', () => { restoreTerminal(); process.exit(0); });
|
package/src/menus/connect.js
CHANGED
|
@@ -11,7 +11,7 @@ const { ProjectXService, connections } = require('../services');
|
|
|
11
11
|
const { RithmicService } = require('../services/rithmic');
|
|
12
12
|
const { TradovateService } = require('../services/tradovate');
|
|
13
13
|
const { getPropFirmsByPlatform } = require('../config');
|
|
14
|
-
const { getDevice, getLogoWidth, centerText } = require('../ui');
|
|
14
|
+
const { getDevice, getLogoWidth, centerText, prepareStdin } = require('../ui');
|
|
15
15
|
const { validateUsername, validatePassword } = require('../security');
|
|
16
16
|
|
|
17
17
|
/**
|
|
@@ -20,6 +20,7 @@ const { validateUsername, validatePassword } = require('../security');
|
|
|
20
20
|
* @returns {Promise<{username: string, password: string}>}
|
|
21
21
|
*/
|
|
22
22
|
const loginPrompt = async (propfirmName) => {
|
|
23
|
+
prepareStdin();
|
|
23
24
|
const device = getDevice();
|
|
24
25
|
console.log();
|
|
25
26
|
console.log(chalk.cyan(`Connecting to ${propfirmName}...`));
|
package/src/menus/dashboard.js
CHANGED
|
@@ -9,13 +9,16 @@ const ora = require('ora');
|
|
|
9
9
|
const { execSync, spawn } = require('child_process');
|
|
10
10
|
|
|
11
11
|
const { connections } = require('../services');
|
|
12
|
-
const { getLogoWidth, centerText } = require('../ui');
|
|
12
|
+
const { getLogoWidth, centerText, prepareStdin } = require('../ui');
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Dashboard menu after login
|
|
16
16
|
* @param {Object} service - Connected service
|
|
17
17
|
*/
|
|
18
18
|
const dashboardMenu = async (service) => {
|
|
19
|
+
// Ensure stdin is ready for prompts
|
|
20
|
+
prepareStdin();
|
|
21
|
+
|
|
19
22
|
const user = service.user;
|
|
20
23
|
const boxWidth = getLogoWidth();
|
|
21
24
|
const W = boxWidth - 2; // Same width as logo (inner width)
|
|
@@ -139,72 +142,173 @@ const dashboardMenu = async (service) => {
|
|
|
139
142
|
return actionMap[action] || 'accounts';
|
|
140
143
|
};
|
|
141
144
|
|
|
145
|
+
/**
|
|
146
|
+
* Wait for user to press Enter
|
|
147
|
+
*/
|
|
148
|
+
const waitForEnter = async () => {
|
|
149
|
+
prepareStdin();
|
|
150
|
+
try {
|
|
151
|
+
await inquirer.prompt([{ type: 'input', name: 'c', message: 'Press Enter to continue...' }]);
|
|
152
|
+
} catch (e) {
|
|
153
|
+
// Ignore prompt errors
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
|
|
142
157
|
/**
|
|
143
158
|
* Handles the update process with auto-restart
|
|
159
|
+
* Robust version that handles all edge cases
|
|
144
160
|
*/
|
|
145
161
|
const handleUpdate = async () => {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
162
|
+
prepareStdin();
|
|
163
|
+
|
|
164
|
+
let spinner = null;
|
|
165
|
+
let currentVersion = 'unknown';
|
|
166
|
+
let latestVersion = null;
|
|
149
167
|
|
|
150
168
|
try {
|
|
151
|
-
//
|
|
169
|
+
// Get current version safely
|
|
170
|
+
try {
|
|
171
|
+
const pkg = require('../../package.json');
|
|
172
|
+
currentVersion = pkg.version || 'unknown';
|
|
173
|
+
} catch (e) {
|
|
174
|
+
currentVersion = 'unknown';
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
spinner = ora('Checking for updates...').start();
|
|
178
|
+
|
|
179
|
+
// Check latest version on npm with timeout
|
|
152
180
|
spinner.text = 'Checking npm registry...';
|
|
153
|
-
let latestVersion;
|
|
154
181
|
try {
|
|
155
|
-
|
|
182
|
+
const result = execSync('npm view hedgequantx version 2>/dev/null', {
|
|
183
|
+
stdio: 'pipe',
|
|
184
|
+
timeout: 15000, // 15 second timeout
|
|
185
|
+
encoding: 'utf8'
|
|
186
|
+
});
|
|
187
|
+
latestVersion = (result || '').toString().trim();
|
|
188
|
+
|
|
189
|
+
// Validate version format (x.y.z)
|
|
190
|
+
if (!latestVersion || !/^\d+\.\d+\.\d+/.test(latestVersion)) {
|
|
191
|
+
throw new Error('Invalid version format received');
|
|
192
|
+
}
|
|
156
193
|
} catch (e) {
|
|
157
194
|
spinner.fail('Cannot reach npm registry');
|
|
195
|
+
console.log(chalk.gray(' Check your internet connection'));
|
|
158
196
|
console.log();
|
|
159
|
-
await
|
|
197
|
+
await waitForEnter();
|
|
160
198
|
return;
|
|
161
199
|
}
|
|
162
200
|
|
|
201
|
+
// Compare versions
|
|
163
202
|
if (currentVersion === latestVersion) {
|
|
164
203
|
spinner.succeed('Already up to date!');
|
|
165
204
|
console.log();
|
|
166
|
-
console.log(chalk.green(`
|
|
205
|
+
console.log(chalk.green(` You have the latest version: v${currentVersion}`));
|
|
206
|
+
console.log();
|
|
207
|
+
await waitForEnter();
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Ask user before updating
|
|
212
|
+
spinner.stop();
|
|
213
|
+
console.log();
|
|
214
|
+
console.log(chalk.cyan(` Current version: v${currentVersion}`));
|
|
215
|
+
console.log(chalk.green(` Latest version: v${latestVersion}`));
|
|
216
|
+
console.log();
|
|
217
|
+
|
|
218
|
+
prepareStdin();
|
|
219
|
+
const { confirm } = await inquirer.prompt([{
|
|
220
|
+
type: 'confirm',
|
|
221
|
+
name: 'confirm',
|
|
222
|
+
message: 'Do you want to update now?',
|
|
223
|
+
default: true
|
|
224
|
+
}]);
|
|
225
|
+
|
|
226
|
+
if (!confirm) {
|
|
227
|
+
console.log(chalk.gray(' Update cancelled'));
|
|
167
228
|
console.log();
|
|
168
|
-
await
|
|
229
|
+
await waitForEnter();
|
|
169
230
|
return;
|
|
170
231
|
}
|
|
171
232
|
|
|
172
233
|
// Update via npm
|
|
173
|
-
spinner
|
|
234
|
+
spinner = ora(`Updating v${currentVersion} -> v${latestVersion}...`).start();
|
|
235
|
+
|
|
174
236
|
try {
|
|
175
|
-
execSync('npm install -g hedgequantx@latest', {
|
|
237
|
+
execSync('npm install -g hedgequantx@latest 2>/dev/null', {
|
|
238
|
+
stdio: 'pipe',
|
|
239
|
+
timeout: 120000, // 2 minute timeout for install
|
|
240
|
+
encoding: 'utf8'
|
|
241
|
+
});
|
|
176
242
|
} catch (e) {
|
|
177
|
-
spinner.fail('Update failed
|
|
178
|
-
console.log(chalk.gray(` Error: ${e.message}`));
|
|
243
|
+
spinner.fail('Update failed');
|
|
179
244
|
console.log();
|
|
180
|
-
|
|
245
|
+
console.log(chalk.yellow(' Try manually:'));
|
|
246
|
+
console.log(chalk.white(' npm install -g hedgequantx@latest'));
|
|
247
|
+
console.log();
|
|
248
|
+
if (e.message) {
|
|
249
|
+
console.log(chalk.gray(` Error: ${e.message.substring(0, 100)}`));
|
|
250
|
+
console.log();
|
|
251
|
+
}
|
|
252
|
+
await waitForEnter();
|
|
181
253
|
return;
|
|
182
254
|
}
|
|
183
255
|
|
|
184
|
-
spinner.succeed('
|
|
185
|
-
console.log();
|
|
186
|
-
console.log(chalk.green(` ✓ Updated: v${currentVersion} -> v${latestVersion}`));
|
|
256
|
+
spinner.succeed('Update complete!');
|
|
187
257
|
console.log();
|
|
188
|
-
console.log(chalk.
|
|
258
|
+
console.log(chalk.green(` Updated: v${currentVersion} -> v${latestVersion}`));
|
|
189
259
|
console.log();
|
|
190
260
|
|
|
191
|
-
//
|
|
192
|
-
|
|
261
|
+
// Ask if user wants to restart
|
|
262
|
+
prepareStdin();
|
|
263
|
+
const { restart } = await inquirer.prompt([{
|
|
264
|
+
type: 'confirm',
|
|
265
|
+
name: 'restart',
|
|
266
|
+
message: 'Restart HQX now?',
|
|
267
|
+
default: true
|
|
268
|
+
}]);
|
|
193
269
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
270
|
+
if (restart) {
|
|
271
|
+
console.log();
|
|
272
|
+
console.log(chalk.cyan(' Restarting HedgeQuantX CLI...'));
|
|
273
|
+
console.log();
|
|
274
|
+
|
|
275
|
+
// Small delay so user can see the message
|
|
276
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
277
|
+
|
|
278
|
+
// Restart the CLI
|
|
279
|
+
try {
|
|
280
|
+
const child = spawn('hedgequantx', [], {
|
|
281
|
+
stdio: 'inherit',
|
|
282
|
+
detached: true,
|
|
283
|
+
shell: true
|
|
284
|
+
});
|
|
285
|
+
child.unref();
|
|
286
|
+
process.exit(0);
|
|
287
|
+
} catch (e) {
|
|
288
|
+
console.log(chalk.yellow(' Could not auto-restart. Please run: hedgequantx'));
|
|
289
|
+
console.log();
|
|
290
|
+
await waitForEnter();
|
|
291
|
+
}
|
|
292
|
+
} else {
|
|
293
|
+
console.log(chalk.gray(' Run "hedgequantx" to use the new version'));
|
|
294
|
+
console.log();
|
|
295
|
+
await waitForEnter();
|
|
296
|
+
}
|
|
202
297
|
|
|
203
298
|
} catch (error) {
|
|
204
|
-
|
|
299
|
+
// Catch-all for any unexpected errors
|
|
300
|
+
if (spinner) {
|
|
301
|
+
try { spinner.fail('Update error'); } catch (e) {}
|
|
302
|
+
}
|
|
303
|
+
console.log();
|
|
304
|
+
console.log(chalk.red(' An error occurred during update'));
|
|
305
|
+
if (error && error.message) {
|
|
306
|
+
console.log(chalk.gray(` ${error.message.substring(0, 100)}`));
|
|
307
|
+
}
|
|
308
|
+
console.log();
|
|
205
309
|
console.log(chalk.yellow(' Try manually: npm install -g hedgequantx@latest'));
|
|
206
310
|
console.log();
|
|
207
|
-
await
|
|
311
|
+
await waitForEnter();
|
|
208
312
|
}
|
|
209
313
|
};
|
|
210
314
|
|