A CLI scaffolding tool that creates new projects from the Storm Reply innovator-template. It clones the template repository, replaces placeholder names with your project name, installs dependencies, and creates an initial commit — all in one command.
- Node.js >= 24
- pnpm >= 10.29.2 (or corepack will enable it automatically)
- GitHub CLI (
gh) installed and available on yourPATH - A GitHub Personal Access Token with
repoandread:packagesscopes and access to thestormreplyorganization
Run directly with pnpm:
pnpm create innovatorOr with npx:
npx create-innovator| Flag | Alias | Description |
|---|---|---|
--name <name> |
-n |
Project name (skips the interactive prompt) |
--latest |
-l |
Skip version selection and use the latest version |
--experimental |
-e |
Include pre-release template versions in the version picker |
Create a project interactively:
pnpm create innovatorCreate a project with a specific name:
pnpm create innovator --name my-projectUse the latest template version without prompting:
pnpm create innovator --latestInclude experimental template versions:
pnpm create innovator --experimental- GitHub authentication — reads your token from
~/.npmrcor prompts you to enter one. Validates required scopes (repo,read:packages) and access to thestormreplyorganization. - Version selection — fetches available template tags and lets you pick a version (or auto-selects the latest when
--latestis used). - Clone — shallow-clones the template at the selected tag using
gh repo clone, then re-initializes a fresh git repository. - Name replacement — replaces
innovator-templatethroughout the project with your chosen name in all case variants (kebab-case, camelCase, PascalCase, Title Case). - Template cleanup — removes template-specific files that are not needed in the new project.
- Setup — installs dependencies via
pnpm install, updates test snapshots, and creates an initial commit.
If the automatic setup fails, the CLI prints the commands to run manually.
git clone git@github.com:stormreply/create-innovator.git
cd create-innovator
pnpm installpnpm dev # Run the CLI locally via tsx
pnpm build # Build with tsup (outputs to dist/)
pnpm test # Run all tests (vitest)
pnpm test:watch # Run tests in watch mode
pnpm lint # ESLint
pnpm format # Prettier (write mode)Run a single test file:
pnpm test -- src/scaffold/clone.test.tssrc/
├── cli.ts # Entry point — arg parsing (citty) and interactive UI (@clack/prompts)
├── cli.test.ts
├── auth/
│ ├── github.ts # Token validation, scope + org access checks
│ ├── github.test.ts
│ ├── prompts.ts # Interactive token input
│ ├── prompts.test.ts
│ ├── token-storage.ts # Read/write token from ~/.npmrc
│ └── token-storage.test.ts
├── scaffold/
│ ├── clone.ts # gh CLI check, tag fetching, shallow clone + git init
│ ├── clone.test.ts
│ ├── template.ts # Name replacement engine + template file cleanup
│ ├── template.test.ts
│ ├── setup.ts # pnpm install, snapshot update, initial commit
│ └── setup.test.ts
└── utils/
├── case.ts # PascalCase conversion (wraps Remeda)
├── case.test.ts
└── constants.ts # GitHub org, repo, scopes, registry URL
- ESM throughout (
"type": "module",.jsextensions in imports) - TypeScript with strict mode, target ES2022, NodeNext module resolution
- Prettier: single quotes, semicolons, trailing commas, 120 char line width
- Dependencies are pinned to exact versions (no
^or~prefixes)
Tests use Vitest with globals: true — no imports needed for describe, it, expect, or vi.
Key patterns:
- Shell commands (
child_process.execFile) are mocked viavi.mock('node:child_process')with callback-style mocks - File system operations in template tests use
memfs(in-memory filesystem) @clack/promptsis mocked in most test files to suppress UI output
| Hook | Action |
|---|---|
pre-commit |
Runs lint-staged — ESLint + Prettier on staged *.{js,json,md,ts} files, vitest on related *.ts files |
prepare-commit-msg |
Launches Commitizen interactively to guide you through a conventional commit message |
commit-msg |
Enforces Conventional Commits via commitlint |
pre-push |
Runs the full test suite (only if working tree is clean) |
This project follows Conventional Commits and is Commitizen friendly. The prepare-commit-msg hook automatically launches Commitizen when you run git commit, guiding you through a structured commit message prompt — no extra commands needed.
Releases are managed with release-it:
pnpm release