Skip to content

[Feature] チーム共有設定ファイル(config.toml) #76

@Kewton

Description

@Kewton

概要

チームで共有可能な設定ファイル commandindex.toml をリポジトリルートに配置し、インデックス設定やEmbeddingプロバイダー設定をチーム全体で統一できるようにする。

背景・動機

現在の設定は .commandindex/ 内に閉じており、.gitignore で除外されるためチーム共有ができない。チームで同じ設定(除外パターン、Embeddingモデル、検索デフォルト等)を使いたい場合に、各メンバーが個別に設定する必要がある。

提案する解決策

設定ファイルの優先順位

1. 環境変数 (COMMANDINDEX_*)        ← 最優先(個人オーバーライド)
2. .commandindex/config.local.toml  ← ローカル個人設定(.gitignore対象)
3. commandindex.toml                ← リポジトリルート(チーム共有、Git管理)
4. .commandindex/config.toml        ← 旧設定(deprecated fallback、警告付き)
5. デフォルト値                      ← フォールバック

マージ仕様

  • フィールドレベルマージ: 各設定フィールド単位で上位優先度の値が下位を上書きする(セクション単位ではない)
  • 上位ソースで未指定(Option::None)のフィールドは、下位ソースの値を維持する

マージ例:

# commandindex.toml(チーム共有)
[embedding]
provider = "ollama"
model = "nomic-embed-text"
endpoint = "http://localhost:11434"

# .commandindex/config.local.toml(個人設定)
[embedding]
endpoint = "http://my-server:11434"

# → 有効設定: provider="ollama", model="nomic-embed-text", endpoint="http://my-server:11434"

環境変数オーバーライド

Phase 1 では以下の環境変数のみサポート(既存互換):

  • COMMANDINDEX_OPENAI_API_KEY: OpenAI APIキーの上書き

将来的に COMMANDINDEX_EMBEDDING_PROVIDER, COMMANDINDEX_EMBEDDING_MODEL 等の網羅的な環境変数対応は別Issueで対応予定。

設定ファイルフォーマット

# commandindex.toml(チーム共有)

[index]
# 対象言語の優先設定(※Phase 1 では設定の読み込みのみ。インデクサーへの反映は別Issue)
languages = ["markdown", "typescript", "python"]

[search]
# デフォルトの検索結果件数(CLI引数が明示指定された場合はCLI引数を優先)
default_limit = 20
# デフォルトのスニペット行数
snippet_lines = 2
snippet_chars = 120

[embedding]
# チーム統一のEmbeddingプロバイダー
provider = "ollama"
model = "nomic-embed-text"
endpoint = "http://localhost:11434"

[rerank]
provider = "ollama"
model = "bge-reranker-v2-m3"

CLI連携

# 現在の有効設定を表示(TOML形式、秘匿値はマスク表示)
commandindex config show

# 読み込まれた設定ファイルのパスを優先順位順に表示(存在するもののみ)
# 旧 .commandindex/config.toml が存在する場合は [deprecated] 注記付きで表示
commandindex config path

: --format オプション(json/human)は Phase 1 ではスコープ外。TOML形式のみサポート。

CLI引数と設定ファイルの優先関係

CLI引数(明示指定時) > 環境変数 > config.local.toml > commandindex.toml > 旧config.toml(deprecated) > デフォルト値
  • CLI引数が明示的に指定された場合はCLI引数を優先
  • CLI引数が未指定(デフォルト値)の場合は設定ファイルの値を使用
  • 対象: --limit, --snippet-lines, --snippet-chars 等の検索関連引数
  • 実装方針: clap の default_value_t を使わず Option<usize> にし、None の場合に config → ハードコードデフォルトの順でフォールバック

設定ファイルの検出方法

  • --path 引数を持つコマンド(index, update, embed, clean): --path で指定されたディレクトリをベースパスとして使用
  • --path 引数を持たないコマンド(search, config): カレントディレクトリをベースパスとして使用
  • commandindex.toml{base_path}/commandindex.toml から読み込み
  • .commandindex/config.local.toml{base_path}/.commandindex/config.local.toml から読み込み

既存設定ファイルからの移行

  • 既存の .commandindex/config.tomldeprecated fallback として読み込みを維持
  • .commandindex/config.toml が存在する場合は 警告メッセージを stderr に出力(deprecated fallback を実際に使用した場合のみ1回)
  • 警告出力条件:
    • 旧設定のみ存在: 読み込んで警告「commandindex.toml への移行を推奨」
    • 新旧両方存在: 新設定を優先し、旧設定は無視。警告「旧設定は無視されています」
  • 優先順位: commandindex.toml > .commandindex/config.toml(旧ファイルは最低優先)
  • clean.rs のハードコード参照を更新:
    • .commandindex/ 配下の保持対象: config.local.toml, config.toml(旧)
    • ルートの commandindex.toml.commandindex/ 外なので clean の対象外
  • これは breaking change ではない: 旧ファイルは引き続き読み込まれるため既存ユーザーの動作は維持される

