Skip to content

feat(setup): platform-aware wizard with manifest-driven workflow recommendations#365

Merged
cameroncooke merged 9 commits intomainfrom
feat/setup-platform-selection
Apr 26, 2026
Merged

feat(setup): platform-aware wizard with manifest-driven workflow recommendations#365
cameroncooke merged 9 commits intomainfrom
feat/setup-platform-selection

Conversation

@cameroncooke
Copy link
Copy Markdown
Collaborator

Closes #280. Replaces #281 (closed because the original PR head was on a fork we couldn't push to). Original commit by @ichoosetoaccept is preserved as the base of this branch.

Builds on the env var session defaults and --format mcp-json foundation landed in #272 to add the platform-aware wizard described in #269.

What this adds

New selectPlatforms step — the first substantive wizard prompt asks which platforms the project targets (macOS, iOS, tvOS, watchOS, visionOS) via multi-select. Previous choices are recovered on re-run from sessionDefaults.platform, sessionDefaults.simulatorPlatform, or the existing workflow set via inferPlatformsFromExisting.

Manifest-driven workflow recommendations — workflow manifests now carry a required targetPlatforms field (a union of iOS | macOS | tvOS | watchOS | visionOS, possibly empty). Setup derives recommended workflows from this metadata instead of a hard-coded mapping. Empty arrays mean "not platform-specific" (e.g. doctor, session-management, workflow-discovery).

Recommended vs. additional workflows in the UI — when target platforms are selected on a fresh setup, the wizard shows recommended workflows first as their own group, then offers an additional-workflows prompt. Existing configs and no-recommendation cases fall back to a flat list. Defaults stay minimal: simulator for simulator platforms, macos for macOS, both for mixed selections. Users can still pick anything regardless of platform.

macOS-only guard — when macOS is the only selected platform, both the simulator selection and device selection prompts are skipped (isMacOsOnly guard in collectSetupSelection). Stale simulatorId, simulatorName, and deviceId session defaults are cleaned from config on save.

platform session default — for single-platform selections, derivePlatformSessionDefault writes platform to sessionDefaults in config.yaml. For multi-platform the key is omitted and any existing platform value is deleted.

--format mcp-json includes XCODEBUILDMCP_PLATFORM — when a single platform is selected, XCODEBUILDMCP_PLATFORM is included in the output env block.

build_device platform supportbuild_device previously hard-coded iOS. It now accepts a platform argument (iOS | tvOS | watchOS | visionOS) using the same shared mapDevicePlatform() helper as build_run_device, get_device_app_path, and test_device. Device tools also normalize simulator-style session defaults like tvOS Simulator to device platforms like tvOS.

Audited targetPlatforms per workflow — values reflect actual tool support:

Workflow targetPlatforms
coverage iOS, macOS, tvOS, watchOS, visionOS
debugging iOS, tvOS, watchOS, visionOS (simulator-only)
device iOS, tvOS, watchOS, visionOS
doctor []
macos macOS
project-discovery iOS, macOS, tvOS, watchOS, visionOS
project-scaffolding iOS, macOS
session-management []
simulator iOS, tvOS, watchOS, visionOS
simulator-management iOS, tvOS, watchOS, visionOS
swift-package iOS, macOS, tvOS, watchOS, visionOS
ui-automation iOS
utilities iOS, macOS, tvOS, watchOS, visionOS
workflow-discovery []
xcode-ide iOS, macOS, tvOS, watchOS, visionOS

Companion docs PR

getsentry/xcodebuildmcp.com#7 carries targetPlatforms through the docs manifest pipeline and updates /docs/setup, /docs/workflows, and the contributor architecture note.

Notes

  • targetPlatforms is setup recommendation guidance only. It does not gate runtime exposure or replace predicates / tool capability checks.
  • Empty targetPlatforms means "not platform-specific" — these workflows are still selectable; they just aren't tied to a platform recommendation.

Ismar Iljazovic and others added 6 commits April 25, 2026 23:18
Introduce platform selection to the setup wizard, recommend workflows
per platform, and avoid prompting for a simulator when macOS is the only
platform selected. Add helpers and constants (SetupPlatform,
PLATFORM_WORKFLOWS, PLATFORM_OPTIONS, infer/derive/filter helpers), a
multi-select platform prompt, and make the setup flow platform-aware
(seed workflow defaults, filter simulators, preserve platform in
sessionDefaults). Add selectionToMcpConfigJson() and a --format mcp-json
option to print a ready-to-paste MCP client config JSON block
(runSetupWizard supports 'mcp-json' early-exit). Update tests
(createPlatformPrompter and four platform-aware cases) and CHANGELOG.md
to document the new behavior.
Add focused tests requested by the PR audit:
- Stale deviceId, simulatorId, and simulatorName are cleared when
  re-running setup with macOS-only after a prior iOS-with-device config.
