Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions DEVELOPER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,14 @@ previews are sanitized and bounded. JSON failures write the envelope to stdout
and leave stderr empty. Human failures write the matching coded `Error`,
`Hint`, and `Usage` lines to stderr and leave stdout empty.

Resolve project-config dependency before calling `CdidxConfigFile.Load`.
Process-static commands (`license`, `--version`, help forms, completions, and
subcommand help) must not discover or parse project config. `validate-config`
and `config show` own malformed-config reporting so they retain their
command-specific contracts while valid settings still reach environment consumers.
Other commands load config before those consumers run; malformed config in JSON mode uses `E024_CONFIG_INVALID` /
`configuration` in the shared command-error envelope.

| Failure class | Exit code | Error code | Category |
|---|---:|---|---|
| Usage / invalid arguments | 1 or 7 | `E010_USAGE_ERROR` | `usage` |
Expand Down Expand Up @@ -3744,6 +3752,14 @@ sanitization し、上限を適用してから merge します。JSON の失敗
出し、stderr を空に保ちます。human の失敗は対応する code 付き `Error`、`Hint`、
`Usage` を stderr に出し、stdout を空に保ちます。

`CdidxConfigFile.Load` を呼ぶ前に project-config 依存性を解決します。process-static な
command(`license`、`--version`、help 形式、completion、subcommand help)は project
config を探索・parse しません。`validate-config` と `config show` は有効な設定を
environment consumer に適用しつつ、不正な file の reporting を command 固有契約で
所有します。それ以外の command は environment consumer の実行前に config を load し、
JSON mode の不正 config は共通の command-error envelope で
`E024_CONFIG_INVALID` / `configuration` を返します。

| failure class | exit code | error code | category |
|---|---:|---|---|
| usage / 不正な引数 | 1 または 7 | `E010_USAGE_ERROR` | `usage` |
Expand Down
8 changes: 4 additions & 4 deletions USER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2417,9 +2417,9 @@ Run `cdidx status --log-path` to print the active log directory without opening

### Project-local configuration file (`.cdidx/config.json` / `.cdidxrc.json`)

