# 帳票設計書 1-Session Export (JSON)

## 概要

本ドキュメントは、opencode CLIの `export` コマンドによるセッションデータのJSON形式エクスポート機能の設計書である。

### 本帳票の処理概要

本帳票は、opencodeのセッション情報とメッセージ履歴をJSON形式で出力するCLIコマンドによるエクスポート機能を提供する。

**業務上の目的・背景**：AIコーディングアシスタントとの対話セッションを永続化・バックアップするために必要である。セッションデータを外部ツールで分析したり、チーム間で共有したり、トラブルシューティングのための詳細なログ取得を可能にする。また、セッションの移行やアーカイブ作業においても重要な役割を果たす。

**帳票の利用シーン**：開発者がセッションの完全なバックアップを取得したい場合、セッションデータを他のシステムに連携したい場合、または過去の対話履歴を詳細に分析したい場合に利用される。特に、長期間にわたるプロジェクトでのセッション管理や、複数の開発者間でのセッション共有時に活用される。

**主要な出力内容**：
1. セッション基本情報（ID、タイトル、作成日時、更新日時、プロジェクトID等）
2. メッセージ履歴（ユーザーメッセージとアシスタントメッセージの時系列リスト）
3. 各メッセージのパーツ情報（テキスト、ツール呼び出し、推論内容等）
4. セッションメタデータ（バージョン、共有URL等）

**帳票の出力タイミング**：CLIから `opencode export [sessionID]` コマンドを実行した時に出力される。sessionIDを省略した場合は、対話形式でセッション選択が行われる。

**帳票の利用者**：開発者、DevOpsエンジニア、テクニカルサポート担当者、データ分析担当者

## 帳票種別

エクスポートデータ / データ出力

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | CLI | `opencode export [sessionID]` | コマンド実行 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | JSON |
| 用紙サイズ | 該当なし（標準出力） |
| 向き | 該当なし |
| ファイル名 | 該当なし（標準出力へ出力、リダイレクトで任意のファイル名に保存可能） |
| 出力方法 | 標準出力（stdout） |
| 文字コード | UTF-8 |

### JSON構造

```json
{
  "info": {
    "id": "session_xxx",
    "slug": "xxx",
    "projectID": "xxx",
    "directory": "/path/to/project",
    "title": "セッションタイトル",
    "version": "x.x.x",
    "time": {
      "created": 1234567890,
      "updated": 1234567890
    }
  },
  "messages": [
    {
      "info": { /* MessageInfo */ },
      "parts": [ /* Part[] */ ]
    }
  ]
}
```

## 帳票レイアウト

### レイアウト概要

JSON形式のため、階層構造でデータを表現する。

```
┌─────────────────────────────────────┐
│              info                   │
│  (セッション基本情報)                 │
├─────────────────────────────────────┤
│              messages               │
│  (メッセージ配列)                    │
│    ├─ info (メッセージ情報)          │
│    └─ parts (パーツ配列)             │
└─────────────────────────────────────┘
```

### info部（セッション情報）

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | id | セッションID | SessionTable.id | 文字列 |
| 2 | slug | セッションスラッグ | SessionTable.slug | 文字列 |
| 3 | projectID | プロジェクトID | SessionTable.project_id | 文字列 |
| 4 | directory | ディレクトリパス | SessionTable.directory | 文字列 |
| 5 | title | セッションタイトル | SessionTable.title | 文字列 |
| 6 | version | バージョン | SessionTable.version | 文字列 |
| 7 | time.created | 作成日時 | SessionTable.time_created | UNIXタイムスタンプ（ミリ秒） |
| 8 | time.updated | 更新日時 | SessionTable.time_updated | UNIXタイムスタンプ（ミリ秒） |

### messages部（メッセージ配列）

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | info | メッセージ情報 | MessageTable.data | オブジェクト |
| 2 | parts | パーツ配列 | PartTable.data | 配列 |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| sessionID | エクスポート対象のセッションID | Yes（指定なしの場合は対話選択） |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | message.id | 昇順（時系列順） |

### 改ページ条件

該当なし（JSON出力のため）

## データベース参照仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| session | セッション基本情報 | PRIMARY KEY (id) |
| message | メッセージ情報 | session_id = session.id |
| part | パーツ情報 | message_id = message.id |

### テーブル別参照項目詳細

#### session

| 参照項目（カラム名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| id | info.id | id = 指定sessionID | - |
| slug | info.slug | - | - |
| project_id | info.projectID | - | - |
| directory | info.directory | - | - |
| title | info.title | - | - |
| version | info.version | - | - |
| time_created | info.time.created | - | - |
| time_updated | info.time.updated | - | - |

#### message

| 参照項目（カラム名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| id | messages[].info.id | session_id = 指定sessionID | - |
| data | messages[].info | - | JSON形式で格納 |

#### part

