agent-mobile 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +226 -0
  3. package/dist/commands/close.d.ts +3 -0
  4. package/dist/commands/close.d.ts.map +1 -0
  5. package/dist/commands/close.js +16 -0
  6. package/dist/commands/close.js.map +1 -0
  7. package/dist/commands/doctor.d.ts +3 -0
  8. package/dist/commands/doctor.d.ts.map +1 -0
  9. package/dist/commands/doctor.js +33 -0
  10. package/dist/commands/doctor.js.map +1 -0
  11. package/dist/commands/fill.d.ts +3 -0
  12. package/dist/commands/fill.d.ts.map +1 -0
  13. package/dist/commands/fill.js +40 -0
  14. package/dist/commands/fill.js.map +1 -0
  15. package/dist/commands/open.d.ts +3 -0
  16. package/dist/commands/open.d.ts.map +1 -0
  17. package/dist/commands/open.js +23 -0
  18. package/dist/commands/open.js.map +1 -0
  19. package/dist/commands/screenshot.d.ts +3 -0
  20. package/dist/commands/screenshot.d.ts.map +1 -0
  21. package/dist/commands/screenshot.js +24 -0
  22. package/dist/commands/screenshot.js.map +1 -0
  23. package/dist/commands/snapshot.d.ts +3 -0
  24. package/dist/commands/snapshot.d.ts.map +1 -0
  25. package/dist/commands/snapshot.js +27 -0
  26. package/dist/commands/snapshot.js.map +1 -0
  27. package/dist/commands/swipe.d.ts +3 -0
  28. package/dist/commands/swipe.d.ts.map +1 -0
  29. package/dist/commands/swipe.js +61 -0
  30. package/dist/commands/swipe.js.map +1 -0
  31. package/dist/commands/tap.d.ts +3 -0
  32. package/dist/commands/tap.d.ts.map +1 -0
  33. package/dist/commands/tap.js +50 -0
  34. package/dist/commands/tap.js.map +1 -0
  35. package/dist/index.d.ts +3 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +32 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/lib/appium.d.ts +10 -0
  40. package/dist/lib/appium.d.ts.map +1 -0
  41. package/dist/lib/appium.js +127 -0
  42. package/dist/lib/appium.js.map +1 -0
  43. package/dist/lib/server.d.ts +26 -0
  44. package/dist/lib/server.d.ts.map +1 -0
  45. package/dist/lib/server.js +165 -0
  46. package/dist/lib/server.js.map +1 -0
  47. package/dist/lib/session.d.ts +19 -0
  48. package/dist/lib/session.d.ts.map +1 -0
  49. package/dist/lib/session.js +39 -0
  50. package/dist/lib/session.js.map +1 -0
  51. package/dist/lib/snapshot.d.ts +11 -0
  52. package/dist/lib/snapshot.d.ts.map +1 -0
  53. package/dist/lib/snapshot.js +136 -0
  54. package/dist/lib/snapshot.js.map +1 -0
  55. package/package.json +54 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 agent-mobile contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,226 @@
