Skip to content

feat: added io keys command for pressing keys with modifiers#264

Merged
gmegidish merged 3 commits into
mainfrom
feat/io-keys
Jun 11, 2026
Merged

feat: added io keys command for pressing keys with modifiers#264
gmegidish merged 3 commits into
mainfrom
feat/io-keys

Conversation

@gmegidish

Copy link
Copy Markdown
Member

No description provided.

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Walkthrough

This PR adds a complete key-combo pressing feature. Users can now press key combinations with modifiers (like cmd+a or ctrl+shift+z) via the new io keys CLI subcommand. The implementation parses human-readable key strings, normalizes modifier aliases, routes requests through a unified ControllableDevice interface, and delegates to platform-specific implementations: Android via ADB keycode commands, iOS and Simulator via WDA client RPC, and Remote via device RPC forwarding. The server registers a new device.io.keys JSON-RPC endpoint to support both HTTP and embedded client requests.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive No pull request description was provided by the author, making it impossible to assess relevance to the changeset. Add a pull request description explaining the purpose, implementation approach, and any relevant context for the 'io keys' command feature.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding an 'io keys' command that supports pressing keys with modifier combinations, which is the primary feature across all modified files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/io-keys

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
commands/keys.go (1)

52-58: ⚡ Quick win

Trim whitespace from modifier parts for better UX.

Users might naturally type combos with spaces (e.g., "cmd + a"), but the current implementation would fail with "unsupported modifier 'cmd '" because spaces are not trimmed before the alias lookup.

