appshot-cli 0.7.0 ā 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +244 -5
- package/dist/cli.js +23 -4
- 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/frame.d.ts +3 -0
- package/dist/commands/frame.d.ts.map +1 -0
- package/dist/commands/frame.js +251 -0
- package/dist/commands/frame.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 +25 -0
- package/dist/core/compose.d.ts.map +1 -1
- package/dist/core/compose.js +82 -0
- package/dist/core/compose.js.map +1 -1
- package/dist/core/devices.d.ts +5 -0
- package/dist/core/devices.d.ts.map +1 -1
- package/dist/core/devices.js +43 -1
- package/dist/core/devices.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
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { promises as fs } from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import pc from 'picocolors';
|
|
5
|
+
import sharp from 'sharp';
|
|
6
|
+
import { initializeFrameRegistry, getImageDimensions, autoSelectFrame, detectDeviceTypeFromDimensions } from '../core/devices.js';
|
|
7
|
+
import { composeFrameOnly } from '../core/compose.js';
|
|
8
|
+
function isImage(file) {
|
|
9
|
+
return /\.(png|jpg|jpeg)$/i.test(file);
|
|
10
|
+
}
|
|
11
|
+
async function ensureDir(dir) {
|
|
12
|
+
await fs.mkdir(dir, { recursive: true });
|
|
13
|
+
}
|
|
14
|
+
async function listImagesRecursively(root) {
|
|
15
|
+
const entries = await fs.readdir(root, { withFileTypes: true });
|
|
16
|
+
const files = [];
|
|
17
|
+
for (const entry of entries) {
|
|
18
|
+
const full = path.join(root, entry.name);
|
|
19
|
+
if (entry.isDirectory()) {
|
|
20
|
+
const nested = await listImagesRecursively(full);
|
|
21
|
+
files.push(...nested);
|
|
22
|
+
}
|
|
23
|
+
else if (entry.isFile() && isImage(entry.name)) {
|
|
24
|
+
files.push(full);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return files;
|
|
28
|
+
}
|
|
29
|
+
async function processSingleFile(inputPath, framesDir, options) {
|
|
30
|
+
const { width, height, orientation } = await getImageDimensions(inputPath);
|
|
31
|
+
// Validate minimum dimensions
|
|
32
|
+
if (width < 100 || height < 100) {
|
|
33
|
+
console.error(pc.red(' ā'), path.basename(inputPath), pc.dim(`Image too small (${width}x${height}). Minimum 100x100 required.`));
|
|
34
|
+
return { processed: 0, errors: 1 };
|
|
35
|
+
}
|
|
36
|
+
// Warn on extreme aspect ratios
|
|
37
|
+
const aspect = Math.max(width, height) / Math.min(width, height);
|
|
38
|
+
if (aspect > 3) {
|
|
39
|
+
console.warn(pc.yellow(' ā '), path.basename(inputPath), pc.dim(`Extreme aspect ratio (${aspect.toFixed(2)}:1) may not match any device frame.`));
|
|
40
|
+
}
|
|
41
|
+
let device = options.device || detectDeviceTypeFromDimensions(width, height);
|
|
42
|
+
if (!device) {
|
|
43
|
+
console.error(pc.red(' ā'), path.basename(inputPath), pc.dim(`Unable to detect device type (${width}x${height}). Use --device to specify.`));
|
|
44
|
+
return { processed: 0, errors: 1 };
|
|
45
|
+
}
|
|
46
|
+
// Choose frame
|
|
47
|
+
const { frame, metadata } = await autoSelectFrame(inputPath, framesDir, device, undefined, Boolean(options.dryRun));
|
|
48
|
+
if (!metadata) {
|
|
49
|
+
console.error(pc.red(' ā'), path.basename(inputPath), pc.dim('No matching frame found'));
|
|
50
|
+
return { processed: 0, errors: 1 };
|
|
51
|
+
}
|
|
52
|
+
if (options.dryRun) {
|
|
53
|
+
console.log(pc.cyan(` ${path.basename(inputPath)}`) + pc.dim(` ā ${device} (${orientation})`));
|
|
54
|
+
console.log(pc.dim(` Source: ${width}x${height}`));
|
|
55
|
+
console.log(pc.dim(` Frame: ${metadata.displayName} (${metadata.frameWidth}x${metadata.frameHeight})`));
|
|
56
|
+
return { processed: 1, errors: 0 };
|
|
57
|
+
}
|
|
58
|
+
if (!frame) {
|
|
59
|
+
console.error(pc.red(' ā'), path.basename(inputPath), pc.dim('Frame image failed to load'));
|
|
60
|
+
return { processed: 0, errors: 1 };
|
|
61
|
+
}
|
|
62
|
+
// Load screenshot buffer
|
|
63
|
+
let screenshotBuffer;
|
|
64
|
+
try {
|
|
65
|
+
await fs.access(inputPath, fs.constants.R_OK);
|
|
66
|
+
screenshotBuffer = await sharp(inputPath).toBuffer();
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
console.error(pc.red(' ā'), path.basename(inputPath), pc.dim(`Failed to read image: ${err instanceof Error ? err.message : String(err)}`));
|
|
70
|
+
return { processed: 0, errors: 1 };
|
|
71
|
+
}
|
|
72
|
+
// Compose framed image with transparent background
|
|
73
|
+
let outBuffer;
|
|
74
|
+
try {
|
|
75
|
+
outBuffer = await composeFrameOnly({
|
|
76
|
+
screenshot: screenshotBuffer,
|
|
77
|
+
frame,
|
|
78
|
+
frameMetadata: {
|
|
79
|
+
frameWidth: metadata.frameWidth,
|
|
80
|
+
frameHeight: metadata.frameHeight,
|
|
81
|
+
screenRect: metadata.screenRect,
|
|
82
|
+
maskPath: metadata.maskPath,
|
|
83
|
+
deviceType: metadata.deviceType,
|
|
84
|
+
displayName: metadata.displayName,
|
|
85
|
+
name: metadata.name
|
|
86
|
+
},
|
|
87
|
+
outputFormat: options.format || 'png',
|
|
88
|
+
jpegQuality: 92,
|
|
89
|
+
verbose: options.verbose
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
console.error(pc.red(' ā'), path.basename(inputPath), pc.dim(`Compose failed: ${err instanceof Error ? err.message : String(err)}`));
|
|
94
|
+
return { processed: 0, errors: 1 };
|
|
95
|
+
}
|
|
96
|
+
// Determine output path
|
|
97
|
+
const format = options.format || 'png';
|
|
98
|
+
const ext = format === 'png' ? '.png' : '.jpg';
|
|
99
|
+
const baseName = path.basename(inputPath, path.extname(inputPath));
|
|
100
|
+
const outputDir = options.output ? path.resolve(options.output) : path.dirname(inputPath);
|
|
101
|
+
await ensureDir(outputDir);
|
|
102
|
+
let suffix = options.suffix ?? '-framed';
|
|
103
|
+
let outName = options.overwrite ? `${baseName}${ext}` : `${baseName}${suffix}${ext}`;
|
|
104
|
+
let outPath = path.join(outputDir, outName);
|
|
105
|
+
if (!options.overwrite) {
|
|
106
|
+
try {
|
|
107
|
+
await fs.access(outPath);
|
|
108
|
+
// File exists; if suffix is empty, fall back to default '-framed'
|
|
109
|
+
if (!suffix) {
|
|
110
|
+
suffix = '-framed';
|
|
111
|
+
outName = `${baseName}${suffix}${ext}`;
|
|
112
|
+
outPath = path.join(outputDir, outName);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// ok, does not exist
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
try {
|
|
120
|
+
await fs.writeFile(outPath, outBuffer);
|
|
121
|
+
console.log(pc.green(' ā'), path.basename(outPath), pc.dim(`[${device}, ${orientation}, transparent]`));
|
|
122
|
+
return { processed: 1, errors: 0 };
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
console.error(pc.red(' ā'), path.basename(inputPath), pc.dim(`Write failed: ${err instanceof Error ? err.message : String(err)}`));
|
|
126
|
+
return { processed: 0, errors: 1 };
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
export default function frameCmd() {
|
|
130
|
+
const cmd = new Command('frame')
|
|
131
|
+
.description('Apply device frames to screenshots with a transparent background (no gradients or captions)')
|
|
132
|
+
.argument('<input>', 'input image file or directory')
|
|
133
|
+
.option('-o, --output <dir>', 'output directory (default: same as input)')
|
|
134
|
+
.option('-d, --device <type>', 'force device type (iphone|ipad|mac|watch)')
|
|
135
|
+
.option('-r, --recursive', 'process directories recursively')
|
|
136
|
+
.option('-f, --format <type>', 'output format (png|jpeg)', 'png')
|
|
137
|
+
.option('--suffix <text>', 'filename suffix when not overwriting', '-framed')
|
|
138
|
+
.option('--overwrite', 'overwrite original file name')
|
|
139
|
+
.option('--dry-run', 'preview files without processing')
|
|
140
|
+
.option('--verbose', 'show detailed information')
|
|
141
|
+
.addHelpText('after', `
|
|
142
|
+
${pc.bold('Examples:')}
|
|
143
|
+
${pc.dim('# Single file (auto-detect device)')}
|
|
144
|
+
$ appshot frame screenshot.png
|
|
145
|
+
|
|
146
|
+
${pc.dim('# Specify output directory')}
|
|
147
|
+
$ appshot frame screenshot.png -o framed/
|
|
148
|
+
|
|
149
|
+
${pc.dim('# Force device type')}
|
|
150
|
+
$ appshot frame screenshot.png --device iphone
|
|
151
|
+
|
|
152
|
+
${pc.dim('# Batch process a directory')}
|
|
153
|
+
$ appshot frame ./screenshots -o ./framed --recursive
|
|
154
|
+
|
|
155
|
+
${pc.dim('# Dry run with verbose logs')}
|
|
156
|
+
$ appshot frame ./screenshots --dry-run --verbose`)
|
|
157
|
+
.action(async (input, opts) => {
|
|
158
|
+
const options = {
|
|
159
|
+
output: opts.output,
|
|
160
|
+
device: opts.device,
|
|
161
|
+
recursive: Boolean(opts.recursive),
|
|
162
|
+
format: (opts.format === 'jpeg' ? 'jpeg' : 'png'),
|
|
163
|
+
suffix: opts.suffix,
|
|
164
|
+
overwrite: Boolean(opts.overwrite),
|
|
165
|
+
verbose: Boolean(opts.verbose),
|
|
166
|
+
dryRun: Boolean(opts.dryRun)
|
|
167
|
+
};
|
|
168
|
+
// Validate device option if provided
|
|
169
|
+
if (options.device && !['iphone', 'ipad', 'mac', 'watch'].includes(options.device)) {
|
|
170
|
+
console.error(pc.red('Error:'), `Invalid --device value: ${options.device}`);
|
|
171
|
+
process.exit(1);
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
// Initialize frames registry (use project frames dir by default)
|
|
175
|
+
const framesDir = path.resolve('frames');
|
|
176
|
+
await initializeFrameRegistry(framesDir);
|
|
177
|
+
const inputPath = path.resolve(input);
|
|
178
|
+
const stat = await fs.stat(inputPath);
|
|
179
|
+
let totalProcessed = 0;
|
|
180
|
+
let totalErrors = 0;
|
|
181
|
+
if (stat.isFile()) {
|
|
182
|
+
// Ensure output directory exists if specified
|
|
183
|
+
if (options.output) {
|
|
184
|
+
await ensureDir(path.resolve(options.output));
|
|
185
|
+
}
|
|
186
|
+
const res = await processSingleFile(inputPath, framesDir, options);
|
|
187
|
+
totalProcessed += res.processed;
|
|
188
|
+
totalErrors += res.errors;
|
|
189
|
+
}
|
|
190
|
+
else if (stat.isDirectory()) {
|
|
191
|
+
// List images
|
|
192
|
+
const files = options.recursive
|
|
193
|
+
? await listImagesRecursively(inputPath)
|
|
194
|
+
: (await fs.readdir(inputPath))
|
|
195
|
+
.filter(isImage)
|
|
196
|
+
.map(f => path.join(inputPath, f));
|
|
197
|
+
if (files.length === 0) {
|
|
198
|
+
console.log(pc.yellow('ā '), 'No images found');
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
console.log(pc.cyan(`\n${path.basename(inputPath)}:`), `${options.dryRun ? 'Would frame' : 'Framing'} ${files.length} images`);
|
|
202
|
+
let currentIndex = 0;
|
|
203
|
+
for (const file of files) {
|
|
204
|
+
currentIndex++;
|
|
205
|
+
if (!options.dryRun && files.length > 5) {
|
|
206
|
+
process.stdout.write(pc.dim(`\r[${currentIndex}/${files.length}] Processing...`));
|
|
207
|
+
}
|
|
208
|
+
// Compute output for recursive structure
|
|
209
|
+
if (options.output && options.recursive) {
|
|
210
|
+
const rel = path.relative(inputPath, path.dirname(file));
|
|
211
|
+
const outDir = path.join(path.resolve(options.output), rel);
|
|
212
|
+
const res = await processSingleFile(file, framesDir, { ...options, output: outDir });
|
|
213
|
+
totalProcessed += res.processed;
|
|
214
|
+
totalErrors += res.errors;
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
const res = await processSingleFile(file, framesDir, options);
|
|
218
|
+
totalProcessed += res.processed;
|
|
219
|
+
totalErrors += res.errors;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
// Clear progress line
|
|
223
|
+
if (!options.dryRun && files.length > 5) {
|
|
224
|
+
process.stdout.write('\r' + ' '.repeat(30) + '\r');
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
console.error(pc.red('Error:'), 'Input must be a file or directory');
|
|
229
|
+
process.exit(1);
|
|
230
|
+
}
|
|
231
|
+
// Summary
|
|
232
|
+
if (options.dryRun) {
|
|
233
|
+
console.log('\n' + pc.bold('Dry run complete!'));
|
|
234
|
+
console.log(pc.cyan(`ā ${totalProcessed} images would be framed`));
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
console.log('\n' + pc.bold('Framing complete!'));
|
|
238
|
+
console.log(pc.green(`ā ${totalProcessed} images processed`));
|
|
239
|
+
if (totalErrors > 0) {
|
|
240
|
+
console.log(pc.red(`ā ${totalErrors} errors`));
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
catch (error) {
|
|
245
|
+
console.error(pc.red('Error:'), error instanceof Error ? error.message : String(error));
|
|
246
|
+
process.exit(1);
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
return cmd;
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=frame.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame.js","sourceRoot":"","sources":["../../src/commands/frame.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,eAAe,EAAE,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AAClI,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAetD,SAAS,OAAO,CAAC,IAAY;IAC3B,OAAO,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,GAAW;IAClC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,KAAK,UAAU,qBAAqB,CAAC,IAAY;IAC/C,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAChE,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,IAAI,CAAC,CAAC;YACjD,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;QACxB,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACjD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,SAAiB,EAAE,SAAiB,EAAE,OAA4B;IACjG,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAE3E,8BAA8B;IAC9B,IAAI,KAAK,GAAG,GAAG,IAAI,MAAM,GAAG,GAAG,EAAE,CAAC;QAChC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,oBAAoB,KAAK,IAAI,MAAM,8BAA8B,CAAC,CAAC,CAAC;QAClI,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IACrC,CAAC;IAED,gCAAgC;IAChC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACjE,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,yBAAyB,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,qCAAqC,CAAC,CAAC,CAAC;IACpJ,CAAC;IAED,IAAI,MAAM,GAAsB,OAAO,CAAC,MAAM,IAAI,8BAA8B,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAChG,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,iCAAiC,KAAK,IAAI,MAAM,6BAA6B,CAAC,CAAC,CAAC;QAC9I,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IACrC,CAAC;IAED,eAAe;IACf,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,eAAe,CAC/C,SAAS,EACT,SAAS,EACT,MAAM,EACN,SAAS,EACT,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CACxB,CAAC;IAEF,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC,CAAC;QAC1F,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IACrC,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,MAAM,KAAK,WAAW,GAAG,CAAC,CAAC,CAAC;QAChG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,eAAe,KAAK,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,cAAc,QAAQ,CAAC,WAAW,KAAK,QAAQ,CAAC,UAAU,IAAI,QAAQ,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;QAC3G,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IACrC,CAAC;IAED,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC,CAAC;QAC7F,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IACrC,CAAC;IAED,yBAAyB;IACzB,IAAI,gBAAwB,CAAC;IAC7B,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC9C,gBAAgB,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC;IACvD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,yBAAyB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5I,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IACrC,CAAC;IAED,mDAAmD;IACnD,IAAI,SAAiB,CAAC;IACtB,IAAI,CAAC;QACH,SAAS,GAAG,MAAM,gBAAgB,CAAC;YACjC,UAAU,EAAE,gBAAgB;YAC5B,KAAK;YACL,aAAa,EAAE;gBACb,UAAU,EAAE,QAAQ,CAAC,UAAU;gBAC/B,WAAW,EAAE,QAAQ,CAAC,WAAW;gBACjC,UAAU,EAAE,QAAQ,CAAC,UAAU;gBAC/B,QAAQ,EAAE,QAAQ,CAAC,QAAQ;gBAC3B,UAAU,EAAE,QAAQ,CAAC,UAAU;gBAC/B,WAAW,EAAE,QAAQ,CAAC,WAAW;gBACjC,IAAI,EAAE,QAAQ,CAAC,IAAI;aACpB;YACD,YAAY,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK;YACrC,WAAW,EAAE,EAAE;YACf,OAAO,EAAE,OAAO,CAAC,OAAO;SACzB,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,mBAAmB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACtI,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IACrC,CAAC;IAED,wBAAwB;IACxB,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC;IACvC,MAAM,GAAG,GAAG,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;IAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;IACnE,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAC1F,MAAM,SAAS,CAAC,SAAS,CAAC,CAAC;IAE3B,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,SAAS,CAAC;IACzC,IAAI,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,QAAQ,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,QAAQ,GAAG,MAAM,GAAG,GAAG,EAAE,CAAC;IACrF,IAAI,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAE5C,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACzB,kEAAkE;YAClE,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,GAAG,SAAS,CAAC;gBACnB,OAAO,GAAG,GAAG,QAAQ,GAAG,MAAM,GAAG,GAAG,EAAE,CAAC;gBACvC,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,qBAAqB;QACvB,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,MAAM,KAAK,WAAW,gBAAgB,CAAC,CAAC,CAAC;QACzG,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IACrC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,iBAAiB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACpI,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IACrC,CAAC;AACH,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,QAAQ;IAC9B,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;SAC7B,WAAW,CAAC,6FAA6F,CAAC;SAC1G,QAAQ,CAAC,SAAS,EAAE,+BAA+B,CAAC;SACpD,MAAM,CAAC,oBAAoB,EAAE,2CAA2C,CAAC;SACzE,MAAM,CAAC,qBAAqB,EAAE,2CAA2C,CAAC;SAC1E,MAAM,CAAC,iBAAiB,EAAE,iCAAiC,CAAC;SAC5D,MAAM,CAAC,qBAAqB,EAAE,0BAA0B,EAAE,KAAK,CAAC;SAChE,MAAM,CAAC,iBAAiB,EAAE,sCAAsC,EAAE,SAAS,CAAC;SAC5E,MAAM,CAAC,aAAa,EAAE,8BAA8B,CAAC;SACrD,MAAM,CAAC,WAAW,EAAE,kCAAkC,CAAC;SACvD,MAAM,CAAC,WAAW,EAAE,2BAA2B,CAAC;SAChD,WAAW,CAAC,OAAO,EAAE;EACxB,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC;IAClB,EAAE,CAAC,GAAG,CAAC,oCAAoC,CAAC;;;IAG5C,EAAE,CAAC,GAAG,CAAC,4BAA4B,CAAC;;;IAGpC,EAAE,CAAC,GAAG,CAAC,qBAAqB,CAAC;;;IAG7B,EAAE,CAAC,GAAG,CAAC,6BAA6B,CAAC;;;IAGrC,EAAE,CAAC,GAAG,CAAC,6BAA6B,CAAC;oDACW,CAAC;SAChD,MAAM,CAAC,KAAK,EAAE,KAAa,EAAE,IAAI,EAAE,EAAE;QACpC,MAAM,OAAO,GAAwB;YACnC,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;YAClC,MAAM,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;YACjD,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;YAClC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;YAC9B,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;SAC7B,CAAC;QAEF,qCAAqC;QACrC,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACnF,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,2BAA2B,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YAC7E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,CAAC;YACH,iEAAiE;YACjE,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACzC,MAAM,uBAAuB,CAAC,SAAS,CAAC,CAAC;YAEzC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACtC,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAEtC,IAAI,cAAc,GAAG,CAAC,CAAC;YACvB,IAAI,WAAW,GAAG,CAAC,CAAC;YAEpB,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;gBAClB,8CAA8C;gBAC9C,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;oBACnB,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;gBAChD,CAAC;gBACD,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;gBACnE,cAAc,IAAI,GAAG,CAAC,SAAS,CAAC;gBAChC,WAAW,IAAI,GAAG,CAAC,MAAM,CAAC;YAC5B,CAAC;iBAAM,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;gBAC9B,cAAc;gBACd,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS;oBAC7B,CAAC,CAAC,MAAM,qBAAqB,CAAC,SAAS,CAAC;oBACxC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;yBAC5B,MAAM,CAAC,OAAO,CAAC;yBACf,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;gBAEvC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACvB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,iBAAiB,CAAC,CAAC;oBAC/C,OAAO;gBACT,CAAC;gBAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,IAAI,KAAK,CAAC,MAAM,SAAS,CAAC,CAAC;gBAE/H,IAAI,YAAY,GAAG,CAAC,CAAC;gBACrB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,YAAY,EAAE,CAAC;oBACf,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,YAAY,IAAI,KAAK,CAAC,MAAM,iBAAiB,CAAC,CAAC,CAAC;oBACpF,CAAC;oBACD,yCAAyC;oBACzC,IAAI,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;wBACxC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;wBACzD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC;wBAC5D,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;wBACrF,cAAc,IAAI,GAAG,CAAC,SAAS,CAAC;wBAChC,WAAW,IAAI,GAAG,CAAC,MAAM,CAAC;oBAC5B,CAAC;yBAAM,CAAC;wBACN,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;wBAC9D,cAAc,IAAI,GAAG,CAAC,SAAS,CAAC;wBAChC,WAAW,IAAI,GAAG,CAAC,MAAM,CAAC;oBAC5B,CAAC;gBACH,CAAC;gBAED,sBAAsB;gBACtB,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;gBACrD,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,mCAAmC,CAAC,CAAC;gBACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,UAAU;YACV,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;gBACnB,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;gBACjD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,cAAc,yBAAyB,CAAC,CAAC,CAAC;YACrE,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;gBACjD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,cAAc,mBAAmB,CAAC,CAAC,CAAC;gBAC9D,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;oBACpB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,WAAW,SAAS,CAAC,CAAC,CAAC;gBACjD,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACxF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unwatch.d.ts","sourceRoot":"","sources":["../../src/commands/unwatch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,MAAM,CAAC,OAAO,UAAU,cAAc,IAAI,OAAO,CAoDhD"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import pc from 'picocolors';
|
|
3
|
+
import { PIDManager } from '../utils/pid-manager.js';
|
|
4
|
+
export default function unwatchCommand() {
|
|
5
|
+
return new Command('unwatch')
|
|
6
|
+
.description('Stop watching directories (alias for "watch stop")')
|
|
7
|
+
.action(async () => {
|
|
8
|
+
try {
|
|
9
|
+
const pidManager = new PIDManager('.appshot/watch.pid');
|
|
10
|
+
const pid = await pidManager.readPID();
|
|
11
|
+
if (!pid) {
|
|
12
|
+
console.log(pc.yellow('ā ļø Watch service is not running'));
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (!(await pidManager.isProcessRunning(pid))) {
|
|
16
|
+
console.log(pc.yellow('ā ļø Watch service PID file exists but process is not running'));
|
|
17
|
+
await pidManager.cleanup();
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
console.log(pc.cyan(`š Stopping watch service (PID: ${pid})...`));
|
|
21
|
+
try {
|
|
22
|
+
process.kill(pid, 'SIGTERM');
|
|
23
|
+
// Wait for process to stop
|
|
24
|
+
let attempts = 0;
|
|
25
|
+
while (attempts < 10 && await pidManager.isProcessRunning(pid)) {
|
|
26
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
27
|
+
attempts++;
|
|
28
|
+
}
|
|
29
|
+
if (await pidManager.isProcessRunning(pid)) {
|
|
30
|
+
// Force kill if still running
|
|
31
|
+
console.log(pc.yellow('ā ļø Process did not stop gracefully, forcing...'));
|
|
32
|
+
process.kill(pid, 'SIGKILL');
|
|
33
|
+
}
|
|
34
|
+
await pidManager.cleanup();
|
|
35
|
+
console.log(pc.green('ā
Watch service stopped'));
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
if (error.code === 'ESRCH') {
|
|
39
|
+
console.log(pc.yellow('ā ļø Process already stopped'));
|
|
40
|
+
await pidManager.cleanup();
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
console.error(pc.red('ā Error stopping watch service:'), error);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=unwatch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unwatch.js","sourceRoot":"","sources":["../../src/commands/unwatch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD,MAAM,CAAC,OAAO,UAAU,cAAc;IACpC,OAAO,IAAI,OAAO,CAAC,SAAS,CAAC;SAC1B,WAAW,CAAC,oDAAoD,CAAC;SACjE,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,oBAAoB,CAAC,CAAC;YACxD,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,CAAC;YAEvC,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,kCAAkC,CAAC,CAAC,CAAC;gBAC3D,OAAO;YACT,CAAC;YAED,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;gBAC9C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,8DAA8D,CAAC,CAAC,CAAC;gBACvF,MAAM,UAAU,CAAC,OAAO,EAAE,CAAC;gBAC3B,OAAO;YACT,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,mCAAmC,GAAG,MAAM,CAAC,CAAC,CAAC;YAEnE,IAAI,CAAC;gBACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;gBAE7B,2BAA2B;gBAC3B,IAAI,QAAQ,GAAG,CAAC,CAAC;gBACjB,OAAO,QAAQ,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC/D,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;oBACvD,QAAQ,EAAE,CAAC;gBACb,CAAC;gBAED,IAAI,MAAM,UAAU,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC3C,8BAA8B;oBAC9B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,iDAAiD,CAAC,CAAC,CAAC;oBAC1E,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;gBAC/B,CAAC;gBAED,MAAM,UAAU,CAAC,OAAO,EAAE,CAAC;gBAC3B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;YACnD,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBACpB,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBAC3B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,6BAA6B,CAAC,CAAC,CAAC;oBACtD,MAAM,UAAU,CAAC,OAAO,EAAE,CAAC;gBAC7B,CAAC;qBAAM,CAAC;oBACN,MAAM,KAAK,CAAC;gBACd,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,iCAAiC,CAAC,EAAE,KAAK,CAAC,CAAC;YAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch-status.d.ts","sourceRoot":"","sources":["../../src/commands/watch-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,MAAM,CAAC,OAAO,UAAU,kBAAkB,IAAI,OAAO,CAsHpD"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import pc from 'picocolors';
|
|
3
|
+
import fs from 'fs/promises';
|
|
4
|
+
import { PIDManager } from '../utils/pid-manager.js';
|
|
5
|
+
export default function watchStatusCommand() {
|
|
6
|
+
return new Command('watch-status')
|
|
7
|
+
.description('Check the status of the watch service')
|
|
8
|
+
.option('--json', 'Output as JSON')
|
|
9
|
+
.option('--verbose', 'Show detailed information')
|
|
10
|
+
.action(async (options) => {
|
|
11
|
+
try {
|
|
12
|
+
const pidManager = new PIDManager('.appshot/watch.pid');
|
|
13
|
+
const pid = await pidManager.readPID();
|
|
14
|
+
// Basic status
|
|
15
|
+
const status = {
|
|
16
|
+
running: false,
|
|
17
|
+
pid: null,
|
|
18
|
+
pidFile: '.appshot/watch.pid',
|
|
19
|
+
processedCache: false,
|
|
20
|
+
cachedHashes: 0
|
|
21
|
+
};
|
|
22
|
+
if (pid) {
|
|
23
|
+
status.pid = pid;
|
|
24
|
+
status.running = await pidManager.isProcessRunning(pid);
|
|
25
|
+
}
|
|
26
|
+
// Check for processed cache
|
|
27
|
+
try {
|
|
28
|
+
const hashCacheFile = '.appshot/processed/hashes.json';
|
|
29
|
+
const content = await fs.readFile(hashCacheFile, 'utf8');
|
|
30
|
+
const hashes = JSON.parse(content);
|
|
31
|
+
status.processedCache = true;
|
|
32
|
+
status.cachedHashes = hashes.length;
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// Cache doesn't exist or is invalid
|
|
36
|
+
}
|
|
37
|
+
if (options.json) {
|
|
38
|
+
console.log(JSON.stringify(status, null, 2));
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
// Human-readable output
|
|
42
|
+
console.log(pc.bold('\nš Watch Service Status\n'));
|
|
43
|
+
if (status.running) {
|
|
44
|
+
console.log(pc.green('ā
Service is running'));
|
|
45
|
+
console.log(pc.dim(` PID: ${status.pid}`));
|
|
46
|
+
console.log(pc.dim(` PID file: ${status.pidFile}`));
|
|
47
|
+
}
|
|
48
|
+
else if (status.pid) {
|
|
49
|
+
console.log(pc.yellow('ā ļø Service is not running'));
|
|
50
|
+
console.log(pc.dim(` Stale PID: ${status.pid}`));
|
|
51
|
+
console.log(pc.dim(' Run "appshot watch stop" to clean up'));
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
console.log(pc.gray('āŖ Service is not running'));
|
|
55
|
+
console.log(pc.dim(' Use "appshot watch start" to begin watching'));
|
|
56
|
+
}
|
|
57
|
+
if (options.verbose) {
|
|
58
|
+
console.log(pc.bold('\nš Cache Information\n'));
|
|
59
|
+
if (status.processedCache) {
|
|
60
|
+
console.log(pc.dim(` Processed hashes: ${status.cachedHashes}`));
|
|
61
|
+
console.log(pc.dim(' Cache file: .appshot/processed/hashes.json'));
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
console.log(pc.dim(' No processing cache found'));
|
|
65
|
+
}
|
|
66
|
+
// Check for watch directories in config
|
|
67
|
+
try {
|
|
68
|
+
const configPath = '.appshot/config.json';
|
|
69
|
+
const configContent = await fs.readFile(configPath, 'utf8');
|
|
70
|
+
const config = JSON.parse(configContent);
|
|
71
|
+
if (config.watch) {
|
|
72
|
+
console.log(pc.bold('\nāļø Watch Configuration\n'));
|
|
73
|
+
if (config.watch.directories) {
|
|
74
|
+
console.log(pc.dim(' Configured directories:'));
|
|
75
|
+
for (const dir of config.watch.directories) {
|
|
76
|
+
const exists = await fs.stat(dir).then(() => true).catch(() => false);
|
|
77
|
+
const indicator = exists ? pc.green('ā') : pc.red('ā');
|
|
78
|
+
console.log(` ${indicator} ${dir}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (config.watch.devices) {
|
|
82
|
+
console.log(pc.dim('\n Configured devices:'));
|
|
83
|
+
for (const device of config.watch.devices) {
|
|
84
|
+
console.log(` ⢠${device}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (config.watch.process !== undefined) {
|
|
88
|
+
console.log(pc.dim(`\n Auto-process: ${config.watch.process ? 'Yes' : 'No'}`));
|
|
89
|
+
if (config.watch.frameOnly) {
|
|
90
|
+
console.log(pc.dim(' Mode: Frame only'));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
// No config or invalid config
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// Quick actions
|
|
100
|
+
console.log(pc.bold('\nšÆ Quick Actions\n'));
|
|
101
|
+
if (status.running) {
|
|
102
|
+
console.log(pc.dim(' appshot watch stop - Stop the service'));
|
|
103
|
+
console.log(pc.dim(' appshot watch status -v - Show detailed info'));
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
console.log(pc.dim(' appshot watch start - Start watching'));
|
|
107
|
+
console.log(pc.dim(' appshot watch setup - Interactive setup'));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
console.error(pc.red('ā Error checking status:'), error);
|
|
112
|
+
process.exit(1);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=watch-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch-status.js","sourceRoot":"","sources":["../../src/commands/watch-status.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,MAAM,CAAC,OAAO,UAAU,YAAY,IAAI,OAAO,CAuV9C"}
|