@birdcc/linter
v0.1.0-beta.0
Published
Lint rule engine for BIRD2 configuration files.
Readme
🧩 BIRD Config Linter (@birdcc/linter)
⚠️ Alpha Stage: This package is in early development. APIs may change frequently, and unexpected issues may occur. Please evaluate carefully before deploying in production environments.
Overview · Features · Installation · Usage · Rules · API Reference
Overview
@birdcc/linter is the rule engine layer of the BIRD-LSP toolchain, providing a pluggable lint rule system for checking protocol compliance, security, and performance issues in BIRD2 configuration files.
Features
- 🧩 Pluggable Rules — Flexible rule system based on the
BirdRuletype - 🌐 Protocol Rules — BGP/OSPF configuration completeness checks
- 🔒 Security Rules — Configuration security best practices
- ⚡ Performance Rules — Performance optimization recommendations
- 🔍 32+ Built-in Rules — Comprehensive coverage of common issues
Installation
# Using pnpm (recommended)
pnpm add @birdcc/linter
# Using npm
npm install @birdcc/linter
# Using yarn
yarn add @birdcc/linterUsage
Basic Linting
import { lintBirdConfig } from "@birdcc/linter";
const config = `
protocol bgp example {
neighbor 192.168.1.1 as 65001;
}
`;
const result = lintBirdConfig(config);
console.log(result.diagnostics);
// [{ code: "bgp/missing-local-as", message: "BGP protocol missing local as configuration", severity: "warning" }]Reference Samples Sync
pnpm --filter @birdcc/linter sync:examplesThis command copies refer/vscode-bird2/syntaxes/bird-tm-grammar/sample/*.conf
to packages/@birdcc/linter/examples/ and runs automatically during build
and test.
Custom Rules
import type { BirdRule, BirdDiagnostic } from "@birdcc/linter";
const namingConventionRule: BirdRule = ({ core }) => {
const diagnostics: BirdDiagnostic[] = [];
for (const symbol of core.symbols) {
if (symbol.kind === "protocol") {
if (!/^[a-z][a-z0-9-]*$/.test(symbol.name)) {
diagnostics.push({
code: "structure/invalid-protocol-name",
message: `Protocol name '${symbol.name}' should only contain lowercase letters, numbers, and hyphens`,
severity: "warning",
source: "linter",
range: {
/* ... */
},
});
}
}
}
return diagnostics;
};Rules
Symbol Rules (sym/*)
| Rule | Description | Level |
| ------------------------- | ----------------------------- | ----- |
| sym/undefined | Reference to undefined symbol | error |
| sym/duplicate | Duplicate symbol definition | error |
| sym/proto-type-mismatch | Protocol type mismatch | error |
Config Rules (cfg/*)
| Rule | Description | Level |
| ------------------------ | ------------------------ | ----- |
| cfg/no-protocol | No protocol defined | error |
| cfg/missing-router-id | Missing router id | error |
| cfg/syntax-error | Syntax error detected | error |
| cfg/value-out-of-range | Value out of valid range | error |
Network Rules (net/*)
| Rule | Description | Level |
| --------------------------- | --------------------- | ----- |
| net/invalid-prefix-length | Invalid prefix length | error |
| net/invalid-ipv4-prefix | Invalid IPv4 prefix | error |
| net/invalid-ipv6-prefix | Invalid IPv6 prefix | error |
Type Rules (type/*)
| Rule | Description | Level |
| ------------------- | -------------------- | ----- |
| type/mismatch | Type mismatch | error |
| type/not-iterable | Non-iterable in loop | error |
BGP Rules (bgp/*)
| Rule | Description | Level |
| ----------------------- | ------------------ | ------- |
| bgp/missing-local-as | Missing local AS | warning |
| bgp/missing-neighbor | Missing neighbor | warning |
| bgp/missing-remote-as | Missing remote AS | warning |
| bgp/as-mismatch | AS number mismatch | warning |
OSPF Rules (ospf/*)
| Rule | Description | Level |
| -------------------- | -------------------------- | ------- |
| ospf/missing-area | Missing area configuration | warning |
| ospf/backbone-stub | Stub area on backbone | warning |
API Reference
lintBirdConfig(text: string, options?): LintResult
Perform complete lint checks (semantic analysis + rule checks).
import { lintBirdConfig } from "@birdcc/linter";
const result = lintBirdConfig(birdConfigText);
// result.parsed → Parsed AST
// result.core → Semantic analysis snapshot
// result.diagnostics → All diagnostic messagesTypes
interface LintResult {
parsed: ParsedBirdDocument;
core: CoreSnapshot;
diagnostics: BirdDiagnostic[];
}
type BirdRule = (context: RuleContext) => BirdDiagnostic[];
interface RuleContext {
text: string;
parsed: ParsedBirdDocument;
core: CoreSnapshot;
}Related Packages
| Package | Description | | ---------------------------------- | ------------------------------ | | @birdcc/parser | Tree-sitter grammar and parser | | @birdcc/core | Semantic analysis engine | | @birdcc/formatter | Code formatting engine | | @birdcc/lsp | LSP server implementation | | @birdcc/cli | Command-line interface |
📖 Documentation
📝 License
This project is licensed under the GPL-3.0 License.
