Repository: MotiaDev/motia
File: packages/snap/src/cli.ts (TypeScript)

Code before:
  .description('Create a new motia project')
  .argument('[folder]', 'The name for your project (optional)')
  .option('-t, --template <template>', 'The template to use for your project')
  .option('-i, --interactive', 'Use interactive prompts to create project') // it's default
  .option('-c, --confirm', 'Confirm the project creation', false)
  .action(
    handler(async (arg, context) => {
      const { createInteractive } = require('./create/interactive')
      const inquirer = require('inquirer')
      let folder = arg.folder
      if (!folder) {
        const { projectName } = await inquirer.prompt([
          {
            type: 'input',
            name: 'projectName',
            message: 'Enter project folder name:',
            default: 'my-motia-app',
          },
        ])
        folder = projectName
      }
      await createInteractive(
        {
          name: folder,
          template: (context as any).template,
          confirm: !!(context as any).confirm,
        },
        context,
      )
    }),
  )

program
  .command('rules')
  .command('pull')
  .description('Install essential AI development guides (AGENTS.md, CLAUDE.md) and optional Cursor IDE rules')
  .option('-f, --force', 'Overwrite existing files')
  .action(
    handler(async (arg, context) => {
      const { pullRules } = require('./create/pull-rules')
      await pullRules({ force: arg.force, rootDir: process.cwd() }, context)
    }),
  )

program
  .command('generate-types')
  .description('Generate types.d.ts file for your project')
  .action(async () => {
    const { generateTypes } = require('./generate-types')
    await generateTypes(process.cwd())
    process.exit(0)

Review comment (suggestion):
Context doesn't have it as well, you need to change the `handler` function which is being passed to `.action()`. Refer to my previous comment for how commander handles `arguments` and `options`

Please try running `pnpm motia create my-project --template nodejs`

This shouldn't prompt you for the template again since you have already mentioned it

You can check the Discord in the `#contributors` channel i have been discussing the approach

Code after:
  .description('Create a new motia project')
  .option('-t, --template <template>', 'The template to use for your project')
  .option('-i, --interactive', 'Use interactive prompts to create project') // it's default
  .option('-c, --confirm', 'Confirm the project creation', false)
  .action((projectName, options) => {
    const mergedArgs = { ...options, name: projectName };
    return handler(async (arg, context) => {
      const { createInteractive } = require('./create/interactive');
      await createInteractive(
        {
          name: arg.name,
          template: arg.template,
          confirm: !!arg.confirm,
        },
        context
      );
    })(mergedArgs);
  });

program
  .command('rules')
  .command('pull')
  .description('Install essential AI development guides (AGENTS.md, CLAUDE.md) and optional Cursor IDE rules')
  .option('-f, --force', 'Overwrite existing files')
  .action(
    handler(async (arg, context) => {
      const { pullRules } = require('./create/pull-rules')
      await pullRules({ force: arg.force, rootDir: process.cwd() }, context)
    }),
  )

program
  .command('generate-types')
  .description('Generate types.d.ts file for your project')
  .action(async () => {
    const { generateTypes } = require('./generate-types')
    await generateTypes(process.cwd())
    process.exit(0)
  })

program
  .command('install')
  .description('Sets up Python virtual environment and install dependencies')
  .option('-v, --verbose', 'Enable verbose logging')
  .action(async (options) => {
    const { install } = require('./install')
    await install({ isVerbose: options.verbose })
  })

program
  .command('dev')