Skip to content
CAI
Software that uses CAICheck a score

tddworks/baguette

43.1

Weak · 1 October 2026

34.5k

lines of production code

Swift

with JavaScript, Objective-C

2

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

Baguette is a headless iOS simulator manager and companion tool that extends the standard Xcode simulator with advanced automation, testing, and visualization capabilities. It provides a comprehensive CLI and web-based interface for controlling device state, including input dispatch, network conditioning, motion simulation, and camera injection, while supporting complex hardware configurations like foldable devices and companion screen streaming. The system features a secure, git-backed plugin architecture that allows users to extend functionality for accessibility auditing, deep-link testing, and media management without compromising security boundaries.

Features

Add 3D model definitions for new iPhone, iPad, and Apple Watch devices

The 3D model resource directory now includes definition files for several new device types, enabling accurate 3D rendering in the simulator. This adds support for iPhone 17, iPhone 17 Pro, iPhone 17 Pro Max, iPhone Air, iPhone Duo, iPad Pro 11-inch (M4), iPad Pro 13-inch (M4), Apple Watch Series 11 (42mm and 46mm), and Apple Watch Ultra 3. Notably, the iPhone 17 Pro and Pro Max definitions include finish variants (Cosmic Orange, Deep Blue, Silver), and the iPhone Duo definition includes specific hardware button mappings and foldable device configuration.

Sources/Baguette/Resources/Models3D · high confidence

Add CLI screen recording capability

The \baguette record\ command is now available, allowing users to capture simulator screens as H.264 video in MP4 or MOV containers. This feature introduces a new domain layer in \Sources/Baguette/Domain/Recording\ that handles frame cadence, output formatting, and error reporting (such as device boot status and frame capture failures). The implementation uses \AVAssetWriter\ to write video files, supporting configurable frame rates, bitrates, and output sizes, while ensuring that recordings are only generated when the simulator screen actually changes.

Sources/Baguette/Domain/Recording · high confidence

Add bidirectional clipboard sync between simulator and host

Users can now copy content from the iOS simulator to the host Mac clipboard and paste text from the host into the simulator. This change introduces a new pasteboard surface that supports full-fidelity synchronization (including images) from the simulator to the host, and allows arbitrary Unicode text to be pasted into the simulator via the host clipboard.

Sources/Baguette/Domain/Pasteboard · high confidence

A new 'deeplink' plugin (v1.2.0) is introduced, providing a 'Deep Links' panel in the simulator UI. This panel allows users to type and open deep links, featuring auto-completion based on URL schemes registered by apps on the device. It also explicitly warns users when an HTTPS link is opened in Safari rather than a specific app, clarifying simulator behavior that differs from physical devices.

plugins/deeplink · high confidence

Add simulated location support for iOS simulators

This change introduces the \SimctlLocation\ implementation within the location infrastructure, enabling the application to control simulated GPS coordinates on iOS simulators. By wrapping \xcrun simctl\ commands, it allows users to set, start, or clear specific location routes for testing purposes.

Sources/Baguette/Infrastructure/Location · high confidence

Add simulator UI settings control for appearance, contrast, and content size

Users can now read and modify the simulator's user-interface settings, including light/dark appearance, increase contrast, and dynamic type content size. The new \Interface\ protocol and \SimctlInterface\ implementation expose these capabilities via \xcrun simctl ui\, allowing the application to toggle themes, adjust accessibility contrast, and step through text sizes. The system distinguishes between settable values and read-only states (such as \unknown\ or \unsupported\), refusing to apply non-settable values and returning clear error messages instead of failing silently or producing confusing CLI dumps.

Sources/Baguette/Domain/Interface, Sources/Baguette/Infrastructure/Interface · high confidence

Add simulator orientation control via domain model and event builder

This change introduces the core domain logic for controlling a booted simulator's interface orientation. It adds the \DeviceOrientation\ enum to represent portrait and landscape states, an \Orientation\ protocol to define the write-only interface for applying these states, and the \OrientationEvent\ builder to construct the specific Mach message required to notify the iOS guest of the rotation. This provides the foundational capability for the simulator to rotate its display.

Sources/Baguette/Domain/Orientation · high confidence

Add simulator shake capability

The application now supports triggering a motion-shake event on a booted iOS simulator. This is implemented via a new \Shake\ protocol and \MotionShake\ struct in the domain layer, which posts the \com.apple.UIKit.SimulatorShake\ Darwin notification into the simulator's guest namespace using \xcrun simctl spawn\. This allows the app to programmatically simulate the same hardware shake signal that the Simulator.app menu provides, enabling testing or automation of shake-based interactions without requiring code execution inside the target app.

Sources/Baguette/Domain/Shake · high confidence

Add simulator status bar override, clear, and read capabilities

Users can now manipulate the status bar of connected iOS simulators directly from the app. This change introduces a new \SimctlStatusBar\ implementation that wraps \xcrun simctl\ commands, enabling three specific actions: overriding the status bar appearance, clearing any overrides to restore the default state, and reading the current status bar configuration. This allows for more precise control and inspection of the simulator's UI state during testing or development workflows.

Sources/Baguette/Infrastructure/StatusBar · high confidence

Automated changelog release and documentation generation workflow

