This PR makes Linux work.
# AI Summary
<details>
Brings Argent up on Linux as a host: per-platform npm bundle, renderer
selection that actually works on hybrid-GPU / Wayland / containerized
Linux, hot-boot guarding that survives the SwiftShader composite gap, a
real Linux preflight, and a Wayland-headless E2E job in CI. macOS stays
on
the path it was on before (no `-gpu` flag was passed; AVD config
decided);
nothing about the iOS Simulator behavior changes.
The diff is broader than "ship the Linux artifact" — calling it out
below
because several pieces affect macOS too and reviewers should be primed
for
that rather than skim past expecting "just packaging."
### What's actually in here
**npm packaging (the original framing — still load-bearing)**
| File | Change |
|---|---|
| `packages/argent/scripts/argent-simulator-server.cjs` (new) | Node
dispatcher exposed as the `argent-simulator-server` bin entry. Joins
`process.platform` into the bin path and execs. Forwards
SIGTERM/SIGINT/SIGHUP parent→child so non-TTY supervisors can't orphan
the binary. |
| `packages/argent/scripts/bundle-tools.cjs` | Copies per-platform
binaries from `packages/native-devtools-ios/bin/<platform>/` into
`packages/argent/bin/<platform>/`. darwin required, linux best-effort. |
| `packages/argent/package.json` | `bin.argent-simulator-server` points
at the dispatcher. |
| `packages/native-devtools-ios/src/index.ts` | Resolver joins
`process.platform` into the simulator-server bin path. iOS-only dylibs
and `ax-service` throw `"requires a macOS host"` on Linux callers so
they get the root cause, not "file not found". |
| `scripts/download-simulator-server.sh` | Downloads
`simulator-server-argent-{macos,linux}` into platform-keyed subdirs.
**Purges each platform dir before its download attempt** so a failed
download can't leave stale binaries in place from a prior run. |
| `scripts/dev.cjs` | Local dev copies the current host's binary into
`bin/<process.platform>/` to match the resolver layout. |
| `.github/workflows/publish{,-next}.yml` | Replaces single `test -x
darwin/...` with a per-platform inventory loop. darwin always required;
Linux gated by `ARGENT_REQUIRE_LINUX_BINARY=1` (flip once radon#118
lands). |
**Linux runtime — emulator boot path**
| File | Change |
|---|---|
| `packages/tool-server/src/tools/devices/boot-device.ts` |
`selectGpuMode()`: Linux defaults to `-gpu swiftshader` (`auto` lands on
lavapipe with ~10× cold-boot slowdown; `-gpu host` produces silent
black-window failures on Optimus / NVIDIA+libglvnd / Wayland-on-hybrid /
containers). macOS keeps `auto` (ANGLE→Metal).
`ARGENT_EMULATOR_GPU_MODE` overrides, **validated against `emulator
-help-gpu`'s whitelist** so a typoed value fails fast instead of burning
the whole boot budget. `ARGENT_EMULATOR_NO_WINDOW=1` appends
`-no-window` for headless contexts (CI / containers / Wayland sessions
with no Qt wayland plugin). |
| `packages/tool-server/src/tools/devices/boot-device.ts` (cont.) |
**Cold-boot:** `awaitFirstRealFrame` polls SwiftShader's lockscreen
composite (PNG byte-count via `screencap -p`); blocks `booted:true`
until a real frame shows up. Without this, callers chaining `boot-device
→ screenshot` get an all-black PNG because `sys.boot_completed=1` fires
5–60 s before the first composite. |
| `packages/tool-server/src/tools/devices/boot-device.ts` (cont.) |
**Hot-boot:** `assertScreencapAlive` polls within an 8 s budget instead
of single-probing. The earlier single-probe caught the sticky-blank
state but also killed the emulator on every transient snapshot-restore
blank, forcing "every boot is cold" cycles. Sticky vs transient is
discriminated by whether the budget exhausts. |
| `packages/tool-server/src/utils/linux-preflight.ts` (new) |
`linuxBootDiagnostics()` checks `/dev/kvm` access. `diagnoseAvdSizing()`
warns when a target AVD's `hw.ramSize`/`vm.heapSize` is below the floor
an aggressive RN/Expo app needs (2G/228M avdmanager defaults wedge under
load). |
| `packages/tool-server/src/utils/android-binary.ts` |
`defaultAndroidRoots()` probes typical SDK install locations when
`ANDROID_HOME`/`ANDROID_SDK_ROOT` are unset — **cross-platform**,
benefits macOS launches from GUI-launched MCP hosts (Claude Code Desktop
etc.) where shell rc env doesn't propagate. |
**Cross-platform fixes that landed alongside**
| File | Change |
|---|---|
| `packages/argent-installer/src/utils.ts` | `getLatestVersion()` now
redirects `npm view`'s stderr to `ignore` so `EBADDEVENGINES` warnings
from a consumer project's `package.json` (e.g. Bluesky's pnpm pin) don't
leak to the user's terminal. **Cross-platform fix**, not Linux-specific.
|
**CI**
| File | Change |
|---|---|
| `.github/workflows/wayland-e2e.yml` (new) | Boots an AVD through the
tool-server under headless Weston; asserts `hw.gpu.mode = swiftshader`
and that screenshots + gesture-tap work without a display. Currently
runs on `pull_request` for the affected paths + `workflow_dispatch`.
Pinned to `radon-daily` for the simulator-server until radon#118 ships a
Linux asset to `radon-main`. |
### Tests added in this PR
- `packages/argent/test/dispatcher.test.ts` — e2e against tmpdir-staged
dispatcher + fake `<platform>/simulator-server`: missing-binary error
path, exit-code passthrough, argv passthrough, SIGTERM forwarding.
- `packages/tool-server/test/native-devtools-ios-resolver.test.ts` —
`requireDarwin` gates for dylibs and `ax-service` on Linux, per-platform
`simulator-server` path resolution, missing-binary error,
`ARGENT_NATIVE_DEVTOOLS_DIR` override.
- `packages/tool-server/test/linux-preflight.test.ts` — KVM diagnostic
shape + `diagnoseAvdSizing` (ram low, heap low, both, neither, missing
keys).
- `packages/tool-server/test/boot-device-hotboot.test.ts` — extended
with `it.each([linux→swiftshader, darwin→auto])` so a single CI runner
exercises both GPU branches (was runner-platform-dependent, regressions
could pass on both runners individually). New cases for the wedged-frame
fallback (under fake timers because the polling budget is short but
real-time enough to exceed vitest's 5 s default), the GPU-mode whitelist
rejection, and the cold-boot composite-wait timeout.
- `packages/tool-server/test/android-binary.test.ts` — extended for
`defaultAndroidRoots` probe ordering and HOME pinning.
### Verification
- `tsc --build`: clean apart from pre-existing
`@argent/native-devtools-android` import errors unrelated to this
branch.
- `vitest run` in `packages/tool-server` and `packages/argent`: 689 + 11
= 700 tests passing; the 4 pre-existing test-file load failures
(native-devtools-android missing) reproduce on `main` and are out of
scope.
- `npm pack -w @swmansion/argent`: produces `swmansion-argent-0.8.0.tgz`
with the per-platform layout.
- Wayland-e2e: triggered on this branch — link will be in a PR comment
once the run completes.
- Manually verified end-to-end on a Wayland-on-hybrid-GPU developer
laptop: AVD boots through the tool-server with `-gpu swiftshader`,
screencap returns real frames, gesture tools work.
### Dependencies / what still gates this
- **radon#118** must land before the Linux artifact ships through the
default channel. The download script tolerates the asset being absent
today (best-effort), so this PR is technically safe to merge before —
Linux installs just won't get a working `simulator-server` until the
upstream artifact is published. Once it lands:
- Drop the `radon-daily` arg in `.github/workflows/wayland-e2e.yml`.
- Flip `ARGENT_REQUIRE_LINUX_BINARY` to `1` in both publish workflows.
- **wayland-e2e is not a required status check** today (no branch
protection on `main` requires it). Worth turning on before merging
anything else that touches the Linux boot path.
### Related
- radon#118 — produces the `simulator-server-argent-linux` artifact this
PR consumes.
- argent-private#11 — cross-builds the iOS Simulator dylibs on Linux.
Strictly orthogonal: those dylibs are macOS-runtime-only regardless of
where they're built, and this PR keeps them under `dylibs/` with a clean
error path on Linux callers.
</details>
Fixes#246
## Summary
- New top-level CLI commands `argent enable <flag>` / `argent disable
<flag>` / `argent flags`.
- Storage is a small JSON file at `~/.argent/flags.json` by default;
`--scope project` writes to `<project-root>/.argent/flags.json` instead.
- `enable` writes `true`. `disable` removes the entry at the chosen
scope (and deletes the file + empty `.argent/` when it becomes the last
flag).
- `isFlagEnabled` walks project → global, so a project entry shadows the
same key in the global file. To opt a single project out of a
globally-enabled flag, hand-edit `<project>/.argent/flags.json` to
`{"flags":{"name":false}}` — there is no CLI for an explicit override.
- The dispatcher routes the new commands to `@argent/cli` exports;
bundling needs no config changes (only `node:fs|path|os`).
## Behaviour
- `argent enable foo` → writes `{ "flags": { "foo": true } }` to global
file.
- `argent disable foo` → removes `foo` from the global file (clean round
trip with `enable`).
- `argent enable foo --scope project` → writes to
`<project-root>/.argent/flags.json`.
- `argent flags` → lists effective state with the winning scope;
`--json` for scripting.
- Project root is the nearest ancestor with `.argent`, `.git`, or
`package.json` — falls back to cwd when none found.
- POSIX `--` separator: `argent enable -- weird-name` is supported.
- Help (`--help` / `-h`), invalid `--scope`, invalid flag names, missing
arg, unknown flags all produce a clear stderr error and `exit 2`.
- Flag-name validation: `/^[a-zA-Z][a-zA-Z0-9._-]*$/`.
- Writes are atomic (tmp file + rename) so concurrent invocations cannot
tear the JSON.
## Reader API
`isFlagEnabled(name)` is exported from `@argent/cli` for future
consumers; it walks project → global and returns `false` when unset.
## Files
- `packages/argent-cli/src/flags.ts` (new) — storage + CLI handlers
- `packages/argent-cli/src/index.ts` — re-exports `enable` / `disable` /
`flags` / `isFlagEnabled` / `FlagScope`
- `packages/argent-cli/test/flags.test.ts` (new) — 41 tests
- `packages/argent-cli/vitest.config.ts` (new)
- `packages/argent-cli/package.json` — description bump
- `packages/argent/src/cli.ts` — dispatcher routes + help text
- `README.md`, `CONTRIBUTING.md` — command tables
## Test plan
- [x] `npm test --workspaces --if-present` → 1085 tests pass (41 in
`@argent/cli`).
- [x] `npm run typecheck:tests --workspaces --if-present` → clean.
- [x] `npm run build` (root `tsc --build`) → clean.
- [x] `npm run build -w @swmansion/argent` (dispatcher + esbuild
bundles) → clean.
- [x] `npx prettier --check .` → clean.
- [x] End-to-end against the built dispatcher in a tmpdir:
- `argent enable my-feature-flag` (global) writes to
`~/.argent/flags.json`.
- `argent enable proj-only --scope project` writes to
`<proj>/.argent/flags.json`.
- `argent disable my-feature-flag` removes the entry; round trip leaves
a clean tree (file + empty `.argent/` removed when no other state lives
there).
- `argent disable foo` preserves sibling flags in the same file.
- `argent flags` lists each flag with the winning scope.
- `argent enable --` errors cleanly; `argent enable -- name-after`
accepts the literal.
- `argent enable foo --scope project` walks up to `.git` /
`package.json` / `.argent`; stray editor configs (`.claude`, `.cursor`,
…) do NOT count as project roots.
- Error paths (`--scope bogus`, no name, `1bad-name`) exit `2` with a
clear message.
We've had multiple instances of iOS-biased references in our skills.
This PR makes these references platform-agnostic.
<details>
## Summary
After Android emulator support landed (#148), several skill docs and
tool descriptions still treated iOS as the only/default platform. A QA
reported that asking the agent to "test … using argent" makes it spin up
an iOS simulator even when an Android emulator is already running.
These are **minimal de-biasing edits** — mostly one-word `simulator` →
`device` swaps. Android is **not** promoted above iOS; the incidental
iOS bias is just removed where it was unnecessary. Genuinely iOS-only
tools (`paste`, `native-*`, `native-profiler-*`) are left untouched
since the capability gate already rejects them on Android.
## Changes (14 files, +43/-29)
- **`argent.md` rule**: one-line `PLATFORM DETECTION` note (call
`list-devices` first, don't default to iOS); `simulator actions` →
`device actions`; mention `adb` next to `xcrun` in the escape-hatch
bullet. Routing order unchanged (iOS still listed first).
- **Skill docs**: `native iOS app navigation` → `app navigation`;
`simulator` → `device` where the action is platform-neutral; added the
missing `argent-android-emulator-setup` row to the RN-workflow Related
Skills table; `argent-ios-simulator-setup` description scoped to iOS.
- **`flow-run` / `flow-start-recording`**: `simulator interactions` →
`device interactions`.
- **`network-logs` / `network-request`**: `device_id` description `iOS
Simulator UDID` → `Device UDID`.
- **`list-devices`**: merged result now sorts by readiness so a booted
Android emulator is not buried beneath idle iOS simulators (the only
logic change).
## Test plan
- [x] `npx tsc --build` clean
- [x] `@argent/tool-server` 478 tests pass; `@argent/mcp` 51;
`@argent/installer` 231; `@argent/registry` 57
- [x] `prettier --check` clean
- [ ] Sanity-check that an agent with only an Android emulator booted no
longer reaches for an iOS simulator
</details>
* feat: first implementation integration of ax-service for enhanced accessibility support
* feat: enhance ax-service with automation enablement and daemon management
* feat: export ensureAutomationEnabled function for improved accessibility automation in simulator server
* feat: add new build scripts for native development and update binary files
* feat: enhance describe tool to support native-devtools fallback and introduce DescribeResult interface
* chore: bump version to 0.4.1
* chore: bump argent-private to main; list ax-service in LICENSE
- Point packages/argent-private at current main and set submodule branch.
- Declare packages/native-devtools-ios/bin/ax-service as proprietary alongside simulator-server and dylibs.
Made-with: Cursor
* docs: document ax-service as proprietary across LICENSE and README
- Extend root README and CONTRIBUTING requirements (mcp README syncs from root at build).
- List bin/ax-service in @swmansion/argent and native-devtools-ios LICENSE.
- Assert ax-service is present and executable in publish workflow.
Made-with: Cursor
---------
Co-authored-by: Filip131311 <Filip.kaminski@swmansion.com>
* chore: update README to improve branding and layout
* chore: update README to include responsive banner images and fix minor text typo
* chore: update README to enhance banner image responsiveness and adjust layout
* feat: adjust banner image display
* feat: merge changes
* fix: update README with absolute image URLs and correct text typo; add new banner images
* feat: update README and MCP documentation with new capabilities and installation instructions; add banner and placeholder images.
* chore: remove outdated badge section from README files in root and MCP packages
* chore: add horizontal rule to README files in root and MCP packages for improved visual separation
* chore: update README files in root and MCP packages to include detailed information about Software Mansion and its services
* chore: update logo links in README files for root and MCP packages to reflect new branding
* chore: update banner image to align with new branding
* chore: update installation command in README to reflect correct usage
* chore: replace placeholder image in README files with a GIF for improved visual appeal
* chore: update placeholder GIF to enhance visual consistency across assets
* chore: adjust image width in README files for consistent presentation
* chore: reposition placeholder GIF in README files for improved layout consistency
* chore: update installation command in README files to ensure consistency across documentation
* chore: update README files to use absolute image URLs and synchronize content between root and MCP README
* chore: remove MCP README.md file and update .gitignore to track README.md
* chore: update README.md for clarity and consistency in naming conventions
* docs: update installation guide to streamline setup process and add local tarball installation instructions
* docs: remove INSTALL.md and RELEASING.md, update CONTRIBUTING.md to streamline release process, and adjust README.md to reflect changes
* chore: remove unused agentic files
* chore: remove deprecated configuration and script files, add new setup-in-workspace script for argent installation
* feat: add first implememntation of environment subagent
* chore: remove the irrelavnt skill from main project config
* feat: add rules support and enhance postinstall script for Argent tools (#23)
* feat: add first implememntation of environment subagent
* feat: enhance argent.md with environment inspection subagent details and workspace information retrieval guidelines
* feat: introduce argent.md with comprehensive guidelines for iOS simulator interactions and React Native workflows
* fix: fix postinstall script
* fix: fix Install Argent launch.json job
* feat: add environment inspector design document and research notes on MCP error signaling
* chore: update .gitignore to include MCP agents and rules directories
* fix: update `argent.md` rule with alwaysApply: true for cursor compatibility
* chore: remove mcp/rules from index
* feat: add basic npx flow
* feat: cicd for releasing the package as nmp through github
* fix: update package name references from @software-mansion-labs to @software-mansion in documentation and configuration files
* refactor: simplify postinstall script for @software-mansion/argent and update configuration instructions