Installation
Install doqtor globally from npm:
$ npm install -g @doqtor/cli
Or run directly with npx:
$ npx @doqtor/cli check
Then initialize a config file in your project:
$ doqtor init
Created doqtor.config.json
Configuration
Create a doqtor.config.json in your project root (or run doqtor init):
{
"docsPaths": ["README.md", "docs/"],
"ignore": ["node_modules/", "dist/", ".git/"],
"ai": {
"enabled": false,
"provider": "openai"
},
"autoPR": true
}
| Option | Type | Default | Description |
|---|---|---|---|
docsPaths | string[] | ["README.md", "docs/"] | Files and directories to scan for documentation |
ignore | string[] | ["node_modules/", "dist/", ".git/"] | Paths to exclude from analysis |
ai.enabled | boolean | false | Use an LLM for fix generation |
ai.provider | string | "openai" | AI provider: "openai" or "anthropic" |
autoPR | boolean | true | Automatically create PRs with fixes |
AI-Assisted Fixes
When ai.enabled is true, doqtor uses an LLM to generate more natural documentation fixes beyond simple find-and-replace. Set the appropriate API key as an environment variable:
# For OpenAI
$ export OPENAI_API_KEY=sk-...
# For Anthropic
$ export ANTHROPIC_API_KEY=sk-ant-...
CLI Reference
The doqtor CLI runs the drift detection pipeline locally against your git changes.
doqtor check
Analyze local git diff for documentation drift. Exits with code 1 if drift is found.
$ doqtor check
$ doqtor check --config path/to/config.json
| Option | Description |
|---|---|
-c, --config <path> | Path to a custom config file |
doqtor fix
Detect drift and apply documentation patches. Use --dry-run to preview without writing.
$ doqtor fix
$ doqtor fix --dry-run
$ doqtor fix --config path/to/config.json
| Option | Description |
|---|---|
-c, --config <path> | Path to a custom config file |
--dry-run | Show patches without applying them |
doqtor init
Generate a default doqtor.config.json in the current directory.
$ doqtor init
API Reference
Doqtor's internals are exposed as scoped packages for programmatic use.
@doqtor/parser
Extract symbols from TypeScript source files using AST analysis (ts-morph).
import { parseSource } from "@doqtor/parser";
const symbols = parseSource("src/index.ts", sourceCode);
// Returns ParsedSymbol[]
@doqtor/core-engine
Diff analysis and drift detection.
import { analyzeDiff } from "@doqtor/core-engine";
import { detectDrift } from "@doqtor/core-engine";
const changeSets = analyzeDiff(unifiedDiff, parseSource);
const report = detectDrift(changeSets, docReferences);
@doqtor/matcher
Maps code changes to documentation references.
import { matchDocs } from "@doqtor/matcher";
const refs = matchDocs(changeSets, docFiles);
@doqtor/fixer
Generates documentation patches from drift reports.
import { generateFixes } from "@doqtor/fixer";
const patches = await generateFixes(report, config);
Core Types
interface ParsedSymbol {
name: string;
kind: "function" | "class" | "interface" | "type" | "constant" | "method";
filePath: string;
line: number;
parameters?: ParameterInfo[];
returnType?: string;
jsDoc?: string;
exported: boolean;
}
interface DriftItem {
type: "signature-mismatch" | "removed-symbol"
| "outdated-example" | "renamed-symbol";
symbolName: string;
docReference: DocReference;
oldValue: string;
newValue: string;
confidence: number;
}
interface DocPatch {
filePath: string;
lineStart: number;
lineEnd: number;
oldText: string;
newText: string;
driftItem: DriftItem;
}
interface DoqtorConfig {
docsPaths: string[];
ignore: string[];
ai: { enabled: boolean; provider?: "openai" | "anthropic" };
autoPR: boolean;
}
GitHub App
Run doqtor as a GitHub App to automatically fix docs when PRs merge.
1. Create a GitHub App
- Go to GitHub Settings → Developer settings → GitHub Apps → New GitHub App
- Set the webhook URL to your deployed backend (e.g.
https://your-server.com/webhook) - Subscribe to Pull request events
- Required permissions:
- Contents: Read & Write (to create branches and commits)
- Pull requests: Read & Write (to create fix PRs)
- Generate a private key and download it
2. Configure Environment
GITHUB_APP_ID=123456
GITHUB_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n..."
GITHUB_WEBHOOK_SECRET=your-webhook-secret
PORT=3000
LOG_LEVEL=info
3. Deploy
The backend is a standard Node.js/Bun server. Deploy to any platform:
# Build and start
$ bun install
$ bun run build
$ bun run --cwd apps/backend src/index.ts
4. Install on Repos
Install your GitHub App on the repositories you want doqtor to monitor. Add a doqtor.config.json to each repo's root.
Architecture
Doqtor is a monorepo built with Turborepo and Bun workspaces.
+------------------+
| GitHub Webhook |
+--------+---------+
|
+--------v---------+
| apps/backend |
| (Hono server) |
+--------+---------+
|
+--------------+--------------+
| | |
+--------v---+ +------v------+ +----v-------+
| @doqtor/ | | @doqtor/ | | @doqtor/ |
| parser | | core-engine | | matcher |
| (ts-morph) | | (diff+drift)| | (doc scan) |
+--------+---+ +------+------+ +----+-------+
| | |
+--------------+--------------+
|
+--------v---------+
| @doqtor/fixer |
| (patch gen) |
+--------+---------+
|
+--------v---------+
| @doqtor/github |
| (PR creation) |
+------------------+
| Package | Description |
|---|---|
packages/parser | TypeScript AST parsing via ts-morph. Extracts functions, classes, interfaces, types. |
packages/core-engine | Shared types, unified diff analysis, drift detection with confidence scoring. |
packages/matcher | Maps changed symbols to documentation file references. |
packages/fixer | Generates doc patches. Supports deterministic and AI-assisted fixes. |
packages/github | GitHub App auth, webhook handling, branch/commit/PR creation. |
apps/backend | Hono webhook server with orchestration pipeline and queue. |
apps/cli | Commander.js CLI for local drift checking and fixing. |
Contributing
Prerequisites
- Bun v1.1+
- Git
Setup
$ git clone https://github.com/cachevector/doqtor.git
$ cd doqtor
$ bun install
$ bun run build
Common Commands
| Command | Description |
|---|---|
bun run dev | Watch mode for all packages |
bun run build | Build all packages |
bun run test | Run all tests |
bun run lint | Lint all packages |
bun run format | Format with Prettier |
bun run typecheck | Type check all packages |
Code Standards
- TypeScript strict mode, no
anytypes - Run
bun run lint:fixandbun run formatbefore committing - Use
import type { ... }for type-only imports - Prefer small, testable functions over large classes
- Unit tests required for all new logic
Commit Messages
Follow Conventional Commits:
feat: add parameter diffing to parser
fix: handle empty diff input in core-engine
docs: update CLI usage examples
test: add matcher edge case tests
chore: update dependencies
Workflow
- Create a branch from
master - Make your changes
- Write or update tests
- Ensure all checks pass:
bun run test && bun run lint && bun run typecheck - Submit a pull request