tapflow 0.1.0-alpha.1 → 0.1.0-alpha.2
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 +5 -11
- package/dist/commands/agent-start.d.ts +7 -0
- package/dist/commands/agent-start.d.ts.map +1 -0
- package/dist/commands/agent-start.js +78 -0
- package/dist/commands/agent-start.js.map +1 -0
- package/dist/commands/boot.d.ts +2 -0
- package/dist/commands/boot.d.ts.map +1 -0
- package/dist/commands/boot.js +47 -0
- package/dist/commands/boot.js.map +1 -0
- package/dist/commands/devices.d.ts +2 -0
- package/dist/commands/devices.d.ts.map +1 -0
- package/dist/commands/devices.js +85 -0
- package/dist/commands/devices.js.map +1 -0
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +41 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/init.d.ts +5 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +64 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/logs.d.ts +5 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +22 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/relay-start.d.ts +5 -0
- package/dist/commands/relay-start.d.ts.map +1 -0
- package/dist/commands/relay-start.js +24 -0
- package/dist/commands/relay-start.js.map +1 -0
- package/dist/commands/reset.d.ts +2 -0
- package/dist/commands/reset.d.ts.map +1 -0
- package/dist/commands/reset.js +49 -0
- package/dist/commands/reset.js.map +1 -0
- package/dist/commands/start.d.ts +6 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +77 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +4 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +56 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/doctor.d.ts +12 -0
- package/dist/lib/doctor.d.ts.map +1 -0
- package/dist/lib/doctor.js +118 -0
- package/dist/lib/doctor.js.map +1 -0
- package/dist/lib/ios-boot.d.ts +3 -0
- package/dist/lib/ios-boot.d.ts.map +1 -0
- package/dist/lib/ios-boot.js +44 -0
- package/dist/lib/ios-boot.js.map +1 -0
- package/dist/lib/platform.d.ts +2 -0
- package/dist/lib/platform.d.ts.map +1 -0
- package/dist/lib/platform.js +10 -0
- package/dist/lib/platform.js.map +1 -0
- package/dist/lib/print.d.ts +13 -0
- package/dist/lib/print.d.ts.map +1 -0
- package/dist/lib/print.js +55 -0
- package/dist/lib/print.js.map +1 -0
- package/dist/lib/tapflow-dir.d.ts +3 -0
- package/dist/lib/tapflow-dir.d.ts.map +1 -0
- package/dist/lib/tapflow-dir.js +8 -0
- package/dist/lib/tapflow-dir.js.map +1 -0
- package/package.json +7 -5
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { RelayServer } from '@tapflowio/relay';
|
|
2
|
+
import { AndroidAgent } from '@tapflowio/android-agent';
|
|
3
|
+
import { banner, createSpinner, step } from '../lib/print.js';
|
|
4
|
+
import { hasAdb } from '../lib/platform.js';
|
|
5
|
+
import { resolveAndBootIOSDevice } from '../lib/ios-boot.js';
|
|
6
|
+
const RELAY_PORT = 4000;
|
|
7
|
+
export async function cmdStart(opts) {
|
|
8
|
+
const isMac = process.platform === 'darwin';
|
|
9
|
+
const relayUrl = `ws://localhost:${RELAY_PORT}`;
|
|
10
|
+
const explicit = opts.platform;
|
|
11
|
+
const runIOS = explicit === 'ios' || explicit === 'all' || (!explicit && isMac);
|
|
12
|
+
const runAndroid = explicit === 'android' || explicit === 'all' || (!explicit && hasAdb());
|
|
13
|
+
// ── 1. Relay (always local) ───────────────────────────────────────────────
|
|
14
|
+
const server = new RelayServer({ port: RELAY_PORT });
|
|
15
|
+
await server.start();
|
|
16
|
+
step(`Relay started on ws://localhost:${RELAY_PORT}`);
|
|
17
|
+
// ── 2. Agent availability check ───────────────────────────────────────────
|
|
18
|
+
if (!runIOS && !runAndroid) {
|
|
19
|
+
banner('success', 'TAPFLOW RELAY READY', [
|
|
20
|
+
`Relay : http://localhost:${RELAY_PORT}`,
|
|
21
|
+
'No agent environment detected — running relay only.',
|
|
22
|
+
`Connect a Mac agent: tapflow agent start --relay ws://<this-ip>:${RELAY_PORT}`,
|
|
23
|
+
'Press Ctrl+C to stop.',
|
|
24
|
+
]);
|
|
25
|
+
process.on('SIGINT', () => process.exit(0));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const agents = [];
|
|
29
|
+
// ── 3. iOS Agent ──────────────────────────────────────────────────────────
|
|
30
|
+
if (runIOS) {
|
|
31
|
+
const iosAgent = await resolveAndBootIOSDevice(opts.device);
|
|
32
|
+
const iosSpinner = createSpinner('Connecting iOS agent…');
|
|
33
|
+
iosSpinner.start();
|
|
34
|
+
try {
|
|
35
|
+
await iosAgent.connect(relayUrl);
|
|
36
|
+
iosSpinner.stop(true);
|
|
37
|
+
agents.push(iosAgent);
|
|
38
|
+
}
|
|
39
|
+
catch (e) {
|
|
40
|
+
iosSpinner.stop(false);
|
|
41
|
+
banner('error', 'IOS CONNECTION FAILED', [e.message]);
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// ── 4. Android Agent ──────────────────────────────────────────────────────
|
|
46
|
+
if (runAndroid) {
|
|
47
|
+
const androidAgent = new AndroidAgent({ deviceFilter: opts.device });
|
|
48
|
+
const androidSpinner = createSpinner('Connecting Android agent…');
|
|
49
|
+
androidSpinner.start();
|
|
50
|
+
try {
|
|
51
|
+
await androidAgent.connect(relayUrl);
|
|
52
|
+
androidSpinner.stop(true);
|
|
53
|
+
agents.push(androidAgent);
|
|
54
|
+
}
|
|
55
|
+
catch (e) {
|
|
56
|
+
androidSpinner.stop(false);
|
|
57
|
+
// Android 연결 실패 시 iOS가 이미 연결됐으면 경고만, 아니면 종료
|
|
58
|
+
if (runIOS && agents.length > 0) {
|
|
59
|
+
console.log(` ⚠ Android: ${e.message}`);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
banner('error', 'ANDROID CONNECTION FAILED', [e.message]);
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
banner('success', 'TAPFLOW READY', [
|
|
68
|
+
`Relay : http://localhost:${RELAY_PORT}`,
|
|
69
|
+
`Open http://localhost:${RELAY_PORT} in your browser.`,
|
|
70
|
+
'Press Ctrl+C to stop.',
|
|
71
|
+
]);
|
|
72
|
+
process.on('SIGINT', () => {
|
|
73
|
+
agents.forEach((a) => a.disconnect());
|
|
74
|
+
process.exit(0);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=start.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAGA,wBAAsB,SAAS,CAAC,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA2DvE"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { WebSocket } from 'ws';
|
|
2
|
+
import { DIM, BOLD, GREEN, YELLOW, RED, R } from '../lib/print.js';
|
|
3
|
+
export async function cmdStatus(opts) {
|
|
4
|
+
const relayUrl = (opts.relay ?? 'ws://localhost:4000').replace(/^http/, 'ws');
|
|
5
|
+
console.log(`\n Connecting to ${relayUrl}…\n`);
|
|
6
|
+
console.log(` ${DIM}● agent ◉ in use ○ idle${R}\n`);
|
|
7
|
+
await new Promise((resolve, reject) => {
|
|
8
|
+
const ws = new WebSocket(relayUrl);
|
|
9
|
+
const timeout = setTimeout(() => {
|
|
10
|
+
ws.terminate();
|
|
11
|
+
reject(new Error(`Could not connect to relay at ${relayUrl} (5s timeout)`));
|
|
12
|
+
}, 5000);
|
|
13
|
+
ws.on('open', () => ws.send(JSON.stringify({ type: 'agents:list' })));
|
|
14
|
+
ws.on('message', (data) => {
|
|
15
|
+
try {
|
|
16
|
+
const msg = JSON.parse(data.toString());
|
|
17
|
+
if (msg.type !== 'agents:listed')
|
|
18
|
+
return;
|
|
19
|
+
clearTimeout(timeout);
|
|
20
|
+
ws.close();
|
|
21
|
+
const sessions = msg.sessions ?? [];
|
|
22
|
+
if (sessions.length === 0) {
|
|
23
|
+
console.log(` ${DIM}No agents connected.${R}\n`);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
let totalDevices = 0;
|
|
27
|
+
let activeSessions = 0;
|
|
28
|
+
for (const session of sessions) {
|
|
29
|
+
console.log(` ${BOLD}${GREEN}●${R} ${BOLD}${session.agentName}${R}`);
|
|
30
|
+
for (const device of session.devices ?? []) {
|
|
31
|
+
const occupied = !!device.joinedBy;
|
|
32
|
+
const dot = occupied ? `${YELLOW}◉${R}` : `${DIM}○${R}`;
|
|
33
|
+
const who = occupied ? ` ${DIM}← ${device.joinedBy}${R}` : '';
|
|
34
|
+
console.log(` ${dot} ${device.name}${who}`);
|
|
35
|
+
totalDevices++;
|
|
36
|
+
if (occupied)
|
|
37
|
+
activeSessions++;
|
|
38
|
+
}
|
|
39
|
+
console.log();
|
|
40
|
+
}
|
|
41
|
+
console.log(` ${DIM}${sessions.length} agent(s) · ${totalDevices} device(s) · ${activeSessions} active session(s)${R}\n`);
|
|
42
|
+
}
|
|
43
|
+
resolve();
|
|
44
|
+
}
|
|
45
|
+
catch { /* ignore non-agents:listed messages */ }
|
|
46
|
+
});
|
|
47
|
+
ws.on('error', (err) => {
|
|
48
|
+
clearTimeout(timeout);
|
|
49
|
+
reject(err);
|
|
50
|
+
});
|
|
51
|
+
}).catch((err) => {
|
|
52
|
+
console.error(`\n ${RED}✗${R} ${err.message}\n`);
|
|
53
|
+
process.exit(1);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { cac } from 'cac';
|
|
2
|
+
import { cmdInit } from './commands/init.js';
|
|
3
|
+
import { cmdDoctor } from './commands/doctor.js';
|
|
4
|
+
import { cmdDevices } from './commands/devices.js';
|
|
5
|
+
import { cmdBoot } from './commands/boot.js';
|
|
6
|
+
import { cmdStart } from './commands/start.js';
|
|
7
|
+
import { cmdRelayStart } from './commands/relay-start.js';
|
|
8
|
+
import { cmdAgentStart } from './commands/agent-start.js';
|
|
9
|
+
import { cmdReset } from './commands/reset.js';
|
|
10
|
+
import { cmdStatus } from './commands/status.js';
|
|
11
|
+
import { cmdLogs } from './commands/logs.js';
|
|
12
|
+
const cli = cac('tapflow');
|
|
13
|
+
cli
|
|
14
|
+
.command('init', 'Create the first admin account on the relay')
|
|
15
|
+
.option('--relay <url>', 'Relay URL (default: http://localhost:4000)')
|
|
16
|
+
.action((opts) => cmdInit(opts));
|
|
17
|
+
cli
|
|
18
|
+
.command('doctor', 'Check system prerequisites')
|
|
19
|
+
.action(() => cmdDoctor());
|
|
20
|
+
cli
|
|
21
|
+
.command('devices', 'List available iOS simulators and Android AVDs')
|
|
22
|
+
.action(() => cmdDevices());
|
|
23
|
+
cli
|
|
24
|
+
.command('boot <name>', 'Boot a simulator by name or UDID')
|
|
25
|
+
.action((name) => cmdBoot(name));
|
|
26
|
+
cli
|
|
27
|
+
.command('start', 'Start relay and available agents locally (local dev shortcut)')
|
|
28
|
+
.option('--platform <platform>', 'Platform to start: ios | android | all (default: auto-detect)')
|
|
29
|
+
.option('--device <name>', 'iOS Simulator name or UDID to use')
|
|
30
|
+
.action((opts) => cmdStart(opts));
|
|
31
|
+
cli
|
|
32
|
+
.command('relay start', 'Start the relay server only (no agents)')
|
|
33
|
+
.option('--port <n>', 'Port to listen on (default: 4000)')
|
|
34
|
+
.action((opts) => cmdRelayStart(opts));
|
|
35
|
+
cli
|
|
36
|
+
.command('agent start', 'Start agents and connect to a relay (no local relay spawned)')
|
|
37
|
+
.option('--relay <url>', 'Relay WebSocket URL (default: ws://localhost:4000)')
|
|
38
|
+
.option('--platform <platform>', 'Platform to start: ios | android | all (default: auto-detect)')
|
|
39
|
+
.option('--device <name>', 'iOS Simulator name or UDID to use')
|
|
40
|
+
.action((opts) => cmdAgentStart(opts));
|
|
41
|
+
cli
|
|
42
|
+
.command('reset', 'Shut down all simulators')
|
|
43
|
+
.action(() => cmdReset());
|
|
44
|
+
cli
|
|
45
|
+
.command('status', 'Show connected agents, devices, and active sessions')
|
|
46
|
+
.option('--relay <url>', 'Relay URL (default: ws://localhost:4000)')
|
|
47
|
+
.action((opts) => cmdStatus(opts));
|
|
48
|
+
cli
|
|
49
|
+
.command('logs', 'Show recent relay log entries')
|
|
50
|
+
.option('--relay <url>', 'Relay URL (default: http://localhost:4000)')
|
|
51
|
+
.option('--lines <n>', 'Number of lines to show (default: 100)', { default: 100 })
|
|
52
|
+
.action((opts) => cmdLogs(opts));
|
|
53
|
+
cli.help();
|
|
54
|
+
cli.version('0.1.0');
|
|
55
|
+
cli.parse();
|
|
56
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface DoctorCheck {
|
|
2
|
+
label: string;
|
|
3
|
+
ok: boolean;
|
|
4
|
+
detail?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface DoctorResult {
|
|
7
|
+
common: DoctorCheck[];
|
|
8
|
+
ios: DoctorCheck[] | null;
|
|
9
|
+
android: DoctorCheck[] | null;
|
|
10
|
+
}
|
|
11
|
+
export declare function runDoctorChecks(): Promise<DoctorResult>;
|
|
12
|
+
//# sourceMappingURL=doctor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/lib/doctor.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,EAAE,EAAE,OAAO,CAAA;IACX,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,WAAW,EAAE,CAAA;IACrB,GAAG,EAAE,WAAW,EAAE,GAAG,IAAI,CAAA;IACzB,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI,CAAA;CAC9B;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,YAAY,CAAC,CAS7D"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process';
|
|
2
|
+
export async function runDoctorChecks() {
|
|
3
|
+
const isMac = process.platform === 'darwin';
|
|
4
|
+
const adbPath = resolveAdb();
|
|
5
|
+
return {
|
|
6
|
+
common: [checkNodeVersion()],
|
|
7
|
+
ios: isMac ? [checkXcode(), checkSimctl(), checkBootedSimulator()] : null,
|
|
8
|
+
android: adbPath !== null ? [checkAdb(adbPath), checkBootedAvd()] : null,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
function checkXcode() {
|
|
12
|
+
try {
|
|
13
|
+
const out = execSync('xcodebuild -version', { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] });
|
|
14
|
+
const version = out.split('\n')[0]?.replace('Xcode ', '') ?? '';
|
|
15
|
+
return { label: `Xcode ${version}`, ok: true };
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return {
|
|
19
|
+
label: 'Xcode',
|
|
20
|
+
ok: false,
|
|
21
|
+
detail: 'Install Xcode from https://developer.apple.com/xcode/ or the Mac App Store.',
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function checkSimctl() {
|
|
26
|
+
try {
|
|
27
|
+
execSync('xcrun simctl list --json', { stdio: 'pipe' });
|
|
28
|
+
return { label: 'xcrun simctl', ok: true };
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return {
|
|
32
|
+
label: 'xcrun simctl',
|
|
33
|
+
ok: false,
|
|
34
|
+
detail: 'Run: xcode-select --install',
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function checkBootedSimulator() {
|
|
39
|
+
try {
|
|
40
|
+
const raw = execSync('xcrun simctl list devices --json', { encoding: 'utf8', stdio: 'pipe' });
|
|
41
|
+
const data = JSON.parse(raw);
|
|
42
|
+
const allDevices = Object.values(data.devices).flat();
|
|
43
|
+
const booted = allDevices.find((d) => d.state === 'Booted');
|
|
44
|
+
if (booted) {
|
|
45
|
+
return { label: `Simulator booted: ${booted.name}`, ok: true };
|
|
46
|
+
}
|
|
47
|
+
const available = allDevices.find((d) => d.state === 'Shutdown');
|
|
48
|
+
const hint = available
|
|
49
|
+
? `Run: tapflow boot "${available.name}"`
|
|
50
|
+
: 'Run: tapflow devices to see available simulators, then: tapflow boot "<name>"';
|
|
51
|
+
return { label: 'Simulator', ok: false, detail: hint };
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return { label: 'Simulator', ok: false, detail: 'Could not query simulators. Is Xcode installed?' };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function checkNodeVersion() {
|
|
58
|
+
const version = process.version;
|
|
59
|
+
const [, major] = version.match(/^v(\d+)/) ?? [];
|
|
60
|
+
const ok = Number(major) >= 20;
|
|
61
|
+
return {
|
|
62
|
+
label: `Node ${version}`,
|
|
63
|
+
ok,
|
|
64
|
+
detail: ok ? undefined : 'Node ≥ 20 required. Install from https://nodejs.org/',
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function resolveAdb() {
|
|
68
|
+
try {
|
|
69
|
+
const path = execSync('which adb', { encoding: 'utf8', stdio: 'pipe' }).trim();
|
|
70
|
+
return path || null;
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function checkAdb(path) {
|
|
77
|
+
return { label: `adb found: ${path}`, ok: true };
|
|
78
|
+
}
|
|
79
|
+
function checkBootedAvd() {
|
|
80
|
+
try {
|
|
81
|
+
const out = execSync('adb devices', { encoding: 'utf8', stdio: 'pipe' });
|
|
82
|
+
const lines = out.trim().split('\n').slice(1).filter(Boolean);
|
|
83
|
+
const emulator = lines.find((l) => l.startsWith('emulator-'));
|
|
84
|
+
if (!emulator) {
|
|
85
|
+
const hint = listAvdHint();
|
|
86
|
+
return {
|
|
87
|
+
label: 'AVD',
|
|
88
|
+
ok: false,
|
|
89
|
+
detail: hint
|
|
90
|
+
? `No running emulator. Run: emulator @${hint}`
|
|
91
|
+
: 'No running emulator. Start an AVD from Android Studio > Device Manager.',
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
const serial = emulator.split('\t')[0]?.trim() ?? '';
|
|
95
|
+
try {
|
|
96
|
+
const avdName = execSync(`adb -s ${serial} emu avd name`, { encoding: 'utf8', stdio: 'pipe' })
|
|
97
|
+
.split('\n')[0]
|
|
98
|
+
?.trim() ?? serial;
|
|
99
|
+
return { label: `AVD: ${avdName}`, ok: true };
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return { label: `AVD: ${serial}`, ok: true };
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return { label: 'AVD', ok: false, detail: 'Could not query running emulators.' };
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function listAvdHint() {
|
|
110
|
+
try {
|
|
111
|
+
const out = execSync('emulator -list-avds', { encoding: 'utf8', stdio: 'pipe' }).trim();
|
|
112
|
+
return out.split('\n')[0]?.trim() || null;
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/lib/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../../src/lib/platform.ts"],"names":[],"mappings":"AAEA,wBAAgB,MAAM,IAAI,OAAO,CAMhC"}
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const R = "\u001B[0m";
|
|
2
|
+
export declare const BOLD = "\u001B[1m";
|
|
3
|
+
export declare const DIM = "\u001B[2m";
|
|
4
|
+
export declare const GREEN = "\u001B[32m";
|
|
5
|
+
export declare const RED = "\u001B[31m";
|
|
6
|
+
export declare const YELLOW = "\u001B[33m";
|
|
7
|
+
export declare function banner(type: 'success' | 'error', title: string, lines?: string[]): void;
|
|
8
|
+
export declare function createSpinner(msg: string): {
|
|
9
|
+
start(): void;
|
|
10
|
+
stop(ok: boolean): void;
|
|
11
|
+
};
|
|
12
|
+
export declare function step(msg: string): void;
|
|
13
|
+
//# sourceMappingURL=print.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"print.d.ts","sourceRoot":"","sources":["../../src/lib/print.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,CAAC,cAAY,CAAA;AAC1B,eAAO,MAAM,IAAI,cAAY,CAAA;AAC7B,eAAO,MAAM,GAAG,cAAY,CAAA;AAC5B,eAAO,MAAM,KAAK,eAAa,CAAA;AAC/B,eAAO,MAAM,GAAG,eAAa,CAAA;AAC7B,eAAO,MAAM,MAAM,eAAa,CAAA;AAahC,wBAAgB,MAAM,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAM,EAAO,GAAG,IAAI,CAkB3F;AAID,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM;;aAY5B,OAAO;EAMnB;AAED,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEtC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export const R = '\x1b[0m';
|
|
2
|
+
export const BOLD = '\x1b[1m';
|
|
3
|
+
export const DIM = '\x1b[2m';
|
|
4
|
+
export const GREEN = '\x1b[32m';
|
|
5
|
+
export const RED = '\x1b[31m';
|
|
6
|
+
export const YELLOW = '\x1b[33m';
|
|
7
|
+
const MAX_WIDTH = 72;
|
|
8
|
+
function wrap(line, maxWidth) {
|
|
9
|
+
if (line.length <= maxWidth)
|
|
10
|
+
return [line];
|
|
11
|
+
const chunks = [];
|
|
12
|
+
for (let i = 0; i < line.length; i += maxWidth) {
|
|
13
|
+
chunks.push(line.slice(i, i + maxWidth));
|
|
14
|
+
}
|
|
15
|
+
return chunks;
|
|
16
|
+
}
|
|
17
|
+
export function banner(type, title, lines = []) {
|
|
18
|
+
const color = type === 'success' ? GREEN : RED;
|
|
19
|
+
const icon = type === 'success' ? '✓' : '✗';
|
|
20
|
+
const wrappedLines = lines.flatMap((l) => wrap(l, MAX_WIDTH));
|
|
21
|
+
const contentWidth = Math.min(MAX_WIDTH, Math.max(title.length + 5, ...wrappedLines.map((l) => l.length + 2), 40));
|
|
22
|
+
const bar = '─'.repeat(contentWidth);
|
|
23
|
+
console.log();
|
|
24
|
+
console.log(`${color}${BOLD} ┌${bar}┐${R}`);
|
|
25
|
+
console.log(`${color}${BOLD} │ ${icon} ${title.padEnd(contentWidth - 5)}│${R}`);
|
|
26
|
+
console.log(`${color}${BOLD} └${bar}┘${R}`);
|
|
27
|
+
for (const line of wrappedLines) {
|
|
28
|
+
console.log(`${DIM} ${line}${R}`);
|
|
29
|
+
}
|
|
30
|
+
console.log();
|
|
31
|
+
}
|
|
32
|
+
const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
33
|
+
export function createSpinner(msg) {
|
|
34
|
+
let frame = 0;
|
|
35
|
+
let id = null;
|
|
36
|
+
return {
|
|
37
|
+
start() {
|
|
38
|
+
process.stdout.write(`\n ${SPINNER_FRAMES[0]} ${msg}`);
|
|
39
|
+
id = setInterval(() => {
|
|
40
|
+
frame = (frame + 1) % SPINNER_FRAMES.length;
|
|
41
|
+
process.stdout.write(`\r ${SPINNER_FRAMES[frame]} ${msg}`);
|
|
42
|
+
}, 80);
|
|
43
|
+
},
|
|
44
|
+
stop(ok) {
|
|
45
|
+
if (id)
|
|
46
|
+
clearInterval(id);
|
|
47
|
+
const icon = ok ? `${GREEN}✓${R}` : `${RED}✗${R}`;
|
|
48
|
+
process.stdout.write(`\r ${icon} ${msg}\n`);
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export function step(msg) {
|
|
53
|
+
console.log(` ${DIM}→${R} ${msg}`);
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=print.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"print.js","sourceRoot":"","sources":["../../src/lib/print.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tapflow-dir.d.ts","sourceRoot":"","sources":["../../src/lib/tapflow-dir.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW,QAA8B,CAAA;AAEtD,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { mkdirSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
export const TAPFLOW_DIR = join(homedir(), '.tapflow');
|
|
5
|
+
export function ensureTapflowDir() {
|
|
6
|
+
mkdirSync(TAPFLOW_DIR, { recursive: true });
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=tapflow-dir.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tapflow-dir.js","sourceRoot":"","sources":["../../src/lib/tapflow-dir.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAA;AAEtD,MAAM,UAAU,gBAAgB;IAC9B,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;AAC7C,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tapflow",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.2",
|
|
4
4
|
"description": "Self-hosted iOS/Android simulator streaming for QA teams",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ios",
|
|
@@ -45,10 +45,11 @@
|
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"cac": "^6.7.14",
|
|
47
47
|
"ws": "^8.0.0",
|
|
48
|
-
"
|
|
49
|
-
"@
|
|
50
|
-
"@
|
|
51
|
-
"@
|
|
48
|
+
"zod": "^4.4.3",
|
|
49
|
+
"@tapflowio/agent-core": "0.1.0-alpha.2",
|
|
50
|
+
"@tapflowio/android-agent": "0.1.0-alpha.2",
|
|
51
|
+
"@tapflowio/ios-agent": "0.1.0-alpha.2",
|
|
52
|
+
"@tapflowio/relay": "0.1.0-alpha.2"
|
|
52
53
|
},
|
|
53
54
|
"devDependencies": {
|
|
54
55
|
"@types/node": "^20.0.0",
|
|
@@ -59,6 +60,7 @@
|
|
|
59
60
|
},
|
|
60
61
|
"scripts": {
|
|
61
62
|
"build": "tsc",
|
|
63
|
+
"typecheck": "tsc --noEmit",
|
|
62
64
|
"dev": "tsx src/index.ts",
|
|
63
65
|
"test": "vitest run",
|
|
64
66
|
"lint": "eslint src"
|