@swmansion/argent 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/LICENSE +195 -0
  2. package/README.md +103 -0
  3. package/agents/argent-environment-inspector.md +106 -0
  4. package/agents/references/quality-control-checklist.md +45 -0
  5. package/bin/ax-service +0 -0
  6. package/bin/simulator-server +0 -0
  7. package/dist/Argent.tracetemplate +0 -0
  8. package/dist/auto-screenshot.d.ts +22 -0
  9. package/dist/auto-screenshot.js +79 -0
  10. package/dist/auto-screenshot.js.map +1 -0
  11. package/dist/cli/constants.d.ts +6 -0
  12. package/dist/cli/constants.js +12 -0
  13. package/dist/cli/constants.js.map +1 -0
  14. package/dist/cli/init.d.ts +2 -0
  15. package/dist/cli/init.js +466 -0
  16. package/dist/cli/init.js.map +1 -0
  17. package/dist/cli/mcp-configs.d.ts +38 -0
  18. package/dist/cli/mcp-configs.js +724 -0
  19. package/dist/cli/mcp-configs.js.map +1 -0
  20. package/dist/cli/uninstall.d.ts +13 -0
  21. package/dist/cli/uninstall.js +389 -0
  22. package/dist/cli/uninstall.js.map +1 -0
  23. package/dist/cli/update.d.ts +1 -0
  24. package/dist/cli/update.js +126 -0
  25. package/dist/cli/update.js.map +1 -0
  26. package/dist/cli/utils.d.ts +27 -0
  27. package/dist/cli/utils.js +158 -0
  28. package/dist/cli/utils.js.map +1 -0
  29. package/dist/cli.d.ts +13 -0
  30. package/dist/cli.js +80 -0
  31. package/dist/cli.js.map +1 -0
  32. package/dist/content.d.ts +31 -0
  33. package/dist/content.js +59 -0
  34. package/dist/content.js.map +1 -0
  35. package/dist/launcher.d.ts +8 -0
  36. package/dist/launcher.js +183 -0
  37. package/dist/launcher.js.map +1 -0
  38. package/dist/mcp-server.d.ts +1 -0
  39. package/dist/mcp-server.js +228 -0
  40. package/dist/mcp-server.js.map +1 -0
  41. package/dist/tool-server.cjs +51288 -0
  42. package/dylibs/libArgentInjectionBootstrap.dylib +0 -0
  43. package/dylibs/libKeyboardPatch.dylib +0 -0
  44. package/dylibs/libNativeDevtoolsIos.dylib +0 -0
  45. package/package.json +53 -0
  46. package/rules/argent.md +121 -0
  47. package/scripts/postinstall.cjs +34 -0
  48. package/skills/argent-create-flow/SKILL.md +213 -0
  49. package/skills/argent-ios-profiler/SKILL.md +103 -0
  50. package/skills/argent-metro-debugger/SKILL.md +117 -0
  51. package/skills/argent-metro-debugger/references/failure-scenarios.md +10 -0
  52. package/skills/argent-metro-debugger/references/source-maps.md +27 -0
  53. package/skills/argent-react-native-app-workflow/SKILL.md +237 -0
  54. package/skills/argent-react-native-optimization/SKILL.md +64 -0
  55. package/skills/argent-react-native-optimization/references/fix-reference.md +14 -0
  56. package/skills/argent-react-native-optimization/references/lint-rules.md +55 -0
  57. package/skills/argent-react-native-optimization/references/semantic-checklist.md +34 -0
  58. package/skills/argent-react-native-profiler/SKILL.md +160 -0
  59. package/skills/argent-react-native-profiler/references/diagnostic-tools.md +94 -0
  60. package/skills/argent-simulator-interact/SKILL.md +272 -0
  61. package/skills/argent-simulator-interact/references/gesture-examples.md +114 -0
  62. package/skills/argent-simulator-setup/SKILL.md +19 -0
  63. package/skills/argent-test-ui-flow/SKILL.md +84 -0
