editprompt 1.5.0 → 1.7.0
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 +45 -10
- package/dist/index.js +816 -192
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2,15 +2,33 @@
|
|
|
2
2
|
import { configureSync, getAnsiColorFormatter, getLogger, getTextFormatter, parseLogLevel, withFilter } from "@logtape/logtape";
|
|
3
3
|
import { cli, define } from "gunshi";
|
|
4
4
|
import { appendFileSync } from "node:fs";
|
|
5
|
+
import { createHash, randomBytes } from "node:crypto";
|
|
6
|
+
import { createConnection } from "node:net";
|
|
7
|
+
import Conf from "conf";
|
|
5
8
|
import { exec, spawn } from "node:child_process";
|
|
6
9
|
import { promisify } from "node:util";
|
|
7
|
-
import Conf from "conf";
|
|
8
10
|
import clipboardy from "clipboardy";
|
|
9
11
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
10
|
-
import { randomBytes } from "node:crypto";
|
|
11
12
|
import { tmpdir } from "node:os";
|
|
12
13
|
import { join } from "node:path";
|
|
13
14
|
|
|
15
|
+
//#region \0rolldown/runtime.js
|
|
16
|
+
var __defProp = Object.defineProperty;
|
|
17
|
+
var __exportAll = (all, no_symbols) => {
|
|
18
|
+
let target = {};
|
|
19
|
+
for (var name in all) {
|
|
20
|
+
__defProp(target, name, {
|
|
21
|
+
get: all[name],
|
|
22
|
+
enumerable: true
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
if (!no_symbols) {
|
|
26
|
+
__defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
27
|
+
}
|
|
28
|
+
return target;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
//#endregion
|
|
14
32
|
//#region src/modules/logger.ts
|
|
15
33
|
function resolveLogFilePath(options) {
|
|
16
34
|
if (options.logFile) return options.logFile;
|
|
@@ -72,7 +90,7 @@ function setupLogger(options = {}) {
|
|
|
72
90
|
|
|
73
91
|
//#endregion
|
|
74
92
|
//#region package.json
|
|
75
|
-
var version = "1.
|
|
93
|
+
var version = "1.7.0";
|
|
76
94
|
|
|
77
95
|
//#endregion
|
|
78
96
|
//#region src/config/constants.ts
|
|
@@ -82,6 +100,9 @@ const DEFAULT_EDITOR = "vim";
|
|
|
82
100
|
const TMUX_IMSG_LIMIT_BYTES = 16 * 1024;
|
|
83
101
|
const TMUX_SEND_CHUNK_BYTES = TMUX_IMSG_LIMIT_BYTES / 2;
|
|
84
102
|
const WEZTERM_SEND_CHUNK_BYTES = TMUX_SEND_CHUNK_BYTES;
|
|
103
|
+
const HERDR_REQUEST_LIMIT_BYTES = 1024 * 1024;
|
|
104
|
+
const HERDR_SEND_CHUNK_BYTES = HERDR_REQUEST_LIMIT_BYTES / 8;
|
|
105
|
+
const NIWATERM_SEND_CHUNK_BYTES = WEZTERM_SEND_CHUNK_BYTES;
|
|
85
106
|
|
|
86
107
|
//#endregion
|
|
87
108
|
//#region src/utils/contentChunker.ts
|
|
@@ -111,10 +132,368 @@ function splitByByteSize(content, maxBytes) {
|
|
|
111
132
|
return chunks;
|
|
112
133
|
}
|
|
113
134
|
|
|
135
|
+
//#endregion
|
|
136
|
+
//#region src/modules/conf.ts
|
|
137
|
+
const projectName = process.env.NODE_ENV === "test" ? "editprompt-test" : "editprompt";
|
|
138
|
+
const conf = new Conf({ projectName });
|
|
139
|
+
|
|
140
|
+
//#endregion
|
|
141
|
+
//#region src/modules/herdr.ts
|
|
142
|
+
var herdr_exports = /* @__PURE__ */ __exportAll({
|
|
143
|
+
appendToQuoteText: () => appendToQuoteText$1,
|
|
144
|
+
calculateEditorSplitRatio: () => calculateEditorSplitRatio,
|
|
145
|
+
checkPaneExists: () => checkPaneExists$3,
|
|
146
|
+
clearEditorPaneId: () => clearEditorPaneId$3,
|
|
147
|
+
clearQuoteText: () => clearQuoteText$1,
|
|
148
|
+
closePane: () => closePane,
|
|
149
|
+
focusPane: () => focusPane$3,
|
|
150
|
+
getCurrentPaneId: () => getCurrentPaneId$3,
|
|
151
|
+
getEditorPaneId: () => getEditorPaneId$3,
|
|
152
|
+
getQuoteText: () => getQuoteText$1,
|
|
153
|
+
getStorageNamespace: () => getStorageNamespace,
|
|
154
|
+
getTargetPaneIds: () => getTargetPaneIds$3,
|
|
155
|
+
inputToHerdrPane: () => inputToHerdrPane,
|
|
156
|
+
isEditorPaneFromConf: () => isEditorPaneFromConf$1,
|
|
157
|
+
markAsEditorPane: () => markAsEditorPane$3,
|
|
158
|
+
resumeEditorPane: () => resumeEditorPane,
|
|
159
|
+
runCommandInPane: () => runCommandInPane,
|
|
160
|
+
saveEditorPaneId: () => saveEditorPaneId$3,
|
|
161
|
+
sendKeyToHerdrPane: () => sendKeyToHerdrPane,
|
|
162
|
+
splitEditorPane: () => splitEditorPane
|
|
163
|
+
});
|
|
164
|
+
const logger$14 = getLogger(["editprompt", "herdr"]);
|
|
165
|
+
const HERDR_REQUEST_TIMEOUT_MS = 6e3;
|
|
166
|
+
let requestSequence = 0;
|
|
167
|
+
function getSocketPath() {
|
|
168
|
+
const socketPath = process.env.HERDR_SOCKET_PATH?.trim();
|
|
169
|
+
if (!socketPath) throw new Error("HERDR_SOCKET_PATH is not set");
|
|
170
|
+
return socketPath;
|
|
171
|
+
}
|
|
172
|
+
async function sendRequest(method, params) {
|
|
173
|
+
const id = `editprompt_${process.pid}_${++requestSequence}`;
|
|
174
|
+
const request = `${JSON.stringify({
|
|
175
|
+
id,
|
|
176
|
+
method,
|
|
177
|
+
params
|
|
178
|
+
})}\n`;
|
|
179
|
+
return new Promise((resolve, reject) => {
|
|
180
|
+
const socket = createConnection(getSocketPath());
|
|
181
|
+
let buffer = "";
|
|
182
|
+
let settled = false;
|
|
183
|
+
const finish = (callback) => {
|
|
184
|
+
if (settled) return;
|
|
185
|
+
settled = true;
|
|
186
|
+
socket.end();
|
|
187
|
+
callback();
|
|
188
|
+
};
|
|
189
|
+
socket.setEncoding("utf8");
|
|
190
|
+
socket.setTimeout(HERDR_REQUEST_TIMEOUT_MS);
|
|
191
|
+
socket.on("connect", () => {
|
|
192
|
+
socket.write(request);
|
|
193
|
+
});
|
|
194
|
+
socket.on("data", (chunk) => {
|
|
195
|
+
buffer += chunk;
|
|
196
|
+
const newlineIndex = buffer.indexOf("\n");
|
|
197
|
+
if (newlineIndex === -1) return;
|
|
198
|
+
const line = buffer.slice(0, newlineIndex);
|
|
199
|
+
let response;
|
|
200
|
+
try {
|
|
201
|
+
response = JSON.parse(line);
|
|
202
|
+
} catch (error) {
|
|
203
|
+
finish(() => {
|
|
204
|
+
reject(/* @__PURE__ */ new Error(`Invalid response from Herdr: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
205
|
+
});
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
if (response.id !== id) {
|
|
209
|
+
finish(() => {
|
|
210
|
+
reject(/* @__PURE__ */ new Error(`Unexpected response ID from Herdr: ${response.id}`));
|
|
211
|
+
});
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
if (response.error) {
|
|
215
|
+
finish(() => {
|
|
216
|
+
reject(/* @__PURE__ */ new Error(`Herdr ${response.error?.code}: ${response.error?.message}`));
|
|
217
|
+
});
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
finish(() => {
|
|
221
|
+
resolve(response.result);
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
socket.on("error", (error) => {
|
|
225
|
+
finish(() => {
|
|
226
|
+
reject(/* @__PURE__ */ new Error(`Failed to communicate with Herdr: ${error.message}`));
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
socket.on("timeout", () => {
|
|
230
|
+
if (settled) return;
|
|
231
|
+
settled = true;
|
|
232
|
+
socket.destroy();
|
|
233
|
+
reject(/* @__PURE__ */ new Error(`Timed out waiting for Herdr response after ${HERDR_REQUEST_TIMEOUT_MS}ms`));
|
|
234
|
+
});
|
|
235
|
+
socket.on("end", () => {
|
|
236
|
+
if (!settled) finish(() => {
|
|
237
|
+
reject(/* @__PURE__ */ new Error("Herdr closed the socket before sending a response"));
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
function getStorageNamespace() {
|
|
243
|
+
return `herdr.session_${createHash("sha256").update(getSocketPath()).digest("hex").slice(0, 16)}`;
|
|
244
|
+
}
|
|
245
|
+
function targetPaneKey(paneId) {
|
|
246
|
+
return `${getStorageNamespace()}.targetPane.pane_${paneId}`;
|
|
247
|
+
}
|
|
248
|
+
function editorPaneKey(paneId) {
|
|
249
|
+
return `${getStorageNamespace()}.editorPane.pane_${paneId}`;
|
|
250
|
+
}
|
|
251
|
+
async function getCurrentPaneId$3() {
|
|
252
|
+
const paneId = process.env.HERDR_PANE_ID?.trim() || process.env.HERDR_ACTIVE_PANE_ID?.trim();
|
|
253
|
+
if (!paneId) throw new Error("HERDR_PANE_ID or HERDR_ACTIVE_PANE_ID is not set");
|
|
254
|
+
return paneId;
|
|
255
|
+
}
|
|
256
|
+
async function checkPaneExists$3(paneId) {
|
|
257
|
+
try {
|
|
258
|
+
await sendRequest("pane.get", { pane_id: paneId });
|
|
259
|
+
return true;
|
|
260
|
+
} catch (error) {
|
|
261
|
+
logger$14.debug("checkPaneExists failed: {error}", { error });
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
async function focusPane$3(paneId) {
|
|
266
|
+
await sendRequest("pane.focus", { pane_id: paneId });
|
|
267
|
+
}
|
|
268
|
+
function calculateEditorSplitRatio(paneHeight, editorPaneRows) {
|
|
269
|
+
if (!Number.isInteger(paneHeight) || paneHeight <= 1) throw new Error(`Invalid Herdr pane height: ${paneHeight}`);
|
|
270
|
+
if (!Number.isInteger(editorPaneRows) || editorPaneRows <= 0) throw new Error(`Invalid Herdr editor pane rows: ${editorPaneRows}`);
|
|
271
|
+
return Math.min(.9, Math.max(.1, 1 - editorPaneRows / paneHeight));
|
|
272
|
+
}
|
|
273
|
+
async function splitEditorPane(targetPaneId, editorPaneRows, cwd, env = {}) {
|
|
274
|
+
const paneHeight = ((await sendRequest("pane.layout", { pane_id: targetPaneId })).layout?.panes?.find((pane) => pane.pane_id === targetPaneId))?.rect?.height;
|
|
275
|
+
if (typeof paneHeight !== "number") throw new Error(`Herdr pane.layout did not return a height for pane ${targetPaneId}`);
|
|
276
|
+
const params = {
|
|
277
|
+
target_pane_id: targetPaneId,
|
|
278
|
+
direction: "down",
|
|
279
|
+
ratio: calculateEditorSplitRatio(paneHeight, editorPaneRows),
|
|
280
|
+
focus: true,
|
|
281
|
+
env
|
|
282
|
+
};
|
|
283
|
+
if (cwd?.trim()) params.cwd = cwd;
|
|
284
|
+
const editorPaneId = (await sendRequest("pane.split", params)).pane?.pane_id;
|
|
285
|
+
if (typeof editorPaneId !== "string" || editorPaneId === "") throw new Error("Herdr pane.split did not return the new pane ID");
|
|
286
|
+
return editorPaneId;
|
|
287
|
+
}
|
|
288
|
+
function quoteShellWord$1(value) {
|
|
289
|
+
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
290
|
+
}
|
|
291
|
+
async function runCommandInPane(paneId, argv) {
|
|
292
|
+
if (argv.length === 0) throw new Error("Cannot run an empty command in a Herdr pane");
|
|
293
|
+
await sendRequest("pane.send_input", {
|
|
294
|
+
pane_id: paneId,
|
|
295
|
+
text: `exec ${argv.map(quoteShellWord$1).join(" ")}`,
|
|
296
|
+
keys: ["Enter"]
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
async function closePane(paneId) {
|
|
300
|
+
await sendRequest("pane.close", { pane_id: paneId });
|
|
301
|
+
}
|
|
302
|
+
async function inputToHerdrPane(paneId, content) {
|
|
303
|
+
const chunks = splitByByteSize(content, HERDR_SEND_CHUNK_BYTES);
|
|
304
|
+
for (const chunk of chunks) await sendRequest("pane.send_text", {
|
|
305
|
+
pane_id: paneId,
|
|
306
|
+
text: chunk
|
|
307
|
+
});
|
|
308
|
+
logger$14.debug("Content sent to Herdr pane: {paneId} ({chunkCount} chunks)", {
|
|
309
|
+
paneId,
|
|
310
|
+
chunkCount: chunks.length
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
async function sendKeyToHerdrPane(paneId, key, delay = 1e3) {
|
|
314
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
315
|
+
await sendRequest("pane.send_keys", {
|
|
316
|
+
pane_id: paneId,
|
|
317
|
+
keys: [key]
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
async function saveEditorPaneId$3(targetPaneId, editorPaneId) {
|
|
321
|
+
const data = conf.get(targetPaneKey(targetPaneId));
|
|
322
|
+
const existing = typeof data === "object" && data !== null ? data : {};
|
|
323
|
+
conf.set(targetPaneKey(targetPaneId), {
|
|
324
|
+
...existing,
|
|
325
|
+
editorPaneId
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
async function getEditorPaneId$3(targetPaneId) {
|
|
329
|
+
const data = conf.get(targetPaneKey(targetPaneId));
|
|
330
|
+
if (typeof data === "object" && data !== null && "editorPaneId" in data) return String(data.editorPaneId);
|
|
331
|
+
return "";
|
|
332
|
+
}
|
|
333
|
+
async function clearEditorPaneId$3(targetPaneId, expectedEditorPaneId) {
|
|
334
|
+
const editorPaneId = await getEditorPaneId$3(targetPaneId);
|
|
335
|
+
if (expectedEditorPaneId && editorPaneId !== expectedEditorPaneId) {
|
|
336
|
+
conf.delete(editorPaneKey(expectedEditorPaneId));
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
const data = conf.get(targetPaneKey(targetPaneId));
|
|
340
|
+
if (typeof data === "object" && data !== null && "editorPaneId" in data) {
|
|
341
|
+
const { editorPaneId: _, ...remaining } = data;
|
|
342
|
+
if (Object.keys(remaining).length === 0) conf.delete(targetPaneKey(targetPaneId));
|
|
343
|
+
else conf.set(targetPaneKey(targetPaneId), remaining);
|
|
344
|
+
}
|
|
345
|
+
if (editorPaneId) conf.delete(editorPaneKey(editorPaneId));
|
|
346
|
+
}
|
|
347
|
+
async function markAsEditorPane$3(editorPaneId, targetPaneIds) {
|
|
348
|
+
const uniqueTargetPaneIds = [...new Set(targetPaneIds)];
|
|
349
|
+
conf.set(editorPaneKey(editorPaneId), { targetPaneIds: uniqueTargetPaneIds });
|
|
350
|
+
for (const targetPaneId of uniqueTargetPaneIds) await saveEditorPaneId$3(targetPaneId, editorPaneId);
|
|
351
|
+
}
|
|
352
|
+
async function getTargetPaneIds$3(editorPaneId) {
|
|
353
|
+
const data = conf.get(editorPaneKey(editorPaneId));
|
|
354
|
+
if (typeof data === "object" && data !== null && "targetPaneIds" in data) {
|
|
355
|
+
const targetPaneIds = data.targetPaneIds;
|
|
356
|
+
if (Array.isArray(targetPaneIds)) return targetPaneIds.map((id) => String(id));
|
|
357
|
+
}
|
|
358
|
+
return [];
|
|
359
|
+
}
|
|
360
|
+
function isEditorPaneFromConf$1(paneId) {
|
|
361
|
+
return conf.has(editorPaneKey(paneId));
|
|
362
|
+
}
|
|
363
|
+
async function resumeEditorPane(targetPaneId) {
|
|
364
|
+
const currentPaneId = await getCurrentPaneId$3();
|
|
365
|
+
const editorPaneId = isEditorPaneFromConf$1(currentPaneId) ? currentPaneId : isEditorPaneFromConf$1(targetPaneId) ? targetPaneId : "";
|
|
366
|
+
if (editorPaneId) {
|
|
367
|
+
const targetPaneIds = await getTargetPaneIds$3(editorPaneId);
|
|
368
|
+
for (const paneId of targetPaneIds) if (await checkPaneExists$3(paneId)) {
|
|
369
|
+
await focusPane$3(paneId);
|
|
370
|
+
return true;
|
|
371
|
+
}
|
|
372
|
+
return false;
|
|
373
|
+
}
|
|
374
|
+
const registeredEditorPaneId = await getEditorPaneId$3(targetPaneId);
|
|
375
|
+
if (registeredEditorPaneId === "") return false;
|
|
376
|
+
if (!await checkPaneExists$3(registeredEditorPaneId)) {
|
|
377
|
+
await clearEditorPaneId$3(targetPaneId);
|
|
378
|
+
return false;
|
|
379
|
+
}
|
|
380
|
+
await focusPane$3(registeredEditorPaneId);
|
|
381
|
+
return true;
|
|
382
|
+
}
|
|
383
|
+
async function appendToQuoteText$1(paneId, content) {
|
|
384
|
+
const data = conf.get(targetPaneKey(paneId));
|
|
385
|
+
const existing = typeof data === "object" && data !== null ? data : {};
|
|
386
|
+
const existingQuoteText = "quote_text" in existing ? String(existing.quote_text) : "";
|
|
387
|
+
const quoteText = existingQuoteText.trim() !== "" ? `${existingQuoteText}\n\n${content}` : content;
|
|
388
|
+
conf.set(targetPaneKey(paneId), {
|
|
389
|
+
...existing,
|
|
390
|
+
quote_text: quoteText
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
async function getQuoteText$1(paneId) {
|
|
394
|
+
const data = conf.get(targetPaneKey(paneId));
|
|
395
|
+
if (typeof data === "object" && data !== null && "quote_text" in data) return String(data.quote_text);
|
|
396
|
+
return "";
|
|
397
|
+
}
|
|
398
|
+
async function clearQuoteText$1(paneId) {
|
|
399
|
+
const data = conf.get(targetPaneKey(paneId));
|
|
400
|
+
if (typeof data === "object" && data !== null && "quote_text" in data) {
|
|
401
|
+
const { quote_text: _, ...remaining } = data;
|
|
402
|
+
if (Object.keys(remaining).length === 0) conf.delete(targetPaneKey(paneId));
|
|
403
|
+
else conf.set(targetPaneKey(paneId), remaining);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
//#endregion
|
|
408
|
+
//#region src/modules/niwaterm.ts
|
|
409
|
+
const execAsync$2 = promisify(exec);
|
|
410
|
+
const logger$13 = getLogger(["editprompt", "niwaterm"]);
|
|
411
|
+
const VAR_EDITOR_PANE = "editprompt_editor_pane";
|
|
412
|
+
const VAR_IS_EDITOR = "editprompt_is_editor";
|
|
413
|
+
const VAR_TARGET_PANES = "editprompt_target_panes";
|
|
414
|
+
const VAR_QUOTE = "editprompt_quote";
|
|
415
|
+
function quoteShellWord(value) {
|
|
416
|
+
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
417
|
+
}
|
|
418
|
+
async function getCurrentPaneId$2() {
|
|
419
|
+
const tabId = process.env.NIWATERM_TAB_ID?.trim();
|
|
420
|
+
if (!tabId) throw new Error("NIWATERM_TAB_ID is not set");
|
|
421
|
+
return tabId;
|
|
422
|
+
}
|
|
423
|
+
async function getTabVar(tabId, key) {
|
|
424
|
+
try {
|
|
425
|
+
const { stdout } = await execAsync$2(`niwa tab var get -t ${quoteShellWord(tabId)} ${quoteShellWord(key)}`);
|
|
426
|
+
return stdout.trim();
|
|
427
|
+
} catch (error) {
|
|
428
|
+
logger$13.debug("getTabVar failed: {error}", { error });
|
|
429
|
+
return "";
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
async function setTabVar(tabId, key, value) {
|
|
433
|
+
await execAsync$2(`niwa tab var set -t ${quoteShellWord(tabId)} ${quoteShellWord(key)} ${quoteShellWord(value)}`);
|
|
434
|
+
}
|
|
435
|
+
async function checkPaneExists$2(paneId) {
|
|
436
|
+
try {
|
|
437
|
+
await execAsync$2(`niwa tab var list -t ${quoteShellWord(paneId)}`);
|
|
438
|
+
return true;
|
|
439
|
+
} catch (error) {
|
|
440
|
+
logger$13.debug("checkPaneExists failed: {error}", { error });
|
|
441
|
+
return false;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
async function focusPane$2(paneId) {
|
|
445
|
+
await execAsync$2(`niwa tab focus -t ${quoteShellWord(paneId)}`);
|
|
446
|
+
}
|
|
447
|
+
async function saveEditorPaneId$2(targetPaneId, editorPaneId) {
|
|
448
|
+
await setTabVar(targetPaneId, VAR_EDITOR_PANE, editorPaneId);
|
|
449
|
+
}
|
|
450
|
+
async function clearEditorPaneId$2(targetPaneId) {
|
|
451
|
+
await setTabVar(targetPaneId, VAR_EDITOR_PANE, "");
|
|
452
|
+
}
|
|
453
|
+
async function getEditorPaneId$2(targetPaneId) {
|
|
454
|
+
return getTabVar(targetPaneId, VAR_EDITOR_PANE);
|
|
455
|
+
}
|
|
456
|
+
async function markAsEditorPane$2(editorPaneId, targetPaneIds) {
|
|
457
|
+
const uniqueTargetPaneIds = [...new Set(targetPaneIds)];
|
|
458
|
+
await setTabVar(editorPaneId, VAR_IS_EDITOR, "1");
|
|
459
|
+
await setTabVar(editorPaneId, VAR_TARGET_PANES, uniqueTargetPaneIds.join(","));
|
|
460
|
+
for (const targetPaneId of uniqueTargetPaneIds) await saveEditorPaneId$2(targetPaneId, editorPaneId);
|
|
461
|
+
}
|
|
462
|
+
async function getTargetPaneIds$2(editorPaneId) {
|
|
463
|
+
const value = await getTabVar(editorPaneId, VAR_TARGET_PANES);
|
|
464
|
+
if (value === "") return [];
|
|
465
|
+
return value.split(",").map((id) => id.trim());
|
|
466
|
+
}
|
|
467
|
+
async function isEditorPane$1(paneId) {
|
|
468
|
+
return await getTabVar(paneId, VAR_IS_EDITOR) === "1";
|
|
469
|
+
}
|
|
470
|
+
async function getQuoteVariableContent$1(paneId) {
|
|
471
|
+
return getTabVar(paneId, VAR_QUOTE);
|
|
472
|
+
}
|
|
473
|
+
async function appendToQuoteVariable$1(paneId, content) {
|
|
474
|
+
const existingContent = await getQuoteVariableContent$1(paneId);
|
|
475
|
+
await setTabVar(paneId, VAR_QUOTE, existingContent.trim() !== "" ? `${existingContent}\n${content}` : content);
|
|
476
|
+
}
|
|
477
|
+
async function clearQuoteVariable$1(paneId) {
|
|
478
|
+
await setTabVar(paneId, VAR_QUOTE, "");
|
|
479
|
+
}
|
|
480
|
+
async function sendKeyToNiwatermPane(paneId, key, delay = 1e3) {
|
|
481
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
482
|
+
await execAsync$2(`niwa tab send-keys -t ${quoteShellWord(paneId)} ${quoteShellWord(key)}`);
|
|
483
|
+
}
|
|
484
|
+
async function inputToNiwatermPane(paneId, content) {
|
|
485
|
+
const chunks = splitByByteSize(content, NIWATERM_SEND_CHUNK_BYTES);
|
|
486
|
+
for (const chunk of chunks) await execAsync$2(`niwa tab send-keys -t ${quoteShellWord(paneId)} ${quoteShellWord(chunk)}`);
|
|
487
|
+
logger$13.debug("Content sent to niwaterm pane: {paneId} ({chunks} chunk(s))", {
|
|
488
|
+
paneId,
|
|
489
|
+
chunks: chunks.length
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
|
|
114
493
|
//#endregion
|
|
115
494
|
//#region src/modules/tmux.ts
|
|
116
495
|
const execAsync$1 = promisify(exec);
|
|
117
|
-
const logger$
|
|
496
|
+
const logger$12 = getLogger(["editprompt", "tmux"]);
|
|
118
497
|
async function getCurrentPaneId$1() {
|
|
119
498
|
const envPaneId = process.env.TMUX_PANE?.trim();
|
|
120
499
|
if (envPaneId) return envPaneId;
|
|
@@ -196,20 +575,15 @@ async function inputToTmuxPane(paneId, content) {
|
|
|
196
575
|
await execAsync$1(`tmux if-shell -t '${paneId}' '[ "#{pane_in_mode}" = "1" ]' "copy-mode -q -t '${paneId}'"`);
|
|
197
576
|
const chunks = splitByByteSize(content, TMUX_SEND_CHUNK_BYTES);
|
|
198
577
|
for (const chunk of chunks) await execAsync$1(`tmux send-keys -t '${paneId}' -- '${chunk.replace(/'/g, "'\\''")}'`);
|
|
199
|
-
logger$
|
|
578
|
+
logger$12.debug("Content sent to tmux pane: {paneId} ({chunks} chunk(s))", {
|
|
200
579
|
paneId,
|
|
201
580
|
chunks: chunks.length
|
|
202
581
|
});
|
|
203
582
|
}
|
|
204
583
|
|
|
205
|
-
//#endregion
|
|
206
|
-
//#region src/modules/conf.ts
|
|
207
|
-
const projectName = process.env.NODE_ENV === "test" ? "editprompt-test" : "editprompt";
|
|
208
|
-
const conf = new Conf({ projectName });
|
|
209
|
-
|
|
210
584
|
//#endregion
|
|
211
585
|
//#region src/modules/wezterm.ts
|
|
212
|
-
const logger$
|
|
586
|
+
const logger$11 = getLogger(["editprompt", "wezterm"]);
|
|
213
587
|
const execAsync = promisify(exec);
|
|
214
588
|
async function getCurrentPaneId() {
|
|
215
589
|
try {
|
|
@@ -217,26 +591,26 @@ async function getCurrentPaneId() {
|
|
|
217
591
|
const activePane = JSON.parse(stdout).find((pane) => pane.is_active === true);
|
|
218
592
|
return String(activePane?.pane_id);
|
|
219
593
|
} catch (error) {
|
|
220
|
-
logger$
|
|
594
|
+
logger$11.debug("getCurrentPaneId failed: {error}", { error });
|
|
221
595
|
return "";
|
|
222
596
|
}
|
|
223
597
|
}
|
|
224
598
|
async function checkPaneExists(paneId) {
|
|
225
599
|
try {
|
|
226
600
|
const { stdout } = await execAsync("wezterm cli list --format json");
|
|
227
|
-
logger$
|
|
601
|
+
logger$11.debug("wezterm cli list output: {stdout}", { stdout });
|
|
228
602
|
return JSON.parse(stdout).some((pane) => String(pane.pane_id) === paneId);
|
|
229
603
|
} catch (error) {
|
|
230
|
-
logger$
|
|
604
|
+
logger$11.debug("checkPaneExists failed: {error}", { error });
|
|
231
605
|
return false;
|
|
232
606
|
}
|
|
233
607
|
}
|
|
234
608
|
async function saveEditorPaneId(targetPaneId, editorPaneId) {
|
|
235
|
-
logger$
|
|
609
|
+
logger$11.debug("Saving editor pane ID to conf key: wezterm.targetPane.pane_{targetPaneId}", { targetPaneId });
|
|
236
610
|
try {
|
|
237
611
|
conf.set(`wezterm.targetPane.pane_${targetPaneId}`, { editorPaneId });
|
|
238
612
|
} catch (error) {
|
|
239
|
-
logger$
|
|
613
|
+
logger$11.debug("saveEditorPaneId failed: {error}", { error });
|
|
240
614
|
}
|
|
241
615
|
}
|
|
242
616
|
async function getEditorPaneId(targetPaneId) {
|
|
@@ -245,7 +619,7 @@ async function getEditorPaneId(targetPaneId) {
|
|
|
245
619
|
if (typeof data === "object" && data !== null && "editorPaneId" in data) return String(data.editorPaneId);
|
|
246
620
|
return "";
|
|
247
621
|
} catch (error) {
|
|
248
|
-
logger$
|
|
622
|
+
logger$11.debug("getEditorPaneId failed: {error}", { error });
|
|
249
623
|
return "";
|
|
250
624
|
}
|
|
251
625
|
}
|
|
@@ -255,7 +629,7 @@ async function clearEditorPaneId(targetPaneId) {
|
|
|
255
629
|
conf.delete(`wezterm.targetPane.pane_${targetPaneId}`);
|
|
256
630
|
if (editorPaneId) conf.delete(`wezterm.editorPane.pane_${editorPaneId}`);
|
|
257
631
|
} catch (error) {
|
|
258
|
-
logger$
|
|
632
|
+
logger$11.debug("clearEditorPaneId failed: {error}", { error });
|
|
259
633
|
}
|
|
260
634
|
}
|
|
261
635
|
async function focusPane(paneId) {
|
|
@@ -267,7 +641,7 @@ async function markAsEditorPane(editorPaneId, targetPaneIds) {
|
|
|
267
641
|
conf.set(`wezterm.editorPane.pane_${editorPaneId}`, { targetPaneIds: uniqueTargetPaneIds });
|
|
268
642
|
for (const targetPaneId of uniqueTargetPaneIds) await saveEditorPaneId(targetPaneId, editorPaneId);
|
|
269
643
|
} catch (error) {
|
|
270
|
-
logger$
|
|
644
|
+
logger$11.debug("markAsEditorPane failed: {error}", { error });
|
|
271
645
|
}
|
|
272
646
|
}
|
|
273
647
|
async function getTargetPaneIds(editorPaneId) {
|
|
@@ -279,7 +653,7 @@ async function getTargetPaneIds(editorPaneId) {
|
|
|
279
653
|
}
|
|
280
654
|
return [];
|
|
281
655
|
} catch (error) {
|
|
282
|
-
logger$
|
|
656
|
+
logger$11.debug("getTargetPaneIds failed: {error}", { error });
|
|
283
657
|
return [];
|
|
284
658
|
}
|
|
285
659
|
}
|
|
@@ -287,7 +661,7 @@ function isEditorPaneFromConf(paneId) {
|
|
|
287
661
|
try {
|
|
288
662
|
return conf.has(`wezterm.editorPane.pane_${paneId}`);
|
|
289
663
|
} catch (error) {
|
|
290
|
-
logger$
|
|
664
|
+
logger$11.debug("isEditorPaneFromConf failed: {error}", { error });
|
|
291
665
|
return false;
|
|
292
666
|
}
|
|
293
667
|
}
|
|
@@ -305,7 +679,7 @@ async function appendToQuoteText(paneId, content) {
|
|
|
305
679
|
} else newData = { quote_text: content };
|
|
306
680
|
conf.set(`wezterm.targetPane.pane_${paneId}`, newData);
|
|
307
681
|
} catch (error) {
|
|
308
|
-
logger$
|
|
682
|
+
logger$11.debug("appendToQuoteText failed: {error}", { error });
|
|
309
683
|
}
|
|
310
684
|
}
|
|
311
685
|
async function getQuoteText(paneId) {
|
|
@@ -314,7 +688,7 @@ async function getQuoteText(paneId) {
|
|
|
314
688
|
if (typeof data === "object" && data !== null && "quote_text" in data) return String(data.quote_text);
|
|
315
689
|
return "";
|
|
316
690
|
} catch (error) {
|
|
317
|
-
logger$
|
|
691
|
+
logger$11.debug("getQuoteText failed: {error}", { error });
|
|
318
692
|
return "";
|
|
319
693
|
}
|
|
320
694
|
}
|
|
@@ -323,7 +697,7 @@ async function clearQuoteText(paneId) {
|
|
|
323
697
|
const key = `wezterm.targetPane.pane_${paneId}.quote_text`;
|
|
324
698
|
if (conf.has(key)) conf.delete(key);
|
|
325
699
|
} catch (error) {
|
|
326
|
-
logger$
|
|
700
|
+
logger$11.debug("clearQuoteText failed: {error}", { error });
|
|
327
701
|
}
|
|
328
702
|
}
|
|
329
703
|
async function sendKeyToWeztermPane(paneId, key, delay = 1e3) {
|
|
@@ -333,7 +707,7 @@ async function sendKeyToWeztermPane(paneId, key, delay = 1e3) {
|
|
|
333
707
|
async function inputToWeztermPane(paneId, content) {
|
|
334
708
|
const chunks = splitByByteSize(content, WEZTERM_SEND_CHUNK_BYTES);
|
|
335
709
|
for (const chunk of chunks) await execAsync(`wezterm cli send-text --no-paste --pane-id '${paneId}' -- '${chunk.replace(/'/g, "'\\''")}'`);
|
|
336
|
-
logger$
|
|
710
|
+
logger$11.debug("Content sent to wezterm pane: {paneId} ({chunks} chunk(s))", {
|
|
337
711
|
paneId,
|
|
338
712
|
chunks: chunks.length
|
|
339
713
|
});
|
|
@@ -477,87 +851,40 @@ function processQuoteText(text, options) {
|
|
|
477
851
|
}
|
|
478
852
|
|
|
479
853
|
//#endregion
|
|
480
|
-
//#region src/
|
|
481
|
-
const
|
|
854
|
+
//#region src/utils/mux.ts
|
|
855
|
+
const SUPPORTED_MUXES = [
|
|
856
|
+
"tmux",
|
|
857
|
+
"wezterm",
|
|
858
|
+
"herdr",
|
|
859
|
+
"niwaterm"
|
|
860
|
+
];
|
|
482
861
|
function isMuxType(value) {
|
|
483
|
-
return value === "tmux" || value === "wezterm";
|
|
862
|
+
return value === "tmux" || value === "wezterm" || value === "herdr" || value === "niwaterm";
|
|
484
863
|
}
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
await clipboardy.write(content);
|
|
864
|
+
function hasValue(value) {
|
|
865
|
+
return typeof value === "string" && value.trim() !== "";
|
|
488
866
|
}
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
else await inputToTmuxPane(targetPaneId, content);
|
|
867
|
+
function isHerdrEnvironment(env = process.env) {
|
|
868
|
+
return hasValue(env.HERDR_SOCKET_PATH) && (hasValue(env.HERDR_PANE_ID) || hasValue(env.HERDR_ACTIVE_PANE_ID));
|
|
492
869
|
}
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
if (firstSuccessPane) if (mux === "tmux") await focusPane$1(firstSuccessPane);
|
|
496
|
-
else await focusPane(firstSuccessPane);
|
|
870
|
+
function isNiwatermEnvironment(env = process.env) {
|
|
871
|
+
return hasValue(env.NIWATERM_TAB_ID);
|
|
497
872
|
}
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
allFailed: false,
|
|
504
|
-
failedPanes: []
|
|
505
|
-
};
|
|
506
|
-
if (targetPanes.length === 0) {
|
|
507
|
-
try {
|
|
508
|
-
await copyToClipboard(content);
|
|
509
|
-
logger$9.info("Content copied to clipboard.");
|
|
510
|
-
} catch (error) {
|
|
511
|
-
logger$9.warn(`Failed to copy to clipboard: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
512
|
-
}
|
|
513
|
-
return {
|
|
514
|
-
successCount: 0,
|
|
515
|
-
totalCount: 0,
|
|
516
|
-
allSuccess: true,
|
|
517
|
-
allFailed: false,
|
|
518
|
-
failedPanes: []
|
|
519
|
-
};
|
|
520
|
-
}
|
|
521
|
-
const results = [];
|
|
522
|
-
for (const targetPane of targetPanes) try {
|
|
523
|
-
await inputContentToPane(content, mux, targetPane);
|
|
524
|
-
results.push({
|
|
525
|
-
pane: targetPane,
|
|
526
|
-
success: true
|
|
527
|
-
});
|
|
528
|
-
} catch (error) {
|
|
529
|
-
logger$9.warn(`Failed to send to pane ${targetPane}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
530
|
-
results.push({
|
|
531
|
-
pane: targetPane,
|
|
532
|
-
success: false
|
|
533
|
-
});
|
|
873
|
+
function resolveMux(explicitMux, env = process.env) {
|
|
874
|
+
const muxValue = explicitMux || env.EDITPROMPT_MUX || (isHerdrEnvironment(env) ? "herdr" : isNiwatermEnvironment(env) ? "niwaterm" : "tmux");
|
|
875
|
+
if (!isMuxType(muxValue)) {
|
|
876
|
+
const displayValue = typeof muxValue === "string" ? muxValue : `<${typeof muxValue}>`;
|
|
877
|
+
throw new Error(`Invalid multiplexer type '${displayValue}'. Supported values: ${SUPPORTED_MUXES.join(", ")}`);
|
|
534
878
|
}
|
|
535
|
-
|
|
536
|
-
const failedPanes = results.filter((r) => !r.success).map((r) => r.pane);
|
|
537
|
-
const allSuccess = successCount === targetPanes.length;
|
|
538
|
-
const allFailed = successCount === 0;
|
|
539
|
-
if (allSuccess) logger$9.info("Content sent successfully to all panes!");
|
|
540
|
-
else if (allFailed) {
|
|
541
|
-
logger$9.error("All target panes failed to receive content.");
|
|
542
|
-
logger$9.info("Falling back to clipboard...");
|
|
543
|
-
await copyToClipboard(content);
|
|
544
|
-
logger$9.info("Content copied to clipboard.");
|
|
545
|
-
} else logger$9.warn(`Content sent to ${successCount}/${targetPanes.length} panes. Failed panes: ${failedPanes.join(", ")}`);
|
|
546
|
-
return {
|
|
547
|
-
successCount,
|
|
548
|
-
totalCount: targetPanes.length,
|
|
549
|
-
allSuccess,
|
|
550
|
-
allFailed,
|
|
551
|
-
failedPanes
|
|
552
|
-
};
|
|
879
|
+
return muxValue;
|
|
553
880
|
}
|
|
554
881
|
|
|
555
882
|
//#endregion
|
|
556
883
|
//#region src/modes/args.ts
|
|
557
|
-
const logger$
|
|
884
|
+
const logger$10 = getLogger(["editprompt"]);
|
|
558
885
|
const ARG_MUX = {
|
|
559
886
|
short: "m",
|
|
560
|
-
description: "Multiplexer type (tmux or
|
|
887
|
+
description: "Multiplexer type (tmux, wezterm, herdr, or niwaterm; auto-detects Herdr and niwaterm, otherwise tmux)",
|
|
561
888
|
type: "string"
|
|
562
889
|
};
|
|
563
890
|
const ARG_TARGET_PANE_SINGLE = {
|
|
@@ -603,17 +930,23 @@ const ARG_VERBOSE = {
|
|
|
603
930
|
description: "Enable debug-level log output",
|
|
604
931
|
type: "boolean"
|
|
605
932
|
};
|
|
933
|
+
const ARG_ENV = {
|
|
934
|
+
short: "E",
|
|
935
|
+
description: "Environment variables to set (e.g., KEY=VALUE)",
|
|
936
|
+
type: "string",
|
|
937
|
+
multiple: true
|
|
938
|
+
};
|
|
606
939
|
function validateMux(value) {
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
940
|
+
try {
|
|
941
|
+
return resolveMux(value);
|
|
942
|
+
} catch (error) {
|
|
943
|
+
logger$10.error(error instanceof Error ? error.message : String(error));
|
|
610
944
|
process.exit(1);
|
|
611
945
|
}
|
|
612
|
-
return muxValue;
|
|
613
946
|
}
|
|
614
947
|
function validateTargetPane(value, commandName) {
|
|
615
948
|
if (!value || typeof value !== "string") {
|
|
616
|
-
logger$
|
|
949
|
+
logger$10.error(`--target-pane is required for ${commandName} command`);
|
|
617
950
|
process.exit(1);
|
|
618
951
|
}
|
|
619
952
|
return value;
|
|
@@ -626,7 +959,7 @@ function normalizeTargetPanes(value) {
|
|
|
626
959
|
|
|
627
960
|
//#endregion
|
|
628
961
|
//#region src/modes/collect.ts
|
|
629
|
-
const logger$
|
|
962
|
+
const logger$9 = getLogger(["editprompt", "collect"]);
|
|
630
963
|
const SUPPORTED_OUTPUTS = ["buffer", "stdout"];
|
|
631
964
|
async function readStdin() {
|
|
632
965
|
return new Promise((resolve, reject) => {
|
|
@@ -650,7 +983,7 @@ function normalizeCollectOutputs(value) {
|
|
|
650
983
|
const uniqueOutputs = [...new Set(outputs)];
|
|
651
984
|
const invalid = uniqueOutputs.filter((v) => !SUPPORTED_OUTPUTS.includes(v));
|
|
652
985
|
if (invalid.length > 0) {
|
|
653
|
-
logger$
|
|
986
|
+
logger$9.error(`Invalid output(s) '${invalid.join(", ")}'. Supported values: ${SUPPORTED_OUTPUTS.join(", ")}`);
|
|
654
987
|
process.exit(1);
|
|
655
988
|
}
|
|
656
989
|
return uniqueOutputs;
|
|
@@ -661,12 +994,13 @@ async function runCollectMode(mux, targetPaneId, rawContent, outputs = ["buffer"
|
|
|
661
994
|
if (rawContent !== void 0) selection = rawContent;
|
|
662
995
|
else selection = await readStdin();
|
|
663
996
|
const processedText = processQuoteText(selection, { withQuote });
|
|
664
|
-
for (const output of outputs) if (output === "buffer")
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
997
|
+
for (const output of outputs) if (output === "buffer") if (mux === "tmux") await appendToQuoteVariable(targetPaneId, processedText);
|
|
998
|
+
else if (mux === "wezterm") await appendToQuoteText(targetPaneId, processedText);
|
|
999
|
+
else if (mux === "niwaterm") await appendToQuoteVariable$1(targetPaneId, processedText);
|
|
1000
|
+
else await appendToQuoteText$1(targetPaneId, processedText);
|
|
1001
|
+
else if (output === "stdout") process.stdout.write(processedText);
|
|
668
1002
|
} catch (error) {
|
|
669
|
-
logger$
|
|
1003
|
+
logger$9.error(`${error instanceof Error ? error.message : "Unknown error"}`);
|
|
670
1004
|
process.exit(1);
|
|
671
1005
|
}
|
|
672
1006
|
}
|
|
@@ -693,10 +1027,10 @@ const collectCommand = define({
|
|
|
693
1027
|
const outputs = normalizeCollectOutputs(ctx.values.output);
|
|
694
1028
|
const withQuote = !ctx.values["no-quote"];
|
|
695
1029
|
let rawContent;
|
|
696
|
-
if (mux === "wezterm") {
|
|
1030
|
+
if (mux === "wezterm" || mux === "herdr" || mux === "niwaterm") {
|
|
697
1031
|
rawContent = extractRawContent(ctx.rest, ctx.positionals);
|
|
698
1032
|
if (rawContent === void 0) {
|
|
699
|
-
logger$
|
|
1033
|
+
logger$9.error(`Text content is required for collect mode with ${mux}. Use: editprompt collect --mux ${mux} --target-pane <id> -- "<text>"`);
|
|
700
1034
|
process.exit(1);
|
|
701
1035
|
}
|
|
702
1036
|
}
|
|
@@ -706,11 +1040,8 @@ const collectCommand = define({
|
|
|
706
1040
|
|
|
707
1041
|
//#endregion
|
|
708
1042
|
//#region src/utils/sendConfig.ts
|
|
709
|
-
const VALID_MUX_TYPES = ["tmux", "wezterm"];
|
|
710
1043
|
function readSendConfig() {
|
|
711
|
-
const
|
|
712
|
-
if (!VALID_MUX_TYPES.includes(muxValue)) throw new Error(`Invalid EDITPROMPT_MUX value: ${muxValue}. Must be one of: ${VALID_MUX_TYPES.join(", ")}`);
|
|
713
|
-
const mux = muxValue;
|
|
1044
|
+
const mux = resolveMux();
|
|
714
1045
|
const alwaysCopy = process.env.EDITPROMPT_ALWAYS_COPY === "1";
|
|
715
1046
|
const delayValue = process.env.EDITPROMPT_SEND_KEY_DELAY;
|
|
716
1047
|
const parsedDelay = delayValue ? Number.parseInt(delayValue, 10) : NaN;
|
|
@@ -723,7 +1054,7 @@ function readSendConfig() {
|
|
|
723
1054
|
|
|
724
1055
|
//#endregion
|
|
725
1056
|
//#region src/modes/dump.ts
|
|
726
|
-
const logger$
|
|
1057
|
+
const logger$8 = getLogger(["editprompt", "dump"]);
|
|
727
1058
|
async function runDumpMode() {
|
|
728
1059
|
try {
|
|
729
1060
|
const config = readSendConfig();
|
|
@@ -732,19 +1063,27 @@ async function runDumpMode() {
|
|
|
732
1063
|
if (config.mux === "tmux") {
|
|
733
1064
|
currentPaneId = await getCurrentPaneId$1();
|
|
734
1065
|
isEditor = await isEditorPane(currentPaneId);
|
|
735
|
-
} else {
|
|
1066
|
+
} else if (config.mux === "wezterm") {
|
|
736
1067
|
currentPaneId = await getCurrentPaneId();
|
|
737
1068
|
isEditor = isEditorPaneFromConf(currentPaneId);
|
|
1069
|
+
} else if (config.mux === "niwaterm") {
|
|
1070
|
+
currentPaneId = await getCurrentPaneId$2();
|
|
1071
|
+
isEditor = await isEditorPane$1(currentPaneId);
|
|
1072
|
+
} else {
|
|
1073
|
+
currentPaneId = await getCurrentPaneId$3();
|
|
1074
|
+
isEditor = isEditorPaneFromConf$1(currentPaneId);
|
|
738
1075
|
}
|
|
739
1076
|
if (!isEditor) {
|
|
740
|
-
logger$
|
|
1077
|
+
logger$8.error("Current pane is not an editor pane");
|
|
741
1078
|
process.exit(1);
|
|
742
1079
|
}
|
|
743
1080
|
let targetPanes;
|
|
744
1081
|
if (config.mux === "tmux") targetPanes = await getTargetPaneIds$1(currentPaneId);
|
|
745
|
-
else targetPanes = await getTargetPaneIds(currentPaneId);
|
|
1082
|
+
else if (config.mux === "wezterm") targetPanes = await getTargetPaneIds(currentPaneId);
|
|
1083
|
+
else if (config.mux === "niwaterm") targetPanes = await getTargetPaneIds$2(currentPaneId);
|
|
1084
|
+
else targetPanes = await getTargetPaneIds$3(currentPaneId);
|
|
746
1085
|
if (targetPanes.length === 0) {
|
|
747
|
-
logger$
|
|
1086
|
+
logger$8.error("No target panes registered for this editor pane");
|
|
748
1087
|
process.exit(1);
|
|
749
1088
|
}
|
|
750
1089
|
const quoteContents = [];
|
|
@@ -753,9 +1092,15 @@ async function runDumpMode() {
|
|
|
753
1092
|
if (config.mux === "tmux") {
|
|
754
1093
|
content = await getQuoteVariableContent(targetPane);
|
|
755
1094
|
await clearQuoteVariable(targetPane);
|
|
756
|
-
} else {
|
|
1095
|
+
} else if (config.mux === "wezterm") {
|
|
757
1096
|
content = await getQuoteText(targetPane);
|
|
758
1097
|
await clearQuoteText(targetPane);
|
|
1098
|
+
} else if (config.mux === "niwaterm") {
|
|
1099
|
+
content = await getQuoteVariableContent$1(targetPane);
|
|
1100
|
+
await clearQuoteVariable$1(targetPane);
|
|
1101
|
+
} else {
|
|
1102
|
+
content = await getQuoteText$1(targetPane);
|
|
1103
|
+
await clearQuoteText$1(targetPane);
|
|
759
1104
|
}
|
|
760
1105
|
if (content.trim() !== "") quoteContents.push(content);
|
|
761
1106
|
}
|
|
@@ -763,7 +1108,7 @@ async function runDumpMode() {
|
|
|
763
1108
|
process.stdout.write(combinedContent.replace(/\n{3,}$/, "\n\n"));
|
|
764
1109
|
process.exit(0);
|
|
765
1110
|
} catch (error) {
|
|
766
|
-
logger$
|
|
1111
|
+
logger$8.error(`${error instanceof Error ? error.message : "Unknown error"}`);
|
|
767
1112
|
process.exit(1);
|
|
768
1113
|
}
|
|
769
1114
|
}
|
|
@@ -793,13 +1138,89 @@ function processContent(content) {
|
|
|
793
1138
|
return processed;
|
|
794
1139
|
}
|
|
795
1140
|
|
|
1141
|
+
//#endregion
|
|
1142
|
+
//#region src/modes/common.ts
|
|
1143
|
+
const logger$7 = getLogger(["editprompt", "delivery"]);
|
|
1144
|
+
async function copyToClipboard(content) {
|
|
1145
|
+
await clipboardy.write(content);
|
|
1146
|
+
}
|
|
1147
|
+
async function inputContentToPane(content, mux, targetPaneId) {
|
|
1148
|
+
if (mux === "wezterm") await inputToWeztermPane(targetPaneId, content);
|
|
1149
|
+
else if (mux === "herdr") await inputToHerdrPane(targetPaneId, content);
|
|
1150
|
+
else if (mux === "niwaterm") await inputToNiwatermPane(targetPaneId, content);
|
|
1151
|
+
else await inputToTmuxPane(targetPaneId, content);
|
|
1152
|
+
}
|
|
1153
|
+
async function focusFirstSuccessPane(mux, targetPanes, failedPanes) {
|
|
1154
|
+
const firstSuccessPane = targetPanes.find((p) => !failedPanes.includes(p));
|
|
1155
|
+
if (firstSuccessPane) if (mux === "tmux") await focusPane$1(firstSuccessPane);
|
|
1156
|
+
else if (mux === "wezterm") await focusPane(firstSuccessPane);
|
|
1157
|
+
else if (mux === "niwaterm") await focusPane$2(firstSuccessPane);
|
|
1158
|
+
else await focusPane$3(firstSuccessPane);
|
|
1159
|
+
}
|
|
1160
|
+
async function handleContentDelivery(content, mux, targetPanes) {
|
|
1161
|
+
if (!content) return {
|
|
1162
|
+
successCount: 0,
|
|
1163
|
+
totalCount: 0,
|
|
1164
|
+
allSuccess: true,
|
|
1165
|
+
allFailed: false,
|
|
1166
|
+
failedPanes: []
|
|
1167
|
+
};
|
|
1168
|
+
if (targetPanes.length === 0) {
|
|
1169
|
+
try {
|
|
1170
|
+
await copyToClipboard(content);
|
|
1171
|
+
logger$7.info("Content copied to clipboard.");
|
|
1172
|
+
} catch (error) {
|
|
1173
|
+
logger$7.warn(`Failed to copy to clipboard: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1174
|
+
}
|
|
1175
|
+
return {
|
|
1176
|
+
successCount: 0,
|
|
1177
|
+
totalCount: 0,
|
|
1178
|
+
allSuccess: true,
|
|
1179
|
+
allFailed: false,
|
|
1180
|
+
failedPanes: []
|
|
1181
|
+
};
|
|
1182
|
+
}
|
|
1183
|
+
const results = [];
|
|
1184
|
+
for (const targetPane of targetPanes) try {
|
|
1185
|
+
await inputContentToPane(content, mux, targetPane);
|
|
1186
|
+
results.push({
|
|
1187
|
+
pane: targetPane,
|
|
1188
|
+
success: true
|
|
1189
|
+
});
|
|
1190
|
+
} catch (error) {
|
|
1191
|
+
logger$7.warn(`Failed to send to pane ${targetPane}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1192
|
+
results.push({
|
|
1193
|
+
pane: targetPane,
|
|
1194
|
+
success: false
|
|
1195
|
+
});
|
|
1196
|
+
}
|
|
1197
|
+
const successCount = results.filter((r) => r.success).length;
|
|
1198
|
+
const failedPanes = results.filter((r) => !r.success).map((r) => r.pane);
|
|
1199
|
+
const allSuccess = successCount === targetPanes.length;
|
|
1200
|
+
const allFailed = successCount === 0;
|
|
1201
|
+
if (allSuccess) logger$7.info("Content sent successfully to all panes!");
|
|
1202
|
+
else if (allFailed) {
|
|
1203
|
+
logger$7.error("All target panes failed to receive content.");
|
|
1204
|
+
logger$7.info("Falling back to clipboard...");
|
|
1205
|
+
await copyToClipboard(content);
|
|
1206
|
+
logger$7.info("Content copied to clipboard.");
|
|
1207
|
+
} else logger$7.warn(`Content sent to ${successCount}/${targetPanes.length} panes. Failed panes: ${failedPanes.join(", ")}`);
|
|
1208
|
+
return {
|
|
1209
|
+
successCount,
|
|
1210
|
+
totalCount: targetPanes.length,
|
|
1211
|
+
allSuccess,
|
|
1212
|
+
allFailed,
|
|
1213
|
+
failedPanes
|
|
1214
|
+
};
|
|
1215
|
+
}
|
|
1216
|
+
|
|
796
1217
|
//#endregion
|
|
797
1218
|
//#region src/modes/input.ts
|
|
798
|
-
const logger$
|
|
1219
|
+
const logger$6 = getLogger(["editprompt", "input"]);
|
|
799
1220
|
async function runInputMode(rawContent, autoSend, sendKey, sendKeyDelay) {
|
|
800
1221
|
const content = processContent(rawContent);
|
|
801
1222
|
if (!content) {
|
|
802
|
-
logger$
|
|
1223
|
+
logger$6.info("No content to send. Exiting.");
|
|
803
1224
|
return;
|
|
804
1225
|
}
|
|
805
1226
|
const config = readSendConfig();
|
|
@@ -808,44 +1229,58 @@ async function runInputMode(rawContent, autoSend, sendKey, sendKeyDelay) {
|
|
|
808
1229
|
if (config.mux === "tmux") {
|
|
809
1230
|
currentPaneId = await getCurrentPaneId$1();
|
|
810
1231
|
isEditor = await isEditorPane(currentPaneId);
|
|
811
|
-
} else {
|
|
1232
|
+
} else if (config.mux === "wezterm") {
|
|
812
1233
|
currentPaneId = await getCurrentPaneId();
|
|
813
1234
|
isEditor = isEditorPaneFromConf(currentPaneId);
|
|
1235
|
+
} else if (config.mux === "niwaterm") {
|
|
1236
|
+
currentPaneId = await getCurrentPaneId$2();
|
|
1237
|
+
isEditor = await isEditorPane$1(currentPaneId);
|
|
1238
|
+
} else {
|
|
1239
|
+
currentPaneId = await getCurrentPaneId$3();
|
|
1240
|
+
isEditor = isEditorPaneFromConf$1(currentPaneId);
|
|
814
1241
|
}
|
|
815
1242
|
if (!isEditor) {
|
|
816
|
-
logger$
|
|
1243
|
+
logger$6.error("Current pane is not an editor pane");
|
|
817
1244
|
process.exit(1);
|
|
818
1245
|
}
|
|
819
1246
|
let targetPanes;
|
|
820
1247
|
if (config.mux === "tmux") targetPanes = await getTargetPaneIds$1(currentPaneId);
|
|
821
|
-
else targetPanes = await getTargetPaneIds(currentPaneId);
|
|
1248
|
+
else if (config.mux === "wezterm") targetPanes = await getTargetPaneIds(currentPaneId);
|
|
1249
|
+
else if (config.mux === "niwaterm") targetPanes = await getTargetPaneIds$2(currentPaneId);
|
|
1250
|
+
else targetPanes = await getTargetPaneIds$3(currentPaneId);
|
|
822
1251
|
if (targetPanes.length === 0) {
|
|
823
|
-
logger$
|
|
1252
|
+
logger$6.error("No target panes registered for this editor pane");
|
|
824
1253
|
process.exit(1);
|
|
825
1254
|
}
|
|
826
1255
|
if (autoSend) {
|
|
827
|
-
const key = sendKey || (config.mux === "wezterm" ? "\\r" : "C-m");
|
|
1256
|
+
const key = sendKey || (config.mux === "wezterm" ? "\\r" : config.mux === "herdr" ? "enter" : "C-m");
|
|
828
1257
|
const delay = /\.(png|webp|avif|jpe?g|gif)\b/i.test(content) ? sendKeyDelay ?? 1e3 : 200;
|
|
829
1258
|
let successCount = 0;
|
|
830
1259
|
for (const targetPane of targetPanes) try {
|
|
831
1260
|
if (config.mux === "wezterm") {
|
|
832
1261
|
await inputToWeztermPane(targetPane, content);
|
|
833
1262
|
await sendKeyToWeztermPane(targetPane, key, delay);
|
|
1263
|
+
} else if (config.mux === "herdr") {
|
|
1264
|
+
await inputToHerdrPane(targetPane, content);
|
|
1265
|
+
await sendKeyToHerdrPane(targetPane, key, delay);
|
|
1266
|
+
} else if (config.mux === "niwaterm") {
|
|
1267
|
+
await inputToNiwatermPane(targetPane, content);
|
|
1268
|
+
await sendKeyToNiwatermPane(targetPane, key, delay);
|
|
834
1269
|
} else {
|
|
835
1270
|
await inputToTmuxPane(targetPane, content);
|
|
836
1271
|
await sendKeyToTmuxPane(targetPane, key, delay);
|
|
837
1272
|
}
|
|
838
1273
|
successCount++;
|
|
839
1274
|
} catch (error) {
|
|
840
|
-
logger$
|
|
1275
|
+
logger$6.error(`Failed to send to pane ${targetPane}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
841
1276
|
}
|
|
842
1277
|
if (config.alwaysCopy) {
|
|
843
1278
|
await copyToClipboard(content);
|
|
844
|
-
logger$
|
|
1279
|
+
logger$6.info("Also copied to clipboard.");
|
|
845
1280
|
}
|
|
846
|
-
if (successCount > 0) logger$
|
|
1281
|
+
if (successCount > 0) logger$6.info("Content sent and submitted successfully!");
|
|
847
1282
|
else {
|
|
848
|
-
logger$
|
|
1283
|
+
logger$6.error("All target panes failed to receive content");
|
|
849
1284
|
process.exit(1);
|
|
850
1285
|
}
|
|
851
1286
|
return;
|
|
@@ -854,12 +1289,12 @@ async function runInputMode(rawContent, autoSend, sendKey, sendKeyDelay) {
|
|
|
854
1289
|
const result = await handleContentDelivery(content, config.mux, targetPanes);
|
|
855
1290
|
if (config.alwaysCopy && !result.allFailed) {
|
|
856
1291
|
await copyToClipboard(content);
|
|
857
|
-
logger$
|
|
1292
|
+
logger$6.info("Also copied to clipboard.");
|
|
858
1293
|
}
|
|
859
1294
|
if (result.successCount > 0) await focusFirstSuccessPane(config.mux, targetPanes, result.failedPanes);
|
|
860
1295
|
if (result.allFailed) process.exit(1);
|
|
861
1296
|
} catch (error) {
|
|
862
|
-
logger$
|
|
1297
|
+
logger$6.error(`${error instanceof Error ? error.message : "Unknown error"}`);
|
|
863
1298
|
process.exit(1);
|
|
864
1299
|
}
|
|
865
1300
|
}
|
|
@@ -887,13 +1322,13 @@ const inputCommand = define({
|
|
|
887
1322
|
});
|
|
888
1323
|
const rawContent = extractRawContent(ctx.rest, ctx.positionals);
|
|
889
1324
|
if (rawContent === void 0) {
|
|
890
|
-
logger$
|
|
891
|
-
logger$
|
|
892
|
-
logger$
|
|
1325
|
+
logger$6.error("Content is required for input command");
|
|
1326
|
+
logger$6.error("Usage: editprompt input \"your content\"");
|
|
1327
|
+
logger$6.error(" or: editprompt input -- \"your content\"");
|
|
893
1328
|
process.exit(1);
|
|
894
1329
|
}
|
|
895
1330
|
if (ctx.values["send-key"] && !ctx.values["auto-send"]) {
|
|
896
|
-
logger$
|
|
1331
|
+
logger$6.error("--send-key requires --auto-send to be enabled");
|
|
897
1332
|
process.exit(1);
|
|
898
1333
|
}
|
|
899
1334
|
const config = readSendConfig();
|
|
@@ -987,8 +1422,9 @@ async function openEditorAndGetContent(editorOption, envVars, sendConfig) {
|
|
|
987
1422
|
|
|
988
1423
|
//#endregion
|
|
989
1424
|
//#region src/modes/openEditor.ts
|
|
990
|
-
const logger$
|
|
1425
|
+
const logger$5 = getLogger(["editprompt", "open"]);
|
|
991
1426
|
async function runOpenEditorMode(options) {
|
|
1427
|
+
let herdrEditorPaneId;
|
|
992
1428
|
if (options.targetPanes.length > 0 && options.mux === "tmux") try {
|
|
993
1429
|
await markAsEditorPane$1(await getCurrentPaneId$1(), options.targetPanes);
|
|
994
1430
|
} catch {}
|
|
@@ -996,16 +1432,25 @@ async function runOpenEditorMode(options) {
|
|
|
996
1432
|
const currentPaneId = await getCurrentPaneId();
|
|
997
1433
|
await markAsEditorPane(currentPaneId, options.targetPanes);
|
|
998
1434
|
} catch {}
|
|
1435
|
+
else if (options.targetPanes.length > 0 && options.mux === "herdr") try {
|
|
1436
|
+
const currentPaneId = await getCurrentPaneId$3();
|
|
1437
|
+
herdrEditorPaneId = currentPaneId;
|
|
1438
|
+
await markAsEditorPane$3(currentPaneId, options.targetPanes);
|
|
1439
|
+
} catch {}
|
|
1440
|
+
else if (options.targetPanes.length > 0 && options.mux === "niwaterm") try {
|
|
1441
|
+
const currentPaneId = await getCurrentPaneId$2();
|
|
1442
|
+
await markAsEditorPane$2(currentPaneId, options.targetPanes);
|
|
1443
|
+
} catch {}
|
|
999
1444
|
try {
|
|
1000
1445
|
const sendConfig = {
|
|
1001
1446
|
mux: options.mux,
|
|
1002
1447
|
alwaysCopy: options.alwaysCopy,
|
|
1003
1448
|
sendKeyDelay: Number.parseInt(process.env.EDITPROMPT_SEND_KEY_DELAY || "", 10) || 1e3
|
|
1004
1449
|
};
|
|
1005
|
-
logger$
|
|
1450
|
+
logger$5.info("Opening editor...");
|
|
1006
1451
|
const content = await openEditorAndGetContent(options.editor, options.env, sendConfig);
|
|
1007
1452
|
if (!content) {
|
|
1008
|
-
logger$
|
|
1453
|
+
logger$5.info("No content entered. Exiting.");
|
|
1009
1454
|
return;
|
|
1010
1455
|
}
|
|
1011
1456
|
try {
|
|
@@ -1014,12 +1459,12 @@ async function runOpenEditorMode(options) {
|
|
|
1014
1459
|
console.log(content);
|
|
1015
1460
|
if (options.alwaysCopy && !result.allFailed) {
|
|
1016
1461
|
await copyToClipboard(content);
|
|
1017
|
-
logger$
|
|
1462
|
+
logger$5.info("Also copied to clipboard.");
|
|
1018
1463
|
}
|
|
1019
1464
|
if (options.targetPanes.length > 0 && result.successCount > 0) await focusFirstSuccessPane(options.mux, options.targetPanes, result.failedPanes);
|
|
1020
1465
|
if (!result.allSuccess) process.exit(1);
|
|
1021
1466
|
} catch (error) {
|
|
1022
|
-
logger$
|
|
1467
|
+
logger$5.error(`${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1023
1468
|
process.exit(1);
|
|
1024
1469
|
}
|
|
1025
1470
|
} finally {
|
|
@@ -1029,6 +1474,12 @@ async function runOpenEditorMode(options) {
|
|
|
1029
1474
|
else if (options.targetPanes.length > 0 && options.mux === "wezterm") try {
|
|
1030
1475
|
for (const targetPane of options.targetPanes) await clearEditorPaneId(targetPane);
|
|
1031
1476
|
} catch {}
|
|
1477
|
+
else if (options.targetPanes.length > 0 && options.mux === "herdr") try {
|
|
1478
|
+
for (const targetPane of options.targetPanes) await clearEditorPaneId$3(targetPane, herdrEditorPaneId);
|
|
1479
|
+
} catch {}
|
|
1480
|
+
else if (options.targetPanes.length > 0 && options.mux === "niwaterm") try {
|
|
1481
|
+
for (const targetPane of options.targetPanes) await clearEditorPaneId$2(targetPane);
|
|
1482
|
+
} catch {}
|
|
1032
1483
|
}
|
|
1033
1484
|
}
|
|
1034
1485
|
const openCommand = define({
|
|
@@ -1042,12 +1493,7 @@ const openCommand = define({
|
|
|
1042
1493
|
"log-file": ARG_LOG_FILE,
|
|
1043
1494
|
quiet: ARG_QUIET,
|
|
1044
1495
|
verbose: ARG_VERBOSE,
|
|
1045
|
-
env:
|
|
1046
|
-
short: "E",
|
|
1047
|
-
description: "Environment variables to set (e.g., KEY=VALUE)",
|
|
1048
|
-
type: "string",
|
|
1049
|
-
multiple: true
|
|
1050
|
-
}
|
|
1496
|
+
env: ARG_ENV
|
|
1051
1497
|
},
|
|
1052
1498
|
async run(ctx) {
|
|
1053
1499
|
setupLogger({
|
|
@@ -1067,10 +1513,10 @@ const openCommand = define({
|
|
|
1067
1513
|
|
|
1068
1514
|
//#endregion
|
|
1069
1515
|
//#region src/modes/register.ts
|
|
1070
|
-
const logger$
|
|
1516
|
+
const logger$4 = getLogger(["editprompt", "register"]);
|
|
1071
1517
|
async function runRegisterMode(options) {
|
|
1072
1518
|
if (options.targetPanes.length === 0) {
|
|
1073
|
-
logger$
|
|
1519
|
+
logger$4.error("--target-pane is required for register command");
|
|
1074
1520
|
process.exit(1);
|
|
1075
1521
|
}
|
|
1076
1522
|
let editorPaneId;
|
|
@@ -1078,29 +1524,45 @@ async function runRegisterMode(options) {
|
|
|
1078
1524
|
else if (options.mux === "tmux") {
|
|
1079
1525
|
editorPaneId = await getCurrentPaneId$1();
|
|
1080
1526
|
if (!await isEditorPane(editorPaneId)) {
|
|
1081
|
-
logger$
|
|
1527
|
+
logger$4.error("Current pane is not an editor pane. Please run this command from an editor pane or specify --editor-pane.");
|
|
1082
1528
|
process.exit(1);
|
|
1083
1529
|
}
|
|
1084
1530
|
} else if (options.mux === "wezterm") {
|
|
1085
1531
|
editorPaneId = await getCurrentPaneId();
|
|
1086
1532
|
if (!isEditorPaneFromConf(editorPaneId)) {
|
|
1087
|
-
logger$
|
|
1533
|
+
logger$4.error("Current pane is not an editor pane. Please run this command from an editor pane or specify --editor-pane.");
|
|
1534
|
+
process.exit(1);
|
|
1535
|
+
}
|
|
1536
|
+
} else if (options.mux === "herdr") {
|
|
1537
|
+
editorPaneId = await getCurrentPaneId$3();
|
|
1538
|
+
if (!isEditorPaneFromConf$1(editorPaneId)) {
|
|
1539
|
+
logger$4.error("Current pane is not an editor pane. Please run this command from an editor pane or specify --editor-pane.");
|
|
1540
|
+
process.exit(1);
|
|
1541
|
+
}
|
|
1542
|
+
} else if (options.mux === "niwaterm") {
|
|
1543
|
+
editorPaneId = await getCurrentPaneId$2();
|
|
1544
|
+
if (!await isEditorPane$1(editorPaneId)) {
|
|
1545
|
+
logger$4.error("Current pane is not an editor pane. Please run this command from an editor pane or specify --editor-pane.");
|
|
1088
1546
|
process.exit(1);
|
|
1089
1547
|
}
|
|
1090
1548
|
} else {
|
|
1091
|
-
logger$
|
|
1549
|
+
logger$4.error("Unsupported multiplexer");
|
|
1092
1550
|
process.exit(1);
|
|
1093
1551
|
}
|
|
1094
1552
|
try {
|
|
1095
1553
|
let existingPanes = [];
|
|
1096
1554
|
if (options.mux === "tmux") existingPanes = await getTargetPaneIds$1(editorPaneId);
|
|
1097
1555
|
else if (options.mux === "wezterm") existingPanes = await getTargetPaneIds(editorPaneId);
|
|
1556
|
+
else if (options.mux === "herdr") existingPanes = await getTargetPaneIds$3(editorPaneId);
|
|
1557
|
+
else if (options.mux === "niwaterm") existingPanes = await getTargetPaneIds$2(editorPaneId);
|
|
1098
1558
|
const mergedTargetPanes = [...new Set([...existingPanes, ...options.targetPanes])];
|
|
1099
1559
|
if (options.mux === "tmux") await markAsEditorPane$1(editorPaneId, mergedTargetPanes);
|
|
1100
1560
|
else if (options.mux === "wezterm") await markAsEditorPane(editorPaneId, mergedTargetPanes);
|
|
1101
|
-
|
|
1561
|
+
else if (options.mux === "herdr") await markAsEditorPane$3(editorPaneId, mergedTargetPanes);
|
|
1562
|
+
else if (options.mux === "niwaterm") await markAsEditorPane$2(editorPaneId, mergedTargetPanes);
|
|
1563
|
+
logger$4.info(`Editor pane ${editorPaneId} registered with target panes: ${mergedTargetPanes.join(", ")}`);
|
|
1102
1564
|
} catch (error) {
|
|
1103
|
-
logger$
|
|
1565
|
+
logger$4.error(`${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1104
1566
|
process.exit(1);
|
|
1105
1567
|
}
|
|
1106
1568
|
}
|
|
@@ -1135,15 +1597,65 @@ const registerCommand = define({
|
|
|
1135
1597
|
|
|
1136
1598
|
//#endregion
|
|
1137
1599
|
//#region src/modes/resume.ts
|
|
1138
|
-
const logger$
|
|
1600
|
+
const logger$3 = getLogger(["editprompt", "resume"]);
|
|
1139
1601
|
async function runResumeMode(targetPane, mux) {
|
|
1602
|
+
if (mux === "herdr") try {
|
|
1603
|
+
process.exit(await resumeEditorPane(targetPane) ? 0 : 1);
|
|
1604
|
+
} catch (error) {
|
|
1605
|
+
logger$3.debug("Herdr resume failed: {error}", { error });
|
|
1606
|
+
process.exit(1);
|
|
1607
|
+
}
|
|
1608
|
+
if (mux === "niwaterm") {
|
|
1609
|
+
const currentPaneId = await getCurrentPaneId$2();
|
|
1610
|
+
if (await isEditorPane$1(currentPaneId)) {
|
|
1611
|
+
logger$3.debug("Current pane is an editor pane");
|
|
1612
|
+
const originalTargetPaneIds = await getTargetPaneIds$2(currentPaneId);
|
|
1613
|
+
if (originalTargetPaneIds.length === 0) {
|
|
1614
|
+
logger$3.debug("No target pane IDs found for editor pane");
|
|
1615
|
+
process.exit(1);
|
|
1616
|
+
}
|
|
1617
|
+
let focused = false;
|
|
1618
|
+
for (const paneId of originalTargetPaneIds) if (await checkPaneExists$2(paneId)) {
|
|
1619
|
+
await focusPane$2(paneId);
|
|
1620
|
+
focused = true;
|
|
1621
|
+
break;
|
|
1622
|
+
}
|
|
1623
|
+
if (!focused) {
|
|
1624
|
+
logger$3.debug("All target panes do not exist");
|
|
1625
|
+
process.exit(1);
|
|
1626
|
+
}
|
|
1627
|
+
process.exit(0);
|
|
1628
|
+
}
|
|
1629
|
+
logger$3.debug("Current pane is not an editor pane");
|
|
1630
|
+
const editorPaneId = await getEditorPaneId$2(targetPane);
|
|
1631
|
+
logger$3.debug("niwaterm editorPaneId: {editorPaneId}", { editorPaneId });
|
|
1632
|
+
if (editorPaneId === "") {
|
|
1633
|
+
logger$3.debug("Editor pane ID not found");
|
|
1634
|
+
process.exit(1);
|
|
1635
|
+
}
|
|
1636
|
+
if (!await checkPaneExists$2(editorPaneId)) {
|
|
1637
|
+
logger$3.debug("Editor pane does not exist");
|
|
1638
|
+
await clearEditorPaneId$2(targetPane);
|
|
1639
|
+
process.exit(1);
|
|
1640
|
+
}
|
|
1641
|
+
try {
|
|
1642
|
+
await focusPane$2(editorPaneId);
|
|
1643
|
+
process.exit(0);
|
|
1644
|
+
} catch (error) {
|
|
1645
|
+
logger$3.debug("Can't focus editorPaneId: {editorPaneId}, error: {error}", {
|
|
1646
|
+
editorPaneId,
|
|
1647
|
+
error
|
|
1648
|
+
});
|
|
1649
|
+
process.exit(1);
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1140
1652
|
if (mux === "wezterm") {
|
|
1141
1653
|
const currentPaneId = await getCurrentPaneId();
|
|
1142
1654
|
if (isEditorPaneFromConf(currentPaneId)) {
|
|
1143
|
-
logger$
|
|
1655
|
+
logger$3.debug("Current pane is an editor pane");
|
|
1144
1656
|
const originalTargetPaneIds = await getTargetPaneIds(currentPaneId);
|
|
1145
1657
|
if (originalTargetPaneIds.length === 0) {
|
|
1146
|
-
logger$
|
|
1658
|
+
logger$3.debug("No target pane IDs found for editor pane");
|
|
1147
1659
|
process.exit(1);
|
|
1148
1660
|
}
|
|
1149
1661
|
let focused = false;
|
|
@@ -1153,20 +1665,20 @@ async function runResumeMode(targetPane, mux) {
|
|
|
1153
1665
|
break;
|
|
1154
1666
|
}
|
|
1155
1667
|
if (!focused) {
|
|
1156
|
-
logger$
|
|
1668
|
+
logger$3.debug("All target panes do not exist");
|
|
1157
1669
|
process.exit(1);
|
|
1158
1670
|
}
|
|
1159
1671
|
process.exit(0);
|
|
1160
1672
|
}
|
|
1161
|
-
logger$
|
|
1673
|
+
logger$3.debug("Current pane is not an editor pane");
|
|
1162
1674
|
const editorPaneId = await getEditorPaneId(targetPane);
|
|
1163
|
-
logger$
|
|
1675
|
+
logger$3.debug("wezterm editorPaneId: {editorPaneId}", { editorPaneId });
|
|
1164
1676
|
if (editorPaneId === "") {
|
|
1165
|
-
logger$
|
|
1677
|
+
logger$3.debug("Editor pane ID not found");
|
|
1166
1678
|
process.exit(1);
|
|
1167
1679
|
}
|
|
1168
1680
|
if (!await checkPaneExists(editorPaneId)) {
|
|
1169
|
-
logger$
|
|
1681
|
+
logger$3.debug("Editor pane does not exist");
|
|
1170
1682
|
await clearEditorPaneId(targetPane);
|
|
1171
1683
|
process.exit(1);
|
|
1172
1684
|
}
|
|
@@ -1174,7 +1686,7 @@ async function runResumeMode(targetPane, mux) {
|
|
|
1174
1686
|
await focusPane(editorPaneId);
|
|
1175
1687
|
process.exit(0);
|
|
1176
1688
|
} catch (error) {
|
|
1177
|
-
logger$
|
|
1689
|
+
logger$3.debug("Can't focus editorPaneId: {editorPaneId}, error: {error}", {
|
|
1178
1690
|
editorPaneId,
|
|
1179
1691
|
error
|
|
1180
1692
|
});
|
|
@@ -1225,10 +1737,10 @@ const resumeCommand = define({
|
|
|
1225
1737
|
|
|
1226
1738
|
//#endregion
|
|
1227
1739
|
//#region src/modes/press.ts
|
|
1228
|
-
const logger$
|
|
1740
|
+
const logger$2 = getLogger(["editprompt", "press"]);
|
|
1229
1741
|
async function runPressMode(key, delay = 0) {
|
|
1230
1742
|
if (!key) {
|
|
1231
|
-
logger$
|
|
1743
|
+
logger$2.error("Key is required");
|
|
1232
1744
|
process.exit(1);
|
|
1233
1745
|
}
|
|
1234
1746
|
const config = readSendConfig();
|
|
@@ -1237,32 +1749,42 @@ async function runPressMode(key, delay = 0) {
|
|
|
1237
1749
|
if (config.mux === "tmux") {
|
|
1238
1750
|
currentPaneId = await getCurrentPaneId$1();
|
|
1239
1751
|
isEditor = await isEditorPane(currentPaneId);
|
|
1240
|
-
} else {
|
|
1752
|
+
} else if (config.mux === "wezterm") {
|
|
1241
1753
|
currentPaneId = await getCurrentPaneId();
|
|
1242
1754
|
isEditor = isEditorPaneFromConf(currentPaneId);
|
|
1755
|
+
} else if (config.mux === "niwaterm") {
|
|
1756
|
+
currentPaneId = await getCurrentPaneId$2();
|
|
1757
|
+
isEditor = await isEditorPane$1(currentPaneId);
|
|
1758
|
+
} else {
|
|
1759
|
+
currentPaneId = await getCurrentPaneId$3();
|
|
1760
|
+
isEditor = isEditorPaneFromConf$1(currentPaneId);
|
|
1243
1761
|
}
|
|
1244
1762
|
if (!isEditor) {
|
|
1245
|
-
logger$
|
|
1763
|
+
logger$2.error("Current pane is not an editor pane");
|
|
1246
1764
|
process.exit(1);
|
|
1247
1765
|
}
|
|
1248
1766
|
let targetPanes;
|
|
1249
1767
|
if (config.mux === "tmux") targetPanes = await getTargetPaneIds$1(currentPaneId);
|
|
1250
|
-
else targetPanes = await getTargetPaneIds(currentPaneId);
|
|
1768
|
+
else if (config.mux === "wezterm") targetPanes = await getTargetPaneIds(currentPaneId);
|
|
1769
|
+
else if (config.mux === "niwaterm") targetPanes = await getTargetPaneIds$2(currentPaneId);
|
|
1770
|
+
else targetPanes = await getTargetPaneIds$3(currentPaneId);
|
|
1251
1771
|
if (targetPanes.length === 0) {
|
|
1252
|
-
logger$
|
|
1772
|
+
logger$2.error("No target panes registered for this editor pane");
|
|
1253
1773
|
process.exit(1);
|
|
1254
1774
|
}
|
|
1255
1775
|
let successCount = 0;
|
|
1256
1776
|
for (const targetPane of targetPanes) try {
|
|
1257
1777
|
if (config.mux === "wezterm") await sendKeyToWeztermPane(targetPane, key, delay);
|
|
1778
|
+
else if (config.mux === "herdr") await sendKeyToHerdrPane(targetPane, key, delay);
|
|
1779
|
+
else if (config.mux === "niwaterm") await sendKeyToNiwatermPane(targetPane, key, delay);
|
|
1258
1780
|
else await sendKeyToTmuxPane(targetPane, key, delay);
|
|
1259
1781
|
successCount++;
|
|
1260
1782
|
} catch (error) {
|
|
1261
|
-
logger$
|
|
1783
|
+
logger$2.warn(`Failed to send key to pane ${targetPane}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1262
1784
|
}
|
|
1263
|
-
if (successCount > 0) logger$
|
|
1785
|
+
if (successCount > 0) logger$2.info("Key sent successfully!");
|
|
1264
1786
|
else {
|
|
1265
|
-
logger$
|
|
1787
|
+
logger$2.error("All target panes failed to receive key");
|
|
1266
1788
|
process.exit(1);
|
|
1267
1789
|
}
|
|
1268
1790
|
}
|
|
@@ -1286,8 +1808,8 @@ const pressCommand = define({
|
|
|
1286
1808
|
});
|
|
1287
1809
|
const key = extractRawContent(ctx.rest, ctx.positionals);
|
|
1288
1810
|
if (key === void 0 || key === "") {
|
|
1289
|
-
logger$
|
|
1290
|
-
logger$
|
|
1811
|
+
logger$2.error("Key is required for press command");
|
|
1812
|
+
logger$2.error("Usage: editprompt press -- \"Tab\"");
|
|
1291
1813
|
process.exit(1);
|
|
1292
1814
|
}
|
|
1293
1815
|
await runPressMode(key, ctx.values.delay ? Number(ctx.values.delay) : 0);
|
|
@@ -1296,9 +1818,9 @@ const pressCommand = define({
|
|
|
1296
1818
|
|
|
1297
1819
|
//#endregion
|
|
1298
1820
|
//#region src/modes/stash.ts
|
|
1299
|
-
const logger = getLogger(["editprompt", "stash"]);
|
|
1821
|
+
const logger$1 = getLogger(["editprompt", "stash"]);
|
|
1300
1822
|
function getStashKey(mux, targetPaneId) {
|
|
1301
|
-
return `${mux}.targetPane.pane_${targetPaneId}.stash`;
|
|
1823
|
+
return `${mux === "herdr" ? getStorageNamespace() : mux}.targetPane.pane_${targetPaneId}.stash`;
|
|
1302
1824
|
}
|
|
1303
1825
|
async function pushStash(mux, targetPaneId, content) {
|
|
1304
1826
|
const key = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -1345,19 +1867,27 @@ async function getTargetPaneForStash() {
|
|
|
1345
1867
|
if (config.mux === "tmux") {
|
|
1346
1868
|
currentPaneId = await getCurrentPaneId$1();
|
|
1347
1869
|
isEditor = await isEditorPane(currentPaneId);
|
|
1348
|
-
} else {
|
|
1870
|
+
} else if (config.mux === "wezterm") {
|
|
1349
1871
|
currentPaneId = await getCurrentPaneId();
|
|
1350
1872
|
isEditor = isEditorPaneFromConf(currentPaneId);
|
|
1873
|
+
} else if (config.mux === "niwaterm") {
|
|
1874
|
+
currentPaneId = await getCurrentPaneId$2();
|
|
1875
|
+
isEditor = await isEditorPane$1(currentPaneId);
|
|
1876
|
+
} else {
|
|
1877
|
+
currentPaneId = await getCurrentPaneId$3();
|
|
1878
|
+
isEditor = isEditorPaneFromConf$1(currentPaneId);
|
|
1351
1879
|
}
|
|
1352
1880
|
if (!isEditor) {
|
|
1353
|
-
logger.error("Current pane is not an editor pane");
|
|
1881
|
+
logger$1.error("Current pane is not an editor pane");
|
|
1354
1882
|
process.exit(1);
|
|
1355
1883
|
}
|
|
1356
1884
|
let targetPanes;
|
|
1357
1885
|
if (config.mux === "tmux") targetPanes = await getTargetPaneIds$1(currentPaneId);
|
|
1358
|
-
else targetPanes = await getTargetPaneIds(currentPaneId);
|
|
1886
|
+
else if (config.mux === "wezterm") targetPanes = await getTargetPaneIds(currentPaneId);
|
|
1887
|
+
else if (config.mux === "niwaterm") targetPanes = await getTargetPaneIds$2(currentPaneId);
|
|
1888
|
+
else targetPanes = await getTargetPaneIds$3(currentPaneId);
|
|
1359
1889
|
if (targetPanes.length === 0) {
|
|
1360
|
-
logger.error("No target panes registered for this editor pane");
|
|
1890
|
+
logger$1.error("No target panes registered for this editor pane");
|
|
1361
1891
|
process.exit(1);
|
|
1362
1892
|
}
|
|
1363
1893
|
return {
|
|
@@ -1368,13 +1898,13 @@ async function getTargetPaneForStash() {
|
|
|
1368
1898
|
async function runPush(rest, positionals) {
|
|
1369
1899
|
const rawContent = extractRawContent(rest, positionals);
|
|
1370
1900
|
if (rawContent === void 0 || rawContent.trim() === "") {
|
|
1371
|
-
logger.error("Content is required for stash push");
|
|
1372
|
-
logger.error("Usage: editprompt stash push -- \"your content\"");
|
|
1901
|
+
logger$1.error("Content is required for stash push");
|
|
1902
|
+
logger$1.error("Usage: editprompt stash push -- \"your content\"");
|
|
1373
1903
|
process.exit(1);
|
|
1374
1904
|
}
|
|
1375
1905
|
const { mux, targetPaneId } = await getTargetPaneForStash();
|
|
1376
1906
|
const key = await pushStash(mux, targetPaneId, rawContent);
|
|
1377
|
-
logger.info("Stashed with key: {key}", { key });
|
|
1907
|
+
logger$1.info("Stashed with key: {key}", { key });
|
|
1378
1908
|
}
|
|
1379
1909
|
async function runList() {
|
|
1380
1910
|
const { mux, targetPaneId } = await getTargetPaneForStash();
|
|
@@ -1385,8 +1915,8 @@ async function runApply(key) {
|
|
|
1385
1915
|
const { mux, targetPaneId } = await getTargetPaneForStash();
|
|
1386
1916
|
const content = getStashContent(mux, targetPaneId, key);
|
|
1387
1917
|
if (content === "") {
|
|
1388
|
-
if (key) logger.error("No stash entry found with key: {key}", { key });
|
|
1389
|
-
else logger.error("No stash entries found");
|
|
1918
|
+
if (key) logger$1.error("No stash entry found with key: {key}", { key });
|
|
1919
|
+
else logger$1.error("No stash entries found");
|
|
1390
1920
|
process.exit(1);
|
|
1391
1921
|
}
|
|
1392
1922
|
process.stdout.write(content);
|
|
@@ -1394,18 +1924,18 @@ async function runApply(key) {
|
|
|
1394
1924
|
async function runDrop(key) {
|
|
1395
1925
|
const { mux, targetPaneId } = await getTargetPaneForStash();
|
|
1396
1926
|
if (!dropStash(mux, targetPaneId, key)) {
|
|
1397
|
-
if (key) logger.error("No stash entry found with key: {key}", { key });
|
|
1398
|
-
else logger.error("No stash entries found");
|
|
1927
|
+
if (key) logger$1.error("No stash entry found with key: {key}", { key });
|
|
1928
|
+
else logger$1.error("No stash entries found");
|
|
1399
1929
|
process.exit(1);
|
|
1400
1930
|
}
|
|
1401
|
-
logger.info("Stash entry dropped");
|
|
1931
|
+
logger$1.info("Stash entry dropped");
|
|
1402
1932
|
}
|
|
1403
1933
|
async function runPop(key) {
|
|
1404
1934
|
const { mux, targetPaneId } = await getTargetPaneForStash();
|
|
1405
1935
|
const content = getStashContent(mux, targetPaneId, key);
|
|
1406
1936
|
if (content === "") {
|
|
1407
|
-
if (key) logger.error("No stash entry found with key: {key}", { key });
|
|
1408
|
-
else logger.error("No stash entries found");
|
|
1937
|
+
if (key) logger$1.error("No stash entry found with key: {key}", { key });
|
|
1938
|
+
else logger$1.error("No stash entries found");
|
|
1409
1939
|
process.exit(1);
|
|
1410
1940
|
}
|
|
1411
1941
|
process.stdout.write(content);
|
|
@@ -1469,14 +1999,107 @@ const stashCommand = define({
|
|
|
1469
1999
|
await runPop(parseKeyOption(subArgs));
|
|
1470
2000
|
break;
|
|
1471
2001
|
default:
|
|
1472
|
-
logger.error("Unknown subcommand '{subcommand}'", { subcommand });
|
|
1473
|
-
logger.error("");
|
|
2002
|
+
logger$1.error("Unknown subcommand '{subcommand}'", { subcommand });
|
|
2003
|
+
logger$1.error("");
|
|
1474
2004
|
showHelp();
|
|
1475
2005
|
process.exit(1);
|
|
1476
2006
|
}
|
|
1477
2007
|
}
|
|
1478
2008
|
});
|
|
1479
2009
|
|
|
2010
|
+
//#endregion
|
|
2011
|
+
//#region src/modes/toggle.ts
|
|
2012
|
+
const logger = getLogger(["editprompt", "toggle"]);
|
|
2013
|
+
const DEFAULT_EDITOR_PANE_ROWS = 12;
|
|
2014
|
+
function buildOpenEditorArgv(options) {
|
|
2015
|
+
const invocation = options.invocation ?? {
|
|
2016
|
+
execPath: process.execPath,
|
|
2017
|
+
scriptPath: process.argv[1]
|
|
2018
|
+
};
|
|
2019
|
+
if (!invocation.scriptPath) throw new Error("Cannot determine the editprompt entrypoint");
|
|
2020
|
+
const argv = [
|
|
2021
|
+
invocation.execPath,
|
|
2022
|
+
invocation.scriptPath,
|
|
2023
|
+
"open",
|
|
2024
|
+
"--mux",
|
|
2025
|
+
options.mux,
|
|
2026
|
+
"--target-pane",
|
|
2027
|
+
options.targetPane
|
|
2028
|
+
];
|
|
2029
|
+
if (options.editor) argv.push("--editor", options.editor);
|
|
2030
|
+
if (options.alwaysCopy) argv.push("--always-copy");
|
|
2031
|
+
for (const env of options.env ?? []) argv.push("--env", env);
|
|
2032
|
+
if (options.logFile) argv.push("--log-file", options.logFile);
|
|
2033
|
+
if (options.quiet) argv.push("--quiet");
|
|
2034
|
+
if (options.verbose) argv.push("--verbose");
|
|
2035
|
+
return argv;
|
|
2036
|
+
}
|
|
2037
|
+
async function runToggleMode(options, herdrApi = herdr_exports) {
|
|
2038
|
+
if (options.mux !== "herdr") throw new Error("toggle currently supports only the Herdr multiplexer");
|
|
2039
|
+
if (!Number.isInteger(options.paneRows) || options.paneRows <= 0) throw new Error("--pane-rows must be a positive integer");
|
|
2040
|
+
if (await herdrApi.resumeEditorPane(options.targetPane)) return;
|
|
2041
|
+
const launchEnv = {};
|
|
2042
|
+
if (process.env.NODE_NO_WARNINGS !== void 0) launchEnv.NODE_NO_WARNINGS = process.env.NODE_NO_WARNINGS;
|
|
2043
|
+
const editorPaneId = await herdrApi.splitEditorPane(options.targetPane, options.paneRows, process.env.HERDR_ACTIVE_PANE_CWD, launchEnv);
|
|
2044
|
+
try {
|
|
2045
|
+
await herdrApi.runCommandInPane(editorPaneId, buildOpenEditorArgv(options));
|
|
2046
|
+
} catch (error) {
|
|
2047
|
+
try {
|
|
2048
|
+
await herdrApi.closePane(editorPaneId);
|
|
2049
|
+
} catch (closeError) {
|
|
2050
|
+
logger.warn("Failed to close editor pane after launch failure: {error}", { error: closeError });
|
|
2051
|
+
}
|
|
2052
|
+
throw error;
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
2055
|
+
const toggleCommand = define({
|
|
2056
|
+
name: "toggle",
|
|
2057
|
+
description: "Open or focus an editor pane",
|
|
2058
|
+
args: {
|
|
2059
|
+
mux: ARG_MUX,
|
|
2060
|
+
"target-pane": ARG_TARGET_PANE_SINGLE,
|
|
2061
|
+
"pane-rows": {
|
|
2062
|
+
description: "Desired rows for the Herdr editor pane",
|
|
2063
|
+
type: "number",
|
|
2064
|
+
default: DEFAULT_EDITOR_PANE_ROWS
|
|
2065
|
+
},
|
|
2066
|
+
editor: ARG_EDITOR,
|
|
2067
|
+
"always-copy": ARG_ALWAYS_COPY,
|
|
2068
|
+
env: ARG_ENV,
|
|
2069
|
+
"log-file": ARG_LOG_FILE,
|
|
2070
|
+
quiet: ARG_QUIET,
|
|
2071
|
+
verbose: ARG_VERBOSE
|
|
2072
|
+
},
|
|
2073
|
+
async run(ctx) {
|
|
2074
|
+
const logFile = ctx.values["log-file"];
|
|
2075
|
+
const quiet = Boolean(ctx.values.quiet);
|
|
2076
|
+
const verbose = Boolean(ctx.values.verbose);
|
|
2077
|
+
setupLogger({
|
|
2078
|
+
quiet,
|
|
2079
|
+
verbose,
|
|
2080
|
+
logFile
|
|
2081
|
+
});
|
|
2082
|
+
const targetPane = validateTargetPane(ctx.values["target-pane"], "toggle");
|
|
2083
|
+
const mux = validateMux(ctx.values.mux);
|
|
2084
|
+
try {
|
|
2085
|
+
await runToggleMode({
|
|
2086
|
+
mux,
|
|
2087
|
+
targetPane,
|
|
2088
|
+
paneRows: Number(ctx.values["pane-rows"]),
|
|
2089
|
+
alwaysCopy: Boolean(ctx.values["always-copy"]),
|
|
2090
|
+
editor: ctx.values.editor,
|
|
2091
|
+
env: ctx.values.env,
|
|
2092
|
+
logFile,
|
|
2093
|
+
quiet,
|
|
2094
|
+
verbose
|
|
2095
|
+
});
|
|
2096
|
+
} catch (error) {
|
|
2097
|
+
logger.error(error instanceof Error ? error.message : String(error));
|
|
2098
|
+
process.exit(1);
|
|
2099
|
+
}
|
|
2100
|
+
}
|
|
2101
|
+
});
|
|
2102
|
+
|
|
1480
2103
|
//#endregion
|
|
1481
2104
|
//#region src/index.ts
|
|
1482
2105
|
await cli(process.argv.slice(2), {
|
|
@@ -1505,6 +2128,7 @@ await cli(process.argv.slice(2), {
|
|
|
1505
2128
|
open: openCommand,
|
|
1506
2129
|
register: registerCommand,
|
|
1507
2130
|
resume: resumeCommand,
|
|
2131
|
+
toggle: toggleCommand,
|
|
1508
2132
|
input: inputCommand,
|
|
1509
2133
|
press: pressCommand,
|
|
1510
2134
|
collect: collectCommand,
|