@houwert/conductor 0.12.3 → 0.13.1
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.
- package/README.md +3 -28
- package/dist/commands/foreground-app.js +1 -0
- package/dist/commands/install.js +1 -139
- package/dist/commands/logs.js +81 -85
- package/dist/commands/memory.js +10 -8
- package/dist/daemon/client.js +2 -9
- package/dist/daemon/log-collector.js +91 -198
- package/dist/daemon/server.js +1 -11
- package/dist/drivers/log-sources/daemon.js +2 -9
- package/dist/drivers/log-sources/metro-discovery.js +208 -0
- package/dist/index.js +1 -21
- package/package.json +3 -6
- package/.claude-plugin/plugin.json +0 -9
- package/dist/commands/cheat-sheet.js +0 -109
- package/dist/postinstall.js +0 -12
- package/skills/conductor/SKILL.md +0 -825
- package/skills/conductor/references/flow-syntax.md +0 -182
- package/skills/skills.yaml +0 -8
package/dist/index.js
CHANGED
|
@@ -25,7 +25,6 @@ const run_flow_js_1 = require("./commands/run-flow.js");
|
|
|
25
25
|
const run_flow_inline_js_1 = require("./commands/run-flow-inline.js");
|
|
26
26
|
const press_key_js_1 = require("./commands/press-key.js");
|
|
27
27
|
const session_js_1 = require("./commands/session.js");
|
|
28
|
-
const cheat_sheet_js_1 = require("./commands/cheat-sheet.js");
|
|
29
28
|
const daemon_js_1 = require("./commands/daemon.js");
|
|
30
29
|
const install_js_1 = require("./commands/install.js");
|
|
31
30
|
const device_pool_js_1 = require("./commands/device-pool.js");
|
|
@@ -87,9 +86,6 @@ const COMMAND_HELP = {
|
|
|
87
86
|
'run-flow': run_flow_js_1.HELP,
|
|
88
87
|
'run-flow-inline': run_flow_inline_js_1.HELP,
|
|
89
88
|
session: session_js_1.HELP,
|
|
90
|
-
'cheat-sheet': cheat_sheet_js_1.HELP,
|
|
91
|
-
'install-plugin': install_js_1.HELP_INSTALL_PLUGIN,
|
|
92
|
-
'install-skills': install_js_1.HELP_INSTALL_SKILLS,
|
|
93
89
|
'install-web': install_js_1.HELP_INSTALL_WEB,
|
|
94
90
|
'daemon-start': daemon_js_1.HELP_DAEMON_START,
|
|
95
91
|
'daemon-stop': daemon_js_1.HELP_DAEMON_STOP,
|
|
@@ -163,7 +159,6 @@ async function main() {
|
|
|
163
159
|
'from',
|
|
164
160
|
'to',
|
|
165
161
|
'source',
|
|
166
|
-
'metro-port',
|
|
167
162
|
'level',
|
|
168
163
|
],
|
|
169
164
|
alias: { h: 'help', v: 'verbose', V: 'version' },
|
|
@@ -195,15 +190,12 @@ async function main() {
|
|
|
195
190
|
'start-device',
|
|
196
191
|
'stop-device',
|
|
197
192
|
'delete-device',
|
|
198
|
-
'cheat-sheet',
|
|
199
|
-
'install-plugin',
|
|
200
|
-
'install-skills',
|
|
201
193
|
'install-web',
|
|
202
194
|
'copy-app',
|
|
203
195
|
'device-pool',
|
|
204
196
|
'run-parallel',
|
|
205
197
|
// `logs --list` and `logs --source metro` only query Metro on localhost — no device needed
|
|
206
|
-
|
|
198
|
+
// `logs` always needs a device session — Metro discovery is device-scoped.
|
|
207
199
|
// `daemon-stop --all` stops every daemon — no device needed
|
|
208
200
|
...(command === 'daemon-stop' && argv['all'] ? ['daemon-stop'] : []),
|
|
209
201
|
]);
|
|
@@ -476,9 +468,6 @@ async function main() {
|
|
|
476
468
|
exitCode = await (0, logs_js_1.logs)(opts, sessionName, {
|
|
477
469
|
source: argv['source'],
|
|
478
470
|
level: argv['level'],
|
|
479
|
-
metro: argv['metro'] || argv['metro-port'] !== undefined,
|
|
480
|
-
metroPort: argv['metro-port'] !== undefined ? Number(argv['metro-port']) : undefined,
|
|
481
|
-
target: argv['target'] !== undefined ? Number(argv['target']) : undefined,
|
|
482
471
|
list: argv['list'],
|
|
483
472
|
recent: argv['recent'] !== undefined ? Number(argv['recent']) : undefined,
|
|
484
473
|
duration: argv['duration'] !== undefined ? Number(argv['duration']) : undefined,
|
|
@@ -505,15 +494,6 @@ async function main() {
|
|
|
505
494
|
case 'session':
|
|
506
495
|
exitCode = await (0, session_js_1.sessionCmd)(argv['clear'], argv['list'], opts, sessionName);
|
|
507
496
|
break;
|
|
508
|
-
case 'cheat-sheet':
|
|
509
|
-
exitCode = await (0, cheat_sheet_js_1.cheatSheet)();
|
|
510
|
-
break;
|
|
511
|
-
case 'install-plugin':
|
|
512
|
-
exitCode = await (0, install_js_1.installPluginCli)(opts, argv['check']);
|
|
513
|
-
break;
|
|
514
|
-
case 'install-skills':
|
|
515
|
-
exitCode = await (0, install_js_1.installSkillsCli)(opts, argv['check']);
|
|
516
|
-
break;
|
|
517
497
|
case 'install-web':
|
|
518
498
|
exitCode = await (0, install_js_1.installWebCli)(opts, argv['check'], rest[0]);
|
|
519
499
|
break;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@houwert/conductor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.1",
|
|
4
4
|
"description": "CLI tool for mobile app interactions — optimized for AI agents",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -17,17 +17,14 @@
|
|
|
17
17
|
"main": "./dist/index.js",
|
|
18
18
|
"files": [
|
|
19
19
|
"dist/",
|
|
20
|
-
"
|
|
21
|
-
"proto/",
|
|
22
|
-
".claude-plugin/"
|
|
20
|
+
"proto/"
|
|
23
21
|
],
|
|
24
22
|
"scripts": {
|
|
25
23
|
"build": "tsc",
|
|
26
24
|
"dev": "tsc --watch",
|
|
27
25
|
"test": "tsc -p tests/tsconfig.json && node dist-tests/tests/all-tests.js",
|
|
28
26
|
"lint": "eslint src && prettier --check src",
|
|
29
|
-
"lint:fix": "eslint src --fix && prettier --write src"
|
|
30
|
-
"postinstall": "node dist/postinstall.js"
|
|
27
|
+
"lint:fix": "eslint src --fix && prettier --write src"
|
|
31
28
|
},
|
|
32
29
|
"packageManager": "pnpm@9.0.0",
|
|
33
30
|
"dependencies": {
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.HELP = void 0;
|
|
7
|
-
exports.cheatSheet = cheatSheet;
|
|
8
|
-
exports.HELP = ` cheat-sheet Print command reference`;
|
|
9
|
-
const promises_1 = __importDefault(require("fs/promises"));
|
|
10
|
-
const path_1 = __importDefault(require("path"));
|
|
11
|
-
async function cheatSheet() {
|
|
12
|
-
// Try to read SKILL.md from the package root
|
|
13
|
-
const skillPath = path_1.default.join(__dirname, '../../skills/conductor/SKILL.md');
|
|
14
|
-
try {
|
|
15
|
-
const content = await promises_1.default.readFile(skillPath, 'utf-8');
|
|
16
|
-
console.log(content);
|
|
17
|
-
}
|
|
18
|
-
catch {
|
|
19
|
-
// Fallback: print inline reference
|
|
20
|
-
console.log(INLINE_CHEAT_SHEET);
|
|
21
|
-
}
|
|
22
|
-
return 0;
|
|
23
|
-
}
|
|
24
|
-
const INLINE_CHEAT_SHEET = `
|
|
25
|
-
conductor — Command Reference
|
|
26
|
-
================================
|
|
27
|
-
|
|
28
|
-
DEVICE MANAGEMENT
|
|
29
|
-
list-devices List connected devices/simulators
|
|
30
|
-
foreground-app Print bundle ID / package of the foreground app
|
|
31
|
-
list-apps List installed app IDs / package names
|
|
32
|
-
session Show current session (appId, deviceId)
|
|
33
|
-
session --clear Clear session state
|
|
34
|
-
session --list List all device sessions
|
|
35
|
-
|
|
36
|
-
APP CONTROL
|
|
37
|
-
download-app <appId> [--output <path>] Download installed app binary from device
|
|
38
|
-
install-app <path> Install .app / .ipa / .apk onto device
|
|
39
|
-
launch-app <appId> [--device <id>] Launch app and save to session
|
|
40
|
-
--clear-state Wipe app data/state before launching
|
|
41
|
-
--clear-keychain Wipe keychain before launching
|
|
42
|
-
--argument key=value Set launch argument (repeatable)
|
|
43
|
-
stop-app [<appId>] Stop app (uses session appId if omitted)
|
|
44
|
-
clear-state [<appId>] Clear app data/state (uses session appId if omitted)
|
|
45
|
-
uninstall-app <appId> Uninstall app from device
|
|
46
|
-
|
|
47
|
-
INTERACTIONS
|
|
48
|
-
tap-on <element> Tap element by text
|
|
49
|
-
--id <id> Match by accessibility ID instead of text
|
|
50
|
-
--index <n> Pick the nth match (0-based)
|
|
51
|
-
--long-press Hold instead of tap
|
|
52
|
-
--double-tap Double-tap the element
|
|
53
|
-
input-text <text> Type text into focused field
|
|
54
|
-
back Press back button (Android only)
|
|
55
|
-
press-key <key> Press a key (Enter, Backspace, Home, ...)
|
|
56
|
-
scroll [--direction down|up|left|right] Scroll (default: down)
|
|
57
|
-
swipe --direction <UP|DOWN|LEFT|RIGHT> Directional swipe
|
|
58
|
-
--start <x,y> Start coordinate (0–1 normalised or absolute px)
|
|
59
|
-
--end <x,y> End coordinate (same)
|
|
60
|
-
--duration <ms> Swipe duration (default: 500)
|
|
61
|
-
|
|
62
|
-
ASSERTIONS
|
|
63
|
-
assert-visible <element> Assert element is visible
|
|
64
|
-
--id <id> Match by accessibility ID instead of text
|
|
65
|
-
--timeout <ms> Max wait time (default: 17000)
|
|
66
|
-
--optional Succeed even if element is not found
|
|
67
|
-
|
|
68
|
-
SCREENSHOTS & INSPECTION
|
|
69
|
-
take-screenshot [--output <path>] Take screenshot (default: ./screenshot-<ts>.png)
|
|
70
|
-
inspect [--dump] Print UI hierarchy (--dump: a11y-enriched JSON)
|
|
71
|
-
capture-ui [--output <path>] Screenshot + hierarchy + a11y snapshot bundle (Argus)
|
|
72
|
-
|
|
73
|
-
FLOW EXECUTION
|
|
74
|
-
run-flow <file> [--device <id>] Run a Maestro YAML flow file
|
|
75
|
-
run-flow-inline <yaml> Run inline YAML commands
|
|
76
|
-
|
|
77
|
-
DAEMON (optional — keeps driver alive between commands)
|
|
78
|
-
daemon-start [--device <id>] Start background daemon
|
|
79
|
-
daemon-stop [--device <id>] [--all] Stop daemon (--all stops every daemon)
|
|
80
|
-
daemon-status [--device <id>] Show daemon status
|
|
81
|
-
|
|
82
|
-
MULTI-AGENT / PARALLEL
|
|
83
|
-
device-pool --list List devices and pool status
|
|
84
|
-
device-pool --acquire Claim a free device (prints device ID)
|
|
85
|
-
device-pool --release <id> Release a device back to the pool
|
|
86
|
-
run-parallel --flows-dir <path> Run flows in parallel across all devices
|
|
87
|
-
|
|
88
|
-
MISC
|
|
89
|
-
install-plugin Register/update the global Claude Code plugin
|
|
90
|
-
install-skills Install skill files into .claude/skills/
|
|
91
|
-
install-web [browser] Install Playwright browser for web automation
|
|
92
|
-
cheat-sheet Print this reference
|
|
93
|
-
|
|
94
|
-
GLOBAL FLAGS
|
|
95
|
-
--device <id> Target device (auto-detected if omitted)
|
|
96
|
-
--json Machine-readable JSON output
|
|
97
|
-
--verbose, -v Log daemon calls, fallbacks, raw output
|
|
98
|
-
--help, -h Show help
|
|
99
|
-
|
|
100
|
-
EXAMPLES
|
|
101
|
-
conductor launch-app com.example.app
|
|
102
|
-
conductor tap-on "Sign In"
|
|
103
|
-
conductor tap-on --id "btn_login"
|
|
104
|
-
conductor input-text "hello@example.com"
|
|
105
|
-
conductor swipe --start 0.5,0.8 --end 0.5,0.2
|
|
106
|
-
conductor assert-visible "Dashboard" --timeout 30000
|
|
107
|
-
conductor take-screenshot --output /tmp/screen.png
|
|
108
|
-
conductor run-flow ./flows/login.yaml
|
|
109
|
-
`.trim();
|
package/dist/postinstall.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const install_js_1 = require("./commands/install.js");
|
|
4
|
-
// Runs as `postinstall` after `npm install -g @houwert/conductor`.
|
|
5
|
-
// Silent on failure so it never breaks the npm install.
|
|
6
|
-
try {
|
|
7
|
-
const version = (0, install_js_1.installPlugin)();
|
|
8
|
-
process.stdout.write(`✓ Conductor Claude Code plugin installed (v${version})\n`);
|
|
9
|
-
}
|
|
10
|
-
catch {
|
|
11
|
-
// Silent on failure — never break npm install
|
|
12
|
-
}
|