This change introduces a suite of scripts to automate the release process and documentation maintenance. The \promote-changelog.sh\ and \changelog-rollover.py\ scripts manage the CHANGELOG.md lifecycle by promoting the \[Unreleased\] section to a versioned release and archiving older minor versions into \docs/changelog/\ to keep the main file concise. The \extract-changelog.sh\ script allows retrieving release notes for specific versions. Additionally, \gen-docs.py\ automates the generation of the command reference (\docs/commands.md\) from the binary's help output and builds the documentation index (\docs/README.md\) from feature frontmatter, while \check-docs.py\ enforces documentation standards such as line budgets and link validity.

scripts · high confidence

Baguette 0.1.5 introduces plugin distribution, clipboard sync, and extensive CLI controls

This release adds a plugin system with git-backed distribution via bakeries (installing, adding, and removing plugins from trusted sources), synchronizes the simulator's selection to the host Mac clipboard via copy/paste dispatch, and expands the CLI with commands for screenshots, H.264 recording, 3D rendering, simulated GPS location, device orientation, hinge control, status-bar overrides, network state, motion, logs streaming, accessibility UI description, and double-tap gestures. It also simplifies number parsing in the reconfiguration parser, enforces plugin command timeouts, and exposes the version string via the CLI configuration.

Sources/Baguette/App · high confidence

CLI recording now outputs H.264 video files

The \baguette record\ command now generates H.264 video files (MP4 or MOV) instead of raw frames. This change introduces \AVAssetWriterReel\, which handles the actual encoding, compositing frames with a user-specified background color, and writing to a temporary file before moving it to the final destination. This ensures that recordings are saved as standard video files that can be played back directly.

Sources/Baguette/Infrastructure/Recording · high confidence

Expanded hardware button support and keyboard input capabilities

The input system now supports a wider range of hardware buttons, including power, volume, action, and Apple Watch controls, with configurable press durations to enable long-press gestures. Virtual buttons for app switching, home, and notification pulls have been added. Additionally, the system now supports keyboard input, allowing users to press individual keys with modifiers or type full ASCII text strings.

Sources/Baguette/Domain/Input · high confidence

Initial repository structure and development guidelines

The repository is initialized with foundational configuration and documentation files. A \.swift-format\ file enforces 4-space indentation and a 120-character line length. An \AGENTS.md\ file establishes strict TDD (Test-Driven Development) rules, requiring failing tests before production code changes, and defines the project's three-layer architecture (App, Domain, Infrastructure) along with naming conventions for abstractions. The \CHANGELOG.md\ is added following the Keep a Changelog format, documenting fixes for input command transmission waits and display enumeration issues in the unreleased section, and detailing the 0.2.1 release which includes fixes for accessibility hit-testing and stream stability. \CONTRIBUTING.md\ outlines build requirements (Apple Silicon, Xcode 26.4.1+), build/test commands, and code organization rules. A \baguette.json\ file defines the official plugin structure, and \codecov.yml\ configures coverage thresholds and ignores for infrastructure and command-layer files. The \.gitignore\ is updated to exclude build intermediates and injected dylibs. The \Makefile\ gains targets for web tests, documentation generation, and changelog validation. \README.md\ is significantly restructured to highlight the headless iOS Simulator manager capabilities, providing a quick start guide with Homebrew installation and basic CLI commands, while removing detailed route and wire protocol documentation in favor of linking to dedicated docs. Finally, \build.sh\ is updated to build injected dylibs and uses a remove-then-copy strategy to avoid macOS code signature caching issues.

(repo-wide) · high confidence

Introduce Baguette SDK for browser-based simulator integration

The Baguette SDK is now available as a client-side JavaScript library, enabling web pages to bootstrap and mount a simulator instance directly in the DOM. The SDK exposes a \Baguette.use()\ entry point that fetches a simulator definition by UDID and returns a \Simulator\ object with a \mount()\ method. It includes a modular architecture for input handling, featuring a \PointerInterpreter\ that unifies mouse, touch, wheel, and Safari native gesture events into a single interface, along with specific sources for edge-band detection, long-press simulation, and 3D screen-quads. The package also provides components for rendering CarPlay frames and managing device-specific bezels and screen pieces.

Sources/Baguette/Resources/Web · high confidence

Introduce Baguette Twin companion app for iOS screen and motion streaming

A new iOS companion app (Baguette Twin) allows users to pair their iPhone with a Mac host to stream the device's screen and gyroscope data in real-time. The app provides a UI to configure the Mac's host address, test the local network connection, and trigger the system broadcast picker to start streaming. The broadcast extension captures the screen using a hardware H.264 encoder and streams video chunks over WebSocket, while a separate motion sender streams gyroscope attitude data at 100 Hz. The implementation uses a shared App Group for configuration and a custom wire protocol (TwinWire) for framing text and binary data, ensuring the broadcast extension stays within memory limits by dropping stale frames during network congestion.

Companion · high confidence

Introduce declarative plugin system with capability-based access control

Baguette now supports a plugin system where extensions declare their capabilities (such as describe-ui, screenshot, input, logs, and media) and contribute UI elements like commands and side-panel lists via a manifest file. The host enforces a least-privilege model by issuing short-lived, per-invocation tokens that grant only the declared capabilities, ensuring that plugins cannot access routes or perform actions outside their scope. Plugins contribute declarative data structures rather than executable UI code, keeping the security boundary clear and preventing untrusted content from injecting markup into the host interface.

Sources/Baguette/Domain/Plugin · high confidence

Introduce device-twin domain structures for companion app communication

