@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
Binary file
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@swmansion/argent",
3
+ "version": "0.5.1",
4
+ "description": "MCP server for iOS Simulator control",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/software-mansion/argent.git"
8
+ },
9
+ "type": "module",
10
+ "bin": {
11
+ "argent": "dist/cli.js",
12
+ "argent-simulator-server": "bin/simulator-server"
13
+ },
14
+ "scripts": {
15
+ "build": "npm run build:mcp && npm run build:tools-bundle && npm run sync-readme",
16
+ "build:mcp": "rm -rf dist tsconfig.tsbuildinfo && tsc",
17
+ "sync-readme": "node scripts/sync-readme.cjs",
18
+ "prepack": "node scripts/sync-readme.cjs",
19
+ "build:tools-bundle": "node scripts/bundle-tools.cjs",
20
+ "dev": "node --loader ts-node/esm src/cli.ts mcp",
21
+ "test": "vitest run",
22
+ "test:watch": "vitest",
23
+ "observe": "node scripts/observe.cjs",
24
+ "benchmark": "node scripts/benchmark.cjs",
25
+ "postinstall": "node scripts/postinstall.cjs"
26
+ },
27
+ "private": false,
28
+ "publishConfig": {
29
+ "registry": "https://registry.npmjs.org",
30
+ "access": "public"
31
+ },
32
+ "files": [
33
+ "dist/",
34
+ "bin/",
35
+ "dylibs/",
36
+ "skills/",
37
+ "agents/",
38
+ "rules/",
39
+ "scripts/postinstall.cjs"
40
+ ],
41
+ "dependencies": {
42
+ "@clack/prompts": "^1.1.0",
43
+ "@modelcontextprotocol/sdk": "^1.20.0",
44
+ "picocolors": "^1.1.1",
45
+ "smol-toml": "^1.6.1"
46
+ },
47
+ "devDependencies": {
48
+ "@types/node": "^22.0.0",
49
+ "esbuild": "^0.27.3",
50
+ "typescript": "^5.5.0",
51
+ "vitest": "^4.0.18"
52
+ }
53
+ }
@@ -0,0 +1,121 @@
1
+ ---
2
+ description: Argent iOS Simulator Agent — always-on guidance for methodology and tools for working with, interacting, testing and profiling mobile app work
3
+ alwaysApply: true
4
+ ---
5
+
6
+ <description>
7
+ Argent MCP tools are available in this project for iOS simulator control. Argent MCP tools are the preferred form of interaction with the application.
8
+ Running MCP server and managing the Argent toolkit utilises `argent` command - if asked use `argent --help` for reference.
9
+ To check current version of MCP server run `argent --version` command.
10
+
11
+ Use cases:
12
+
13
+ - User mentions iOS simulator, device, or app interaction
14
+ - The app user is working with is a mobile application which can be run in the simulator
15
+ - Any tapping, swiping, typing, screenshotting, or inspecting a running app
16
+ - Running, debugging, or testing a React Native app
17
+ - Profiling performance or diagnosing re-renders in a React Native app
18
+ </description>
19
+
20
+ <tapping_rule>
21
+ <important>**Never** derive tap coordinates from a screenshot</important>
22
+ Before **every** tap, you MUST call a discovery tool and extract coordinates from the result. This is not optional. Preferred tools are, in order:
23
+
24
+ - `describe` - native app-level components and safely targetable foreground apps.
25
+ - `native-describe-screen` - accessibility screen description via injected native devtools
26
+ - `debugger-component-tree` - react-native specific components
27
+
28
+ `native-user-interactable-view-at-point` / `native-view-at-point` are follow-up diagnostics once you already have a candidate point.
29
+
30
+ Whenever something changed YOU MUST first call `describe`, or another appropriate discovery tool so you do not hallucinate element positions. Do not guess coordinates if you can use discovery tool. Do not tap if you have not called a discovery tool in the current step. Screenshots alone are never sufficient for coordinates.
31
+
32
+ If a **tap fails twice** at the same coordinates, **stop retrying**. Re-run the discovery tool.
33
+
34
+ If `describe` fails, **read the exact error before reacting**, follow the recovery guidance in `argent-simulator-interact` to choose the correct next action.
35
+
36
+ Before starting to interact with the app, read the `argent-simulator-interact` skill first.
37
+ </tapping_rule>
38
+
39
+ <skill_reading_rule>
40
+ <important>Always read relevant skills for guidance before executing argent-mcp tool - read skill_routing reference</important>
41
+ </skill_reading_rule>
42
+
43
+ <general_rules>
44
+
45
+ - All simulator interactions go through argent MCP tools — never use `xcrun simctl`,
46
+ raw `curl` to simulator ports, or the simulator-server binary directly.
47
+ - Before calling any gesture tool for the first time, use ToolSearch to load its schema.
48
+ - Interaction tools (`gesture-tap`, `gesture-swipe`, `gesture-pinch`, `gesture-rotate`, `gesture-custom`, `launch-app`, etc.) return a screenshot automatically.
49
+ Call `screenshot` separately only for a baseline before any action or after a delay.
50
+ - Always open apps with `launch-app` or `open-url` — never tap home screen icons.
51
+ - Always use `run-sequence` when performing multiple sequential simulator actions where you don't need to observe the screen between steps. More in `simulator-interact` skill.
52
+ - When the session ends or the user says they are done: call `stop-all-simulator-servers`.
53
+ If the user started Metro separately, ask whether to call `stop-metro` (specify the port if not 8081).
54
+ - If tools provided by mcp-server are not sufficient and action can be done using `xcrun` or other commands, use the command. Examples: changing simulator options, performing simulator action such as lock, shake, etc.
55
+ - When waiting for an action, do not call `screenshot` repeatedly without a proper wait mechanism. For example, six consecutive `screenshot` calls with no adequate delay between them will cause context bloat.
56
+ </general_rules>
57
+
58
+ <react_native_detection>
59
+ Project type is determined by the `argent-environment-inspector` subagent (see `subagents` section).
60
+ When the subagent result is available, use its `is_react_native` field as the authoritative
61
+ source — do not re-inspect files manually.
62
+
63
+ If the subagent has not run yet and project type is unknown, run it first before proceeding. Always use subagents if available to run `gather-workspace-data` data tool, if possible do not run yourself.
64
+
65
+ When `is_react_native` is true: load `argent-react-native-app-workflow` skill. Use `debugger-component-tree` for element discovery - if the responses are large or unhelpful, try `describe`.
66
+ </react_native_detection>
67
+
68
+ <skill_routing>
69
+ Load the matching skill before starting work and executing tools from argent-mcp — skills contain the full step-by-step
70
+ procedure and edge-case handling for each workflow.
71
+
72
+ SIMULATOR SETUP
73
+ Skill: `argent-simulator-setup`
74
+ When: Beginning a task that involves the simulator, no simulator booted yet, need UDID or simulator-server.
75
+
76
+ TAPPING, SWIPING, TYPING, GESTURES, SCREENSHOTS, SCROLLING
77
+ Skill: `argent-simulator-interact`
78
+ When: Performing touch interactions, typing, pressing hardware buttons, launching/restarting apps, opening URLs, rotating device, or taking standalone screenshots.
79
+
80
+ RUNNING / BUILDING / DEBUGGING REACT NATIVE APP
81
+ Skill: `argent-react-native-app-workflow`
82
+ When: Project is react-native, starting Metro or running iOS app, build failures, pod issues, lost Metro connection, reading logs, reloading JS bundle, reinstalling app.
83
+
84
+ JS EVALUATION, METRO CONNECTION, REACT NATIVE
85
+ Skill: `argent-metro-debugger`
86
+ When: evaluating expressions, inspecting React component tree at source level, finding element placement via `debugger-component-tree`.
87
+
88
+ REACT APP & COMPONENT PROFILING
89
+ Use skill: `argent-react-native-profiler`
90
+ When: To measure performance of specific components, to find app-wide bottlenecks. Investigating re-renders or CPU hotspots, producing ranked performance reports.
91
+
92
+ NATIVE iOS PROFILING
93
+ Use skill: `argent-ios-profiler`
94
+ When: Profiling native iOS performance (CPU hotspots, UI hangs, memory leaks via Instruments). Useful as a reference for iOS-specific investigation when running dual profiling via `argent-react-native-profiler`.
95
+
96
+ PERFORMANCE OPTIMIZATION
97
+ Use skill: `argent-react-native-optimization`
98
+ When: App feels slow, user asks to optimize, reducing bundle size, improving startup time, fixing re-renders, optimizing lists/images/navigation, or any performance-related task. This is the entry-point skill for all performance work — it delegates to `argent-react-native-profiler` for measurement.
99
+
100
+ END-TO-END UI TESTING
101
+ Skill: `argent-test-ui-flow`
102
+ When: Verifying complete user flows, running interact → screenshot → verify loops, testing features by using the app.
103
+
104
+ RECORDING & REPLAYING FLOWS
105
+ Use skill: `argent-create-flow`
106
+ When: A multi-step interaction sequence needs to be repeated — re-profiling after a fix, A/B comparisons, regression checks, user says "again" / "run that flow", or you worked through a complex path worth saving. Also use proactively: if you are about to repeat steps you already performed, record first, then replay.
107
+ Prompt keywords: flow, repeat, test X times
108
+ </skill_routing>
109
+
110
+ <subagents>
111
+ ENVIRONMENT INSPECTION AT SESSION START
112
+ Use subagent: `argent-environment-inspector`
113
+ When:
114
+ - Environment context of the project is not yet known
115
+ - No "Project Environment" section exists in project memory / `MEMORY.md` or you lack information about basic setup workflows
116
+ - Need to determine build commands, startup scripts, metro port, platform support, or QA tooling
117
+ If the subagent already ran this session (result in memory), use that context directly — do NOT re-run.
118
+ Rules:
119
+ - Run the `argent-environment-inspector` subagent if possible. Never call `gather-workspace-data` yourself - do only if subagent is not available.
120
+ - The main agent is responsible for persisting the subagent's JSON result to project memory
121
+ </subagents>
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env node
2
+ // @ts-check
3
+ "use strict";
4
+
5
+ // Runs automatically after `npm install @swmansion/argent`.
6
+ // Set ARGENT_SKIP_POSTINSTALL=1 to suppress the init message (used by `argent update`).
7
+
8
+ const os = require("os");
9
+ const fs = require("fs");
10
+ const path = require("path");
11
+
12
+ // Always kill any running tool-server so the new binary takes effect on next use.
13
+ const stateFile = path.join(os.homedir(), ".argent", "tool-server.json");
14
+ try {
15
+ const state = JSON.parse(fs.readFileSync(stateFile, "utf8"));
16
+ if (state && state.pid) {
17
+ try {
18
+ process.kill(state.pid, "SIGTERM");
19
+ } catch {}
20
+ }
21
+ fs.unlinkSync(stateFile);
22
+ } catch {}
23
+
24
+ if (process.env.ARGENT_SKIP_POSTINSTALL === "1") {
25
+ process.exit(0);
26
+ }
27
+
28
+ console.log(`
29
+ @swmansion/argent installed.
30
+
31
+ To set up your workspace (MCP server, skills, rules), run:
32
+
33
+ argent init
34
+ `);
@@ -0,0 +1,213 @@
1
+ ---
2
+ name: argent-create-flow
3
+ description: Record a reusable flow (scripted sequence of MCP tool calls) that can be replayed later with a single command. Use when the user asks to create, record, or build a flow, or to script a sequence of simulator actions.
4
+ ---
5
+
6
+ ## 1. Overview
7
+
8
+ A flow is a recorded sequence of MCP tool calls saved to a `.yaml` file in the `.argent/flows/` directory. Each step is **executed live** as you add it, so you verify it works before it becomes part of the flow. Replay a finished flow with `flow-execute`.
9
+
10
+ ## 2. Tools
11
+
12
+ | Tool | Purpose |
13
+ | ------------------------ | -------------------------------------------------------------------------- |
14
+ | `flow-start-recording` | Start recording — takes a name and executionPrerequisite, creates the file |
15
+ | `flow-add-step` | Execute a tool call live and record it if it succeeds |
16
+ | `flow-add-echo` | Add a label/comment that prints during replay |
17
+ | `flow-finish-recording` | Stop recording and get a summary |
18
+ | `flow-read-prerequisite` | Read a flow's execution prerequisite without running it |
19
+ | `flow-execute` | Replay a saved flow by name |
20
+
21
+ ## 3. Workflow
22
+
23
+ ### Recording
24
+
25
+ 1. **Start**: Call `flow-start-recording` with a descriptive name, the absolute `project_root`, and an `executionPrerequisite` describing the required app state before running the flow (e.g. "App on home screen after a fresh reload"). `project_root` is stored for the session — you do **not** need to pass it again to subsequent tools.
26
+ 2. **Build step-by-step**: For each action, call `flow-add-step` with the tool name and args. The tool runs immediately — check the result before moving on.
27
+ 3. **Add labels**: Use `flow-add-echo` between steps to describe what each section does.
28
+ 4. **Finish**: Call `flow-finish-recording` to stop recording. It returns the file path where the flow was saved and a summary of all steps. You can edit the `.yaml` file directly afterwards to remove, reorder, or tweak steps.
29
+
30
+ Every tool during recording returns the current flow file contents so you can track what has been recorded.
31
+
32
+ ### Replaying
33
+
34
+ Call `flow-execute` with the flow name. If the flow has an execution prerequisite:
35
+
36
+ 1. The tool returns a **notice** with the prerequisite text instead of running. It asks you to verify the prerequisite is met and call `flow-execute` again with `prerequisiteAcknowledged: true`.
37
+ 2. You can also call `flow-read-prerequisite` beforehand to inspect the prerequisite without triggering a run.
38
+ 3. Once you pass `prerequisiteAcknowledged: true`, the flow runs all steps in order and returns every tool call result (including screenshots) merged into a single response.
39
+
40
+ If the flow has no prerequisite, it runs immediately without needing acknowledgment.
41
+
42
+ ## 4. flow-add-step Usage
43
+
44
+ The `command` parameter is the MCP tool name. The `args` parameter is a **JSON string** (not an object):
45
+
46
+ ```
47
+ command: "launch-app"
48
+ args: "{\"udid\": \"<UDID>\", \"bundleId\": \"com.apple.Preferences\"}"
49
+ ```
50
+
51
+ ```
52
+ command: "gesture-tap"
53
+ args: "{\"udid\": \"<UDID>\", \"x\": 0.5, \"y\": 0.35}"
54
+ ```
55
+
56
+ ```
57
+ command: "screenshot"
58
+ args: "{\"udid\": \"<UDID>\"}"
59
+ ```
60
+
61
+ For tools with no arguments, omit `args` entirely.
62
+
63
+ ## 5. Important Rules
64
+
65
+ - **Every step runs live.** You will see the real tool result (including screenshots). Use this to verify the step worked before continuing.
66
+ - **Only successful steps are recorded.** If a tool call fails, nothing is written to the flow file — fix the issue and try again.
67
+ - **Pass `project_root` only to `flow-start-recording`.** It is stored for the session and automatically used by all subsequent flow tools. An error is returned if the path is not absolute.
68
+ - **You do NOT need to pass a flow name** to `flow-add-step`, `flow-add-echo`, or `flow-finish-recording`. The active flow is tracked automatically after `flow-start-recording`.
69
+ - **Start before adding.** Calling `flow-add-step`, `flow-add-echo`, or `flow-finish-recording` without an active recording returns an error: _"No active flow. Call flow-start-recording first."_
70
+ - **One flow at a time.** If you call `flow-start-recording` while already recording, the active flow switches to the new one. The response tells you which flow was abandoned and which is now active. The old flow's file remains on disk.
71
+ - **Mistakes can be edited out.** If a step was recorded by mistake, edit the `.yaml` file directly to remove or reorder entries.
72
+
73
+ ## 6. Example Session
74
+
75
+ ```
76
+ flow-start-recording { name: "open-settings", project_root: "/Users/dev/MyApp", executionPrerequisite: "Simulator booted with app installed" }
77
+ flow-add-echo { message: "Launch Settings app" }
78
+ flow-add-step { command: "launch-app", args: "{\"udid\": \"ABC\", \"bundleId\": \"com.apple.Preferences\"}" }
79
+ flow-add-echo { message: "Tap General" }
80
+ flow-add-step { command: "gesture-tap", args: "{\"udid\": \"ABC\", \"x\": 0.5, \"y\": 0.35}" }
81
+ flow-add-echo { message: "Tap About" }
82
+ flow-add-step { command: "gesture-tap", args: "{\"udid\": \"ABC\", \"x\": 0.5, \"y\": 0.17}" }
83
+ flow-finish-recording {}
84
+ ```
85
+
86
+ ## 7. Replay Example
87
+
88
+ ```
89
+ flow-execute { name: "open-settings", project_root: "/Users/dev/MyApp" }
90
+ → Returns: notice with executionPrerequisite: "Simulator booted with app installed"
91
+ "Verify the prerequisite is met and call flow-execute again with prerequisiteAcknowledged set to true."
92
+
93
+ flow-execute { name: "open-settings", project_root: "/Users/dev/MyApp", prerequisiteAcknowledged: true }
94
+ → Runs all steps, returns merged results with status and output for every step
95
+ ```
96
+
97
+ ## 8. Flow File Format
98
+
99
+ Flow files use YAML. The top-level is an object with `executionPrerequisite` (describes required state) and `steps` (array of actions):
100
+
101
+ - `- echo: <message>` — a label
102
+ - `- tool: <name>` with optional `args:` — a tool call
103
+
104
+ Example `.yaml` file:
105
+
106
+ ```yaml
107
+ executionPrerequisite: Simulator booted with app installed
108
+ steps:
109
+ - echo: Launch Settings app
110
+ - tool: launch-app
111
+ args:
112
+ udid: ABC
113
+ bundleId: com.apple.Preferences
114
+ - echo: Tap General
115
+ - tool: gesture-tap
116
+ args:
117
+ udid: ABC
118
+ x: 0.5
119
+ y: 0.35
120
+ - echo: Tap About
121
+ - tool: gesture-tap
122
+ args:
123
+ udid: ABC
124
+ x: 0.5
125
+ y: 0.17
126
+ ```
127
+
128
+ ## 9. When to Proactively Record a Flow
129
+
130
+ You do not need the user to ask for a flow. Record one proactively when you recognize any of these patterns:
131
+
132
+ - **About to re-profile**: You completed a profiling session and are about to apply a fix and re-profile. Record the interaction steps now so the re-profile replays them identically (see `argent-react-native-profiler` and `argent-ios-profiler` skills).
133
+ - **Repeating steps**: You have already performed a multi-step interaction sequence once and the task requires doing it again (comparison, retry, re-test).
134
+ - **Complex path discovered**: You worked through a non-trivial sequence of taps/swipes/navigation to reach a desired app state. Capture it before it is lost.
135
+ - **User says "again" / "one more time"**: Any request to redo what you just did is a signal to record first, then replay.
136
+
137
+ ## 10. Flow Self-Improvement
138
+
139
+ Flows break. UI layouts change, coordinates drift, screens get added or removed. When `flow-execute` returns a failure, follow this procedure to diagnose and fix the flow instead of silently re-recording or giving up.
140
+
141
+ ### 10.1 Classify the Result
142
+
143
+ After every `flow-execute`, classify the outcome before proceeding:
144
+
145
+ | Outcome | Signal | Action |
146
+ | ---------------------- | --------------------------------------------------------------------- | ------------------ |
147
+ | **Success** | All steps completed, final screenshot shows expected state | Continue with task |
148
+ | **Hard error** | A step has `ERROR` in the result — engine stopped there | Enter §10.2 |
149
+ | **Silent misfire** | All steps completed but final screenshot shows wrong screen | Enter §10.2 |
150
+ | **Partial divergence** | Intermediate screenshot shows wrong state even though later steps ran | Enter §10.2 |
151
+
152
+ For silent misfires and partial divergence, echo annotations (§10.5) are your reference for what each screen _should_ look like.
153
+
154
+ ### 10.2 Diagnose
155
+
156
+ 1. Note the failure step index and error message (if hard error).
157
+ 2. Call `screenshot` to see where the app actually is now.
158
+ 3. Call `describe` or `debugger-component-tree` to get the current element tree.
159
+ 4. Compare current state to what the failed step expected. Classify the root cause:
160
+
161
+ | Root cause | Symptoms |
162
+ | ---------------- | --------------------------------------------------------------- |
163
+ | Coordinate drift | Tap succeeded but hit wrong element; elements shifted positions |
164
+ | Missing element | Target element not present in element tree |
165
+ | Wrong screen | Screenshot shows entirely different page than expected |
166
+ | Timing | Element exists in tree but tap missed; loading spinner visible |
167
+ | State mismatch | First step fails — executionPrerequisite was not actually met |
168
+
169
+ 5. State the diagnosis in one sentence before attempting any correction.
170
+
171
+ ### 10.3 Correct
172
+
173
+ Choose the lightest strategy that fits:
174
+
175
+ **Strategy 1 — Edit the YAML** (coordinate drift, parameter changes).
176
+ Read `.argent/flows/<flow-name>.yaml`, update the broken step's `x`/`y`, `bundleId`, `text`, or other args. Re-run `flow-execute` to verify.
177
+
178
+ **Strategy 2 — Manual recovery + continue** (timing/transient issues, one-off replay).
179
+ Manually execute the failed step with corrected coordinates from §10.2 discovery, then manually execute remaining steps. Does not fix the YAML — use only when re-recording is not worth it.
180
+
181
+ **Strategy 3 — Re-record from failure point** (structural changes, new intermediate screens).
182
+ Navigate the app to the state just before the failure point. Call `flow-start-recording` with the same flow name (overwrites). Re-add the working prefix steps via `flow-add-step`, then continue recording new steps from the divergence point. Call `flow-finish-recording`.
183
+
184
+ **Strategy 4 — Full re-record** (major changes, unclear diagnosis, or 3+ broken steps).
185
+ Reset the app to prerequisite state (`restart-app` + `launch-app`). Record from scratch with the same flow name.
186
+
187
+ **Decision heuristic:**
188
+
189
+ - 1 step broken, parameter-only change → Strategy 1
190
+ - 1 step broken, transient issue, not worth persisting → Strategy 2
191
+ - 2–3 steps broken or flow structure partially changed → Strategy 3
192
+ - 3+ steps broken, or unclear root cause → Strategy 4
193
+ - Flow used for profiling comparison (must be identical) → Strategy 4
194
+
195
+ ### 10.4 Verify and Bound Retries
196
+
197
+ After applying a correction, re-run `flow-execute` to verify.
198
+
199
+ - If it succeeds → done. Report what changed (e.g. "Fixed step 4: updated tap coordinates from 0.5,0.35 to 0.5,0.42").
200
+ - If it fails at a **different** step → return to §10.2 for a second attempt.
201
+ - If this is already the second correction attempt → **stop**. Report the diagnosis to the user and recommend a full re-record or manual investigation.
202
+
203
+ **Hard cap: 2 correction cycles.** Do not enter an unbounded fix loop.
204
+
205
+ ### 10.5 Making Flows Resilient
206
+
207
+ Apply these when recording new flows to reduce future breakage:
208
+
209
+ - **Echo expected state, not just actions.** Write `"On Settings > General screen, about to tap About"` not `"Tap About"`. During diagnosis these tell you what the screen _should_ look like.
210
+ - **Add screenshot steps after critical navigation.** Insert `screenshot` steps after screen transitions. These produce images in the flow result you can inspect during diagnosis.
211
+ - **Write specific executionPrerequisites.** `"App on home tab, user logged in, simulator UDID is <X>"` — not `"App running"`. Verify with `screenshot` + `describe` before acknowledging.
212
+ - **Prefer launch-app / open-url over navigation chains.** Deep links are more resilient to layout changes than tap sequences.
213
+ - **Echo accessibility labels for coordinate taps.** When recording a tap, add an echo with the target's label or testID: `"Tapping 'Submit' button (testID: submit-btn) at 0.5, 0.82"`. During repair, use `describe` to find the element by label and update coordinates. Only use `screenshot` for permission or system overlays when `describe` cannot expose the target reliably.
@@ -0,0 +1,103 @@
1
+ ---
2
+ name: argent-ios-profiler
3
+ description: Native iOS profiling for CPU hotspots, UI hangs, and memory leaks via xctrace. Use when diagnosing native-level performance issues on iOS simulators or devices.
4
+ ---
5
+
6
+ ## 1. Tool Overview
7
+
8
+ | Tool | Purpose |
9
+ | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
10
+ | `ios-profiler-start` | Start xctrace recording on a booted simulator or device. Captures CPU, hangs, and leaks. Optional: `app_process`, `template_path`. |
11
+ | `ios-profiler-stop` | Stop xctrace, export trace data to XML files (timestamped, persist on disk). |
12
+ | `ios-profiler-analyze` | Parse exported XML and return structured bottleneck payload (CPU hotspots, UI hangs, leaks). |
13
+ | `profiler-stack-query` | Drill into parsed data: hang stacks, function callers, thread breakdown, leak details. |
14
+ | `profiler-load` | List and reload previous trace sessions from disk for re-investigation. |
15
+
16
+ ---
17
+
18
+ ## 2. Investigation Patterns
19
+
20
+ After `ios-profiler-analyze` surfaces findings, use `profiler-stack-query` to drill into root causes:
21
+
22
+ - **Hang detected** → `profiler-stack-query` mode=`hang_stacks` for full native call chains → mode=`function_callers` for the suspected function → read native source.
23
+ - **CPU hotspot** → `profiler-stack-query` mode=`thread_breakdown` for per-thread distribution → mode=`function_callers` for the dominant function.
24
+ - **Memory leak** → `profiler-stack-query` mode=`leak_stacks` filtered by `object_type` for responsible frames and libraries.
25
+
26
+ After presenting findings, ask the user whether to investigate further, implement fixes, or stop. After applying fixes, always re-profile the same scenario and compare with `profiler-load`. Report honestly whether the target metric improved, regressed, or stayed flat. If the fix showed no net benefit or introduced regressions elsewhere, say so and reconsider.
27
+
28
+ **Tip:** For reproducible before/after comparisons, record the interaction sequence as a flow using the `argent-create-flow` skill before the first profiling run. Replay with `flow-execute` on subsequent runs to eliminate interaction variance.
29
+
30
+ > **Note:** The `argent-react-native-profiler` instructs to start iOS profiling automatically alongside React profiling. This skill's workflow and investigation patterns apply in both cases.
31
+
32
+ ---
33
+
34
+ ## 3. Workflow
35
+
36
+ **Complete all steps in order — do not break mid-flow.**
37
+
38
+ ### Step 0: Ensure the target app is running
39
+
40
+ The `ios-profiler-start` tool **auto-detects** the running app on the simulator.
41
+ You do not need to derive `app_process` manually — just make sure the app is launched.
42
+
43
+ 1. If the app is already running on the simulator, skip to Step 1 (do not pass `app_process`).
44
+ 2. If the app is not running, use `launch-app` with the correct bundle ID first.
45
+ 3. Only pass `app_process` explicitly if the tool reports multiple running user apps and you need to disambiguate.
46
+
47
+ > **Note**: If multiple build flavors are installed (dev, staging, prod), the tool will detect whichever one is currently running. If both are running, it will ask you to specify.
48
+
49
+ ### Step 1: Start recording
50
+
51
+ Call `ios-profiler-start` with `device_id` (simulator UDID). The tool auto-detects the running app and saves the trace to `/tmp/argent-profiler-cwd/` with a timestamped filename.
52
+ Let the user interact with the app or drive interaction via simulator tools (see `argent-simulator-interact` skill).
53
+
54
+ ### Step 2: Stop and export
55
+
56
+ Call `ios-profiler-stop` with `device_id`. This sends SIGINT to xctrace, waits for trace packaging, and exports CPU, hangs, and leaks data to XML. Check `exportDiagnostics` in the response for any export warnings.
57
+
58
+ ### Step 3: Analyze
59
+
60
+ Call `ios-profiler-analyze` with `device_id`. Returns a markdown report with bottlenecks categorized as CPU hotspots, UI hangs, or memory leaks, sorted by severity.
61
+
62
+ ### Step 4: Present findings and ask about next steps
63
+
64
+ Present a concise summary of the key findings. Then follow the "After analysis" guideline — ask whether to investigate further with query tools, implement fixes, or stop.
65
+
66
+ ### Step 5: Drill-down investigation
67
+
68
+ Use `profiler-stack-query` to investigate specific findings. See §3 Investigation Patterns for chaining guidance.
69
+
70
+ ### Step 6: Reload previous sessions
71
+
72
+ To revisit a previous trace:
73
+
74
+ 1. Call `profiler-load` mode=`list` to see available sessions.
75
+ 2. Call `profiler-load` mode=`load_instruments` session_id=`<timestamp>` device_id=`<UDID>` to re-parse the XML files.
76
+ 3. Use `profiler-stack-query` to investigate the reloaded data.
77
+
78
+ ---
79
+
80
+ ## 4. Understanding Results
81
+
82
+ Bottlenecks are categorized by severity:
83
+
84
+ - **RED**: CPU functions taking >15% of total time, all UI hangs, all memory leaks. These require immediate attention.
85
+ - **YELLOW**: CPU functions taking 5-15% of total time. Worth investigating but may be acceptable.
86
+
87
+ Each bottleneck type indicates a different class of problem:
88
+
89
+ - **CPU hotspots**: Native functions consuming excessive CPU time. Look for tight loops, expensive computations, or redundant work.
90
+ - **UI hangs**: Main thread blocked long enough to cause visible jank or unresponsiveness. Often caused by synchronous I/O, heavy layout passes, or lock contention.
91
+ - **Memory leaks**: Objects allocated but never freed. Common causes include retain cycles, unclosed resources, or forgotten observers.
92
+
93
+ ---
94
+
95
+ ## 5. Important Caveats
96
+
97
+ - **Simulator vs device**: Simulator profiling reflects host Mac performance, not real device hardware. Use device profiling for accurate CPU timings and memory behavior.
98
+ - **xctrace availability**: Requires Xcode command-line tools installed. Verify with `xcrun xctrace version`.
99
+ - **Profiler overhead**: xctrace instrumentation adds CPU load. If `JSLexer`, `JSONEmitter`, or Hermes runtime internals dominate the JS thread in CPU hotspot results, those reflect profiler overhead — not app work. Discount those entries when evaluating findings.
100
+ - **Run-to-run variance**: Small fluctuations in CPU percentages between runs are normal. Treat only consistent directional changes (across 2+ runs or >15% delta) as actionable signal.
101
+ - **Live data variability**: If the app fetches live API data, different responses between runs change rendering workload independently of code changes. Note when data-dependent screens show variance.
102
+
103
+ ---
@@ -0,0 +1,117 @@
1
+ ---
2
+ name: argent-metro-debugger
3
+ description: Debug a React Native app via Metro CDP using argent debugger tools. Use when connecting to Metro, inspecting React components, reading console logs, or evaluating JavaScript in the app runtime.
4
+ ---
5
+
6
+ ## 1. Prerequisites
7
+
8
+ The debugger requires **Metro dev server running** (default `localhost:8081`) and **a React Native app connected to Metro** (at least one CDP target). Verify via `debugger-status`.
9
+
10
+ ## 2. Tool Overview
11
+
12
+ All tools accept `port` (default 8081) AND `device_id` (the iOS Simulator UDID, a.k.a. `logicalDeviceId`). Always make sure you target the correct app on the correct device.
13
+
14
+ One Metro port can serve multiple connected devices (e.g. two simulators on `localhost:8081`). `device_id` pins every debugger/network/profiler call to a specific device so sessions do not collide.
15
+
16
+ ### Connect & diagnostics
17
+
18
+ | Tool | Purpose |
19
+ | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
20
+ | `debugger-connect` | Connect to Metro CDP. Returns port, projectRoot, deviceName, appName, `logicalDeviceId`, isNewDebugger, connected. The returned `logicalDeviceId` is the `device_id` for every subsequent debugger/network/profiler call. |
21
+ | `debugger-status` | Like connect + loadedScripts, enabledDomains, sourceMapReady. **Use to diagnose.** |
22
+
23
+ ### Reload & recovery
24
+
25
+ | Tool | Purpose |
26
+ | ----------------------- | ---------------------------------------------------------------------------------------- |
27
+ | `debugger-reload-metro` | Reload all connected apps (like pressing "r" in Metro terminal). Needs a CDP target. |
28
+ | `restart-app` | Terminate and relaunch the app by UDID and bundleId. Use when app lost Metro connection. |
29
+
30
+ ### Inspection & console
31
+
32
+ | Tool | Purpose |
33
+ | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
34
+ | `debugger-component-tree` | Full React fiber tree (names, depth, bounding rects, tap coordinates). |
35
+ | `debugger-inspect-element` | Inspect at (x, y) using **logical pixel coordinates** (not normalized 0-1): component hierarchy with source file:line and code fragment. See `references/source-maps.md`. |
36
+ | `debugger-log-registry` | Get log summary (counts, clusters, file path). Then use `Grep`/`Read` on the flat log file for details. |
37
+ | `debugger-evaluate` | Run a JS expression in the app runtime. |
38
+
39
+ ---
40
+
41
+ ## 3. Component Inspection
42
+
43
+ ### `debugger-component-tree` vs `debugger-inspect-element`
44
+
45
+ | | `debugger-component-tree` | `debugger-inspect-element` |
46
+ | -------- | ---------------------------------------------------------------------- | --------------------------------------------------------------- |
47
+ | Best for | Layout overview; finding tap targets; user-defined component hierarchy | Identifying a visible element and tracing it to its source file |
48
+ | Use when | "What's on screen and where?" | "What component is this and where is it defined?" |
49
+
50
+ Both can point to source files, but `inspect-element` is purpose-built for source tracing. `component-tree` is for orientation and tap-target discovery.
51
+
52
+ ### `includeSkipped` guidance
53
+
54
+ Applies to both `debugger-component-tree` and `debugger-inspect-element`. Set to `true` only when debugging filter behavior — e.g., an expected component is missing from output, or you need to inspect a very specific branch of the tree (not just an overview).
55
+
56
+ > **Warning:** Output can be very large. Always combine with `maxNodes` (component-tree) or `maxItems` (inspect-element) and increase it incrementally (e.g., start at 50, then grow). Do not use `includeSkipped` without a limit on large apps.
57
+
58
+ ---
59
+
60
+ ## 4. Golden Rules
61
+
62
+ 1. **`debugger-status` first when something fails** — it runs discovery, connection, and returns diagnostics.
63
+ 2. **"No CDP targets" → get the app to connect to Metro** — use `restart-app` on simulator, then retry `debugger-status`.
64
+ 3. **Never assume one failure is permanent** — follow recovery steps before asking the user. For starting Metro and full failure recovery, see `argent-react-native-app-workflow` and `references/failure-scenarios.md`.
65
+
66
+ ---
67
+
68
+ ## 5. Reading Console Logs (Log Registry)
69
+
70
+ Logs are written to a flat log file on disk. Use the **log-registry → grep** pattern instead of reading logs inline.
71
+
72
+ ### Workflow
73
+
74
+ 1. **Call `debugger-log-registry`** — returns: `file` (log path), `totalEntries`, `byLevel`, `clusters` (top message groups with counts and source file info)
75
+ 2. **Search the file** using `Grep` or `Read` with patterns from the response.
76
+
77
+ > **Large log files:** If `totalEntries` exceeds 10 000, delegate the grep exploration to an `Explore` subagent — pass it the file path, the entry format, and the patterns you need.
78
+
79
+ ### Flat log format
80
+
81
+ One entry per line — fields (whitespace-separated, `|` delimiter before message)
82
+
83
+ | Field | Example | Notes |
84
+ | ------------- | --------------------------- | --------------------------------------------------- |
85
+ | `[L:<id>]` | `[L:42]` | Unique grep anchor |
86
+ | `<timestamp>` | `2026-03-17T14:30:00.000Z` | ISO 8601 |
87
+ | `<LEVEL>` | `ERROR`, `WARN `, `LOG ` | Uppercase, padded to 5 chars |
88
+ | `<source>` | `src/api/user.ts:42` or `-` | Relative path from source map; `-` if unavailable |
89
+ | `<message>` | `Failed login attempt` | Full message; embedded newlines replaced with space |
90
+
91
+ Source attribution (file + line) is also available in `clusters` returned by `debugger-log-registry`.
92
+
93
+ Log files and messages can be large - **Always scope your search**, treat the file like a database, not a document.
94
+
95
+ When reading from the log file:
96
+
97
+ - Never `Read` the log file directly. Use `grep` or shell commands with limits using the above file format tips.
98
+ - Default to `-m 50` unless you need more.
99
+ - Use `tail -N` recent entries.
100
+ - `clusters[].message` gives you the exact text which you may look for
101
+
102
+ > **If the file is too large** Delegate to an `Explore` subagent with the file path, the format spec above, and the specific patterns you need.
103
+
104
+ ---
105
+
106
+ ## Quick Reference
107
+
108
+ | Action | Tool |
109
+ | ----------------------------- | ------------------------------------------------------------------- |
110
+ | Diagnose / check connection | `debugger-status` |
111
+ | Connect to Metro CDP | `debugger-connect` |
112
+ | Reload JS (already connected) | `debugger-reload-metro` |
113
+ | Relaunch app on simulator | `restart-app` |
114
+ | Inspect component at point | `debugger-inspect-element` |
115
+ | Full component tree | `debugger-component-tree` |
116
+ | Console log overview | `debugger-log-registry` (summary + log file path for `Grep`/`Read`) |
117
+ | Evaluate JS | `debugger-evaluate` |