♻️ Proposed fix to trim spaces
 	modifiers := make([]string, 0, len(modifierParts))
 	for _, part := range modifierParts {
-		modifier, ok := modifierAliases[strings.ToLower(part)]
+		modifier, ok := modifierAliases[strings.ToLower(strings.TrimSpace(part))]
 		if !ok {
 			return wda.KeyCombo{}, fmt.Errorf("unsupported modifier '%s' in key combo '%s'", part, combo)
 		}
 		modifiers = append(modifiers, modifier)

Also trim the key itself:

 	return wda.KeyCombo{
-		Key:       strings.ToLower(key),
+		Key:       strings.ToLower(strings.TrimSpace(key)),
 		Modifiers: modifiers,
 	}, nil
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@commands/keys.go` around lines 52 - 58, The parsing of modifierParts fails
when users include spaces (e.g., "cmd + a"); update the loop that iterates
modifierParts to trim whitespace (use strings.TrimSpace) on each part before
doing the alias lookup against modifierAliases and before appending to
modifiers, and also trim the key token when building the resulting wda.KeyCombo
(the variables to change are modifierParts, modifier, modifierAliases,
modifiers, combo and the final key parsing that produces the key field of the
wda.KeyCombo).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@commands/keys.go`:
- Around line 52-58: The parser loop over modifierParts (using modifierAliases
and appending into modifiers to build a wda.KeyCombo) does not detect duplicate
modifiers; update the loop to track seen modifiers (e.g., a local
map[string]bool keyed by the resolved modifier value) and if a modifier is
encountered twice return an error (e.g., "duplicate modifier '%s' in key combo
'%s'") instead of appending a duplicate; ensure you reference the same resolved
modifier value (not the raw part) when checking/marking seen to prevent
duplicates like "cmd+cmd+a".

In `@devices/ios.go`:
- Around line 841-843: The RPC handler sends keys as []string but
IOSDevice.PressKeys currently forwards []wda.KeyCombo to d.wdaClient.PressKeys,
causing a JSON mismatch; change the contract by updating IOSDevice.PressKeys to
accept []string (or add a new overload that does) and convert each string into a
wda.KeyCombo before calling d.wdaClient.PressKeys, so the RPC payload (keys
[]string) is translated into the wda.KeyCombo slice expected by the WDA client
(referencing IOSDevice.PressKeys and d.wdaClient.PressKeys and the RPC handler
that expects keys []string).

In `@devices/wda/press-keys.go`:
- Around line 9-16: WdaClient.PressKeys is sending the wrong RPC payload shape
("keys": []KeyCombo objects) but device.io.keys expects "keys": []string; update
PressKeys to map the incoming []KeyCombo (type KeyCombo) to the string form
(e.g., modifiers + "+" + key or the same conversion used in devices/remote.go)
and pass that []string to CallRPC("device.io.keys", params) so the params become
{"keys": []string}; change only the conversion inside PressKeys (referencing
WdaClient.PressKeys, KeyCombo, and CallRPC) before calling the RPC.

---

Nitpick comments:
In `@commands/keys.go`:
- Around line 52-58: The parsing of modifierParts fails when users include
spaces (e.g., "cmd + a"); update the loop that iterates modifierParts to trim
whitespace (use strings.TrimSpace) on each part before doing the alias lookup
against modifierAliases and before appending to modifiers, and also trim the key
token when building the resulting wda.KeyCombo (the variables to change are
modifierParts, modifier, modifierAliases, modifiers, combo and the final key
parsing that produces the key field of the wda.KeyCombo).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: efde09d2-0dea-4a54-86d7-280cec077f0b

📥 Commits

Reviewing files that changed from the base of the PR and between 991ba12 and 6db7553.

📒 Files selected for processing (11)
  • cli/io.go
  • commands/keys.go
  • commands/keys_test.go
  • devices/android.go
  • devices/common.go
  • devices/ios.go
  • devices/remote.go
  • devices/simulator.go
  • devices/wda/press-keys.go
  • server/dispatch.go
  • server/server.go

Comment thread commands/keys.go
Comment thread devices/ios.go Outdated
Comment thread devices/wda/press-keys.go

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/openrpc.json`:
- Around line 287-297: The "keys" parameter schema currently allows an empty
array even though the description requires "one or more key combinations";
update the "keys" property's JSON schema (the object with "name": "keys") to
include "minItems": 1 under its "schema" object so the OpenRPC contract enforces
at least one item is provided.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ef5684e6-2689-44f9-805c-afbde90b7508

📥 Commits

Reviewing files that changed from the base of the PR and between 69d9547 and d6c8d44.

📒 Files selected for processing (1)
  • docs/openrpc.json

Comment thread docs/openrpc.json
Comment on lines +287 to +297
{
"name": "keys",
"description": "Key combinations to press, in order (e.g. [\"cmd+a\", \"backspace\"])",
"required": true,
"schema": {
"type": "array",
"items": {
"type": "string"
}
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add minItems: 1 constraint to match the description.

The description at line 277 states "Presses one or more key combinations", but the schema allows an empty keys array. Add a minItems constraint to enforce the documented contract and prevent no-op calls.

📋 Proposed fix
         {
           "name": "keys",
           "description": "Key combinations to press, in order (e.g. [\"cmd+a\", \"backspace\"])",
           "required": true,
           "schema": {
             "type": "array",
+            "minItems": 1,
             "items": {
               "type": "string"
             }
           }
         }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{
"name": "keys",
"description": "Key combinations to press, in order (e.g. [\"cmd+a\", \"backspace\"])",
"required": true,
"schema": {
"type": "array",
"items": {
"type": "string"
}
}
}
{
"name": "keys",
"description": "Key combinations to press, in order (e.g. [\"cmd+a\", \"backspace\"])",
"required": true,
"schema": {
"type": "array",
"minItems": 1,
"items": {
"type": "string"
}
}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/openrpc.json` around lines 287 - 297, The "keys" parameter schema
currently allows an empty array even though the description requires "one or
more key combinations"; update the "keys" property's JSON schema (the object
with "name": "keys") to include "minItems": 1 under its "schema" object so the
OpenRPC contract enforces at least one item is provided.

@gmegidish gmegidish merged commit 4adb95d into main Jun 11, 2026
19 checks passed
@gmegidish gmegidish deleted the feat/io-keys branch June 11, 2026 11:20
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.

1 participant