Added core domain models and protocols in the Device module to support the new device-twin feature, enabling the host to communicate with a companion app on a physical phone. This includes \TwinSession\ to manage the WebSocket handshake and state machine (hello, attitude, video format), \TwinEnvelope\ for parsing JSON messages, \Attitude\ for handling quaternion-based gyroscope data with smoothing and re-zeroing, \AVCCParameterSets\ for parsing H.264 codec parameters, and \Device\/\Devices\ to represent connected hardware. These changes establish the foundational data structures and parsing logic required for motion and video streaming from companion devices.

Sources/Baguette/Domain/Device · high confidence

Introduce device-twin infrastructure for mirroring physical iPhones

This change adds the core server-side infrastructure for the 'device-twin' feature, enabling the mirroring of physical iPhones. It introduces \LiveDevices\ to manage device registration via companion sockets, \TwinScreen\ and \VTH264Decoder\ to ingest and decode H.264 video streams from the device, and \TwinGyroState\ to process gyroscope data with interpolation and dead-band filtering for smooth pose synchronization. Additionally, \TwinPoses\ and \TwinScreens\ provide the necessary state management and fan-out mechanisms for motion and video data to multiple subscribers.

Sources/Baguette/Infrastructure/Device · high confidence

Introduce filesystem-based plugin discovery and bundled plugin support

Users can now extend the application via a plugin system that discovers plugins from directories on disk, specifically scanning \\~/.baguette/plugins/\ for installed marketplace plugins, \\<cwd\>/.baguette/plugins/\ for project-local plugins, and any path specified via the \--plugin-dir\ flag. The system prioritizes later roots over earlier ones, allowing local or installed plugins to shadow bundled defaults. Additionally, the application now ships with bundled plugins (such as a reference accessibility audit) located in the source tree or sidecar bundle, which are discovered automatically during development or standard installation, providing immediate toolbar functionality out of the box.

Sources/Baguette/Infrastructure/Plugin · high confidence

Introduce git-backed bakery infrastructure with secure, atomic plugin management

This change adds the core infrastructure for distributing and managing plugins via git-backed bakeries. It introduces \FileSystemBakeries\ to handle the trusted sources registry (\bakeries.json\) and installed plugin provenance (\installed.json\) with thread-safe, atomic file operations to prevent data corruption during concurrent installs. It also adds \GitCheckout\, a secure git client that performs shallow clones (\--depth 1\) without recursing into submodules, enforces strict timeouts to prevent hanging, and uses a staging-directory-then-swap strategy to ensure atomic updates and prevent race conditions during plugin installation or preview.

Sources/Baguette/Infrastructure/Bakery · high confidence

Introduce git-backed plugin bakeries with pinned commits and trusted-source installation

Users can now add external git repositories as trusted "bakeries" to source plugins, with each bakery pinned to a specific commit to ensure reproducible, safe installations. The system validates bakery menus to prevent path-escape vulnerabilities, supports multiple reference formats (GitHub shorthand, URLs, SCP), and allows installing plugins from these trusted sources directly via the browser after initial terminal-based trust establishment. A new \bakery outdated\ command helps users see when pinned sources have moved, while the architecture ensures that only explicitly trusted bakeries can serve plugins, maintaining a clear security boundary between trusted and untrusted sources.

Sources/Baguette/Domain/Bakery · high confidence

New 3D device rendering engine with foldable and live-stream support

The render domain now supports high-fidelity 3D device previews, replacing the previous implementation with a new architecture that handles both standard phones and foldable devices. Users can now view devices in 3D with live camera controls, adjustable rotation, and zoom. For foldable devices, the system renders the 'book' pose, correctly projecting the unfolded and cover screens onto the 3D mesh based on the hinge angle, and supports hardware button interaction. The feature includes a live 3D stream for real-time updates, optional cover-glass reflections, and a device model catalog that matches physical hardware identifiers to 3D assets. Render options allow for custom backgrounds, screen fit modes (cover/contain/stretch), and variant selection (e.g., color/material changes).

Sources/Baguette/Domain/Render · high confidence

This update introduces a suite of new command-line tools for interacting with iOS simulators. Users can now install app bundles or add media files directly via \install\ and \add-media\, and manage clipboard content with \clipboard get/sync/copy\. Deep link testing is supported via \openurl\ (which warns about universal link limitations) and \schemes\ to list available URL schemes. Accessibility debugging is enabled through \describe-ui\ to dump the UI tree. Plugin distribution is managed via the \bakery\ command group (add, list, outdated, remove, update). Device configuration is expanded with \interface\ (appearance, contrast, text size), \location\ (set, start, walk, clear), \hinge\ (for iPhone Duo), \lifetime\ (simulator app quit behavior), and \heal\ (to reclaim input surface from Xcode 27). Additionally, \logs\ streams unified logs, and \diag-digitizer-trackpad\ provides a diagnostic probe for trackpad input events.

Sources/Baguette/App/Commands · high confidence

New Expo/React Native example plugins for simulator input

Added an \expo-bakery\ example demonstrating two plugins (\expo-reload\ and \expo-devmenu\) that send keyboard chords (⌘R and ⌘D) to a focused simulator via the HTTP input route. The example includes the plugin manifests declaring the \input\ capability, Python scripts that POST to \/simulators/:udid/input\, and a \baguette.json\ configuration, illustrating how plugins can interact with the running server using environment variables.

examples · high confidence

New Injected tools for iPhone Duo hinge control and simulator virtual camera/motion

The Injected area now includes three new components: HingeControl, which drives the iPhone Duo's hinge and hardware keys by registering virtual HID services inside the simulator; VirtualCamera, a dylib that injects into simulator apps to provide a working camera feed from a Mac webcam via shared memory, including support for photo capture and preview layer rendering; and VirtualMotion, which fabricates CoreMotion data objects (activity, pedometer, accelerometer, gyro, device motion) to simulate motion sensors in the simulator.

