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
- Add
commanderto the project. - Create
src/cli.tsand importCommand. - 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 commanderCreate 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:
{
"scripts": {
"review": "tsx src/cli.ts review"
}
}Now pnpm review <url> runs your CLI.
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.
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/examplesExpected output:
Would review: https://github.com/vercel/examplesAnd without an argument, you should see commander's built-in error:
pnpm reviewerror: 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
commanderis installedsrc/cli.tsregisters areview <repoUrl>commandpnpm review <url>echoes the URL backpnpm review(no args) shows commander's missing-argument error
Solution
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();{
"scripts": {
"review": "tsx src/cli.ts review"
}
}Was this helpful?