This guide covers how to set up and work with the Flarum CLI codebase locally.
- Node.js >= 18.0.0
- Yarn package manager
-
Clone the repository (if you haven't already)
-
Install dependencies:
yarn install
-
Build the TypeScript source:
yarn prepack
This command:
- Compiles TypeScript from
src/tolib/ - Generates the oclif manifest
- Updates the README with command documentation
- Compiles TypeScript from
You have several options for running the CLI during development:
./bin/run [command]Example:
./bin/run --help
./bin/run init
./bin/run make modelAdd an alias to your shell configuration file without affecting existing installations:
For zsh (add to ~/.zshrc):
alias fl-dev='/path/to/cli/bin/run'For bash (add to ~/.bashrc or ~/.bash_profile):
alias fl-dev='/path/to/cli/bin/run'After adding the alias, reload your shell:
source ~/.zshrc # or source ~/.bashrcThen use:
fl-dev [command]This allows you to keep your existing fl1, fl2, etc. aliases intact while having a dedicated fl-dev for local development.
yarn linkAfter linking, you can use any of these commands:
flarum-cli [command]fl [command]fl2 [command]
Warning: This will override any globally installed version of @flarum/cli.
- Edit TypeScript source files in
src/ - Rebuild the project:
yarn prepack
- Test your changes:
./bin/run [command]
Run the test suite:
yarn testThis will:
- Run Jest tests
- Check code formatting with Prettier
- Lint code with ESLint
- Perform a TypeScript dry-run build
Format code automatically:
yarn formatThis runs ESLint with auto-fix and Prettier.
.
├── bin/ # Executable entry points
│ └── run # Main CLI entry point
├── src/ # TypeScript source code
│ ├── commands/ # CLI command definitions
│ ├── steps/ # Reusable step implementations
│ ├── boilersmith/ # Scaffolding system
│ └── base-command.ts # Base command class
├── lib/ # Compiled JavaScript (gitignored)
├── test/ # Test files
├── boilerplate/ # Scaffolding templates
├── stubs/ # Code generation templates
├── php-subsystem/ # PHP parser for extend.php
└── package.json
- oclif: CLI framework
- TypeScript: Primary language
- PHP subsystem: Uses
nikic/php-parserfor PHP code manipulation - mem-fs: In-memory filesystem for atomic operations
Commands (in src/commands/)
- User-facing CLI commands
- Built on oclif framework
- Orchestrate step execution
Steps (in src/steps/)
- Granular, reusable operations
- Modify in-memory filesystem
- Can be composed atomically
- Support parameter sharing between steps
Step Manager
- Fluent API for chaining steps
- Handles optional steps
- Manages parameter passing between steps
- Supports atomic groups for transactional changes
Scaffolding System (src/boilersmith/)
- Manages extension infrastructure modules
- Supports initialization and updates
- Module-based file and config ownership
node --inspect ./bin/run [command]Most commands support flags for additional output. Check command help:
./bin/run [command] --help- Create command file in
src/commands/ - Extend from
BaseCommandclass - Define steps using Step Manager
- Rebuild with
yarn prepack - Test with
./bin/run [your-command]
- Create step class in appropriate
src/steps/subdirectory - Implement required methods (
run,getExposedParams, etc.) - Add unit tests
- Use step in command's
steps()method
- Edit files in
boilerplate/skeleton/extension/ - Update module definitions in scaffolding system
- Test with
./bin/run initor./bin/run infra
- Ensure you've run
yarn prepackto rebuild - Check that
lib/directory exists and contains compiled code
- Run
yarn posttestto see type checking output - Ensure
tsconfig.jsonincludes your new files
- Run
yarn testto see full output - Check that step unit tests match your changes
When making changes:
- Follow existing code patterns
- Add unit tests for new steps and functionality
- Update documentation as needed
- Run
yarn formatbefore committing - Ensure
yarn testpasses
- oclif Documentation
- README.md - User-facing documentation
- Main README "For Maintainers" section - Architecture deep-dive