Injected · high confidence

New RealityKit-based 3D device rendering with foldable support

The 3D rendering engine has switched from SceneKit to RealityKit, providing a persistent live-stream pipeline for device models. This change introduces support for foldable devices, including real-time hinge angle updates, centered book-pose animation, and separate screen rendering for unfolded and cover panels. The new system features studio-quality HDR lighting, optional cover-glass reflections, and supersampled antialiasing for screen edges. It also includes a verified asset cache that downloads and validates 3D models via SHA-256, and a Metal-backed render target ring for efficient real-time frame delivery.

Sources/Baguette/Infrastructure/Render · high confidence

New accessibility audit plugin with display settings control

A new 'a11y' plugin (v1.2.0) is available to help users verify and adjust accessibility conditions. It introduces an 'Accessibility' panel that runs an audit against the current screen, checking for interactive elements missing labels, tap targets smaller than the 44x44pt Human Interface Guidelines minimum, and duplicate identifiers that could cause UI test ambiguity. Additionally, a 'Display & Text Size' panel allows users to toggle Dark/Light appearance, enable Increase Contrast, and select from five standard accessibility text sizes (plus step-up/step-down controls), enabling them to re-run audits under specific rendering conditions.

Sources/Baguette/Resources/Plugins/a11y · high confidence

New accessibility domain for reading and merging the simulator UI tree

This change introduces the core domain logic for accessing the simulator's accessibility tree. It adds AXNode to represent UI elements, AXElementReader to extract properties from the Objective-C runtime, and AXFrameTransform to map macOS host coordinates to device points. To handle elements missed by the standard recursive tree walk (such as SpringBoard's status bar or childless SwiftUI containers), it implements AXHitTestGrid for position-scoped hit-testing and AXNodeMerge to graft these discovered elements into the tree, ensuring a complete and accurate representation of the on-screen UI.

Sources/Baguette/Domain/Accessibility · high confidence

New camera input sources: webcam, video files, and still images

The camera infrastructure now supports three distinct input types for the simulator. Physical webcams are captured via AVFoundation with resolution capping to fit the shared canvas. Users can also stream video files (looping playback with timestamp-based pacing) and still images (re-emitted at a fixed cadence to keep the buffer fresh). A new staging system securely handles browser-uploaded camera sources, and a shared-memory sink delivers frames to the in-simulator dylib.

Sources/Baguette/Infrastructure/Camera · high confidence

New camera streaming domain with virtual camera support

The simulator now supports streaming camera input from a host webcam, a still image, or a looping video file via a new virtual camera mechanism. Frames are captured on the host, converted to tightly-packed BGRA, and written into a shared-memory ring buffer that a dylib injected into the simulator reads. Users can select the source type, toggle display preferences like fit-to-fill and mirroring, and see the stream reflected in the simulator's camera feed.

Sources/Baguette/Domain/Camera · high confidence

New domain models for simulated location walking and bearing

Added core domain types in the Location module to support joystick-driven simulator location walking. Bearing normalizes compass directions to \[0, 360) and provides cardinal point readouts. Coordinate validates lat/lon ranges and implements great-circle projection logic for calculating new positions along a bearing. LocationRoute defines multi-waypoint routes with optional speed, distance, and interval tuning for simctl. LocationWalk models the joystick vector (origin, bearing, speed) and projects it into LocationRoute instances, enabling smooth, continuous simulated movement rather than discrete point updates.

Sources/Baguette/Domain/Location · high confidence

The server now exposes dedicated HTTP endpoints to support a new plugin system and enhanced device management. Plugins can interact with the simulator via routes for accessibility inspection (\describe-ui.json\), input dispatch (\input\), and command execution (\/plugins/:id/commands/:cmd\), while the browser can manage trusted plugin sources through bakery preview and install endpoints. Physical device support is expanded with companion-screen routes for CarPlay and watch pairing, deep-link handling with scheme completion, and interface setting controls (appearance, contrast, content size). These changes enable plugins to drive simulator features and allow the UI to manage companion displays and device settings directly.

Sources/Baguette/Infrastructure/Server · high confidence

Simulator domain model refactored to protocol-based architecture with new foldable and companion device support

The simulator domain layer has been restructured from a concrete struct to a protocol-based architecture (Simulator, DeviceHost, Display, etc.) to enable mocking and cleaner separation of concerns. This change introduces native support for foldable devices, including hinge angle monitoring, panel binding, and motion control via new Hinge domain types. It also adds support for companion screens, allowing the simulator to stream and manage external displays (CarPlay) and paired Apple Watches. Additionally, the input surface handling now detects and heals from Xcode 27's Device Hub shadowing, and the SDK bootstrap definition (SimulatorDefinition) has been expanded to include detailed chrome, button, and screen geometry data for the JS facade.

Sources/Baguette/Domain/Simulator · high confidence

Simulator infrastructure refactored to support foldable devices and multi-feature dylib injection

The simulator backend has been restructured to support complex device configurations, specifically foldables like the iPhone Duo, by introducing \CoreSimulator\ as the central production implementation that resolves device state and delegates to specific feature handlers (screen, input, hinge, motion, network, etc.). This change adds support for foldable-specific behaviors, including hinge angle monitoring via \SharedHinge\, binding to the correct lit panel on dual-screen devices, and hardware key input for foldables. Additionally, the system now supports injecting multiple dylibs (such as for motion and network simulation) into the simulator environment concurrently by using a unified \DYLD\_INSERT\_LIBRARIES\ management strategy with file-based locking to prevent race conditions, and introduces a generic \InjectedDylibInstaller\ to handle dylib resolution and installation from various build configurations.

