The fullscreen plugin view has a full-width tool bar above the logs and device panels. Each panel has its own controls. Logs sit on the left and both simulators on the right above 800px; smaller views place both simulators above logs. The Logs tab reopens the logs panel. Click Logs to collapse the left panel to a tab, then click it again to reopen. The panel beside a chat keeps the collapsible drawer below the simulator. Each view has its own UI resource, so the layout does not depend on the host's display-mode flag. Logs follow the foreground app on the selected device by default through an editable app:"com.example.app" clause in the search bar. The shared device-app store checks every three seconds and replaces that clause on app switches while preserving other search terms. An unnamed iOS foreground process uses an exact pid:123 clause. Collection includes all device processes; app switches filter existing rows and keep the same stream and buffer. Edit or clear the app clause to stop automatic following and control the visible apps yourself. Clearing the search shows other apps' buffered logs, subject to the source, level, and system-noise settings. If discovery fails or reports no foreground app, the automatic clause is removed and collection continues. Follow foreground app in Log sources enables automatic following again. Choosing another Android log device disables automatic following. No app launch, restart, or debugger attachment is needed.
For Metro, enter its local URL and click Find sources. Select the app and device in Metro app. Native source follows the device selected in the panel. You can also choose another connected Android device for logs. You can read native and Metro logs together. An explicitly chosen Metro target stays connected; its app metadata participates in the same visible search query as native logs. Metro target selection remains explicit.
Hide iOS system noise in Log settings is enabled by default for simulators and physical iPhones. It applies 34 Apple subsystem-family rules and seven framework exclusions before buffering. These include DevSuite's original exclusions plus observed SystemConfiguration, CoreAudio, LaunchServices, push-service, location, Wi-Fi, Bluetooth, brightness, and developer-connection chatter. Routine logs are hidden, while errors, faults, warnings, and unrecognized levels stay visible. Rules use DevSuite's ordering debug < default/notice < info < error < fault; UIKit, CFBundle, UIKitCore, CoreFoundation, MobileGestalt, container-manager and CoreAnalytics rules stop at default/notice, so their info records remain visible. Subsystems match without regard to case, including dot-separated children: com.apple.xpc.transaction inherits the com.apple.xpc rule, while com.apple.xpcustom does not. Custom app subsystems remain visible. Sender image paths use case-sensitive substrings. Switching the setting restarts collection and clears current logs. Previously excluded records cannot be recovered. Android and Metro logs are unaffected. MCP callers can set options.native.hideSystemLogs: false to disable these exclusions.
JS and Native toggle each source. Info, Warn, Error, and Debug toggle each level.
The search field supports DevSuite-style keyword filters. Plain keywords match log text, stack traces, and metadata; spaces mean AND and quotes keep phrases together. Use app:com.example.app, pid:123, level:error message:network, level:error level:warn (repeated fields mean OR without explicit operators or groups), age:5m, -message:noise, or network & (timeout | failed). App IDs and PIDs match exactly; native app IDs come from local process discovery, while Metro supplies its selected target's app ID. Regex uses message~:"error.*timeout"; quote patterns containing spaces or parentheses. Supported fields are app, pid, level, message, age, source, origin, process, tag, subsystem, category, stack, and timestamp. Level aliases include warning, err, and verbose; age accepts seconds, minutes, hours, and days (s, m, h, d). Age filters refresh once per second while Logs is visible, including when collection is paused. Filtering runs before repeat grouping so counts reflect matching occurrences. Open the help button beside the field for examples. Invalid syntax shows an inline error until corrected.
Stack groups exact repeats by source, level, device, and process and shows the count on the right. Follow keeps the latest rows in view. Scrolling away from the bottom turns Follow off; scrolling back to the bottom turns it on. Pause stops log readers; Resume opens a new session. Closing the drawer also stops its readers. Clear removes the buffered rows while the stream runs.
While Performance is visible, the log view is unmounted and the browser stops reading, filtering, and rendering log batches. Collection continues in the plugin's separate Node process, bounded to 2,000 records and 4 MiB per session. Returning to Logs immediately restores cached rows, filters, selection, and scroll position, then catches up from the same cursor when the app is unchanged. If the foreground app changed while Logs was hidden, reopening applies the latest search clause over the retained buffer and continues the same session. A small keep-alive once per minute retains the session without transferring logs. Closing the tools panel still stops collection.
The list shows messages without embedded JavaScript stack traces. Click a row to read its message and full stack in the details panel. Copy, search, and chat actions retain the original log. Attach to chat adds that log, its source, and its repeat count to the agent's next prompt, along with the selected simulator. Ask the agent to fix the error in your next message. Remove attachment clears the log. Each new attachment replaces the prior log. Removing the attachment in Codex also clears the panel's attachment state.
Right-click a log and choose Fix in chat or Ask in chat to attach the full log and stack trace as a context pill and send a short request. These actions wait for the attachment before sending and keep the log available if delivery fails. Hosts without context pills receive the full log in the message.
Expired log sessions reconnect without an error banner. Existing rows, filters, selection and scroll position remain available during recovery. Pause or closing Logs cancels the retry.
iOS simulators use xcrun simctl spawn <UDID> log stream --style ndjson --level debug. Physical iPhones use the bundled libimobiledevice OS trace relay reader over the existing paired USB or Wi-Fi connection. Select the phone in the device picker; no app launch, restart, debugger attachment, or app SDK is required. App ID searches continue across main-process PID changes. MCP callers can explicitly scope collection with an iOS executable name or PID, or an Android package. Unified logs exclude ordinary print/printf stdout/stderr output and may redact private values. Metro reads console events and exceptions through the inspector. Each log reader retries dropped connections. Metro keeps the chosen target ID; refresh its targets if an app restart assigns a new ID. Buffers hold at most 2,000 records and cap their byte size. The UI shares this capacity between JS and native logs, removing older rows from the busier source first. Native bursts no longer erase JS history. Legend List renders the visible rows and lets you scroll through all buffered matches.
npm run test:logs reads logs from an already booted simulator through the built MCP server. npm run test:ios-logs -- --device <hardware-UDID> reads a connected physical iPhone, with optional --process <executable-name>. Both print counts, close the log reader, and leave the device and app running. For tool-only physical logs, pass { platform: "ios", kind: "physical", deviceId: "<hardware-UDID>" } to mobile_logs_session; use the udid returned by mobile_list_ios_devices, rather than its coreDeviceId.