API Reference
Use Branchwright programmatically in your Node.js applications.
Main API
Branchwright Class
The main interface for programmatic usage:
import { Branchwright } from '@branchwright/cli';
const branchwright = new Branchwright(config?);
Constructor
new Branchwright(config?: BranchwrightConfig)
Creates a new instance with optional configuration. If no config is provided, it will attempt to load from branchwright.config.ts.
Methods
validate(branchName: string): Promise<ValidationResult>
Validate a branch name against configured rules.
const result = await branchwright.validate('feat/user-auth');
if (result.valid) {
console.log('✓ Branch name is valid');
} else {
console.log(`✗ ${result.message}`);
console.log('Suggestions:', result.suggestions);
}
create(): Promise<string>
Launch interactive branch creation wizard.
const branchName = await branchwright.create();
console.log(`Created: ${branchName}`);
lint(options?: LintOptions): Promise<LintResult[]>
Validate one or more branches.
// Lint current branch
const results = await branchwright.lint();
// Lint all branches
const allResults = await branchwright.lint({ all: true });
// Lint specific branches
const specificResults = await branchwright.lint({
branches: ['feat/auth', 'fix/bug']
});
getValidator(): Validator
Get the underlying validator instance for advanced usage.
getCreator(): Creator
Get the underlying creator instance for advanced usage.
Type Definitions
BranchwrightConfig
interface BranchwrightConfig {
branchTypes?: BranchTypeOption[];
template?: string;
maxDescriptionLength?: number;
descriptionStyle?: 'kebab-case' | 'snake_case' | 'camelCase' | 'PascalCase';
ignoredBranches?: string[];
rules?: Rules;
extraQuestions?: InteractiveQuestions;
questions?: QuestionConfig;
plugins?: string[];
presets?: string[];
showCliTips?: boolean;
}
BranchTypeOption
interface BranchTypeOption {
name: string; // Short identifier (feat, fix, etc.)
label: string; // Display name for prompts
}
ValidationResult
interface ValidationResult {
valid: boolean;
message?: string;
suggestions?: string[];
violations?: RuleViolation[];
}
LintOptions
interface LintOptions {
all?: boolean;
branches?: string[];
json?: boolean;
}
LintResult
interface LintResult {
branch: string;
valid: boolean;
message?: string;
violations?: RuleViolation[];
}
Rule System API
defineRule
Create custom validation rules:
import { defineRule } from '@branchwright/cli';
const myRule = defineRule(
{
id: 'my-rule',
meta: {
title: 'My Custom Rule',
description: 'Validates something specific',
},
defaultSeverity: 'required',
},
(context: RuleContext) => {
// Return null if valid
if (isValid(context.branchName)) {
return null;
}
// Return violation if invalid
return {
message: 'Branch name is invalid',
suggestions: ['alternative-name'],
};
}
);
RuleContext
interface RuleContext {
branchName: string;
config: BranchwrightConfig;
options?: any; // Rule-specific options
}
evaluateRules
Evaluate multiple rules against a branch name:
import { evaluateRules, coreRuleRegistry } from '@branchwright/cli';
const violations = await evaluateRules(
'feat/my-branch',
config,
coreRuleRegistry
);
violations.forEach(v => {
console.error(`${v.ruleId}: ${v.message}`);
});
createRegistry
Create a custom rule registry:
import { createRegistry, coreRuleRegistry } from '@branchwright/cli';
const customRegistry = createRegistry(
...coreRuleRegistry.entries(),
myCustomRule,
anotherCustomRule
);
Utility Functions
defineConfig
Type-safe configuration helper:
import { defineConfig } from '@branchwright/cli';
export default defineConfig({
// Full TypeScript autocomplete and validation
branchTypes: [/* ... */],
template: '{{type}}/{{desc}}',
});
loadConfig
Load configuration from a file:
import { loadConfig } from '@branchwright/cli';
const config = await loadConfig('./path/to/config.ts');
Integration Examples
Custom CLI Tool
#!/usr/bin/env node
import { Branchwright } from '@branchwright/cli';
async function main() {
const brw = new Branchwright();
if (process.argv[2] === 'validate') {
const branch = process.argv[3] || getCurrentBranch();
const result = await brw.validate(branch);
process.exit(result.valid ? 0 : 1);
}
}
main();
Express.js Webhook
import express from 'express';
import { Branchwright } from '@branchwright/cli';
const app = express();
const brw = new Branchwright();
app.post('/validate-branch', async (req, res) => {
const { branchName } = req.body;
const result = await brw.validate(branchName);
res.json({
valid: result.valid,
message: result.message,
});
});
GitHub Action
import { Branchwright } from '@branchwright/cli';
import * as core from '@actions/core';
async function run() {
try {
const brw = new Branchwright();
const branch = process.env.GITHUB_HEAD_REF;
const result = await brw.validate(branch);
if (!result.valid) {
core.setFailed(result.message);
}
} catch (error) {
core.setFailed(error.message);
}
}
run();
Husky Pre-push Hook
#!/usr/bin/env node
import { Branchwright } from '@branchwright/cli';
import { execSync } from 'child_process';
async function validateCurrentBranch() {
const brw = new Branchwright();
const branch = execSync('git branch --show-current')
.toString()
.trim();
const result = await brw.validate(branch);
if (!result.valid) {
console.error(`✗ Invalid branch name: ${result.message}`);
process.exit(1);
}
console.log('✓ Branch name is valid');
}
validateCurrentBranch();
Advanced Usage
Custom Validator
import { Validator } from '@branchwright/cli';
class CustomValidator extends Validator {
async validate(branchName: string) {
// Custom validation logic
const result = await super.validate(branchName);
// Add additional checks
if (branchName.includes('temp')) {
return {
valid: false,
message: 'Temporary branches not allowed',
};
}
return result;
}
}
Rule Plugin Development
// my-plugin.ts
import { defineRule } from '@branchwright/cli';
export default [
defineRule(
{
id: 'team-prefix',
meta: {
title: 'Team prefix required',
description: 'Branch must start with team name',
},
defaultSeverity: 'required',
},
(context) => {
const { team } = context.options;
if (!context.branchName.startsWith(`${team}/`)) {
return {
message: `Branch must start with ${team}/`,
suggestions: [`${team}/${context.branchName}`],
};
}
return null;
}
),
// More rules...
];
// Usage in config
export default defineConfig({
plugins: ['./my-plugin.ts'],
rules: {
'team-prefix': ['required', { team: 'frontend' }],
},
});