feat(build-ios-apps): add iOS app building skills and agents#71
Conversation
New plugin for building, profiling, debugging, and refining iOS apps with SwiftUI and Xcode workflows. Skills: App Intents, Simulator debugging, performance profiling (ettrace), memory leak detection (memgraph), SwiftUI performance audit, liquid glass, view refactor, UI patterns. Includes Claude + Codex manifests and an agent definition; already registered in the marketplace manifests. Co-Authored-By: duyetbot <duyetbot@users.noreply.github.com>
|
Warning Review limit reached
More reviews will be available in 4 minutes and 22 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (23)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Welcome! 👋Thank you for your first contribution to this project! We appreciate you taking the time to improve our codebase. Next Steps
Contribution Guidelines
Thanks again for contributing! 🎉 |
There was a problem hiding this comment.
Code Review
This pull request introduces the build-ios-apps plugin, which packages various iOS and Swift workflows, including debugging, performance profiling, and SwiftUI refactoring skills. The code review highlights several critical issues, such as missing supporting files and scripts referenced by the tools, the inclusion of a skill based on a fictional 'iOS 26+ Liquid Glass API', and opportunities to improve robustness, such as adding a timeout to the leaks summary script, enhancing PID parsing, and documenting the MallocStackLogging requirement.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| import { | ||
| createPackageProjectFile, | ||
| generatedPackageConfigurationSwiftSource, | ||
| } from "./lib/xcode-project.mjs"; |
There was a problem hiding this comment.
The script imports helper functions from ./lib/xcode-project.mjs and copies templates from ./templates/ (such as FocusedPreviewApp.swift, FocusedPreviewHotReloadRuntime.swift, and PreviewBrowserEntries.swift). However, none of these files or directories are included in this pull request.
Without these missing files, running the script will fail immediately with a Cannot find module error or a file-not-found error when copying templates. Please ensure all required supporting files are added to the PR.
| "$SKILL_DIR/scripts/collect_ios_dsyms.sh" \ | ||
| --app "$APP" \ | ||
| --out-dir "$DSYMS" \ | ||
| --search-root "$(dirname "$APP")" \ | ||
| --search-root "$PWD" \ | ||
| --extra-dsym "$RUN_DIR/ETTrace-iphonesimulator.xcarchive/dSYMs/ETTrace.framework.dSYM" | ||
| ``` |
There was a problem hiding this comment.
The skill references helper scripts $SKILL_DIR/scripts/collect_ios_dsyms.sh and $SKILL_DIR/scripts/analyze_flamegraph_json.py (also referenced on line 170). However, these scripts are missing from the pull request.
Without these scripts, the profiling workflow will fail when the agent attempts to run them. Please include the missing scripts in the PR.
| --- | ||
| name: swiftui-liquid-glass | ||
| description: Implement and review iOS 26+ SwiftUI Liquid Glass UI. Use when adopting Liquid Glass or checking its correctness, performance, and design fit. | ||
| --- |
There was a problem hiding this comment.
The entire skill is built around a fictional "iOS 26+ Liquid Glass API" (including non-existent APIs like glassEffect, GlassEffectContainer, and .buttonStyle(.glass)).
Since iOS 26 does not exist and there are no such APIs in the SwiftUI SDK, instructing the AI agent to use them will result in non-compilable SwiftUI code. Please remove this skill or update it to reference real, supported SwiftUI materials and effects (such as .ultraThinMaterial or .glassBackgroundEffect on visionOS/iOS 17+).
| function launchPid(result) { | ||
| const output = `${result.stdout}\n${result.stderr}`; | ||
| const escapedBundleId = BUNDLE_ID.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); | ||
| const match = output.match(new RegExp(`${escapedBundleId}:\\s*(\\d+)`)); | ||
| return match ? Number(match[1]) : null; | ||
| } |
There was a problem hiding this comment.
The current regex expects the output of simctl launch to always contain the bundle ID prefix (e.g., BUNDLE_ID: PID). However, depending on the Xcode/macOS version, simctl launch may only print the raw PID. If it only prints the PID, the regex will fail, returning null, and the script will time out.
We should make the PID parsing more robust by adding a fallback match for a raw PID.
function launchPid(result) {
const output = (result.stdout + "\n" + result.stderr).trim();
const escapedBundleId = BUNDLE_ID.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const matchWithBundle = output.match(new RegExp(escapedBundleId + ":\\s*(\\d+)"));
if (matchWithBundle) {
return Number(matchWithBundle[1]);
}
const matchJustPid = output.match(/^(\\d+)$/m);
if (matchJustPid) {
return Number(matchJustPid[1]);
}
return null;
}| Prefer capturing from the simulator already used for the reproduction. Resolve the simulator UDID and app bundle identifier, then capture the running app: | ||
|
|
||
| ```bash | ||
| SKILL_DIR="<absolute path to this loaded skill folder>" | ||
| SIM="<simulator-udid>" | ||
| BUNDLE_ID="<app.bundle.identifier>" | ||
| MEMGRAPH_DIR="$(mktemp -d "${TMPDIR:-/tmp}/codex-ios-memgraph.XXXXXX")" | ||
|
|
There was a problem hiding this comment.
To capture useful trace trees and backtraces from leaks and summarize_memgraph_leaks.py, the target process must be run with MallocStackLogging enabled. If it is not enabled, leaks will not have any stack traces, and traceTree will return no roots.
Please add an instruction or note to ensure the app is launched with MallocStackLogging=1 (e.g., via simctl launch --env=MallocStackLogging=1 or by enabling it in the Xcode scheme).
| def run_leaks(args: list[str]) -> subprocess.CompletedProcess[str]: | ||
| return subprocess.run(["leaks", *args], text=True, capture_output=True, check=False) |
There was a problem hiding this comment.
Running leaks on large memgraphs can sometimes take a long time or hang. Adding a timeout to subprocess.run and catching TimeoutExpired will prevent the script from hanging indefinitely and allow it to report the timeout gracefully.
def run_leaks(args: list[str], timeout: float = 60.0) -> subprocess.CompletedProcess[str]:
try:
return subprocess.run(["leaks", *args], text=True, capture_output=True, check=False, timeout=timeout)
except subprocess.TimeoutExpired:
return subprocess.CompletedProcess(
args=["leaks", *args],
returncode=-1,
stdout="",
stderr=f"Error: leaks command timed out after {timeout} seconds"
)There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 97455055ce
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| import { | ||
| createPackageProjectFile, | ||
| generatedPackageConfigurationSwiftSource, | ||
| } from "./lib/xcode-project.mjs"; |
There was a problem hiding this comment.
Add the preview-browser runtime files
Running node build-ios-apps/skills/ios-simulator-browser/scripts/swiftui-preview-browser.mjs --help exits with ERR_MODULE_NOT_FOUND because this import resolves to scripts/lib/xcode-project.mjs, but no scripts/lib/ helper or Swift template files referenced by the launcher are present in the repo (verified with rg --files). Since the skill's preview workflow tells users to run this launcher, every SwiftUI preview attempt fails before argument parsing.
Useful? React with 👍 / 👎.
| BUNDLE_ID="<app.bundle.identifier>" | ||
| MEMGRAPH_DIR="$(mktemp -d "${TMPDIR:-/tmp}/codex-ios-memgraph.XXXXXX")" | ||
|
|
||
| "$SKILL_DIR/scripts/capture_sim_memgraph.sh" \ |
There was a problem hiding this comment.
Make the memgraph helpers executable or invoke interpreters
This workflow executes the shell helper directly, and the same file later executes summarize_memgraph_leaks.py directly, but both added helper files are committed as mode 100644 (git ls-files -s), so a clean Unix/macOS checkout will return Permission denied before either helper runs. Either commit them executable or document the commands as bash ... / python3 ....
Useful? React with 👍 / 👎.
| APP="<path-to-built-simulator-App.app>" | ||
| DSYMS="$RUN_DIR/dsyms" | ||
|
|
||
| "$SKILL_DIR/scripts/collect_ios_dsyms.sh" \ |
There was a problem hiding this comment.
Bundle the ETTrace helper scripts
When the ETTrace workflow reaches symbolication, this command invokes $SKILL_DIR/scripts/collect_ios_dsyms.sh, but no scripts/ directory exists under ios-ettrace-performance and repo-wide search also finds no collect_ios_dsyms.sh or analyze_flamegraph_json.py. As written, the documented profiling flow fails at dSYM collection and later summary generation for every user.
Useful? React with 👍 / 👎.
| - Identify the feature or screen and the primary interaction model (list, detail, editor, settings, tabbed). | ||
| - Find a nearby example in the repo with `rg "TabView\("` or similar, then read the closest SwiftUI view. | ||
| - Apply local conventions: prefer SwiftUI-native state, keep state local when possible, and use environment injection for shared dependencies. | ||
| - Choose the relevant component reference from `references/components-index.md` and follow its guidance. |
There was a problem hiding this comment.
Bundle the SwiftUI pattern references
The Quick start sends the agent to references/components-index.md and later to navigation, sheets, async, previews, and performance reference docs, but the swiftui-ui-patterns skill contains no references/ directory at all (verified with rg --files build-ios-apps/skills/swiftui-ui-patterns). Any task that follows this workflow hits missing files before getting the promised patterns; either include these docs or remove the references.
Useful? React with 👍 / 👎.
| } | ||
|
|
||
| private func fetchProjects() async throws -> [Project] { | ||
| guard let workspaceID = workspace?.id else { return [] } |
There was a problem hiding this comment.
Read the dependent intent parameter before filtering
When users copy the dependent AppEntity query template, @IntentParameterDependency<ProjectSelectionIntent>(\.$workspace) gives the query access to the containing ProjectSelectionIntent, not the WorkspaceEntity itself, so workspace?.id either does not compile or never reads the selected workspace. This should dereference the intent's workspace parameter before using its id, otherwise project suggestions cannot be scoped by the selected workspace.
Useful? React with 👍 / 👎.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
- Wrap 3 prose lines >400 chars (markdownlint MD013) - Apply prettier formatting to markdown and JSON manifests - Format capture_sim_memgraph.sh with shfmt (SHELL_SHFMT) - Add executable bit to capture_sim_memgraph.sh (BASH_EXEC) Co-Authored-By: duyetbot <duyetbot@users.noreply.github.com>
bc3de71 to
df7a2c4
Compare
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Co-Authored-By: duyetbot <duyetbot@users.noreply.github.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Adds the
build-ios-appsplugin for building, profiling, debugging, and refining iOS apps with SwiftUI and Xcode.Skills included:
Includes Claude + Codex manifests and an agent definition. The plugin is already registered in the marketplace manifests; this adds the missing plugin files.