Sources/Baguette/Infrastructure/Simulator · high confidence

Simulator motion simulation via injected dylib

Added a new motion domain that allows simulating device movement (walking, running, cycling, automotive) in iOS simulators. Since simulators lack native motion sensors, this feature uses an injected dylib to expose motion data to apps. It classifies movement based on speed, maintains cumulative step and distance totals across multiple legs of a walk, and requires explicit activation before location-based movement can drive the simulation.

Sources/Baguette/Domain/Motion · high confidence

Users can now apply network degradation profiles (such as 3G, LTE, or Very Bad Network) to iOS simulators. This feature introduces a validated \NetworkCondition\ model that translates Network Link Conditioner presets into specific latency, bandwidth, and loss parameters, and uses a shared file mechanism to arm a dynamic library that enforces these conditions on simulator apps. The implementation includes stable JSON encoding for cross-process communication and automatic schedule calculation to pace network traffic accurately.

Sources/Baguette/Domain/Network · high confidence

Simulator network conditioning via shared file and dylib injection

A new \SharedFileNetwork\ implementation enables network condition simulation on iOS simulators by writing atomic JSON condition files to \/tmp\ and arming a dynamic library via \DYLD\_INSERT\_LIBRARIES\. This allows the simulator to throttle or modify network behavior for specific apps, with per-simulator file scoping to prevent cross-device interference and explicit handling of stale conditions to ensure accurate state reporting.

Sources/Baguette/Infrastructure/Network · high confidence

Simulator status bar override and read capabilities

Users can now pin specific status-bar indicators (time, carrier, network type, signal bars, battery state/level) to fixed values on a booted simulator via the \override\ command, and restore live readings with \clear\. A new \read\ command allows fetching the current override state via \simctl status\_bar list\, enabling UI controls to hydrate from the device's actual configuration rather than guessing.

Sources/Baguette/Domain/StatusBar · high confidence

Support for foldable devices, per-button images, and actionable bezel interactions

The Chrome domain now supports multi-panel devices (such as the iPhone Duo) by exposing secondary panel assets and framebuffer masks, ensuring correct screen clipping and sizing for unfolded states. Bezel rendering has been enhanced to support 9-slice composition as a fallback, read device padding from configuration for accurate button overshoot, and expose per-button rasterized images with hover/press states (including depressed sprites) via the layout JSON. These changes enable the front end to render buttons as separate, animatable DOM elements layered over a bare bezel, providing a more realistic interactive experience.

Sources/Baguette/Domain/Chrome · high confidence

Support for iPhone Duo hinge angle monitoring and control

This change introduces infrastructure to read and control the hinge angle of the iPhone Duo device. It adds a \DevicectlHinge\ implementation that queries the hinge angle via \xcrun devicectl\ and streams real-time angle updates. A \SharedHinge\ class manages these subscriptions efficiently, ensuring a single monitor per device while providing immediate standing angles to new watchers. Additionally, a \GuestHingeMotor\ is added to drive the hinge physically by sending commands to a guest service, enabling programmatic folding and hardware key presses.

Sources/Baguette/Infrastructure/Hinge · high confidence

Support for importing media files into the Simulator's Photos app

Users can now drag and drop images or videos onto the app to automatically import them into the connected Simulator's Camera Roll. This change introduces a domain model for media items (classifying supported formats like PNG, JPG, HEIC, MP4, etc.) and an infrastructure adapter that executes \xcrun simctl addmedia\ to perform the import, enabling seamless media transfer from the host to the device.

Sources/Baguette/Domain/Photos, Sources/Baguette/Infrastructure/Photos · high confidence

Support for installing apps via drag-and-drop and zip archives

Users can now install iOS apps directly onto the simulator by dragging and dropping \.app\ bundles or \.ipa\ files. The system also accepts zipped folder-form \.app\ archives (\.zip\), automatically extracting them using \ditto\ to preserve executable permissions before installation. To ensure safety, the upload process includes a zip-bomb defense that checks the declared uncompressed size before extraction, rejecting archives that exceed the size limit. Additionally, the apps domain now supports opening deep links on the device, with intelligent routing that distinguishes between custom URL schemes (dispatched to the registered app) and web schemes (opened in Safari).

Sources/Baguette/Domain/Apps · high confidence

Support for multi-panel foldable devices and 9-slice bezel composition

The simulator now supports devices with multiple display panels (such as foldables) by resolving and rendering a distinct chrome bezel for each panel, including optional framebuffer masks to handle non-rectangular screen areas. For device types that no longer ship pre-baked composite images, the system automatically composes the bezel from nine separate PDF slices (corners and edges), ensuring crisp scaling by rasterizing each piece individually before stretching. Additionally, individual button images are now extracted and cached, enabling interactive visual states like depressed buttons in the UI.

Sources/Baguette/Infrastructure/Chrome · high confidence

Unified simulator log streaming with performance batching

The app now streams unified logs from iOS simulators in real time, replacing previous logging mechanisms. To maintain UI responsiveness during high-volume log output, log lines are automatically batched (defaulting to 200 lines or every 50ms) before being sent to the interface. Users can filter these logs by severity level (default, info, debug), output style, specific bundle identifiers, or custom predicates. The underlying implementation introduces a robust subprocess abstraction to manage the \log stream\ process lifecycle, including graceful termination and error handling.

