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.

Configuration

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

.gitian/config.yaml
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.

ValueDescription
<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.

ValueDescription
nestedAnnotations appear inline alongside code
separatedAnnotations appear in a separate panel

annotations.tags.<tag_name>.kind

default: block

Controls the shape and code-capture behavior of the annotation. Each key under annotations.tags creates a tag triggered by @gitian:<name> in comments.

ValueDescription
markerNo code capture — grouped into a collapsible summary list
inlineNo code capture — foldable annotation card with description only
blockCaptures following code — foldable card with embedded code block

annotations.tags.<tag_name>.color

default: #9ca3af

Accent color used for the tag pill, border, and tinted backgrounds.

ValueDescription
#rrggbb6-digit hex color code (e.g. #f59e0b, #22d3ee, #ef4444)

annotations.tags.<tag_name>.label

default: <name>

Display name shown in the annotation pill. Falls back to the tag name if omitted.

ValueDescription
<string>Any string (e.g. To Do, API, Performance)

annotations.tags.<tag_name>.urgency

default: normal

Controls visual prominence — how aggressively an annotation demands attention. Orthogonal to kind (which controls shape).

ValueDescription
subtleThin border, text-only pill, muted title — for FYI notes and minor context
normalStandard border, outlined pill — for general documentation
loudTinted background, filled pill, bold text — for warnings and deprecations
criticalThick border, solid pill, alert icon — for security issues and critical bugs

annotations.tags.<tag_name>.groups

default: (none)

Default groups this tag belongs to. Annotations with this tag are automatically added to these groups, merged with per-annotation --group= metadata.

ValueDescription
<comma-separated>Comma-separated group names (e.g. auth,global)

annotations.tags.<tag_name>.pinned

default: false

Whether annotations with this tag surface on the repo dashboard front page.

ValueDescription
trueAnnotations appear on the dashboard
falseAnnotations only appear in the file viewer

Built-in Tags

These tags are available out of the box. Override any field by redefining the tag in your config.

TagKindUrgencyColorPinned
todomarkernormal #f59e0bfalse
noteblocksubtle #22d3eefalse
warningblockloud #d97706false
deprecatedblockloud #f43f5efalse
securityblockcritical #ef4444false
bugblockloud #fb7185true
perfblocknormal #a78bfafalse

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.

ValueDescription
<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.

ValueDescription
#rrggbb6-digit hex color code

groups.global.label

default: Global

Display name for the global group badge.

ValueDescription
<string>Any string

groups.global.pinned

default: true

Whether the global group surfaces on the repo dashboard.

ValueDescription
trueGroup appears on the dashboard
falseGroup 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.

ValueDescription
#rrggbb6-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.

ValueDescription
<string>Any string (e.g. Authentication, Billing)

groups.<group_name>.pinned

default: false

Whether this group surfaces on the repo dashboard front page.

ValueDescription
trueGroup appears on the dashboard
falseGroup 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.

ValueDescription
trueOnly show files with docs or annotations
falseShow 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.

ValueDescription
<list>YAML sequence of plugin IDs (e.g. summary-table, alert-tags). Omit to enable all.

pr_analysis.alert_tags

default: security, bug

Annotation tags that trigger a prominent alert callout in the PR comment when added or modified. Defaults to security and bug.

ValueDescription
<list>YAML sequence of tag names (e.g. security, bug, deprecated)

Available Plugins

Each plugin produces one section in the PR comment. All are enabled by default.

IDDescriptionDefault
summary-tableOverview metrics — files changed, annotations added/removedEnabled
annotation-diffsTables of added and removed annotations with tag, file, and descriptionEnabled
alert-tagsProminent callout when security or bug annotations are addedEnabled
todo-trendTODO/FIXME resolved vs. newly introduced countEnabled
groups-affectedWhich annotation groups the PR touchesEnabled
orphaned-docsWarns when a doc file's source file is deleted by the PREnabled

Example configuration

.gitian/config.yaml
pr_analysis:
  enabled:
    - summary-table
    - annotation-diffs
    - alert-tags
    - todo-trend
  alert_tags:
    - security
    - bug
    - deprecated
Markdown Rendering

Obsidian-flavored markdown with wikilinks, callouts, diagrams, math, and syntax highlighting.

Callouts

