Skip to content

PR #416

PR #416 #1377

Triggered via dynamic May 21, 2026 22:30
Status Success
Total duration 1m 38s
Artifacts

codeql

on: dynamic
Matrix: analyze
Fit to window
Zoom out
Zoom in

Annotations

2 errors and 5 warnings
Published ui-action-result v2 schema mutated instead of kept frozen: schemas/structured-output/xcodebuildmcp.output.ui-action-result/2.schema.json#L362
New action variants (`type-text`, `key-press`, `key-sequence`, `batch`), new `$defs` (`compactRuntimeSnapshot`, `recoverableUiError`, `point`, `direction`, `runtimeElement*`), and optional `capture`/`uiError` fields are being added to the existing v2 schema; published schema versions must be frozen and all new capabilities introduced only in the new v3 file.
v3 schema declared but setUiActionStructuredOutput always emits schemaVersion '2': schemas/structured-output/xcodebuildmcp.output.ui-action-result/3.schema.json#L199
The new v3 schema accepts a full `runtimeSnapshot` capture (with `protocol: "rs/1"`), but `setUiActionStructuredOutput` hardcodes `schemaVersion: '2'` for every path — so any `UiActionResultDomainResult` carrying a `RuntimeSnapshotV1` capture produces a payload that fails v2 validation. Update `setUiActionStructuredOutput` to emit `schemaVersion: '3'` when `capture` is a full `RuntimeSnapshotV1`.
Normalization test validates pre-compaction RuntimeSnapshotV1 shape that never appears in capture-result fixture output: src/snapshot-tests/__tests__/json-normalize.test.ts#L78
The test uses `schema: 'xcodebuildmcp.output.capture-result'` with `protocol`, `capturedAtMs`, `expiresAtMs`, `elements`, and `actions` fields, but `toStructuredEnvelope` compacts `RuntimeSnapshotV1` into `rs: '1'`, `targets`, `scroll`, `text`, `count`, `udid` — stripping those fields before any fixture is written. The normalizer rules for `capturedAtMs` and `expiresAtMs` are exercised against a data shape that no real `capture-result` snapshot fixture will ever contain.
`candidates` in `UiAutomationRecoverableError` is unbounded, unlike the capped snapshot targets list: src/types/ui-snapshot.ts#L111
When a `TARGET_NOT_ACTIONABLE` error is returned, `candidates` is populated with every element in the snapshot that supports the requested action — no limit is applied — while the main compact snapshot enforces `COMPACT_RUNTIME_TARGET_LIMIT = 64`. A complex UI can produce error payloads with hundreds of candidate entries.
O(n²) element scanning in findActiveForegroundRoot: src/mcp/tools/ui-automation/shared/runtime-next-steps.ts#L376
Each call to `foregroundScore` performs two O(n) passes — `findSheetGrabberDescendant` (linear scan) and `records.filter(isForegroundCandidateForRoot)` — once per unique candidate element, making the total cost O(n²) over all records on every UI action response.
[7JS-LXJ] O(n²) element scanning in findActiveForegroundRoot (additional location): src/mcp/tools/ui-automation/shared/runtime-next-steps.ts#L546
Each call to `foregroundScore` performs two O(n) passes — `findSheetGrabberDescendant` (linear scan) and `records.filter(isForegroundCandidateForRoot)` — once per unique candidate element, making the total cost O(n²) over all records on every UI action response.
Platform detection coupled to hardcoded error message string: src/utils/renderers/domain-result-text.ts#L799
Determining `isMac` based on `result.error === 'Failed to launch macOS app.'` tightly couples the renderer to the exact error string set in `buildLaunchError`; if that message ever changes, macOS error results will silently render as generic 'Launch App' failures with the wrong header and no params.