Sources/Baguette/Domain/Logs · high confidence

Behavioural changes

Coalesced framebuffer captures to prevent streaming runaway

The screen capture infrastructure now coalesces rapid framebuffer updates into a single pending capture, preventing the streaming process from running away when the composite rate exceeds the capture rate. This change introduces a \PendingCapture\ coalescer in \SimulatorKitScreen\ to avoid duplicate queueing and excessive XPC round-trips, while also adding an idle floor timer for specific display bindings and refactoring surface selection to respect explicit \DisplayBinding\ constraints rather than just picking the largest surface.

Sources/Baguette/Infrastructure/Screen · high confidence

Improved accessibility element detection via server-side hit-testing and coordinate mapping

The accessibility infrastructure now uses a server-side hit-test (via the 3-argument \objectAtPoint\ API) to detect UI elements that the static tree walk misses, such as SwiftUI tab bars and toolbars. It also introduces an \AXFrameTransform\ to correctly map macOS host-window coordinates to device points, ensuring accurate gesture routing, and refactors the AX setup into a reusable context to manage dispatcher tokens and timeouts more robustly.

Sources/Baguette/Infrastructure/Accessibility · high confidence

Improved screen binding logic and capture stability for foldables and CarPlay

The screen domain now uses a shape-based heuristic to correctly bind the active panel on foldable devices (like the iPhone Duo) by tracking the hinge's lit panel, preventing incorrect port assignments. It also introduces coalescing for framebuffer captures to prevent unbounded queue growth and performance degradation during streaming, and adds a minimum frame-rate floor to keep external displays (such as CarPlay) from freezing when frame callbacks stop.

Sources/Baguette/Domain/Screen · high confidence

Improved streaming stability and low-latency performance

The streaming infrastructure now uses a new \VideoFrameScaler\ to replace the previous \Scaler\, ensuring stable GPU buffer handling for the VideoToolbox encoder. The H.264 encoder supports a low-latency tuning mode that optimizes rate control and frame reordering, reducing input lag in the AVCC simulation tab. Additionally, the \WebSocketFrameSink\ now employs a \FrameBacklog\ to bound memory usage when clients fall behind, discarding older frames to maintain real-time delivery, and the \SeedFilter\ has been updated to track surface IDs to prevent race conditions with recycled framebuffer surfaces.

Sources/Baguette/Infrastructure/Stream · high confidence

Replaced mouse-event input path with digitizer dispatch to fix iOS 26 gesture regression

The input infrastructure now uses a dedicated digitizer event dispatch (\IOHIDDigitizerDispatch\) instead of the previous mouse-event path, resolving a regression in iOS 26/Xcode 26 where taps were misinterpreted as Home gestures or dropped. This change enables accurate edge-gesture support (swipe-to-home, app switcher) by correctly routing touches via \IndigoHIDMessageForTrackpadEventFromHIDEventRef\ and patching target/edge byte slots. It also introduces a \DeviceHost\ protocol for device resolution, adds support for CarPlay digitizer teardown safety, and extends input capabilities to include hardware button presses, keyboard modifiers, and Apple Watch button support.

Sources/Baguette/Infrastructure/Input · high confidence

Simulator motion intents are now published via per-simulator shared files

Motion intents for iOS simulators are now communicated through a dedicated JSON file located in /tmp, scoped per simulator UDID (e.g., /tmp/BaguetteMotion-\<udid\>.json) to prevent cross-simulator interference. This approach replaces previous mechanisms with atomic file writes to ensure that the injected dylib always reads a complete, parseable intent, while also handling the arming and disarming of the dylib injection via environment variables. If the required dylib is missing from the build, publishing an intent will now fail explicitly with a 'dylibMissing' error rather than silently succeeding.

Sources/Baguette/Infrastructure/Motion · high confidence

Simulator orientation changes now use direct Mach messaging

Orientation updates for booted iOS simulators are now handled by sending a \GSEventTypeDeviceOrientationChanged\ Mach message directly to the simulator's \PurpleWorkspacePort\. This replaces previous mechanisms with a reverse-engineered integration that resolves the workspace port via the device's bootstrap namespace and delivers the 112-byte orientation event buffer using \mach\_msg\_send\. This change ensures orientation changes are applied reliably to the guest OS interface without relying on higher-level abstractions that may fail or crash during device state transitions.

Sources/Baguette/Infrastructure/Orientation · high confidence

Stream validation, low-latency H.264 tuning, and frame backlog controls

The stream module now enforces stricter CLI validation by rejecting empty or unknown --display values instead of silently defaulting to the phone plane. It introduces a low-latency H.264 encoding preset that disables frame reordering and minimizes buffering to reduce input lag, alongside a new FrameBacklog component that caps buffered data at a 4MB byte budget to prevent slow consumers from causing unbounded memory growth. Additionally, the stream format enum now supports case iteration, and the AVCC envelope parser includes robust unwrapping logic to safely handle truncated or malformed chunks from device-twin ingest.

Sources/Baguette/Domain/Stream · high confidence

Unified capture size vocabulary and pixel geometry model

The capture system now uses a shared \CaptureSize\ model across Swift and JavaScript, ensuring that size presets (such as App Store dimensions, square, and aspect ratios) and resolution logic behave identically regardless of whether the request comes from the CLI, HTTP routes, or the toolbar. This change introduces a consistent rounding strategy (round half up) to eliminate pixel-level discrepancies between the Swift and JS implementations, particularly for \.cover\ fits. Additionally, a new \CaptureGeometry\ struct exposes the detailed pixel coordinates of the captured frame, including framebuffer dimensions, scaled pixels, and placement details, providing transparency into the exact geometry used during capture.

