tapflow 0.2.1 → 0.3.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.
- package/README.md +53 -20
- package/dist/commands/agent-start.d.ts +3 -1
- package/dist/commands/agent-start.d.ts.map +1 -1
- package/dist/commands/agent-start.js +29 -35
- package/dist/commands/agent-start.js.map +1 -1
- package/dist/commands/start.d.ts +3 -1
- package/dist/commands/start.d.ts.map +1 -1
- package/dist/commands/start.js +29 -36
- package/dist/commands/start.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/dist/lib/ios-boot.d.ts +0 -3
- package/dist/lib/ios-boot.d.ts.map +0 -1
- package/dist/lib/ios-boot.js +0 -44
- package/dist/lib/ios-boot.js.map +0 -1
- package/dist/lib/platform.d.ts +0 -2
- package/dist/lib/platform.d.ts.map +0 -1
- package/dist/lib/platform.js +0 -10
- package/dist/lib/platform.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
<img src="docs/public/logo-hero.svg" height="72" alt="tapflow" />
|
|
3
3
|
|
|
4
|
-
<h3>
|
|
4
|
+
<h3>A self-hosted Appetize / BrowserStack alternative for mobile QA teams</h3>
|
|
5
5
|
|
|
6
6
|
<p>
|
|
7
|
-
Run simulators in
|
|
7
|
+
Run iOS simulators and Android emulators in any browser — no toolchain setup, no device management, no cloud uploads.<br />
|
|
8
8
|
App data never leaves your network.
|
|
9
9
|
</p>
|
|
10
10
|
|
|
@@ -14,11 +14,15 @@
|
|
|
14
14
|
<img src="https://img.shields.io/badge/platform-macOS-lightgrey" alt="macOS Agent" />
|
|
15
15
|
<a href="https://github.com/jo-duchan/tapflow/blob/main/CONTRIBUTING.md"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs welcome" /></a>
|
|
16
16
|
</p>
|
|
17
|
-
</div>
|
|
18
|
-
|
|
19
|
-
---
|
|
20
17
|
|
|
21
|
-
|
|
18
|
+
<p>
|
|
19
|
+
<a href="https://www.tapflow.dev">📖 Docs</a>
|
|
20
|
+
·
|
|
21
|
+
<a href="https://www.tapflow.dev/guide/getting-started">🚀 Quick Start</a>
|
|
22
|
+
·
|
|
23
|
+
<a href="https://www.tapflow.dev/guide/introduction">🎥 Demo</a>
|
|
24
|
+
</p>
|
|
25
|
+
</div>
|
|
22
26
|
|
|
23
27
|
<div align="center">
|
|
24
28
|
<a href="https://github.com/user-attachments/assets/01914ed2-f35c-4230-ae01-166ffe6af395" target="_blank" rel="noopener noreferrer">
|
|
@@ -31,34 +35,60 @@
|
|
|
31
35
|
|
|
32
36
|
## Why tapflow?
|
|
33
37
|
|
|
38
|
+
If you work on a mobile product, you've probably seen this.
|
|
39
|
+
|
|
40
|
+
Physical devices are never enough. Covering every OS version is even harder — iOS doesn't support downgrading, so maintaining a range of versions means managing a pool of locked devices, which is overhead nobody wants.
|
|
41
|
+
|
|
42
|
+
But the bigger friction is access. Simulators only run on a developer's Mac, behind complex developer toolchains. Anyone on the team who isn't a mobile developer has to ask one every single time they need to verify something:
|
|
43
|
+
|
|
44
|
+
> **Server / FE developer** — "How do I install the sandbox build to check what was deployed?"
|
|
45
|
+
>
|
|
46
|
+
> **Product manager** — "I keep having to install and remove different versions just to compare behavior."
|
|
47
|
+
>
|
|
48
|
+
> **Designer** — "I need to check the layout across screen sizes, but I don't have the right devices."
|
|
49
|
+
|
|
50
|
+
Cloud simulator services exist. But uploading internal app builds to an external service — and paying monthly fees for simulators already running on Macs you own — was never something we wanted to do.
|
|
51
|
+
|
|
52
|
+
So we built tapflow.
|
|
53
|
+
|
|
34
54
|
| Solution | Problem |
|
|
35
55
|
| ----------------------- | ------------------------------------------------------------------------ |
|
|
36
56
|
| Appetize / BrowserStack | Expensive — app data leaves your network |
|
|
37
57
|
| Physical devices | Cost, loss, management overhead |
|
|
38
58
|
| Xcode / Android Studio | Every QA member needs their own Mac + full toolchain setup |
|
|
39
|
-
| **tapflow** | Use the Mac you already own — data stays on-prem,
|
|
59
|
+
| **tapflow** | Use the Mac you already own — data stays on-prem, whole team does QA from a browser |
|
|
40
60
|
|
|
41
61
|
## Features
|
|
42
62
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
- **
|
|
46
|
-
- **
|
|
47
|
-
- **
|
|
48
|
-
- **
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
63
|
+
tapflow focuses on:
|
|
64
|
+
|
|
65
|
+
- **Zero setup for QA** — any browser, no toolchain. Designers, PMs, and server devs test without asking a mobile developer.
|
|
66
|
+
- **Data on-premises** — app binaries and session recordings never leave your network.
|
|
67
|
+
- **Your existing Mac** — no new hardware, no monthly cloud subscription.
|
|
68
|
+
- **API-first** — REST endpoints and PATs built in, ready for CI/CD and AI agent workflows.
|
|
69
|
+
|
|
70
|
+
What's included:
|
|
71
|
+
|
|
72
|
+
- **iOS & Android streaming** — ~30 fps, no additional app required on the device
|
|
73
|
+
- **Touch, swipe & pinch** — real-time input forwarded to the simulator
|
|
74
|
+
- **Deeplink** — jump directly to any screen from the QA toolbar, no manual navigation
|
|
75
|
+
- **Keyboard shortcuts** — simulator toolbar actions without leaving the keyboard
|
|
76
|
+
- **App Center** — upload `.app.zip` / `.apk`, track builds by status (Backlog / In Progress / Done / Rejected)
|
|
77
|
+
- **Session recordings** — record and share QA sessions, retained 72 hours
|
|
78
|
+
- **Screenshot REST endpoint** — `GET /api/v1/sessions/:sessionId/screenshot` for CI and AI agents
|
|
79
|
+
- **Mac resource monitoring** — CPU & RAM per agent, spot overloaded hosts before assigning sessions
|
|
80
|
+
- **Team management** — invite links, roles (Admin / Developer / QA / Viewer), Personal Access Tokens
|
|
81
|
+
- **MCP Server** *(experimental)* — `@tapflowio/mcp-server` lets Claude Code and other LLM agents control simulators as native tools.
|
|
52
82
|
|
|
53
83
|
## How it works
|
|
54
84
|
|
|
55
85
|
```
|
|
56
|
-
Browser (
|
|
57
|
-
|
|
86
|
+
Browser (your team) ← WebSocket → Relay Server ← WebSocket (outbound) → Mac Agent
|
|
87
|
+
(Linux / Mac) (iOS · Android)
|
|
58
88
|
```
|
|
59
89
|
|
|
60
90
|
1. The **Mac Agent** connects _outbound_ to the relay — no inbound firewall rules needed.
|
|
61
|
-
2.
|
|
91
|
+
2. Anyone on the team opens the **dashboard** in any browser and sees all available devices.
|
|
62
92
|
3. Touch events are forwarded in real time; the screen streams back to the browser.
|
|
63
93
|
4. The **relay** also serves the dashboard SPA on the same port — no separate web server needed.
|
|
64
94
|
|
|
@@ -103,7 +133,7 @@ Navigate to `http://localhost:4000` and sign in with the account you just create
|
|
|
103
133
|
| **Relay server** | Node.js ≥ 20, any OS (Linux/macOS), ~512 MB RAM |
|
|
104
134
|
| **iOS Agent** | macOS, Xcode with iOS Simulator Runtime, Node.js ≥ 20 |
|
|
105
135
|
| **Android Agent** | macOS, Android SDK (`adb` in `$PATH` or `$ANDROID_HOME` set), AVD with `google_apis/arm64-v8a` (android-34), Node.js ≥ 20 |
|
|
106
|
-
| **Browser
|
|
136
|
+
| **Browser** | Any modern browser — Chrome, Firefox, Safari, Edge |
|
|
107
137
|
|
|
108
138
|
## Self-Hosting
|
|
109
139
|
|
|
@@ -177,6 +207,9 @@ Full reference → [CLI docs](https://www.tapflow.dev/reference/cli)
|
|
|
177
207
|
- [Configuration](https://www.tapflow.dev/reference/configuration)
|
|
178
208
|
- [REST API](https://www.tapflow.dev/reference/api)
|
|
179
209
|
|
|
210
|
+
**AI Agent**
|
|
211
|
+
- [MCP Server](https://www.tapflow.dev/guide/mcp-server) *(experimental)*
|
|
212
|
+
|
|
180
213
|
**[Troubleshooting](https://www.tapflow.dev/guide/troubleshooting)**
|
|
181
214
|
|
|
182
215
|
## Development
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import '@tapflowio/ios-agent';
|
|
2
|
+
import '@tapflowio/android-agent';
|
|
1
3
|
export interface AgentStartOptions {
|
|
2
4
|
device?: string;
|
|
3
5
|
relay?: string;
|
|
4
|
-
platform?:
|
|
6
|
+
platform?: string;
|
|
5
7
|
}
|
|
6
8
|
export declare function cmdAgentStart(opts: AgentStartOptions): Promise<void>;
|
|
7
9
|
//# sourceMappingURL=agent-start.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-start.d.ts","sourceRoot":"","sources":["../../src/commands/agent-start.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"agent-start.d.ts","sourceRoot":"","sources":["../../src/commands/agent-start.ts"],"names":[],"mappings":"AAEA,OAAO,sBAAsB,CAAA;AAC7B,OAAO,0BAA0B,CAAA;AAGjC,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAUD,wBAAsB,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA8D1E"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import {
|
|
2
|
+
import { AgentRegistry } from '@tapflowio/agent-core';
|
|
3
|
+
import '@tapflowio/ios-agent';
|
|
4
|
+
import '@tapflowio/android-agent';
|
|
3
5
|
import { banner, createSpinner } from '../lib/print.js';
|
|
4
|
-
import { hasAdb } from '../lib/platform.js';
|
|
5
|
-
import { resolveAndBootIOSDevice } from '../lib/ios-boot.js';
|
|
6
6
|
const DEFAULT_RELAY = 'ws://localhost:4000';
|
|
7
7
|
const relayUrlSchema = z
|
|
8
8
|
.string()
|
|
@@ -10,7 +10,6 @@ const relayUrlSchema = z
|
|
|
10
10
|
message: '--relay must start with ws:// or wss://',
|
|
11
11
|
});
|
|
12
12
|
export async function cmdAgentStart(opts) {
|
|
13
|
-
const isMac = process.platform === 'darwin';
|
|
14
13
|
const rawRelay = opts.relay ?? DEFAULT_RELAY;
|
|
15
14
|
const relayResult = relayUrlSchema.safeParse(rawRelay);
|
|
16
15
|
if (!relayResult.success) {
|
|
@@ -19,9 +18,21 @@ export async function cmdAgentStart(opts) {
|
|
|
19
18
|
}
|
|
20
19
|
const relayUrl = relayResult.data;
|
|
21
20
|
const explicit = opts.platform;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
let platformsToRun;
|
|
22
|
+
if (!explicit || explicit === 'all') {
|
|
23
|
+
platformsToRun = AgentRegistry.available();
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
if (!AgentRegistry.platforms().includes(explicit)) {
|
|
27
|
+
banner('error', 'UNKNOWN PLATFORM', [
|
|
28
|
+
`'${explicit}' is not a registered platform.`,
|
|
29
|
+
`Registered: ${AgentRegistry.platforms().join(', ') || 'none'}`,
|
|
30
|
+
]);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
platformsToRun = [explicit];
|
|
34
|
+
}
|
|
35
|
+
if (platformsToRun.length === 0) {
|
|
25
36
|
banner('error', 'NO PLATFORM AVAILABLE', [
|
|
26
37
|
'No iOS simulator or Android adb found.',
|
|
27
38
|
'Run `tapflow doctor` to diagnose.',
|
|
@@ -29,39 +40,22 @@ export async function cmdAgentStart(opts) {
|
|
|
29
40
|
process.exit(1);
|
|
30
41
|
}
|
|
31
42
|
const agents = [];
|
|
32
|
-
// ──
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
iosSpinner.start();
|
|
37
|
-
try {
|
|
38
|
-
await iosAgent.connect(relayUrl);
|
|
39
|
-
iosSpinner.stop(true);
|
|
40
|
-
agents.push(iosAgent);
|
|
41
|
-
}
|
|
42
|
-
catch (e) {
|
|
43
|
-
iosSpinner.stop(false);
|
|
44
|
-
banner('error', 'IOS CONNECTION FAILED', [e.message]);
|
|
45
|
-
process.exit(1);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
// ── Android Agent ─────────────────────────────────────────────────────────
|
|
49
|
-
if (runAndroid) {
|
|
50
|
-
const androidAgent = new AndroidAgent({ deviceFilter: opts.device });
|
|
51
|
-
const androidSpinner = createSpinner('Connecting Android agent…');
|
|
52
|
-
androidSpinner.start();
|
|
43
|
+
// ── Connect each registered platform ────────────────────────────────────
|
|
44
|
+
for (const platform of platformsToRun) {
|
|
45
|
+
const spinner = createSpinner(`Connecting ${platform} agent…`);
|
|
46
|
+
spinner.start();
|
|
53
47
|
try {
|
|
54
|
-
await
|
|
55
|
-
|
|
56
|
-
agents.push(
|
|
48
|
+
const agent = await AgentRegistry.connect(platform, relayUrl, { deviceFilter: opts.device });
|
|
49
|
+
spinner.stop(true);
|
|
50
|
+
agents.push(agent);
|
|
57
51
|
}
|
|
58
52
|
catch (e) {
|
|
59
|
-
|
|
60
|
-
if (
|
|
61
|
-
console.log(` ⚠
|
|
53
|
+
spinner.stop(false);
|
|
54
|
+
if (agents.length > 0) {
|
|
55
|
+
console.log(` ⚠ ${platform}: ${e.message}`);
|
|
62
56
|
}
|
|
63
57
|
else {
|
|
64
|
-
banner('error',
|
|
58
|
+
banner('error', `${platform.toUpperCase()} CONNECTION FAILED`, [e.message]);
|
|
65
59
|
process.exit(1);
|
|
66
60
|
}
|
|
67
61
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-start.js","sourceRoot":"","sources":["../../src/commands/agent-start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"agent-start.js","sourceRoot":"","sources":["../../src/commands/agent-start.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/start.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import '@tapflowio/ios-agent';
|
|
2
|
+
import '@tapflowio/android-agent';
|
|
1
3
|
export interface StartOptions {
|
|
2
4
|
device?: string;
|
|
3
|
-
platform?:
|
|
5
|
+
platform?: string;
|
|
4
6
|
}
|
|
5
7
|
export declare function cmdStart(opts: StartOptions): Promise<void>;
|
|
6
8
|
//# sourceMappingURL=start.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AAGA,OAAO,sBAAsB,CAAA;AAC7B,OAAO,0BAA0B,CAAA;AAIjC,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAID,wBAAsB,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAoEhE"}
|
package/dist/commands/start.js
CHANGED
|
@@ -1,17 +1,28 @@
|
|
|
1
1
|
import { RelayServer, initDb, config } from '@tapflowio/relay';
|
|
2
|
+
import { AgentRegistry } from '@tapflowio/agent-core';
|
|
2
3
|
import path from 'path';
|
|
3
|
-
import
|
|
4
|
+
import '@tapflowio/ios-agent';
|
|
5
|
+
import '@tapflowio/android-agent';
|
|
4
6
|
import { banner, createSpinner, step } from '../lib/print.js';
|
|
5
|
-
import { hasAdb } from '../lib/platform.js';
|
|
6
|
-
import { resolveAndBootIOSDevice } from '../lib/ios-boot.js';
|
|
7
7
|
import { initConfigFile } from '../lib/init-config.js';
|
|
8
8
|
const RELAY_PORT = 4000;
|
|
9
9
|
export async function cmdStart(opts) {
|
|
10
|
-
const isMac = process.platform === 'darwin';
|
|
11
10
|
const relayUrl = `ws://localhost:${RELAY_PORT}`;
|
|
12
11
|
const explicit = opts.platform;
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
let platformsToRun;
|
|
13
|
+
if (!explicit || explicit === 'all') {
|
|
14
|
+
platformsToRun = AgentRegistry.available();
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
if (!AgentRegistry.platforms().includes(explicit)) {
|
|
18
|
+
banner('error', 'UNKNOWN PLATFORM', [
|
|
19
|
+
`'${explicit}' is not a registered platform.`,
|
|
20
|
+
`Registered: ${AgentRegistry.platforms().join(', ') || 'none'}`,
|
|
21
|
+
]);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
platformsToRun = [explicit];
|
|
25
|
+
}
|
|
15
26
|
// ── 1. Relay (always local) ───────────────────────────────────────────────
|
|
16
27
|
initConfigFile();
|
|
17
28
|
initDb(path.join(config.server.dataDir, 'tapflow.db'));
|
|
@@ -19,7 +30,7 @@ export async function cmdStart(opts) {
|
|
|
19
30
|
await server.start();
|
|
20
31
|
step(`Relay started on ws://localhost:${RELAY_PORT}`);
|
|
21
32
|
// ── 2. Agent availability check ───────────────────────────────────────────
|
|
22
|
-
if (
|
|
33
|
+
if (platformsToRun.length === 0) {
|
|
23
34
|
banner('success', 'TAPFLOW RELAY READY', [
|
|
24
35
|
`Relay : http://localhost:${RELAY_PORT}`,
|
|
25
36
|
'No agent environment detected — running relay only.',
|
|
@@ -30,40 +41,22 @@ export async function cmdStart(opts) {
|
|
|
30
41
|
return;
|
|
31
42
|
}
|
|
32
43
|
const agents = [];
|
|
33
|
-
// ── 3.
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
iosSpinner.start();
|
|
38
|
-
try {
|
|
39
|
-
await iosAgent.connect(relayUrl);
|
|
40
|
-
iosSpinner.stop(true);
|
|
41
|
-
agents.push(iosAgent);
|
|
42
|
-
}
|
|
43
|
-
catch (e) {
|
|
44
|
-
iosSpinner.stop(false);
|
|
45
|
-
banner('error', 'IOS CONNECTION FAILED', [e.message]);
|
|
46
|
-
process.exit(1);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
// ── 4. Android Agent ──────────────────────────────────────────────────────
|
|
50
|
-
if (runAndroid) {
|
|
51
|
-
const androidAgent = new AndroidAgent({ deviceFilter: opts.device });
|
|
52
|
-
const androidSpinner = createSpinner('Connecting Android agent…');
|
|
53
|
-
androidSpinner.start();
|
|
44
|
+
// ── 3. Connect each registered platform ──────────────────────────────────
|
|
45
|
+
for (const platform of platformsToRun) {
|
|
46
|
+
const spinner = createSpinner(`Connecting ${platform} agent…`);
|
|
47
|
+
spinner.start();
|
|
54
48
|
try {
|
|
55
|
-
await
|
|
56
|
-
|
|
57
|
-
agents.push(
|
|
49
|
+
const agent = await AgentRegistry.connect(platform, relayUrl, { deviceFilter: opts.device });
|
|
50
|
+
spinner.stop(true);
|
|
51
|
+
agents.push(agent);
|
|
58
52
|
}
|
|
59
53
|
catch (e) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
console.log(` ⚠ Android: ${e.message}`);
|
|
54
|
+
spinner.stop(false);
|
|
55
|
+
if (agents.length > 0) {
|
|
56
|
+
console.log(` ⚠ ${platform}: ${e.message}`);
|
|
64
57
|
}
|
|
65
58
|
else {
|
|
66
|
-
banner('error',
|
|
59
|
+
banner('error', `${platform.toUpperCase()} CONNECTION FAILED`, [e.message]);
|
|
67
60
|
process.exit(1);
|
|
68
61
|
}
|
|
69
62
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAC9D,OAAO,
|
|
1
|
+
{"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -34,7 +34,7 @@ cli
|
|
|
34
34
|
.action((name) => cmdBoot(name));
|
|
35
35
|
cli
|
|
36
36
|
.command('start', 'Start relay and available agents locally (local dev shortcut)')
|
|
37
|
-
.option('--platform <platform>', 'Platform to start:
|
|
37
|
+
.option('--platform <platform>', 'Platform to start: registered key or all (default: auto-detect)')
|
|
38
38
|
.option('--device <name>', 'iOS Simulator name or UDID to use')
|
|
39
39
|
.action((opts) => cmdStart(opts));
|
|
40
40
|
cli
|
|
@@ -49,7 +49,7 @@ cli
|
|
|
49
49
|
cli
|
|
50
50
|
.command('agent <subcommand>', 'Agent commands (subcommand: start)')
|
|
51
51
|
.option('--relay <url>', 'Relay WebSocket URL (default: ws://localhost:4000)')
|
|
52
|
-
.option('--platform <platform>', 'Platform to start:
|
|
52
|
+
.option('--platform <platform>', 'Platform to start: registered key or all (default: auto-detect)')
|
|
53
53
|
.option('--device <name>', 'iOS Simulator name or UDID to use')
|
|
54
54
|
.action((subcommand, opts) => {
|
|
55
55
|
if (subcommand === 'start')
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAA;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAA;AACnC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAEzB,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AACzD,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAwB,CAAA;AACnH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAE5C,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,GAAG,EAAE,EAAE;IACvC,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;IAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA;AAEF,MAAM,GAAG,GAAG,GAAG,CAAC,SAAS,CAAC,CAAA;AAE1B,GAAG;KACA,OAAO,CAAC,MAAM,EAAE,6CAA6C,CAAC;KAC9D,MAAM,CAAC,eAAe,EAAE,4CAA4C,CAAC;KACrE,MAAM,CAAC,CAAC,IAAwB,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAA;AAEtD,GAAG;KACA,OAAO,CAAC,QAAQ,EAAE,4BAA4B,CAAC;KAC/C,MAAM,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC,CAAA;AAE5B,GAAG;KACA,OAAO,CAAC,SAAS,EAAE,gDAAgD,CAAC;KACpE,MAAM,CAAC,GAAG,EAAE,CAAC,UAAU,EAAE,CAAC,CAAA;AAE7B,GAAG;KACA,OAAO,CAAC,aAAa,EAAE,kCAAkC,CAAC;KAC1D,MAAM,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAA;AAE1C,GAAG;KACA,OAAO,CAAC,OAAO,EAAE,+DAA+D,CAAC;KACjF,MAAM,CAAC,uBAAuB,EAAE
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tapflow",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Self-hosted iOS/Android simulator streaming for QA teams",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ios",
|
|
@@ -46,10 +46,10 @@
|
|
|
46
46
|
"cac": "^6.7.14",
|
|
47
47
|
"ws": "^8.0.0",
|
|
48
48
|
"zod": "^4.4.3",
|
|
49
|
-
"@tapflowio/agent-core": "0.
|
|
50
|
-
"@tapflowio/
|
|
51
|
-
"@tapflowio/
|
|
52
|
-
"@tapflowio/relay": "0.
|
|
49
|
+
"@tapflowio/agent-core": "0.3.0",
|
|
50
|
+
"@tapflowio/android-agent": "0.3.0",
|
|
51
|
+
"@tapflowio/ios-agent": "0.3.0",
|
|
52
|
+
"@tapflowio/relay": "0.3.0"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@types/node": "^20.0.0",
|
package/dist/lib/ios-boot.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ios-boot.d.ts","sourceRoot":"","sources":["../../src/lib/ios-boot.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAG/C,wBAAsB,uBAAuB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAuCtF"}
|
package/dist/lib/ios-boot.js
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { execSync } from 'node:child_process';
|
|
2
|
-
import { IOSAgent } from '@tapflowio/ios-agent';
|
|
3
|
-
import { banner, createSpinner, step } from './print.js';
|
|
4
|
-
export async function resolveAndBootIOSDevice(deviceFilter) {
|
|
5
|
-
const agent = new IOSAgent();
|
|
6
|
-
const devices = await agent.listDevices();
|
|
7
|
-
if (deviceFilter) {
|
|
8
|
-
const match = devices.find((d) => d.name === deviceFilter || d.id === deviceFilter);
|
|
9
|
-
if (!match) {
|
|
10
|
-
banner('error', 'DEVICE NOT FOUND', [
|
|
11
|
-
`"${deviceFilter}" does not match any simulator.`,
|
|
12
|
-
'Run `tapflow devices` to see available simulators.',
|
|
13
|
-
]);
|
|
14
|
-
process.exit(1);
|
|
15
|
-
}
|
|
16
|
-
if (match.status !== 'booted') {
|
|
17
|
-
const spinner = createSpinner(`Booting ${match.name}…`);
|
|
18
|
-
spinner.start();
|
|
19
|
-
execSync(`xcrun simctl boot ${match.id}`, { stdio: 'pipe' });
|
|
20
|
-
spinner.stop(true);
|
|
21
|
-
}
|
|
22
|
-
step(`iOS Simulator: ${match.name}`);
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
25
|
-
const booted = devices.find((d) => d.status === 'booted');
|
|
26
|
-
if (booted) {
|
|
27
|
-
step(`iOS Simulator: ${booted.name}`);
|
|
28
|
-
}
|
|
29
|
-
else {
|
|
30
|
-
const first = devices[0];
|
|
31
|
-
if (!first) {
|
|
32
|
-
banner('error', 'NO SIMULATOR FOUND', ['Create one in Xcode → Window → Devices and Simulators.']);
|
|
33
|
-
process.exit(1);
|
|
34
|
-
}
|
|
35
|
-
const spinner = createSpinner(`Booting ${first.name}…`);
|
|
36
|
-
spinner.start();
|
|
37
|
-
execSync(`xcrun simctl boot ${first.id}`, { stdio: 'pipe' });
|
|
38
|
-
spinner.stop(true);
|
|
39
|
-
step(`iOS Simulator: ${first.name}`);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
return agent;
|
|
43
|
-
}
|
|
44
|
-
//# sourceMappingURL=ios-boot.js.map
|
package/dist/lib/ios-boot.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ios-boot.js","sourceRoot":"","sources":["../../src/lib/ios-boot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAExD,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,YAAqB;IACjE,MAAM,KAAK,GAAG,IAAI,QAAQ,EAAE,CAAA;IAC5B,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,WAAW,EAAE,CAAA;IAEzC,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,IAAI,CAAC,CAAC,EAAE,KAAK,YAAY,CAAC,CAAA;QACnF,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,CAAC,OAAO,EAAE,kBAAkB,EAAE;gBAClC,IAAI,YAAY,iCAAiC;gBACjD,oDAAoD;aACrD,CAAC,CAAA;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC9B,MAAM,OAAO,GAAG,aAAa,CAAC,WAAW,KAAK,CAAC,IAAI,GAAG,CAAC,CAAA;YACvD,OAAO,CAAC,KAAK,EAAE,CAAA;YACf,QAAQ,CAAC,qBAAqB,KAAK,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;YAC5D,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACpB,CAAC;QACD,IAAI,CAAC,kBAAkB,KAAK,CAAC,IAAI,EAAE,CAAC,CAAA;IACtC,CAAC;SAAM,CAAC;QACN,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAA;QACzD,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC,kBAAkB,MAAM,CAAC,IAAI,EAAE,CAAC,CAAA;QACvC,CAAC;aAAM,CAAC;YACN,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;YACxB,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,CAAC,OAAO,EAAE,oBAAoB,EAAE,CAAC,wDAAwD,CAAC,CAAC,CAAA;gBACjG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACjB,CAAC;YACD,MAAM,OAAO,GAAG,aAAa,CAAC,WAAW,KAAK,CAAC,IAAI,GAAG,CAAC,CAAA;YACvD,OAAO,CAAC,KAAK,EAAE,CAAA;YACf,QAAQ,CAAC,qBAAqB,KAAK,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;YAC5D,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAClB,IAAI,CAAC,kBAAkB,KAAK,CAAC,IAAI,EAAE,CAAC,CAAA;QACtC,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC"}
|
package/dist/lib/platform.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../../src/lib/platform.ts"],"names":[],"mappings":"AAEA,wBAAgB,MAAM,IAAI,OAAO,CAMhC"}
|
package/dist/lib/platform.js
DELETED
package/dist/lib/platform.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../../src/lib/platform.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAE7C,MAAM,UAAU,MAAM;IACpB,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAA;IACrF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC"}
|