fix: pause-pointの応答から重複情報を削減し、変数値だけを後から選んで取得できるように改善 - #1857
Conversation
EvidenceSummary in await-pause-point's response duplicated fields already present on pausePointStatusResponse and MatchingLogs (EditorState, PausePoint metadata, log counts). The only field it added that wasn't a duplicate was Warning, so it now lives directly on pausePointWaitResult (and the timeout error Details map) with omitempty, cutting redundant JSON without losing information.
CapturedVariables already carries the latest hit's variables, so keeping a matching frame in CapturedVariableHistory duplicated it 100% of the time in single-shot mode (the default) and once per continuous-mode hit. filterPausePointCapturedVariableHistory drops any frame whose HitSequence equals LastHitSequence in both the await-pause-point hit response and pause-point-status output, with a table-driven test covering single-shot, continuous, and no-history cases.
Every non-Unity-object variable always got UnityObjectKind="", UnityObjectPath="", and UnityObjectInstanceId=0 in the response, three fields of pure noise for the common case (int, string, custom class fields). Verified in Unity's SourcePausePointVariableFormatter that non-Unity-object variables always hardcode these three fields to their zero value, and that Unity object variables (including destroyed ones) always set a non-empty UnityObjectKind, making Kind the safe discriminator even in the theoretical case where UnityObjectInstanceId itself lands on zero (possible on 6000.4+, where it is the lower 32 bits of an EntityId). Independent omitempty per field keeps the shape correct in both cases, with tests locking in the discriminator contract.
For classes with many SerializeField fields, continuous mode's history already multiplies entry count by MaxHistory, and every entry always carried a Value string. names lets an agent pull a lightweight Name/Scope/TypeName list first and fetch specific values afterward via TryGetCapturedValue or pause-point-status, instead of paying for every value up front. The new flag constant lives in cli/common/clicore (shared with dispatcher shell completion in completion_options.go), so this also updates both project-runner and dispatcher shared-inputs stamps per the release trigger guard.
The response shape changed in this PR: EvidenceSummary is gone (Warning moved to a top-level field), CapturedVariableHistory no longer repeats the latest hit, and UnityObject* fields are omitted for non-Unity-object variables. Updated the doc accordingly, added a pull-type usage pattern for --captured-variables names on field-heavy classes, and documented which of TryGetCapturedValue vs. pause-point-status is the faithful evidence source for value types, live reference-type state, and capture-time reference-type state. Synced .claude/skills and .agents/skills byte-identically from the Packages/src source of truth.
pause_point_wait.go grew past the 500-line architecture guard (TestProductionGoFilesStayFocused) once the --captured-variables mode type, parser, and stripping logic were added. Moved that functionally-cohesive block (mode type, parse, apply, strip helper) into pause_point_captured_variables_mode.go, no behavior change.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (3)
📝 WalkthroughWalkthroughChangesThe pause-point CLI now supports Pause-point output and evidence
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant PausePointCLI
participant ResponseNormalizer
participant JSONOutput
User->>PausePointCLI: Run await-pause-point or pause-point-status
PausePointCLI->>ResponseNormalizer: Parse captured-variables mode
ResponseNormalizer->>ResponseNormalizer: Filter latest history frame
ResponseNormalizer->>ResponseNormalizer: Strip values in names mode
ResponseNormalizer->>JSONOutput: Emit captured variables and warnings
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@cli/project-runner/internal/projectrunner/pause_point_types.go`:
- Around line 60-67: Update pausePointCapturedVariable.Value and its JSON
representation so a legitimate empty string remains serialized in full mode,
while names mode can still omit the value as intended. Preserve the documented
distinction between full and names modes and the existing behavior of other
optional fields.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 39ac6afa-4006-41f3-bf9d-d02e211b15ce
📒 Files selected for processing (12)
.agents/skills/uloop-pause-point/SKILL.md.claude/skills/uloop-pause-point/SKILL.mdPackages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.mdcli/common/clicore/command_registry.gocli/dispatcher/internal/dispatcher/completion_options.gocli/dispatcher/shared-inputs-stamp.jsoncli/project-runner/internal/projectrunner/pause_point_captured_variables_mode.gocli/project-runner/internal/projectrunner/pause_point_logs.gocli/project-runner/internal/projectrunner/pause_point_types.gocli/project-runner/internal/projectrunner/pause_point_wait.gocli/project-runner/internal/projectrunner/pause_point_wait_test.gocli/project-runner/shared-inputs-stamp.json
CodeRabbit flagged that Value used a plain string with `omitempty`, which made a legitimately empty value (e.g. a captured `string s = ""`) indistinguishable from names mode stripping the value. Value is now a pointer so full mode keeps "Value":"" for a real empty string while names mode sets it to nil to omit the field entirely.
Summary
await-pause-point/pause-point-statusの応答から、既に他フィールドと重複していた情報や常に空だったフィールドを削減し、エージェントが読むトークン量を減らした--captured-variables namesを追加し、Valueを省いた軽量な変数リストだけを先に取得できるようにしたUser Impact
await-pause-pointの応答にEvidenceSummaryという重複ラッパーがあり、既にEditorStateやポーズポイントのメタ情報、マッチしたログとして返っている内容がもう一度別の形で埋め込まれていた。また、非Unityオブジェクトの変数にも常に空のUnityObjectKind/UnityObjectPath/UnityObjectInstanceIdが出力され、CapturedVariableHistoryには直近のヒットと同じフレームが重複して含まれていたEvidenceSummaryを廃止し、唯一実用的だった情報(複数ヒットやログ切り詰めの注意喚起)はWarning(空なら省略)としてトップレベルに残した。Unityオブジェクトでない変数ではUnityObjectKind等のフィールドが出力されなくなり、CapturedVariableHistoryは直近ヒットを除いた過去分だけになった。さらに--captured-variables namesでValueを省いた変数一覧だけを先に取得し、必要な値だけをpause-point-statusやTryGetCapturedValueで後から引けるようになったChanges
await-pause-point/pause-point-statusの応答からEvidenceSummaryを削除し、Warning(omitempty)をトップレベルに追加CapturedVariableHistoryから、最新ヒットと同じフレームを常に除外するフィルタを追加UnityObjectKind/UnityObjectPath/UnityObjectInstanceIdを出力しないよう独立したomitemptyを付与(判別はUnityObjectKindの有無で行い、UnityObjectInstanceId == 0には依存しない)--captured-variables names(デフォルトfull)を追加。names指定時は履歴フレームも含めた全ての捕捉変数からValueを除去するcli/commonの新フラグ定数追加に伴い、release-triggerルールに従ってcli/project-runner/cli/dispatcher双方のshared-inputs-stamp.jsonを更新pause_point_wait.goがアーキテクチャの500行上限を超えたため、--captured-variablesモードのロジックをpause_point_captured_variables_mode.goに分離Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.mdを新しい応答形状・新フラグの使い方に合わせて更新し、.claude/skills/uloop-pause-point/SKILL.mdと.agents/skills/uloop-pause-point/SKILL.mdに同期Before / After(実機PlayModeで取得した実例)
Before(このPR適用前の形状、
EvidenceSummary相当・重複履歴フレームを含む想定){ "Success": true, "Id": "Assets/Tests/Demo/DemoLongPressButton.cs:49", "IsHit": true, "CapturedVariableHistory": [ { "HitSequence": 1, "CapturedVariables": [ { "Name": "this", "TypeName": "...DemoLongPressButton", "Value": "LongPressButton", "UnityObjectKind": "SceneObject", "UnityObjectPath": "SimulateMouseDemoScene:/Canvas/LongPressButton", "UnityObjectInstanceId": 34148 } ] } ], "CapturedVariables": [ { "Name": "eventData", "TypeName": "UnityEngine.EventSystems.PointerEventData", "Value": "...", "UnityObjectKind": "", "UnityObjectPath": "", "UnityObjectInstanceId": 0 }, { "Name": "this", "TypeName": "...DemoLongPressButton", "Value": "LongPressButton", "UnityObjectKind": "SceneObject", "UnityObjectPath": "SimulateMouseDemoScene:/Canvas/LongPressButton", "UnityObjectInstanceId": 34148 } ], "EvidenceSummary": { "EditorState": { "IsPlaying": true, "IsPaused": true }, "PausePoint": { "Id": "Assets/Tests/Demo/DemoLongPressButton.cs:49", "HitCount": 1 }, "Logs": [] } }After(本PRで実際に取得した応答。デフォルト
fullモード){ "Success": true, "Id": "Assets/Tests/Demo/DemoLongPressButton.cs:49", "Status": "Hit", "IsHit": true, "HitCount": 1, "CapturedVariableHistory": [], "CapturedVariables": [ { "Name": "eventData", "Scope": "Parameter", "TypeName": "UnityEngine.EventSystems.PointerEventData", "Value": "<b>Position</b>: (400.00, 420.00)\n..." }, { "Name": "this", "Scope": "This", "TypeName": "io.github.hatayama.UnityCliLoop.Tests.Demo.DemoLongPressButton", "Value": "LongPressButton", "UnityObjectKind": "SceneObject", "UnityObjectPath": "SimulateMouseDemoScene:/Canvas/LongPressButton", "UnityObjectInstanceId": 34148 }, { "Name": "requiredHoldTime", "Scope": "InstanceField", "TypeName": "System.Single", "Value": "3" } ], "CapturedVariablesTruncated": true, "MatchingLogs": [] }(
EvidenceSummaryは無くなり、Warningは今回の単発ヒットでは値が無いため省略されている。eventData/requiredHoldTimeにUnityObjectKind等は出ていない一方、thisには出ている)--captured-variables names指定時(同じヒットを再現、Valueのみ省略){ "CapturedVariables": [ { "Name": "eventData", "Scope": "Parameter", "TypeName": "UnityEngine.EventSystems.PointerEventData" }, { "Name": "this", "Scope": "This", "TypeName": "io.github.hatayama.UnityCliLoop.Tests.Demo.DemoLongPressButton", "UnityObjectKind": "SceneObject", "UnityObjectPath": "SimulateMouseDemoScene:/Canvas/LongPressButton", "UnityObjectInstanceId": 34148 }, { "Name": "requiredHoldTime", "Scope": "InstanceField", "TypeName": "System.Single" } ] }Verification
sh scripts/check-go-cli.sh: fmt/vet/lint/test/build 全て成功(Goテストは新規追加分含めて全通過)sh scripts/build-go-cli.sh: ネイティブバイナリを再ビルドuloop compile:ErrorCount: 0,WarningCount: 0(本PRはGoのみの変更でC#差分なし)enable-pause-point→await-pause-point(デフォルト)でEvidenceSummaryが無いこと、CapturedVariableHistoryに直近フレームの重複が無いこと、非Unityオブジェクト変数にUnityObject*が出ないことを確認await-pause-point --captured-variables namesでValueが省略されることを確認pause-point-status --id <id>でフル情報の再取得(pullフォールバック)が機能することを確認