.zsh.xcode owns the native Xcode action workspace and Apple skill export.
xcode owns both modes (xcode, xcode --export-skills) through one
same-source help companion; any other arguments delegate directly to
xcodebuild and keep its status.
- Nothing at load time. Source time defines functions only: never probe Xcode, enumerate projects, start Simulator, export skills or write files.
- Xcode owns Xcode semantics. Schemes, destinations, build/test/settings behavior, compatibility, dependency graphs and rebuild decisions come from Xcode's own tools; Compozsh never infers them from Git, timestamps or DerivedData.
- Actions are explicit execution boundaries. Build, Rebuild, Test, Analyze, Clean, Run and their variants may execute project scripts, plugins, macros, tests and app code. They run only when chosen, after screen restoration, against a revalidated container — never to populate details.
- Bounded and provider-free interaction. Every provider capture, item count and diagnostic is bounded during capture. Repaint, filtering, focus, scrolling and resize never invoke a provider.
- Native handoffs, disclosed. Device installation/launch and log streaming
are explicit native-tool handoffs, like a user's
git push; they are not Compozsh-owned network discovery. Logging privacy settings are never changed.
- Bare
xcodewalks upward fromPWDfor literal.xcworkspaceand.xcodeprojdirectories, stops at the nearest scope, offers workspaces before projects there, rejects symlink containers and never scans descendants. A dumb or noninteractive bare call may print the nearest container's safe native list instead of opening the workspace. - Request machine-readable JSON where the CLI offers it and parse it with the
system
plutil; accept the documented destination listing only after validating a fixed platform vocabulary and a literal stable identifier. - Bound every retained capture (currently 256 KiB; Run's build settings 5 MiB, see Run targets), diagnostic and item count, enforcing byte bounds during capture — including temporary files — rather than checking size afterward. Keep every validated scheme within bounds; an exceeded scheme bound fails with no partial catalog, while the destination list keeps its first 100 validated entries.
- Discovery is read-only coordination, though Xcode may inspect project and
package metadata. Always disable automatic package resolution and updates and
require versions from
Package.resolved. Never silently enable provisioning updates or skip package-plugin/macro validation. Keep these policy arguments centralized and test their exact presence and absence.
- One shallow controller over Container → Scheme → Destination → Action, using the shared renderer, screen owner, input loop, guide, focus language and cleanup; configuration choices return to the action dashboard. No new renderer, key parser, watcher, workflow framework, persistent project state or shortcut.
- Digit-select pages hold ten rows so every visible index is reachable with Option plus 0–9; ordinary paging reaches later candidates.
- Present Actions after scheme discovery. Destination discovery waits until Destination opens or an action needs one; browsing uncached schemes starts no provider. An unresolved action requires explicit destination selection with the pending action and its execution effects visible; canceling grants nothing.
- Interactive discovery uses the shared status view and input loop with one invocation-owned supervisor process group, bounded nonblocking streams and ownership-checked cleanup. Never background an untracked synchronous capture or launch a provider from an idle callback. Escape cancels initial discovery or returns from destination discovery; Ctrl-C aborts.
- Dispatch every action after screen restoration, first revalidating that the exact captured container leaf still exists, matches its project/workspace kind and isn't a symlink. Test may start a new screen session afterward using only its captured result snapshot.
- Destination compatibility may reuse an LRU of at most four successful parsed scheme snapshots inside the controller. Keep exact IDs, platforms, names, architectures and variants; never merge destinations by device ID alone.
- Preserve the complete validated destination specification through refresh, cached restoration, build, test, settings and launch. Explicit selections are kept separately from snapshots and evicted with them. Never cache raw output or failures; returning to a cached scheme makes no provider call.
- Refresh destinations replaces the current snapshot, keeping an exact surviving selection; a missing one becomes unresolved and needs a new choice. A refresh that can't retain its new snapshot forgets the prior entry and fails explicitly rather than allowing stale restoration.
- Release all entries on action, cancellation or exit; reopening
xcodeis always fresh.
- Build, Rebuild, Test, Rebuild & Test, Analyze, Clean, Build & Run and
Rebuild & Run are offered for every concrete destination Xcode reports; the
code-execution boundary is stated in the dashboard, README and
xcode --help. Native build/test output goes to the restored terminal. - Build, Test and Build & Run use Xcode's incremental
build/test. Rebuild and Rebuild & Run send orderedclean build; Rebuild & Test sendsclean testfor the exact scheme and destination. Recovery actions are never triggered automatically. - Both test modes add one temporary result bundle, then reopen a shared result
view from bounded
xcresulttoolsummaries, failed-test source locations and build issues: semantic success/failure colors, exact scheme/destination and mode, the native status preserved. Read no attachments or source contents, disable verbose test-diagnostic collection for that bundle, and remove it before presenting the snapshot. - With
pbcopyavailable, the result view may offer one Copy report and done candidate: plain text built only from the snapshot (native status, mode, test context, totals, every retained failure with identifiers, reasons, files and capture limits). Write it after screen restoration, recheck the captured executable, never read source files or the clipboard, and keep a failing test status whether or not copying succeeds. - The view and the report are two projections of one pure model over the retained snapshot, so they agree on totals, failures and files; each involved source location gets its own line.
- Resolve runnable
.appbundles (with validated bundle identifiers) or native Mac command-line products from boundedxcodebuild -showBuildSettings -jsonover at most 100 targets. Xcode reports about 42 KiB of settings per target, so this one capture has its own 5 MiB bound (or the user limit when larger), held in invocation memory and released on return; beyond it, Run fails with guidance that names the bound andZSH_XCODE_CAPTURE_MAX_BYTES. Several runnable products require an explicit shared Run product choice after building; Escape there launches nothing and returns 1, the shared cancel status (task semantics), and without interactive UI, ambiguity fails. Revalidate the chosen leaf. Never infer products by recursive filesystem search. - Mac: open a new instance of the exact built app with native
open, or run a built command-line product in the restored terminal, honoring the captured architecture. An app launch status is not its exit status. - Physical device: the selected Xcode's
devicectlinstalls and launches with the exact device ID and app path/bundle identifier (--terminate-existing --console); installation can replace the device's app. Interactive Run captures the owned child's output through one private FIFO in a mode-0700 directory into the shared log reader; plain fallback keeps the native foreground console. Stop restores the screen, forwards termination, drains for at most one second, then ends an unresponsive child with a check-the-device notice; revalidate the job before signaling, reap it, keep native failures, remove FIFO and directory. No app-stdin editor. Document wired/wireless communication, persistent installation, failure status and the absence of rollback. Never silently pair devices, enable Developer Mode, change signing or provisioning, launch another target after failure, or claim compatibility beyond the selected tools. LLDB and unified logging stay Simulator-only; reading, filtering and copying cover device output too. - Simulator:
xcrun simctlboots, installs and launches the chosen app; opening the selected Xcode's Device Hub or Simulator app is part of that action. Never choose a generic destination for a launch. Evidence: destination Run.
- Simulator and device Run open the full-width log reader first; Escape returns to Run controls (Stop, Read output, conditional LLDB) without ending the run.
- Keep only the newest 32 KiB / 200 lines of combined stdout/stderr and scoped unified logs as a live tail, plus bounded frozen preview and reader snapshots, in memory; each source keeps at most 8 KiB of an unfinished line.
- Simulator output travels through two private mode-0600 FIFOs under a
mode-0700 invocation directory in the selected Simulator's
data/tmp— never log files. Resolve that device's data root with a bounded capture, validate root and child, keep host and Simulator-relative paths separate, and clean up via the captured host root. Run replaces a running instance of the selected bundle (--terminate-running-process) and setsSIMCTL_CHILD_NSUnbufferedIO=YESonly for the launch and its log-stream child; app buffering can still occur. - Read at most 32 KiB per idle turn, fairly across sources, never during paint or resize, with input priority. Freeze displayed text while reading or in the guide. A failed source is disclosed while the other continues. No source-time work, persistent worker or new key map.
- Read output is a reader-only shared document view: full width, wrapped up to the shared 20,000-row bound, no selectable or numbered rows. It uses shared fuzzy character matching plus the literal Exclude field, keeps source order and duplicates, and counts source lines rather than wrapped rows. Both fields, their focus and the severity view survive Options, Copy and reopen. It follows the latest tail by default; scrolling up pauses publication and reaching the bottom or Follow latest resumes, with mode, filters and paused bookmark kept across Options, Run and reopen. Unchanged output triggers no reformat or repaint, but status and limit changes still update. Enter opens options; Escape/Ctrl-G returns to Run; Options Escape returns to the reader. No phantom list focus, count or digit action.
- A bounded pure helper formats recognized native compact records (compact time/severity/scope header, separate body, spacing); unrecognized lines stay plain and message words never imply severity. Error/Fault counts cover the whole snapshot including hidden records; Errors and faults intersects with the filters; Show all levels restores plain output. These are log counts, not app health or delivery-completeness claims. Matching, counts and copying use original source lines. Evidence: log monitor.
- Copy all, Copy filtered or reader Ctrl-Y freezes the complete matching raw lines of the displayed snapshot (including offscreen content, without UI labels or wrapping), offered only for nonempty text and a captured clipboard capability. Options copies the display captured when Options opened. Write after screen restoration, never read the clipboard, reopen Run with visible feedback, keep the reader bookmark and running app, and keep a nonzero status after clipboard failure. Copied text outlives the run under OS/user control and may hold native private payloads — disclose that in public privacy docs.
Scoped to the selected Simulator and the canonical installed
CFBundleExecutable path: native
log stream --level debug --style compact --color none through simctl spawn with an exact processImagePath
predicate applied before delivery — never a broad stream filtered afterward.
Start it before launch, wait a bounded time for its readiness header, and set
LOGRC=/dev/null for that child only so personal .logrc rules can't broaden
capture. Framework records inside the app are included; helpers and
extensions with other executable paths are not. Disclose that another launch
of the same executable can match, records can drop, startup can race,
duplicates can reach both sources and merged order isn't timestamp order.
Never enable private-data logging or promise redaction (Simulator defaults can
expose private payloads). The observer belongs to this run only: stop and reap
it before LLDB and in all cleanup. No persistent logging configuration.
Resolve the Run PID only from simctl's launch response, never app output, and
revalidate user, start time and executable before LLDB and before stopping the
exact bundle; disclose non-atomic exit races. Escape/Stop in Run and handled
errors stop the run after restoration. LLDB gets the restored terminal with
automatic init and symbol-script loading disabled; one scoped child drains
app output until LLDB exits, then cleanup stops the run and reaps the drainer.
Never change signing, use sudo, attach by a guessed name or launch a
different app. A closed output stream is not proof of exit. Preserve
launch/debugger failure status and disclose missing identity, failed stop and
crash-cleanup limits.
Signal an owned child (discovery supervisor, device console, log observer or
drainer) only after revalidating its job, and reap it through the shared job
reaper: retire only its own job record and preserve unrelated jobs — never an
unqualified jobs/wait sweep (see the
job-lifecycle limitation). The discovery
supervisor's process group, the device console and the log observer stop
through one grace-period helper: TERM, CONT for a suspended child (always for
the group), at most one second of caller-specific draining, KILL, reap.
xcode --export-skills runs xcrun agent skills export for detected coding
agents' skill directories. Interactive export reviews the captured
destinations in the shared action view before staging or writing; Escape
cancels and no exporter runs while the plan is painted. Noninteractive, dumb
or missing-UI export runs directly, as documented. Export needs no project
discovery.
Cover discovery order, spaces in paths, multi-page scheme catalogs,
bounded/failed JSON, hostile destination text, no-scheme/no-destination
states, argument delegation, noninteractive fallback, cancellation, resize
cleanup, ten-row digit pages, container replacement, failed-refresh eviction,
exact incremental/rebuild action arrays and Mac/device/Simulator dispatch with
PATH-shadowed first-party spies. Also: hostile action arguments,
result-bundle symlink rejection, destination provider-call counts, cache
restoration, four-scheme eviction, explicit refresh, test totals, assertion
and build failures, source locations, result colors, bounded reports,
conditional clipboard affordance, post-screen copying, status preservation,
bundle cleanup; for Run, the exact log predicate, child environment isolation,
bounded readiness, fair draining and partial-line bounds, independent source
failure, replacement launch, observer stop/reap before LLDB and on error,
bounded stops of suspended or TERM-ignoring children (with the device
notice), reader geometry, anchors after resize/reopen, fuzzy and exclusion matching,
no-match recovery, scroll pause/resume, stable Options copying, quiet
callbacks, independent bookmarks and sticky clipboard failure. Real
Xcode/Simulator checks are optional host integration tests and never read
private project data or mutate the user's active project.
- A separate public skill-export command;
xcode --export-skillsis the only entry.