Sources/Baguette/Domain/Capture · high confidence

Unified log streaming for iOS simulators

The \baguette logs\ command now uses a new \SimDeviceLogStream\ to stream simulator logs via \xcrun simctl spawn\, replacing previous methods. This change ensures compatibility with iOS 26 by avoiding direct simulator API calls that require Apple signing, and introduces a robust \HostSubprocess\ abstraction to handle child process lifecycle, output piping, and signal handling safely.

Sources/Baguette/Infrastructure/Logs · high confidence

Fixes

Improved iOS simulator clipboard reliability with devicectl fallback

The simulator pasteboard implementation now attempts to write text using the \devicectl\ command first, falling back to the legacy \simctl pbcopy\ if that fails. This change addresses a regression in newer Xcode versions where \simctl pbcopy\ exits successfully but writes nothing, ensuring that copying text from the simulator to the host Mac clipboard works reliably across different Xcode and iOS versions.

Sources/Baguette/Infrastructure/Pasteboard · high confidence

Test coverage

Added comprehensive test coverage for the camera subsystem; Added regression tests for device chrome mapping and profile parsing; Added test coverage for app dispatchers, pasteboard operations, and terminal styling; Added test coverage for app installation, media upload, and deep-link routing; Added test coverage for device-twin communication and motion handling; Added test coverage for network condition validation, presets, and dylib integration; Added test coverage for simulator infrastructure and companion screens; Added test coverage for the Baguette Bakery plugin distribution system; Added test coverage for the Baguette motion simulation feature; Added test coverage for the logging subsystem; Added tests for 3D device rendering and foldable device support; Added tests for CLI command parsing and structure; Added tests for CaptureSize presets, resolution, and placement logic; Added tests for OrientationEvent wire-format and PurpleEventOrientation error handling; Added tests for StatusBarOverride parsing and SimctlStatusBar subprocess orchestration; Added tests for foldable device hinge monitoring and control; Added tests for interface settings, plugin system, and simctl orchestration; Added tests for location simulation, server routes, and device controls; Added tests for screen capture, display binding, and surface selection logic; Added unit tests for pasteboard copy, paste, and simctl orchestration; Added unit tests for simulator shake functionality; Added unit tests for streaming subsystem components; Added unit tests for the Accessibility subsystem; Added unit tests for the Baguette Web capture and device-filtering modules; Added unit tests for the new \baguette record\ CLI feature; Expanded test coverage for input handling, HID targets, and gesture parsing.

Dependencies

Update build configuration and add resource dependencies

The build manifest removes explicit linkage to SimulatorKit and CoreSimulator frameworks, switching to runtime dynamic loading to resolve launch path issues across different Xcode installations. It adds SceneKit as a linked framework to support the new device renderer. Additionally, the package now includes several resource directories: 3D model assets (USDZ), plugin bundles for accessibility auditing, and vendored dylibs for virtual camera, motion, network, and hinge control features. Test resources are also updated to include pre-encoded H.264 clips to ensure stable video decoding tests in CI environments.

(dependencies) · high confidence

Housekeeping

Documentation for network conditioning spike results and implementation plan

Added documentation for the network conditioning feature, including a spike results report (\plans/network-conditioning-spike.md\) and an implementation plan (\plans/network-conditioning.md\). The spike results confirm that a \URLProtocol\-based approach can intercept React Native \fetch\ and other HTTP traffic in the simulator, but requires both class registration and a configuration swizzle to be effective. The plan outlines the architecture for per-simulator network conditioning, including CLI commands, domain models, and a dylib for injection, while noting limitations such as the inability to intercept WebSocket or \NWConnection\ traffic.

.claude · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.

Score

  • CAI 45 → 43 (-2.1)
  • Rubric changed (rubric-2026.09.11 → rubric-2026.09.18) — scores are not directly comparable.

Lenses

  • Code Health 42 → 42 (+0.5)
  • Architecture 100 → 76 (-23.7)
  • Maturity 63 → 62 (-1.2)
  • Readiness 44 → 39 (-5.8)
  • Security 39 → 38 (-0.8)
  • Accessibility 58 → 61 (+3.2)
  • Performance 78 (new)

Resolved (22)

  • (anonymous)::attach (cognitive 18) (Sources/Baguette/Resources/Web/sim-3d.js)
  • (anonymous)::attach (cyclomatic 16) (Sources/Baguette/Resources/Web/sim-3d.js)
  • (anonymous)::boot (cognitive 21) (Sources/Baguette/Resources/Web/sim-native.js)
  • (anonymous)::boot (cyclomatic 19) (Sources/Baguette/Resources/Web/sim-native.js)
  • (anonymous)::toggle3D (cognitive 29) (Sources/Baguette/Resources/Web/sim-native.js)
  • (anonymous)::toggle3D (cyclomatic 21) (Sources/Baguette/Resources/Web/sim-native.js)
  • Documentation: no installation or build instructions (README.md)
  • Documentation: no installation or build instructions (docs/features/network.md)
  • Documentation: no installation or build instructions (docs/features/paste.md)
  • Documentation: no usage examples (README.md)
  • Documentation: written for insiders (docs/index.html)
  • Duplicated block (8 lines × 2) (Sources/Baguette/Infrastructure/Input/IOHIDDigitizerDispatch.swift)
  • Duplicated block (8 lines × 2) (Sources/Baguette/Infrastructure/Server/Server.swift)
  • High: security finding (details withheld)
  • Hotspot: Sources/Baguette/Resources/Web/capture/capture-size-menu.js (Sources/Baguette/Resources/Web/capture/capture-size-menu.js)
  • Hotspot: Sources/Baguette/Resources/Web/sim-camera.js (Sources/Baguette/Resources/Web/sim-camera.js)
  • Hotspot: Sources/Baguette/Resources/Web/sim-file-drop.js (Sources/Baguette/Resources/Web/sim-file-drop.js)
  • Near-duplicate member pair (43 shared lines) (Sources/Baguette/Infrastructure/Server/Server.swift)
  • No assertions: (Tests/BaguetteTests/Screen/ScreenSnapshotTests.swift)
  • Off-boarding risk: anonymized user #1
  • …and 2 more