You can check a `.cdidx/config.json` or `.cdidxrc.json` file into a repository to set per-project defaults instead of relying on shell-profile or CI env vars (#1571). On startup `cdidx` walks upward from the current working directory looking for the first project config file, validates its schema, and materializes recognized keys as process environment variables — so every existing env-var consumer picks them up without further changes. Discovery stops after checking a directory that contains `.git`, `.hg`, `.svn`, `cdidx.workspace.json`, or `.cdidx-workspace.json`, so a child workspace does not inherit a config file from an unrelated parent.
You can check a `.cdidx/config.json` or `.cdidxrc.json` file into a repository to set per-project defaults instead of relying on shell-profile or CI env vars (#1571). Before a config-dependent command runs, `cdidx` walks upward from the current working directory looking for the first project config file, validates its schema, and materializes recognized keys as scoped environment settings — so every existing env-var consumer picks them up without process-global mutation. Static commands that do not consume project settings (`license`, `--version`, help forms, shell completions, and any command's `--help`) skip config discovery and remain usable even when an unrelated project config is malformed. Discovery stops after checking a directory that contains `.git`, `.hg`, `.svn`, `cdidx.workspace.json`, or `.cdidx-workspace.json`, so a child workspace does not inherit a config file from an unrelated parent.

Precedence is **CLI flag > environment variable > config file > built-in default**. A config-file value is applied only when the matching env var is not already set in the process, so a value the user already exported in the shell or CI always wins. Config JSON is bounded to 64 KiB and a conservative nesting depth before schema validation. A malformed file (invalid JSON, unknown key, wrong type, or excessive nesting) is a hard error: cdidx exits `1` with the file path and all detected offending fields; set `CDIDX_DISABLE_CONFIG_FILE=1` to bypass the file entirely.
Precedence is **CLI flag > environment variable > config file > built-in default**. A config-file value is applied only when the matching env var is not already set in the process, so a value the user already exported in the shell or CI always wins. Config JSON is bounded to 64 KiB and a conservative nesting depth before schema validation. For config-dependent commands, a malformed file (invalid JSON, unknown key, wrong type, or excessive nesting) is a hard error: cdidx exits `1` with the file path and all detected offending fields. JSON mode returns the versioned command-error envelope with `error_code: "E024_CONFIG_INVALID"` and `category: "configuration"` instead of writing human-only text to stderr. Set `CDIDX_DISABLE_CONFIG_FILE=1` to bypass the file entirely.

Secrets are intentionally **not** loadable from the file: `CDIDX_GITHUB_TOKEN`, `CDIDX_MCP_AUTH_TOKEN`, and `CDIDX_MCP_HTTP_TOKEN` are env-only so tokens never get checked into version control.

Expand Down Expand Up @@ -5655,9 +5655,9 @@ MCP のレスポンスサイズ上限は、環境変数 override で guard が

### プロジェクト固有の設定ファイル (`.cdidx/config.json` / `.cdidxrc.json`)

シェルプロファイルや CI の環境変数に頼らず、プロジェクトごとの既定値を `.cdidx/config.json` または `.cdidxrc.json` ファイルとしてリポジトリにチェックインできます (#1571)。`cdidx` は起動時にカレントディレクトリから上方向に最初のプロジェクト設定ファイルを探索し、スキーマを検証してから既知のキーをプロセス環境変数として注入します。これにより、既存の環境変数コンシューマはコード変更なしに同じ値を受け取れます。探索は `.git`、`.hg`、`.svn`、`cdidx.workspace.json`、`.cdidx-workspace.json` を含むディレクトリを確認した後で停止するため、子 workspace が無関係な親ディレクトリの設定ファイルを継承しません。
シェルプロファイルや CI の環境変数に頼らず、プロジェクトごとの既定値を `.cdidx/config.json` または `.cdidxrc.json` ファイルとしてリポジトリにチェックインできます (#1571)。config に依存する command の実行前に、`cdidx` はカレントディレクトリから上方向に最初のプロジェクト設定ファイルを探索し、スキーマを検証してから既知のキーを scoped environment setting として注入します。これにより、process-global な環境変数を変更せずに、既存の環境変数コンシューマが同じ値を受け取れます。プロジェクト設定を使用しない static command(`license`、`--version`、help 形式、shell completion、および各 command の `--help`)は config 探索を省略するため、無関係なプロジェクト設定が不正でも利用できます。探索は `.git`、`.hg`、`.svn`、`cdidx.workspace.json`、`.cdidx-workspace.json` を含むディレクトリを確認した後で停止するため、子 workspace が無関係な親ディレクトリの設定ファイルを継承しません。

優先順位は **CLI フラグ > 環境変数 > 設定ファイル > 組み込み既定値** です。設定ファイル由来の値は、対応する環境変数がプロセスで未設定の場合にのみ適用されるため、シェルや CI で既に export されている値が常に優先されます。設定 JSON はスキーマ検証前に 64 KiB と保守的なネスト深度の上限で検査されます。不正なファイル(無効な JSON、未知のキー、型違い、過度なネスト)は hard error として扱われ、cdidx はファイルパスと検出できた該当フィールドすべてを示して終了コード `1` で終了します。完全にバイパスしたい場合は `CDIDX_DISABLE_CONFIG_FILE=1` を設定してください。
優先順位は **CLI フラグ > 環境変数 > 設定ファイル > 組み込み既定値** です。設定ファイル由来の値は、対応する環境変数がプロセスで未設定の場合にのみ適用されるため、シェルや CI で既に export されている値が常に優先されます。設定 JSON はスキーマ検証前に 64 KiB と保守的なネスト深度の上限で検査されます。config に依存する command では、不正なファイル(無効な JSON、未知のキー、型違い、過度なネスト)は hard error として扱われ、cdidx はファイルパスと検出できた該当フィールドすべてを示して終了コード `1` で終了します。JSON mode では human-only text を stderr に書く代わりに、`error_code: "E024_CONFIG_INVALID"` と `category: "configuration"` を持つ versioned command-error envelope を返します。完全にバイパスしたい場合は `CDIDX_DISABLE_CONFIG_FILE=1` を設定してください。

シークレットは意図的に**ファイルから読み込めません**。`CDIDX_GITHUB_TOKEN` / `CDIDX_MCP_AUTH_TOKEN` / `CDIDX_MCP_HTTP_TOKEN` は環境変数専用としており、トークンがバージョン管理に混入するのを防ぎます。

Expand Down
19 changes: 19 additions & 0 deletions changelog.d/unreleased/4886.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
category: fixed
issues:
- 4886
affected:
- src/CodeIndex/Cli/CliCommandMetadata.cs
- src/CodeIndex/Cli/ProgramRunner.cs
- tests/CodeIndex.Tests/CdidxConfigFileTests.cs
- USER_GUIDE.md
- DEVELOPER_GUIDE.md
---

## English

- **Static commands stay usable and config failures remain machine-readable under malformed project config (#4886)** — `license`, `--version`, help forms, shell completions, and subcommand help now skip unrelated project-config parsing, while config-dependent commands return the versioned `E024_CONFIG_INVALID` JSON error envelope instead of human-only stderr.

## 日本語

- **不正なプロジェクト設定があっても static command と機械可読な config error を利用できるようになりました (#4886)** — `license`、`--version`、help 形式、shell completion、subcommand help は無関係な project-config parse を省略し、config に依存する command は human-only な stderr の代わりに versioned `E024_CONFIG_INVALID` JSON error envelope を返します。
12 changes: 12 additions & 0 deletions src/CodeIndex/Cli/CliCommandMetadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ internal static class CliCommandMetadata
internal static IReadOnlySet<string> OptionalSubcommandCommands { get; } =
new[] { "recipes", "suggestions" }.ToFrozenSet(StringComparer.Ordinal);

// These commands render process-static metadata and must not discover or parse
// project configuration. validate-config owns malformed-config reporting so it
// can preserve its command-specific contract.
// これらの command は process-static metadata を描画するため、project config を
// 探索・parse しない。validate-config は command 固有契約を保つため、不正な config の
// reporting を自身で所有する。
internal static IReadOnlySet<string> ProjectConfigIndependentCommands { get; } =
new[] { "help", "completions", "license" }.ToFrozenSet(StringComparer.Ordinal);

internal static IReadOnlySet<string> ProjectConfigSelfManagedCommands { get; } =
new[] { "validate-config" }.ToFrozenSet(StringComparer.Ordinal);

private static ReadOnlyCollection<string> ReadOnly(params string[] values) =>
Array.AsReadOnly(values);
}
Loading
Loading