TL;DR
The decision in 20 seconds:
- xcsift formats
xcodebuildoutput. It does not run builds, manage simulators, install on devices, or stream app logs. You still own the orchestration. - FlowDeck replaces the orchestration. One CLI for the entire Apple toolchain, with versioned NDJSON output your agent or CI can parse directly, no piping required.
- If your only problem is verbose build logs eating LLM context, xcsift is a clean, focused fix. Pipe it into your existing scripts and move on.
- If your agent needs to run the app, see live logs, click a button, or read a test result without spawning
xcrunten different ways, you want FlowDeck.
What is xcsift?
xcsift is a Swift command-line tool by Łukasz Domaradzki that parses xcodebuild and Swift Package Manager output into structured formats AI agents can read efficiently. It installs via Homebrew (brew install xcsift) and runs as a Unix-style filter:
xcodebuild -workspace MyApp.xcworkspace \
-scheme MyApp \
-destination 'platform=iOS Simulator,name=iPhone 16' \
build 2>&1 | xcsift
Default output is JSON. With -f toon you get TOON, a token-optimized object notation that's 30-60% smaller than equivalent JSON. With the GitHub Actions renderer, you get inline workflow annotations. Beyond formatting, xcsift extracts code coverage from .profraw (SPM) and .xcresult (xcodebuild), reports per-target build timing, and flags slow or flaky tests.
There's also a companion MCP server, xcsift-mcp, and built-in subcommands (install-claude-code, install-codex, install-cursor) that wire xcsift into an agent's workflow with one command. The positioning is clear: stop wasting LLM context on raw build logs.
xcsift is the right tool for one specific problem: turning verbose xcodebuild stdout into something an agent can read without burning 50,000 tokens.
What xcsift does well
Three things xcsift gets right, and gets right cleanly.
Token economy
A 200-line xcodebuild log compresses to a small structured object with just the errors, warnings, and failures. TOON format pushes that further. If you run an agent loop where the bottleneck is context window, swapping raw build output for xcsift JSON is an obvious improvement and lands in your shell pipeline with zero ceremony.
Unix composability
xcsift does one thing: parse stdin into structured stdout. That means it slots into whatever you already have. A Makefile, a fastlane lane, a tuist generate && xcodebuild build chain, pipe it through xcsift and you keep your existing pipeline. There's no project lock-in, no config file required (though --init generates an .xcsift.toml if you want one), and no opinion about how you invoke xcodebuild.
Coverage and timing extraction
Beyond beautifying logs, xcsift pulls structured data out of .xcresult bundles and .profraw files, code coverage, per-target build times, slow test detection. That's useful in CI dashboards and useful for an agent asked "which test is making this suite slow?" without having to write the xcresulttool incantation itself.
The author's blog post, Stop Wasting Context on Build Output, frames the problem honestly: build logs are an LLM context tax, and most tools either parse them poorly or not at all. xcsift solves that one problem and stops there. That focus is a feature, not a bug.
Where the seams show
xcsift's scope ends where the build does. Everything downstream of xcodebuild exiting with code 0 is still your problem: simulators, devices, install, launch, app logs, UI automation, test discovery without a build, scheme detection, derived-data cleanup, signing. Each of those is its own Apple CLI with its own flag syntax, its own destination string format, and its own failure mode the agent has to learn.
Concretely, here are the seams an xcsift-based workflow leaves you to fill.
You still own the xcodebuild invocation
xcsift parses output; it doesn't construct destinations. Your agent still needs to write -destination 'platform=iOS Simulator,name=iPhone 16,OS=18.4' correctly, and that string changes every Xcode release. Get the OS wrong, get the simulator name wrong, get a quote wrong, and xcsift faithfully reports "build failed" without telling you the destination didn't resolve.
Simulators are xcrun simctl's problem
Booting, listing, finding the right UDID, installing the .app, launching the bundle ID, waiting for the app to come up, none of that is xcsift. An agent that builds successfully through xcsift then has to spawn xcrun simctl boot, xcrun simctl install, xcrun simctl launch, and parse their (unstructured) output to know whether each step worked.
Physical devices are xcrun devicectl
A different CLI, a different identifier format, a different set of failure modes. An agent shipping to a real iPhone has to learn a second tool that xcsift doesn't touch.
App logs are a separate pipeline
OSLog, os_log, and print() output don't appear in xcodebuild stdout. They live in xcrun simctl spawn booted log stream --predicate '...', with a predicate language an agent has to know. xcsift can't help here, it's not in the build path.
Test discovery still requires a build
If your agent wants to enumerate tests before running them, to pick a subset, to retry only failures, to verify a new test got registered, it has to build first, parse the test plan, and hope. xcsift can structure the post-build output, but it can't tell you "this scheme has tests X, Y, Z" without spinning up xcodebuild.
UI automation is out of scope
Tapping a button, typing into a field, screenshotting a screen, reading the accessibility tree, none of that is in xcsift's mandate. You'd reach for xctest, AXe, or a separate Appium/Maestro stack. The agent now has three tools to learn and three failure surfaces to handle.
Output is parsed at the end, not streamed during
Because xcsift is a Unix filter, it processes stdout after xcodebuild finishes (or in a buffered chunk if you tee). For long builds that's fine; for an agent that wants live progress, "compilation started on target X, 12 of 47 files done", it's not the right shape. The structured event has to wait for the build to be over.
No project state
xcsift has no notion of "this project's scheme is MyApp, the simulator I last used was iPhone 16, the build is configured as Debug." Every invocation, the agent reconstructs the world from scratch. That's a feature for a pure filter; it's friction in a build loop the agent runs forty times an hour.
None of this is a knock on xcsift. It's just not what xcsift is for. But if your goal is "give my agent a reliable, low-friction way to develop an iOS app end-to-end," parsing build output is one small piece, and the surface area xcsift doesn't cover is most of the work.
How FlowDeck addresses each seam
FlowDeck takes the same problem xcsift identified, raw xcodebuild output is hostile to agents, and pushes the solution up the stack. Instead of parsing whatever xcodebuild emits, FlowDeck owns the invocation and emits versioned NDJSON events directly. Then it does the same for everything downstream of the build.
Seam by seam:
- Destinations
-S "iPhone 16"or-D "My Mac". FlowDeck resolves simulator and device names against the live runtime list and constructs the destination string itself. If the simulator doesn't exist, you get a typed error with the available names, not a generic "no destinations matched."- Simulators
flowdeck runhandles boot, install, and launch in one command.flowdeck simulator boot "iPhone 16 Pro"if you want it explicit. Noxcrun simctlneeded. The bundle ID is read from the build product, not constructed from a guess.- Physical devices
- Same surface.
-D "iPhone"matches a paired device by name. Pairing, signing, and installation happen behind one command. You don't learnxcrun devicectl; you don't need to. - App logs
flowdeck logs <app-id>. Per-app filtering at the app's bundle ID and subsystem.OSLog,print(), and crash output, formatted and live, no predicate language to learn. Pipe it torgfor filtering, or to nothing if you just want to read it.- Test discovery
flowdeck test discover --json. AST parsing, no build required. The agent can enumerate tests, pick a subset, and callflowdeck test --only LoginTests/testValidLogin, all without spinning upxcodebuildfirst.- UI automation
flowdeck ui simulator session start, thentap,type,swipe,screen,tree. The accessibility tree comes back as structured JSON. Screenshots are JPEGs the agent can read. macOS apps get the same:flowdeck ui mac click,type,menu click "File > Save". Not bolted on; same CLI, same output contract.- Streaming events, not buffered parse
- FlowDeck's
--jsonmode emits NDJSON live. Build start, per-file compile, warning, error, build complete, each one is a line on stdout the moment it happens. Your agent can react mid-build instead of waiting for the buffer to close. - Project state
- FlowDeck saves your scheme, simulator, device, and configuration to
.flowdeck/config.json. Every subsequentflowdeck builduses those defaults. The agent stops re-deriving the world on every invocation; it just runs the command. - One stream, one contract
- Build output, test output, log output, UI tree, simulator state, all on the same versioned NDJSON schema. Your agent learns one output format, not eight.
xcsift fixes one token tax: noisy build logs. FlowDeck removes the orchestration tax that's eating the rest of your agent's context.
A day in the loop, side by side
The workflow: build, run on a simulator, stream logs while the agent codes, run one failing test.
With xcsift, seven commands across four tools and two shell sessions:
# 1. Discover schemes
xcodebuild -list -workspace MyApp.xcworkspace 2>&1 | xcsift
# 2. Build
xcodebuild -workspace MyApp.xcworkspace \
-scheme MyApp \
-destination 'platform=iOS Simulator,name=iPhone 16' \
-configuration Debug build 2>&1 | xcsift
# 3. Find the .app and bundle id
xcodebuild ... -showBuildSettings | grep BUILT_PRODUCTS_DIR
/usr/libexec/PlistBuddy -c 'Print :CFBundleIdentifier' \
"$BUILT/MyApp.app/Info.plist"
# 4. Boot the simulator
xcrun simctl list devices available
xcrun simctl boot <UDID>
# 5. Install + launch
xcrun simctl install <UDID> "$BUILT/MyApp.app"
xcrun simctl launch <UDID> com.example.MyApp
# 6. Stream logs (in another shell)
xcrun simctl spawn <UDID> log stream \
--predicate 'process == "MyApp"' --style compact
# 7. Run one failing test
xcodebuild test \
-workspace MyApp.xcworkspace \
-scheme MyApp \
-destination 'platform=iOS Simulator,name=iPhone 16' \
-only-testing:MyAppTests/LoginTests/testValidLogin \
2>&1 | xcsift
Every step the agent gets wrong is its own debugging round trip. The destination string, the UDID lookup, the predicate language, the bundle-id extraction, every one of those is a chance for a tool call to fail in a way xcsift can't recover from, because none of it is upstream of xcsift.
With FlowDeck, four commands, one tool:
# 1. Discover (instant, no build)
flowdeck context --json
# 2. Build, install, and launch
flowdeck run
# 3. Stream logs
flowdeck logs <app-id>
# 4. Run one failing test
flowdeck test --only LoginTests/testValidLogin
Every step emits NDJSON the agent can read directly. No predicate language. No PlistBuddy. No "find the .app." The agent's context budget goes to thinking about your code, not parsing four different tool outputs into one mental model.
When xcsift is still the right answer
FlowDeck is not the answer to everything. Here's when to stay on xcsift.
- You have an existing Make-based or fastlane-based pipeline you don't want to touch.
- If your team's CI is a complex shell chain with
xcodebuildcalls embedded across dozens of scripts, dropping xcsift in front of those calls is a one-line change with immediate token savings. FlowDeck is a different posture, it owns the invocation, and that's a bigger migration than your release window allows. - You're on Linux for SPM-only work.
- FlowDeck targets Apple platforms and requires Xcode locally. xcsift runs on Linux for parsing
swift buildoutput. If your agent is building a Swift Package on a Linux runner, xcsift is the right tool for that runner. FlowDeck won't help, Apple's toolchain isn't there to wrap. - You specifically want TOON.
- If you've benchmarked your agent and the bottleneck is the JSON size of structured build output, TOON is a real win and FlowDeck doesn't emit it (today). Pipe FlowDeck's NDJSON through a converter if you need it, or run xcsift on the upstream
xcodebuildoutput as a preprocessing step, they're not mutually exclusive.
The rule of thumb: xcsift is the right answer when build output is your only problem. Once the agent has to do something with a successful build, run it, log it, click it, test a subset of it, you've outgrown a stdout filter.
Annex
Quick reference
The scannable summary.
| Capability | xcsift | FlowDeck |
|---|---|---|
| Runs builds | No, pipes xcodebuild stdin |
Yes, owns the invocation |
| Build output format | JSON, TOON, GitHub Actions | Versioned NDJSON, streamed live |
| Destination handling | Your problem | -S "iPhone 16" |
| Simulator boot / install / launch | Your problem (xcrun simctl) |
flowdeck run |
| Physical devices | Your problem (xcrun devicectl) |
-D "iPhone" |
| Stream app logs | Out of scope | flowdeck logs |
| Test discovery without build | No | AST-based, instant |
| Run a single test | Construct -only-testing:... manually |
--only LoginTests/testValidLogin |
| UI automation | Out of scope | Built in (iOS + macOS) |
| Code coverage | Yes, .profraw + .xcresult |
Via xcresulttool; first-class roadmap item |
| Project state (scheme / sim defaults) | None | .flowdeck/config.json |
| Editor extension | None | VS Code / Cursor |
| Runtime | Swift binary | Swift binary |
| Install | brew install xcsift |
curl | sh |
| License | Open source | Commercial |
FAQ
Is xcsift a replacement for xcodebuild?
No. xcsift parses the output of xcodebuild (or swift build). You still run xcodebuild yourself and pipe its stdout into xcsift. It's a filter, not a build system.
Can I use xcsift and FlowDeck together?
Technically yes, FlowDeck's text mode is human-readable and could be piped through xcsift, but the result is redundant. FlowDeck already emits structured NDJSON via --json, which is the same problem xcsift solves at the xcodebuild layer. If you want TOON specifically, run xcsift on FlowDeck's underlying xcodebuild calls, but at that point you've reintroduced the layering FlowDeck removed.
Does FlowDeck support TOON output?
Not as of this writing. FlowDeck emits NDJSON, which is more compact than pretty-printed JSON but not as token-efficient as TOON. If TOON is a hard requirement, the underlying event model would make a TOON renderer a small addition.
What about xcsift-mcp vs FlowDeck?
xcsift-mcp wraps xcsift in an MCP server so agents can call it as a tool. The comparison is the same shape: xcsift-mcp gives your agent structured build output via MCP; FlowDeck gives your agent the whole Apple toolchain via a direct CLI with NDJSON. For the trade-offs between CLI and MCP transports specifically, see FlowDeck vs XcodeBuildMCP.
Does xcsift run on Linux?
Yes, for parsing swift build output. Code coverage features are macOS-only. FlowDeck is Apple-platform only, it requires Xcode, which is a macOS dependency, so for Linux SPM CI, xcsift is the natural fit.
If I'm already running xcsift on CI, why switch to FlowDeck?
If CI is the only place you need structured build output, you don't need to switch. The case for FlowDeck is when an agent or developer is doing more than building, running the app on a simulator, streaming logs, driving UI, picking specific tests, or working across iOS and macOS in the same flow. At that point, the rest of your shell pipeline becomes the bottleneck, not the build log.
Is xcsift faster than FlowDeck's build path?
For the parse step alone, xcsift and FlowDeck are comparable, both are native Swift, both stream. End-to-end, FlowDeck is usually faster because it skips redundant xcodebuild -list calls, caches scheme and simulator metadata, and discovers tests via AST instead of building. The agent loop is faster when the orchestration is collapsed, not when one stage is optimized.
Is FlowDeck open source?
FlowDeck is a commercial product with a 14-day free trial. xcsift is MIT-licensed open source. If license is the decision criterion, the comparison ends there. The commercial model funds stable releases, a published roadmap, and support; for teams that want a supported tool with no breaking changes between minor versions, that's the trade.
Where to next
- FlowDeck vs
xcodebuild, the build system underneath both tools. - FlowDeck vs XcodeBuildMCP, CLI vs MCP transport, and the agent-loop trade-offs.
- Give AI agents an iOS build loop, wire Claude Code or Codex to FlowDeck end-to-end.
- MCP vs CLI for AI-powered iOS development, the deeper read on transport choice.
- Start your FlowDeck free trial, install in one command, no credit card.