zudo-doc
GitHub repository

Type to search...

to open search from anywhere

Doc History Server

Created Mar 25, 2026Updated Jun 7, 2026Takeshi Takatsudo

Standalone package for serving and generating document git history, with dual modes: REST API server for local development and CLI batch generator for CI builds.

Overview

The Doc History Server is a sub-package at packages/doc-history-server/ that handles all git history extraction for the Document History feature. It was extracted from the zfb build pipeline to decouple expensive git operations from the site build.

It operates in two modes:

  • Server mode -- runs an HTTP server during local development, serving history on demand

  • CLI mode -- batch-generates all history JSON files for production builds in CI

This separation enables a parallel CI strategy where the zfb site build and history generation run as independent jobs, reducing total build time.

Server Mode (Local Development)

The server runs on a configurable port (default 4322) and serves document history via a REST API. In the standard pnpm dev setup, zfb and the doc-history-server run concurrently via run-p.

Starting the Server

pnpm dev -- --content-dir src/content/docs --locale ja:src/content/docs-ja --port 4322

Endpoints

GET /doc-history/{slug}.json

Returns the full git history for a document.

GET /doc-history/guides/writing-docs.json

GET /doc-history/{locale}/{slug}.json

Returns history for a localized document.

GET /doc-history/ja/guides/writing-docs.json

GET /health

Health check endpoint.

{ "status": "ok" }

Server Options

FlagRequiredDefaultDescription
--content-dirYes--Content directory to scan for documents
--locale <key>:<dir>No--Additional locale directory (repeatable)
--portNo4322HTTP server port
--max-entriesNo50Maximum git commits per document

Server Behavior

  • File index refreshes every 10 seconds, automatically picking up new or renamed files

  • CORS headers are included for cross-origin dev access

  • Requests for unknown slugs return 404 with { "error": "No doc found for slug: ..." }

zfb Integration

In dev mode, the doc-history zfb plugin's devMiddleware hook proxies /doc-history/* requests to this server. This means the history panel in the browser transparently fetches from the standalone server through the zfb dev server.

The root pnpm dev command runs both zfb (port 4321) and the doc-history-server (port 4322) concurrently using run-p.

CLI Mode (CI Builds)

The CLI generates static JSON files for all documents, intended for CI pipelines.

Usage

pnpm generate -- --content-dir src/content/docs --locale ja:src/content/docs-ja --out-dir dist/doc-history

CLI Options

FlagRequiredDefaultDescription
--content-dirYes--Content directory to scan
--locale <key>:<dir>No--Additional locale directory (repeatable)
--out-dirYes--Output directory for generated JSON files
--max-entriesNo50Maximum git commits per document

CI Pipeline Integration

The CI pipeline runs history generation as a parallel job alongside the zfb site build:

  • build-site job: full clone (fetch-depth: 0), builds the zfb site with pnpm build (no SKIP_DOC_HISTORY — the preBuild step runs git log --follow to populate .zfb/doc-history-meta.json with real dates, inlined into the SSG HTML as the visible Created/Updated/Author block)

  • build-history job: full clone (fetch-depth: 0), runs @takazudo/zudo-doc-history-server generate

  • deploy job: merges both artifacts and deploys to Cloudflare Workers

This parallelization is possible because the history generation is fully independent of the zfb build.

Tip

Both the build-history and build-site jobs require a full clone (fetch-depth: 0). build-history needs the complete commit history to extract revision data for the DocHistory island dropdown. build-site needs it so the preBuild step can populate the SSG meta block (Created/Updated/Author) with real git dates.

Data Format

DocHistoryEntry

A single git revision entry for a document:

interface DocHistoryEntry {
  /** Full commit hash (use .slice(0, 7) for display) */
  hash: string;
  /** ISO 8601 date string */
  date: string;
  /** Commit author name */
  author: string;
  /** First line of commit message */
  message: string;
  /** Full file content at this revision */
  content: string;
}

DocHistoryData

Complete history data for a single document:

interface DocHistoryData {
  /** Document slug (route path) */
  slug: string;
  /** Relative file path in the repository */
  filePath: string;
  /** Git revision entries, newest first */
  entries: DocHistoryEntry[];
}

Output Structure

Generated files mirror the content directory structure:

dist/doc-history/
  getting-started.json
  guides/writing-docs.json
  guides/color.json
  ja/getting-started.json
  ja/guides/writing-docs.json

Architecture

Git Operations

History extraction uses synchronous git calls (execFileSync) for:

  • git log -- commit listing with --follow for rename tracking

  • git show -- file content at each revision

The --follow flag tracks file history across renames with multiple fallback strategies, so documents that have been moved or renamed retain their complete history.

Key Design Decisions

  • Synchronous git -- execFileSync is acceptable for the dev server (same-process, sequential). The CI CLI uses bounded parallelism: tasks run via Promise.all with a semaphore limited to Math.min(8, Math.max(2, cpus().length)) concurrent workers

  • Repo-relative paths -- API responses use relative file paths to avoid leaking absolute server paths

  • Standalone package -- decoupled from zfb to enable parallel CI builds and independent versioning

Sub-Package Location

packages/doc-history-server/
├── src/
│   ├── index.ts        # Server entry — parses args, starts HTTP server
│   ├── cli.ts          # CLI entry — parses args, batch generates JSONs
│   ├── args.ts         # Shared argument parsing with bounds checking
│   ├── server.ts       # HTTP server (REST API endpoints)
│   ├── git-history.ts  # Core git logic (log, show, follow, rename tracking)
│   ├── shared.ts       # Shared helpers (getContentDirEntries)
│   └── types.ts        # DocHistoryEntry, DocHistoryData types
├── package.json
├── tsconfig.json
└── README.md

Revision History

Takeshi TakatsudoCreated: 2026-03-25T23:13:29+09:00Updated: 2026-06-07T16:23:39+09:00

AI Assistant

Ask a question about the documentation.