tapflow 0.1.0-alpha.1 → 0.1.0-alpha.3

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 (66) hide show
  1. package/README.md +29 -35
  2. package/dist/commands/agent-start.d.ts +7 -0
  3. package/dist/commands/agent-start.d.ts.map +1 -0
  4. package/dist/commands/agent-start.js +78 -0
  5. package/dist/commands/agent-start.js.map +1 -0
  6. package/dist/commands/boot.d.ts +2 -0
  7. package/dist/commands/boot.d.ts.map +1 -0
  8. package/dist/commands/boot.js +47 -0
  9. package/dist/commands/boot.js.map +1 -0
  10. package/dist/commands/devices.d.ts +2 -0
  11. package/dist/commands/devices.d.ts.map +1 -0
  12. package/dist/commands/devices.js +83 -0
  13. package/dist/commands/devices.js.map +1 -0
  14. package/dist/commands/doctor.d.ts +2 -0
  15. package/dist/commands/doctor.d.ts.map +1 -0
  16. package/dist/commands/doctor.js +46 -0
  17. package/dist/commands/doctor.js.map +1 -0
  18. package/dist/commands/init.d.ts +5 -0
  19. package/dist/commands/init.d.ts.map +1 -0
  20. package/dist/commands/init.js +64 -0
  21. package/dist/commands/init.js.map +1 -0
  22. package/dist/commands/logs.d.ts +5 -0
  23. package/dist/commands/logs.d.ts.map +1 -0
  24. package/dist/commands/logs.js +22 -0
  25. package/dist/commands/logs.js.map +1 -0
  26. package/dist/commands/relay-start.d.ts +5 -0
  27. package/dist/commands/relay-start.d.ts.map +1 -0
  28. package/dist/commands/relay-start.js +26 -0
  29. package/dist/commands/relay-start.js.map +1 -0
  30. package/dist/commands/reset.d.ts +2 -0
  31. package/dist/commands/reset.d.ts.map +1 -0
  32. package/dist/commands/reset.js +49 -0
  33. package/dist/commands/reset.js.map +1 -0
  34. package/dist/commands/start.d.ts +6 -0
  35. package/dist/commands/start.d.ts.map +1 -0
  36. package/dist/commands/start.js +79 -0
  37. package/dist/commands/start.js.map +1 -0
  38. package/dist/commands/status.d.ts +4 -0
  39. package/dist/commands/status.d.ts.map +1 -0
  40. package/dist/commands/status.js +58 -0
  41. package/dist/commands/status.js.map +1 -0
  42. package/dist/index.d.ts +2 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +70 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/lib/doctor.d.ts +13 -0
  47. package/dist/lib/doctor.d.ts.map +1 -0
  48. package/dist/lib/doctor.js +119 -0
  49. package/dist/lib/doctor.js.map +1 -0
  50. package/dist/lib/ios-boot.d.ts +3 -0
  51. package/dist/lib/ios-boot.d.ts.map +1 -0
  52. package/dist/lib/ios-boot.js +44 -0
  53. package/dist/lib/ios-boot.js.map +1 -0
  54. package/dist/lib/platform.d.ts +2 -0
  55. package/dist/lib/platform.d.ts.map +1 -0
  56. package/dist/lib/platform.js +10 -0
  57. package/dist/lib/platform.js.map +1 -0
  58. package/dist/lib/print.d.ts +13 -0
  59. package/dist/lib/print.d.ts.map +1 -0
  60. package/dist/lib/print.js +55 -0
  61. package/dist/lib/print.js.map +1 -0
  62. package/dist/lib/tapflow-dir.d.ts +3 -0
  63. package/dist/lib/tapflow-dir.d.ts.map +1 -0
  64. package/dist/lib/tapflow-dir.js +8 -0
  65. package/dist/lib/tapflow-dir.js.map +1 -0
  66. package/package.json +7 -5
