@hominhtuan/repodoctor
v0.1.2
Published
Zero-config Repository Health, Security & CI Linter for modern open-source projects
Maintainers
Readme
🩺 RepoDoctor
Zero-config Repository Health, Security & CI Linter for modern open-source projects.
Table of Contents
- Problem Statement
- Key Features
- Installation & Setup
- Quick Start
- CLI Usage & Commands
- Rule Catalog
- Configuration
- Automated Remediation (Fixers)
- Output Formats & CI Integration
- Architecture Overview
- Security Model
- Limitations
- Development & Testing
- Contributing
- Roadmap
- License
Problem Statement
As open-source repositories grow, they accumulate hygiene decay, security vulnerabilities, and workflow misconfigurations:
- GitHub Actions run unpinned floating tags (susceptible to supply-chain attacks).
- Workflows lack timeout bounds or concurrency cancellation, burning CI credits.
- Sensitive environment variables and keys lack
.gitignorecoverage. - Missing OSS governance (LICENSE, SECURITY.md, issue templates, PR checklists) slows down contributions.
- Conflicting lockfiles or open version ranges break builds unpredictably.
Existing linters are fragmented: ESLint only checks JavaScript ASTs, Flake8 only checks Python, and heavy commercial security scanners require SaaS signups, cloud tokens, or complex setups.
RepoDoctor provides a single, zero-config CLI tool that diagnoses 29 built-in cross-ecosystem repository health rules, computes a deterministic 0-100 Repository Health Score (Grades A+ to F), auto-fixes common violations, and generates standard SARIF 2.1.0 reports for GitHub Code Scanning.
Key Features
- ⚡ Deterministic & Local-first: Evaluates repositories locally with in-memory parsing caches without requiring network access.
- 🔒 Security & Supply-Chain Hardened: Detects unpinned GitHub Actions, dangerous
pull_request_targetusage, plaintext tokens, missing.gitignoresecret rules, andcurl | shpipes. - 📜 OSS Standards Compliance: Verifies LICENSE integrity, README completeness, CONTRIBUTING guides, CODE_OF_CONDUCT, and SECURITY.md policies.
- 🚦 CI/CD Best Practices: Validates workflow
timeout-minutes, PR concurrency cancellation groups, and multi-OS matrix configurations. - 📦 Package & Lockfile Hygiene: Checks for missing lockfiles (npm, yarn, pnpm, cargo, poetry, uv, go), conflicting lockfiles, and unconstrained wildcard
*dependencies. - 🛠️ One-Command Remediation (
repodoctor fix): Safely generates missing.gitattributes,.gitignoresecret patterns,SECURITY.md,CONTRIBUTING.md,CODE_OF_CONDUCT.md, issue templates, and PR templates. - 📊 Multi-Format Reporting: Supports Terminal ANSI tables, JSON, Markdown, GitHub workflow annotations (
::error::), and OASIS SARIF v2.1.0 for GitHub Security tab integration. - 🎛️ Extensible & Configurable: Zero-config by default, with optional
.repodoctor.ymlfor custom rules, severity overrides, and score thresholds.
Installation & Setup
Local Development / Repository Clone
Clone the repository and install dependencies:
git clone https://github.com/knmt1219/repodoctor.git
cd repodoctor
npm install
npm run buildRun RepoDoctor locally:
# Run health diagnostics
node ./bin/repodoctor.js check .
# Run auto-remediation fixers
node ./bin/repodoctor.js fix .When Published to npm
Once published to the npm registry, RepoDoctor can be executed directly:
# Run instantly with npx
npx repodoctor check
# Global installation
npm install -g repodoctor
# Project development dependency
npm install --save-dev repodoctorQuick Start
Run a full health check on your current repository:
node ./bin/repodoctor.js check .Sample output:
RepoDoctor v0.1.0 — Repository Health & Security Diagnostics
──────────────────────────────────────────────────────────────────────
WARN [sec-002] Workflow ".github/workflows/ci.yml" does not declare top-level or job-level 'permissions:' block at .github/workflows/ci.yml:1:1
└─ Fix: Add `permissions: read-all` or specific granular permissions at the top of the workflow
WARN [git-001] Missing .gitattributes file for cross-platform line ending normalization
└─ Fix: Create a `.gitattributes` file containing `* text=auto eol=lf`.
──────────────────────────────────────────────────────────────────────
Health Score: 92/100 (Grade: A)
Category Breakdown: security: 90% | oss: 100% | ci: 100% | package: 100% | git: 90% | docker: 100%
Summary: 2 warnings, 1 auto-fixable (29 rules evaluated)Auto-fix eligible issues immediately:
node ./bin/repodoctor.js fix .CLI Usage & Commands
repodoctor [command] [options] [target-directory]Commands
| Command | Description |
| :--- | :--- |
| repodoctor check [target] | (Default) Run diagnostics and output report |
| repodoctor fix [target] | Automatically apply safe remediation fixes to the repository |
| repodoctor init [target] | Scaffold a standard .repodoctor.yml configuration file |
| repodoctor rules [category] | List all built-in rules, severities, and descriptions |
| repodoctor explain <rule-id> | Show in-depth rationale, non-compliant vs compliant code examples, and remediation steps |
Flags & Options (check command)
| Option | Alias | Description | Default |
| :--- | :---: | :--- | :--- |
| --format <format> | -f | Output format: terminal, json, sarif, markdown, github | terminal |
| --output <file> | -o | Save the generated report to a file | stdout |
| --config <path> | -c | Custom path to configuration file | .repodoctor.yml |
| --score-threshold <num> | | Minimum acceptable health score (exits 1 if lower) | 75 |
| --max-warnings <num> | | Maximum allowed warnings before exiting with code 1 | -1 (unlimited) |
| --strict | | Treat warnings as errors (fails if any warning exists) | false |
| --fix | | Automatically apply fixes before computing final score | false |
| --version | -V | Output installed version | |
| --help | -h | Display command help | |
Rule Catalog
RepoDoctor includes 29 built-in production rules categorized across 6 core domains:
1. 🔒 Security & Supply Chain (security)
sec-001(error): Action Commit SHA Pinning — Ensures GitHub Actions use immutable 40-character commit hashes rather than mutable floating tags (@v4).sec-002(warn): Explicit Workflow Permissions — Ensures workflows declare least-privilegepermissions:blocks and avoidspermissions: write-all.sec-003(error, fixable): Gitignore Secrets Coverage — Validates that.gitignoreprevents staging.env,*.key,*.pem, and credential files.sec-004(error): No Remote Pipe-to-Shell — Flags dangerouscurl | shorwget | bashexecutions in CI workflows and package scripts.sec-005(error): Committed Secret Scanner — Scans tracked files for high-entropy API keys (OpenAI, AWS, Slack, GitHub tokens) and private key headers with automatic redaction.sec-006(warn): Safepull_request_targetUsage — Flags risky combinations ofpull_request_targettriggers checking out untrusted fork head code.
2. 📜 Open Source & Community Standards (oss)
oss-001(error): Valid LICENSE File — Checks for an OSI-compliant, non-empty LICENSE file.oss-002(warn): Comprehensive README — Ensures README exists and provides structured documentation.oss-003(warn, fixable): CONTRIBUTING Guide — Checks forCONTRIBUTING.mdin root or.github/.oss-004(info, fixable): Code of Conduct — Checks forCODE_OF_CONDUCT.md.oss-005(warn, fixable): SECURITY.md Policy — Verifies a vulnerability reporting policy exists.oss-006(info, fixable): Issue Templates — Checks for.github/ISSUE_TEMPLATE/forms.oss-007(info, fixable): Pull Request Template — Checks for.github/pull_request_template.md.oss-008(warn): Package Metadata Completeness — Verifiesdescriptionandrepositoryfields in package manifests.
3. 🚦 CI/CD Best Practices (ci)
ci-001(warn): Workflow Job Timeouts — Ensures all GitHub Actions jobs declaretimeout-minutesto avoid runaway billing.ci-002(warn): PR Concurrency Cancellation — Ensures PR workflows setconcurrencywithcancel-in-progress: trueand non-empty group to prevent runner backlog.ci-003(warn): CI Workflow Presence — Checks that at least one CI workflow is configured in.github/workflows/.ci-004(info): Matrix Fail-Fast Policy — Recommends explicitfail-fastconfiguration on large test matrices.
4. 📦 Package & Dependency Hygiene (package)
pkg-001(error): Committed Lockfile — Ensures package manifests have matching lockfiles (package-lock.json,pnpm-lock.yaml,yarn.lock,Cargo.lock,poetry.lock,uv.lock,go.sum).pkg-002(error): No Conflicting Lockfiles — Detects accidental co-existence of multiple lockfiles (e.g.package-lock.jsonANDyarn.lock).pkg-003(warn): No Wildcard Dependencies — Flags dangerous*orlatestunconstrained dependencies inpackage.json.pkg-004(warn): Standard Lifecycle Scripts — Ensurespackage.json#scriptsdefines required executable lifecycle scripts (defaults to['test'], configurable viaoptions.requiredScripts).
5. 📁 Git & File Structure Hygiene (git)
git-001(warn, fixable): Cross-Platform.gitattributes— Ensures* text=auto eol=lfis configured to prevent CRLF corruption.git-002(error): No Merge Conflict Markers — Detects committed<<<<<<<,=======,>>>>>>>markers in files.git-003(warn): Large Binary Tracking — Warns on large binary files tracked without Git LFS (defaults to >1024 KB / 1 MB threshold, configurable viaoptions.maxBinarySizeKb).git-004(error): No Nested.gitDirectories — Detects accidental embedded git repositories or unregistered submodules.git-005(error): No Broken Symbolic Links — Detects dead or repository-escaping symlinks.
6. 🐳 Docker & Container Hygiene (docker)
docker-001(warn): Base Image Pinning — Warns on:latestor unpinned tags inDockerfile.docker-002(warn, fixable):.dockerignorePresence — Ensures.dockerignoreexists whenDockerfileis present.
Configuration
Initialize a configuration file with:
repodoctor initThis creates .repodoctor.yml in your repository root:
# Minimum acceptable health score (0 - 100)
scoreThreshold: 85
# Maximum allowed warnings before exiting with code 1 (-1 for unlimited)
maxWarnings: 0
# Enable or disable categories
categories:
security: true
oss: true
ci: true
package: true
git: true
docker: true
# Custom rule severity overrides ('error', 'warn', 'info', 'off')
rules:
sec-001: error # Action SHA pinning
sec-002: warn # Workflow permissions
ci-001: error # Enforce timeouts as strict errors
oss-004: off # Disable Code of Conduct check
# Global analyzer options
options:
checkTrackedOnly: false # Scan only git-tracked files when true
requiredScripts: ['test'] # Lifecycle scripts required by pkg-004
maxBinarySizeKb: 1024 # Binary size threshold in KB for git-003
# Files and directories to ignore
ignore:
- '**/legacy/**'
- '**/fixtures/**'RepoDoctor also supports .repodoctor.json, .repodoctorrc, or a "repodoctor" section in package.json.
Automated Remediation (Fixers)
Run:
node ./bin/repodoctor.js fix .RepoDoctor will safely apply non-destructive, idempotent fixes:
git-001: Generates.gitattributeswith* text=auto eol=lf.sec-003: Appends.env,.env.*,*.key,*.pem, andcredentials.jsonrules to.gitignore.oss-003: GeneratesCONTRIBUTING.mdtemplate.oss-004: GeneratesCODE_OF_CONDUCT.mdtemplate.oss-005: GeneratesSECURITY.mdvulnerability reporting policy template.oss-006: Generates.github/ISSUE_TEMPLATE/forms (bug_report.ymlandfeature_request.yml).oss-007: Generates.github/pull_request_template.md.docker-002: Generates.dockerignoreignoring node_modules,.git,.env, and build artifacts.
Output Formats & CI Integration
1. Terminal (Default)
repodoctor check2. SARIF v2.1.0 (for GitHub Code Scanning)
Integrate RepoDoctor directly with GitHub's Security / Code Scanning tab:
# .github/workflows/repodoctor.yml
name: RepoDoctor Scan
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
security-events: write
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
node-version: 20
- run: npm ci
- run: npm run build
- run: node ./bin/repodoctor.js check . --format sarif --output results.sarif
continue-on-error: true
- uses: github/codeql-action/upload-sarif@6bb034f26f1da0b37c6335a3983f3333bed7a2ff # v3.28.11
with:
sarif_file: results.sarif3. Markdown Report
Generate rich Markdown tables for $GITHUB_STEP_SUMMARY or PR comments:
repodoctor check --format markdown >> $GITHUB_STEP_SUMMARY4. JSON (Machine-Readable)
repodoctor check --format json --output report.json5. GitHub Annotations
Directly annotate pull request diffs using GitHub Actions workflow commands:
repodoctor check --format githubArchitecture Overview
┌──────────────────────────┐
│ CLI / Entry Point │
│ (Commander, Flags, Args) │
└─────────────┬────────────┘
│
▼
┌──────────────────────────┐
│ Config Loader │
│ (.repodoctor.yml, JSON) │
└─────────────┬────────────┘
│
▼
┌──────────────────────────┐
│ RepoDoctor Engine │
│ - Rule Context Cache │
│ - Parallel Rule Runner │
└─────────────┬────────────┘
│
┌───────────────────────────┴───────────────────────────┐
▼ ▼
┌───────────────────────┐ ┌───────────────────────┐
│ Rule Catalog │ │ Score Calculator │
│ - Security (sec-*) │ │ - 0-100 Score │
│ - OSS (oss-*) │ │ - Grade A+ to F │
│ - CI (ci-*) │ │ - Category Breakdown │
│ - Package (pkg-*) │ └───────────┬───────────┘
│ - Git (git-*) │ │
│ - Docker (docker-*) │ │
└───────────┬───────────┘ │
└─────────────────────────┬─────────────────────────────┘
│
▼
┌──────────────────────────┐
│ Reporters │
│ - Terminal (ANSI) │
│ - SARIF v2.1.0 │
│ - Markdown Summary │
│ - JSON / GH Annotations │
└──────────────────────────┘Security Model
- Static Analysis: RepoDoctor treats analyzed files as data. The engine performs static inspection without dynamically evaluating or importing target repository executable scripts.
- Offline-First Design: RepoDoctor is designed to operate locally on the filesystem without network access.
- Path Boundary Protection: Safe file reading and writing utilities verify paths against the repository root boundary to prevent unintended file access outside the target repository.
- Secret Redaction: Common API keys and tokens matching built-in patterns are masked before formatting in reports to help avoid accidental exposure in terminal output or CI logs.
Limitations
- AST parsing is focused on configuration structures (YAML, JSON, TOML, Dockerfiles, and Git attributes). Deep semantic AST analysis of language-specific logic (e.g. complex TypeScript control flow) is best paired with specialized linters like ESLint.
- Git historical scanning checks currently tracked files and
.gitconfig; full-history deep commit rewriting is recommended via tools likegit-filter-repo.
Development & Testing
Run Tests
npm testRun Coverage Report
npm run test:coverageType Checking & Linting
npm run typecheck
npm run lintSelf-Dogfooding
npm run doctorContributing
Contributions are warmly welcome! Please read our Contributing Guide and Code of Conduct before submitting a pull request.
Roadmap
- [x] Initial release (v0.1.0) with 29 built-in production rules and SARIF 2.1.0 support
- [ ] Pre-commit git hook integration (
repodoctor hook install) - [ ] Custom community plugin architecture (
repodoctor-plugin-*) - [ ] Monorepo package boundary and workspace dependency analyzer
- [ ] Direct PR comment bot GitHub Action
License
MIT License © 2026 RepoDoctor Contributors
