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:
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."
Simulatorsflowdeck run handles boot, install, and launch in one command. flowdeck simulator boot "iPhone 16 Pro" if you want it explicit. No xcrun simctl needed. 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 learn xcrun devicectl; you don't need to.
App logsflowdeck 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 to rg for filtering, or to nothing if you just want to read it.
Test discoveryflowdeck test discover --json. AST parsing, no build required. The agent can enumerate tests, pick a subset, and call flowdeck test --only LoginTests/testValidLogin, all without spinning up xcodebuild first.
UI automationflowdeck ui simulator session start, then tap, 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 --json mode 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 subsequent flowdeck build uses 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:
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:
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 xcodebuild calls 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 build output. 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 xcodebuild output 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.
Quick reference
The scannable summary.
Capability | xcsift | FlowDeck |
|---|---|---|
Runs builds | No, pipes | Yes, owns the invocation |
Build output format | JSON, TOON, GitHub Actions | Versioned NDJSON, streamed live |
Destination handling | Your problem |
|
Simulator boot / install / launch | Your problem ( |
|
Physical devices | Your problem ( |
|
Stream app logs | Out of scope |
|
Test discovery without build | No | AST-based, instant |
Run a single test | Construct |
|
UI automation | Out of scope | Built in (iOS + macOS) |
Code coverage | Yes, | Via |
Project state (scheme / sim defaults) | None |
|
Editor extension | None | VS Code / Cursor |
Runtime | Swift binary | Swift binary |
Install |
|
|
License | Open source | Commercial |
FAQ
Is xcsift a replacement for xcodebuild?
Can I use xcsift and FlowDeck together?
Does FlowDeck support TOON output?
What about xcsift-mcp vs FlowDeck?
Does xcsift run on Linux?
If I’m already running xcsift on CI, why switch to FlowDeck?
Is xcsift faster than FlowDeck’s build path?
Is FlowDeck open source?