@@ -0,0 +1,10 @@
1
+ # Failure Scenarios: Recovery Steps
2
+
3
+ When a debugger tool fails, use **`debugger-status`** first to diagnose. Then match the error or situation below and act as specified. Do not retry the same failing tool repeatedly without following the recovery steps.
4
+
5
+ | Scenario | Error or situation | What to do |
6
+ | ---------------------------------- | ------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
7
+ | **Metro not running** | Error contains: `Metro at port 8081 is not running (got: ...)` | **Start Metro yourself** unless the user asked you not to: scan the workspace configuration and run the appropriate command to start Metro in the background (by default `npx react-native start` or `npx expo start`). Wait for Metro to be ready, then retry `debugger-connect` or `debugger-status`. If you cannot determine the project root, ask the user. |
8
+ | **Metro not standard** | Error contains: `Metro at port 8081 did not return X-React-Native-Project-Root header` | Something on that port is not the standard React Native Metro server. Try starting Metro yourself from the app's project root using the command resolution above. If you cannot determine the correct root or the problem persists, inform the user what you found and what you tried. |
9
+ | **App not connected** | Error contains: `Metro at port 8081 has no CDP targets — is a React Native app connected?` | 1) Confirm the app is running on simulator or device. 2) If simulator: use `restart-app` with the app's UDID and bundleId to relaunch so it connects to Metro. 3) Wait a few seconds for the bundle to load. 4) Retry `debugger-status`. Do **not** use `debugger-reload-metro` to fix this — it also requires at least one target. |
10
+ | **Was connected, then tool fails** | Any debugger tool fails with a connection or disconnect error after it was working | The app may have crashed or been closed. Use `restart-app` (simulator) to relaunch the app, then call `debugger-connect` again to pick up the fresh `logicalDeviceId` (UDID may change for booted-fresh simulators), and use that new `device_id` on all subsequent calls. |
@@ -0,0 +1,27 @@
1
+ # Source Resolution for `inspect-element`
2
+
3
+ `debugger-inspect-element` tries to resolve each component in the hierarchy to its source file and line. It uses a fallback chain:
4
+
5
+ 1. **`_debugStack`** (React fiber property) — a stack trace string from the bundled code. When available, the tool symbolicates it via Metro's `/symbolicate` endpoint to resolve to the original source file, then reads a code fragment from disk. Set `resolveSourceMaps: false` to skip symbolication and return raw bundled locations instead.
6
+ 2. **`_debugSource`** (React fiber property) — contains `{ fileName, lineNumber, columnNumber }` pointing directly to the original source file. No symbolication needed. The tool reads the code fragment from disk automatically.
7
+ 3. **Neither available** — the tool returns the component hierarchy with `source: null` and `code: null` for all items. The hierarchy (component names) is still useful.
8
+
9
+ ## When Source Info Is Missing
10
+
11
+ If `debugger-inspect-element` returns all items with `source: null`, the React Native project's Babel configuration does not inject source information into JSX elements. This is common with the **automatic JSX transform** (used by Expo SDK 50+ and React Native 0.73+).
12
+
13
+ **To enable source resolution**, inform the user that they can add `@babel/plugin-transform-react-jsx-source` to their project's Babel config. For example, in `babel.config.js`:
14
+
15
+ ```js
16
+ module.exports = function (api) {
17
+ api.cache(true);
18
+ return {
19
+ presets: ["babel-preset-expo"], // or 'module:@react-native/babel-preset'
20
+ plugins: [
21
+ "@babel/plugin-transform-react-jsx-source", // enables _debugSource on fibers
22
+ ],
23
+ };
24
+ };
25
+ ```
26
+
27
+ After adding the plugin, restart Metro (`npx react-native start --reset-cache` or `npx expo start --clear`) and reload the app. The tool will then automatically pick up `_debugSource` and resolve components to their source files. No extra `npm install` needed — the plugin ships with `babel-preset-expo` and `@babel/preset-env`.
@@ -0,0 +1,237 @@
1
+ ---
2
+ name: argent-react-native-app-workflow
3
+ description: Step-by-step workflows for developing or debugging React Native apps with iOS simulator. Use when starting the app, debugging Metro, fixing builds, diagnosing runtime errors, or running tests.
4
+ ---
5
+
6
+ ## 1. Starting the React Native App
7
+
8
+ ### 1.1 Explore Configuration (MANDATORY — Do This First)
9
+
10
+ **Before running commands**, read the project's build and run configuration from the `argent-environment-inspector` subagent result.
11
+
12
+ Do NOT default to `npx react-native start` or `npx react-native run-ios` without first checking for custom scripts and workflows.
13
+
14
+ **Manual fallback** (if neither the agent nor the tool is available): read ALL `package.json` scripts — look for custom scripts like `start:local`, `start:dev`, `ios`, `build:ios`, flavors, etc. Custom scripts take priority over default commands. Also check `metro.config.js` for non-default port or watchFolders. For iOS builds, prefer opening `.xcworkspace` over `.xcodeproj` (CocoaPods generates the workspace).
15
+
16
+ **If the project structure is convoluted, ask the user before proceeding.**
17
+
18
+ **Remember the workflow:** Once you discover the project's build/run workflow, save it to project memory so you don't need to re-discover it each time.
19
+
20
+ **Checklist before start:**
21
+
22
+ - [ ] `node_modules` present (if not: `npm install` or `yarn`)
23
+ - [ ] For iOS: `ios/Podfile` exists; if `ios/Pods` missing or stale, run `cd ios && pod install && cd ..`
24
+ - [ ] No conflicting Metro on default port (see 1.2)
25
+
26
+ ### 1.2 Start Metro
27
+
28
+ 1. Check whether metro is already running on port found in configuration and if it is - do not start another server. Refer to point 2.1.
29
+
30
+ 1. **Use the project's custom start script if one exists** (e.g. `npm run start:local`, `yarn start:dev`). Fall back to default commands if no custom scripts are defined:
31
+
32
+ ```bash
33
+ npx react-native start
34
+ ```
35
+
36
+ Optional: `npx react-native start --reset-cache` if cache issues are suspected.
37
+
38
+ 1. **Verify Metro is ready**: use the `debugger-status` tool to verify Metro is running and reachable.
39
+
40
+ 1. **Projects with flavors or custom configs**: Use project-specific start script if present (e.g. `npm run start:local`), and start Metro **before** running the app.
41
+
42
+ ### 1.3 Run the iOS App
43
+
44
+ In a **separate** terminal (Metro keeps running in the first):
45
+
46
+ **Use the project's custom build/run script if one exists** (e.g. `npm run ios`, `yarn ios:debug`). Only fall back to the default if no custom scripts are defined:
47
+
48
+ ```bash
49
+ npx react-native run-ios
50
+ ```
51
+
52
+ Optional: specify device or simulator, e.g. `npx react-native run-ios --simulator="iPhone 16"`.
53
+
54
+ **Agent checklist:**
55
+
56
+ - [ ] Metro is already running and shows "ready"
57
+ - [ ] Command run from project root
58
+ - [ ] If simulator not booted: use the `boot-simulator` tool with proper UDID. Refer to the `argent-simulator-setup` skill.
59
+
60
+ ---
61
+
62
+ ## 2. Ensuring / Debugging Metro
63
+
64
+ ### 2.1 Check for Existing Metro
65
+
66
+ Before starting Metro, avoid "port already in use" errors. Default port to check is :8081, infer the port from documentation:
67
+
68
+ ```bash
69
+ lsof -i :PORT
70
+ ```
71
+
72
+ - **No output** → Port free; safe to start Metro.
73
+ - **Output with PID** → Another process is using the port.
74
+
75
+ Use the `debugger-status` tool to check whether the process on that port is actually a Metro server. If not Metro — ask the user whether you may kill the process.
76
+
77
+ To kill a Metro process, use the `stop-metro` tool (requires user confirmation).
78
+
79
+ ### 2.2 Confirm Correct Server Connection
80
+
81
+ - **App must point at the same host/port as the running Metro.** Default: same machine, port 8081.
82
+ - **iOS Simulator:** By default uses localhost; no extra config needed for same-machine Metro.
83
+
84
+ **Verify Metro is reachable:** use the `debugger-status` tool.
85
+
86
+ ### 2.3 Reload the App (Ensure New Bundle)
87
+
88
+ After code or config changes, the app must load the new bundle:
89
+
90
+ | Method | How |
91
+ | ----------- | ------------------------------------------------------------------------------------------------- |
92
+ | Reload tool | Use the `debugger-reload-metro` tool |
93
+ | Restart app | Use the `restart-app` tool, or kill the app in simulator and run `npx react-native run-ios` again |
94
+
95
+ **Agent checklist:**
96
+
97
+ - [ ] Only one Metro process (no duplicate on port)
98
+ - [ ] App was started after Metro was ready
99
+ - [ ] When needing to reload: refer to 2.3
100
+
101
+ ---
102
+
103
+ ## 3. Build / Install / Retry (React Native & iOS Native)
104
+
105
+ ### 3.1 When Build Fails (e.g. xcodebuild exit code 65)
106
+
107
+ **Order of operations (simplest first):**
108
+
109
+ 1. Clean build folder, then retry the build command
110
+ 2. Clear caches and reinstall dependencies: reset Metro cache, `watchman watch-del-all`, remove `node_modules` + lockfile, `npm install`, then `cd ios && rm -rf build Pods Podfile.lock && pod install --repo-update`
111
+ 3. CocoaPods issues: `pod deintegrate` then `pod install --repo-update`
112
+ 4. Open `ios/*.xcworkspace` in Xcode for detailed errors in the Report navigator
113
+
114
+ ### 3.2 When to Ask the User
115
+
116
+ **After 2-3 failed build or run attempts, STOP and ask the user for guidance.** The user may know about required env vars, Xcode version requirements, custom build configurations, monorepo-specific setup, or required external services.
117
+
118
+ If the project structure is convoluted and the correct build approach is not obvious, **ask the user early** rather than guessing.
119
+
120
+ ### 3.3 Saving Build Workflow for Later
121
+
122
+ Once you discover the correct build/run workflow for a project, **save it to project memory**. Capture: commands to start Metro, commands to build/run the app, and any required environment setup.
123
+
124
+ ### 3.4 When to Reinstall vs Refresh
125
+
126
+ | Situation | Action |
127
+ | ----------------------------------------------------- | ------------------------------------------------------------------------------------- |
128
+ | JS/React only changed | Use `debugger-reload-metro` tool. No rebuild. |
129
+ | Native code or `pod install` / project config changed | Rebuild: `npx react-native run-ios` (Metro can stay running). |
130
+ | `node_modules` or `package.json` changed | `npm install`, then if native deps changed run `cd ios && pod install`. Then rebuild. |
131
+ | App needs reinstalling from .app path | Use `reinstall-app` tool with UDID, bundle ID, and .app path. |
132
+ | Persistent native build errors | Full clean + reinstall (step 2 above). |
133
+
134
+ ### 3.5 iOS Simulator Control
135
+
136
+ | Action | Tool / Command |
137
+ | -------------------------- | -------------------------------------------------- |
138
+ | List devices | `list-simulators` tool |
139
+ | Boot a simulator | `boot-simulator` tool (pass UDID) |
140
+ | Launch an app | `launch-app` tool (pass UDID + bundle ID) |
141
+ | Restart an app | `restart-app` tool (pass UDID + bundle ID) |
142
+ | Open a URL / deep link | `open-url` tool (pass UDID + URL) |
143
+ | Rotate simulator | `rotate` tool |
144
+ | Stop simulator server | `stop-simulator-server` tool (for a specific UDID) |
145
+ | Stop all simulator servers | `stop-all-simulator-servers` tool |
146
+
147
+ For full simulator setup workflow, refer to the `argent-simulator-setup` skill.
148
+
149
+ ---
150
+
151
+ ## 4. Runtime Problems in the App
152
+
153
+ ### 4.1 Where to Look
154
+
155
+ | Problem type | Tool / Where to look |
156
+ | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
157
+ | **JavaScript errors / logs** | Use `debugger-log-registry` to get a summary and log file path, then `Grep`/`Read` to search. |
158
+ | **React component hierarchy** | Use `debugger-component-tree` tool for a text tree, or `debugger-inspect-element` at specific logical pixel coordinates (not normalized 0-1). |
159
+ | **Visual state of the app** | Use `screenshot` tool to capture the current screen, but prefer `describe` or `debugger-component-tree` for actual navigation and target discovery. If a permission prompt or system-owned modal overlay is not exposed reliably, then fall back to `screenshot`. |
160
+ | **Evaluate JS in the app** | Use `debugger-evaluate` tool to run JavaScript in the app's runtime. |
161
+ | **Native crashes / native stack** | `npx react-native log-ios` or iOS Simulator: Debug → Open System Log. |
162
+ | **Build/runtime config** | `metro.config.js`, `babel.config.js`, `package.json` scripts, `ios/Podfile`. |
163
+
164
+ For comprehensive Metro debugging workflows (component inspection, console logs, JS evaluation), refer to the `argent-metro-debugger` skill.
165
+
166
+ ### 4.2 JS Console Logs (Log Registry)
167
+
168
+ Logs are written to a flat log file on disk under `~/.argent/tmp/`. Use the **log-registry → grep** pattern instead of reading logs inline.
169
+
170
+ For the full workflow, flat entry format, and grep examples, see `argent-metro-debugger` skill §5.
171
+
172
+ ### 4.3 Do not try to use the DevMenu in React Native apps by default.
173
+
174
+ Use the argent tools instead.
175
+
176
+ ---
177
+
178
+ ## 5. Testing the App
179
+
180
+ Check the `argent-environment-inspector` result for test commands. For interactive UI testing with automatic screenshot verification, use the `argent-test-ui-flow` skill.
181
+
182
+ - **Unit tests**: Look for Jest in `package.json` (`"test": "jest"`, `jest` config). Run: `npm test` or `yarn test`.
183
+ - **E2E**: Look for Detox (`.detoxrc.js` or similar), or other E2E config. Dependencies: `detox`, `detox-cli`, and for iOS often `applesimutils`.
184
+ - **UI flow testing**: For interactive UI testing with automatic screenshot verification, refer to the `argent-test-ui-flow` skill.
185
+
186
+ ### 5.2 Running Tests (Typical)
187
+
188
+ If the user's intent is ambiguous (run existing tests, write new tests, or find missing coverage), clarify before proceeding.
189
+
190
+ - **Jest**: `npm test` or `npx jest`.
191
+ - **Detox (example)**:
192
+ - Build: `detox build --configuration ios.sim.release` (or debug).
193
+ - Run: `detox test --configuration ios.sim.release`.
194
+ - Ensure simulator is booted and not used by another process.
195
+
196
+ ### 5.3 Agent Testing Checklist
197
+
198
+ - [ ] Read `package.json` and test config (Jest, Detox, etc.).
199
+ - [ ] If E2E: confirm simulator/device and build config.
200
+ - [ ] If unclear: clarify whether to use existing workflows or write new tests.
201
+
202
+ ---
203
+
204
+ ## Quick Reference: Tools & Commands
205
+
206
+ | Goal | Tool / Command |
207
+ | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
208
+ | Check port 8081 | `lsof -i :8081` |
209
+ | Kill Metro | `stop-metro` tool |
210
+ | Start Metro | `npx react-native start` |
211
+ | Start Metro (reset cache) | `npx react-native start --reset-cache` |
212
+ | Run iOS app | `npx react-native run-ios` |
213
+ | List simulators | `list-simulators` tool |
214
+ | Boot simulator | `boot-simulator` tool |
215
+ | Take screenshot | `screenshot` tool |
216
+ | Describe screen (a11y tree) | `describe` tool for normal app screens and in-app modals; use `screenshot` only when permission/system overlays are not exposed reliably |
217
+ | Read JS console logs | `debugger-log-registry` tool |
218
+ | Reload JS bundle | `debugger-reload-metro` tool |
219
+ | Check Metro status | `debugger-status` tool |
220
+ | Inspect React component tree | `debugger-component-tree` tool |
221
+ | Run JS in app | `debugger-evaluate` tool |
222
+ | iOS native logs | `npx react-native log-ios` |
223
+ | Clean + reinstall (nuclear) | See §3.1 step 3 |
224
+
225
+ ---
226
+
227
+ ## Related Skills
228
+
229
+ | Skill | When to use |
230
+ | ------------------------------ | ------------------------------------------------------------------------------- |
231
+ | `argent-simulator-setup` | Initial simulator boot and connection setup |
232
+ | `argent-simulator-interact` | Tapping, swiping, typing, hardware buttons, gestures on the simulator |
233
+ | `argent-metro-debugger` | Full Metro CDP debugging: component inspection, console logs, JS evaluation |
234
+ | `argent-react-native-profiler` | Profiling performance, finding re-render issues, CPU hotspots |
235
+ | `argent-test-ui-flow` | Interactive UI testing with automatic screenshot verification after each action |
236
+
237
+ Ask the user before running tests: confirm which test suite (unit, E2E, or both), whether to use existing CI commands, and whether they want you to run existing tests, write new ones, or explore test cases yourself.
@@ -0,0 +1,64 @@
1
+ ---
2
+ name: argent-react-native-optimization
3
+ description: Optimizes a React Native app by profiling first to find real bottlenecks, then sweeping for mechanical issues. Entry-point for all performance work. Use when the app feels slow, user asks to optimize, fix re-renders, reduce jank, or improve startup. Delegates to react-native-profiler for measurement.
4
+ ---
5
+
6
+ ## Rules
7
+
8
+ - Do not apply shotgun optimizations. Measure first, define what "good enough" looks like (target metric + threshold), fix the top offender, re-measure honestly.
9
+ - **Quick scan** — `react-profiler-renders` for a live render count table. Identifies hot components instantly.
10
+ - **Deep measure** — load `react-native-profiler` skill. `react-profiler-start` → interact → `react-profiler-stop` → `react-profiler-analyze`.
11
+ - **Inspect** — `react-profiler-component-source` per finding. `react-profiler-fiber-tree` to trace component ancestry and render cost.
12
+ - **Verify correctness** - before fixing, recollect information from steps above and make a logical conclusion whether the approach is worth undertaking.
13
+ - **Fix** — apply one fix. Validate with `debugger-evaluate` before committing.
14
+ - **Re-measure** — report whether the target metric improved, regressed, or stayed flat. Check for regressions in other areas. If no net benefit or unacceptable tradeoffs, revert.
15
+ - **Profile for discovery, not only verification.** Use the profiler to find issues static analysis missed, not only to confirm fixes.
16
+ - **One fix per cycle for architectural changes.** Mechanical batch fixes (inline styles, index keys) can be grouped — re-profile once after the batch. When the measurement involves simulator interaction, record it as a flow (`create-flow` skill) before the first run so all subsequent cycles replay identical steps.
17
+ - **React Compiler**: if `react-profiler-analyze` reports `reactCompilerEnabled: true`, do NOT propose `useCallback`/`useMemo`/`React.memo` unless you confirmed compiler bail-out via `react-profiler-fiber-tree` (absent `useMemoCache`).
18
+ - **Sub-agents**: Phases 1–2 dispatch sub-agents — one per file for lint results, one per checklist item for semantic. Sub-agents CANNOT touch the simulator - all profiling and E2E verification must happen in the main agent.
19
+
20
+ ## Pipeline
21
+
22
+ **Lint and semantic sweeps catch deterministic issues cheaply. Profiling finds runtime bottlenecks that static analysis misses. Do both.**
23
+
24
+ Copy this checklist into your TODO list:
25
+
26
+ ```
27
+ Optimization Progress:
28
+ - [ ] Phase 1: Lint sweep (deterministic — catch mechanical issues without a running app)
29
+ - [ ] Phase 2: Semantic sweep (judgment — memoization, lists, animations, etc.)
30
+ - [ ] Phase 3: Baseline profile (find real bottlenecks, fix top offenders)
31
+ - [ ] Phase 4: Verify no regressions (crashes, errors, red screens)
32
+ ```
33
+
34
+ ### Phase 1: Lint sweep
35
+
36
+ Run ESLint once at the project root with a comprehensive RN performance ruleset. Dispatch sub-agents to fix results — one per file.
37
+ See [references/lint-rules.md](references/lint-rules.md) for ruleset and procedure.
38
+
39
+ ### Phase 2: Semantic sweep
40
+
41
+ Review each area requiring judgment — memoization, list rendering, animations, async patterns, effect cleanup, state hygiene, context architecture. Dispatch one sub-agent per checklist item.
42
+ See [references/semantic-checklist.md](references/semantic-checklist.md) for full checklist.
43
+
44
+ ### Phase 3: Visual profiling
45
+
46
+ 1. Load `react-native-profiler` skill, start dual profiling
47
+ 2. Exercise key user flows (navigate screens the user specified, or all major flows)
48
+ 3. Analyze with `react-profiler-analyze` + `ios-profiler-analyze` + `profiler-combined-report`
49
+ 4. Cross-reference profiling results with Phase 1–2 findings
50
+ 5. Fix highest-impact issues. Re-profile after architectural changes; batch mechanical fixes. If a recorded flow breaks after a fix (e.g., UI layout changed), follow `create-flow` skill to repair the flow rather than silently discarding it.
51
+
52
+ ### Phase 4: Verify no regressions
53
+
54
+ Navigate every screen and UI flow within scope, confirm each renders without errors. If no scope was specified, verify the entire app — cover all reachable screens via `simulator-interact`. Use `debugger-log-registry` to check for runtime errors and take screenshots to check for red/yellow error screens. Check for regressions introduced by fixes (e.g., fewer re-renders but higher CPU, or new jank in a different screen). Main agent only.
55
+
56
+ ## App-wide optimization
57
+
58
+ 1. **Phase 1**: run lint centrally (one command), dispatch sub-agents to fix per-file in parallel
59
+ 2. **Phase 2**: one sub-agent per checklist item for semantic sweep
60
+ 3. **Phase 3**: main agent profiles top offending screens; fixes architectural issues top-down
61
+ 4. **Phase 4**: main agent navigates all screens to verify nothing crashes
62
+
63
+ After the entire run, run lint again to verify no new issues were introduced with your changes.
64
+ This also helps ensure you haven't missed any issues which could've been fixed.
@@ -0,0 +1,14 @@
1
+ # Fix Reference
2
+
3
+ Match profiler findings and semantic sweep results to concrete fixes.
4
+
5
+ | Finding | Fix | Detail |
6
+ | -------------------------------------------- | ----------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
7
+ | Re-renders with same props | `React.memo(Comp)` | **Skip if React Compiler active** — `react-profiler-analyze` reports compiler status per component |
8
+ | Expensive recomputation / unstable callbacks | `useMemo(fn, [deps])` / `useCallback(fn, [deps])` | `useCallback` must pair with `React.memo` on child — alone it has no effect |
9
+ | Inline objects/arrays in JSX | `StyleSheet.create()` / module-level const | New reference every render breaks shallow equality |
10
+ | List jank | `removeClippedSubviews`, `maxToRenderPerBatch`, `windowSize`, `getItemLayout` | Or migrate to `@shopify/flash-list` with `estimatedItemSize` |
11
+ | JS-thread animation jank | `useNativeDriver: true` or `react-native-reanimated` | `useNativeDriver` only works for `transform` and `opacity` properties |
12
+ | Heavy work during transitions | `InteractionManager.runAfterInteractions()` | Defers execution until active animations complete |
13
+ | Slow startup | Hermes + inline requires in `metro.config.js` | Lazy `require()` defers loading heavy modules until first use |
14
+ | Redundant, heavy, or n+1 network calls | `view-network-logs` → `view-network-request-details` | Batch, debounce, or cache at the data layer |
@@ -0,0 +1,55 @@
1
+ # Phase 1: Lint Rules
2
+
3
+ Run once at the project root. Catches mechanical issues deterministically.
4
+ Install missing plugins before running: `npm install --save-dev eslint-plugin-react-perf`.
5
+
6
+ ## Rules
7
+
8
+ ### Performance (eslint-plugin-react-perf)
9
+
10
+ | Rule | Catches |
11
+ | ---------------------------------------- | -------------------------------------------------------- |
12
+ | `react-perf/jsx-no-new-object-as-prop` | Object literals `{}` as JSX props - new ref every render |
13
+ | `react-perf/jsx-no-new-array-as-prop` | Array literals `[]` as JSX props - new ref every render |
14
+ | `react-perf/jsx-no-new-function-as-prop` | Arrow functions / function expressions as JSX props |
15
+ | `react-perf/jsx-no-jsx-as-prop` | JSX elements as prop values (e.g. `icon={<Icon />}`) |
16
+
17
+ ### React (eslint-plugin-react)
18
+
19
+ | Rule | Catches |
20
+ | ----------------------------------------- | ------------------------------------------------------------------- |
21
+ | `react/no-array-index-key` | `key={index}` - incorrect reconciliation on reorder |
22
+ | `react/jsx-no-bind` | `.bind()` in JSX props - new function ref every render |
23
+ | `react/jsx-no-constructed-context-values` | Object/array literals as Context `value` - re-renders all consumers |
24
+ | `react/no-unstable-nested-components` | Components defined inside render - full remount each render |
25
+ | `react/no-object-type-as-default-prop` | Object/array defaults in destructuring (e.g. `{ items = [] }`) |
26
+
27
+ ### React Native (eslint-plugin-react-native)
28
+
29
+ | Rule | Catches |
30
+ | --------------------------------------------- | ------------------------------------------------ |
31
+ | `react-native/no-inline-styles` | Inline `style={{}}` - defeats shallow comparison |
32
+ | `react-native/no-unused-styles` | StyleSheet rules never referenced |
33
+ | `react-native/no-color-literals` | Color literals in styles instead of constants |
34
+ | `react-native/no-single-element-style-arrays` | `style={[single]}` instead of `style={single}` |
35
+
36
+ ### Hooks (eslint-plugin-react-hooks)
37
+
38
+ | Rule | Catches |
39
+ | ----------------------------- | ---------------------------------------- |
40
+ | `react-hooks/exhaustive-deps` | Missing/incorrect hook dependency arrays |
41
+ | `react-hooks/rules-of-hooks` | Hooks called conditionally or in loops |
42
+
43
+ ### Error handling (ESLint core)
44
+
45
+ | Rule | Catches |
46
+ | ------------------------------------------ | ------------------------------------- |
47
+ | `no-empty` (with `allowEmptyCatch: false`) | Empty catch blocks - swallowed errors |
48
+
49
+ ## Procedure
50
+
51
+ 1. Check if the project has an existing ESLint config.
52
+ 2a. If yes, extend it with missing rules from above.
53
+ 2b. If no config, create a temporary `.eslintrc.json` with all rules above.
54
+ 2. Run: `npx eslint --format json <src_dir>` — replace `<src_dir>` with the project's JS/TS source root (check `package.json` scripts or look for `src/`, `app/`, `lib/`)
55
+ 3. Parse output into: `file:line -> rule -> message`.
@@ -0,0 +1,34 @@
1
+ # Phase 2: Semantic Sweep
2
+
3
+ Work through each area. Do not skip.
4
+ See [fix-reference.md](fix-reference.md) for concrete fix patterns per finding.
5
+
6
+ ## Checklist
7
+
8
+ ### Memoization
9
+
10
+ Check every exported function component: is it rendered in a list, a frequently-updating parent, or a context consumer? If yes and props are stable, wrap in `React.memo`. Check context providers for unstable `value` props. Skip `React.memo` if React Compiler is active.
11
+
12
+ ### List rendering
13
+
14
+ Check all list-like rendering: ScrollView+map, manually iterated arrays, deeply nested FlatLists. Verify lists use virtualization (`FlatList`/`FlashList`), stable keys, and proper item sizing.
15
+
16
+ ### Animations
17
+
18
+ Check all animation code against current library best practices. Prefer Reanimated over the Animated API. Check for JS-thread animation bottlenecks (`requestAnimationFrame` loops, state-driven animations).
19
+
20
+ ### Async patterns
21
+
22
+ Check for sequential `await` calls that could be `Promise.all`. Check for missing `AbortController` / cancellation on unmount. Check for fetch waterfalls (parent fetches → child fetches → grandchild fetches).
23
+
24
+ ### Effect cleanup
25
+
26
+ Check all `useEffect` hooks that create timers, listeners, or subscriptions. Verify each returns a cleanup function. Check for effects missing dependency arrays (runs every render).
27
+
28
+ ### State hygiene
29
+
30
+ Check for unused state (set but never rendered), unbounded state growth (arrays/objects that grow without cap), and derived state that should be computed with `useMemo` instead.
31
+
32
+ ### Monolithic context
33
+
34
+ Flag but do NOT auto-fix. Report as architectural recommendation.
@@ -0,0 +1,160 @@
1
+ ---
2
+ name: argent-react-native-profiler
3
+ description: Profile a React Native Hermes app to measure re-render and CPU performance using argent profiler tools. Use when optimizing for performance, measuring before/after a fix, spotting slow components, diagnosing re-renders, checking CPU hotspots, or producing a ranked issue report.
4
+ ---
5
+
6
+ This skill is complementary to `argent-react-native-optimization`, not a replacement for it.
7
+
8
+ ## 2. Tool Overview
9
+
10
+ ### React Profiler (Hermes / React commits)
11
+
12
+ | Tool | Purpose |
13
+ | --------------------------------- | ------------------------------------------------------------------------------------------------------------- |
14
+ | `react-profiler-start` | Start CPU sampling + inject React commit-capture hook. Optional: `sample_interval_us` (default 100). |
15
+ | `react-profiler-stop` | Stop recording; stores cpuProfile + commitTree in session. |
16
+ | `react-profiler-analyze` | Run pipeline -> report with CPU-enriched hot commits, sorted by `totalRenderMs` DESC. Saves raw data to disk. |
17
+ | `react-profiler-component-source` | AST lookup: file, line, memoization status, 50 lines of source for a component. |
18
+ | `react-profiler-renders` | Live fiber walk: render counts + durations per component (no profiling session required). |
19
+ | `react-profiler-fiber-tree` | Live fiber walk: full component hierarchy as JSON. |
20
+
21
+ ### Drill-Down Query Tools (call after analyze)
22
+
23
+ | Tool | Purpose |
24
+ | -------------------------- | -------------------------------------------------------------------------------------------- |
25
+ | `profiler-cpu-query` | Targeted CPU investigation: top functions, time-windowed CPU, call trees, per-component CPU. |
26
+ | `profiler-commit-query` | Targeted commit investigation: by component, time range, commit index, or cascade tree. |
27
+ | `profiler-stack-query` | iOS Instruments drill-down: hang stacks, function callers, thread breakdown, leak details. |
28
+ | `profiler-combined-report` | Cross-correlated report when both React Profiler and iOS Instruments ran in parallel. |
29
+ | `profiler-load` | List and reload previous profiling sessions from disk for re-investigation with query tools. |
30
+
31
+ For native iOS profiling (CPU hotspots, UI hangs, memory leaks), see the `argent-ios-profiler` skill.
32
+
33
+ ---
34
+
35
+ ## 3. Agent Behavior Guidelines
36
+
37
+ Follow these rules throughout the profiling workflow:
38
+
39
+ - Start `react-profiler-start` and `ios-profiler-start` in parallel (two tool calls in one message). Both need `device_id`; use the same UDID for both so their data can be correlated later. This gives best coverage.
40
+ - If the user only wants iOS-only, use the `argent-ios-profiler` skill workflow. Only skip `ios-profiler-start` if the user has **already explicitly said** they don't want native profiling in this session
41
+
42
+ ### After analysis: ask about next steps
43
+
44
+ After presenting the analysis report, always ask the user what they want to do next. Present these options:
45
+
46
+ 1. **Investigate further** — drill down into specific findings using query tools (CPU call trees, commit cascades, hang stacks, etc.) to identify root causes with confidence before making changes.
47
+ 2. **Implement fixes** — apply changes based on the current findings, then re-profile to measure whether the metric changed (improved, regressed, or stayed flat).
48
+ 3. **Done for now** — accept the report as-is.
49
+
50
+ Do NOT silently move on after the report. The report is the starting point, not the end — query tools exist specifically to let you dig deeper into anything the report flags.
51
+
52
+ ### During investigation: use query tools proactively
53
+
54
+ When drilling down, chain query tool calls based on what you find:
55
+
56
+ - A hot commit -> `profiler-commit-query` mode=`by_index` to see all components -> `profiler-cpu-query` mode=`component_cpu` for the slowest one -> `profiler-cpu-query` mode=`call_tree` for the hot function -> read the source file -> propose a fix.
57
+ - A memory leak -> `profiler-stack-query` mode=`leak_stacks` to identify the responsible module -> read the native source if actionable.
58
+ - An iOS hang -> `profiler-stack-query` mode=`hang_stacks` to get the native call chain -> correlate with React commit timing.
59
+
60
+ ### After fixes: always re-profile
61
+
62
+ When you apply a fix, always re-profile the same scenario afterward. Compare before/after metrics (commit durations, CPU time, render counts) and report honestly: did the target metric improve, stay flat, or regress? Did any _other_ metric get worse? If you need to reference the original data, use `profiler-load` to reload the pre-fix session. If the fix showed no improvement or introduced a regression, say so explicitly and reconsider the approach.
63
+
64
+ ### Use flows for reproducible profiling
65
+
66
+ When profiling requires a specific interaction sequence (scroll a list, navigate screens, trigger an animation), **record the interaction as a flow** using the `argent-create-flow` skill before the first profiling run. Then replay the same flow for every subsequent run. This eliminates interaction variance as a confounder and makes before/after comparisons meaningful. Especially important when:
67
+
68
+ - You are about to re-profile after applying a fix (Step 8).
69
+ - The user asks you to compare multiple profiling sessions.
70
+ - The interaction path is more than 2-3 steps long.
71
+
72
+ ---
73
+
74
+ ## 4. Standard Profiling Workflow
75
+
76
+ **Complete all steps in order — do not break mid-flow.**
77
+
78
+ ### Step 1: Start profiling
79
+
80
+ Mind the react-native and ios-native profiler selection mentioned above when starting the session and start the tools. **Save `startedAtEpochMs` from the response** — you will need it later to compute annotation offsets. Every subsequent profiler/query call in this session must use the same `device_id`. Before beginning, define lightweight success criteria with the user: which metric matters most (e.g., `totalRenderMs`, specific commit duration, render count for a component) and what threshold would be meaningful. This anchors later evaluation. On success:
81
+
82
+ - if user asked you to perform the profiling, determine how to profile yourself using tools described in `argent-simulator-interact` skill.
83
+ - if the user stated they wish to perform the interaction themselves — suggest what interaction to perform (e.g. "scroll the list", "switch tabs") and wait for their reply.
84
+
85
+ #### Annotate every interaction
86
+
87
+ After each `gesture-tap` or `gesture-swipe` call, record an annotation using the returned `timestampMs`. Compute `offsetMs = timestampMs - startedAtEpochMs`. Do this for _every_ interaction — including back-navigation swipes, not just the primary action. Pass all collected annotations to `react-profiler-analyze` in Step 3.
88
+
89
+ ### Step 2: Stop and collect
90
+
91
+ Call `react-profiler-stop` **and** `ios-profiler-stop` in parallel. Only skip `ios-profiler-stop` if you did not start it in Step 1. Note `duration_ms`, `fiber_renders_captured`, `hook_installed`.
92
+ If `hook_installed: false` or `fiber_renders_captured: 0`, warn the user — React commit data may be missing.
93
+
94
+ ### Step 3: Analyze
95
+
96
+ Call `react-profiler-analyze` with `port`, `device_id`, `project_root`, `platform`, and `rn_version`. The report includes metadata such as `reactCompilerEnabled`, `strictModeEnabled`, and `buildMode` — check these in the returned markdown report.
97
+
98
+ If you performed interactions using `gesture-tap`/`gesture-swipe`, pass `annotations` to mark when each action occurred. Each annotation's `offsetMs` must be computed as `tapTimestampMs - startedAtEpochMs`, where `tapTimestampMs` is the `timestampMs` returned by the gesture-tap/gesture-swipe tool and `startedAtEpochMs` was returned by `react-profiler-start`. Do **not** use `Date.now()` for this calculation — only server-side timestamps from the tool return values.
99
+
100
+ If dual profiling, also call `ios-profiler-analyze`, then **you must** call `profiler-combined-report` for the cross-correlated view — do not skip this step when both profilers ran; the combined report surfaces correlations that individual reports miss.
101
+
102
+ The analyze report includes **CPU hotspots per commit** — showing exactly which JS functions ran during each slow React commit. Raw data is saved to disk automatically for later reload.
103
+
104
+ ### Step 4: Assess results
105
+
106
+ Analyze whether the results give you a proper image of what is wrong with the application - **do not assume improvement always exists**, verify results logically with reference to how react-native works. Make sure to give honest feedback and be ready to change the approach if needed.
107
+
108
+ ### Step 5: Present findings and ask about next steps
109
+
110
+ Present a concise summary of the key findings - present whether possibilities for improvement exist and how performing further actions could affect performance. Then follow the "After analysis" guideline — ask whether to investigate further, implement fixes (if available), or stop.
111
+
112
+ ### Step 6: Drill-down investigation (iterative)
113
+
114
+ Based on findings from the report, use query tools to investigate deeper:
115
+
116
+ - **Slow component?** -> `profiler-cpu-query` mode=`component_cpu` component_name=`AppNavigator` — shows what JS functions ran during that component's commits.
117
+ - **Want to see the call tree?** -> `profiler-cpu-query` mode=`call_tree` function_name=`expensiveFunction` — shows callers and callees.
118
+ - **What happened during a time window?** -> `profiler-commit-query` mode=`by_time_range` — lists all commits in a range.
119
+ - **Full commit detail?** -> `profiler-commit-query` mode=`by_index` commit_index=38 — all components, props changes, parent cascade.
120
+ - **Who triggered whom?** -> `profiler-commit-query` mode=`cascade_tree` — visual parent-child cascade.
121
+ - **iOS hang details?** -> `profiler-stack-query` mode=`hang_stacks` — native call stacks during a hang.
122
+
123
+ Repeat as needed until you identify the root cause function and file, referring to step 4 for honest evaluation. After each round of investigation, ask the user if they want to continue digging or move to fixing.
124
+
125
+ ### Step 7: Reload a previous session
126
+
127
+ If you profiled multiple scenarios and need to revisit earlier data:
128
+
129
+ 1. Call `profiler-load` mode=`list` to see all saved sessions with timestamps (the list now also shows Runtime / Device / Metro bundle columns to help identify the right session).
130
+ 2. Call `profiler-load` mode=`load_react` session_id=`<timestamp>` device_id=`<UDID>` to reload React data. `device_id` scopes the reload into the `port:device_id` cache slot.
131
+ 3. Call `profiler-load` mode=`load_instruments` session_id=`<timestamp>` device_id=`<UDID>` to reload iOS data.
132
+ 4. Query tools now operate on the reloaded session data — **pass the same `device_id` you loaded with**, otherwise they will miss the cache.
133
+
134
+ This is useful for before/after comparisons: profile, fix, re-profile, then reload the original session to compare metrics side by side.
135
+
136
+ ### Step 8: Apply fix and re-profile
137
+
138
+ If fix is present, read the source code of the identified bottleneck using `react-profiler-component-source` or the Read tool. Apply the fix, then re-profile (Step 1 -> user interaction -> Step 2 -> Step 3 -> Step 4). Report whether the target metric improved, stayed flat, or regressed. Also check whether the fix introduced regressions in other metrics (e.g., render count dropped but CPU time increased, or a different component now re-renders more). If the fix showed no net benefit or unacceptable tradeoffs, revert and reconsider.
139
+
140
+ **Tip:** If the interaction sequence was recorded as a flow (see "Use flows for reproducible profiling" above), replay it with `flow-execute` instead of manually repeating the steps. This guarantees identical interaction conditions for the comparison. If the flow fails during replay (e.g., a UI fix changed the layout), follow `argent-create-flow` skill §10 (Flow Self-Improvement) to diagnose and repair the flow before retrying the profiling cycle.
141
+
142
+ If the user stated that they do not wish for changes, present the profiling report and skip the fix but suggest it to the user.
143
+
144
+ **React Compiler rule:** If the analyze report indicates React Compiler is enabled, do NOT propose `useCallback`/`useMemo`/`React.memo` unless you confirmed compiler bail-out (check `react-profiler-fiber-tree` for absent `useMemoCache` on that component).
145
+
146
+ ---
147
+
148
+ ## 5. Important Caveats
149
+
150
+ - **Dev mode inflation**: `buildMode: "dev"` renders are ~3x slower than production. Prioritize high `normalizedRenderCount` — it scales to prod.
151
+ - **Re-run after fixes**: Always re-profile after changes. Report honestly whether the metric improved, regressed, or stayed flat — do not assume improvement.
152
+ - **`excluded` is informational**: Components in `animatedSubtrees` and `recyclerChildren` re-render by design.
153
+ - **Strict Mode**: Double-invokes renders. The pipeline halves `normalizedRenderCount` automatically when detected.
154
+ - **Debugger connection**: If interrupted, started profiling also closes. Check debugger status and restart the flow on errors.
155
+ - **Confounders to watch for**:
156
+ - Live API data may differ between runs (different payload sizes, content counts), which shifts render counts and durations independently of your fix. Note when data-dependent components show variance.
157
+ - Profiler overhead inflates CPU measurements. If iOS Instruments shows `JSLexer`, `JSONEmitter`, or Hermes internals dominating the JS thread, that reflects profiler instrumentation cost — not app work. Discount those entries.
158
+ - Runs are not perfectly reproducible. Small variations (under ~10-15%) in commit duration may be noise; only treat consistent, directional changes as signal.
159
+
160
+ For standalone diagnostic tools (live render stats, fiber tree, CPU summary), see `references/diagnostic-tools.md`.