Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 1.4k
feat(cli-v3): add --no-browser flag and examples to init/login --help#3483
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "trigger.dev": patch | ||
| --- | ||
| Add `--no-browser` flag to `init` and `login` to skip auto-opening the browser during authentication. Also error loudly when `init` is run without `--yes` under non-TTY stdin (previously default-and-exited silently, leaving the project half-initialized). Both commands now show an `Examples` section in `--help`. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -57,6 +57,7 @@ const InitCommandOptions = CommonCommandOptions.extend({ | ||
| gitRef: z.string().default("main"), | ||
| javascript: z.boolean().default(false), | ||
| yes: z.boolean().default(false), | ||
| browser: z.boolean().default(true), | ||
| }); | ||
| type InitCommandOptions = z.infer<typeof InitCommandOptions>; | ||
| @@ -65,7 +66,23 @@ export function configureInitCommand(program: Command) { | ||
| return commonOptions( | ||
| program | ||
| .command("init") | ||
| .description("Initialize your existing project for development with Trigger.dev") | ||
| .summary("Initialize your existing project for development with Trigger.dev") | ||
| .description( | ||
| `Initialize your existing project for development with Trigger.dev. | ||
| Examples: | ||
| # Interactive setup | ||
| $ trigger.dev init | ||
| # Non-interactive (CI / scripts) | ||
| $ trigger.dev init --yes --project-ref proj_abc123 | ||
| # Headless / agent (no browser) | ||
| $ trigger.dev init --yes --project-ref proj_abc123 --no-browser | ||
| # Use a named profile | ||
| $ trigger.dev init --profile staging` | ||
| ) | ||
| .argument("[path]", "The path to the project", ".") | ||
| .option( | ||
| "-p, --project-ref <project ref>", | ||
| @@ -89,6 +106,7 @@ export function configureInitCommand(program: Command) { | ||
| "Additional arguments to pass to the package manager, accepts CSV for multiple args" | ||
| ) | ||
| .option("-y, --yes", "Skip all prompts and use defaults (requires --project-ref)") | ||
| .option("--no-browser", "Don't automatically open the browser during login; print the URL only") | ||
| ) | ||
| .addOption( | ||
| new CommandOption( | ||
| @@ -118,9 +136,21 @@ async function _initCommand(dir: string, options: InitCommandOptions) { | ||
| throw new Error("--project-ref is required when using --yes flag"); | ||
| } | ||
| // Refuse to run interactively when stdin isn't a TTY (CI, agent harness, etc). | ||
| // Previously this silently default-and-exited at the first prompt, leaving the | ||
| // project half-initialized. | ||
| if (!options.yes && !process.stdin.isTTY) { | ||
| throw new Error( | ||
| "Interactive prompts cannot be used in non-TTY environments. Pass --yes (and --project-ref) to run non-interactively." | ||
| ); | ||
| } | ||
nicktrn marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| const hasSeenMCPInstallPrompt = readConfigHasSeenMCPInstallPrompt(); | ||
| if (!hasSeenMCPInstallPrompt) { | ||
| // Skip the MCP-vs-CLI prompt when --yes is set: the user explicitly chose CLI | ||
| // by running `trigger.dev init` non-interactively, and the prompt would | ||
| // otherwise hang on a fresh machine where `hasSeenMCPInstallPrompt` is false. | ||
| if (!hasSeenMCPInstallPrompt && !options.yes) { | ||
| const installChoice = await select({ | ||
| message: "Choose how you want to initialize your project:", | ||
| options: [ | ||
| @@ -165,6 +195,7 @@ async function _initCommand(dir: string, options: InitCommandOptions) { | ||
| embedded: true, | ||
| defaultApiUrl: options.apiUrl, | ||
| profile: options.profile, | ||
| browser: options.browser, | ||
| }); | ||
| if (!authorization.ok) { | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -41,6 +41,7 @@ import { links } from "@trigger.dev/core/v3"; | ||
| export const LoginCommandOptions = CommonCommandOptions.extend({ | ||
| apiUrl: z.string(), | ||
| browser: z.boolean().default(true), | ||
| }); | ||
| export type LoginCommandOptions = z.infer<typeof LoginCommandOptions>; | ||
| @@ -49,7 +50,21 @@ export function configureLoginCommand(program: Command) { | ||
| return commonOptions( | ||
| program | ||
| .command("login") | ||
| .description("Login with Trigger.dev so you can perform authenticated actions") | ||
| .summary("Login with Trigger.dev so you can perform authenticated actions") | ||
| .description( | ||
| `Login with Trigger.dev so you can perform authenticated actions. | ||
| Examples: | ||
| # Interactive login (opens browser) | ||
| $ trigger.dev login | ||
| # Headless / agent (print URL only) | ||
| $ trigger.dev login --no-browser | ||
nicktrn marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| # Login to a named profile | ||
| $ trigger.dev login --profile staging` | ||
| ) | ||
| .option("--no-browser", "Don't automatically open the browser; print the URL only") | ||
| ) | ||
| .version(VERSION, "-v, --version", "Display the version number") | ||
| .action(async (options) => { | ||
| @@ -67,14 +82,20 @@ export async function loginCommand(options: unknown) { | ||
| } | ||
| async function _loginCommand(options: LoginCommandOptions) { | ||
| return login({ defaultApiUrl: options.apiUrl, embedded: false, profile: options.profile }); | ||
| return login({ | ||
| defaultApiUrl: options.apiUrl, | ||
| embedded: false, | ||
| profile: options.profile, | ||
| browser: options.browser, | ||
| }); | ||
| } | ||
| export type LoginOptions = { | ||
| defaultApiUrl?: string; | ||
| embedded?: boolean; | ||
| profile?: string; | ||
| silent?: boolean; | ||
| browser?: boolean; | ||
| }; | ||
| export async function login(options?: LoginOptions): Promise<LoginResult> { | ||
| @@ -259,7 +280,9 @@ export async function login(options?: LoginOptions): Promise<LoginResult> { | ||
| `Please visit the following URL to login:\n${chalkLink(authorizationCodeResult.url)}` | ||
| ); | ||
| if (await isLinuxServer()) { | ||
| if (opts.browser === false) { | ||
| log.message("Browser auto-open disabled. Visit the URL above to login."); | ||
| } else if (await isLinuxServer()) { | ||
| log.message("Please install `xdg-utils` to automatically open the login URL."); | ||
| } else { | ||
| await open(authorizationCodeResult.url); | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.