Skip to content

fix(cli): name --udid when a device identity is passed to --device - #2065

Open
NicolasBataille wants to merge 1 commit into
callstack:mainfrom
NicolasBataille:fix/2064-udid-discoverability
Open

fix(cli): name --udid when a device identity is passed to --device#2065
NicolasBataille wants to merge 1 commit into
callstack:mainfrom
NicolasBataille:fix/2064-udid-discoverability

Conversation

@NicolasBataille

Copy link
Copy Markdown

Closes #2064

Summary

--udid is the only selector that pins one simulator when several share a name, and it was
effectively undiscoverable: help commands listed no device selector at all, and passing a UDID to
--device answered with a literal lookup failure that neither named --udid nor hinted that a
UDID-taking flag exists.

Before:

$ agent-device snapshot --platform ios --device 204BFFD9-9644-4830-B2C1-1B946597A07C
Error (DEVICE_NOT_FOUND): No device named 204BFFD9-9644-4830-B2C1-1B946597A07C
Hint: Verify the target device is booted/connected and selectors match.

After:

Error (DEVICE_NOT_FOUND): No device named 204BFFD9-9644-4830-B2C1-1B946597A07C
Hint: 204BFFD9-9644-4830-B2C1-1B946597A07C is the id of "iPhone 17", not its name.
      Did you mean --udid 204BFFD9-9644-4830-B2C1-1B946597A07C?

Two changes:

  1. resolveDeviceByName answers the flag mistake. When the --device value is the id of a
    listed candidate it names that device and the flag the value belongs to — --udid for Apple,
    --serial for serial-addressable platforms. When it merely has UDID shape (8-4-4-4-12 hex) but
    matches no listed device, it names --udid anyway, because a shut-down simulator is still a
    wrong-flag answer. An ordinary unknown name keeps the generic hint untouched.

    This mirrors, rather than invents, the answer assertSelectorFlagMatchesPlatform already gives
    a few lines above for a mismatched identity flag (--udid on --platform android).

  2. help commands renders a Device Selection section for the selectors every command
    accepts: --platform, --device, --udid, --serial, --session.

    Device Selection (accepted by every device command):
      --platform apple|android|...  Platform to target (`apple` aliases the Apple automation backend)
      --device <name>               Device name to target (a UDID belongs in --udid, a serial in --serial)
      --udid <udid>                 Apple device or simulator UDID; the only selector that pins one
                                    device when several share a --device name
      --serial <serial>             Android device or Vega VVD serial
      --session <name>              Named session
    

    Deliberately a new help section rather than a GLOBAL_FLAG_KEYS addition: those keys mark a
    flag as supported by * in buildOptionSpecs and move it from supportedFlags to globalFlags
    in explain. These selectors reach device resolution, not the CLI envelope; they stay in
    COMMON_COMMAND_SUPPORTED_FLAG_KEYS, so the option schema, explain output and MCP surface are
    byte-identical.

--udid and --device also get sharper one-line descriptions, which is where an agent reading the
new section actually learns the distinction.

Tests

  • packages/kernel/src/device-selector-flags.test.ts — the existing home for selector-flag
    mistakes — gains four cases: a UDID and a serial passed to --device (each naming the right
    flag and the device it identifies), a UDID-shaped value no listed device carries, and an ordinary
    unknown name keeping the generic hint. All four were observed red against the pre-fix code.
  • src/cli-schema/cli-help-topics.test.ts gains a Device Selection section assertion. The
    existing "only global flags in its global flags section" test slices from Global Flags: to
    Configuration:; the new section sits above Global Flags:, so that slice is unaffected.

pnpm check:quick, pnpm test:unit (8092 passed), pnpm check:command-docs and
pnpm check:agent-guidance are green.

Live check

Run from the built clone against a local simulator set with two simulators named "iPhone 17":

  • --device <udid> → the new identity hint naming --udid and "iPhone 17".
  • --device 11111111-2222-3333-4444-555555555555 (no such device) → the shape hint naming --udid.
  • --device "iPhone 99" → unchanged generic hint.
  • help commands renders the new section.

What a maintainer might push back on

  • The UDID regex. It is deliberately the fallback: the primary signal is exact id-equality
    against the candidate set, which needs no shape knowledge and gets --serial right for Android.
    The regex only covers a device the current inventory does not list. Dropping it would still fix
    the reported case; keeping it covers the shut-down-simulator variant the issue's workaround
    section implies.
  • --device accepting a UDID outright was the issue's other suggested fix. Not taken: it would
    make --device a two-meaning flag and quietly duplicate --udid/--serial's platform routing,
    including the assertSelectorFlagMatchesPlatform cross-check. Naming the right flag is smaller
    and keeps one meaning per selector.
  • Section placement and title. Device Selection (accepted by every device command) is long;
    a shorter title works if it does not read as "global", which is exactly the distinction that
    keeps the option schema unchanged.
  • Selector set. --target is also a common selector and was left out to match the issue's list.
    Adding it is a one-line change to DEVICE_SELECTION_FLAG_KEYS.

`--device <udid>` failed with "No device named <udid>" and the generic
booted/connected hint, and `help commands` listed no device selector at all, so
`--udid` — the only flag that pins one simulator among several sharing a name —
was reachable only from `help device`'s usage line.

Two changes, both discoverability:

- `resolveDeviceByName` now answers the flag mistake instead of the literal
  lookup. When the `--device` value is the id of a listed device it names that
  device and the flag the value belongs to (`--udid` for Apple, `--serial` for
  serial-addressable platforms); when it merely has UDID shape it names `--udid`.
  An ordinary unknown name keeps the generic hint. This mirrors the answer
  `assertSelectorFlagMatchesPlatform` already gives for a mismatched identity flag.
- `help commands` renders a `Device Selection` section for the selectors every
  command accepts (`--platform`, `--device`, `--udid`, `--serial`, `--session`).
  They stay in `COMMON_COMMAND_SUPPORTED_FLAG_KEYS`, not `GLOBAL_FLAG_KEYS`, so
  the option schema and `explain` output are unchanged.

Closes callstack#2064
@thymikee

Copy link
Copy Markdown
Member

[P1] Remove the partial UDID-shape heuristic and keep the hint grounded in observed device identity. The exact candidates.find(device.id === deviceName) path already fixes #2064 for every discovered Apple/serial device and reuses the kernel’s platform facts. DEVICE_UDID_SHAPE then reconstructs Apple identity syntax with a UUID-only regex: it excludes the modern physical-device UDIDs already used in this repo (00008150-001849640CF8401C), can misclassify an arbitrary UUID-shaped device name, and needs a long comment to justify a shutdown-device case that current inventory may still list. Either delete this fallback (the smaller fix the PR body already identifies) or move complete Apple identity recognition behind an Apple-owned typed interface with tests for simulator and physical formats. Keep the exact-candidate --udid/--serial hint and the help section. Exact-head CI is also still absent, so do not apply ready-for-human yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

--device <udid> fails DEVICE_NOT_FOUND without hinting at --udid, which is absent from Global Flags

2 participants