Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .argus.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
],
"symlink": [],
"commands": [
"mise trust",
"mise install",
"pnpm install"
]
},
Expand Down
44 changes: 44 additions & 0 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ All commands accept `--session <name>` to scope to a named session and
| `scroll` | Scroll a direction or onto an element. |
| `scroll-until-visible` | Repeatedly scroll until the target element appears. |
| `swipe` | Swipe between two points (or in a cardinal direction). |
| `pinch` | Two-finger pinch. `--scale <n>` (zoom out <1, zoom in >1), `--center x,y`, `--angle <deg>`, `--duration <ms>`. |
| `rotate-gesture` | Two-finger rotate. `--degrees <n>`, `--center x,y`, `--duration <ms>`. |
| `gesture <json>` | Play an arbitrary multi-touch path. JSON shape: `[{"steps":[{"x":,"y":,"dt":}]}, ...]`. One path per finger; `dt` is delay since previous step (seconds). Pass `--file path.json` instead of inline JSON. |
| `clipboard read` | Print the iOS simulator clipboard. iOS only — Android has no portable userspace clipboard API. |
| `clipboard write <t>` | Set the iOS simulator clipboard. |
| `paste` | Type the clipboard contents into the focused field (iOS only). |

---

Expand All @@ -47,6 +53,7 @@ All commands accept `--session <name>` to scope to a named session and
| Command | What it does |
| ----------------- | ------------------------------------------------------------------------------------- |
| `inspect` | Dump the live UI hierarchy as JSON. `--dump` prints the raw driver output unmodified. |
| `inspect --at x,y`| Print the topmost view at a screen point. Add `--tappable` to filter to interactive elements. |
| `focused` | Print metadata of the focused element. `--poll` keeps printing on change. |
| `take-screenshot` | Save a PNG to `--output <path>` (or stdout if omitted). |
| `capture-ui` | Combined screenshot + hierarchy + a11y snapshot — designed to feed into Argus. |
Expand Down Expand Up @@ -99,6 +106,11 @@ Both accept the same disambiguators as `tap-on`: `--id`, `--text`,
| `run-flow` | Run a YAML flow file against the current session's device. |
| `run-flow-inline` | Run a YAML flow string passed on the command line (great for one-off agent calls). |
| `run-parallel` | Shard a directory of flow files round-robin across every booted device. |
| `run-sequence` | Run a batch of commands serially against one session, stopping on first failure. Reads `{"steps":[{"cmd":"tap-on","args":["Login"]}, ...]}` from `--file path.json` or stdin. |
| `flow record start` | Begin recording subsequent device-action commands into a YAML flow at `--out <path>` (or `~/.conductor/recordings/`). Any action you run while recording is appended automatically. |
| `flow record echo <text>` | Insert a `runScript` comment step into the active recording. |
| `flow record status` | Show the active recording path (if any). |
| `flow record finish` | Close the active recording and print the file path. |

See [Flows](/conductor/docs/flows) for the YAML format, env var
injection, and parallel execution semantics.
Expand All @@ -116,6 +128,38 @@ Once installed, the same commands above work on `web` "devices" — see

---

## Workspace

| Command | What it does |
| ----------------- | ---------------------------------------------------------------------------------- |
| `workspace info` | One-shot report of project type (RN / Expo / iOS / Android / Web / mixed), bundle ids, detected `ios/` and `android/` dirs, Metro port, and booted devices. Avoids the agent re-deriving these from `package.json` and `list-devices`. |

---

## Metro

For React Native projects.

| Command | What it does |
| --------------- | ---------------------------------------------------------------------------------------- |
| `metro stop` | Stop the Metro bundler process listening on `--port <n>` (default 8081). Uses `lsof` + `SIGTERM`, escalates to `SIGKILL` after 2s. |
| `metro reload` | Reload the JS bundle without restarting the native process. `Page.reload` over CDP, falls back to `POST /reload`. |

---

## Crashes

| Command | What it does |
| ------------------ | ---------------------------------------------------------------------------------------- |
| `crashes list` | List recent crash reports. iOS host-side `.ips`/`.crash` files from `~/Library/Logs/DiagnosticReports/`, plus Android `logcat -b crash` for the current device. `--app <bundleId>`, `--since <duration>` (e.g. `2h`, `30m`). |
| `crashes show <id>`| Print a specific iOS crash report by file name. |
| `crashes tail` | Stream new crash reports as they appear. iOS via `fs.watch` on the diagnostic reports directory; Android via `adb logcat -b crash`. |

Output schema (JSON): `{ id, timestamp, app, type, signal, threadName, topFrames[], sourceFile, platform }`.
The text parser is heuristic — most fields are best-effort across iOS versions; symbolicated frames may not appear without a matching `.dSYM`.

---

## Daemon

| Command | What it does |
Expand Down
76 changes: 76 additions & 0 deletions docs/experimental.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Experimental commands

Conductor ships a set of commands that depend on **React Native runtime internals**
(`__REACT_DEVTOOLS_GLOBAL_HOOK__`, fiber shape, `UIManager` / `nativeFabricUIManager`,
`renderer.rendererConfig`). They work — they're modelled directly on the patterns
used by tools like `react-devtools` — but RN reorganises these internals occasionally,
so the scripts may need maintenance per RN major version.