@@ -0,0 +1,49 @@
1
+ import { execSync } from 'node:child_process';
2
+ import * as readline from 'node:readline/promises';
3
+ import { stdin as input, stdout as output } from 'node:process';
4
+ import { banner, step } from '../lib/print.js';
5
+ export async function cmdReset() {
6
+ const rl = readline.createInterface({ input, output });
7
+ const answer = await rl.question('This will shut down all simulators and emulators (no data loss). Continue? [y/N] ');
8
+ rl.close();
9
+ if (!answer.trim().toLowerCase().startsWith('y')) {
10
+ console.log('\n Aborted.\n');
11
+ return;
12
+ }
13
+ // iOS
14
+ if (process.platform === 'darwin') {
15
+ try {
16
+ execSync('xcrun simctl shutdown all', { stdio: 'pipe' });
17
+ step('iOS: all simulators shut down.');
18
+ }
19
+ catch {
20
+ step('iOS: no simulators to shut down.');
21
+ }
22
+ }
23
+ // Android
24
+ try {
25
+ execSync('which adb', { stdio: 'pipe' });
26
+ const out = execSync('adb devices', { encoding: 'utf8', stdio: 'pipe' });
27
+ const emulators = out.trim().split('\n').slice(1)
28
+ .filter((l) => l.startsWith('emulator-'))
29
+ .map((l) => l.split('\t')[0]?.trim() ?? '')
30
+ .filter(Boolean);
31
+ if (emulators.length === 0) {
32
+ step('Android: no running emulators.');
33
+ }
34
+ else {
35
+ for (const serial of emulators) {
36
+ try {
37
+ execSync(`adb -s ${serial} emu kill`, { stdio: 'pipe' });
38
+ step(`Android: ${serial} shut down.`);
39
+ }
40
+ catch {
41
+ step(`Android: could not shut down ${serial}.`);
42
+ }
43
+ }
44
+ }
45
+ }
46
+ catch { /* adb not available */ }
47
+ banner('success', 'RESET COMPLETE');
48
+ }
49
+ //# sourceMappingURL=reset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reset.js","sourceRoot":"","sources":["../../src/commands/reset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC7C,OAAO,KAAK,QAAQ,MAAM,wBAAwB,CAAA;AAClD,OAAO,EAAE,KAAK,IAAI,KAAK,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,cAAc,CAAA;AAC/D,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AAE9C,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;IACtD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAC9B,mFAAmF,CACpF,CAAA;IACD,EAAE,CAAC,KAAK,EAAE,CAAA;IAEV,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAA;QAC7B,OAAM;IACR,CAAC;IAED,MAAM;IACN,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,IAAI,CAAC;YACH,QAAQ,CAAC,2BAA2B,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;YACxD,IAAI,CAAC,gCAAgC,CAAC,CAAA;QACxC,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,kCAAkC,CAAC,CAAA;QAC1C,CAAC;IACH,CAAC;IAED,UAAU;IACV,IAAI,CAAC;QACH,QAAQ,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;QACxC,MAAM,GAAG,GAAG,QAAQ,CAAC,aAAa,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;QACxE,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;aAC9C,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;aACxC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;aAC1C,MAAM,CAAC,OAAO,CAAC,CAAA;QAElB,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,gCAAgC,CAAC,CAAA;QACxC,CAAC;aAAM,CAAC;YACN,KAAK,MAAM,MAAM,IAAI,SAAS,EAAE,CAAC;gBAC/B,IAAI,CAAC;oBACH,QAAQ,CAAC,UAAU,MAAM,WAAW,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;oBACxD,IAAI,CAAC,YAAY,MAAM,aAAa,CAAC,CAAA;gBACvC,CAAC;gBAAC,MAAM,CAAC;oBACP,IAAI,CAAC,gCAAgC,MAAM,GAAG,CAAC,CAAA;gBACjD,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,uBAAuB,CAAC,CAAC;IAEnC,MAAM,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAA;AACrC,CAAC"}
@@ -0,0 +1,6 @@
1
+ export interface StartOptions {
2
+ device?: string;
3
+ platform?: 'ios' | 'android' | 'all';
4
+ }
5
+ export declare function cmdStart(opts: StartOptions): Promise<void>;
6
+ //# sourceMappingURL=start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,KAAK,CAAA;CACrC;AAID,wBAAsB,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA2EhE"}
@@ -0,0 +1,79 @@
1
+ import { RelayServer, initDb, config } from '@tapflowio/relay';
2
+ import path from 'path';
3
+ import { AndroidAgent } from '@tapflowio/android-agent';
4
+ import { banner, createSpinner, step } from '../lib/print.js';
5
+ import { hasAdb } from '../lib/platform.js';
6
+ import { resolveAndBootIOSDevice } from '../lib/ios-boot.js';
7
+ const RELAY_PORT = 4000;
8
+ export async function cmdStart(opts) {
9
+ const isMac = process.platform === 'darwin';
10
+ const relayUrl = `ws://localhost:${RELAY_PORT}`;
11
+ const explicit = opts.platform;
12
+ const runIOS = explicit === 'ios' || explicit === 'all' || (!explicit && isMac);
13
+ const runAndroid = explicit === 'android' || explicit === 'all' || (!explicit && hasAdb());
14
+ // ── 1. Relay (always local) ───────────────────────────────────────────────
15
+ initDb(path.join(config.server.dataDir, 'tapflow.db'));
16
+ const server = new RelayServer({ port: RELAY_PORT });
17
+ await server.start();
18
+ step(`Relay started on ws://localhost:${RELAY_PORT}`);
19
+ // ── 2. Agent availability check ───────────────────────────────────────────
20
+ if (!runIOS && !runAndroid) {
21
+ banner('success', 'TAPFLOW RELAY READY', [
22
+ `Relay : http://localhost:${RELAY_PORT}`,
23
+ 'No agent environment detected — running relay only.',
24
+ `Connect a Mac agent: tapflow agent start --relay ws://<this-ip>:${RELAY_PORT}`,
25
+ 'Press Ctrl+C to stop.',
26
+ ]);
27
+ process.on('SIGINT', () => process.exit(0));
28
+ return;
29
+ }
30
+ const agents = [];
31
+ // ── 3. iOS Agent ──────────────────────────────────────────────────────────
32
+ if (runIOS) {
33
+ const iosAgent = await resolveAndBootIOSDevice(opts.device);
34
+ const iosSpinner = createSpinner('Connecting iOS agent…');
35
+ iosSpinner.start();
36
+ try {
37
+ await iosAgent.connect(relayUrl);
38
+ iosSpinner.stop(true);
39
+ agents.push(iosAgent);
40
+ }
41
+ catch (e) {
42
+ iosSpinner.stop(false);
43
+ banner('error', 'IOS CONNECTION FAILED', [e.message]);
44
+ process.exit(1);
45
+ }
46
+ }
47
+ // ── 4. Android Agent ──────────────────────────────────────────────────────
48
+ if (runAndroid) {
49
+ const androidAgent = new AndroidAgent({ deviceFilter: opts.device });
50
+ const androidSpinner = createSpinner('Connecting Android agent…');
51
+ androidSpinner.start();
52
+ try {
53
+ await androidAgent.connect(relayUrl);
54
+ androidSpinner.stop(true);
55
+ agents.push(androidAgent);
56
+ }
57
+ catch (e) {
58
+ androidSpinner.stop(false);
59
+ // Android 연결 실패 시 iOS가 이미 연결됐으면 경고만, 아니면 종료
60
+ if (runIOS && agents.length > 0) {
61
+ console.log(` ⚠ Android: ${e.message}`);
62
+ }
63
+ else {
64
+ banner('error', 'ANDROID CONNECTION FAILED', [e.message]);
65
+ process.exit(1);
66
+ }
67
+ }
68
+ }
69
+ banner('success', 'TAPFLOW READY', [
70
+ `Relay : http://localhost:${RELAY_PORT}`,
71
+ `Open http://localhost:${RELAY_PORT} in your browser.`,
72
+ 'Press Ctrl+C to stop.',
73
+ ]);
74
+ process.on('SIGINT', () => {
75
+ agents.forEach((a) => a.disconnect());
76
+ process.exit(0);
77
+ });
78
+ }
79
+ //# 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,4 @@
1
+ export declare function cmdStatus(opts: {
2
+ relay?: string;
3
+ }): Promise<void>;
4
+ //# sourceMappingURL=status.d.ts.map
@@ -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,CA6DvE"}
@@ -0,0 +1,58 @@
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
+ const platformLabel = session.platform === 'ios' ? 'iOS' : session.platform === 'android' ? 'Android' : session.platform;
30
+ const platformSuffix = platformLabel ? ` ${DIM}(${platformLabel})${R}` : '';
31
+ console.log(` ${BOLD}${GREEN}●${R} ${BOLD}${session.agentName}${R}${platformSuffix}`);
32
+ for (const device of session.devices ?? []) {
33
+ const occupied = !!device.joinedBy;
34
+ const dot = occupied ? `${YELLOW}◉${R}` : `${DIM}○${R}`;
35
+ const who = occupied ? ` ${DIM}← ${device.joinedBy}${R}` : '';
36
+ console.log(` ${dot} ${device.name}${who}`);
37
+ totalDevices++;
38
+ if (occupied)
39
+ activeSessions++;
40
+ }
41
+ console.log();
42
+ }
43
+ console.log(` ${DIM}${sessions.length} agent(s) · ${totalDevices} device(s) · ${activeSessions} active session(s)${R}\n`);
44
+ }
45
+ resolve();
46
+ }
47
+ catch { /* ignore non-agents:listed messages */ }
48
+ });
49
+ ws.on('error', (err) => {
50
+ clearTimeout(timeout);
51
+ reject(err);
52
+ });
53
+ }).catch((err) => {
54
+ console.error(`\n ${RED}✗${R} ${err.message}\n`);
55
+ process.exit(1);
56
+ });
57
+ }
58
+ //# 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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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -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,70 @@
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
+ process.on('unhandledRejection', (err) => {
13
+ console.error(err instanceof Error ? err.message : String(err));
14
+ process.exit(1);
15
+ });
16
+ const cli = cac('tapflow');
17
+ cli
18
+ .command('init', 'Create the first admin account on the relay')
19
+ .option('--relay <url>', 'Relay URL (default: http://localhost:4000)')
20
+ .action((opts) => cmdInit(opts));
21
+ cli
22
+ .command('doctor', 'Check system prerequisites')
23
+ .action(() => cmdDoctor());
24
+ cli
25
+ .command('devices', 'List available iOS simulators and Android AVDs')
26
+ .action(() => cmdDevices());
27
+ cli
28
+ .command('boot <name>', 'Boot a simulator by name or UDID')
29
+ .action((name) => cmdBoot(name));
30
+ cli
31
+ .command('start', 'Start relay and available agents locally (local dev shortcut)')
32
+ .option('--platform <platform>', 'Platform to start: ios | android | all (default: auto-detect)')
33
+ .option('--device <name>', 'iOS Simulator name or UDID to use')
34
+ .action((opts) => cmdStart(opts));
35
+ cli
36
+ .command('relay <subcommand>', 'Relay server commands (subcommand: start)')
37
+ .option('--port <n>', 'Port to listen on (default: 4000)')
38
+ .action((subcommand, opts) => {
39
+ if (subcommand === 'start')
40
+ return cmdRelayStart(opts);
41
+ console.error(`Unknown subcommand: relay ${subcommand}`);
42
+ process.exit(1);
43
+ });
44
+ cli
45
+ .command('agent <subcommand>', 'Agent commands (subcommand: start)')
46
+ .option('--relay <url>', 'Relay WebSocket URL (default: ws://localhost:4000)')
47
+ .option('--platform <platform>', 'Platform to start: ios | android | all (default: auto-detect)')
48
+ .option('--device <name>', 'iOS Simulator name or UDID to use')
49
+ .action((subcommand, opts) => {
50
+ if (subcommand === 'start')
51
+ return cmdAgentStart(opts);
52
+ console.error(`Unknown subcommand: agent ${subcommand}`);
53
+ process.exit(1);
54
+ });
55
+ cli
56
+ .command('reset', 'Shut down all simulators')
57
+ .action(() => cmdReset());
58
+ cli
59
+ .command('status', 'Show connected agents, devices, and active sessions')
60
+ .option('--relay <url>', 'Relay URL (default: ws://localhost:4000)')
61
+ .action((opts) => cmdStatus(opts));
62
+ cli
63
+ .command('logs', 'Show recent relay log entries')
64
+ .option('--relay <url>', 'Relay URL (default: http://localhost:4000)')
65
+ .option('--lines <n>', 'Number of lines to show (default: 100)', { default: 100 })
66
+ .action((opts) => cmdLogs(opts));
67
+ cli.help();
68
+ cli.version('0.1.0');
69
+ cli.parse();
70
+ //# 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,13 @@
1
+ export interface DoctorCheck {
2
+ label: string;
3
+ ok: boolean;
4
+ warn?: boolean;
5
+ detail?: string;
6
+ }
7
+ export interface DoctorResult {
8
+ common: DoctorCheck[];
9
+ ios: DoctorCheck[] | null;
10
+ android: DoctorCheck[] | null;
11
+ }
12
+ export declare function runDoctorChecks(): Promise<DoctorResult>;
13
+ //# 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,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,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,119 @@
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
+ warn: true,
90
+ detail: hint
91
+ ? `No running emulator. Run: emulator @${hint}`
92
+ : 'No running emulator. Start an AVD from Android Studio > Device Manager.',
93
+ };
94
+ }
95
+ const serial = emulator.split('\t')[0]?.trim() ?? '';
96
+ try {
97
+ const avdName = execSync(`adb -s ${serial} emu avd name`, { encoding: 'utf8', stdio: 'pipe' })
98
+ .split('\n')[0]
99
+ ?.trim() ?? serial;
100
+ return { label: `AVD: ${avdName}`, ok: true };
101
+ }
102
+ catch {
103
+ return { label: `AVD: ${serial}`, ok: true };
104
+ }
105
+ }
106
+ catch {
107
+ return { label: 'AVD', ok: false, detail: 'Could not query running emulators.' };
108
+ }
109
+ }
110
+ function listAvdHint() {
111
+ try {
112
+ const out = execSync('emulator -list-avds', { encoding: 'utf8', stdio: 'pipe' }).trim();
113
+ return out.split('\n')[0]?.trim() || null;
114
+ }
115
+ catch {
116
+ return null;
117
+ }
118
+ }
119
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/lib/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAe7C,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAA;IAC3C,MAAM,OAAO,GAAG,UAAU,EAAE,CAAA;IAE5B,OAAO;QACL,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;QAC5B,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,EAAE,WAAW,EAAE,EAAE,oBAAoB,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI;QACzE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI;KACzE,CAAA;AACH,CAAC;AAED,SAAS,UAAU;IACjB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,QAAQ,CAAC,qBAAqB,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAA;QAClG,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,EAAE,CAAA;QAC/D,OAAO,EAAE,KAAK,EAAE,SAAS,OAAO,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAA;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,KAAK,EAAE,OAAO;YACd,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,6EAA6E;SACtF,CAAA;IACH,CAAC;AACH,CAAC;AAED,SAAS,WAAW;IAClB,IAAI,CAAC;QACH,QAAQ,CAAC,0BAA0B,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;QACvD,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,EAAE,IAAI,EAAE,CAAA;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,KAAK,EAAE,cAAc;YACrB,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,6BAA6B;SACtC,CAAA;IACH,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB;IAC3B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,QAAQ,CAAC,kCAAkC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;QAC7F,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAsF,CAAA;QACjH,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAA;QACrD,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAA;QAC3D,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,EAAE,KAAK,EAAE,qBAAqB,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAA;QAChE,CAAC;QACD,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,UAAU,CAAC,CAAA;QAChE,MAAM,IAAI,GAAG,SAAS;YACpB,CAAC,CAAC,sBAAsB,SAAS,CAAC,IAAI,GAAG;YACzC,CAAC,CAAC,gFAAgF,CAAA;QACpF,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAA;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,iDAAiD,EAAE,CAAA;IACrG,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB;IACvB,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAA;IAC/B,MAAM,CAAC,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,CAAA;IAChD,MAAM,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAA;IAC9B,OAAO;QACL,KAAK,EAAE,QAAQ,OAAO,EAAE;QACxB,EAAE;QACF,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,sDAAsD;KAChF,CAAA;AACH,CAAC;AAED,SAAS,UAAU;IACjB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;QAC9E,OAAO,IAAI,IAAI,IAAI,CAAA;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO,EAAE,KAAK,EAAE,cAAc,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAA;AAClD,CAAC;AAED,SAAS,cAAc;IACrB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,QAAQ,CAAC,aAAa,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;QACxE,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QAC7D,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAA;QAC7D,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,GAAG,WAAW,EAAE,CAAA;YAC1B,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,EAAE,EAAE,KAAK;gBACT,IAAI,EAAE,IAAI;gBACV,MAAM,EAAE,IAAI;oBACV,CAAC,CAAC,uCAAuC,IAAI,EAAE;oBAC/C,CAAC,CAAC,yEAAyE;aAC9E,CAAA;QACH,CAAC;QAED,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;QACpD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,QAAQ,CAAC,UAAU,MAAM,eAAe,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;iBAC3F,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBACf,EAAE,IAAI,EAAE,IAAI,MAAM,CAAA;YACpB,OAAO,EAAE,KAAK,EAAE,QAAQ,OAAO,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAA;QAC/C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,KAAK,EAAE,QAAQ,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAA;QAC9C,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,oCAAoC,EAAE,CAAA;IAClF,CAAC;AACH,CAAC;AAED,SAAS,WAAW;IAClB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,QAAQ,CAAC,qBAAqB,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;QACvF,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAA;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { IOSAgent } from '@tapflowio/ios-agent';
2
+ export declare function resolveAndBootIOSDevice(deviceFilter?: string): Promise<IOSAgent>;
3
+ //# sourceMappingURL=ios-boot.d.ts.map
@@ -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,2 @@
1
+ export declare function hasAdb(): boolean;
2
+ //# sourceMappingURL=platform.d.ts.map
@@ -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,10 @@
1
+ import { execSync } from 'node:child_process';
2
+ export function hasAdb() {
3
+ try {
4
+ return execSync('which adb', { encoding: 'utf8', stdio: 'pipe' }).trim().length > 0;
5
+ }
6
+ catch {
7
+ return false;
8
+ }
9
+ }
10
+ //# sourceMappingURL=platform.js.map
@@ -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,3 @@
1
+ export declare const TAPFLOW_DIR: string;
2
+ export declare function ensureTapflowDir(): void;
3
+ //# sourceMappingURL=tapflow-dir.d.ts.map