appshot-cli 0.8.0 → 0.8.5
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 +101 -4
- package/dist/cli.js +18 -3
- package/dist/cli.js.map +1 -1
- package/dist/commands/device.d.ts +3 -0
- package/dist/commands/device.d.ts.map +1 -0
- package/dist/commands/device.js +414 -0
- package/dist/commands/device.js.map +1 -0
- package/dist/commands/unwatch.d.ts +3 -0
- package/dist/commands/unwatch.d.ts.map +1 -0
- package/dist/commands/unwatch.js +53 -0
- package/dist/commands/unwatch.js.map +1 -0
- package/dist/commands/watch-status.d.ts +3 -0
- package/dist/commands/watch-status.d.ts.map +1 -0
- package/dist/commands/watch-status.js +116 -0
- package/dist/commands/watch-status.js.map +1 -0
- package/dist/commands/watch.d.ts +3 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +322 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/core/compose.d.ts.map +1 -1
- package/dist/core/compose.js +4 -0
- package/dist/core/compose.js.map +1 -1
- package/dist/services/compose-bridge.d.ts +47 -0
- package/dist/services/compose-bridge.d.ts.map +1 -0
- package/dist/services/compose-bridge.js +222 -0
- package/dist/services/compose-bridge.js.map +1 -0
- package/dist/services/device-manager.d.ts +14 -0
- package/dist/services/device-manager.d.ts.map +1 -0
- package/dist/services/device-manager.js +244 -0
- package/dist/services/device-manager.js.map +1 -0
- package/dist/services/doctor.d.ts +1 -0
- package/dist/services/doctor.d.ts.map +1 -1
- package/dist/services/doctor.js +94 -2
- package/dist/services/doctor.js.map +1 -1
- package/dist/services/processing-queue.d.ts +32 -0
- package/dist/services/processing-queue.d.ts.map +1 -0
- package/dist/services/processing-queue.js +150 -0
- package/dist/services/processing-queue.js.map +1 -0
- package/dist/services/screenshot-router.d.ts +31 -0
- package/dist/services/screenshot-router.d.ts.map +1 -0
- package/dist/services/screenshot-router.js +227 -0
- package/dist/services/screenshot-router.js.map +1 -0
- package/dist/services/system-requirements.d.ts +26 -0
- package/dist/services/system-requirements.d.ts.map +1 -0
- package/dist/services/system-requirements.js +189 -0
- package/dist/services/system-requirements.js.map +1 -0
- package/dist/services/watch-service.d.ts +39 -0
- package/dist/services/watch-service.d.ts.map +1 -0
- package/dist/services/watch-service.js +293 -0
- package/dist/services/watch-service.js.map +1 -0
- package/dist/types/device.d.ts +52 -0
- package/dist/types/device.d.ts.map +1 -0
- package/dist/types/device.js +2 -0
- package/dist/types/device.js.map +1 -0
- package/dist/types.d.ts +9 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/pid-manager.d.ts +11 -0
- package/dist/utils/pid-manager.d.ts.map +1 -0
- package/dist/utils/pid-manager.js +76 -0
- package/dist/utils/pid-manager.js.map +1 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -4,11 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
[](https://github.com/chrisvanbuskirk/appshot/actions/workflows/ci.yml)
|
|
6
6
|
[](https://www.npmjs.com/package/appshot-cli)
|
|
7
|
+
[](https://www.npmjs.com/package/appshot-cli)
|
|
8
|
+
[](https://nodejs.org)
|
|
7
9
|
[](https://opensource.org/licenses/MIT)
|
|
8
10
|
|
|
9
|
-
🆕 **Version 0.8.
|
|
11
|
+
🆕 **Version 0.8.5** - **Watch Mode & Device Capture** - File system monitoring with auto-processing and direct iOS simulator capture!
|
|
10
12
|
|
|
11
|
-
> ⚠️ **NEW in v0.8.
|
|
13
|
+
> ⚠️ **NEW in v0.8.5**: `appshot watch` for automatic screenshot processing and `appshot device` for iOS simulator capture (macOS only). Includes duplicate detection and background service management.
|
|
12
14
|
|
|
13
15
|
> ⚠️ **BREAKING CHANGE in v0.4.0**: Output structure now always uses language subdirectories.
|
|
14
16
|
> Single language builds now output to `final/device/lang/` instead of `final/device/`.
|
|
@@ -64,6 +66,8 @@ Appshot is the only **agent-first CLI tool** designed for automated App Store sc
|
|
|
64
66
|
- 🎭 **Frame-Only Mode** - Quick device framing with transparent backgrounds (no gradients/captions)
|
|
65
67
|
- 📏 **App Store Specs** - All official resolutions with validation and presets
|
|
66
68
|
- 🔄 **Orientation Detection** - Intelligently handles both portrait and landscape
|
|
69
|
+
- 👁️ **Watch Mode** - File system monitoring with auto-processing (macOS)
|
|
70
|
+
- 📱 **Device Capture** - Direct capture from iOS simulators (macOS)
|
|
67
71
|
- ⚡ **Parallel Processing** - Configurable concurrency for large batches
|
|
68
72
|
- 🔍 **Caption Autocomplete** - Intelligent suggestions with fuzzy search and learning
|
|
69
73
|
- 🔬 **Dry-Run Mode** - Preview what would be built without generating images
|
|
@@ -130,6 +134,24 @@ appshot frame ./screenshots --recursive
|
|
|
130
134
|
# ✨ Framed PNGs with transparent backgrounds ready!
|
|
131
135
|
```
|
|
132
136
|
|
|
137
|
+
### Watch Mode (macOS)
|
|
138
|
+
|
|
139
|
+
Automatically process screenshots as they're added:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Start watching for new screenshots
|
|
143
|
+
appshot watch start --process --background
|
|
144
|
+
|
|
145
|
+
# Capture from simulator (auto-processes via watch)
|
|
146
|
+
appshot device capture
|
|
147
|
+
|
|
148
|
+
# Check status
|
|
149
|
+
appshot watch status
|
|
150
|
+
|
|
151
|
+
# Stop watching
|
|
152
|
+
appshot watch stop
|
|
153
|
+
```
|
|
154
|
+
|
|
133
155
|
### Example Output Structure
|
|
134
156
|
|
|
135
157
|
```
|
|
@@ -983,6 +1005,82 @@ appshot frame ./screenshots --dry-run --verbose
|
|
|
983
1005
|
appshot frame screenshot.png --format jpeg
|
|
984
1006
|
```
|
|
985
1007
|
|
|
1008
|
+
### `appshot device` (macOS only)
|
|
1009
|
+
|
|
1010
|
+
Capture screenshots from iOS simulators.
|
|
1011
|
+
|
|
1012
|
+
```bash
|
|
1013
|
+
appshot device <command> [options]
|
|
1014
|
+
```
|
|
1015
|
+
|
|
1016
|
+
**Commands:**
|
|
1017
|
+
- `capture` - Capture screenshot from device
|
|
1018
|
+
- `list` - List available devices
|
|
1019
|
+
- `prepare` - Boot simulators
|
|
1020
|
+
|
|
1021
|
+
**Capture Options:**
|
|
1022
|
+
- `-d, --device <name>` - Device name or alias
|
|
1023
|
+
- `--all` - Capture from all devices
|
|
1024
|
+
- `--simulators` - Filter simulators
|
|
1025
|
+
- `--booted` - Currently booted simulators
|
|
1026
|
+
- `--process` - Auto-process with frames
|
|
1027
|
+
- `--app <bundleId>` - Launch app before capture
|
|
1028
|
+
|
|
1029
|
+
**Examples:**
|
|
1030
|
+
```bash
|
|
1031
|
+
# List devices
|
|
1032
|
+
appshot device list
|
|
1033
|
+
|
|
1034
|
+
# Interactive capture
|
|
1035
|
+
appshot device capture
|
|
1036
|
+
|
|
1037
|
+
# Capture from specific device
|
|
1038
|
+
appshot device capture --device "iPhone 15 Pro"
|
|
1039
|
+
|
|
1040
|
+
# Capture and process
|
|
1041
|
+
appshot device capture --process
|
|
1042
|
+
```
|
|
1043
|
+
|
|
1044
|
+
### `appshot watch` (macOS only)
|
|
1045
|
+
|
|
1046
|
+
Monitor directories for new screenshots with automatic processing.
|
|
1047
|
+
|
|
1048
|
+
```bash
|
|
1049
|
+
appshot watch <command> [options]
|
|
1050
|
+
```
|
|
1051
|
+
|
|
1052
|
+
**Commands:**
|
|
1053
|
+
- `start` - Start watching directories
|
|
1054
|
+
- `stop` - Stop the watch service
|
|
1055
|
+
- `status` - Check service status
|
|
1056
|
+
- `setup` - Interactive configuration
|
|
1057
|
+
|
|
1058
|
+
**Start Options:**
|
|
1059
|
+
- `-d, --dirs <paths...>` - Directories to watch
|
|
1060
|
+
- `--devices <names...>` - Device names for processing
|
|
1061
|
+
- `--process` - Auto-process with frames
|
|
1062
|
+
- `--frame-only` - Frames only (no gradient/caption)
|
|
1063
|
+
- `--background` - Run in background
|
|
1064
|
+
- `--verbose` - Detailed output
|
|
1065
|
+
|
|
1066
|
+
**Examples:**
|
|
1067
|
+
```bash
|
|
1068
|
+
# Interactive setup
|
|
1069
|
+
appshot watch setup
|
|
1070
|
+
|
|
1071
|
+
# Start in background with processing
|
|
1072
|
+
appshot watch start --process --background
|
|
1073
|
+
|
|
1074
|
+
# Watch multiple directories
|
|
1075
|
+
appshot watch start --dirs ./screenshots ./downloads
|
|
1076
|
+
|
|
1077
|
+
# Check status
|
|
1078
|
+
appshot watch status --verbose
|
|
1079
|
+
|
|
1080
|
+
# Stop watching
|
|
1081
|
+
appshot watch stop
|
|
1082
|
+
```
|
|
1083
|
+
|
|
986
1084
|
### `appshot gradients`
|
|
987
1085
|
|
|
988
1086
|
Manage gradient presets.
|
|
@@ -1946,8 +2044,7 @@ For security vulnerabilities, please see [SECURITY.md](SECURITY.md).
|
|
|
1946
2044
|
### NPM Package
|
|
1947
2045
|
|
|
1948
2046
|
- 📦 [appshot-cli on NPM](https://www.npmjs.com/package/appshot-cli)
|
|
1949
|
-
- 🔄 Latest version: 0.8.
|
|
1950
|
-
- ⬇️ Weekly downloads: 
|
|
2047
|
+
- 🔄 Latest version: 0.8.5
|
|
1951
2048
|
|
|
1952
2049
|
---
|
|
1953
2050
|
|
package/dist/cli.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
+
import { platform } from 'os';
|
|
2
3
|
import pc from 'picocolors';
|
|
3
4
|
import initCmd from './commands/init.js';
|
|
4
5
|
import captionCmd from './commands/caption.js';
|
|
@@ -15,6 +16,10 @@ import fontsCmd from './commands/fonts.js';
|
|
|
15
16
|
import migrateCmd from './commands/migrate.js';
|
|
16
17
|
import { createCleanCommand } from './commands/clean.js';
|
|
17
18
|
import frameCmd from './commands/frame.js';
|
|
19
|
+
import deviceCmd from './commands/device.js';
|
|
20
|
+
import watchCmd from './commands/watch.js';
|
|
21
|
+
import unwatchCmd from './commands/unwatch.js';
|
|
22
|
+
import watchStatusCmd from './commands/watch-status.js';
|
|
18
23
|
const program = new Command();
|
|
19
24
|
program
|
|
20
25
|
.name('appshot')
|
|
@@ -27,7 +32,8 @@ ${pc.bold('Features:')}
|
|
|
27
32
|
• AI-powered translation to 25+ languages
|
|
28
33
|
• Smart caption wrapping and positioning
|
|
29
34
|
• All official App Store resolutions
|
|
30
|
-
•
|
|
35
|
+
• File system watch mode for auto-processing
|
|
36
|
+
• Device capture from simulators/physical devices (macOS)
|
|
31
37
|
|
|
32
38
|
${pc.bold('Quick Start:')}
|
|
33
39
|
$ appshot init # Initialize project
|
|
@@ -40,10 +46,12 @@ ${pc.bold('Common Workflows:')}
|
|
|
40
46
|
$ appshot gradients select # Pick gradient
|
|
41
47
|
$ appshot frame ./screenshots --recursive # Batch frame images
|
|
42
48
|
$ appshot build --preset iphone-6-9,ipad-13 # App Store presets
|
|
43
|
-
$ appshot localize --langs es,fr,de # Batch translate
|
|
49
|
+
$ appshot localize --langs es,fr,de # Batch translate${platform() === 'darwin' ? `
|
|
50
|
+
$ appshot device capture # Capture from simulator/device (macOS)
|
|
51
|
+
$ appshot watch start --process # Auto-process new screenshots` : ''}
|
|
44
52
|
|
|
45
53
|
${pc.dim('Docs: https://github.com/chrisvanbuskirk/appshot')}`)
|
|
46
|
-
.version('0.8.
|
|
54
|
+
.version('0.8.5')
|
|
47
55
|
.addHelpText('after', `\n${pc.bold('Environment Variables:')}
|
|
48
56
|
OPENAI_API_KEY API key for translation features
|
|
49
57
|
APPSHOT_DISABLE_FONT_SCAN Skip system font detection (CI optimization)
|
|
@@ -62,6 +70,13 @@ program.addCommand(fontsCmd());
|
|
|
62
70
|
program.addCommand(localizeCmd());
|
|
63
71
|
program.addCommand(buildCmd());
|
|
64
72
|
program.addCommand(frameCmd());
|
|
73
|
+
// Add device and watch commands only on macOS
|
|
74
|
+
if (platform() === 'darwin') {
|
|
75
|
+
program.addCommand(deviceCmd());
|
|
76
|
+
program.addCommand(watchCmd());
|
|
77
|
+
program.addCommand(unwatchCmd());
|
|
78
|
+
program.addCommand(watchStatusCmd());
|
|
79
|
+
}
|
|
65
80
|
program.addCommand(specsCmd());
|
|
66
81
|
program.addCommand(checkCmd());
|
|
67
82
|
program.addCommand(doctorCmd());
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,OAAO,MAAM,oBAAoB,CAAC;AACzC,OAAO,UAAU,MAAM,uBAAuB,CAAC;AAC/C,OAAO,WAAW,MAAM,wBAAwB,CAAC;AACjD,OAAO,QAAQ,MAAM,qBAAqB,CAAC;AAC3C,OAAO,QAAQ,MAAM,qBAAqB,CAAC;AAC3C,OAAO,QAAQ,MAAM,qBAAqB,CAAC;AAC3C,OAAO,SAAS,MAAM,sBAAsB,CAAC;AAC7C,OAAO,UAAU,MAAM,uBAAuB,CAAC;AAC/C,OAAO,WAAW,MAAM,wBAAwB,CAAC;AACjD,OAAO,QAAQ,MAAM,qBAAqB,CAAC;AAC3C,OAAO,YAAY,MAAM,yBAAyB,CAAC;AACnD,OAAO,QAAQ,MAAM,qBAAqB,CAAC;AAC3C,OAAO,UAAU,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,QAAQ,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../src/commands/device.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAapC,MAAM,CAAC,OAAO,UAAU,aAAa,IAAI,OAAO,CAoR/C"}
|
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { select, confirm } from '@inquirer/prompts';
|
|
3
|
+
import { platform } from 'os';
|
|
4
|
+
import pc from 'picocolors';
|
|
5
|
+
import fs from 'fs/promises';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import { systemRequirements } from '../services/system-requirements.js';
|
|
8
|
+
import { deviceManager } from '../services/device-manager.js';
|
|
9
|
+
import { screenshotRouter } from '../services/screenshot-router.js';
|
|
10
|
+
import { createComposeBridge } from '../services/compose-bridge.js';
|
|
11
|
+
import { loadConfig } from '../core/files.js';
|
|
12
|
+
export default function deviceCommand() {
|
|
13
|
+
const cmd = new Command('device')
|
|
14
|
+
.description('Capture screenshots from simulators and physical devices (macOS only)');
|
|
15
|
+
// Capture subcommand
|
|
16
|
+
cmd
|
|
17
|
+
.command('capture')
|
|
18
|
+
.description('Capture screenshot from a device')
|
|
19
|
+
.option('-d, --device <name>', 'Device name or alias')
|
|
20
|
+
.option('--all', 'Capture from all connected/booted devices')
|
|
21
|
+
.option('--physical', 'Physical devices only')
|
|
22
|
+
.option('--simulators', 'Simulators only')
|
|
23
|
+
.option('--booted', 'Use currently booted simulator')
|
|
24
|
+
.option('--process', 'Auto-process with frames and gradients')
|
|
25
|
+
.option('--app <bundleId>', 'Launch app before capture')
|
|
26
|
+
.option('--screen <name>', 'Screen name for filename')
|
|
27
|
+
.action(async (options) => {
|
|
28
|
+
// Check platform first
|
|
29
|
+
if (platform() !== 'darwin') {
|
|
30
|
+
console.error(pc.red('❌ Device features are only available on macOS'));
|
|
31
|
+
console.error(pc.yellow('\nThis feature requires:'));
|
|
32
|
+
console.error(pc.dim(' • macOS operating system'));
|
|
33
|
+
console.error(pc.dim(' • Xcode or Xcode Command Line Tools'));
|
|
34
|
+
console.error(pc.dim(' • iOS simulators or connected iOS devices'));
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
// Check system requirements
|
|
38
|
+
const hasRequirements = await systemRequirements.ensureRequirements();
|
|
39
|
+
if (!hasRequirements) {
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
// Get list of devices
|
|
44
|
+
let devices = await deviceManager.listAllDevices();
|
|
45
|
+
// Apply filters
|
|
46
|
+
if (options.physical) {
|
|
47
|
+
devices = devices.filter(d => d.type === 'physical');
|
|
48
|
+
}
|
|
49
|
+
else if (options.simulators) {
|
|
50
|
+
devices = devices.filter(d => d.type === 'simulator');
|
|
51
|
+
}
|
|
52
|
+
if (options.booted) {
|
|
53
|
+
devices = devices.filter(d => d.state === 'booted');
|
|
54
|
+
if (devices.length === 0) {
|
|
55
|
+
console.error(pc.red('❌ No booted simulators found'));
|
|
56
|
+
console.log(pc.dim(' Boot a simulator first or use --device to select one'));
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Handle device selection
|
|
61
|
+
let selectedDevices = [];
|
|
62
|
+
if (options.all) {
|
|
63
|
+
// Capture from all available devices
|
|
64
|
+
selectedDevices = devices.filter(d => d.type === 'physical' ? d.state === 'connected' : true);
|
|
65
|
+
if (selectedDevices.length === 0) {
|
|
66
|
+
console.error(pc.red('❌ No available devices found'));
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else if (options.device) {
|
|
71
|
+
// Find device by name or alias
|
|
72
|
+
const device = await findDevice(devices, options.device);
|
|
73
|
+
if (!device) {
|
|
74
|
+
console.error(pc.red(`❌ Device not found: ${options.device}`));
|
|
75
|
+
console.log(pc.dim(' Use "appshot device list" to see available devices'));
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
selectedDevices = [device];
|
|
79
|
+
}
|
|
80
|
+
else if (options.booted && devices.length === 1) {
|
|
81
|
+
// Single booted device, use it automatically
|
|
82
|
+
selectedDevices = devices;
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
// Interactive selection
|
|
86
|
+
const device = await selectDevice(devices);
|
|
87
|
+
if (!device) {
|
|
88
|
+
console.log(pc.yellow('Cancelled'));
|
|
89
|
+
process.exit(0);
|
|
90
|
+
}
|
|
91
|
+
selectedDevices = [device];
|
|
92
|
+
}
|
|
93
|
+
// Launch app if specified
|
|
94
|
+
if (options.app) {
|
|
95
|
+
for (const device of selectedDevices) {
|
|
96
|
+
try {
|
|
97
|
+
console.log(pc.cyan(`Launching ${options.app} on ${device.name}...`));
|
|
98
|
+
await deviceManager.launchApp({
|
|
99
|
+
device,
|
|
100
|
+
bundleId: options.app
|
|
101
|
+
});
|
|
102
|
+
// Wait for app to load
|
|
103
|
+
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
console.error(pc.red(`❌ Failed to launch app on ${device.name}:`), error);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// Capture screenshots
|
|
111
|
+
for (const device of selectedDevices) {
|
|
112
|
+
await captureFromDevice(device, {
|
|
113
|
+
screenName: options.screen,
|
|
114
|
+
process: options.process
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
console.log(pc.green('\n✅ Screenshot capture complete!'));
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
console.error(pc.red('❌ Error:'), error);
|
|
121
|
+
process.exit(1);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
// List subcommand
|
|
125
|
+
cmd
|
|
126
|
+
.command('list')
|
|
127
|
+
.description('List available devices')
|
|
128
|
+
.option('--json', 'Output as JSON')
|
|
129
|
+
.action(async (options) => {
|
|
130
|
+
// Check platform first
|
|
131
|
+
if (platform() !== 'darwin') {
|
|
132
|
+
console.error(pc.red('❌ Device features are only available on macOS'));
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
const hasRequirements = await systemRequirements.ensureRequirements();
|
|
136
|
+
if (!hasRequirements) {
|
|
137
|
+
process.exit(1);
|
|
138
|
+
}
|
|
139
|
+
try {
|
|
140
|
+
const devices = await deviceManager.listAllDevices();
|
|
141
|
+
if (options.json) {
|
|
142
|
+
console.log(JSON.stringify(devices, null, 2));
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
// Group devices
|
|
146
|
+
const physical = devices.filter(d => d.type === 'physical');
|
|
147
|
+
const simulators = devices.filter(d => d.type === 'simulator');
|
|
148
|
+
console.log(pc.bold('\n📱 Available Devices:\n'));
|
|
149
|
+
if (physical.length > 0) {
|
|
150
|
+
console.log(pc.bold('Physical Devices:'));
|
|
151
|
+
for (const device of physical) {
|
|
152
|
+
const status = device.state === 'connected' ? pc.green('🟢') : pc.gray('⚪');
|
|
153
|
+
const info = `${device.displaySize || ''} ${device.resolution || ''}`.trim();
|
|
154
|
+
console.log(` ${status} ${device.name.padEnd(30)} ${device.osVersion || ''} ${pc.dim(info)}`);
|
|
155
|
+
}
|
|
156
|
+
console.log();
|
|
157
|
+
}
|
|
158
|
+
if (simulators.length > 0) {
|
|
159
|
+
console.log(pc.bold('Simulators:'));
|
|
160
|
+
// Group by category
|
|
161
|
+
const iphones = simulators.filter(d => d.category === 'iphone');
|
|
162
|
+
const ipads = simulators.filter(d => d.category === 'ipad');
|
|
163
|
+
const watches = simulators.filter(d => d.category === 'watch');
|
|
164
|
+
const others = simulators.filter(d => !['iphone', 'ipad', 'watch'].includes(d.category));
|
|
165
|
+
if (iphones.length > 0) {
|
|
166
|
+
console.log(pc.dim(' iPhone:'));
|
|
167
|
+
for (const device of iphones) {
|
|
168
|
+
const status = device.state === 'booted' ? pc.green('🟢') : pc.gray('⚪');
|
|
169
|
+
const info = `${device.displaySize || ''} ${device.resolution || ''}`.trim();
|
|
170
|
+
console.log(` ${status} ${device.name.padEnd(28)} ${device.osVersion || ''} ${pc.dim(info)}`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
if (ipads.length > 0) {
|
|
174
|
+
console.log(pc.dim(' iPad:'));
|
|
175
|
+
for (const device of ipads) {
|
|
176
|
+
const status = device.state === 'booted' ? pc.green('🟢') : pc.gray('⚪');
|
|
177
|
+
const info = `${device.displaySize || ''} ${device.resolution || ''}`.trim();
|
|
178
|
+
console.log(` ${status} ${device.name.padEnd(28)} ${device.osVersion || ''} ${pc.dim(info)}`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
if (watches.length > 0) {
|
|
182
|
+
console.log(pc.dim(' Apple Watch:'));
|
|
183
|
+
for (const device of watches) {
|
|
184
|
+
const status = device.state === 'booted' ? pc.green('🟢') : pc.gray('⚪');
|
|
185
|
+
const info = `${device.displaySize || ''} ${device.resolution || ''}`.trim();
|
|
186
|
+
console.log(` ${status} ${device.name.padEnd(28)} ${device.osVersion || ''} ${pc.dim(info)}`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if (others.length > 0) {
|
|
190
|
+
console.log(pc.dim(' Other:'));
|
|
191
|
+
for (const device of others) {
|
|
192
|
+
const status = device.state === 'booted' ? pc.green('🟢') : pc.gray('⚪');
|
|
193
|
+
const info = `${device.displaySize || ''} ${device.resolution || ''}`.trim();
|
|
194
|
+
console.log(` ${status} ${device.name.padEnd(28)} ${device.osVersion || ''} ${pc.dim(info)}`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
if (devices.length === 0) {
|
|
199
|
+
console.log(pc.yellow('No devices found'));
|
|
200
|
+
console.log(pc.dim('\nTips:'));
|
|
201
|
+
console.log(pc.dim(' • Connect a physical device via USB'));
|
|
202
|
+
console.log(pc.dim(' • Open Xcode > Window > Devices and Simulators'));
|
|
203
|
+
console.log(pc.dim(' • Create simulators in Xcode'));
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
console.error(pc.red('❌ Error listing devices:'), error);
|
|
208
|
+
process.exit(1);
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
// Prepare subcommand (boot simulators)
|
|
212
|
+
cmd
|
|
213
|
+
.command('prepare')
|
|
214
|
+
.description('Boot required simulators for App Store presets')
|
|
215
|
+
.option('--preset <name>', 'App Store preset (e.g., iphone-6-9,ipad-13)')
|
|
216
|
+
.option('--device <name>', 'Specific device to boot')
|
|
217
|
+
.action(async (options) => {
|
|
218
|
+
// Check platform first
|
|
219
|
+
if (platform() !== 'darwin') {
|
|
220
|
+
console.error(pc.red('❌ Device features are only available on macOS'));
|
|
221
|
+
process.exit(1);
|
|
222
|
+
}
|
|
223
|
+
const hasRequirements = await systemRequirements.ensureRequirements();
|
|
224
|
+
if (!hasRequirements) {
|
|
225
|
+
process.exit(1);
|
|
226
|
+
}
|
|
227
|
+
try {
|
|
228
|
+
const devices = await deviceManager.listSimulators();
|
|
229
|
+
if (options.device) {
|
|
230
|
+
// Boot specific device
|
|
231
|
+
const device = await findDevice(devices, options.device);
|
|
232
|
+
if (!device) {
|
|
233
|
+
console.error(pc.red(`❌ Device not found: ${options.device}`));
|
|
234
|
+
process.exit(1);
|
|
235
|
+
}
|
|
236
|
+
if (device.state === 'booted') {
|
|
237
|
+
console.log(pc.green(`✅ ${device.name} is already booted`));
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
await deviceManager.bootSimulator(device);
|
|
241
|
+
console.log(pc.green(`✅ ${device.name} booted successfully`));
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
else if (options.preset) {
|
|
245
|
+
// Boot devices for preset
|
|
246
|
+
console.log(pc.cyan('🚀 Preparing devices for App Store preset...'));
|
|
247
|
+
// TODO: Implement preset device selection
|
|
248
|
+
console.log(pc.yellow('Preset support coming soon!'));
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
// Interactive selection
|
|
252
|
+
const device = await selectDevice(devices.filter(d => d.state !== 'booted'));
|
|
253
|
+
if (device) {
|
|
254
|
+
await deviceManager.bootSimulator(device);
|
|
255
|
+
console.log(pc.green(`✅ ${device.name} booted successfully`));
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
catch (error) {
|
|
260
|
+
console.error(pc.red('❌ Error:'), error);
|
|
261
|
+
process.exit(1);
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
return cmd;
|
|
265
|
+
}
|
|
266
|
+
async function selectDevice(devices) {
|
|
267
|
+
if (devices.length === 0) {
|
|
268
|
+
console.error(pc.red('No devices available'));
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
// Group devices for better display
|
|
272
|
+
const choices = [];
|
|
273
|
+
// Physical devices
|
|
274
|
+
const physical = devices.filter(d => d.type === 'physical');
|
|
275
|
+
if (physical.length > 0) {
|
|
276
|
+
choices.push({
|
|
277
|
+
name: pc.dim('━━━ 📱 Physical Devices ━━━'),
|
|
278
|
+
value: null,
|
|
279
|
+
disabled: true
|
|
280
|
+
});
|
|
281
|
+
for (const device of physical) {
|
|
282
|
+
const status = device.state === 'connected' ? '🟢' : '⚪';
|
|
283
|
+
const info = device.displaySize ? `• ${device.displaySize}" display` : '';
|
|
284
|
+
choices.push({
|
|
285
|
+
name: `${status} ${device.name.padEnd(30)} ${device.osVersion || ''} ${pc.dim(info)}`,
|
|
286
|
+
value: device
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
// Simulators
|
|
291
|
+
const simulators = devices.filter(d => d.type === 'simulator');
|
|
292
|
+
if (simulators.length > 0) {
|
|
293
|
+
if (choices.length > 0) {
|
|
294
|
+
choices.push({
|
|
295
|
+
name: '',
|
|
296
|
+
value: null,
|
|
297
|
+
disabled: true
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
choices.push({
|
|
301
|
+
name: pc.dim('━━━ 💻 Simulators ━━━'),
|
|
302
|
+
value: null,
|
|
303
|
+
disabled: true
|
|
304
|
+
});
|
|
305
|
+
// Group by category
|
|
306
|
+
const categories = ['iphone', 'ipad', 'watch', 'tv', 'vision'];
|
|
307
|
+
for (const category of categories) {
|
|
308
|
+
const categoryDevices = simulators.filter(d => d.category === category);
|
|
309
|
+
if (categoryDevices.length > 0) {
|
|
310
|
+
for (const device of categoryDevices) {
|
|
311
|
+
const status = device.state === 'booted' ? '🟢' : '⚪';
|
|
312
|
+
const info = device.displaySize ? `• ${device.displaySize}" • ${device.resolution || ''}` : '';
|
|
313
|
+
choices.push({
|
|
314
|
+
name: `${status} ${device.name.padEnd(30)} ${device.osVersion || ''} ${pc.dim(info)}`,
|
|
315
|
+
value: device
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
try {
|
|
322
|
+
const selected = await select({
|
|
323
|
+
message: 'Select a device for screenshot capture:',
|
|
324
|
+
choices: choices.filter(c => c.value !== null || c.disabled),
|
|
325
|
+
pageSize: 15
|
|
326
|
+
});
|
|
327
|
+
return selected;
|
|
328
|
+
}
|
|
329
|
+
catch {
|
|
330
|
+
// User cancelled
|
|
331
|
+
return null;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
async function findDevice(devices, query) {
|
|
335
|
+
// Try exact match
|
|
336
|
+
let device = devices.find(d => d.name === query);
|
|
337
|
+
if (device)
|
|
338
|
+
return device;
|
|
339
|
+
// Try case-insensitive match
|
|
340
|
+
device = devices.find(d => d.name.toLowerCase() === query.toLowerCase());
|
|
341
|
+
if (device)
|
|
342
|
+
return device;
|
|
343
|
+
// Try partial match
|
|
344
|
+
device = devices.find(d => d.name.toLowerCase().includes(query.toLowerCase()));
|
|
345
|
+
if (device)
|
|
346
|
+
return device;
|
|
347
|
+
// Try by index (if numeric)
|
|
348
|
+
if (/^\d+$/.test(query)) {
|
|
349
|
+
const index = parseInt(query) - 1;
|
|
350
|
+
if (devices[index])
|
|
351
|
+
return devices[index];
|
|
352
|
+
}
|
|
353
|
+
return null;
|
|
354
|
+
}
|
|
355
|
+
async function captureFromDevice(device, options) {
|
|
356
|
+
// Boot simulator if needed
|
|
357
|
+
if (device.type === 'simulator' && device.state !== 'booted') {
|
|
358
|
+
const shouldBoot = await confirm({
|
|
359
|
+
message: `${device.name} is not booted. Boot it now?`,
|
|
360
|
+
default: true
|
|
361
|
+
});
|
|
362
|
+
if (shouldBoot) {
|
|
363
|
+
console.log(pc.cyan(`Booting ${device.name}...`));
|
|
364
|
+
await deviceManager.bootSimulator(device);
|
|
365
|
+
// Wait for boot to complete
|
|
366
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
367
|
+
}
|
|
368
|
+
else {
|
|
369
|
+
console.log(pc.yellow('Skipping device'));
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
// Capture screenshot
|
|
374
|
+
console.log(pc.cyan(`📸 Capturing from ${device.name}...`));
|
|
375
|
+
try {
|
|
376
|
+
const screenshot = await deviceManager.captureScreenshot({
|
|
377
|
+
device,
|
|
378
|
+
format: 'png'
|
|
379
|
+
});
|
|
380
|
+
// Route to correct directory
|
|
381
|
+
const tempPath = path.join('/tmp', `appshot-temp-${Date.now()}.png`);
|
|
382
|
+
await fs.writeFile(tempPath, screenshot);
|
|
383
|
+
const targetPath = await screenshotRouter.routeAndMove(device, tempPath, options.screenName);
|
|
384
|
+
console.log(pc.green(`✅ Saved to: ${targetPath}`));
|
|
385
|
+
// Process if requested
|
|
386
|
+
if (options.process) {
|
|
387
|
+
console.log(pc.cyan('🎨 Processing with frame and gradient...'));
|
|
388
|
+
const config = await loadConfig();
|
|
389
|
+
const composeBridge = createComposeBridge(config);
|
|
390
|
+
const result = await composeBridge.processDeviceScreenshot({
|
|
391
|
+
screenshotPath: targetPath,
|
|
392
|
+
device,
|
|
393
|
+
processOptions: {
|
|
394
|
+
frameOnly: false,
|
|
395
|
+
format: 'png'
|
|
396
|
+
}
|
|
397
|
+
});
|
|
398
|
+
if (result.success) {
|
|
399
|
+
console.log(pc.green(`✅ Final: ${result.outputPath}`));
|
|
400
|
+
if (result.frameUsed) {
|
|
401
|
+
console.log(pc.dim(` Frame: ${result.frameUsed}`));
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
else {
|
|
405
|
+
console.log(pc.red(`❌ Processing failed: ${result.error}`));
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
catch (error) {
|
|
410
|
+
console.error(pc.red(`❌ Failed to capture from ${device.name}:`), error);
|
|
411
|
+
throw error;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
//# sourceMappingURL=device.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device.js","sourceRoot":"","sources":["../../src/commands/device.ts"],"names":[],"mappings":"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"}
|