From e16714d70c88c2fe519aa57ce99728000fb39c7b Mon Sep 17 00:00:00 2001 From: Mathew Goldsborough Date: Sat, 4 Oct 2025 21:55:06 -1000 Subject: [PATCH 1/3] 0.3.0 --- package-lock.json | 4 ++-- package.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7a67eb5..6843de0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@nimbletools/ntcli", - "version": "0.2.0", + "version": "0.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@nimbletools/ntcli", - "version": "0.2.0", + "version": "0.3.0", "license": "Apache-2.0", "dependencies": { "@types/inquirer": "^9.0.8", diff --git a/package.json b/package.json index 89a17bc..f572781 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@nimbletools/ntcli", - "version": "0.2.0", + "version": "0.3.0", "description": "Command-line interface for NimbleTools MCP Platform - deploy, manage, and integrate MCP servers", "keywords": [ "mcp", @@ -89,4 +89,4 @@ "access": "public", "registry": "https://registry.npmjs.org/" } -} \ No newline at end of file +} From 71828afb0a6f303fa36c623d1677be4a84f74949 Mon Sep 17 00:00:00 2001 From: Mathew Goldsborough Date: Sat, 4 Oct 2025 21:56:17 -1000 Subject: [PATCH 2/3] 0.4.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6843de0..f2942ae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@nimbletools/ntcli", - "version": "0.3.0", + "version": "0.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@nimbletools/ntcli", - "version": "0.3.0", + "version": "0.4.0", "license": "Apache-2.0", "dependencies": { "@types/inquirer": "^9.0.8", diff --git a/package.json b/package.json index f572781..9c562f4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@nimbletools/ntcli", - "version": "0.3.0", + "version": "0.4.0", "description": "Command-line interface for NimbleTools MCP Platform - deploy, manage, and integrate MCP servers", "keywords": [ "mcp", From 66fbe38260326b35de713fdb905ad60a21e16961 Mon Sep 17 00:00:00 2001 From: Mathew Goldsborough Date: Wed, 8 Oct 2025 14:31:26 -1000 Subject: [PATCH 3/3] updatnig CLI for prod clerk values --- src/commands/auth/login.ts | 6 +++--- src/index.ts | 10 +++++++--- src/lib/auth/clerk-oauth-client.ts | 11 ----------- src/lib/auth/token-exchange.ts | 24 ++++++++++++++++++++++-- src/lib/config-manager.ts | 21 +++++++++++++++------ src/lib/config.ts | 2 +- 6 files changed, 48 insertions(+), 26 deletions(-) diff --git a/src/commands/auth/login.ts b/src/commands/auth/login.ts index 70e5909..23eda00 100644 --- a/src/commands/auth/login.ts +++ b/src/commands/auth/login.ts @@ -1,11 +1,11 @@ import chalk from 'chalk'; -import ora from 'ora'; import open from 'open'; +import ora from 'ora'; import { v4 as uuidv4 } from 'uuid'; import { ClerkOAuthClient } from '../../lib/auth/clerk-oauth-client.js'; -import { TokenManager } from '../../lib/auth/token-manager.js'; import { LocalCallbackServer } from '../../lib/auth/local-server.js'; import { TokenExchangeClient } from '../../lib/auth/token-exchange.js'; +import { TokenManager } from '../../lib/auth/token-manager.js'; import { Config } from '../../lib/config.js'; import { AuthCommandOptions } from '../../types/index.js'; @@ -91,7 +91,7 @@ export async function handleLogin(options: AuthCommandOptions = {}): Promise process.stderr.write(chalk.red(str)), - }); + }) + .addHelpText('afterAll', `\nNeed more help? Visit ${chalk.cyan('https://www.nimblebrain.ai/discord')}`); // Info command program @@ -1062,7 +1063,7 @@ async function main() { // Parse command line arguments try { - // Check for global flags before parsing + // Check for global flags before parsing if (process.argv.includes("--debug")) { process.env.NTCLI_DEBUG = "1"; } @@ -1070,7 +1071,10 @@ async function main() { await program.parseAsync(process.argv); } catch (error) { if (error instanceof Error) { - console.error(chalk.red(`Error: ${error.message}`)); + // Don't show error for help/version outputs + if (error.message !== '(outputHelp)' && error.message !== '(outputVersion)') { + console.error(chalk.red(`Error: ${error.message}`)); + } } else { console.error(chalk.red("An unexpected error occurred")); } diff --git a/src/lib/auth/clerk-oauth-client.ts b/src/lib/auth/clerk-oauth-client.ts index 4933249..c713c74 100644 --- a/src/lib/auth/clerk-oauth-client.ts +++ b/src/lib/auth/clerk-oauth-client.ts @@ -8,12 +8,6 @@ import { UserInfo, } from "../../types/index.js"; -// Get Clerk domain from environment or use default -const DEFAULT_CLERK_OAUTH_DOMAIN = process.env.CLERK_OAUTH_DOMAIN || "clerk.nimbletools.ai"; - -// Get Clerk OAuth audience from environment -const CLERK_OAUTH_AUDIENCE = process.env.CLERK_OAUTH_AUDIENCE; - /** * Clerk OAuth client implementing OAuth 2.0 with PKCE flow */ @@ -61,11 +55,6 @@ export class ClerkOAuthClient { code_challenge_method: pkceChallenge.codeChallengeMethod, }); - // Add audience if configured - if (CLERK_OAUTH_AUDIENCE) { - params.append("audience", CLERK_OAUTH_AUDIENCE); - } - // Use domain from environment variable if available, otherwise use config domain const domain = process.env.CLERK_OAUTH_DOMAIN || this.config.domain; return `https://${domain}/oauth/authorize?${params.toString()}`; diff --git a/src/lib/auth/token-exchange.ts b/src/lib/auth/token-exchange.ts index 1fbad56..bed3bf5 100644 --- a/src/lib/auth/token-exchange.ts +++ b/src/lib/auth/token-exchange.ts @@ -1,3 +1,4 @@ +import { ConfigManager } from '../config-manager.js'; /** * Token exchange response from the API @@ -14,8 +15,13 @@ export class TokenExchangeClient { private baseUrl: string; constructor(baseUrl?: string) { - // Use environment variable or default to production URL - this.baseUrl = baseUrl || process.env.NIMBLEBRAIN_API_URL || 'https://studio-api.nimblebrain.ai'; + if (baseUrl) { + this.baseUrl = baseUrl; + } else { + // Use ConfigManager to get the Studio API URL + const configManager = new ConfigManager(); + this.baseUrl = configManager.getStudioApiUrl(); + } } /** @@ -24,6 +30,12 @@ export class TokenExchangeClient { async exchangeToken(idToken: string): Promise { const url = `${this.baseUrl}/api/v1/auth/token-exchange`; + if (process.env.NTCLI_DEBUG) { + console.log('\n[DEBUG] Token Exchange Request:'); + console.log(' URL:', url); + console.log(' ID Token (first 50 chars):', idToken.substring(0, 50) + '...'); + } + try { const response = await fetch(url, { method: 'POST', @@ -35,6 +47,10 @@ export class TokenExchangeClient { }), }); + if (process.env.NTCLI_DEBUG) { + console.log('[DEBUG] Response Status:', response.status); + } + if (!response.ok) { let errorMessage = ''; try { @@ -44,6 +60,10 @@ export class TokenExchangeClient { errorMessage = await response.text(); } + if (process.env.NTCLI_DEBUG) { + console.log('[DEBUG] Error Response:', errorMessage); + } + // Include status code in error message for better handling if (response.status === 403) { throw new Error(`403: ${errorMessage || 'Access forbidden'}`); diff --git a/src/lib/config-manager.ts b/src/lib/config-manager.ts index 40c7c02..e511edc 100644 --- a/src/lib/config-manager.ts +++ b/src/lib/config-manager.ts @@ -195,6 +195,7 @@ export class ConfigManager { /** * Get the Clerk authentication domain + * Note: This is independent of the main domain and always defaults to nimblebrain.ai */ getClerkDomain(): string { // Use environment variable if set @@ -202,14 +203,22 @@ export class ConfigManager { return process.env.CLERK_OAUTH_DOMAIN; } - // Fall back to deriving from main domain - const domain = this.getDomain(); + // Always use nimblebrain.ai for production Clerk, not derived from main domain + return 'clerk.nimblebrain.ai'; + } - // For localhost, return as-is - if (domain.includes('localhost') || domain.includes('127.0.0.1')) { - return domain; + /** + * Get the Studio API URL (for token exchange) + * Note: This is independent of the main domain and always defaults to nimblebrain.ai + */ + getStudioApiUrl(): string { + // Use environment variable if set + if (process.env.NIMBLEBRAIN_API_URL) { + return process.env.NIMBLEBRAIN_API_URL; } - return `clerk.${domain}`; + + // Always use nimblebrain.ai for Studio API, not derived from main domain + return 'https://studio-api.nimblebrain.ai'; } // Authentication methods diff --git a/src/lib/config.ts b/src/lib/config.ts index 7be2738..665a2c6 100644 --- a/src/lib/config.ts +++ b/src/lib/config.ts @@ -20,7 +20,7 @@ export class Config { * Get Clerk OAuth configuration */ getClerkConfig(): ClerkOAuthConfig { - const clientId = process.env.CLERK_OAUTH_CLIENT_ID || "0MUyvaWYSj4g0lzE"; + const clientId = process.env.CLERK_OAUTH_CLIENT_ID || "96WRYcxabFktp9wn"; // Get domain from unified config const configManager = new ConfigManager();