実装方針

  1. config モジュール新規作成src/config/mod.rs

    • 全設定セクション(index, search, embedding, rerank)を統合管理する AppConfig 構造体を定義
    • マージ用の中間構造体(全フィールド Option<T>)で設定ソースを読み込み、フィールドレベルマージを実施
    • 専用エラー型 ConfigError enum を定義
    • EmbeddingConfig, RerankConfig は現在のモジュール(embedding/rerank)に型定義を残し、AppConfig から参照する設計(循環依存を回避)
    • 設定ファイル名を定数化: TEAM_CONFIG_FILE, LOCAL_CONFIG_FILE, LEGACY_CONFIG_FILE
    • config を唯一の設定読込入口にする原則を適用
  2. 既存 embedding::Config の移行

    • embedding::Config および embedding::EmbeddingConfig の設定読み込みロジックを config モジュールに移行
    • embedding::Config は削除し、全呼び出し箇所を config::AppConfig に更新
    • 対象箇所: cli/search.rs(4箇所)、cli/embed.rs(1箇所)、cli/index.rs(1箇所)
    • clean.rs の config.toml ハードコード参照も更新(LOCAL_CONFIG_FILE, LEGACY_CONFIG_FILE を保持対象に)
  3. Serialize 対応と config show 用 view model

    • EmbeddingConfig, RerankConfigSerialize derive を追加
    • config show 用のマスク済み表示構造体(view model)を別途用意
    • 秘匿値(api_key 等)はマスク表示(***)を保証
  4. toml crate でパース(既にCargo.tomlに toml = "0.8" 依存済み)

  5. CLIサブコマンド追加

    • config show / config path サブコマンドを src/cli/config.rs に実装
    • Commands enum にネストした ConfigCommands を追加
    • config show は秘匿値を必ずマスク表示
    • config path は旧設定ファイルがあれば [deprecated] 注記付きで表示
  6. CLIデフォルト値の変更

    • --limit, --snippet-lines, --snippet-charsOption<usize> に変更
    • 未指定時は config → ハードコードデフォルトの順でフォールバック
  7. Config::load() の呼び出し最適化

    • search.rs 内で最大4回呼ばれる現状を改善
    • AppConfig::load() の結果を1回だけ生成し、各関数に引数として渡す設計にリファクタリング
  8. エラー型の整理

    • config::ConfigError enum を作成
    • 既存 EmbeddingError::ConfigError(String)config::ConfigError からの From 変換で生成
  9. deprecated 警告の統一

    • 警告メッセージは stderr に出力
    • deprecated fallback を実際に使用した場合のみ1回出力
    • 新旧両方存在して旧設定が無視される場合も別メッセージで通知
  10. テストの更新

    • tests/e2e_embedding.rstests/e2e_semantic_hybrid.rs.commandindex/config.toml 参照を新パスに更新
    • tests/cli_args.rsconfig show / config path のテストを追加
    • 設定ファイル名を定数化してDRYに(テストヘルパーでも定数を使用)
    • E2Eテスト3系統: commandindex.toml のみ、config.local.toml 上書き、legacy config.toml fallback
    • CLI引数優先順位テスト: 「未指定時はハードコード既定値」「設定あり時は設定値」「CLI明示時はCLI優先」
    • clean --keep-embeddings の回帰テスト
    • 各コマンドのベースパス別設定検出テスト

受け入れ基準

  • commandindex.toml をリポジトリルートに配置してチーム共有設定ができる
  • .commandindex/config.local.toml で個人オーバーライドができる
  • 設定マージはフィールドレベルで行われる(セクション単位の上書きではない)
  • 環境変数 COMMANDINDEX_OPENAI_API_KEY で最優先オーバーライドができる
  • commandindex config show で有効設定をTOML形式で表示できる(秘匿値はマスク、view model 経由)
  • commandindex config path で読み込まれた設定ファイルのパスを表示できる(旧ファイルは[deprecated]注記付き)
  • 既存のEmbedding/Rerank設定がconfig経由で動作する(既存 embedding::Config からの移行完了)
  • [search] の default_limit/snippet_lines/snippet_chars がCLI引数未指定時に反映される
  • [index] languages は設定ファイルの読み込みのみ(インデクサーへの反映は別Issue)
  • 設定ファイルが存在しない場合はデフォルト値で動作する(後方互換)
  • .commandindex/config.toml が存在する場合は deprecated fallback として読み込み、警告メッセージを stderr に出力
  • 新旧両方の設定ファイルが存在する場合は新設定を優先し、旧設定無視の警告を出力
  • clean.rs の保持対象が LOCAL_CONFIG_FILE, LEGACY_CONFIG_FILE に更新されている(ルートの commandindex.toml は対象外)
  • 専用エラー型 ConfigError が定義されている
  • 設定ファイル名が定数化されている(TEAM_CONFIG_FILE, LOCAL_CONFIG_FILE, LEGACY_CONFIG_FILE)
  • EmbeddingConfig / RerankConfig に Serialize が追加されている
  • E2Eテスト3系統(新設定のみ、ローカル上書き、レガシーfallback)が存在する
  • CLI引数優先順位テスト(未指定/設定あり/CLI明示)が存在する
  • .commandindex/config.local.toml.gitignore で除外されていること(.commandindex/ が既に除外済みなら確認のみ)
  • cargo test / clippy / fmt 全パス

依存 Issue

  • なし(Phase 5完了が前提)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions