Skip to content

fix: pause-pointの応答から重複情報を削減し、変数値だけを後から選んで取得できるように改善 - #1857

Merged
hatayama merged 7 commits into
v3-betafrom
feat/pause-point-response-diet
Jul 19, 2026
Merged

fix: pause-pointの応答から重複情報を削減し、変数値だけを後から選んで取得できるように改善#1857
hatayama merged 7 commits into
v3-betafrom
feat/pause-point-response-diet

Conversation

@hatayama

@hatayama hatayama commented Jul 19, 2026

Copy link
Copy Markdown
Owner

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 namesValue を省いた変数一覧だけを先に取得し、必要な値だけを pause-point-statusTryGetCapturedValue で後から引けるようになった

Changes

  • await-pause-point / pause-point-status の応答から EvidenceSummary を削除し、Warningomitempty)をトップレベルに追加
  • CapturedVariableHistory から、最新ヒットと同じフレームを常に除外するフィルタを追加
  • 変数がUnityオブジェクトでない場合、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/requiredHoldTimeUnityObjectKind 等は出ていない一方、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#差分なし)
  • 実機Unity Editor(PlayMode)で E2E 確認:
    • enable-pause-pointawait-pause-point(デフォルト)で EvidenceSummary が無いこと、CapturedVariableHistory に直近フレームの重複が無いこと、非Unityオブジェクト変数に UnityObject* が出ないことを確認
    • await-pause-point --captured-variables namesValue が省略されることを確認
    • resume後の pause-point-status --id <id> でフル情報の再取得(pullフォールバック)が機能することを確認

Review in cubic

hatayama added 6 commits July 20, 2026 01:24
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.
@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e08386e3-c470-4d4e-bdeb-7c924691d8d0

📥 Commits

Reviewing files that changed from the base of the PR and between fa2ad2c and f1e4319.

📒 Files selected for processing (3)
  • cli/project-runner/internal/projectrunner/pause_point_captured_variables_mode.go
  • cli/project-runner/internal/projectrunner/pause_point_types.go
  • cli/project-runner/internal/projectrunner/pause_point_wait_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • cli/project-runner/internal/projectrunner/pause_point_captured_variables_mode.go
  • cli/project-runner/internal/projectrunner/pause_point_types.go
  • cli/project-runner/internal/projectrunner/pause_point_wait_test.go

📝 Walkthrough

Walkthrough

Changes

The pause-point CLI now supports --captured-variables full|names, excludes the latest hit from continuous history, emits top-level warnings instead of evidence summaries, and updates captured-variable JSON contracts, tests, and documentation.

Pause-point output and evidence

Layer / File(s) Summary
Captured-variable mode and JSON contract
cli/common/clicore/command_registry.go, cli/dispatcher/..., cli/project-runner/internal/projectrunner/pause_point_captured_variables_mode.go, pause_point_types.go, pause_point_wait.go
Adds flag parsing and completion, supports full/names output, strips values in names mode, and omits empty fields.
History filtering and warning responses
cli/project-runner/internal/projectrunner/pause_point_logs.go, pause_point_wait.go
Filters the latest history frame and replaces evidence summaries with matching logs and top-level warnings.
Response and serialization tests
cli/project-runner/internal/projectrunner/pause_point_wait_test.go
Tests modes, history filtering, warnings, timeout details, value omission, and Unity-object metadata serialization.
Pause-point evidence guidance
.agents/skills/uloop-pause-point/SKILL.md, .claude/skills/uloop-pause-point/SKILL.md, Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md
Documents history behavior, metadata, warnings, retrieval modes, and evidence-source selection.

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
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: reducing duplicate pause-point response data and adding a way to fetch variable values later.
Description check ✅ Passed The description is clearly related and matches the changeset, including the new --captured-variables names mode and response simplification.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/pause-point-response-diet

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 77658f8 and fa2ad2c.

📒 Files selected for processing (12)
  • .agents/skills/uloop-pause-point/SKILL.md
  • .claude/skills/uloop-pause-point/SKILL.md
  • Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md
  • cli/common/clicore/command_registry.go
  • cli/dispatcher/internal/dispatcher/completion_options.go
  • cli/dispatcher/shared-inputs-stamp.json
  • cli/project-runner/internal/projectrunner/pause_point_captured_variables_mode.go
  • cli/project-runner/internal/projectrunner/pause_point_logs.go
  • cli/project-runner/internal/projectrunner/pause_point_types.go
  • cli/project-runner/internal/projectrunner/pause_point_wait.go
  • cli/project-runner/internal/projectrunner/pause_point_wait_test.go
  • cli/project-runner/shared-inputs-stamp.json

Comment thread cli/project-runner/internal/projectrunner/pause_point_types.go Outdated
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.
@hatayama
hatayama merged commit d507274 into v3-beta Jul 19, 2026
11 checks passed
@hatayama
hatayama deleted the feat/pause-point-response-diet branch July 19, 2026 17:10
@github-actions github-actions Bot mentioned this pull request Jul 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant