Skip to content

Commit b485f41

Browse files
authored
Add nested inspect field projections (#5136)
* Add nested inspect field projections (#5098) * Fix inspect projection edge cases (#5098) * Preserve inspect projection metadata (#5098)
1 parent 2671f01 commit b485f41

15 files changed

Lines changed: 809 additions & 95 deletions

DEVELOPER_GUIDE.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2190,6 +2190,18 @@ case-sensitive; unknown values use the versioned `E010_USAGE_ERROR` command
21902190
error when JSON is requested, and discovery runs before query or database
21912191
access.
21922192

2193+
`inspect` keeps a dedicated typed schema in the same registry because its
2194+
established JSON bundle is not a shared bounded-response envelope. It accepts
2195+
top-level groups and exactly one `collection.field` level for definitions,
2196+
nearby symbols, references, callers, and callees. Inspect selectors normalize
2197+
case and hyphens, resolve aliases before first-occurrence deduplication, and
2198+
preserve canonical request order. A selected parent dominates its children and
2199+
keeps complete rows; otherwise the row projector emits only selected leaves.
2200+
Projection runs before final serialization and byte budgeting while preserving
2201+
root metadata, section totals/cursors/truncation, partial-family metadata, and
2202+
definition body paging/recovery fields. The queryless `inspect --fields list`
2203+
catalog and unknown-field errors are generated from that same schema.
2204+
21932205
| Output mode | Contract |
21942206
|---|---|
21952207
| Human-readable default | Query commands (`search`, `definition`, `references`, `callers`, `callees`, `symbols`, `files`, `excerpt`, `map`, `inspect`, `outline`, `suggestions`) default to **human-readable output**. |
@@ -6113,6 +6125,17 @@ help はすべてこのレジストリを参照します。field 名は大文字
61136125
値で JSON が要求されている場合は versioned `E010_USAGE_ERROR` command error を
61146126
返します。発見処理は query や database access より先に実行します。
61156127

6128+
`inspect` は従来の JSON bundle を shared bounded-response envelope に変更しないため、
6129+
同じレジストリ内に専用の typed schema を持ちます。top-level group に加え、definitions、
6130+
nearby symbols、references、callers、callees では 1 階層だけの `collection.field` を
6131+
受け付けます。inspect selector は大小文字と hyphen を正規化し、alias 解決後に最初の出現を
6132+
残して重複を除き、canonical な指定順を維持します。parent が選択されていれば child より
6133+
優先して完全な row を保持し、それ以外は選択した leaf だけを row projector が出力します。
6134+
projection は最終 serialization と byte budget 適用より前に行い、root metadata、section の
6135+
total / cursor / truncation、partial-family metadata、definition body の paging / recovery field を
6136+
維持します。query 不要の `inspect --fields list` catalog と未知 field error も同じ schema から
6137+
生成します。
6138+
61166139
| output mode | 契約 |
61176140
|---|---|
61186141
| human-readable default | query command(`search`、`definition`、`references`、`callers`、`callees`、`symbols`、`files`、`excerpt`、`map`、`inspect`、`outline`、`suggestions`)は既定で**人間向け出力**です。 |

TESTING_GUIDE.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Use the full suite by default. Use targeted filters only while iterating locally
1919

2020
## Test Stack
2121

22+
- Issue #5098 inspect projection coverage belongs in `QueryCommandRunnerInspectTests.cs`. Keep one graph-ready partial-type fixture covering canonical and alias selectors, multiple leaves across collections, parent-over-child precedence, stable row order, empty arrays, compact truncation, byte bounds, body paging/recovery, partial-family metadata, queryless catalog discovery, and typed unknown parent/leaf errors. `ConsoleUiTests.cs` separately pins the `<csv|list>` usage, nested-field help text, and examples.
2223
- Path-containment coverage for #5091 pairs platform-independent `PathCasingTests` seams for mixed parent-namespace case policies and directory identities with `FileIndexerTests` integration through an internal file symlink. Keep both checks when changing internal-symlink policy: a case-insensitive project mount must not make a distinct case-only sibling in its case-sensitive parent namespace appear internal, while genuine same-namespace aliases remain accepted.
2324
- `WorkspaceCheckTruncationIssue5055Tests` owns the bounded `workspace_check` list contract. Keep zero, below-limit, exact-limit, and over-limit coverage for all six categories, plus the 1260/20/1240 example and one shared filesystem fixture for raw JSON, list-only projection, compact output, byte-budget trimming, deterministic order, and human sample labeling.
2425
- Recipe issue-draft summary coverage in `QueryCommandRunnerSearchTests` keeps the dedicated compact DTO separate from full draft bodies, asserts returned/total/omitted row cardinality (including `count == drafts.length` and positive queries hidden by `--total-limit`), preserves pre-limit evidence-path counts with authority/lower-bound metadata, measures the complete UTF-8 document with multibyte paths and its final newline, verifies whole-row truncation and typed `E028` audit identity, and preserves the full-output contract.
@@ -1107,6 +1108,7 @@ dotnet test --filter "FullyQualifiedName~GitHelperTests"
11071108

11081109
## テストスタック
11091110

1111+
- Issue #5098 の inspect projection coverage は `QueryCommandRunnerInspectTests.cs` が担当します。graph-ready な partial type fixture 1つで canonical / alias selector、collection をまたぐ複数 leaf、parent の child に対する優先、安定した row 順、空配列、compact truncation、byte 上限、body paging / recovery、partial-family metadata、query 不要の catalog discovery、未知 parent / leaf の型付き error を維持してください。`ConsoleUiTests.cs` では `<csv|list>` usage、nested-field help text、例を別途固定します。
11101112
- #5091 の path containment coverage は、親 directory namespace の case policy と directory identity が混在する状況を OS 非依存で再現する `PathCasingTests` の seam と、内部 file symlink を通す `FileIndexerTests` の integration を対にします。internal-symlink policy を変更するときは両方を維持し、case-insensitive な project mount の policy で、case-sensitive な親 namespace にある別 identity の case-only sibling を内部 path と誤認しないこと、および同一 namespace の正当な alias は引き続き受理されることを検証してください。
11111113
- `WorkspaceCheckTruncationIssue5055Tests` は上限付き `workspace_check` 一覧の契約を担当します。6カテゴリすべての0件・上限未満・上限一致・上限超過、1260/20/1240 の例、および raw JSON、一覧単独 projection、compact 出力、byte budget による短縮、決定的順序、human 向け sample 表示を1つの共有 filesystem fixture で検証する coverage を維持してください。
11121114
- `QueryCommandRunnerSearchTests` の recipe issue-draft summary coverage は、専用 compact DTO を完全版 draft body から分離し、返却 / total / omitted row の cardinality(`count == drafts.length` と `--total-limit` に隠れた positive query を含む)、limit 適用前の evidence-path count と authority / lower-bound metadata の維持、multibyte path と末尾改行を含む UTF-8 document 全体の計測、完全な row 単位の truncation、型付き `E028` の audit identity、完全版 output contract の維持を検証します。

USER_GUIDE.md

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ When a bounded `find --all` scan exits partially, its terminal record includes
390390
`next_cursor`; replaying it resumes after the last scanned line.
391391
The bounded-response commands `search`, `definition`, `find`, `status`,
392392
`hotspots`, `references`, `callers`, `callees`, `symbols`, `files`,
393-
`languages`, `impact`, and `map` validate `--fields` values case-sensitively
393+
`languages`, `impact`, `map`, and `inspect` validate `--fields` values
394394
against one command-specific registry. Unknown names return a typed
395395
`E010_USAGE_ERROR` instead of successful empty objects. Run
396396
`cdidx <command> --fields list` before a query to obtain the machine-readable
@@ -415,9 +415,18 @@ same section envelopes and accepts their cursors. In path/line mode, `--path`
415415
locates the definition but does not restrict inbound references or callers to
416416
that file. Inspect graph cursors are accepted only by `inspect`; passing one to
417417
another command is a usage error.
418-
For narrower `inspect` evidence, `--fields <csv>` implies JSON and selects
418+
For narrower `inspect` evidence, `--fields <csv|list>` implies JSON and selects
419419
top-level groups such as `definitions`, `file`, `graph`, `references`,
420-
`callers`, and `callees`; `--outline-only` is shorthand for
420+
`callers`, and `callees`. Collection selectors accept one nested level, for
421+
example `definitions.name`, `definitions.path`, `definitions.line`,
422+
`references.path`, or `callers.path`. Selecting a parent keeps the full rows;
423+
when a parent and child are both requested, the parent wins. Child rows follow
424+
the canonical request order, aliases and duplicates are normalized
425+
deterministically, empty arrays remain arrays, and response counts, truncation,
426+
cursor, body recovery, and partial-family metadata remain available. Unknown
427+
parents or leaves return a typed usage error with the field catalog. Run
428+
`cdidx inspect --fields list` without a query or database to inspect that
429+
catalog. `--outline-only` is shorthand for
421430
`--fields file,definitions,nearby_symbols`, and `--body-only` is shorthand for
422431
`--body --fields definitions`. When a definition body is longer than the returned slice,
423432
`body_content_next_start_line` points to the next source line to pass with
@@ -457,6 +466,8 @@ cdidx inspect Compute --body-only # definitions with body_content only
457466
cdidx inspect Compute --body --body-start 40 --body-lines 40
458467
cdidx inspect Compute --line 42 --context 2 --json
459468
cdidx inspect Compute --json --limit 1 --cursor '<next_cursor>'
469+
cdidx inspect Compute --json --fields definitions.name,definitions.path,references.line
470+
cdidx inspect --fields list
460471
```
461472

462473
## Editor and index portability
@@ -2243,7 +2254,7 @@ same source location.
22432254
| `--summary-only` | `map`, `recipes`, `audit`, `deps`, `hotspots`, and supported `search` JSON contexts | Emit aggregate/context JSON while omitting heavy result arrays where supported. For `deps`, use `--json` or `--format json-graph`; for `hotspots`, use `--json`. Machine-readable `deps` output emits `Progress:` diagnostics only with `--verbose`; other large graph queries emit them at `--limit 80+` or with `--verbose`. |
22442255
| `--sort <mode>` | `symbols`, `outline` | For `outline`, sort one file's symbols by `source`, `kind`, `references`, `size` / `span`, `complexity`, `path`, or `name` before `--limit` / cursor paging. |
22452256
| `--outline-fields <csv>` | `outline` | Project outline JSON symbol fields such as `name`, `line`, `kind`, `signature`, `container`, `range`, `body`, `reference_count`, `size_lines`, `complexity_score`, or `sort_mode`; pass `all` for the full symbol payload with paging metadata. |
2246-
| `--fields <csv>` | `inspect` | Select top-level inspect JSON groups: `file`, `workspace`, `graph`, `definitions`, `body`, `source_excerpt`, `nearby_symbols`, `references`, `callers`, `callees`, or `all`. `body` includes definition bodies and maps to `definitions`. |
2257+
| `--fields <csv\|list>` | `inspect` | Select top-level inspect JSON groups or one-level collection leaves such as `definitions.name`, `definitions.path`, `references.line`, and `callers.path`. A parent keeps full rows and wins over its children; aliases, duplicates, and output order are normalized deterministically. `body` includes definition bodies and maps to `definitions`. Use `list` for the queryless typed catalog. |
22472258
| `--outline-only` | `inspect` | Shorthand for `--fields file,definitions,nearby_symbols`, useful for outline-first review of large classes/types before requesting body or graph evidence. |
22482259
| `--body-only` | `inspect` | Shorthand for `--body --fields definitions`, useful when large audits need implementation text without graph context. |
22492260
| `--body-start <line>` | `inspect` | Start the returned definition body slice at a 1-based source line inside the symbol body. Pair with `body_content_next_start_line` from JSON to page a long body. |
@@ -4000,9 +4011,16 @@ path/line mode の `--path` は定義の位置を特定しますが、inbound re
40004011
そのファイルだけに制限しません。MCP `analyze_symbol` も同じ section envelope を公開し、
40014012
その cursor を受け付けます。inspect graph cursor は `inspect` だけが受理し、別 command に
40024013
渡すと usage error になります。
4003-
`inspect` の証跡をさらに絞りたい場合、`--fields <csv>` は JSON 出力を暗黙に有効化し、
4014+
`inspect` の証跡をさらに絞りたい場合、`--fields <csv|list>` は JSON 出力を暗黙に有効化し、
40044015
`definitions`、`file`、`graph`、`references`、`callers`、`callees` などの
4005-
top-level group を選択します。`--outline-only` は
4016+
top-level group を選択します。collection selector は 1 階層の nested field に対応し、
4017+
たとえば `definitions.name`、`definitions.path`、`definitions.line`、
4018+
`references.path`、`callers.path` を指定できます。parent を選ぶと row 全体を保持し、
4019+
parent と child を同時指定した場合は parent が優先されます。child row は canonical な
4020+
指定順を保ち、alias と重複は決定的に正規化されます。空配列は配列のまま保持され、count、
4021+
truncation、cursor、body recovery、partial-family metadata も維持されます。未知の parent / leaf
4022+
は field catalog 付きの型付き usage error になります。query や DB なしで
4023+
`cdidx inspect --fields list` を実行すると catalog を確認できます。`--outline-only` は
40064024
`--fields file,definitions,nearby_symbols` の shorthand で、`--body-only` は
40074025
`--body --fields definitions` の shorthand です。definition body が返却 slice より長い場合は
40084026
`body_content_next_start_line` が次に `--body-start` へ渡す source line を示します。
@@ -4040,6 +4058,8 @@ cdidx inspect Compute --body-only # body_content 付き definitions の
40404058
cdidx inspect Compute --body --body-start 40 --body-lines 40
40414059
cdidx inspect Compute --line 42 --context 2 --json
40424060
cdidx inspect Compute --json --limit 1 --cursor '<next_cursor>'
4061+
cdidx inspect Compute --json --fields definitions.name,definitions.path,references.line
4062+
cdidx inspect --fields list
40434063
```
40444064

40454065
## Editor / index portability
@@ -5747,7 +5767,7 @@ raw match density を正確に測る、といった理由で全 raw chunk hit
57475767
| `--summary-only` | `map`、`recipes`、`audit`、`deps`、`hotspots`、および対応する `search` JSON 文脈 | 対応コマンドで重い結果配列を省き、集計と文脈中心の JSON を返す。`deps` では `--json` または `--format json-graph`、`hotspots` では `--json` と組み合わせる。machine-readable な `deps` 出力は `--verbose` 指定時だけ stderr へ `Progress:` 診断を出し、それ以外の大きい graph query は `--limit 80` 以上または `--verbose` 指定時に出す。 |
57485768
| `--sort <mode>` | `symbols`、`outline` | `outline` では 1ファイル内のシンボルを `source`、`kind`、`references`、`size` / `span`、`complexity`、`path`、`name` で並べ替えてから `--limit` / カーソルページングを適用する。 |
57495769
| `--outline-fields <csv>` | `outline` | outline JSON のシンボルフィールドを投影する。`name`、`line`、`kind`、`signature`、`container`、`range`、`body`、`reference_count`、`size_lines`、`complexity_score`、`sort_mode` などを指定でき、`all` を渡すとシンボルペイロード全体とページングメタデータを返す。 |
5750-
| `--fields <csv>` | `inspect` | inspect JSON の top-level group を選択。`file`、`workspace`、`graph`、`definitions`、`body`、`source_excerpt`、`nearby_symbols`、`references`、`callers`、`callees`、`all` を指定できる。`body` は definition body を含め、`definitions` に対応する。 |
5770+
| `--fields <csv\|list>` | `inspect` | inspect JSON の top-level group または `definitions.name`、`definitions.path`、`references.line`、`callers.path` など 1 階層の collection leaf を選択する。parent は row 全体を保持して child より優先され、alias、重複、出力順は決定的に正規化される。`body` は definition body を含め、`definitions` に対応する。query 不要の型付き catalog は `list` で取得できる。 |
57515771
| `--outline-only` | `inspect` | `--fields file,definitions,nearby_symbols` の shorthand。大きな class / type を body や graph evidence なしでアウトライン優先で確認したい場合に使う。 |
57525772
| `--body-only` | `inspect` | `--body --fields definitions` の shorthand。大規模 audit で graph context なしに実装本文だけが必要な場合に使う。 |
57535773
| `--body-start <line>` | `inspect` | symbol body 内の 1-based source line から definition body slice を返す。長い body の page 送りでは JSON の `body_content_next_start_line` を次の値として渡す。 |
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
category: added
3+
issues:
4+
- 5098
5+
affected:
6+
- src/CodeIndex/Cli/ProjectionFieldRegistry.cs
7+
- src/CodeIndex/Cli/QueryCommandRunner.ArgumentParser.Filters.cs
8+
- src/CodeIndex/Cli/QueryCommandRunner.ArgumentParser.cs
9+
- src/CodeIndex/Cli/QueryCommandRunner.Inspect.cs
10+
- tests/CodeIndex.Tests/QueryCommandRunnerInspectTests.cs
11+
- USER_GUIDE.md
12+
- DEVELOPER_GUIDE.md
13+
- TESTING_GUIDE.md
14+
---
15+
16+
## English
17+
18+
- **Inspect JSON supports nested collection field projections (#5098)**`cdidx inspect --fields` can now select one-level leaves such as `definitions.name`, `references.path`, and `callers.line`, while preserving response and coupled row truncation metadata, compact and byte-bounded behavior, definition-body recovery fields, deterministic parent/alias/order and repeated-option semantics, typed unknown-field errors, and a queryless `--fields list` catalog.
19+
20+
## 日本語
21+
22+
- **inspect JSON で collection の nested field projection に対応しました (#5098)**`cdidx inspect --fields``definitions.name``references.path``callers.line` など 1 階層の leaf を選択できるようになりました。response metadata と行内の関連 truncation metadata、compact / byte 上限制御、definition body の recovery field、決定的な parent / alias / 順序 / 重複 option の規則、未知 field の型付き error、query 不要の `--fields list` catalog も維持します。

src/CodeIndex/Cli/CliFlagSchema.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ private static IReadOnlyList<CliFlag> BuildAll()
547547
new() { Name = "--body-start", ValuePlaceholder = "<line>", Description = "Inspect: start definition body slice at this 1-based source line", PrimaryCommands = Set(InspectFieldCommands) },
548548
new() { Name = "--body-lines", ValuePlaceholder = "<n>", Description = "Inspect: return at most this many definition body lines", PrimaryCommands = Set(InspectFieldCommands) },
549549
new() { Name = "--body-line-count", ValuePlaceholder = "<n>", Description = "Inspect: alias for --body-lines", PrimaryCommands = Set(InspectFieldCommands) },
550-
new() { Name = "--fields", ValuePlaceholder = "<csv>", Description = "Project bounded-response row fields; inspect selects top-level evidence groups; nested collections accept collection.field", PrimaryCommands = Set(InspectFieldCommands.Concat(BoundedProjectionCommands).ToArray()) },
550+
new() { Name = "--fields", ValuePlaceholder = "<csv>", Description = "Project bounded-response fields; inspect accepts top-level groups or collection.field and `list` prints its typed catalog", PrimaryCommands = Set(InspectFieldCommands.Concat(BoundedProjectionCommands).ToArray()) },
551551
new() { Name = "--body-only", Description = "Inspect: body-focused JSON shorthand for --body --fields definitions", PrimaryCommands = Set(InspectFieldCommands) },
552552
new() { Name = "--outline-only", Description = "Inspect: outline-first JSON shorthand for --fields file,definitions,nearby_symbols", PrimaryCommands = Set(InspectFieldCommands) },
553553
new() { Name = "--exact", Description = "Backward-compatible exact shorthand; search mode is incompatible with --fts", PrimaryCommands = Set(ExactCommands) },

0 commit comments

Comments
 (0)