- YAML persistence for tvOS, watchOS, and visionOS single-platform
  selections writes the correct platform string and selects a
  platform-matching simulator from a multi-runtime simctl listing.
- Verify filterSimulatorsByPlatforms matches a SimRuntime-style
  visionOS runtime via the xrOS keyword.
Replace three parallel string-literal cascades for SetupPlatform <-> session-defaults
platform conversion with two derived lookup tables, reusing the existing XcodePlatform
enum so the session-defaults platform value has a single source of truth.

Replace the inline visionOS/xrOS branch in filterSimulatorsByPlatforms with a
SIMULATOR_RUNTIME_KEYWORDS table so runtime keyword matching is data-driven.
Add `targetPlatforms` to the workflow manifest schema and populate it on
all built-in workflows. The setup wizard now derives recommended
workflows from this manifest metadata instead of a hand-coded
`PLATFORM_WORKFLOWS` map, and splits the prompt into recommended vs
additional workflows so the default selection stays minimal (macos
and/or simulator) while non-recommended workflows remain reachable.

Custom workflows from `config.yaml` and the workflow-discovery entry
declare empty `targetPlatforms`; tests for schema, exposure, registry,
and the setup wizard cover required/empty/invalid metadata and the new
recommended/additional prompt flow.
Extract a shared `devicePlatformSchema` and reuse `mapDevicePlatform`
across `build_device`, `build_run_device`, `get_device_app_path`, and
`test_device` so each device tool accepts a `platform` argument and
threads it into the xcodebuild invocation and log prefix.

The schema preprocesses simulator-flavored session defaults
(e.g. `tvOS Simulator`) down to the matching device platform so a
session configured for a simulator runtime still produces a valid
device build target. Tests cover the new platform argument, the
simulator-to-device normalization, and the rejected `macOS` case.
Add a guidance line to AGENTS.md and CLAUDE.md telling reviewers to
focus on behavior changes caused by the current branch and to ignore
known test flakes, environment setup issues, and nondeterministic tool
output churn unless explicitly asked to investigate them.
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Apr 26, 2026

Open in StackBlitz

npm i https://pkg.pr.new/xcodebuildmcp@365

commit: 1eb1734

@cameroncooke cameroncooke force-pushed the feat/setup-platform-selection branch from a5b3bfe to e3e2ee5 Compare April 26, 2026 19:30
@cameroncooke cameroncooke reopened this Apr 26, 2026
@cameroncooke cameroncooke force-pushed the feat/setup-platform-selection branch from 73b2730 to bfcff14 Compare April 26, 2026 19:39
The reminder workflow posted a PR comment when tool contract files
changed, but org-level GITHUB_TOKEN policy blocks the comment write
and the check stays failing without surfacing useful information on
the PR. Authoring guidance is maintained in the docs site at
xcodebuildmcp.com/docs/tool-authoring.
@cameroncooke cameroncooke force-pushed the feat/setup-platform-selection branch from bfcff14 to f0eb257 Compare April 26, 2026 19:40
Comment thread src/cli/commands/setup.ts Outdated
The setup wizard was writing the user's "which platforms does this
project target?" answer into sessionDefaults.platform, conflating UI
memory with a runtime tool-param default. It also relied on
sessionDefaults.simulatorPlatform (an internal cache) to recover the
non-macOS half of multi-platform selections, which silently reverted
[macOS, visionOS] to [macOS, iOS] on re-run.

Move wizard memory to a dedicated top-level setupPreferences.platforms
field. sessionDefaults.platform/simulatorPlatform are no longer touched
by setup; they remain agent-controlled session defaults. The mcp-json
output still seeds XCODEBUILDMCP_PLATFORM for fresh clients, since that
is an explicit env-var bootstrap, not internal state.

Follow-up #366 tracks moving simulatorPlatform out of sessionDefaults.
Comment thread src/cli/commands/setup.ts Fixed
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 82d3101. Configure here.

Comment thread src/cli/commands/setup.ts Outdated
The reverse mapping had a single consumer in the legacy
inferPlatformsFromExisting branch. After 82d3101 moved wizard memory
to setupPreferences.platforms, that lookup is gone and the constant is
dead. CodeQL flagged it.
@cameroncooke cameroncooke merged commit 6265454 into main Apr 26, 2026
12 of 13 checks passed
@cameroncooke cameroncooke deleted the feat/setup-platform-selection branch April 26, 2026 20:46
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.

feat(setup): platform-aware wizard — platform selection, smart workflow pre-seeding, macOS-only simulator/device skip

1 participant