Documentation
Gitian renders rich markdown from GitHub repos in the browser. This page covers every supported feature — from markdown rendering and code intelligence to navigation and project structure.
Customize Gitian behavior by adding a .gitian/config.yaml file to your repository root. All fields are optional — missing values use sensible defaults.
Complete example
annotations:
anchor: gitian
render_style: nested
tags:
todo:
kind: marker
color: "#f59e0b"
label: "To Do"
urgency: normal
groups: ""
pinned: false
api:
kind: inline
color: "#60a5fa"
label: API
urgency: normal
groups: api,global
pinned: false
discovery:
docs_dirs: docs,.docs
groups:
auth:
color: "#10b981"
label: Authentication
pinned: false
global:
color: "#3b82f6"
label: Global
pinned: true
files:
hide_source_only: false- -All fields are optional — omitted values fall back to built-in defaults
- -Repo config merges on top of defaults; only the keys you set are overridden
- -No config file required — everything works out of the box
annotations
Controls the annotation anchor, rendering style, and tag definitions.
annotations.anchor
default: gitian
The base name for the annotation trigger. The @ symbol is prepended automatically, so anchor: gitian matches @gitian in comments.
| Value | Description |
|---|---|
| <string> | An alphanumeric identifier (e.g. "gitian", "my-project"). The @ prefix is added automatically. |
annotations.render_style
default: nested
Controls how annotations are positioned relative to source code.
| Value | Description |
|---|---|
| nested | Annotations appear inline alongside code |
| separated | Annotations appear in a separate panel |
Built-in Tags
These tags are available out of the box. Override any field by redefining the tag in your config.
| Tag | Kind | Urgency | Color | Pinned |
|---|---|---|---|---|
| todo | marker | normal | #f59e0b | false |
| note | block | subtle | #22d3ee | false |
| warning | block | loud | #d97706 | false |
| deprecated | block | loud | #f43f5e | false |
| security | block | critical | #ef4444 | false |
| bug | block | loud | #fb7185 | true |
| perf | block | normal | #a78bfa | false |
discovery
Controls how Gitian discovers documentation directories in your repository.
discovery.docs_dirs
default: docs,.docs
Comma-separated list of directory basenames treated as documentation directories. Matched by basename at any depth in the repository tree.
| Value | Description |
|---|---|
| <comma-separated> | Basenames only — no slashes (e.g. docs,.docs,wiki). Setting this replaces the defaults |
groups
Groups organize annotations by domain. Assign annotations to groups via --group=name metadata or tag-level groups config.
groups.global
The built-in default group. Pinned to the dashboard by default. Override any field by redefining global in your config.
groups.global.color
default: #3b82f6
Accent color for the global group badge.
| Value | Description |
|---|---|
| #rrggbb | 6-digit hex color code |
groups.global.label
default: Global
Display name for the global group badge.
| Value | Description |
|---|---|
| <string> | Any string |
groups.global.pinned
default: true
Whether the global group surfaces on the repo dashboard.
| Value | Description |
|---|---|
| true | Group appears on the dashboard |
| false | Group only appears in the file viewer |
groups.<group_name>.color
default: #9ca3af
Accent color used for the group badge. Define custom groups by adding keys under groups in your config.
| Value | Description |
|---|---|
| #rrggbb | 6-digit hex color code (e.g. #10b981, #3b82f6) |
groups.<group_name>.label
default: <name>
Display name shown in the group badge. Falls back to the group name if omitted.
| Value | Description |
|---|---|
| <string> | Any string (e.g. Authentication, Billing) |
groups.<group_name>.pinned
default: false
Whether this group surfaces on the repo dashboard front page.
| Value | Description |
|---|---|
| true | Group appears on the dashboard |
| false | Group only appears in the file viewer |
files
files.hide_source_only
default: false
Hides files that have no paired documentation and no annotations from the sidebar tree.
| Value | Description |
|---|---|
| true | Only show files with docs or annotations |
| false | Show all files in the tree |
pr_analysis
Controls which stat plugins run when Gitian analyzes a pull request and posts a summary comment. All plugins are enabled by default — use the enabled field to restrict the set.
pr_analysis.enabled
default: (all plugins)
Explicit list of stat plugin IDs to run. When omitted, all built-in plugins are enabled. To disable a plugin, list only the IDs you want.
| Value | Description |
|---|---|
| <list> | YAML sequence of plugin IDs (e.g. summary-table, alert-tags). Omit to enable all. |
Available Plugins
Each plugin produces one section in the PR comment. All are enabled by default.
| ID | Description | Default |
|---|---|---|
| summary-table | Overview metrics — files changed, annotations added/removed | Enabled |
| annotation-diffs | Tables of added and removed annotations with tag, file, and description | Enabled |
| alert-tags | Prominent callout when security or bug annotations are added | Enabled |
| todo-trend | TODO/FIXME resolved vs. newly introduced count | Enabled |
| groups-affected | Which annotation groups the PR touches | Enabled |
| orphaned-docs | Warns when a doc file's source file is deleted by the PR | Enabled |
Example configuration
pr_analysis:
enabled:
- summary-table
- annotation-diffs
- alert-tags
- todo-trend
alert_tags:
- security
- bug
- deprecatedObsidian-flavored markdown with wikilinks, callouts, diagrams, math, and syntax highlighting.
Wikilinks
Navigate between documents using [[wikilink]] syntax. Links are resolved across the entire repository using shortest-path matching.
[[Page]] → link to Page.md
[[Page|Display Text]] → custom display text
[[Page#Heading]] → anchor to a heading
[[folder/Page]] → nested path
[[Page#Heading|Click me]] → all combined- -Resolved links render as clickable navigation within the repository
- -Unresolved links render with strikethrough styling
- -Resolution order: exact match → with .md → with .mdx → relative path → shortest path across all files
Callouts
All callout types are supported with proper icons, colors, and nesting.
> [!note] Title here
> Callout body text. Supports **markdown** inside.
> [!warning]+ Expanded by default
> Use + for expanded, - for collapsed.
> [!tip]- Collapsed by default
> Click to expand.| Type | Aliases | Color |
|---|---|---|
| note | info | Blue |
| tip | hint, important | Cyan |
| abstract | summary | Cyan |
| success | check, done | Green |
| question | faq | Yellow |
| warning | caution, attention | Orange |
| danger | error, bug | Red |
| example | — | Purple |
| quote | cite | Gray |
| todo | — | Blue |
Mermaid Diagrams
Flowcharts, sequence diagrams, ERDs, and all other Mermaid diagram types render inline. Powered by Mermaid 11 with DOMPurify sanitization.
```mermaid
graph TD
A[Write docs] --> B[Push to GitHub]
B --> C[Browse in Gitian]
```KaTeX Math
Inline and display math expressions render via KaTeX with full LaTeX support.
The equation $E = mc^2$ is well known.$$
\frac{-b \pm \sqrt{b^2 - 4ac}}{2a}
$$Code Highlighting
Fenced code blocks are syntax-highlighted using highlight.js with support for 100+ languages. Line numbers are included automatically.
```typescript
export function greet(name: string) {
return `Hello, ${name}!`;
}
```Frontmatter
YAML frontmatter at the top of markdown files is parsed and displayed as a banner above the content. Array values render as badge pills.
---
title: Authentication Module
tags: [auth, security, session]
status: stable
---
# Authentication
Content starts here...GitHub Flavored Markdown
Full GFM support via remark-gfm, including tables, strikethrough, autolinks, and task lists.
| Feature | Status |
|------------|--------|
| Wikilinks | ✓ |
| Callouts | ✓ |
~~strikethrough~~ and https://auto.link
- [x] Completed task
- [ ] Pending taskAnnotate source code with structured tags, metadata, groups, and embed them in your docs.
Annotations
Annotate your source code with @gitian or @gitian:<tag> to generate documentation blocks. The parser captures the description and (for most tags) the code block that follows.
Basic usage
// @gitian Validates user input before processing.
export function validateUser(input: UserInput) {
// ... function body is captured automatically
}/* @gitian
* Session manager — handles encrypted cookie storage
* and token refresh for authenticated GitHub sessions.
*/
export class SessionManager {
// ... class body is captured automatically
}# @gitian Request rate limiter using token bucket algorithm
def rate_limit(request):
# ... function body is captured by indentationTitle and body
When an annotation spans multiple comment lines, the first line becomes the collapsible title and remaining lines become the expanded body (rendered as markdown with wikilinks, formatting, etc.).
# @gitian:secret Home-manager secrets via sops-nix.
# Decrypts `secrets/<username>.yaml` at activation time using the user's age key.
# Secrets are exposed as files under `config.sops.secrets.<name>.path`.
# See [[secrets]] for the full encryption flow.- -Title: text on the same line as the tag — shown in the collapsible summary header
- -Body: subsequent comment lines — rendered as markdown when expanded (supports wikilinks, backtick code, etc.)
- -Single-line annotations have a title only — the collapsible body contains just the code block
Sub-tags
Use @gitian:<tag> for semantic categorization. Built-in tags get distinctive styling; unknown tags render with a neutral fallback.
// @gitian:todo Add rate limiting per IP address
// @gitian:warning This bypasses auth — only for internal use
// @gitian:deprecated Use createBatch() instead
// @gitian:security Sanitize input before rendering
// @gitian:bug Double-click fires handler twice
// @gitian:note Requires Node 18+ for crypto.randomUUID()
// @gitian:perf Consider memoizing for large listsBuilt-in tags
Defaults can be overridden via configuration.
| Tag | Color | Kind |
|---|---|---|
| @gitian | Primary | block |
| @gitian:todo | Amber | marker |
| @gitian:note | Cyan | block |
| @gitian:warning | Amber | block |
| @gitian:deprecated | Rose | block |
| @gitian:security | Red | block |
| @gitian:bug | Rose | block |
| @gitian:perf | Violet | block |
| @gitian:custom | Neutral | block |
- -Contiguous comment lines after the tag become the description (rendered as markdown)
- -Block tags (
@gitian,@gitian:note, etc.) capture the code block following the comment using brace-depth tracking or indentation - -Inline tags render as annotation cards with description only (no code capture)
- -Marker tags (
@gitian:todo) collect into a collapsible summary list with a count badge - -Unknown tags default to block kind with neutral gray styling
Doc Comment Detection
Enable detect_docs: true in your config to extract annotations from JSDoc block comments and triple-slash (///) comments. Recognized doc tags like @param, @returns, and @deprecated are surfaced as lightweight annotations with muted styling.
annotations:
detect_docs: trueSupported comment styles
/**
* Validates user input before processing.
* @param input - The raw user input
* @returns The validated result
* @throws {ValidationError} If input is malformed
*/
export function validateUser(input: UserInput) {
// ...
}/// Computes the shortest path between two nodes.
/// @param graph - The adjacency list
/// @param start - Starting node ID
/// @returns Array of node IDs forming the path
fn shortest_path(graph: &Graph, start: NodeId) -> Vec<NodeId> {
// ...
}Common tags
| Tag | Description |
|---|---|
| @param | Documents a function parameter |
| @returns | Documents the return value |
| @deprecated | Marks the symbol as deprecated |
| @throws | Documents exceptions the function may throw |
| @see | Cross-reference to related symbols or URLs |
| @example | Inline usage example |
| @since | Version when the symbol was introduced |
| @author | Author or maintainer of the symbol |
| @todo | Pending work within the doc comment |
| @type | Type annotation for the documented symbol |
- -Doc comment annotations render with muted styling to distinguish them from explicit @gitian annotations
- -No code capture — doc comments produce inline-style cards with description only
- -File-level docs can override detection via YAML front matter:
detect_docs: falsedisables doc comment extraction for that file - -Both
/** */JSDoc blocks and///triple-slash comments are supported
Keyword Detection
Enable detect_keywords: true in your config to surface bare TODO, FIXME, HACK, and other common keywords found in code comments. Each keyword maps to a built-in tag with appropriate kind and styling.
annotations:
detect_keywords: true// TODO: Add input validation
# FIXME: This breaks on empty arrays
/* HACK: Workaround for upstream bug */
-- NOTE: Requires PostgreSQL 15+Default keyword mappings
| Keyword | Maps to | Kind |
|---|---|---|
| TODO | todo | marker |
| FIXME | bug | block |
| HACK | warning | block |
| NOTE | note | block |
| WARNING | warning | block |
| BUG | bug | block |
| XXX | warning | block |
| OPTIMIZE | perf | block |
Custom keywords
annotations:
detect_keywords: true
keywords:
SAFETY: security
CLEANUP: todo
REFACTOR: note- -Keyword matching is case-insensitive — TODO, todo, and Todo all match
- -Keywords are only detected inside comment markers (
//,#,/* */,--) - -Each keyword annotation shows a badge with the original keyword text
- -No code capture — keyword annotations produce lightweight cards without embedded code blocks
- -File-level docs can override detection via YAML front matter:
detect_keywords: falsedisables keyword extraction for that file
Metadata
Add structured key-value metadata to annotations using --key=value lines immediately after the tag line. Metadata lines are consumed by the parser and do not appear in the rendered description.
Syntax
// @gitian:todo Add rate limiting per IP address
// --id=rate-limit-01
// --priority=high// @gitian:security Sanitize input before rendering
// --id=input-sanitize (security team review needed)
// --owner=backend-team (assigned Q2)/* @gitian Session encryption
* --id=session-enc
* --group=auth
* Handles encrypted cookie storage and token refresh.
*/- -Metadata lines must appear immediately after the tag line, before any description text
- -Format:
--key=value— keys must start with a letter and may contain letters, digits, and hyphens - -Values cannot contain spaces — everything after the first whitespace is ignored (treated as a comment)
- -The
--idkey is special: it provides a stable identifier for embedding annotations via directives - -Consecutive metadata lines are consumed; the first non-metadata line begins the description
Groups
Add groups to annotations to surface them beyond the file they live in. Groups enable cross-cutting views: a global group hoists annotations to the dashboard, and markdown files can pull in grouped annotations via frontmatter. Groups are assigned via --group= metadata or tag config defaults.
Syntax
// @gitian:security This endpoint has no rate limiting.
// --group=global,security
// Consider adding throttling before production release.# In .gitian/config.yaml:
# annotations:
# tags:
# security:
# groups: global,security
#
# Then all @gitian:security annotations automatically belong
# to the "global" and "security" groups — no --group= needed.// @gitian:note Works exactly as before — file-local only.- -
--group=namemetadata adds groups to individual annotations - -
annotations.tags.<name>.groupsin config sets default groups for all annotations using that tag - -Config groups and --group= metadata merge (deduplicated)
- -
globalis the only predefined group; all others are user-defined
Global group
Annotations in the global group appear in the dashboard annotations card under a dedicated “Global” section with a globe icon and file links.
Frontmatter group directive
Markdown files can aggregate grouped annotations using a group field in frontmatter. All matching annotations from across the repo are rendered between the frontmatter banner and the document content.
---
title: Auth Overview
group: auth,security
---
# Authentication
Content here. Grouped annotations from the codebase appear above.Group configuration
Customize group appearance in .gitian/config.yaml under the groups key.
groups:
auth:
color: "#10b981"
label: Authentication
global:
color: "#3b82f6"
label: Global- -
color— hex color for the group heading dot (default#9ca3af) - -
label— display name (defaults to the group name) - -The
globalgroup is predefined with blue (#3b82f6); all other groups are user-defined
Directives
Embed annotations directly in your markdown documentation using the {{type:argument}} directive syntax. Directives are resolved at render time and replaced with live annotation cards.
Syntax
| Directive | Resolves to |
|---|---|
| {{annotation:abc123}} | Single annotation by ID |
| {{annotation:#api}} | All annotations with group api |
| {{annotation:@todo}} | All annotations with tag todo |
Single annotation
Reference an annotation by its --id to embed it as a card with tag pill, description, file link, and code block.
# Authentication
This module handles user sessions.
{{annotation:session-enc}}
See the implementation above for details.Group embeds
Use # to embed all annotations that share a group. Cards render in a grouped container with a header and count.
# Security Overview
All security-related annotations across the codebase:
{{annotation:#security}}Tag groups
Use @ to embed all annotations that share a tag. Useful for surfacing all TODOs, warnings, or any custom tag in a single view.
# Open Items
{{annotation:@todo}}
# Known Issues
{{annotation:@bug}}Editor autocomplete
In the VS Code extension, typing {{ triggers a two-stage completion menu.
- -Stage 1: typing
{{offers available directive types (e.g.annotation:) - -Stage 2: typing
{{annotation:offers groups (#name), tags (@name), and individual annotations with descriptions and file locations - -Selecting an annotation with a generated ID automatically writes the stable --id to the source file
- -Groups and tags are sorted first since they match multiple annotations
Line Selection & Permalinks
Click any line number in the code viewer to select it and update the URL hash. Shift+click to extend the selection to a range. Right-click line numbers to open a context menu with copy actions.
URL hash format
#L42 → selects line 42
#L42-L50 → selects lines 42 through 50Context menu actions
| Action | Description |
|---|---|
| Copy link to line(s) | Copies the Gitian URL with #L42 or #L42-L50 hash |
| Copy GitHub permalink | Copies the GitHub blob URL for the same line(s). Hidden for local repos. |
| Copy line(s) | Copies the raw source text of the selected line(s) |
- -Clicking a line number highlights it and syncs the URL hash
- -Shift+clicking extends the selection to a range
- -Loading a URL with a line hash (e.g. #L42) scrolls to and highlights that line
- -Right-click context menu is available in both the code viewer and annotation code blocks
- -The GitHub permalink option is hidden for locally-loaded repositories
Provider Connections
Coming soonConnect to GitLab, Bitbucket, and self-hosted Git providers. Stay tuned.
Automatic docs discovery and file-doc pairing from your repository layout.
Docs Discovery
Gitian scans your repo for documentation directories and merges them into a single unified view. By default it looks for docs/ and .docs/, but this is configurable via discovery.docs_dirs.
my-project/
├── docs/ ← root docs directory
│ ├── README.md.md
│ ├── config.ts.md
│ └── src.md
├── src/
│ ├── auth.ts
│ └── utils.ts
├── examples/
│ └── docs/ ← nested docs directory
│ └── api.ts.md
└── README.md- -Configured docs directories at any level are discovered automatically
- -All discovered docs directories merge into a single file-doc mapping
- -Docs directories are hidden from the sidebar file tree
- -Rich markdown (wikilinks, callouts, etc.) is fully supported in doc files
File-Doc Pairing
Source files are automatically paired with markdown companions inside your configured docs directories by matching filenames.
Source file → Doc file
auth.ts → docs/auth.ts.md
Button.tsx → docs/Button.tsx.md
examples/ → docs/examples.md (directory doc)
Nested docs dirs work relative to their parent:
src/lib/auth.ts → src/lib/docs/auth.ts.md- -Paired files show a tabbed UI — Docs tab with rendered markdown and Source tab with syntax-highlighted code
- -Directory-level docs use the directory name (e.g. examples.md for the examples/ folder)
- -Docs support wikilinks, callouts, math, diagrams, and more
See it in action
Browse the demo repo to see all these features rendered live — wikilinks, callouts, annotations, line permalinks, and more.
Open demo