New (101)

  • (anonymous) (cognitive 16) (Sources/Baguette/Resources/Web/baguette/gestures/screen-pieces.js)
  • (anonymous) (cognitive 20) (Sources/Baguette/Resources/Web/baguette/parts/button.js)
  • (anonymous) (cyclomatic 22) (Sources/Baguette/Resources/Web/baguette/parts/button.js)
  • (anonymous)::attach (cognitive 19) (Sources/Baguette/Resources/Web/sim-3d.js)
  • (anonymous)::attach (cyclomatic 17) (Sources/Baguette/Resources/Web/sim-3d.js)
  • (anonymous)::boot (cognitive 28) (Sources/Baguette/Resources/Web/sim-native.js)
  • (anonymous)::boot (cyclomatic 26) (Sources/Baguette/Resources/Web/sim-native.js)
  • (anonymous)::toggle3D (cognitive 47) (Sources/Baguette/Resources/Web/sim-native.js)
  • (anonymous)::toggle3D (cyclomatic 33) (Sources/Baguette/Resources/Web/sim-native.js)
  • Change coupling: DeviceScene.swift ↔ sim-3d.js (Sources/Baguette/Domain/Render/DeviceScene.swift)
  • Change coupling: DeviceScene.swift ↔ sim-native.js (Sources/Baguette/Domain/Render/DeviceScene.swift)
  • Change coupling: RealityKitDeviceScene.swift ↔ sim-3d.js (Sources/Baguette/Infrastructure/Render/RealityKitDeviceScene.swift)
  • Change coupling: RealityKitDeviceScene.swift ↔ sim-native.js (Sources/Baguette/Infrastructure/Render/RealityKitDeviceScene.swift)
  • Coverage not measured — Swift suite
  • Duplicated block (16 lines × 2) (Sources/Baguette/Infrastructure/Simulator/SimctlInputSurface.swift)
  • Duplicated block (21 lines × 2) (Sources/Baguette/App/GestureDispatcher.swift)
  • Duplicated block (5 lines × 2) (Sources/Baguette/Domain/Render/FoldedScreenProjection.swift)
  • Duplicated block (5 lines × 2) (Sources/Baguette/Infrastructure/Server/Server.swift)
  • Duplicated block (6 lines × 2) (Sources/Baguette/Infrastructure/Server/Server.swift)
  • Duplicated block (7 lines × 2) (Sources/Baguette/Domain/Render/Device3DCamera.swift)
  • …and 81 more

Changes since last survey

  • 61 commits — 42 feature/other, 19 fixes

By area

  • Sources/Baguette — 26 commits
  • (repo) — 15 commits
  • (root) — 13 commits
  • .github/workflows — 3 commits
  • docs/features — 3 commits
  • Tests/BaguetteTests — 1 commit

Notable commits

  • fix: Merge origin/main into fix/simctl-display-enumeration
  • fix: Merge origin/main into fix/simctl-display-enumeration
  • fix: Merge pull request #78 from tddworks/fix/xcode27-device-hub-hid-surface
  • fix: Merge pull request #84 from EYHN/fix/xcode27-pasteboard-copy
  • fix: Merge pull request #87 from tddworks/fix/help-strings-and-hinge-docs
  • fix: Merge pull request #88 from AprilNEA/fix/async-stream-lifecycle
  • fix: Merge pull request #89 from AprilNEA/fix/ax-descendant-hit-testing
  • fix: Merge pull request #90 from AprilNEA/fix/hid-send-completion
  • fix: Merge pull request #92 from AprilNEA/fix/simctl-display-enumeration
  • fix: fix(accessibility): hit-test descendants outside container bounds
  • fix: fix(input): await HID transmission before acknowledging gestures
  • fix: fix(input): reclaim the input surface from Xcode 27's Device Hub
  • fix: fix(pasteboard): write through devicectl before simctl pbcopy
  • fix: fix(simulator): bound display enumeration and preserve device sets
  • fix: fix(simulator): close capture pipes after pending reads stop
  • fix: fix(simulator): drain display enumeration without DispatchIO
  • fix: fix(stream): await termination without dispatchMain
  • fix: fix: help for stream --format and logs --level/--style lists what they accept
  • fix: merge: sync upstream main into HID completion fix
  • change: Merge pull request #79 from tddworks/feat/iphone-duo-xcode-27-1
  • …and 41 more

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

tddworks/baguette was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 1 October 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 6c42e586994a6d8139ca093c8107297db45d193f — the exact code this score is about.
  • Scored under rubric-2026.09.18 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-e569280dd5e2.