If you hit a breakage, the failure mode is usually a clear error (`"No React DevTools hook"`,
`"No fiber roots"`, `"rendererConfig.getInspectorDataForViewAtPoint unavailable"`) and the
underlying Metro / app is unaffected — you can fall back to native inspection.

All three groups below talk to **Metro's Chrome DevTools Protocol endpoint** (`/json` on
port 8081 by default). Pass `--port <n>` to point at a different bundler, `--target <n>`
to pick a specific debugger target when several are connected.

---

## RN debugger

| Command | What it does |
| -------------------------------- | ---------------------------------------------------------------------------------- |
| `debug status` | Show Metro target list, connection state, loaded scripts, enabled CDP domains. |
| `debug evaluate <expr>` | `Runtime.evaluate` in the app's JS context. Awaits promises. Reads Redux, calls app functions, inspects state. |
| `debug component-tree` | Walk the React fiber tree, batch-measure on-screen rects via `UIManager.measureInWindow` (Paper) or `nativeFabricUIManager.measure` (Fabric). Filters out wrapper noise. |
| `debug inspect-element <x,y>` | Use `renderer.rendererConfig.getInspectorDataForViewAtPoint` (React's own inspector) to find the component at a screen point. Walks UP via `.return` and resolves source via `_debugStack` / `_debugSource`. |
| `debug log-registry` | Summary of recent Metro console output — counts by level and clustering. |
| `debug reload` | `Page.reload` over CDP. Same as `metro reload`. |

**Caveats**

- Requires Hermes (`__REACT_DEVTOOLS_GLOBAL_HOOK__` is registered on Hermes startup).
- `debug component-tree` works on both Fabric and Paper, but the SKIP list of wrapper component names is hard-coded — new RN versions may surface new wrappers we don't filter.
- `debug inspect-element` requires `getInspectorDataForViewAtPoint` on the renderer; this exists on RN 0.70+. Older versions error out.
- Source frames come from `_debugStack` (RN ≥ 0.76) or `_debugSource` (`@babel/plugin-transform-react-jsx-source`). With neither, the frame is `null`.

---

## Network inspection

| Command | What it does |
| ----------------------------------------------- | ---------------------------------------------------------------------------------- |
| `network logs [--limit n]` | Install a `fetch`/`XHR` shim into the running app (idempotent — only once per JS context) and read the captured entries. Each entry: `{ id, kind, method, url, status, durationMs, error, start }`. |
| `network request <url> [--method --body --header k=v]` | Issue an HTTP request from the app's network context. Honours the app's cookies, headers, and TLS pinning. |

**Caveats**

- Shim only sees `fetch` and `XMLHttpRequest` — apps that use native networking modules directly (e.g. `okhttp` on Android via a TurboModule) bypass it.
- A `metro reload` or app reload clears the shim — call `network logs` once to reinstall.
- The shim's ring buffer caps at ~200 entries; tune by re-installing if needed.

---

## Profiling

| Command | What it does |
| ---------------------------------- | ---------------------------------------------------------------------------------- |
| `profile cpu --duration <s>` | Record a CPU trace. iOS: `xcrun xctrace record --template "Time Profiler"`. Android: `adb shell simpleperf record`. Writes to `--out <path>` or a `tmp/` file. |
| `profile memory --track <s>` | Poll memory at `--interval <ms>` (default 1000ms) for `track` seconds. Reports per-sample app + system memory; suitable for spotting leaks under repeated interactions. |
| `profile react start` | Install a React commit-profiler hook via `__REACT_DEVTOOLS_GLOBAL_HOOK__.onCommitFiberRoot`. Subsequent commits are collected into a ring buffer with per-component `actualDuration`. |
| `profile react stop [--top n]` | Stop the profiler, summarise the top N components by total render time across commits. |

**Caveats**

- `profile cpu` requires `xctrace` (Xcode) or `simpleperf` (Android NDK) on `PATH`. Argent's profiling tools also have a query layer over saved traces — Conductor only does record + summary today.
- `profile react` is Hermes-only and intercepts `onCommitFiberRoot` — interaction with other DevTools clients (the standalone React DevTools window, Flipper) is undefined; only run one profiler at a time.
- `profile memory` is a polling shim over `memory` — for finer detail use the underlying `conductor memory` directly.

---

## When experimental graduates

Each command above moves to the main [Command catalogue](/conductor/docs/commands)
once it survives a full RN minor-version cycle without script changes. Until then,
expect that an RN upgrade may briefly break one of these and a Conductor patch
release will follow.
6 changes: 6 additions & 0 deletions docs/marketing-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@
"file": "web.md",
"title": "Web testing",
"summary": "The same commands you use on iOS and Android, driving Playwright-managed Chromium, Firefox, or WebKit instead."
},
{
"slug": "experimental",
"file": "experimental.md",
"title": "Experimental",
"summary": "RN debugger, network inspection, and profiling. Powerful but depend on React Native runtime internals — expect occasional drift between RN versions."
}
]
},
Expand Down
Loading
Loading