1
+ # agent-mobile
2
+
3
+ Mobile automation CLI for AI agents - control iOS simulators with simple commands.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -g agent-mobile
9
+ ```
10
+
11
+ That's it. Appium and drivers are bundled - no separate setup required.
12
+
13
+ ## Prerequisites
14
+
15
+ - **macOS** with Xcode installed
16
+ - **iOS Simulator** booted (the tool will tell you if one isn't running)
17
+
18
+ ### First Time Setup
19
+
20
+ ```bash
21
+ # 1. Boot a simulator
22
+ xcrun simctl boot "iPhone 16 Pro"
23
+ open -a Simulator
24
+
25
+ # 2. Check everything is ready
26
+ agent-mobile doctor
27
+ ```
28
+
29
+ ## Quick Start
30
+
31
+ ```bash
32
+ # Launch an app
33
+ agent-mobile open com.apple.Preferences
34
+
35
+ # Get interactive elements with refs
36
+ agent-mobile snapshot
37
+
38
+ # Tap an element by ref
39
+ agent-mobile tap @e1
40
+ ```
41
+
42
+ ## Commands
43
+
44
+ ### open
45
+
46
+ Launch an iOS app by bundle ID.
47
+
48
+ ```bash
49
+ agent-mobile open <bundleId> [options]
50
+
51
+ # Options:
52
+ # -d, --device <name> Device name (default: "iPhone Simulator")
53
+
54
+ # Examples:
55
+ agent-mobile open com.apple.Preferences
56
+ agent-mobile open com.apple.calculator -d "iPhone 15 Pro"
57
+ ```
58
+
59
+ ### snapshot
60
+
61
+ Get UI elements with refs for interaction.
62
+
63
+ ```bash
64
+ agent-mobile snapshot [options]
65
+
66
+ # Options:
67
+ # -a, --all Show all elements, not just interactive
68
+
69
+ # Output example:
70
+ # @e1 button "General"
71
+ # @e2 button "Display & Brightness"
72
+ # @e3 switch "Airplane Mode" [off]
73
+ ```
74
+
75
+ ### tap
76
+
77
+ Tap an element by ref or coordinates.
78
+
79
+ ```bash
80
+ agent-mobile tap <target>
81
+
82
+ # Examples:
83
+ agent-mobile tap @e1 # Tap by ref
84
+ agent-mobile tap 100,200 # Tap by coordinates
85
+ ```
86
+
87
+ ### fill
88
+
89
+ Fill text into an input field.
90
+
91
+ ```bash
92
+ agent-mobile fill <ref> <text> [options]
93
+
94
+ # Options:
95
+ # --no-clear Do not clear existing text
96
+
97
+ # Examples:
98
+ agent-mobile fill @e1 "Hello World"
99
+ agent-mobile fill @e2 "append this" --no-clear
100
+ ```
101
+
102
+ ### swipe
103
+
104
+ Swipe in a direction.
105
+
106
+ ```bash
107
+ agent-mobile swipe <direction> [options]
108
+
109
+ # Directions: up, down, left, right
110
+ # Options:
111
+ # --distance <percent> Swipe distance (1-100, default: 50)
112
+
113
+ # Examples:
114
+ agent-mobile swipe down
115
+ agent-mobile swipe up --distance 75
116
+ ```
117
+
118
+ ### screenshot
119
+
120
+ Take a screenshot of the current screen.
121
+
122
+ ```bash
123
+ agent-mobile screenshot [filename]
124
+
125
+ # Default filename: screenshot.png
126
+
127
+ # Examples:
128
+ agent-mobile screenshot
129
+ agent-mobile screenshot my-screen.png
130
+ agent-mobile screenshot /tmp/debug.png
131
+ ```
132
+
133
+ ### close
134
+
135
+ Close the current Appium session.
136
+
137
+ ```bash
138
+ agent-mobile close
139
+ ```
140
+
141
+ ### doctor
142
+
143
+ Check system requirements and diagnose issues.
144
+
145
+ ```bash
146
+ agent-mobile doctor
147
+
148
+ # Output:
149
+ # ✓ Xcode: Xcode 16.0
150
+ # ✓ Simulator: iPhone 16 Pro (booted)
151
+ # ✓ Appium: Running on port 4723
152
+ # ✓ XCUITest Driver: Installed
153
+ ```
154
+
155
+ ## For Agents
156
+
157
+ **Copy this section to your AI assistant (Claude, Cursor, GPT, etc.):**
158
+
159
+ ---
160
+
161
+ To automate iOS simulators, use `agent-mobile`. Install with:
162
+
163
+ ```bash
164
+ npm install -g agent-mobile
165
+ ```
166
+
167
+ Basic workflow:
168
+ ```bash
169
+ agent-mobile open com.apple.Preferences # Launch app
170
+ agent-mobile snapshot # Get elements with refs
171
+ agent-mobile tap @e1 # Tap by ref
172
+ agent-mobile fill @e2 "text" # Fill input
173
+ agent-mobile swipe down # Swipe
174
+ agent-mobile screenshot /tmp/s.png # Screenshot
175
+ agent-mobile close # End session
176
+ ```
177
+
178
+ Prerequisites: macOS with Xcode, iOS Simulator booted (`xcrun simctl boot "iPhone 16 Pro"`).
179
+
180
+ Run `agent-mobile doctor` to check setup.
181
+
182
+ ---
183
+
184
+ ## AI Integration
185
+
186
+ agent-mobile is designed for AI coding assistants. The refs pattern (`@e1`, `@e2`, etc.) provides stable element identifiers that AI tools can easily parse and use.
187
+
188
+ ### Claude Code
189
+
190
+ When using Claude Code in a project with agent-mobile, the `.claude/skills/agent-mobile/SKILL.md` file provides auto-discovery. Claude will know how to:
191
+
192
+ - Launch apps and navigate UI
193
+ - Read element refs from snapshots
194
+ - Interact with elements by ref
195
+ - Take screenshots for visual debugging
196
+
197
+ ### Example AI Workflow
198
+
199
+ ```
200
+ User: "Open Settings and turn on Airplane Mode"
201
+
202
+ AI runs:
203
+ 1. agent-mobile open com.apple.Preferences
204
+ 2. agent-mobile snapshot
205
+ → sees: @e3 switch "Airplane Mode" [off]
206
+ 3. agent-mobile tap @e3
207
+ 4. agent-mobile snapshot
208
+ → confirms: @e3 switch "Airplane Mode" [on]
209
+ ```
210
+
211
+ ## Troubleshooting
212
+
213
+ Run `agent-mobile doctor` to diagnose issues.
214
+
215
+ **No simulator booted:**
216
+ ```bash
217
+ xcrun simctl boot "iPhone 16 Pro"
218
+ open -a Simulator
219
+ ```
220
+
221
+ **Xcode not installed:**
222
+ Install Xcode from the App Store and open it once to accept the license.
223
+
224
+ ## License
225
+
226
+ MIT
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const closeCommand: Command;
3
+ //# sourceMappingURL=close.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"close.d.ts","sourceRoot":"","sources":["../../src/commands/close.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,eAAO,MAAM,YAAY,SAWrB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { Command } from 'commander';
2
+ import { closeSession } from '../lib/appium.js';
3
+ export const closeCommand = new Command('close')
4
+ .description('Close the current session\n\nExample:\n agent-mobile close')
5
+ .action(async () => {
6
+ try {
7
+ await closeSession();
8
+ console.log('Session closed');
9
+ }
10
+ catch (error) {
11
+ const err = error;
12
+ console.error(`Error: ${err.message}`);
13
+ process.exit(1);
14
+ }
15
+ });
16
+ //# sourceMappingURL=close.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"close.js","sourceRoot":"","sources":["../../src/commands/close.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;KAC7C,WAAW,CAAC,6DAA6D,CAAC;KAC1E,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,IAAI,CAAC;QACH,MAAM,YAAY,EAAE,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,KAAc,CAAC;QAC3B,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const doctorCommand: Command;
3
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,eAAO,MAAM,aAAa,SAiCtB,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { Command } from 'commander';
2
+ import { runDoctor } from '../lib/server.js';
3
+ export const doctorCommand = new Command('doctor')
4
+ .description('Check system requirements and diagnose issues\n\nExample:\n agent-mobile doctor')
5
+ .action(async () => {
6
+ console.log('Checking system requirements...\n');
7
+ const result = await runDoctor();
8
+ const check = (ok) => ok ? '\x1b[32m✓\x1b[0m' : '\x1b[31m✗\x1b[0m';
9
+ console.log(`${check(result.xcode.ok)} Xcode: ${result.xcode.message}`);
10
+ console.log(`${check(result.simulator.ok)} Simulator: ${result.simulator.message}`);
11
+ console.log(`${check(result.appium.ok)} Appium: ${result.appium.message}`);
12
+ console.log(`${check(result.xcuitest.ok)} XCUITest Driver: ${result.xcuitest.message}`);
13
+ const allOk = result.xcode.ok && result.simulator.ok;
14
+ console.log('');
15
+ if (allOk) {
16
+ console.log('\x1b[32mAll checks passed!\x1b[0m Ready to use agent-mobile.');
17
+ }
18
+ else {
19
+ console.log('\x1b[33mSome issues found.\x1b[0m Fix the items marked with ✗ above.');
20
+ if (!result.xcode.ok) {
21
+ console.log('\nTo install Xcode:');
22
+ console.log(' 1. Open App Store');
23
+ console.log(' 2. Search for "Xcode"');
24
+ console.log(' 3. Install and open once to accept license');
25
+ }
26
+ if (!result.simulator.ok && result.xcode.ok) {
27
+ console.log('\nTo boot a simulator:');
28
+ console.log(' xcrun simctl boot "iPhone 16 Pro"');
29
+ console.log(' open -a Simulator');
30
+ }
31
+ }
32
+ });
33
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CAAC,kFAAkF,CAAC;KAC/F,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;IAEjD,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;IAEjC,MAAM,KAAK,GAAG,CAAC,EAAW,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,kBAAkB,CAAC;IAE5E,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,WAAW,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACxE,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,eAAe,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC;IACpF,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3E,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,qBAAqB,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IAExF,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;IAErD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;IAC9E,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,sEAAsE,CAAC,CAAC;QACpF,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;YACvC,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;QAC9D,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;YAC5C,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;YACtC,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;YACnD,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const fillCommand: Command;
3
+ //# sourceMappingURL=fill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fill.d.ts","sourceRoot":"","sources":["../../src/commands/fill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,eAAO,MAAM,WAAW,SAwCpB,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { Command } from 'commander';
2
+ import { getDriver } from '../lib/appium.js';
3
+ import { getRef } from '../lib/session.js';
4
+ export const fillCommand = new Command('fill')
5
+ .description('Fill text into input by ref\n\nExamples:\n agent-mobile fill @e1 "Hello World"\n agent-mobile fill @e2 "append" --no-clear')
6
+ .argument('<ref>', 'Element ref (e.g., @e1)')
7
+ .argument('<text>', 'Text to enter')
8
+ .option('--no-clear', 'Do not clear existing text')
9
+ .action(async (ref, text, options) => {
10
+ try {
11
+ const driver = await getDriver();
12
+ if (!ref.startsWith('@')) {
13
+ console.error('Error: Ref must start with @ (e.g., @e1)');
14
+ process.exit(1);
15
+ }
16
+ const refData = getRef(ref);
17
+ if (!refData) {
18
+ console.error(`Error: Ref ${ref} not found. Run: agent-mobile snapshot`);
19
+ process.exit(1);
20
+ }
21
+ // Check if it's an input type
22
+ const inputTypes = ['textField', 'secureTextField', 'textView', 'searchField'];
23
+ if (!inputTypes.includes(refData.type)) {
24
+ console.error(`Error: ${ref} is not a text input (type: ${refData.type})`);
25
+ process.exit(1);
26
+ }
27
+ const element = await driver.$(refData.xpath);
28
+ if (options.clear) {
29
+ await element.clearValue();
30
+ }
31
+ await element.setValue(text);
32
+ console.log(`Filled ${ref} with "${text}"`);
33
+ }
34
+ catch (error) {
35
+ const err = error;
36
+ console.error(`Error: ${err.message}`);
37
+ process.exit(1);
38
+ }
39
+ });
40
+ //# sourceMappingURL=fill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fill.js","sourceRoot":"","sources":["../../src/commands/fill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;KAC3C,WAAW,CAAC,8HAA8H,CAAC;KAC3I,QAAQ,CAAC,OAAO,EAAE,yBAAyB,CAAC;KAC5C,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;KACnC,MAAM,CAAC,YAAY,EAAE,4BAA4B,CAAC;KAClD,MAAM,CAAC,KAAK,EAAE,GAAW,EAAE,IAAY,EAAE,OAA2B,EAAE,EAAE;IACvE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;QAEjC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;YAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,cAAc,GAAG,wCAAwC,CAAC,CAAC;YACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,8BAA8B;QAC9B,MAAM,UAAU,GAAG,CAAC,WAAW,EAAE,iBAAiB,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;QAC/E,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACvC,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,+BAA+B,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC;YAC3E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAE9C,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;QAC7B,CAAC;QAED,MAAM,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,UAAU,GAAG,UAAU,IAAI,GAAG,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,KAAc,CAAC;QAC3B,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const openCommand: Command;
3
+ //# sourceMappingURL=open.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open.d.ts","sourceRoot":"","sources":["../../src/commands/open.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,eAAO,MAAM,WAAW,SAkBpB,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { Command } from 'commander';
2
+ import { createSession } from '../lib/appium.js';
3
+ export const openCommand = new Command('open')
4
+ .description('Launch an iOS app by bundle ID\n\nExamples:\n agent-mobile open com.apple.Preferences\n agent-mobile open com.apple.calculator -d "iPhone 15 Pro"')
5
+ .argument('<bundleId>', 'App bundle ID (e.g., com.apple.calculator)')
6
+ .option('-d, --device <name>', 'Device name', 'iPhone Simulator')
7
+ .action(async (bundleId, options) => {
8
+ try {
9
+ const driver = await createSession({
10
+ bundleId,
11
+ deviceName: options.device,
12
+ });
13
+ console.log(`Session started: ${driver.sessionId}`);
14
+ console.log(`App: ${bundleId}`);
15
+ console.log(`Device: ${options.device}`);
16
+ }
17
+ catch (error) {
18
+ const err = error;
19
+ console.error(`Error: ${err.message}`);
20
+ process.exit(1);
21
+ }
22
+ });
23
+ //# sourceMappingURL=open.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open.js","sourceRoot":"","sources":["../../src/commands/open.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;KAC3C,WAAW,CAAC,qJAAqJ,CAAC;KAClK,QAAQ,CAAC,YAAY,EAAE,4CAA4C,CAAC;KACpE,MAAM,CAAC,qBAAqB,EAAE,aAAa,EAAE,kBAAkB,CAAC;KAChE,MAAM,CAAC,KAAK,EAAE,QAAgB,EAAE,OAA2B,EAAE,EAAE;IAC9D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC;YACjC,QAAQ;YACR,UAAU,EAAE,OAAO,CAAC,MAAM;SAC3B,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,oBAAoB,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,QAAQ,QAAQ,EAAE,CAAC,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,WAAW,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,KAAc,CAAC;QAC3B,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const screenshotCommand: Command;
3
+ //# sourceMappingURL=screenshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../src/commands/screenshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,iBAAiB,SAmB1B,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { Command } from 'commander';
2
+ import { getDriver } from '../lib/appium.js';
3
+ import * as fs from 'fs';
4
+ import * as path from 'path';
5
+ export const screenshotCommand = new Command('screenshot')
6
+ .description('Take a screenshot\n\nExamples:\n agent-mobile screenshot\n agent-mobile screenshot /tmp/debug.png')
7
+ .argument('[filename]', 'Output filename', 'screenshot.png')
8
+ .action(async (filename) => {
9
+ try {
10
+ const driver = await getDriver();
11
+ const screenshot = await driver.takeScreenshot();
12
+ const filepath = path.isAbsolute(filename)
13
+ ? filename
14
+ : path.resolve(process.cwd(), filename);
15
+ fs.writeFileSync(filepath, screenshot, 'base64');
16
+ console.log(`Screenshot saved: ${filepath}`);
17
+ }
18
+ catch (error) {
19
+ const err = error;
20
+ console.error(`Error: ${err.message}`);
21
+ process.exit(1);
22
+ }
23
+ });
24
+ //# sourceMappingURL=screenshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screenshot.js","sourceRoot":"","sources":["../../src/commands/screenshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,OAAO,CAAC,YAAY,CAAC;KACvD,WAAW,CAAC,qGAAqG,CAAC;KAClH,QAAQ,CAAC,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,CAAC;KAC3D,MAAM,CAAC,KAAK,EAAE,QAAgB,EAAE,EAAE;IACjC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;QACjC,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,cAAc,EAAE,CAAC;QAEjD,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YACxC,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;QAE1C,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,qBAAqB,QAAQ,EAAE,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,KAAc,CAAC;QAC3B,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const snapshotCommand: Command;
3
+ //# sourceMappingURL=snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/commands/snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,eAAO,MAAM,eAAe,SAqBxB,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { Command } from 'commander';
2
+ import { getDriver } from '../lib/appium.js';
3
+ import { takeSnapshot } from '../lib/snapshot.js';
4
+ export const snapshotCommand = new Command('snapshot')
5
+ .description('Get UI elements with refs\n\nExamples:\n agent-mobile snapshot\n agent-mobile snapshot -a')
6
+ .option('-a, --all', 'Show all elements, not just interactive')
7
+ .action(async (options) => {
8
+ try {
9
+ const driver = await getDriver();
10
+ const result = await takeSnapshot(driver, {
11
+ interactive: !options.all,
12
+ all: options.all,
13
+ });
14
+ if (result.count === 0) {
15
+ console.log('No elements found');
16
+ }
17
+ else {
18
+ console.log(result.text);
19
+ }
20
+ }
21
+ catch (error) {
22
+ const err = error;
23
+ console.error(`Error: ${err.message}`);
24
+ process.exit(1);
25
+ }
26
+ });
27
+ //# sourceMappingURL=snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/commands/snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC;KACnD,WAAW,CAAC,6FAA6F,CAAC;KAC1G,MAAM,CAAC,WAAW,EAAE,yCAAyC,CAAC;KAC9D,MAAM,CAAC,KAAK,EAAE,OAA0B,EAAE,EAAE;IAC3C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,MAAM,EAAE;YACxC,WAAW,EAAE,CAAC,OAAO,CAAC,GAAG;YACzB,GAAG,EAAE,OAAO,CAAC,GAAG;SACjB,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;QACnC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,KAAc,CAAC;QAC3B,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const swipeCommand: Command;
3
+ //# sourceMappingURL=swipe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swipe.d.ts","sourceRoot":"","sources":["../../src/commands/swipe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,YAAY,SA+DrB,CAAC"}
@@ -0,0 +1,61 @@
1
+ import { Command } from 'commander';
2
+ import { getDriver } from '../lib/appium.js';
3
+ export const swipeCommand = new Command('swipe')
4
+ .description('Swipe in a direction\n\nExamples:\n agent-mobile swipe down\n agent-mobile swipe up --distance 75')
5
+ .argument('<direction>', 'Direction: up, down, left, right')
6
+ .option('--distance <percent>', 'Swipe distance as percentage of screen', '50')
7
+ .action(async (direction, options) => {
8
+ try {
9
+ const validDirections = ['up', 'down', 'left', 'right'];
10
+ if (!validDirections.includes(direction)) {
11
+ console.error('Error: Invalid direction. Use: up, down, left, right');
12
+ process.exit(1);
13
+ }
14
+ const distance = parseInt(options.distance, 10);
15
+ if (isNaN(distance) || distance < 1 || distance > 100) {
16
+ console.error('Error: Distance must be a number between 1 and 100');
17
+ process.exit(1);
18
+ }
19
+ const driver = await getDriver();
20
+ const { width, height } = await driver.getWindowSize();
21
+ const centerX = Math.floor(width / 2);
22
+ const centerY = Math.floor(height / 2);
23
+ const distanceFraction = distance / 100;
24
+ let startX = centerX;
25
+ let startY = centerY;
26
+ let endX = centerX;
27
+ let endY = centerY;
28
+ switch (direction) {
29
+ case 'up':
30
+ startY = Math.floor(height * 0.7);
31
+ endY = Math.floor(height * (0.7 - distanceFraction * 0.5));
32
+ break;
33
+ case 'down':
34
+ startY = Math.floor(height * 0.3);
35
+ endY = Math.floor(height * (0.3 + distanceFraction * 0.5));
36
+ break;
37
+ case 'left':
38
+ startX = Math.floor(width * 0.8);
39
+ endX = Math.floor(width * (0.8 - distanceFraction * 0.6));
40
+ break;
41
+ case 'right':
42
+ startX = Math.floor(width * 0.2);
43
+ endX = Math.floor(width * (0.2 + distanceFraction * 0.6));
44
+ break;
45
+ }
46
+ await driver
47
+ .action('pointer', { parameters: { pointerType: 'touch' } })
48
+ .move({ x: startX, y: startY })
49
+ .down()
50
+ .move({ x: endX, y: endY, duration: 300 })
51
+ .up()
52
+ .perform();
53
+ console.log(`Swiped ${direction}`);
54
+ }
55
+ catch (error) {
56
+ const err = error;
57
+ console.error(`Error: ${err.message}`);
58
+ process.exit(1);
59
+ }
60
+ });
61
+ //# sourceMappingURL=swipe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swipe.js","sourceRoot":"","sources":["../../src/commands/swipe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const tapCommand: Command;
3
+ //# sourceMappingURL=tap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tap.d.ts","sourceRoot":"","sources":["../../src/commands/tap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,eAAO,MAAM,UAAU,SAgDnB,CAAC"}
@@ -0,0 +1,50 @@
1
+ import { Command } from 'commander';
2
+ import { getDriver } from '../lib/appium.js';
3
+ import { getRef } from '../lib/session.js';
4
+ export const tapCommand = new Command('tap')
5
+ .description('Tap element by ref (@e1) or coordinates (x,y)\n\nExamples:\n agent-mobile tap @e1\n agent-mobile tap 100,200')
6
+ .argument('<target>', 'Element ref or coordinates')
7
+ .action(async (target) => {
8
+ try {
9
+ const driver = await getDriver();
10
+ if (target.startsWith('@')) {
11
+ // Tap by ref
12
+ const ref = getRef(target);
13
+ if (!ref) {
14
+ console.error(`Error: Ref ${target} not found. Run: agent-mobile snapshot`);
15
+ process.exit(1);
16
+ }
17
+ const element = await driver.$(ref.xpath);
18
+ await element.click();
19
+ const label = ref.label ? `: "${ref.label}"` : '';
20
+ console.log(`Tapped ${target} (${ref.type}${label})`);
21
+ }
22
+ else if (target.includes(',')) {
23
+ // Tap by coordinates
24
+ const [xStr, yStr] = target.split(',');
25
+ const x = parseInt(xStr, 10);
26
+ const y = parseInt(yStr, 10);
27
+ if (isNaN(x) || isNaN(y)) {
28
+ console.error('Error: Invalid coordinates. Use format: x,y (e.g., 100,200)');
29
+ process.exit(1);
30
+ }
31
+ await driver
32
+ .action('pointer', { parameters: { pointerType: 'touch' } })
33
+ .move({ x, y })
34
+ .down()
35
+ .up()
36
+ .perform();
37
+ console.log(`Tapped (${x}, ${y})`);
38
+ }
39
+ else {
40
+ console.error('Error: Invalid target. Use ref (@e1) or coordinates (x,y)');
41
+ process.exit(1);
42
+ }
43
+ }
44
+ catch (error) {
45
+ const err = error;
46
+ console.error(`Error: ${err.message}`);
47
+ process.exit(1);
48
+ }
49
+ });
50
+ //# sourceMappingURL=tap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tap.js","sourceRoot":"","sources":["../../src/commands/tap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,OAAO,CAAC,KAAK,CAAC;KACzC,WAAW,CAAC,gHAAgH,CAAC;KAC7H,QAAQ,CAAC,UAAU,EAAE,4BAA4B,CAAC;KAClD,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,EAAE;IAC/B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;QAEjC,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3B,aAAa;YACb,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;YAC3B,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,OAAO,CAAC,KAAK,CAAC,cAAc,MAAM,wCAAwC,CAAC,CAAC;gBAC5E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAC1C,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;YAEtB,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAClD,OAAO,CAAC,GAAG,CAAC,UAAU,MAAM,KAAK,GAAG,CAAC,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC;QACxD,CAAC;aAAM,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAChC,qBAAqB;YACrB,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACvC,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAC7B,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAE7B,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzB,OAAO,CAAC,KAAK,CAAC,6DAA6D,CAAC,CAAC;gBAC7E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,MAAM,MAAM;iBACT,MAAM,CAAC,SAAS,EAAE,EAAE,UAAU,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;iBAC3D,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;iBACd,IAAI,EAAE;iBACN,EAAE,EAAE;iBACJ,OAAO,EAAE,CAAC;YAEb,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAC;YAC3E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,KAAc,CAAC;QAC3B,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}