@juspay/neurolink
Version:
Universal AI Development Platform with working MCP integration, multi-provider support, voice (TTS/STT/realtime), and professional CLI. 58+ external MCP servers discoverable, multimodal file processing, RAG pipelines. Build, test, and deploy AI applicatio
385 lines • 16.9 kB
JavaScript
/**
* Auth Command Factory for NeuroLink
*
* Creates the unified authentication command with subcommands for AI providers.
* Subcommands:
* - login, logout, status, refresh: Anthropic OAuth (API key + OAuth)
* - providers, validate, health: Multi-provider auth management
*/
/**
* Supported providers for authentication
*/
const SUPPORTED_PROVIDERS = ["anthropic"];
/**
* Auth Command Factory
*
* Creates the main auth command with subcommands:
* - login: Authenticate with a provider (Anthropic OAuth)
* - logout: Clear stored credentials
* - status: Show authentication status
* - refresh: Manually refresh OAuth tokens
* - providers: List available auth providers
* - validate: Validate a token against a provider
* - health: Check auth provider health
*/
export class AuthCommandFactory {
/**
* Create the main auth command with subcommands
*/
static createAuthCommands() {
return {
command: "auth <subcommand>",
describe: "Manage authentication with AI providers (API key or OAuth)",
builder: (yargs) => {
return yargs
.command("login <provider>", "Authenticate with an AI provider", (yargs) => this.buildLoginOptions(yargs), async (argv) => {
const { handleLogin } = await import("../commands/auth.js");
await handleLogin(argv);
})
.command("logout <provider>", "Clear stored credentials for a provider", (yargs) => this.buildLogoutOptions(yargs), async (argv) => {
const { handleLogout } = await import("../commands/auth.js");
await handleLogout(argv);
})
.command("status [provider]", "Show authentication status for provider(s)", (yargs) => this.buildStatusOptions(yargs), async (argv) => {
const { handleStatus } = await import("../commands/auth.js");
await handleStatus(argv);
})
.command("refresh <provider>", "Manually refresh OAuth tokens for a provider", (yargs) => this.buildRefreshOptions(yargs), async (argv) => {
const { handleRefresh } = await import("../commands/auth.js");
await handleRefresh(argv);
})
.command("list", "List all authenticated accounts", (yargs) => this.buildListOptions(yargs), async (argv) => {
const { handleList } = await import("../commands/auth.js");
await handleList(argv);
})
.command("remove <provider>", "Remove an authenticated account", (yargs) => this.buildRemoveOptions(yargs), async (argv) => {
const { handleRemove } = await import("../commands/auth.js");
await handleRemove(argv);
})
.command("cleanup", "Remove expired and disabled accounts from token store", (yargs) => this.buildCleanupOptions(yargs), async (argv) => {
const { handleCleanup } = await import("../commands/auth.js");
await handleCleanup(argv);
})
.command("enable <account>", "Re-enable a previously disabled account", (yargs) => this.buildEnableOptions(yargs), async (argv) => {
const { handleEnable } = await import("../commands/auth.js");
await handleEnable(argv);
})
.command("set-primary <email>", "Set the proxy's primary (home) Anthropic account", (yargs) => this.buildSetPrimaryOptions(yargs), async (argv) => {
const { handleSetPrimary } = await import("../commands/auth.js");
await handleSetPrimary(argv);
})
.command("get-primary", "Show the proxy's currently configured primary account", (yargs) => this.buildPrimaryConfigOption(yargs), async (argv) => {
const { handleGetPrimary } = await import("../commands/auth.js");
await handleGetPrimary(argv);
})
.command("clear-primary", "Clear the proxy's configured primary account", (yargs) => this.buildPrimaryConfigOption(yargs), async (argv) => {
const { handleClearPrimary } = await import("../commands/auth.js");
await handleClearPrimary(argv);
})
.command("providers", "List available authentication providers", (yargs) => yargs.option("format", {
type: "string",
choices: ["text", "json", "table"],
default: "text",
description: "Output format",
alias: "f",
}), async (argv) => {
const { handleProvidersCommand } = await import("../commands/authProviders.js");
await handleProvidersCommand(argv);
})
.command("validate <token>", "Validate an authentication token", (yargs) => this.buildValidateOptions(yargs), async (argv) => {
const { handleValidateCommand } = await import("../commands/authProviders.js");
await handleValidateCommand(argv);
})
.command("health", "Check authentication provider health", (yargs) => this.buildHealthOptions(yargs), async (argv) => {
const { handleHealthCommand } = await import("../commands/authProviders.js");
await handleHealthCommand(argv);
})
.option("format", {
choices: ["text", "json"],
default: "text",
description: "Output format",
})
.option("quiet", {
type: "boolean",
alias: "q",
default: false,
description: "Suppress non-essential output",
})
.option("debug", {
type: "boolean",
default: false,
description: "Enable debug output",
})
.demandCommand(1, "Please specify an auth subcommand")
.example("$0 auth login anthropic", "Authenticate with Anthropic")
.example("$0 auth login anthropic --method create-api-key", "Create API key via OAuth (Claude Pro/Max - Recommended)")
.example("$0 auth login anthropic --add --label alice", "Add additional account with label")
.example("$0 auth list", "List all authenticated accounts")
.example("$0 auth status", "Show authentication status for all providers")
.example("$0 auth logout anthropic", "Clear Anthropic stored credentials")
.example("$0 auth remove anthropic --label alice", "Remove a specific account")
.example("$0 auth refresh anthropic", "Refresh Anthropic OAuth tokens")
.example("$0 auth cleanup", "Remove expired and disabled accounts")
.example("$0 auth cleanup --force", "Remove stale accounts without confirmation")
.example("$0 auth enable anthropic:1-VjRIq", "Re-enable a disabled account")
.example("$0 auth set-primary alice@example.com", "Make alice@example.com the proxy's primary (home) account")
.example("$0 auth get-primary", "Show the proxy's currently configured primary account")
.example("$0 auth clear-primary", "Remove the configured primary account (use insertion-order fallback)")
.help();
},
handler: () => {
// No-op handler as subcommands handle everything
},
};
}
/**
* Build options for login subcommand
*/
static buildLoginOptions(yargs) {
return yargs
.positional("provider", {
type: "string",
description: "AI provider to authenticate with",
choices: SUPPORTED_PROVIDERS,
demandOption: true,
})
.option("method", {
type: "string",
alias: "m",
description: "Authentication method",
choices: ["api-key", "oauth", "create-api-key"],
})
.option("non-interactive", {
type: "boolean",
description: "Skip interactive prompts (requires environment variables)",
default: false,
})
.option("add", {
type: "boolean",
default: false,
description: "Add as additional account to the pool (instead of replacing)",
})
.option("label", {
type: "string",
description: "Human-readable label for this account (used with --add)",
})
.example("$0 auth login anthropic", "Interactive authentication (choose method)")
.example("$0 auth login anthropic --method api-key", "API key authentication")
.example("$0 auth login anthropic --method create-api-key", "Create API key via OAuth (Claude Pro/Max)")
.example("$0 auth login anthropic --method oauth", "Direct OAuth (experimental)")
.example("$0 auth login anthropic --add --label alice", "Add as additional account with label");
}
/**
* Build options for logout subcommand
*/
static buildLogoutOptions(yargs) {
return yargs
.positional("provider", {
type: "string",
description: "AI provider to log out from",
choices: SUPPORTED_PROVIDERS,
demandOption: true,
})
.example("$0 auth logout anthropic", "Clear all Anthropic credentials");
}
/**
* Build options for status subcommand
*/
static buildStatusOptions(yargs) {
return yargs
.positional("provider", {
type: "string",
description: "AI provider to check (optional, shows all if not specified)",
choices: SUPPORTED_PROVIDERS,
})
.example("$0 auth status", "Show status for all configured providers")
.example("$0 auth status anthropic", "Show Anthropic authentication status")
.example("$0 auth status --format json", "Show status in JSON format");
}
/**
* Build options for refresh subcommand
*/
static buildRefreshOptions(yargs) {
return yargs
.positional("provider", {
type: "string",
description: "AI provider to refresh tokens for",
choices: SUPPORTED_PROVIDERS,
demandOption: true,
})
.example("$0 auth refresh anthropic", "Refresh Anthropic OAuth tokens");
}
/**
* Build options for list subcommand
*/
static buildListOptions(yargs) {
return yargs
.example("$0 auth list", "List all authenticated accounts")
.example("$0 auth list --format json", "List accounts in JSON format");
}
/**
* Build options for remove subcommand
*/
static buildRemoveOptions(yargs) {
return yargs
.positional("provider", {
type: "string",
description: "AI provider to remove account from",
choices: SUPPORTED_PROVIDERS,
demandOption: true,
})
.option("label", {
type: "string",
description: "Label of the account to remove (e.g., alice)",
})
.option("account", {
type: "string",
description: "Full compound key of the account to remove (e.g., anthropic:alice)",
})
.conflicts("label", "account")
.check((argv) => {
if (argv.account &&
!String(argv.account).startsWith(`${String(argv.provider)}:`)) {
throw new Error("--account must belong to the selected provider");
}
return true;
})
.example("$0 auth remove anthropic --label alice", "Remove account with label alice")
.example("$0 auth remove anthropic --account anthropic:alice", "Remove account by compound key");
}
/**
* Build options for cleanup subcommand
*/
static buildCleanupOptions(yargs) {
return yargs
.option("force", {
type: "boolean",
default: false,
description: "Skip confirmation when removing disabled accounts",
})
.example("$0 auth cleanup", "Remove expired and disabled accounts")
.example("$0 auth cleanup --force", "Remove stale accounts without confirmation");
}
/**
* Build options for enable subcommand
*/
static buildEnableOptions(yargs) {
return yargs
.positional("account", {
type: "string",
description: "Account key to re-enable (e.g., anthropic:1-VjRIq)",
demandOption: true,
})
.example("$0 auth enable anthropic:1-VjRIq", "Re-enable a disabled account");
}
/**
* Build options for set-primary subcommand
*/
static buildSetPrimaryOptions(yargs) {
return yargs
.positional("email", {
type: "string",
description: "Email/label of the Anthropic account to make primary (home)",
demandOption: true,
})
.option("config", {
type: "string",
description: "Path to the proxy config YAML (default: ~/.neurolink/proxy-config.yaml)",
})
.example("$0 auth set-primary alice@example.com", "Write routing.primary-account to the default proxy config")
.example("$0 auth set-primary alice@example.com --config ./proxy.yaml", "Use a non-default config path");
}
/**
* Build options for get-primary / clear-primary subcommands.
*/
static buildPrimaryConfigOption(yargs) {
return yargs.option("config", {
type: "string",
description: "Path to the proxy config YAML (default: ~/.neurolink/proxy-config.yaml)",
});
}
/**
* Auth provider choices for multi-provider commands
*/
static AUTH_PROVIDER_CHOICES = [
"auth0",
"clerk",
"supabase",
"firebase",
"workos",
"better-auth",
"jwt",
"oauth2",
"cognito",
"keycloak",
];
/**
* Build common provider options for validate/health commands
*/
static buildProviderOptions(yargs) {
return yargs
.option("provider", {
type: "string",
choices: this.AUTH_PROVIDER_CHOICES,
default: "auth0",
description: "Authentication provider type",
alias: "p",
})
.option("domain", {
type: "string",
description: "Auth0 domain (for auth0 provider)",
})
.option("clientId", {
type: "string",
description: "Client ID (for auth0 provider)",
alias: "client-id",
})
.option("secretKey", {
type: "string",
description: "Secret key (for clerk provider)",
alias: "secret-key",
})
.option("url", {
type: "string",
description: "Provider URL (for supabase, better-auth)",
})
.option("anonKey", {
type: "string",
description: "Anon key (for supabase provider)",
alias: "anon-key",
})
.option("apiKey", {
type: "string",
description: "API key (for workos provider)",
alias: "api-key",
})
.option("secret", {
type: "string",
description: "Secret (for better-auth, jwt providers). Can also be set via BETTER_AUTH_SECRET or JWT_SECRET env vars.",
})
.option("format", {
type: "string",
choices: ["text", "json"],
default: "text",
description: "Output format",
alias: "f",
});
}
/**
* Build options for validate subcommand
*/
static buildValidateOptions(yargs) {
return this.buildProviderOptions(yargs.positional("token", {
type: "string",
description: "The token to validate (JWT or session token)",
demandOption: true,
}));
}
/**
* Build options for health subcommand
*/
static buildHealthOptions(yargs) {
return this.buildProviderOptions(yargs);
}
}
//# sourceMappingURL=authCommandFactory.js.map