Files
Ignacy Łątka c58777fd57 fix(tool-server): route a device-less refusal through the same paths a bad arg takes
`argent run` answers a missing required flag locally: exit 2, the tool's
help block, and one object on stderr under `--json`. Relaxing `udid` moved
that answer to the server, which replied with prose in `error` alone -
`describeServerValidationFailure` recognises a rejected invocation
structurally, found no issue list, and the call fell through to the generic
runtime path (exit 1, nothing on the `--json` channel). The refusal now
sends the three fields a schema rejection does: prose in `message`, the
list in `issues`, that list as JSON in `error` for a CLI released before
`issues` existed.

The nested `list-devices` emits its own invoke/complete pair and was
minting a fresh unattributed id, so every device-less call added an
anonymous `list-devices` to telemetry - the very metric that would show
whether this feature removed those calls. Dispatch it through
`invokeSubTool` with a recorder bound to the request, the mechanism
run-sequence and flow-execute already use. `invokeSubTool`'s context
parameter narrows to the two fields it reads, so the HTTP layer can hand
over attribution before it owns a `ToolContext`.

Also:
- `flow-add-step` still needs `udid` in nested args by design - a recorded
  step pins its own device - so say that in the `args` description
- `scripts/e2e-full`'s README promised missing-required coverage for every
  tool, which no longer holds for the ten whose only required field was
  `udid`
2026-08-31 23:20:57 +02:00
..