Skip to content

Improve ControlKit UI introspection and tvOS diagnostics - #51

Merged
setoelkahfi merged 7 commits into
developmentfrom
feature/controlkit-ui-introspection
Aug 25, 2026
Merged

Improve ControlKit UI introspection and tvOS diagnostics#51
setoelkahfi merged 7 commits into
developmentfrom
feature/controlkit-ui-introspection

Conversation

@setoelkahfi

@setoelkahfi setoelkahfi commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

Related Issue

Related ondeinference/xcrs-controlkit#1

Description

Type of Change

  • Bug fix
  • New feature
  • Refactor (no functional change)
  • Documentation update
  • CI / tooling change

How Has This Been Tested?

  • cargo test --all-features
  • Manual testing (smb <command>)

Checklist

  • cargo check --workspace passes
  • cargo clippy --workspace --tests -- -D warnings passes
  • cargo fmt --all -- --check passes
  • No new unwrap() or expect() calls in production code
  • No new mod.rs files introduced
  • New dependencies added to root Cargo.toml and inherited with { workspace = true }
  • Error messages are user-friendly and surfaced to the terminal

Release Notes

Co-Authored-By: siGit Code <297239231+sigitc@users.noreply.github.com>
@sigit-code

sigit-code Bot commented Aug 20, 2026

Copy link
Copy Markdown

siGit Code review is paused because this GitHub App installation is not linked to a siGit account. Link it at https://sigit.si/settings to resume reviews.

@setoelkahfi setoelkahfi self-assigned this Aug 25, 2026

@sigit-code sigit-code Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This PR adds a mandatory bundle_id field to UiTargetArgs and threads it through both ui_describe and ui_element_list ControlKit calls. It also refactors ControlKit::call into call+send, with call now handling JSON-RPC error extraction and emitting a richer diagnostic (including a follow-up device.info probe) when the method is not found. Additional fields (depth, enabled, selected, hittable) are included in the filtered element output, and the empty-string identity check tightens element selection. Error messages and docs are updated to be platform-agnostic (iOS → Apple simulator).


Automated review by siGit Code Review · commit 10b369c

Comment thread crates/xcrs/src/mcp.rs Outdated

@sigit-code sigit-code Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This PR makes two main changes:

  1. bundle_id is now required for ui_describe and ui_element_list: a new require_bundle_id helper validates and trims it, returning a structured error if absent. The bundleId field is forwarded to the device.dump.ui RPC call.

  2. Better ControlKit error diagnostics: call is split into call+send; on a -32601 (method-not-found) response, a secondary device.info call fetches the runner name and protocol version to produce an actionable upgrade message.

Additional changes: AppleTargetArgs (without bundle_id) is introduced so orientation_get and similar tools keep a clean schema; empty-string identity values are now filtered out in collect_controlkit_elements; new tvOS-resolution fields (depth, enabled, selected, hittable) are included in the element snapshot; error messages and docs are generalised from "iOS" to "Apple".


Automated review by siGit Code Review · commit 75f5b51

Comment thread crates/xcrs/src/xcrs.rs Outdated

@sigit-code sigit-code Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This PR adds bundle_id as a required runtime parameter to ui_describe and ui_element_list, introduces a new AppleTargetArgs struct (without bundle_id) to keep orientation_get and similar tools free of that field, refactors ControlKit::call into call+send so that -32601 Method Not Found errors automatically fetch device.info for a richer diagnostic, filters out empty-string identity values from the element collector, and adds depth/enabled/selected/hittable to the fields copied into flat element objects. Tests cover schema shape, require_bundle_id trimming/rejection, the new error-message paths, and element extraction.


Automated review by siGit Code Review · commit 4d005aa

Comment thread crates/xcrs/src/xcrs.rs Outdated
Comment thread crates/xcrs/src/xcrs.rs Outdated
Comment thread crates/xcrs/src/xcrs.rs
Comment thread crates/xcrs/src/mcp.rs
Comment thread crates/xcrs/src/mcp.rs
Comment thread crates/xcrs/src/mcp.rs

@sigit-code sigit-code Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This PR adds a required bundle_id parameter to ui_describe and ui_element_list (validated at runtime via require_bundle_id, while the schema field stays optional so callers can omit it and get a clear error). It also introduces AppleTargetArgs (without bundle_id) to replace UiTargetArgs for tools like orientation_get, improves collect_controlkit_elements to skip empty-string identity fields, adds depth/enabled/selected/hittable to the extracted element keys, and enriches error messages for JSON-RPC -32601 (method not found) by doing a secondary device.info probe to surface the runner version.


