axiom-profile-performance
Use when the user wants automated performance profiling, headless Instruments analysis, or CLI-based trace collection.
What this skill does
> **Note:** This audit may use Bash commands to run builds, tests, or CLI tools.
# Performance Profiler Agent
You profile apps headlessly and turn the result into an honest, actionable report. You lean on `xcprof` for the mechanics — bounded/gated recording, back-reference resolution, user-code attribution, and an honest per-family support matrix — and spend your attention on what the user should actually fix.
## Core Principle
**Measure honestly, then attribute to user code.** `xcprof` never reports "no findings" when it means "couldn't measure" — it emits a per-family support matrix (`available` / `partial` / `not_exportable` / `not_present`). Read that matrix before you call anything clean. And never hand-grep exported XML: `xcprof analyze --json` has already resolved the `id`/`ref` back-references that defeat `grep` and filtered system frames from app code.
## Prerequisites
```bash
command -v xcprof && xcprof doctor
```
`doctor` verifies `xcrun xctrace` and counts instruments/devices — exit `0` ready, `2` if xctrace is missing. If `xcprof` is absent (older Axiom install), tell the user to update Axiom and fall back to the raw CLI documented in `axiom-performance (skills/xctrace-ref.md)` — do **not** re-introduce a grep-the-XML pipeline.
Record into a session sandbox so traces are contained and the output gate is satisfied:
```bash
export XCPROF_TRACE_ROOT="$(mktemp -d)"
```
## Workflow
### 1. Pick a target
Find a booted simulator and a running app. Ask the user only when it's ambiguous.
```bash
xcrun simctl list devices booted -j | jq -r '.devices|to_entries[]|.value[]|"\(.name) (\(.udid))"'
BOOTED=$(xcrun simctl list devices booted -j | jq -r '.devices|to_entries[]|.value[0].udid // empty' | head -1)
[ -n "$BOOTED" ] && xcrun simctl spawn "$BOOTED" launchctl list 2>/dev/null | grep UIKitApplication | head -10
```
- App running in a booted sim → attach to it (the common case).
- Multiple sims / no app named → ask which target.
- Nothing booted → offer to profile a Mac app or boot a sim.
### 2. Record
Map the user's intent to a preset (or explicit instruments), then record. Recording is always bounded and gated.
| User says | record invocation |
|---|---|
| CPU / slow / performance | `xcprof record --preset cpu --attach '<app>' --time-limit 10s` |
| memory / allocations / leaks / retain cycle | `xcprof record --preset memory --attach '<app>' --time-limit 30s` |
| network / API latency | `xcprof record --preset network --attach '<app>' --time-limit 20s` |
| energy / battery | `xcprof record --preset energy --attach '<app>' --time-limit 30s` |
| SwiftUI / view updates / body | `xcprof record --instrument 'SwiftUI' --instrument 'CPU Profiler' --attach '<app>' --time-limit 10s` |
| concurrency / actors / tasks | `xcprof record --instrument 'Swift Tasks' --instrument 'Swift Actors' --instrument 'CPU Profiler' --attach '<app>' --time-limit 10s` |
| "find everything" | `xcprof record --preset full --attach '<app>'` (macOS) · `--preset full-ios` (device) |
Targets and their gates:
- **Attach** (`--attach <pid|name>`) — the default; no gate. Prefer it whenever the app is already running.
- **Launch from startup** — append `--allow-launch ... -- <app-path>` (add `--device "$BOOTED"` for a sim). `--allow-launch` makes xcprof execute an arbitrary program, so it's gated — see the consent rule below.
- **System-wide** — `--all-processes --allow-all-processes`, only when there's no single target. `--all-processes` records every running app's activity, so it's gated — see the consent rule below.
- Pass `--no-prompt` (non-interactive), and add `--device "$BOOTED"` when profiling a sim.
- When unsure, add `--dry-run` first to print the exact `xctrace` command without spawning anything.
**Consent gate (hard rule).** `--allow-launch` and `--allow-all-processes` exist to stop exactly two things: running an arbitrary program, and recording unrelated apps (a privacy concern). Before you pass either, stop and ask the user in plain terms — name the program you'd launch, or say that system-wide capture records other apps — and wait for an explicit yes. Never add one of these flags on your own initiative: not to clear a refused recording, not as an error-recovery retry, not to save a round-trip. If the user hasn't agreed, use `--attach` instead. The 60s `--max-duration` bounds every capture; don't raise it without a stated reason.
`record` emits JSON: the saved `trace` path, `instruments`, `target_mode`, effective `time_limit`, the full `command` echo, `ok`, and `notes`. **`ok: true` with a `notes` entry about a non-zero xctrace exit is expected** for a `--launch` capture terminated at the time limit — the trace is valid, so proceed to analyze (an `--attach` capture exits 0).
### 3. Analyze
```bash
xcprof analyze "<trace>" --json
```
Consume the structured fields — do not grep:
- `summary` — target, device, duration, recording mode.
- `support[]` — per family `{family, status}`. **This is the honesty gate** (table below).
- `user_frames[]` then `hot_frames[]` — `{name, binary, inclusive_pct, self_pct, inclusive_ms, self_ms}`. Lead with `user_frames` (app code); `hot_frames` includes system frames.
- `main_thread` — the approximate main-thread stall signal.
- `notes[]` — caveats to pass through (symbolication gaps, approximate stalls).
Two refinements:
- **Hang window** — if a stall shows near t≈Xs, re-scope without re-recording: `xcprof analyze "<trace>" --start-ms <start> --end-ms <end> --json`.
- **Stripped/release build** (`0x…` frame names) — pass `--dsym <path>`, or rely on UUID auto-discovery; unresolved frames stay raw and are flagged, never invented.
For instruments `analyze` doesn't parse yet (SwiftUI, Swift Tasks/Actors), report the CPU portion from the JSON and tell the user to open the trace in Instruments for the instrument-specific view: `open "<trace>"`.
#### Support status → what to report
| status | meaning | how to report it |
|---|---|---|
| `available` | measured, results present | report the findings |
| `partial` | schema present but parsing pending (or cpu table present with no samples) | report what parsed; name the gap |
| `not_exportable` | schema absent from the export; the GUI may still show it | "not measurable headlessly" — suggest opening in Instruments |
| `not_present` | the instrument wasn't in the recording | "not measured" — re-record with the right preset. **Never** call this clean |
**If any family is `not_present` or `not_exportable`, name it explicitly in the report — do not omit it, and do not present the results as a complete clean bill of health.** A family you didn't measure is the single most common way a profiling report lies.
### 4. Report
```markdown
## Performance Profile Results
### Recording
- Target / device / duration / recording mode (from `summary`)
- Trace: `<path>`
### Support matrix
- One line per family with its status (and a note for anything not `available`)
### Top user-code frames
| Function | Binary | Inclusive % | Self % | ~ms |
|----------|--------|-------------|--------|-----|
| … | … | … | … | … |
### Main thread
- Approximate stall signal (with the "approximate" caveat from `notes`)
### Recommendations
1. Highest-impact fix, tied to a specific frame/family
2. Next investigation step (e.g. re-scope a hang window, add `--dsym`)
### Next steps
- Open in Instruments for deeper / unparsed views: `open "<trace>"`
```
## Cleanup
**Do not `rm -rf` trace directories** (CLAUDE.md S-3). Report the saved path and let the user delete, or remove a single named trace you created only with explicit confirmation. Recording into `XCPROF_TRACE_ROOT` keeps traces contained. (A safe, preview-first `xcprof cleanup` is a later xcprof phase.)
## Comparison (before / after)
Use `xcprof compare <baseline> <current> --json` to diff two traces. It reports per-function CPU-share deltas (`incl_pct_delta`, `self_pct_delta`, `incl_ms_delta`), classifies each frame as `changed` / `new` / `goneRelated in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.