clipshot 1.0.8 → 1.0.10
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/.github/workflows/publish.yml +31 -0
- package/dist/config.js +11 -4
- package/dist/index.js +89 -76
- package/dist/monitor.js +49 -24
- package/dist/prompts.js +52 -17
- package/package.json +2 -1
- package/demo_video.gif +0 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: Publish to npm
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
publish:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- name: Checkout
|
|
14
|
+
uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- name: Setup Node.js
|
|
17
|
+
uses: actions/setup-node@v4
|
|
18
|
+
with:
|
|
19
|
+
node-version: '20'
|
|
20
|
+
registry-url: 'https://registry.npmjs.org'
|
|
21
|
+
|
|
22
|
+
- name: Install dependencies
|
|
23
|
+
run: npm ci
|
|
24
|
+
|
|
25
|
+
- name: Build
|
|
26
|
+
run: npm run build
|
|
27
|
+
|
|
28
|
+
- name: Publish to npm
|
|
29
|
+
run: npm publish
|
|
30
|
+
env:
|
|
31
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/dist/config.js
CHANGED
|
@@ -99,13 +99,14 @@ function detectSSHRemotes() {
|
|
|
99
99
|
}
|
|
100
100
|
return hosts;
|
|
101
101
|
}
|
|
102
|
-
function detectSSHFromHistory() {
|
|
102
|
+
function detectSSHFromHistory(limit = 5) {
|
|
103
103
|
const home = os.homedir();
|
|
104
104
|
const historyFiles = [
|
|
105
105
|
path.join(home, ".bash_history"),
|
|
106
106
|
path.join(home, ".zsh_history"),
|
|
107
107
|
];
|
|
108
|
-
|
|
108
|
+
// Track remotes in order of most recent appearance
|
|
109
|
+
const remotes = [];
|
|
109
110
|
for (const histFile of historyFiles) {
|
|
110
111
|
if (!fs.existsSync(histFile))
|
|
111
112
|
continue;
|
|
@@ -122,7 +123,12 @@ function detectSSHFromHistory() {
|
|
|
122
123
|
// Clean up any trailing characters
|
|
123
124
|
const clean = remote.replace(/[;|&].*$/, "");
|
|
124
125
|
if (clean.match(/^[\w.-]+@[\w.-]+$/)) {
|
|
125
|
-
|
|
126
|
+
// Remove if exists, then add to end (most recent)
|
|
127
|
+
const idx = remotes.indexOf(clean);
|
|
128
|
+
if (idx !== -1) {
|
|
129
|
+
remotes.splice(idx, 1);
|
|
130
|
+
}
|
|
131
|
+
remotes.push(clean);
|
|
126
132
|
}
|
|
127
133
|
}
|
|
128
134
|
}
|
|
@@ -132,5 +138,6 @@ function detectSSHFromHistory() {
|
|
|
132
138
|
// Ignore read errors
|
|
133
139
|
}
|
|
134
140
|
}
|
|
135
|
-
|
|
141
|
+
// Return most recent entries (last N items, reversed so most recent is first)
|
|
142
|
+
return remotes.slice(-limit).reverse();
|
|
136
143
|
}
|
package/dist/index.js
CHANGED
|
@@ -41,6 +41,69 @@ const child_process_1 = require("child_process");
|
|
|
41
41
|
const config_1 = require("./config");
|
|
42
42
|
const prompts_1 = require("./prompts");
|
|
43
43
|
const monitor_1 = require("./monitor");
|
|
44
|
+
const isWindows = process.platform === "win32";
|
|
45
|
+
function findClipshotProcesses() {
|
|
46
|
+
const processes = [];
|
|
47
|
+
try {
|
|
48
|
+
if (isWindows) {
|
|
49
|
+
// Use PowerShell to get node processes with command line (WMIC is deprecated)
|
|
50
|
+
const psScript = `$ProgressPreference = 'SilentlyContinue'; Get-CimInstance Win32_Process -Filter "name = 'node.exe'" | Where-Object { $_.CommandLine -like '*clipshot*' -and $_.CommandLine -like '*--daemon*' } | Select-Object ProcessId,CommandLine | ConvertTo-Csv -NoTypeInformation`;
|
|
51
|
+
const encoded = Buffer.from(psScript, "utf16le").toString("base64");
|
|
52
|
+
const result = (0, child_process_1.execSync)(`powershell -NoProfile -WindowStyle Hidden -EncodedCommand ${encoded}`, { encoding: "utf8", windowsHide: true, stdio: ["pipe", "pipe", "pipe"] });
|
|
53
|
+
for (const line of result.split("\n").slice(1)) { // Skip header
|
|
54
|
+
if (!line.trim())
|
|
55
|
+
continue;
|
|
56
|
+
// CSV format: "ProcessId","CommandLine"
|
|
57
|
+
const match = line.match(/"(\d+)","(.*)"/);
|
|
58
|
+
if (match) {
|
|
59
|
+
const pid = parseInt(match[1]);
|
|
60
|
+
if (!isNaN(pid) && pid !== process.pid) {
|
|
61
|
+
processes.push({ pid, command: match[2] });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
// Unix: use pgrep
|
|
68
|
+
const result = (0, child_process_1.execSync)("pgrep -af 'node.*[c]lipshot.*--daemon'", { encoding: "utf8" });
|
|
69
|
+
for (const line of result.trim().split("\n").filter(Boolean)) {
|
|
70
|
+
const pid = parseInt(line.split(/\s+/)[0]);
|
|
71
|
+
if (!isNaN(pid)) {
|
|
72
|
+
processes.push({ pid, command: line });
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// No processes found
|
|
79
|
+
}
|
|
80
|
+
return processes;
|
|
81
|
+
}
|
|
82
|
+
function killProcess(pid, force = false) {
|
|
83
|
+
try {
|
|
84
|
+
if (isWindows) {
|
|
85
|
+
(0, child_process_1.execSync)(`taskkill /PID ${pid}${force ? " /F" : ""}`, { stdio: "pipe", windowsHide: true });
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
process.kill(pid, force ? "SIGKILL" : "SIGTERM");
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
// Process may have already exited
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function killAllClipshotProcesses() {
|
|
96
|
+
const processes = findClipshotProcesses();
|
|
97
|
+
for (const proc of processes) {
|
|
98
|
+
killProcess(proc.pid);
|
|
99
|
+
}
|
|
100
|
+
// Check if any survived and force kill
|
|
101
|
+
const remaining = findClipshotProcesses();
|
|
102
|
+
for (const proc of remaining) {
|
|
103
|
+
killProcess(proc.pid, true);
|
|
104
|
+
}
|
|
105
|
+
return processes.length;
|
|
106
|
+
}
|
|
44
107
|
function getVersion() {
|
|
45
108
|
const pkgPath = path.join(__dirname, "..", "package.json");
|
|
46
109
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
@@ -53,11 +116,12 @@ async function addRemotes(existing) {
|
|
|
53
116
|
// From SSH config
|
|
54
117
|
const sshHosts = (0, config_1.detectSSHRemotes)();
|
|
55
118
|
for (const host of sshHosts) {
|
|
56
|
-
if
|
|
57
|
-
|
|
119
|
+
// Use user@host format if user is specified, otherwise just host name
|
|
120
|
+
const remoteName = host.user ? `${host.user}@${host.name}` : host.name;
|
|
121
|
+
if (!remotes.includes(remoteName)) {
|
|
58
122
|
allDetected.push({
|
|
59
|
-
name:
|
|
60
|
-
source:
|
|
123
|
+
name: remoteName,
|
|
124
|
+
source: "config",
|
|
61
125
|
});
|
|
62
126
|
}
|
|
63
127
|
}
|
|
@@ -118,18 +182,9 @@ Run without command to setup/configure.
|
|
|
118
182
|
}
|
|
119
183
|
function uninstall() {
|
|
120
184
|
// Stop any running process
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
for (const pid of pids) {
|
|
125
|
-
process.kill(parseInt(pid), "SIGTERM");
|
|
126
|
-
}
|
|
127
|
-
if (pids.length > 0) {
|
|
128
|
-
console.log("Stopped running process");
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
catch {
|
|
132
|
-
// Not running
|
|
185
|
+
const count = killAllClipshotProcesses();
|
|
186
|
+
if (count > 0) {
|
|
187
|
+
console.log("Stopped running process");
|
|
133
188
|
}
|
|
134
189
|
// Remove config directory
|
|
135
190
|
const configDir = path.join(os.homedir(), ".config", "clipshot");
|
|
@@ -140,63 +195,30 @@ function uninstall() {
|
|
|
140
195
|
console.log("\nNow run: npm uninstall -g clipshot");
|
|
141
196
|
}
|
|
142
197
|
function stopBackground() {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
const pids = result.trim().split("\n").filter(Boolean);
|
|
147
|
-
if (pids.length === 0) {
|
|
148
|
-
console.log("No clipshot process running");
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
// Use pkill for reliable process termination
|
|
152
|
-
try {
|
|
153
|
-
(0, child_process_1.execSync)("pkill -f 'node.*clipshot.*--daemon'", { encoding: "utf8" });
|
|
154
|
-
}
|
|
155
|
-
catch {
|
|
156
|
-
// pkill returns non-zero even on success sometimes
|
|
157
|
-
}
|
|
158
|
-
// Verify they're stopped
|
|
159
|
-
try {
|
|
160
|
-
(0, child_process_1.execSync)("pgrep -f 'node.*[c]lipshot.*--daemon'", { encoding: "utf8" });
|
|
161
|
-
// If we get here, some processes survived - try SIGKILL
|
|
162
|
-
(0, child_process_1.execSync)("pkill -9 -f 'node.*clipshot.*--daemon'", { encoding: "utf8" });
|
|
163
|
-
}
|
|
164
|
-
catch {
|
|
165
|
-
// No processes found - good
|
|
166
|
-
}
|
|
167
|
-
console.log(`Stopped ${pids.length} process(es)`);
|
|
198
|
+
const count = killAllClipshotProcesses();
|
|
199
|
+
if (count > 0) {
|
|
200
|
+
console.log(`Stopped ${count} process(es)`);
|
|
168
201
|
}
|
|
169
|
-
|
|
202
|
+
else {
|
|
170
203
|
console.log("No clipshot process running");
|
|
171
204
|
}
|
|
172
205
|
}
|
|
173
206
|
function showStatus() {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
const target = match[2];
|
|
185
|
-
console.log(`Running (PID: ${pid}) -> ${target}`);
|
|
186
|
-
}
|
|
187
|
-
else {
|
|
188
|
-
const pid = line.split(/\s+/)[0];
|
|
189
|
-
console.log(`Running (PID: ${pid})`);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
207
|
+
const processes = findClipshotProcesses();
|
|
208
|
+
if (processes.length === 0) {
|
|
209
|
+
console.log("Not running");
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
for (const proc of processes) {
|
|
213
|
+
// Try to extract target from command line
|
|
214
|
+
const match = proc.command.match(/--daemon\s+(\S+)/);
|
|
215
|
+
if (match) {
|
|
216
|
+
console.log(`Running (PID: ${proc.pid}) -> ${match[1]}`);
|
|
192
217
|
}
|
|
193
218
|
else {
|
|
194
|
-
console.log(
|
|
219
|
+
console.log(`Running (PID: ${proc.pid})`);
|
|
195
220
|
}
|
|
196
221
|
}
|
|
197
|
-
catch {
|
|
198
|
-
console.log("Not running");
|
|
199
|
-
}
|
|
200
222
|
}
|
|
201
223
|
async function runConfig() {
|
|
202
224
|
let config = (0, config_1.loadConfig)();
|
|
@@ -243,18 +265,9 @@ async function startCommand() {
|
|
|
243
265
|
selected = await (0, prompts_1.promptSelect)("Select target", options);
|
|
244
266
|
}
|
|
245
267
|
// Stop any existing process before starting new one
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
for (const pid of pids) {
|
|
250
|
-
process.kill(parseInt(pid), "SIGTERM");
|
|
251
|
-
}
|
|
252
|
-
if (pids.length > 0) {
|
|
253
|
-
console.log(`Stopped previous process`);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
catch {
|
|
257
|
-
// Not running, continue
|
|
268
|
+
const count = killAllClipshotProcesses();
|
|
269
|
+
if (count > 0) {
|
|
270
|
+
console.log(`Stopped previous process`);
|
|
258
271
|
}
|
|
259
272
|
startBackground(selected);
|
|
260
273
|
}
|
package/dist/monitor.js
CHANGED
|
@@ -44,7 +44,11 @@ const LOG_MAX_AGE_MS = 60 * 60 * 1000; // 1 hour
|
|
|
44
44
|
let lastImageHash = null;
|
|
45
45
|
let logFile = null;
|
|
46
46
|
let logStartTime = 0;
|
|
47
|
+
const isWindows = process.platform === "win32";
|
|
47
48
|
function isWSL() {
|
|
49
|
+
if (isWindows) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
48
52
|
try {
|
|
49
53
|
const release = fs.readFileSync("/proc/version", "utf8");
|
|
50
54
|
return release.toLowerCase().includes("microsoft") || release.toLowerCase().includes("wsl");
|
|
@@ -84,7 +88,7 @@ function log(message) {
|
|
|
84
88
|
process.stdout.write(message + "\n");
|
|
85
89
|
}
|
|
86
90
|
}
|
|
87
|
-
async function
|
|
91
|
+
async function getClipboardImageWindows() {
|
|
88
92
|
try {
|
|
89
93
|
// PowerShell script to get clipboard image as base64
|
|
90
94
|
const psScript = `
|
|
@@ -98,9 +102,12 @@ if ($img -ne $null) {
|
|
|
98
102
|
`;
|
|
99
103
|
// Encode as UTF-16LE base64 for -EncodedCommand
|
|
100
104
|
const encoded = Buffer.from(psScript, "utf16le").toString("base64");
|
|
101
|
-
|
|
105
|
+
// Use powershell.exe for WSL, powershell for native Windows
|
|
106
|
+
const psCmd = isWindows ? "powershell" : "powershell.exe";
|
|
107
|
+
const result = (0, child_process_1.execSync)(`${psCmd} -NoProfile -WindowStyle Hidden -EncodedCommand ${encoded}`, {
|
|
102
108
|
encoding: "utf8",
|
|
103
109
|
timeout: 5000,
|
|
110
|
+
windowsHide: true,
|
|
104
111
|
}).trim();
|
|
105
112
|
if (result && result.length > 0) {
|
|
106
113
|
return Buffer.from(result, "base64");
|
|
@@ -131,8 +138,8 @@ async function getClipboardImageNative() {
|
|
|
131
138
|
}
|
|
132
139
|
}
|
|
133
140
|
async function getClipboardImage() {
|
|
134
|
-
if (isWSL()) {
|
|
135
|
-
return
|
|
141
|
+
if (isWindows || isWSL()) {
|
|
142
|
+
return getClipboardImageWindows();
|
|
136
143
|
}
|
|
137
144
|
return getClipboardImageNative();
|
|
138
145
|
}
|
|
@@ -161,39 +168,53 @@ function saveLocal(imageBuffer, filename) {
|
|
|
161
168
|
return { success: false, path: filePath };
|
|
162
169
|
}
|
|
163
170
|
}
|
|
164
|
-
function
|
|
171
|
+
function getRemoteHomePath(remote) {
|
|
165
172
|
// Extract username from user@host format
|
|
166
173
|
const match = remote.match(/^([^@]+)@/);
|
|
167
|
-
|
|
168
|
-
|
|
174
|
+
if (match) {
|
|
175
|
+
const user = match[1];
|
|
176
|
+
return user === "root" ? "/root" : `/home/${user}`;
|
|
177
|
+
}
|
|
178
|
+
// Named host without user - fall back to ~
|
|
179
|
+
return "~";
|
|
169
180
|
}
|
|
170
181
|
async function pipeToRemote(imageBuffer, remote, filename) {
|
|
171
|
-
const homeDir =
|
|
182
|
+
const homeDir = getRemoteHomePath(remote);
|
|
172
183
|
const remotePath = `${homeDir}/clipshot-screenshots/${filename}`;
|
|
173
184
|
return new Promise((resolve) => {
|
|
174
|
-
//
|
|
175
|
-
// Use ControlMaster options for faster repeated connections
|
|
185
|
+
// Use ~ in the command so SSH resolves it correctly
|
|
176
186
|
const proc = (0, child_process_1.spawn)("ssh", [
|
|
177
|
-
"-o", "ControlMaster=auto",
|
|
178
|
-
"-o", "ControlPath=~/.ssh/clipshot-%r@%h:%p",
|
|
179
|
-
"-o", "ControlPersist=60",
|
|
180
187
|
remote,
|
|
181
|
-
`mkdir -p
|
|
182
|
-
]
|
|
188
|
+
`mkdir -p ~/clipshot-screenshots && cat > ~/clipshot-screenshots/${filename}`
|
|
189
|
+
], {
|
|
190
|
+
windowsHide: true,
|
|
191
|
+
});
|
|
192
|
+
let stderr = "";
|
|
193
|
+
proc.stderr.on("data", (data) => {
|
|
194
|
+
stderr += data.toString();
|
|
195
|
+
});
|
|
183
196
|
proc.stdin.write(imageBuffer);
|
|
184
197
|
proc.stdin.end();
|
|
185
198
|
proc.on("close", (code) => {
|
|
186
|
-
|
|
199
|
+
// Return the explicit path for clipboard, but command used ~ for reliability
|
|
200
|
+
resolve({ success: code === 0, path: remotePath, error: stderr.trim() || undefined });
|
|
187
201
|
});
|
|
188
|
-
proc.on("error", () => {
|
|
189
|
-
resolve({ success: false, path: remotePath });
|
|
202
|
+
proc.on("error", (err) => {
|
|
203
|
+
resolve({ success: false, path: remotePath, error: err.message });
|
|
190
204
|
});
|
|
191
205
|
});
|
|
192
206
|
}
|
|
193
|
-
function
|
|
207
|
+
function copyToClipboardWindows(text) {
|
|
194
208
|
try {
|
|
195
|
-
|
|
196
|
-
|
|
209
|
+
if (isWindows) {
|
|
210
|
+
// On native Windows, use PowerShell's Set-Clipboard
|
|
211
|
+
const escaped = text.replace(/'/g, "''");
|
|
212
|
+
(0, child_process_1.execSync)(`powershell -NoProfile -WindowStyle Hidden -Command "Set-Clipboard -Value '${escaped}'"`, { timeout: 2000, windowsHide: true });
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
// On WSL, use clip.exe
|
|
216
|
+
(0, child_process_1.execSync)(`echo -n '${text.replace(/'/g, "'\\''")}' | clip.exe`, { timeout: 2000 });
|
|
217
|
+
}
|
|
197
218
|
}
|
|
198
219
|
catch {
|
|
199
220
|
// Ignore clipboard errors
|
|
@@ -210,8 +231,8 @@ async function copyToClipboardNative(text) {
|
|
|
210
231
|
}
|
|
211
232
|
}
|
|
212
233
|
async function copyToClipboard(text) {
|
|
213
|
-
if (isWSL()) {
|
|
214
|
-
|
|
234
|
+
if (isWindows || isWSL()) {
|
|
235
|
+
copyToClipboardWindows(text);
|
|
215
236
|
}
|
|
216
237
|
else {
|
|
217
238
|
await copyToClipboardNative(text);
|
|
@@ -222,8 +243,9 @@ async function startMonitor(remote) {
|
|
|
222
243
|
logFile = createNewLogFile();
|
|
223
244
|
logStartTime = Date.now();
|
|
224
245
|
const wsl = isWSL();
|
|
246
|
+
const env = isWindows ? "Windows" : (wsl ? "WSL" : "Native");
|
|
225
247
|
log(`Starting monitor for: ${remote}`);
|
|
226
|
-
log(`Environment: ${
|
|
248
|
+
log(`Environment: ${env}`);
|
|
227
249
|
log(`Log file: ${logFile}`);
|
|
228
250
|
if (remote === "local") {
|
|
229
251
|
log(`Saving to: ${getLocalScreenshotDir()}`);
|
|
@@ -268,6 +290,9 @@ async function startMonitor(remote) {
|
|
|
268
290
|
}
|
|
269
291
|
else {
|
|
270
292
|
log(` -> Failed to send to ${remote}`);
|
|
293
|
+
if (result.error) {
|
|
294
|
+
log(` -> Error: ${result.error}`);
|
|
295
|
+
}
|
|
271
296
|
}
|
|
272
297
|
}
|
|
273
298
|
}
|
package/dist/prompts.js
CHANGED
|
@@ -6,28 +6,63 @@ exports.promptSelect = promptSelect;
|
|
|
6
6
|
exports.promptMultiSelect = promptMultiSelect;
|
|
7
7
|
// @ts-ignore
|
|
8
8
|
const { Select, Confirm, Input, MultiSelect } = require("enquirer");
|
|
9
|
+
// Suppress enquirer's readline error on Ctrl+C (Node.js 24+ issue)
|
|
10
|
+
process.on("uncaughtException", (err) => {
|
|
11
|
+
if (err.message?.includes("readline was closed")) {
|
|
12
|
+
console.log("\nCancelled");
|
|
13
|
+
process.exit(0);
|
|
14
|
+
}
|
|
15
|
+
throw err;
|
|
16
|
+
});
|
|
17
|
+
function handleCancel() {
|
|
18
|
+
console.log("\nCancelled");
|
|
19
|
+
process.exit(0);
|
|
20
|
+
}
|
|
9
21
|
async function promptConfirm(message) {
|
|
10
|
-
|
|
11
|
-
|
|
22
|
+
try {
|
|
23
|
+
const prompt = new Confirm({
|
|
24
|
+
name: "confirm",
|
|
25
|
+
message,
|
|
26
|
+
format: (v) => v ? "Y" : "N",
|
|
27
|
+
});
|
|
28
|
+
return await prompt.run();
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
handleCancel();
|
|
32
|
+
}
|
|
12
33
|
}
|
|
13
34
|
async function promptInput(message) {
|
|
14
|
-
|
|
15
|
-
|
|
35
|
+
try {
|
|
36
|
+
const prompt = new Input({ name: "input", message });
|
|
37
|
+
return await prompt.run();
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
handleCancel();
|
|
41
|
+
}
|
|
16
42
|
}
|
|
17
43
|
async function promptSelect(message, choices) {
|
|
18
|
-
|
|
19
|
-
|
|
44
|
+
try {
|
|
45
|
+
const prompt = new Select({ name: "select", message, choices });
|
|
46
|
+
return await prompt.run();
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
handleCancel();
|
|
50
|
+
}
|
|
20
51
|
}
|
|
21
52
|
async function promptMultiSelect(message, choices) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
53
|
+
try {
|
|
54
|
+
const prompt = new MultiSelect({
|
|
55
|
+
name: "multiselect",
|
|
56
|
+
message,
|
|
57
|
+
choices: choices,
|
|
58
|
+
initial: choices,
|
|
59
|
+
indicator(state, choice) {
|
|
60
|
+
return choice.enabled ? "●" : "○";
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
return await prompt.run();
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
handleCancel();
|
|
67
|
+
}
|
|
33
68
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clipshot",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"description": "Screenshot monitor CLI tool",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"build": "tsc",
|
|
11
|
+
"dev": "tsc && node dist/index.js",
|
|
11
12
|
"prepublishOnly": "npm run build"
|
|
12
13
|
},
|
|
13
14
|
"keywords": [
|
package/demo_video.gif
DELETED
|
Binary file
|