ドキュメントのgit履歴の配信と生成のためのスタンドアロンパッケージです。ローカル開発用のREST APIサーバーとCIビルド用のCLIバッチジェネレーターの2つのモードを持ちます。

## 概要

Doc History Serverは`packages/doc-history-server/`にあるサブパッケージで、[ドキュメント履歴](https://zudo-doc.takazudomodular.com/ja/docs/guides/doc-history)機能のすべてのgit履歴抽出を処理します。コストの高いgit操作をサイトビルドから分離するために、zfbビルドパイプラインから抽出されました。

2つのモードで動作します：

- **サーバーモード** -- ローカル開発時にHTTPサーバーを実行し、オンデマンドで履歴を配信
- **CLIモード** -- CIの本番ビルドですべての履歴JSONファイルをバッチ生成

この分離により、zfbサイトビルドとHistory生成を独立したジョブとして実行する並列CI戦略が可能になり、合計ビルド時間を短縮します。

## サーバーモード（ローカル開発）

サーバーは設定可能なポート（デフォルト4322）で実行され、REST API経由でドキュメント履歴を配信します。`docHistory`を有効にしてscaffoldしたプロジェクトでは、これは自動的に配線されます — `create-zudo-doc`は`dev`スクリプトとして`run-parallel dev:zfb dev:history`を生成するため、zfbとdoc-history-serverが同時に実行されます。`run-parallel`は`@takazudo/zudo-doc`が同梱する小さなbinなので、追加の開発依存は不要です。

### サーバーの起動

生成される`dev:history`スクリプト経由で実行してください — `doc-history-server`はプロジェクトの`node_modules/.bin`にのみ存在し、パッケージマネージャーのスクリプト経由では自動的に`PATH`に追加されますが、素のシェルプロンプトでは追加されません。

```sh
pnpm dev:history
# または: npm run dev:history
```

内部的には、このスクリプトは以下を実行しています。

```sh
doc-history-server --port 4322 --content-dir src/content/docs
```

追加ロケールを設定すると、`create-zudo-doc`は設定済みロケールごとに、順序を保った`--locale <lang>:src/content/docs-<lang>`フラグを1つずつ追加します。たとえば EN + JA + DE では `--locale ja:src/content/docs-ja --locale de:src/content/docs-de` が出力されます。別のフラグでサーバーを手動実行したい場合は、下記の[サーバーオプション](https://zudo-doc.takazudomodular.com/ja/docs/reference/doc-history-server#%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%83%A2%E3%83%BC%E3%83%89%EF%BC%88%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E9%96%8B%E7%99%BA%EF%BC%89-%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3)を参照してください。

### エンドポイント

#### GET /doc-history/\{slug\}.json

ドキュメントの完全なgit履歴を返します。

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

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

ローカライズされたドキュメントの履歴を返します。

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

#### GET /health

ヘルスチェックエンドポイント。

```json
{ "status": "ok" }
```

### サーバーオプション

| フラグ | 必須 | デフォルト | 説明 |
| ------ | ---- | ---------- | ---- |
| `--content-dir` | はい | -- | スキャンするコンテンツディレクトリ |
| `--locale <key>:<dir>` | いいえ | -- | 追加のロケールディレクトリ（繰り返し可） |
| `--port` | いいえ | `4322` | HTTPサーバーポート |
| `--max-entries` | いいえ | `50` | ドキュメントあたりの最大gitコミット数 |

### サーバーの動作

- ファイルインデックスは10秒ごとにリフレッシュされ、新しいファイルやリネームされたファイルを自動的に検出します
- クロスオリジン開発アクセス用のCORSヘッダーが含まれます
- 不明なスラッグへのリクエストは`{ "error": "No doc found for slug: ..." }`とともに404を返します

### zfbインテグレーション

開発モードでは、doc-historyのzfbプラグインの`devMiddleware`フックが`/doc-history/*`リクエストをこのサーバーにプロキシします。これにより、ブラウザの履歴パネルはzfb開発サーバーを通じてスタンドアロンサーバーから透過的に取得します。

`docHistory`が有効なプロジェクトが生成する`dev`スクリプト（`run-parallel dev:zfb dev:history`）は、zfb（ポート4321）とdoc-history-server（ポート4322）を同時に実行します。

## CLIモード（CIビルド）

CLIはすべてのドキュメントの静的JSONファイルを生成します。CIパイプライン向けです。

### 使い方

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

### CLIオプション

| フラグ | 必須 | デフォルト | 説明 |
| ------ | ---- | ---------- | ---- |
| `--content-dir` | はい | -- | スキャンするコンテンツディレクトリ |
| `--locale <key>:<dir>` | いいえ | -- | 追加のロケールディレクトリ（繰り返し可） |
| `--out-dir` | はい | -- | 生成されたJSONファイルの出力ディレクトリ |
| `--max-entries` | いいえ | `50` | ドキュメントあたりの最大gitコミット数 |

### CIパイプライン統合

CIパイプラインはzfbサイトビルドと並行して履歴生成を実行します：

- **build-site**ジョブ：フルクローン（`fetch-depth: 0`）、`pnpm build`でzfbサイトをビルド（`SKIP_DOC_HISTORY`なし — preBuildステップが`git log --follow`を実行して`.zfb/doc-history-meta.json`に実際の日付を書き込み、SSG HTMLに作成日・更新日・著者ブロックとしてインライン展開される）
- **build-history**ジョブ：フルクローン（`fetch-depth: 0`）、`@takazudo/zudo-doc-history-server generate`を実行
- **deploy**ジョブ：両方のアーティファクトをマージしてCloudflare Workersにデプロイ

この並列化は、履歴生成がzfbビルドから完全に独立しているため可能です。

[Dynamic content unavailable in text export]

`build-history`と`build-site`の両ジョブともフルクローン（`fetch-depth: 0`）が必要です。`build-history`はDocHistoryアイランドのドロップダウン用にリビジョンデータを抽出するため、`build-site`はpreBuildステップがSSGメタブロック（作成日・更新日・著者）に実際のgit日付を埋め込むために完全なコミット履歴が必要です。



[Dynamic content unavailable in text export]

`DOC_HISTORY_SKIP_POSTBUILD`（[デプロイガイド](https://zudo-doc.takazudomodular.com/ja/docs/guides/deployment)を参照）は、`build-site`内で実行されるzfbプラグインのインラインpostBuildフックのみを制御します — `build-history`ジョブが実際に実行するこのスタンドアロンの`generate` CLIには影響しません。このCLIは呼び出されると常に生成します。



## データ形式

### DocHistoryEntry

ドキュメントの単一のgitリビジョンエントリ：

```ts
interface DocHistoryEntry {
  /** 完全なコミットハッシュ（表示には.slice(0, 7)を使用） */
  hash: string;
  /** ISO 8601形式の日付文字列 */
  date: string;
  /** コミット著者名 */
  author: string;
  /** コミットメッセージの1行目 */
  message: string;
  /** このリビジョンでの完全なファイル内容 */
  content: string;
}
```

### DocHistoryData

単一ドキュメントの完全な履歴データ：

```ts
interface DocHistoryData {
  /** ドキュメントスラッグ（ルートパス） */
  slug: string;
  /** リポジトリ内の相対ファイルパス */
  filePath: string;
  /** gitリビジョンエントリ（新しい順） */
  entries: DocHistoryEntry[];
}
```

### 出力構造

生成されるファイルはコンテンツディレクトリ構造をミラーします：

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

## アーキテクチャ

### Git操作

履歴抽出は以下のノンブロッキングな`execFile` / `spawn`コールを使用します：

- `git log` -- `--follow`によるリネーム追跡を含むコミットリスト
- `git show` -- 各リビジョンでのファイル内容

`--follow`フラグは複数のフォールバック戦略によるリネーム追跡を行うため、移動やリネームされたドキュメントでも完全な履歴が保持されます。

### 主要な設計判断

- **単一の非同期抽出パス** -- 開発サーバーとCI CLIはいずれも`getDocHistoryAsync`をawaitします。CLIはセマフォで`Math.min(8, Math.max(2, cpus().length))`の同時ワーカー数に制限します。同期処理はキャッシュされる初回のリポジトリルート検出だけです
- **リポジトリ相対パス** -- APIレスポンスは絶対サーバーパスの漏洩を避けるために相対ファイルパスを使用します
- **スタンドアロンパッケージ** -- 並列CIビルドと独立したバージョニングを可能にするためにzfbから分離されています

## サブパッケージの場所

```
packages/doc-history-server/
├── src/
│   ├── index.ts        # サーバーエントリー — 引数解析、HTTPサーバー起動
│   ├── cli.ts          # CLIエントリー — 引数解析、JSONバッチ生成
│   ├── args.ts         # 境界チェック付き共有引数解析
│   ├── server.ts       # HTTPサーバー（REST APIエンドポイント）
│   ├── git-history.ts  # コアgitロジック（log、show、follow、リネーム追跡）
│   ├── shared.ts       # 共有ヘルパー（getContentDirEntries）
│   └── types.ts        # DocHistoryEntry、DocHistoryData型
├── package.json
├── tsconfig.json
└── README.md
```