| 参照項目（カラム名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| id | messages[].parts[].id | message_id = message.id | - |
| data | messages[].parts[] | - | JSON形式で格納 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| - | - | - | 計算項目なし |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[export コマンド実行] --> B{sessionID指定あり?}
    B -->|Yes| D[Session.get でセッション取得]
    B -->|No| C[Session.list でセッション一覧取得]
    C --> C2[ユーザーがセッション選択]
    C2 --> D
    D --> E{セッション存在?}
    E -->|Yes| F[Session.messages でメッセージ取得]
    E -->|No| G[エラー出力・終了]
    F --> H[exportData オブジェクト構築]
    H --> I[JSON.stringify で文字列化]
    I --> J[標準出力に出力]
    J --> K[終了]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| セッションなし | 指定されたsessionIDが存在しない | `Session not found: {sessionID}` | 正しいsessionIDを指定 |
| セッション一覧空 | 対話選択時にセッションが0件 | `No sessions found` | セッションを作成してから実行 |
| キャンセル | ユーザーが対話選択をキャンセル | - | 再実行 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 1セッションあたり最大数千メッセージ |
| 目標出力時間 | 数秒以内 |
| 同時出力数上限 | 1（CLIコマンドのため） |

## セキュリティ考慮事項

- セッションデータには機密情報（コード、APIキーなど）が含まれる可能性があるため、出力先の管理に注意が必要
- 標準出力への出力のため、リダイレクト先ファイルのパーミッション設定を適切に行う必要がある
- 共有時は機密情報のマスキングを検討する

## 備考

- メッセージ出力は `process.stderr` に出力され、JSON本体は `process.stdout` に出力されるため、パイプライン処理が可能
- 出力JSONは整形（2スペースインデント）されて出力される
- 大規模セッションの場合、メモリ使用量に注意が必要

---

## コードリーディングガイド

本帳票を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、エクスポートされるデータの構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | session.sql.ts | `packages/opencode/src/session/session.sql.ts` | SessionTable、MessageTable、PartTableのスキーマ定義を確認 |
| 1-2 | index.ts | `packages/opencode/src/session/index.ts` | Session.Info型定義（116-157行）、fromRow関数（50-81行）でDBからの変換を理解 |

**読解のコツ**: TypeScriptの型定義とDrizzle ORMのテーブル定義を対照しながら読むとデータ構造が明確になる。

#### Step 2: エントリーポイントを理解する

処理の起点となるCLIコマンドを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | export.ts | `packages/opencode/src/cli/cmd/export.ts` | ExportCommandの定義、handler関数が処理の起点 |

**主要処理フロー**:
1. **9-17行**: コマンド定義とsessionIDパラメータの設定
2. **18-66行**: sessionIDの有無による分岐処理
3. **68-85行**: セッション取得とエクスポートデータ構築

#### Step 3: セッションデータ取得処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.ts | `packages/opencode/src/session/index.ts` | Session.get関数（335-339行）、Session.messages関数（512-526行）の実装 |

**主要処理フロー**:
- **335-339行**: IDによるセッション取得
- **512-526行**: MessageV2.streamを使用したメッセージ一覧取得

### プログラム呼び出し階層図

```
ExportCommand.handler (export.ts:18)
    │
    ├─ bootstrap() - 初期化処理
    │
    ├─ Session.list() - セッション一覧取得（対話選択時）
    │      └─ Database.use() - DB操作
    │
    ├─ prompts.autocomplete() - 対話選択UI
    │
    ├─ Session.get(sessionID) - セッション情報取得
    │      └─ Database.use() → SessionTable SELECT
    │
    ├─ Session.messages({sessionID}) - メッセージ取得
    │      └─ MessageV2.stream() → MessageTable/PartTable SELECT
    │
    └─ JSON.stringify() → process.stdout.write() - 出力
```

### データフロー図

```
[入力]                    [処理]                         [出力]

sessionID ────────▶ Session.get() ─────▶ sessionInfo
(CLI引数)                    │
                            ▼
                    Session.messages() ──▶ messages[]
                            │
                            ▼
                    exportData構築 ───────▶ JSON文字列 ──▶ stdout
                    {info, messages}
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| export.ts | `packages/opencode/src/cli/cmd/export.ts` | ソース | CLIコマンド定義・メイン処理 |
| index.ts | `packages/opencode/src/session/index.ts` | ソース | Session名前空間・データ操作 |
| session.sql.ts | `packages/opencode/src/session/session.sql.ts` | ソース | テーブルスキーマ定義 |
| message-v2.ts | `packages/opencode/src/session/message-v2.ts` | ソース | メッセージ型定義・ストリーム処理 |
| cmd.ts | `packages/opencode/src/cli/cmd/cmd.ts` | ソース | コマンド定義ヘルパー |
| bootstrap.ts | `packages/opencode/src/cli/bootstrap.ts` | ソース | CLI初期化処理 |
