Vercel Logo

Scaffold the repo-review CLI

A reusable function is great. Nobody's typing pnpm tsx src/sandbox-lifecycle.ts https://github.com/... every day, though.

We need a command-line surface. Something a person can run from a terminal, something a CI job can call, something with a name. We'll use commander because it handles the boring parts (parsing args, generating help text, exit behavior) and we'd rather not.

Outcome

Create src/cli.ts with a review <repoUrl> command using commander. The command parses its argument and prints what it received. No Sandbox work yet.

Fast Track

  1. Add commander to the project.
  2. Create src/cli.ts and import Command.
  3. Register a review <repoUrl> command whose action logs the URL.

Hands-on exercise

commander is already in the starter's package.json, so no install needed. If you were spinning this up from scratch, you'd run:

pnpm add commander

Create src/cli.ts:

import { Command } from 'commander';
 
const program = new Command();
 
program
  .name('repo-review')
  .description('Clone and review a GitHub repository in a Sandbox')
  .version('0.1.0');
 
program
  .command('review <repoUrl>')
  .description('Run a Sandbox review against a GitHub repository URL')
  .action(async (repoUrl: string) => {
    console.log(`Would review: ${repoUrl}`);
  });
 
program.parse();

That's the whole skeleton. The action callback is where the Sandbox lifecycle will live in lesson 2.3, but right now we're just confirming the plumbing works. If you run it with a URL and see the URL echoed back, the CLI surface is in place.

Add a script to your package.json so we don't have to type the long form every time:

package.json
{
  "scripts": {
    "review": "tsx src/cli.ts review"
  }
}

Now pnpm review <url> runs your CLI.

Troubleshooting: command not found

If pnpm review reports "command not found", check that the script is in your package.json and that tsx is installed (pnpm add -D tsx if not). The commander part of "command not found" is misleading; the error usually comes from missing scripts, not missing commander.

Troubleshooting: help text empty

program.parse() reads from process.argv. If you run pnpm review with no args, commander prints "missing required argument 'repoUrl'", not your description. That's expected behavior, not a bug.

Try It

pnpm review https://github.com/vercel/examples

Expected output:

Would review: https://github.com/vercel/examples

And without an argument, you should see commander's built-in error:

pnpm review
error: missing required argument 'repoUrl'

Both behaviors are good. The first proves the action runs; the second proves commander is enforcing the argument shape for us.

Commit

git add src/cli.ts package.json
git commit -m "feat(cli): scaffold review command with commander"

Done-When

  • commander is installed
  • src/cli.ts registers a review <repoUrl> command
  • pnpm review <url> echoes the URL back
  • pnpm review (no args) shows commander's missing-argument error

Solution

src/cli.ts
import { Command } from 'commander';
 
const program = new Command();
 
program
  .name('repo-review')
  .description('Clone and review a GitHub repository in a Sandbox')
  .version('0.1.0');
 
program
  .command('review <repoUrl>')
  .description('Run a Sandbox review against a GitHub repository URL')
  .action(async (repoUrl: string) => {
    console.log(`Would review: ${repoUrl}`);
  });
 
program.parse();
package.json (scripts section)
{
  "scripts": {
    "review": "tsx src/cli.ts review"
  }
}

Was this helpful?

supported.