All callout types are supported with proper icons, colors, and nesting.

Syntax
> [!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.
TypeAliasesColor
noteinfo Blue
tiphint, important Cyan
abstractsummary Cyan
successcheck, done Green
questionfaq Yellow
warningcaution, attention Orange
dangererror, bug Red
example Purple
quotecite Gray
todo Blue

Mermaid Diagrams

Flowcharts, sequence diagrams, ERDs, and all other Mermaid diagram types render inline. Powered by Mermaid 11 with DOMPurify sanitization.

Syntax
```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.

Inline math
The equation $E = mc^2$ is well known.
Display math
$$
\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.

Syntax
```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.

Syntax
---
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.

Examples
| Feature    | Status |
|------------|--------|
| Wikilinks  | ✓      |
| Callouts   | ✓      |

~~strikethrough~~ and https://auto.link

- [x] Completed task
- [ ] Pending task
Code Intelligence

Annotate 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

Plain @gitian — captures code
// @gitian Validates user input before processing.
export function validateUser(input: UserInput) {
  // ... function body is captured automatically
}
Block comment
/* @gitian
 * Session manager — handles encrypted cookie storage
 * and token refresh for authenticated GitHub sessions.
 */
export class SessionManager {
  // ... class body is captured automatically
}
Hash comment (Python, YAML, Shell)
# @gitian Request rate limiter using token bucket algorithm
def rate_limit(request):
    # ... function body is captured by indentation

Title 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.).

Multi-line annotation with title + body
# @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.

Examples
// @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 lists

Built-in tags

Defaults can be overridden via configuration.

TagColorKind
@gitian Primaryblock
@gitian:todo Ambermarker
@gitian:note Cyanblock
@gitian:warning Amberblock
@gitian:deprecated Roseblock
@gitian:security Redblock
@gitian:bug Roseblock
@gitian:perf Violetblock
@gitian:custom Neutralblock
  • -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.

.gitian/config.yaml
annotations:
  detect_docs: true

Supported comment styles

JSDoc block comment
/**
 * 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) {
  // ...
}
Triple-slash comment
/// 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

TagDescription
@paramDocuments a function parameter
@returnsDocuments the return value
@deprecatedMarks the symbol as deprecated
@throwsDocuments exceptions the function may throw
@seeCross-reference to related symbols or URLs
@exampleInline usage example
@sinceVersion when the symbol was introduced
@authorAuthor or maintainer of the symbol
@todoPending work within the doc comment
@typeType 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: false disables 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.

.gitian/config.yaml
annotations:
  detect_keywords: true
Keywords in different comment styles
// TODO: Add input validation
# FIXME: This breaks on empty arrays
/* HACK: Workaround for upstream bug */
-- NOTE: Requires PostgreSQL 15+

Default keyword mappings

KeywordMaps toKind
TODOtodomarker
FIXMEbugblock
HACKwarningblock
NOTEnoteblock
WARNINGwarningblock
BUGbugblock
XXXwarningblock
OPTIMIZEperfblock

Custom keywords

.gitian/config.yaml
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: false disables 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

Basic metadata
// @gitian:todo Add rate limiting per IP address
// --id=rate-limit-01
// --priority=high
Trailing comments are ignored
// @gitian:security Sanitize input before rendering
// --id=input-sanitize (security team review needed)
// --owner=backend-team (assigned Q2)
Block comment style
/* @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 --id key 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

--group= metadata
// @gitian:security This endpoint has no rate limiting.
// --group=global,security
// Consider adding throttling before production release.
Config-driven groups
# 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.
No groups (default)
// @gitian:note Works exactly as before — file-local only.
  • ---group=name metadata adds groups to individual annotations
  • -annotations.tags.<name>.groups in config sets default groups for all annotations using that tag
  • -Config groups and --group= metadata merge (deduplicated)
  • -global is 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.

Example frontmatter
---
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.

.gitian/config.yaml
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 global group 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

DirectiveResolves 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.

Embed by ID
# 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.

Embed by group
# 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.

Embed by tag
# 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
Code Navigation

Select lines, copy permalinks, and connect to external Git providers.

Provider Connections

Coming soonConnect to GitLab, Bitbucket, and self-hosted Git providers. Stay tuned.

Project Structure

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.

Repository structure
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.

Naming convention
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