6.5 KiB
6.5 KiB
name, description, allowed-tools
| name | description | allowed-tools |
|---|---|---|
| oclif-patterns | Enterprise CLI patterns using oclif framework with TypeScript. Use when building oclif CLIs, creating plugins, implementing commands with flags/args, adding auto-documentation, testing CLI commands, or when user mentions oclif, enterprise CLI, TypeScript CLI, plugin system, or CLI testing. | Read, Write, Edit, Bash, Glob, Grep |
oclif Enterprise CLI Patterns
Provides comprehensive patterns for building production-grade CLIs with oclif framework.
Core Capabilities
1. Command Structure
- Single and multi-command CLIs
- Flag definitions (string, boolean, integer, custom)
- Argument parsing with validation
- Command inheritance and base classes
- Async command execution
2. Plugin System
- Installable plugins
- Plugin discovery and loading
- Hook system for extensibility
- Plugin commands and lifecycle
3. Auto-Documentation
- Auto-generated help text
- README generation
- Command reference docs
- Flag and argument documentation
4. Testing Patterns
- Command unit tests
- Integration testing
- Mock stdin/stdout
- Fixture management
- Test helpers
Implementation Guide
Command Creation
Use templates:
templates/command-basic.ts- Simple command with flagstemplates/command-advanced.ts- Complex command with validationtemplates/command-async.ts- Async operationstemplates/base-command.ts- Custom base class
Key patterns:
- Import Command from '@oclif/core'
- Define flags using
Flagsobject - Define args using
Argsobject - Implement async run() method
- Use this.log() for output
- Use this.error() for errors
Flag Patterns
Common flags:
- String:
Flags.string({ description, required, default }) - Boolean:
Flags.boolean({ description, allowNo }) - Integer:
Flags.integer({ description, min, max }) - Custom:
Flags.custom<T>({ parse: async (input) => T }) - Multiple:
Flags.string({ multiple: true })
Best practices:
- Always provide clear descriptions
- Use char for common short flags
- Set required vs optional explicitly
- Provide sensible defaults
- Validate in parse function for custom flags
Argument Patterns
Definition:
static args = {
name: Args.string({ description: 'Name', required: true }),
file: Args.file({ description: 'File path', exists: true })
}
Access in run():
const { args } = await this.parse(MyCommand)
Plugin Development
Use templates:
templates/plugin-package.json- Plugin package.jsontemplates/plugin-command.ts- Plugin command structuretemplates/plugin-hooks.ts- Hook implementations
Plugin structure:
my-plugin/
├── package.json (oclif configuration)
├── src/
│ ├── commands/ (plugin commands)
│ └── hooks/ (lifecycle hooks)
├── test/ (plugin tests)
└── README.md
Testing Setup
Use templates:
templates/test-command.ts- Command test templatetemplates/test-helpers.ts- Test utilitiestemplates/test-setup.ts- Test configuration
Testing approach:
- Use @oclif/test for test helpers
- Mock stdin/stdout with fancy-test
- Test flag parsing separately
- Test command execution
- Test error handling
- Use fixtures for file operations
Auto-Documentation
Generated automatically:
- Command help via
--helpflag - README.md with command reference
- Usage examples
- Flag and argument tables
Use scripts:
scripts/generate-docs.sh- Generate all documentationscripts/update-readme.sh- Update README with commands
Quick Start Examples
Create Basic Command
# Use template
./scripts/create-command.sh my-command basic
# Results in: src/commands/my-command.ts
Create Plugin
# Use template
./scripts/create-plugin.sh my-plugin
# Results in: plugin directory structure
Run Tests
# Use test helpers
npm test
# or with coverage
npm run test:coverage
Validation Scripts
Available validators:
scripts/validate-command.sh- Check command structurescripts/validate-plugin.sh- Verify plugin structurescripts/validate-tests.sh- Ensure test coverage
Templates Reference
TypeScript Commands
command-basic.ts- Simple command patterncommand-advanced.ts- Full-featured commandcommand-async.ts- Async/await patternsbase-command.ts- Custom base classcommand-with-config.ts- Configuration management
Plugin System
plugin-package.json- Plugin package.jsonplugin-command.ts- Plugin commandplugin-hooks.ts- Hook implementationsplugin-manifest.json- Plugin manifest
Testing
test-command.ts- Command unit testtest-helpers.ts- Test utilitiestest-setup.ts- Test configurationtest-integration.ts- Integration test
Configuration
tsconfig.json- TypeScript configpackage.json- oclif package.json.eslintrc.json- ESLint config
Examples Directory
See examples/ for complete working examples:
examples/basic-cli/- Simple CLI with commandsexamples/plugin-cli/- CLI with plugin supportexamples/enterprise-cli/- Full enterprise setup
Common Patterns
Error Handling
if (!valid) {
this.error('Invalid input', { exit: 1 })
}
Spinner/Progress
const spinner = ux.action.start('Processing')
// ... work
ux.action.stop()
Prompts
const answer = await ux.prompt('Continue?')
Table Output
ux.table(data, { columns: [...] })
Requirements
- Node.js 18+
- TypeScript 5+
- @oclif/core ^3.0.0
- @oclif/test for testing
- Knowledge of TypeScript decorators (optional but helpful)
Best Practices
- Command Design: Keep commands focused, single responsibility
- Flags: Use descriptive names, provide help text
- Testing: Test command parsing and execution separately
- Documentation: Let oclif generate docs, keep them updated
- Plugins: Design for extensibility from the start
- Error Messages: Provide actionable error messages
- TypeScript: Use strict mode, define proper types
- Async: Use async/await, handle promises properly
Advanced Features
Custom Flag Types
Create reusable custom flag parsers for complex validation.
Hook System
Implement hooks for: init, prerun, postrun, command_not_found.
Topic Commands
Organize commands into topics (e.g., mycli topic:command).
Auto-Update
Use @oclif/plugin-update for automatic CLI updates.
Analytics
Integrate analytics to track command usage.