diff --git a/packages/atxp/src/help.ts b/packages/atxp/src/help.ts index 47ac0dd..3f20902 100644 --- a/packages/atxp/src/help.ts +++ b/packages/atxp/src/help.ts @@ -33,6 +33,7 @@ export function showHelp(): void { console.log(); console.log(chalk.bold('Login Options:')); + console.log(' ' + chalk.yellow('--token, -t') + ' ' + 'Provide token directly (headless mode)'); console.log(' ' + chalk.yellow('--force') + ' ' + 'Update connection string even if already set'); console.log(); @@ -52,7 +53,8 @@ export function showHelp(): void { console.log(); console.log(chalk.bold('Examples:')); - console.log(' npx atxp login # Log in to ATXP'); + console.log(' npx atxp login # Log in to ATXP (browser)'); + console.log(' npx atxp login --token $TOKEN # Log in with token (headless)'); console.log(' npx atxp search "latest AI news" # Search the web'); console.log(' npx atxp image "sunset over mountains" # Generate an image'); console.log(' npx atxp music "relaxing piano" # Generate music'); diff --git a/packages/atxp/src/index.ts b/packages/atxp/src/index.ts index 1e039eb..e0cd0ac 100644 --- a/packages/atxp/src/index.ts +++ b/packages/atxp/src/index.ts @@ -28,6 +28,7 @@ interface CreateOptions { interface LoginOptions { force: boolean; + token?: string; } // Parse command line arguments @@ -76,6 +77,7 @@ function parseArgs(): { const verbose = process.argv.includes('--verbose') || process.argv.includes('-v'); const refresh = process.argv.includes('--refresh'); const force = process.argv.includes('--force'); + const token = getArgValue('--token', '-t'); // Parse create options const framework = getArgValue('--framework', '-f') as Framework | undefined; @@ -110,7 +112,7 @@ function parseArgs(): { subCommand, demoOptions: { port, dir, verbose, refresh }, createOptions: { framework, appName, git }, - loginOptions: { force }, + loginOptions: { force, token }, toolArgs, }; } diff --git a/packages/atxp/src/login.ts b/packages/atxp/src/login.ts index 0515c23..84c785c 100644 --- a/packages/atxp/src/login.ts +++ b/packages/atxp/src/login.ts @@ -7,6 +7,7 @@ import open from 'open'; interface LoginOptions { force?: boolean; + token?: string; } const CONFIG_DIR = path.join(os.homedir(), '.atxp'); @@ -16,7 +17,7 @@ export async function login(options: LoginOptions = {}): Promise { // Check if already logged in const existingConnection = process.env.ATXP_CONNECTION; - if (existingConnection && !options.force) { + if (existingConnection && !options.force && !options.token) { console.log(chalk.yellow('Already logged in (ATXP_CONNECTION is set).')); console.log('Run with --force to update your connection string.'); return; @@ -26,7 +27,17 @@ export async function login(options: LoginOptions = {}): Promise { console.log(); try { - const connectionString = await loginWithBrowser(); + let connectionString: string; + + // If token provided directly, use it (headless mode) + if (options.token) { + connectionString = options.token; + console.log('Using provided token for headless authentication...'); + } else { + // Otherwise, use browser-based login + connectionString = await loginWithBrowser(); + } + saveConnectionString(connectionString); console.log();