hedgequantx 2.5.9 → 2.5.11

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.5.9",
3
+ "version": "2.5.11",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -121,7 +121,7 @@ const showExistingTokens = async () => {
121
121
  // Show found tokens
122
122
  console.clear();
123
123
  displayBanner();
124
- drawBoxHeader('EXISTING SESSIONS FOUND', boxWidth);
124
+ drawBoxHeaderContinue('EXISTING SESSIONS FOUND', boxWidth);
125
125
 
126
126
  console.log(makeLine(chalk.green(`FOUND ${tokens.length} EXISTING SESSION(S)`)));
127
127
  console.log(makeLine(''));
@@ -174,9 +174,17 @@ const showExistingTokens = async () => {
174
174
  const spinner = ora({ text: 'VALIDATING TOKEN...', color: 'cyan' }).start();
175
175
 
176
176
  try {
177
- // Validate the token
178
- const credentials = { apiKey: selectedToken.token };
179
- const validation = await aiService.validateConnection(selectedToken.provider, 'api_key', credentials);
177
+ // Validate the token - include metadata from scanner
178
+ const credentials = {
179
+ apiKey: selectedToken.token,
180
+ sessionKey: selectedToken.token,
181
+ accessToken: selectedToken.token,
182
+ fromKeychain: selectedToken.sourceId === 'secureStorage' || selectedToken.sourceId === 'keychain',
183
+ subscriptionType: selectedToken.subscriptionType,
184
+ refreshToken: selectedToken.refreshToken,
185
+ expiresAt: selectedToken.expiresAt
186
+ };
187
+ const validation = await aiService.validateConnection(selectedToken.provider, selectedToken.type, credentials);
180
188
 
181
189
  if (!validation.valid) {
182
190
  spinner.fail(`TOKEN INVALID OR EXPIRED: ${validation.error}`);
@@ -236,7 +244,7 @@ const selectCategory = async () => {
236
244
 
237
245
  console.clear();
238
246
  displayBanner();
239
- drawBoxHeader('SELECT PROVIDER TYPE', boxWidth);
247
+ drawBoxHeaderContinue('SELECT PROVIDER TYPE', boxWidth);
240
248
 
241
249
  const categories = getCategories();
242
250
 
@@ -305,7 +313,7 @@ const selectProvider = async (categoryId) => {
305
313
 
306
314
  const categories = getCategories();
307
315
  const category = categories.find(c => c.id === categoryId);
308
- drawBoxHeader(category.name, boxWidth);
316
+ drawBoxHeaderContinue(category.name, boxWidth);
309
317
 
310
318
  const providers = getProvidersByCategory(categoryId);
311
319
 
@@ -391,7 +399,7 @@ const selectProviderOption = async (provider) => {
391
399
 
392
400
  console.clear();
393
401
  displayBanner();
394
- drawBoxHeader(provider.name, boxWidth);
402
+ drawBoxHeaderContinue(provider.name, boxWidth);
395
403
 
396
404
  console.log(makeLine(chalk.white('SELECT CONNECTION METHOD:')));
397
405
  console.log(makeLine(''));
@@ -539,7 +547,7 @@ const setupConnection = async (provider, option) => {
539
547
  // Show instructions for this field
540
548
  console.clear();
541
549
  displayBanner();
542
- drawBoxHeader(`CONNECT TO ${provider.name}`, boxWidth);
550
+ drawBoxHeaderContinue(`CONNECT TO ${provider.name}`, boxWidth);
543
551
 
544
552
  const instructions = getCredentialInstructions(provider, option, field);
545
553
 
@@ -656,7 +664,7 @@ const selectModel = async (provider) => {
656
664
 
657
665
  console.clear();
658
666
  displayBanner();
659
- drawBoxHeader('SELECT MODEL', boxWidth);
667
+ drawBoxHeaderContinue('SELECT MODEL', boxWidth);
660
668
 
661
669
  const models = provider.models || [];
662
670
 
@@ -150,11 +150,54 @@ const validateConnection = async (providerId, optionId, credentials) => {
150
150
  // Validation functions for each provider
151
151
  const validateAnthropic = async (credentials) => {
152
152
  try {
153
+ const token = credentials.apiKey || credentials.sessionKey || credentials.accessToken;
154
+
155
+ // Check if it's an OAuth token (sk-ant-oat...) vs API key (sk-ant-api...)
156
+ const isOAuthToken = token && token.startsWith('sk-ant-oat');
157
+
158
+ if (isOAuthToken) {
159
+ // OAuth tokens use Bearer auth and claude.ai endpoint
160
+ const response = await fetch('https://api.claude.ai/api/organizations', {
161
+ method: 'GET',
162
+ headers: {
163
+ 'Authorization': `Bearer ${token}`,
164
+ 'Content-Type': 'application/json',
165
+ 'User-Agent': 'HQX-CLI/1.0'
166
+ }
167
+ });
168
+
169
+ if (response.ok) {
170
+ return { valid: true, tokenType: 'oauth', subscriptionType: credentials.subscriptionType || 'max' };
171
+ }
172
+
173
+ // Try alternate endpoint
174
+ const altResponse = await fetch('https://claude.ai/api/auth/session', {
175
+ method: 'GET',
176
+ headers: {
177
+ 'Authorization': `Bearer ${token}`,
178
+ 'Cookie': `sessionKey=${token}`
179
+ }
180
+ });
181
+
182
+ if (altResponse.ok) {
183
+ return { valid: true, tokenType: 'oauth', subscriptionType: credentials.subscriptionType || 'max' };
184
+ }
185
+
186
+ // For OAuth tokens from Keychain, trust them without validation
187
+ // since the Keychain already verified the user
188
+ if (credentials.fromKeychain) {
189
+ return { valid: true, tokenType: 'oauth', subscriptionType: credentials.subscriptionType || 'max', trusted: true };
190
+ }
191
+
192
+ return { valid: false, error: 'OAuth token expired or invalid' };
193
+ }
194
+
195
+ // Standard API key validation
153
196
  const response = await fetch('https://api.anthropic.com/v1/messages', {
154
197
  method: 'POST',
155
198
  headers: {
156
199
  'Content-Type': 'application/json',
157
- 'x-api-key': credentials.apiKey || credentials.sessionKey,
200
+ 'x-api-key': token,
158
201
  'anthropic-version': '2023-06-01'
159
202
  },
160
203
  body: JSON.stringify({
@@ -165,7 +208,7 @@ const validateAnthropic = async (credentials) => {
165
208
  });
166
209
 
167
210
  if (response.ok) {
168
- return { valid: true };
211
+ return { valid: true, tokenType: 'api_key' };
169
212
  }
170
213
 
171
214
  const error = await response.json();