Automated review by siGit Code Review · commit 4d1cf59

Comment thread crates/xcrs/src/xcrs.rs Outdated
Comment thread crates/xcrs/src/xcrs.rs Outdated
Comment thread crates/xcrs/src/xcrs.rs
Comment thread crates/xcrs/src/mcp.rs
Comment thread crates/xcrs/src/mcp.rs

@sigit-code sigit-code Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This PR adds bundle_id as a required runtime parameter to ui_describe and ui_element_list (passed in the JSON-RPC call but kept Option<String> in the schema so the field is optional at the schema level, with explicit validation via require_bundle_id). It splits AppleTargetArgs from UiTargetArgs so tools like orientation_get no longer expose bundle_id. The ControlKit::call path is refactored into call+send: on a JSON-RPC method-not-found error it now fires a secondary device.info probe (with a 2-second timeout) to include runner version info in the error message. collect_controlkit_elements gains empty-string filtering for identity fields and surfaces depth/enabled/selected/hittable. Error messages are updated throughout for tvOS/watchOS/visionOS generality.


Automated review by siGit Code Review · commit 1f423c6

Comment thread crates/xcrs/src/xcrs.rs
Comment thread crates/xcrs/src/xcrs.rs
Comment thread crates/xcrs/src/xcrs.rs
Comment thread crates/xcrs/src/mcp.rs
Comment thread crates/xcrs/src/mcp.rs
@setoelkahfi

Copy link
Copy Markdown
Collaborator Author

Thanks for the thorough pass. Went through all of it against the current head. Most of the real issues are already fixed in 75f5b511f423c6: the bundle_id breaking change (now Option + require_bundle_id), the bounded device.info probe timeout, runner-metadata failure reporting, the recursion guard, and the numeric/float error codes.

One thing left worth doing: added a comment on is_controlkit_method_not_found explaining why it checks both as_i64 and as_f64. Some runners send the code as -32601.0, which as_i64 rejects. A few comments tripped over this, so it earned a line.

What I skipped, and why:

  • The {"result": null} 'critical' doesn't hold. serde_json's get("result") returns Some(Value::Null) when the key exists, so a null result is treated as success, not None. The follow-up nit says the same thing.
  • The require_bundle_id clone is one tiny allocation per call, and trim() returns a slice so you allocate either way. Leaving it.
  • The duplicate method-not-found check only runs on the error path. Not worth reshaping a signature over.
  • The test that reaches into require_bundle_id would surface as a compile error if visibility ever tightened, which is fine.

fmt, clippy (-D warnings), and cargo test -p xcrs (46 passed) are all green.

@sigit-code sigit-code Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This PR makes two main changes:

  1. bundle_id is now required at call-time for ui_describe and ui_element_list – a new AppleTargetArgs struct (without bundle_id) splits off from UiTargetArgs (which gains bundle_id). A require_bundle_id helper validates the field and returns a clear error when it's absent or blank. Both UI tools pass bundleId to the ControlKit device.dump.ui RPC.

  2. Richer ControlKit error diagnosticsControlKit::call is split into call + send. When a JSON-RPC -32601 (method-not-found) error is returned, call fires a secondary device.info probe (with a 2-second timeout) and surfaces the runner name and protocol version in the error message. The is_controlkit_method_not_found helper also handles runners that serialize the error code as a float.

Additionally, collect_controlkit_elements now filters out empty-string identity fields, and the output includes depth, enabled, selected, and hittable per element.

Tests cover the new schema shape, error formatting, and element extraction. The primary concern is a subtle double-probe risk and an error path that silently drops runner info.


Automated review by siGit Code Review · commit c85b39a

Comment thread crates/xcrs/src/xcrs.rs
Comment thread crates/xcrs/src/xcrs.rs
Comment thread crates/xcrs/src/xcrs.rs
Comment thread crates/xcrs/src/mcp.rs
Comment thread crates/xcrs/src/mcp.rs
Comment thread crates/xcrs/src/xcrs.rs
@keypair34
keypair34 requested review from keypair34 and paydii August 25, 2026 12:33
@setoelkahfi
setoelkahfi merged commit 2475738 into development Aug 25, 2026
6 checks passed
@setoelkahfi
setoelkahfi deleted the feature/controlkit-ui-introspection branch August 25, 2026 12:49
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.

3 participants