# バッチ設計書 1-listen

## 概要

本ドキュメントは、clojure-lspのlistenコマンド（LSPサーバー起動機能）のバッチ設計を記載する。

### 本バッチの処理概要

clojure-lspをLanguage Server Protocol（LSP）サーバーとして起動し、標準入力（stdin）からのJSON-RPCメッセージをリッスンする機能を提供する。エディタやIDEとの通信を仲介し、Clojure/ClojureScript/ClojureDartプロジェクトに対するコード補完、定義ジャンプ、リファクタリング等のLSP機能を実現する。

**業務上の目的・背景**：開発者がVS Code、Emacs、Vim、IntelliJ IDEA等の各種エディタでClojureコードを編集する際に、リアルタイムでコード解析・補完・診断機能を提供するため。LSPプロトコルを採用することで、特定のエディタに依存せず、LSPをサポートする全てのエディタで統一的な開発体験を提供する。

**バッチの実行タイミング**：エディタ起動時にエディタのLSPクライアントによって自動的に起動される。手動実行も可能（引数なしでclojure-lspを実行）。

**主要な処理内容**：
1. Timbreロガーの初期化とログファイルの設定
2. JSON-RPC/LSPサーバーの起動（標準入出力使用）
3. クライアントからのinitializeリクエスト受信と初期化処理
4. clj-kondoによるプロジェクト解析の実行
5. 各種LSPリクエスト（completion、definition、references等）の非同期処理
6. 診断情報（diagnostics）のリアルタイム配信
7. ファイル変更の監視と増分解析

**前後の処理との関連**：このコマンドは他のバッチの前提条件ではなく、独立して動作する。CLIコマンド（clean-ns、diagnostics等）はこのサーバーを経由せず直接APIを呼び出す。

**影響範囲**：エディタとの通信全般。プロジェクト内の全Clojure/ClojureScript/ClojureDartファイルの解析データベース。

## バッチ種別

サーバープロセス / リアルタイム通信処理

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（エディタ起動時） |
| 実行時刻 | 該当なし |
| 実行曜日 | 該当なし |
| 実行日 | 該当なし |
| トリガー | エディタのLSPクライアント起動 / 手動実行 |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| Java/GraalVM | JVM版の場合はJava 11以上が必要。ネイティブ版では不要 |
| プロジェクト存在 | deps.edn/project.clj/shadow-cljs.edn等のプロジェクトファイルが存在すること |
| 標準入出力 | stdin/stdoutが利用可能であること |

### 実行可否判定

環境変数BABASHKA_PODがtrueの場合はpodモードで起動する。それ以外で引数なし、または"listen"引数の場合にサーバーモードで起動する。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| --trace-level | String | No | "off" | トレースログレベル（off/messages/verbose） |
| --log-path | String | No | 一時ファイル | ログファイルの出力パス |
| --settings | EDN | No | {} | LSP設定をEDN形式で指定 |
| --project-root | Path | No | カレントディレクトリ | プロジェクトルートパス |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| 標準入力（stdin） | JSON-RPC | LSPクライアントからのリクエスト/通知 |
| プロジェクトファイル | 各種 | deps.edn、project.clj、shadow-cljs.edn等 |
| .clj-kondo設定 | EDN | clj-kondoの解析設定 |
| .lsp/config.edn | EDN | clojure-lspのプロジェクト設定 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| 標準出力（stdout） | JSON-RPC | LSPレスポンス/通知 |
| ログファイル | テキスト | clojure-lsp.outログ |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | clojure-lsp.{uuid}.out |
| 出力先 | システム一時ディレクトリ（デフォルト） |
| 文字コード | UTF-8 |
| 区切り文字 | 該当なし |

## 処理フロー

### 処理シーケンス

```
1. CLIパース
   └─ コマンドライン引数の解析とオプション抽出
2. ロガー初期化
   └─ Timbreロガーのセットアップ、ログファイル作成
3. LSPサーバー起動
   └─ JSON-RPC IOサーバーの作成と標準入出力バインド
4. 非同期タスク起動
   └─ 診断、変更監視、編集のチャネル処理開始
5. initializeリクエスト待機
   └─ クライアントからのinitializeを受信
6. プロジェクト初期化
   └─ classpathの取得、clj-kondoによる解析、DBへの格納
7. メインループ
   └─ LSPリクエスト/通知の受信と処理を継続
8. shutdownリクエスト受信
   └─ リソースのクリーンアップ
9. exitによる終了
   └─ サーバープロセスの終了
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[CLI引数解析]
    B --> C[ロガー初期化]
    C --> D[LSPサーバー起動]
    D --> E[非同期タスク起動]
    E --> F{initializeリクエスト受信}
    F -->|受信| G[プロジェクト初期化]
    G --> H[initializedレスポンス送信]
    H --> I[LSPメインループ]
    I --> J{リクエスト/通知受信}
    J -->|処理| K[ハンドラー実行]
    K --> L[レスポンス送信]
    L --> I
    J -->|shutdown| M[クリーンアップ]
    M --> N[バッチ終了]
```

## データベース操作仕様

### 操作別データベース影響一覧

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 該当なし | - | - | 外部DBは使用しない（インメモリDB使用） |

### テーブル別操作詳細

本バッチは外部データベースを使用しない。内部的にAtom（db*）を使用してプロジェクト解析データ、設定、ドキュメント情報を管理する。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | 初期化エラー | clj-kondo解析失敗 | ログ確認、.clj-kondo設定見直し |
| 1 | 接続エラー | stdin/stdout切断 | エディタ再起動 |
| 1 | 設定エラー | 不正な設定ファイル | .lsp/config.edn修正 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 該当なし |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | リトライは行わない |

### 障害時対応

サーバーがクラッシュした場合、エディタのLSPクライアントが自動的に再起動を試みる。ログファイル（clojure-lsp.out）を確認し、エラー原因を特定する。

## トランザクション仕様

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | 該当なし（インメモリ処理） |
| コミットタイミング | 該当なし |
| ロールバック条件 | 該当なし |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | リクエスト数に依存（無制限） |
| 目標処理時間 | 各リクエスト応答: 100ms以内推奨 |
| メモリ使用量上限 | デフォルト3GB（-Xmx3g） |

## 排他制御

同一プロジェクトディレクトリで複数のclojure-lspインスタンスを起動可能だが、ポート競合（nREPL使用時）に注意が必要。LSPプロトコル上の排他制御はクライアント側で管理される。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 開始ログ | サーバー起動時 | "[server] Starting server..." |
| 初期化ログ | initialize時 | "Initializing..." |
| 進捗ログ | プロジェクト解析中 | 解析進捗（%） |
| 終了ログ | exit受信時 | 終了処理ログ |
| エラーログ | エラー発生時 | スタックトレース、エラーメッセージ |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 処理時間 | 設定なし | エディタUIに表示 |
| エラー件数 | 設定なし | エディタUIに表示 |

## 備考

- ネイティブイメージ（GraalVM）版はJVMより高速に起動する
- MUSL版（静的リンク）はスタックサイズの制約があり、別スレッドで実行される
- nREPLサーバーが利用可能な場合、開発用に自動起動される（ポートはdb*に格納）
- OTLPによるテレメトリログ出力をサポート
