editprompt 1.5.0 → 1.6.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 +641 -193
- 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.6.0";
|
|
76
94
|
|
|
77
95
|
//#endregion
|
|
78
96
|
//#region src/config/constants.ts
|
|
@@ -82,6 +100,8 @@ 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;
|
|
85
105
|
|
|
86
106
|
//#endregion
|
|
87
107
|
//#region src/utils/contentChunker.ts
|
|
@@ -111,10 +131,282 @@ function splitByByteSize(content, maxBytes) {
|
|
|
111
131
|
return chunks;
|
|
112
132
|
}
|
|
113
133
|
|
|
134
|
+
//#endregion
|
|
135
|
+
//#region src/modules/conf.ts
|
|
136
|
+
const projectName = process.env.NODE_ENV === "test" ? "editprompt-test" : "editprompt";
|
|
137
|
+
const conf = new Conf({ projectName });
|
|
138
|
+
|
|
139
|
+
//#endregion
|
|
140
|
+
//#region src/modules/herdr.ts
|
|
141
|
+
var herdr_exports = /* @__PURE__ */ __exportAll({
|
|
142
|
+
appendToQuoteText: () => appendToQuoteText$1,
|
|
143
|
+
calculateEditorSplitRatio: () => calculateEditorSplitRatio,
|
|
144
|
+
checkPaneExists: () => checkPaneExists$2,
|
|
145
|
+
clearEditorPaneId: () => clearEditorPaneId$2,
|
|
146
|
+
clearQuoteText: () => clearQuoteText$1,
|
|
147
|
+
closePane: () => closePane,
|
|
148
|
+
focusPane: () => focusPane$2,
|
|
149
|
+
getCurrentPaneId: () => getCurrentPaneId$2,
|
|
150
|
+
getEditorPaneId: () => getEditorPaneId$2,
|
|
151
|
+
getQuoteText: () => getQuoteText$1,
|
|
152
|
+
getStorageNamespace: () => getStorageNamespace,
|
|
153
|
+
getTargetPaneIds: () => getTargetPaneIds$2,
|
|
154
|
+
inputToHerdrPane: () => inputToHerdrPane,
|
|
155
|
+
isEditorPaneFromConf: () => isEditorPaneFromConf$1,
|
|
156
|
+
markAsEditorPane: () => markAsEditorPane$2,
|
|
157
|
+
resumeEditorPane: () => resumeEditorPane,
|
|
158
|
+
runCommandInPane: () => runCommandInPane,
|
|
159
|
+
saveEditorPaneId: () => saveEditorPaneId$2,
|
|
160
|
+
sendKeyToHerdrPane: () => sendKeyToHerdrPane,
|
|
161
|
+
splitEditorPane: () => splitEditorPane
|
|
162
|
+
});
|
|
163
|
+
const logger$13 = getLogger(["editprompt", "herdr"]);
|
|
164
|
+
const HERDR_REQUEST_TIMEOUT_MS = 6e3;
|
|
165
|
+
let requestSequence = 0;
|
|
166
|
+
function getSocketPath() {
|
|
167
|
+
const socketPath = process.env.HERDR_SOCKET_PATH?.trim();
|
|
168
|
+
if (!socketPath) throw new Error("HERDR_SOCKET_PATH is not set");
|
|
169
|
+
return socketPath;
|
|
170
|
+
}
|
|
171
|
+
async function sendRequest(method, params) {
|
|
172
|
+
const id = `editprompt_${process.pid}_${++requestSequence}`;
|
|
173
|
+
const request = `${JSON.stringify({
|
|
174
|
+
id,
|
|
175
|
+
method,
|
|
176
|
+
params
|
|
177
|
+
})}\n`;
|
|
178
|
+
return new Promise((resolve, reject) => {
|
|
179
|
+
const socket = createConnection(getSocketPath());
|
|
180
|
+
let buffer = "";
|
|
181
|
+
let settled = false;
|
|
182
|
+
const finish = (callback) => {
|
|
183
|
+
if (settled) return;
|
|
184
|
+
settled = true;
|
|
185
|
+
socket.end();
|
|
186
|
+
callback();
|
|
187
|
+
};
|
|
188
|
+
socket.setEncoding("utf8");
|
|
189
|
+
socket.setTimeout(HERDR_REQUEST_TIMEOUT_MS);
|
|
190
|
+
socket.on("connect", () => {
|
|
191
|
+
socket.write(request);
|
|
192
|
+
});
|
|
193
|
+
socket.on("data", (chunk) => {
|
|
194
|
+
buffer += chunk;
|
|
195
|
+
const newlineIndex = buffer.indexOf("\n");
|
|
196
|
+
if (newlineIndex === -1) return;
|
|
197
|
+
const line = buffer.slice(0, newlineIndex);
|
|
198
|
+
let response;
|
|
199
|
+
try {
|
|
200
|
+
response = JSON.parse(line);
|
|
201
|
+
} catch (error) {
|
|
202
|
+
finish(() => {
|
|
203
|
+
reject(/* @__PURE__ */ new Error(`Invalid response from Herdr: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
204
|
+
});
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
if (response.id !== id) {
|
|
208
|
+
finish(() => {
|
|
209
|
+
reject(/* @__PURE__ */ new Error(`Unexpected response ID from Herdr: ${response.id}`));
|
|
210
|
+
});
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
if (response.error) {
|
|
214
|
+
finish(() => {
|
|
215
|
+
reject(/* @__PURE__ */ new Error(`Herdr ${response.error?.code}: ${response.error?.message}`));
|
|
216
|
+
});
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
finish(() => {
|
|
220
|
+
resolve(response.result);
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
socket.on("error", (error) => {
|
|
224
|
+
finish(() => {
|
|
225
|
+
reject(/* @__PURE__ */ new Error(`Failed to communicate with Herdr: ${error.message}`));
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
socket.on("timeout", () => {
|
|
229
|
+
if (settled) return;
|
|
230
|
+
settled = true;
|
|
231
|
+
socket.destroy();
|
|
232
|
+
reject(/* @__PURE__ */ new Error(`Timed out waiting for Herdr response after ${HERDR_REQUEST_TIMEOUT_MS}ms`));
|
|
233
|
+
});
|
|
234
|
+
socket.on("end", () => {
|
|
235
|
+
if (!settled) finish(() => {
|
|
236
|
+
reject(/* @__PURE__ */ new Error("Herdr closed the socket before sending a response"));
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
function getStorageNamespace() {
|
|
242
|
+
return `herdr.session_${createHash("sha256").update(getSocketPath()).digest("hex").slice(0, 16)}`;
|
|
243
|
+
}
|
|
244
|
+
function targetPaneKey(paneId) {
|
|
245
|
+
return `${getStorageNamespace()}.targetPane.pane_${paneId}`;
|
|
246
|
+
}
|
|
247
|
+
function editorPaneKey(paneId) {
|
|
248
|
+
return `${getStorageNamespace()}.editorPane.pane_${paneId}`;
|
|
249
|
+
}
|
|
250
|
+
async function getCurrentPaneId$2() {
|
|
251
|
+
const paneId = process.env.HERDR_PANE_ID?.trim() || process.env.HERDR_ACTIVE_PANE_ID?.trim();
|
|
252
|
+
if (!paneId) throw new Error("HERDR_PANE_ID or HERDR_ACTIVE_PANE_ID is not set");
|
|
253
|
+
return paneId;
|
|
254
|
+
}
|
|
255
|
+
async function checkPaneExists$2(paneId) {
|
|
256
|
+
try {
|
|
257
|
+
await sendRequest("pane.get", { pane_id: paneId });
|
|
258
|
+
return true;
|
|
259
|
+
} catch (error) {
|
|
260
|
+
logger$13.debug("checkPaneExists failed: {error}", { error });
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
async function focusPane$2(paneId) {
|
|
265
|
+
await sendRequest("pane.focus", { pane_id: paneId });
|
|
266
|
+
}
|
|
267
|
+
function calculateEditorSplitRatio(paneHeight, editorPaneRows) {
|
|
268
|
+
if (!Number.isInteger(paneHeight) || paneHeight <= 1) throw new Error(`Invalid Herdr pane height: ${paneHeight}`);
|
|
269
|
+
if (!Number.isInteger(editorPaneRows) || editorPaneRows <= 0) throw new Error(`Invalid Herdr editor pane rows: ${editorPaneRows}`);
|
|
270
|
+
return Math.min(.9, Math.max(.1, 1 - editorPaneRows / paneHeight));
|
|
271
|
+
}
|
|
272
|
+
async function splitEditorPane(targetPaneId, editorPaneRows, cwd, env = {}) {
|
|
273
|
+
const paneHeight = ((await sendRequest("pane.layout", { pane_id: targetPaneId })).layout?.panes?.find((pane) => pane.pane_id === targetPaneId))?.rect?.height;
|
|
274
|
+
if (typeof paneHeight !== "number") throw new Error(`Herdr pane.layout did not return a height for pane ${targetPaneId}`);
|
|
275
|
+
const params = {
|
|
276
|
+
target_pane_id: targetPaneId,
|
|
277
|
+
direction: "down",
|
|
278
|
+
ratio: calculateEditorSplitRatio(paneHeight, editorPaneRows),
|
|
279
|
+
focus: true,
|
|
280
|
+
env
|
|
281
|
+
};
|
|
282
|
+
if (cwd?.trim()) params.cwd = cwd;
|
|
283
|
+
const editorPaneId = (await sendRequest("pane.split", params)).pane?.pane_id;
|
|
284
|
+
if (typeof editorPaneId !== "string" || editorPaneId === "") throw new Error("Herdr pane.split did not return the new pane ID");
|
|
285
|
+
return editorPaneId;
|
|
286
|
+
}
|
|
287
|
+
function quoteShellWord(value) {
|
|
288
|
+
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
289
|
+
}
|
|
290
|
+
async function runCommandInPane(paneId, argv) {
|
|
291
|
+
if (argv.length === 0) throw new Error("Cannot run an empty command in a Herdr pane");
|
|
292
|
+
await sendRequest("pane.send_input", {
|
|
293
|
+
pane_id: paneId,
|
|
294
|
+
text: `exec ${argv.map(quoteShellWord).join(" ")}`,
|
|
295
|
+
keys: ["Enter"]
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
async function closePane(paneId) {
|
|
299
|
+
await sendRequest("pane.close", { pane_id: paneId });
|
|
300
|
+
}
|
|
301
|
+
async function inputToHerdrPane(paneId, content) {
|
|
302
|
+
const chunks = splitByByteSize(content, HERDR_SEND_CHUNK_BYTES);
|
|
303
|
+
for (const chunk of chunks) await sendRequest("pane.send_text", {
|
|
304
|
+
pane_id: paneId,
|
|
305
|
+
text: chunk
|
|
306
|
+
});
|
|
307
|
+
logger$13.debug("Content sent to Herdr pane: {paneId} ({chunkCount} chunks)", {
|
|
308
|
+
paneId,
|
|
309
|
+
chunkCount: chunks.length
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
async function sendKeyToHerdrPane(paneId, key, delay = 1e3) {
|
|
313
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
314
|
+
await sendRequest("pane.send_keys", {
|
|
315
|
+
pane_id: paneId,
|
|
316
|
+
keys: [key]
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
async function saveEditorPaneId$2(targetPaneId, editorPaneId) {
|
|
320
|
+
const data = conf.get(targetPaneKey(targetPaneId));
|
|
321
|
+
const existing = typeof data === "object" && data !== null ? data : {};
|
|
322
|
+
conf.set(targetPaneKey(targetPaneId), {
|
|
323
|
+
...existing,
|
|
324
|
+
editorPaneId
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
async function getEditorPaneId$2(targetPaneId) {
|
|
328
|
+
const data = conf.get(targetPaneKey(targetPaneId));
|
|
329
|
+
if (typeof data === "object" && data !== null && "editorPaneId" in data) return String(data.editorPaneId);
|
|
330
|
+
return "";
|
|
331
|
+
}
|
|
332
|
+
async function clearEditorPaneId$2(targetPaneId, expectedEditorPaneId) {
|
|
333
|
+
const editorPaneId = await getEditorPaneId$2(targetPaneId);
|
|
334
|
+
if (expectedEditorPaneId && editorPaneId !== expectedEditorPaneId) {
|
|
335
|
+
conf.delete(editorPaneKey(expectedEditorPaneId));
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
const data = conf.get(targetPaneKey(targetPaneId));
|
|
339
|
+
if (typeof data === "object" && data !== null && "editorPaneId" in data) {
|
|
340
|
+
const { editorPaneId: _, ...remaining } = data;
|
|
341
|
+
if (Object.keys(remaining).length === 0) conf.delete(targetPaneKey(targetPaneId));
|
|
342
|
+
else conf.set(targetPaneKey(targetPaneId), remaining);
|
|
343
|
+
}
|
|
344
|
+
if (editorPaneId) conf.delete(editorPaneKey(editorPaneId));
|
|
345
|
+
}
|
|
346
|
+
async function markAsEditorPane$2(editorPaneId, targetPaneIds) {
|
|
347
|
+
const uniqueTargetPaneIds = [...new Set(targetPaneIds)];
|
|
348
|
+
conf.set(editorPaneKey(editorPaneId), { targetPaneIds: uniqueTargetPaneIds });
|
|
349
|
+
for (const targetPaneId of uniqueTargetPaneIds) await saveEditorPaneId$2(targetPaneId, editorPaneId);
|
|
350
|
+
}
|
|
351
|
+
async function getTargetPaneIds$2(editorPaneId) {
|
|
352
|
+
const data = conf.get(editorPaneKey(editorPaneId));
|
|
353
|
+
if (typeof data === "object" && data !== null && "targetPaneIds" in data) {
|
|
354
|
+
const targetPaneIds = data.targetPaneIds;
|
|
355
|
+
if (Array.isArray(targetPaneIds)) return targetPaneIds.map((id) => String(id));
|
|
356
|
+
}
|
|
357
|
+
return [];
|
|
358
|
+
}
|
|
359
|
+
function isEditorPaneFromConf$1(paneId) {
|
|
360
|
+
return conf.has(editorPaneKey(paneId));
|
|
361
|
+
}
|
|
362
|
+
async function resumeEditorPane(targetPaneId) {
|
|
363
|
+
const currentPaneId = await getCurrentPaneId$2();
|
|
364
|
+
const editorPaneId = isEditorPaneFromConf$1(currentPaneId) ? currentPaneId : isEditorPaneFromConf$1(targetPaneId) ? targetPaneId : "";
|
|
365
|
+
if (editorPaneId) {
|
|
366
|
+
const targetPaneIds = await getTargetPaneIds$2(editorPaneId);
|
|
367
|
+
for (const paneId of targetPaneIds) if (await checkPaneExists$2(paneId)) {
|
|
368
|
+
await focusPane$2(paneId);
|
|
369
|
+
return true;
|
|
370
|
+
}
|
|
371
|
+
return false;
|
|
372
|
+
}
|
|
373
|
+
const registeredEditorPaneId = await getEditorPaneId$2(targetPaneId);
|
|
374
|
+
if (registeredEditorPaneId === "") return false;
|
|
375
|
+
if (!await checkPaneExists$2(registeredEditorPaneId)) {
|
|
376
|
+
await clearEditorPaneId$2(targetPaneId);
|
|
377
|
+
return false;
|
|
378
|
+
}
|
|
379
|
+
await focusPane$2(registeredEditorPaneId);
|
|
380
|
+
return true;
|
|
381
|
+
}
|
|
382
|
+
async function appendToQuoteText$1(paneId, content) {
|
|
383
|
+
const data = conf.get(targetPaneKey(paneId));
|
|
384
|
+
const existing = typeof data === "object" && data !== null ? data : {};
|
|
385
|
+
const existingQuoteText = "quote_text" in existing ? String(existing.quote_text) : "";
|
|
386
|
+
const quoteText = existingQuoteText.trim() !== "" ? `${existingQuoteText}\n\n${content}` : content;
|
|
387
|
+
conf.set(targetPaneKey(paneId), {
|
|
388
|
+
...existing,
|
|
389
|
+
quote_text: quoteText
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
async function getQuoteText$1(paneId) {
|
|
393
|
+
const data = conf.get(targetPaneKey(paneId));
|
|
394
|
+
if (typeof data === "object" && data !== null && "quote_text" in data) return String(data.quote_text);
|
|
395
|
+
return "";
|
|
396
|
+
}
|
|
397
|
+
async function clearQuoteText$1(paneId) {
|
|
398
|
+
const data = conf.get(targetPaneKey(paneId));
|
|
399
|
+
if (typeof data === "object" && data !== null && "quote_text" in data) {
|
|
400
|
+
const { quote_text: _, ...remaining } = data;
|
|
401
|
+
if (Object.keys(remaining).length === 0) conf.delete(targetPaneKey(paneId));
|
|
402
|
+
else conf.set(targetPaneKey(paneId), remaining);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
114
406
|
//#endregion
|
|
115
407
|
//#region src/modules/tmux.ts
|
|
116
408
|
const execAsync$1 = promisify(exec);
|
|
117
|
-
const logger$
|
|
409
|
+
const logger$12 = getLogger(["editprompt", "tmux"]);
|
|
118
410
|
async function getCurrentPaneId$1() {
|
|
119
411
|
const envPaneId = process.env.TMUX_PANE?.trim();
|
|
120
412
|
if (envPaneId) return envPaneId;
|
|
@@ -196,20 +488,15 @@ async function inputToTmuxPane(paneId, content) {
|
|
|
196
488
|
await execAsync$1(`tmux if-shell -t '${paneId}' '[ "#{pane_in_mode}" = "1" ]' "copy-mode -q -t '${paneId}'"`);
|
|
197
489
|
const chunks = splitByByteSize(content, TMUX_SEND_CHUNK_BYTES);
|
|
198
490
|
for (const chunk of chunks) await execAsync$1(`tmux send-keys -t '${paneId}' -- '${chunk.replace(/'/g, "'\\''")}'`);
|
|
199
|
-
logger$
|
|
491
|
+
logger$12.debug("Content sent to tmux pane: {paneId} ({chunks} chunk(s))", {
|
|
200
492
|
paneId,
|
|
201
493
|
chunks: chunks.length
|
|
202
494
|
});
|
|
203
495
|
}
|
|
204
496
|
|
|
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
497
|
//#endregion
|
|
211
498
|
//#region src/modules/wezterm.ts
|
|
212
|
-
const logger$
|
|
499
|
+
const logger$11 = getLogger(["editprompt", "wezterm"]);
|
|
213
500
|
const execAsync = promisify(exec);
|
|
214
501
|
async function getCurrentPaneId() {
|
|
215
502
|
try {
|
|
@@ -217,26 +504,26 @@ async function getCurrentPaneId() {
|
|
|
217
504
|
const activePane = JSON.parse(stdout).find((pane) => pane.is_active === true);
|
|
218
505
|
return String(activePane?.pane_id);
|
|
219
506
|
} catch (error) {
|
|
220
|
-
logger$
|
|
507
|
+
logger$11.debug("getCurrentPaneId failed: {error}", { error });
|
|
221
508
|
return "";
|
|
222
509
|
}
|
|
223
510
|
}
|
|
224
511
|
async function checkPaneExists(paneId) {
|
|
225
512
|
try {
|
|
226
513
|
const { stdout } = await execAsync("wezterm cli list --format json");
|
|
227
|
-
logger$
|
|
514
|
+
logger$11.debug("wezterm cli list output: {stdout}", { stdout });
|
|
228
515
|
return JSON.parse(stdout).some((pane) => String(pane.pane_id) === paneId);
|
|
229
516
|
} catch (error) {
|
|
230
|
-
logger$
|
|
517
|
+
logger$11.debug("checkPaneExists failed: {error}", { error });
|
|
231
518
|
return false;
|
|
232
519
|
}
|
|
233
520
|
}
|
|
234
521
|
async function saveEditorPaneId(targetPaneId, editorPaneId) {
|
|
235
|
-
logger$
|
|
522
|
+
logger$11.debug("Saving editor pane ID to conf key: wezterm.targetPane.pane_{targetPaneId}", { targetPaneId });
|
|
236
523
|
try {
|
|
237
524
|
conf.set(`wezterm.targetPane.pane_${targetPaneId}`, { editorPaneId });
|
|
238
525
|
} catch (error) {
|
|
239
|
-
logger$
|
|
526
|
+
logger$11.debug("saveEditorPaneId failed: {error}", { error });
|
|
240
527
|
}
|
|
241
528
|
}
|
|
242
529
|
async function getEditorPaneId(targetPaneId) {
|
|
@@ -245,7 +532,7 @@ async function getEditorPaneId(targetPaneId) {
|
|
|
245
532
|
if (typeof data === "object" && data !== null && "editorPaneId" in data) return String(data.editorPaneId);
|
|
246
533
|
return "";
|
|
247
534
|
} catch (error) {
|
|
248
|
-
logger$
|
|
535
|
+
logger$11.debug("getEditorPaneId failed: {error}", { error });
|
|
249
536
|
return "";
|
|
250
537
|
}
|
|
251
538
|
}
|
|
@@ -255,7 +542,7 @@ async function clearEditorPaneId(targetPaneId) {
|
|
|
255
542
|
conf.delete(`wezterm.targetPane.pane_${targetPaneId}`);
|
|
256
543
|
if (editorPaneId) conf.delete(`wezterm.editorPane.pane_${editorPaneId}`);
|
|
257
544
|
} catch (error) {
|
|
258
|
-
logger$
|
|
545
|
+
logger$11.debug("clearEditorPaneId failed: {error}", { error });
|
|
259
546
|
}
|
|
260
547
|
}
|
|
261
548
|
async function focusPane(paneId) {
|
|
@@ -267,7 +554,7 @@ async function markAsEditorPane(editorPaneId, targetPaneIds) {
|
|
|
267
554
|
conf.set(`wezterm.editorPane.pane_${editorPaneId}`, { targetPaneIds: uniqueTargetPaneIds });
|
|
268
555
|
for (const targetPaneId of uniqueTargetPaneIds) await saveEditorPaneId(targetPaneId, editorPaneId);
|
|
269
556
|
} catch (error) {
|
|
270
|
-
logger$
|
|
557
|
+
logger$11.debug("markAsEditorPane failed: {error}", { error });
|
|
271
558
|
}
|
|
272
559
|
}
|
|
273
560
|
async function getTargetPaneIds(editorPaneId) {
|
|
@@ -279,7 +566,7 @@ async function getTargetPaneIds(editorPaneId) {
|
|
|
279
566
|
}
|
|
280
567
|
return [];
|
|
281
568
|
} catch (error) {
|
|
282
|
-
logger$
|
|
569
|
+
logger$11.debug("getTargetPaneIds failed: {error}", { error });
|
|
283
570
|
return [];
|
|
284
571
|
}
|
|
285
572
|
}
|
|
@@ -287,7 +574,7 @@ function isEditorPaneFromConf(paneId) {
|
|
|
287
574
|
try {
|
|
288
575
|
return conf.has(`wezterm.editorPane.pane_${paneId}`);
|
|
289
576
|
} catch (error) {
|
|
290
|
-
logger$
|
|
577
|
+
logger$11.debug("isEditorPaneFromConf failed: {error}", { error });
|
|
291
578
|
return false;
|
|
292
579
|
}
|
|
293
580
|
}
|
|
@@ -305,7 +592,7 @@ async function appendToQuoteText(paneId, content) {
|
|
|
305
592
|
} else newData = { quote_text: content };
|
|
306
593
|
conf.set(`wezterm.targetPane.pane_${paneId}`, newData);
|
|
307
594
|
} catch (error) {
|
|
308
|
-
logger$
|
|
595
|
+
logger$11.debug("appendToQuoteText failed: {error}", { error });
|
|
309
596
|
}
|
|
310
597
|
}
|
|
311
598
|
async function getQuoteText(paneId) {
|
|
@@ -314,7 +601,7 @@ async function getQuoteText(paneId) {
|
|
|
314
601
|
if (typeof data === "object" && data !== null && "quote_text" in data) return String(data.quote_text);
|
|
315
602
|
return "";
|
|
316
603
|
} catch (error) {
|
|
317
|
-
logger$
|
|
604
|
+
logger$11.debug("getQuoteText failed: {error}", { error });
|
|
318
605
|
return "";
|
|
319
606
|
}
|
|
320
607
|
}
|
|
@@ -323,7 +610,7 @@ async function clearQuoteText(paneId) {
|
|
|
323
610
|
const key = `wezterm.targetPane.pane_${paneId}.quote_text`;
|
|
324
611
|
if (conf.has(key)) conf.delete(key);
|
|
325
612
|
} catch (error) {
|
|
326
|
-
logger$
|
|
613
|
+
logger$11.debug("clearQuoteText failed: {error}", { error });
|
|
327
614
|
}
|
|
328
615
|
}
|
|
329
616
|
async function sendKeyToWeztermPane(paneId, key, delay = 1e3) {
|
|
@@ -333,7 +620,7 @@ async function sendKeyToWeztermPane(paneId, key, delay = 1e3) {
|
|
|
333
620
|
async function inputToWeztermPane(paneId, content) {
|
|
334
621
|
const chunks = splitByByteSize(content, WEZTERM_SEND_CHUNK_BYTES);
|
|
335
622
|
for (const chunk of chunks) await execAsync(`wezterm cli send-text --no-paste --pane-id '${paneId}' -- '${chunk.replace(/'/g, "'\\''")}'`);
|
|
336
|
-
logger$
|
|
623
|
+
logger$11.debug("Content sent to wezterm pane: {paneId} ({chunks} chunk(s))", {
|
|
337
624
|
paneId,
|
|
338
625
|
chunks: chunks.length
|
|
339
626
|
});
|
|
@@ -477,87 +764,36 @@ function processQuoteText(text, options) {
|
|
|
477
764
|
}
|
|
478
765
|
|
|
479
766
|
//#endregion
|
|
480
|
-
//#region src/
|
|
481
|
-
const
|
|
767
|
+
//#region src/utils/mux.ts
|
|
768
|
+
const SUPPORTED_MUXES = [
|
|
769
|
+
"tmux",
|
|
770
|
+
"wezterm",
|
|
771
|
+
"herdr"
|
|
772
|
+
];
|
|
482
773
|
function isMuxType(value) {
|
|
483
|
-
return value === "tmux" || value === "wezterm";
|
|
774
|
+
return value === "tmux" || value === "wezterm" || value === "herdr";
|
|
484
775
|
}
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
await clipboardy.write(content);
|
|
488
|
-
}
|
|
489
|
-
async function inputContentToPane(content, mux, targetPaneId) {
|
|
490
|
-
if (mux === "wezterm") await inputToWeztermPane(targetPaneId, content);
|
|
491
|
-
else await inputToTmuxPane(targetPaneId, content);
|
|
776
|
+
function hasValue(value) {
|
|
777
|
+
return typeof value === "string" && value.trim() !== "";
|
|
492
778
|
}
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
if (firstSuccessPane) if (mux === "tmux") await focusPane$1(firstSuccessPane);
|
|
496
|
-
else await focusPane(firstSuccessPane);
|
|
779
|
+
function isHerdrEnvironment(env = process.env) {
|
|
780
|
+
return hasValue(env.HERDR_SOCKET_PATH) && (hasValue(env.HERDR_PANE_ID) || hasValue(env.HERDR_ACTIVE_PANE_ID));
|
|
497
781
|
}
|
|
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
|
-
});
|
|
782
|
+
function resolveMux(explicitMux, env = process.env) {
|
|
783
|
+
const muxValue = explicitMux || env.EDITPROMPT_MUX || (isHerdrEnvironment(env) ? "herdr" : "tmux");
|
|
784
|
+
if (!isMuxType(muxValue)) {
|
|
785
|
+
const displayValue = typeof muxValue === "string" ? muxValue : `<${typeof muxValue}>`;
|
|
786
|
+
throw new Error(`Invalid multiplexer type '${displayValue}'. Supported values: ${SUPPORTED_MUXES.join(", ")}`);
|
|
534
787
|
}
|
|
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
|
-
};
|
|
788
|
+
return muxValue;
|
|
553
789
|
}
|
|
554
790
|
|
|
555
791
|
//#endregion
|
|
556
792
|
//#region src/modes/args.ts
|
|
557
|
-
const logger$
|
|
793
|
+
const logger$10 = getLogger(["editprompt"]);
|
|
558
794
|
const ARG_MUX = {
|
|
559
795
|
short: "m",
|
|
560
|
-
description: "Multiplexer type (tmux or
|
|
796
|
+
description: "Multiplexer type (tmux, wezterm, or herdr; auto-detects Herdr, otherwise tmux)",
|
|
561
797
|
type: "string"
|
|
562
798
|
};
|
|
563
799
|
const ARG_TARGET_PANE_SINGLE = {
|
|
@@ -603,17 +839,23 @@ const ARG_VERBOSE = {
|
|
|
603
839
|
description: "Enable debug-level log output",
|
|
604
840
|
type: "boolean"
|
|
605
841
|
};
|
|
842
|
+
const ARG_ENV = {
|
|
843
|
+
short: "E",
|
|
844
|
+
description: "Environment variables to set (e.g., KEY=VALUE)",
|
|
845
|
+
type: "string",
|
|
846
|
+
multiple: true
|
|
847
|
+
};
|
|
606
848
|
function validateMux(value) {
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
849
|
+
try {
|
|
850
|
+
return resolveMux(value);
|
|
851
|
+
} catch (error) {
|
|
852
|
+
logger$10.error(error instanceof Error ? error.message : String(error));
|
|
610
853
|
process.exit(1);
|
|
611
854
|
}
|
|
612
|
-
return muxValue;
|
|
613
855
|
}
|
|
614
856
|
function validateTargetPane(value, commandName) {
|
|
615
857
|
if (!value || typeof value !== "string") {
|
|
616
|
-
logger$
|
|
858
|
+
logger$10.error(`--target-pane is required for ${commandName} command`);
|
|
617
859
|
process.exit(1);
|
|
618
860
|
}
|
|
619
861
|
return value;
|
|
@@ -626,7 +868,7 @@ function normalizeTargetPanes(value) {
|
|
|
626
868
|
|
|
627
869
|
//#endregion
|
|
628
870
|
//#region src/modes/collect.ts
|
|
629
|
-
const logger$
|
|
871
|
+
const logger$9 = getLogger(["editprompt", "collect"]);
|
|
630
872
|
const SUPPORTED_OUTPUTS = ["buffer", "stdout"];
|
|
631
873
|
async function readStdin() {
|
|
632
874
|
return new Promise((resolve, reject) => {
|
|
@@ -650,7 +892,7 @@ function normalizeCollectOutputs(value) {
|
|
|
650
892
|
const uniqueOutputs = [...new Set(outputs)];
|
|
651
893
|
const invalid = uniqueOutputs.filter((v) => !SUPPORTED_OUTPUTS.includes(v));
|
|
652
894
|
if (invalid.length > 0) {
|
|
653
|
-
logger$
|
|
895
|
+
logger$9.error(`Invalid output(s) '${invalid.join(", ")}'. Supported values: ${SUPPORTED_OUTPUTS.join(", ")}`);
|
|
654
896
|
process.exit(1);
|
|
655
897
|
}
|
|
656
898
|
return uniqueOutputs;
|
|
@@ -661,12 +903,12 @@ async function runCollectMode(mux, targetPaneId, rawContent, outputs = ["buffer"
|
|
|
661
903
|
if (rawContent !== void 0) selection = rawContent;
|
|
662
904
|
else selection = await readStdin();
|
|
663
905
|
const processedText = processQuoteText(selection, { withQuote });
|
|
664
|
-
for (const output of outputs) if (output === "buffer")
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
906
|
+
for (const output of outputs) if (output === "buffer") if (mux === "tmux") await appendToQuoteVariable(targetPaneId, processedText);
|
|
907
|
+
else if (mux === "wezterm") await appendToQuoteText(targetPaneId, processedText);
|
|
908
|
+
else await appendToQuoteText$1(targetPaneId, processedText);
|
|
909
|
+
else if (output === "stdout") process.stdout.write(processedText);
|
|
668
910
|
} catch (error) {
|
|
669
|
-
logger$
|
|
911
|
+
logger$9.error(`${error instanceof Error ? error.message : "Unknown error"}`);
|
|
670
912
|
process.exit(1);
|
|
671
913
|
}
|
|
672
914
|
}
|
|
@@ -693,10 +935,10 @@ const collectCommand = define({
|
|
|
693
935
|
const outputs = normalizeCollectOutputs(ctx.values.output);
|
|
694
936
|
const withQuote = !ctx.values["no-quote"];
|
|
695
937
|
let rawContent;
|
|
696
|
-
if (mux === "wezterm") {
|
|
938
|
+
if (mux === "wezterm" || mux === "herdr") {
|
|
697
939
|
rawContent = extractRawContent(ctx.rest, ctx.positionals);
|
|
698
940
|
if (rawContent === void 0) {
|
|
699
|
-
logger$
|
|
941
|
+
logger$9.error(`Text content is required for collect mode with ${mux}. Use: editprompt collect --mux ${mux} --target-pane <id> -- "<text>"`);
|
|
700
942
|
process.exit(1);
|
|
701
943
|
}
|
|
702
944
|
}
|
|
@@ -706,11 +948,8 @@ const collectCommand = define({
|
|
|
706
948
|
|
|
707
949
|
//#endregion
|
|
708
950
|
//#region src/utils/sendConfig.ts
|
|
709
|
-
const VALID_MUX_TYPES = ["tmux", "wezterm"];
|
|
710
951
|
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;
|
|
952
|
+
const mux = resolveMux();
|
|
714
953
|
const alwaysCopy = process.env.EDITPROMPT_ALWAYS_COPY === "1";
|
|
715
954
|
const delayValue = process.env.EDITPROMPT_SEND_KEY_DELAY;
|
|
716
955
|
const parsedDelay = delayValue ? Number.parseInt(delayValue, 10) : NaN;
|
|
@@ -723,7 +962,7 @@ function readSendConfig() {
|
|
|
723
962
|
|
|
724
963
|
//#endregion
|
|
725
964
|
//#region src/modes/dump.ts
|
|
726
|
-
const logger$
|
|
965
|
+
const logger$8 = getLogger(["editprompt", "dump"]);
|
|
727
966
|
async function runDumpMode() {
|
|
728
967
|
try {
|
|
729
968
|
const config = readSendConfig();
|
|
@@ -732,19 +971,23 @@ async function runDumpMode() {
|
|
|
732
971
|
if (config.mux === "tmux") {
|
|
733
972
|
currentPaneId = await getCurrentPaneId$1();
|
|
734
973
|
isEditor = await isEditorPane(currentPaneId);
|
|
735
|
-
} else {
|
|
974
|
+
} else if (config.mux === "wezterm") {
|
|
736
975
|
currentPaneId = await getCurrentPaneId();
|
|
737
976
|
isEditor = isEditorPaneFromConf(currentPaneId);
|
|
977
|
+
} else {
|
|
978
|
+
currentPaneId = await getCurrentPaneId$2();
|
|
979
|
+
isEditor = isEditorPaneFromConf$1(currentPaneId);
|
|
738
980
|
}
|
|
739
981
|
if (!isEditor) {
|
|
740
|
-
logger$
|
|
982
|
+
logger$8.error("Current pane is not an editor pane");
|
|
741
983
|
process.exit(1);
|
|
742
984
|
}
|
|
743
985
|
let targetPanes;
|
|
744
986
|
if (config.mux === "tmux") targetPanes = await getTargetPaneIds$1(currentPaneId);
|
|
745
|
-
else targetPanes = await getTargetPaneIds(currentPaneId);
|
|
987
|
+
else if (config.mux === "wezterm") targetPanes = await getTargetPaneIds(currentPaneId);
|
|
988
|
+
else targetPanes = await getTargetPaneIds$2(currentPaneId);
|
|
746
989
|
if (targetPanes.length === 0) {
|
|
747
|
-
logger$
|
|
990
|
+
logger$8.error("No target panes registered for this editor pane");
|
|
748
991
|
process.exit(1);
|
|
749
992
|
}
|
|
750
993
|
const quoteContents = [];
|
|
@@ -753,9 +996,12 @@ async function runDumpMode() {
|
|
|
753
996
|
if (config.mux === "tmux") {
|
|
754
997
|
content = await getQuoteVariableContent(targetPane);
|
|
755
998
|
await clearQuoteVariable(targetPane);
|
|
756
|
-
} else {
|
|
999
|
+
} else if (config.mux === "wezterm") {
|
|
757
1000
|
content = await getQuoteText(targetPane);
|
|
758
1001
|
await clearQuoteText(targetPane);
|
|
1002
|
+
} else {
|
|
1003
|
+
content = await getQuoteText$1(targetPane);
|
|
1004
|
+
await clearQuoteText$1(targetPane);
|
|
759
1005
|
}
|
|
760
1006
|
if (content.trim() !== "") quoteContents.push(content);
|
|
761
1007
|
}
|
|
@@ -763,7 +1009,7 @@ async function runDumpMode() {
|
|
|
763
1009
|
process.stdout.write(combinedContent.replace(/\n{3,}$/, "\n\n"));
|
|
764
1010
|
process.exit(0);
|
|
765
1011
|
} catch (error) {
|
|
766
|
-
logger$
|
|
1012
|
+
logger$8.error(`${error instanceof Error ? error.message : "Unknown error"}`);
|
|
767
1013
|
process.exit(1);
|
|
768
1014
|
}
|
|
769
1015
|
}
|
|
@@ -793,13 +1039,87 @@ function processContent(content) {
|
|
|
793
1039
|
return processed;
|
|
794
1040
|
}
|
|
795
1041
|
|
|
1042
|
+
//#endregion
|
|
1043
|
+
//#region src/modes/common.ts
|
|
1044
|
+
const logger$7 = getLogger(["editprompt", "delivery"]);
|
|
1045
|
+
async function copyToClipboard(content) {
|
|
1046
|
+
await clipboardy.write(content);
|
|
1047
|
+
}
|
|
1048
|
+
async function inputContentToPane(content, mux, targetPaneId) {
|
|
1049
|
+
if (mux === "wezterm") await inputToWeztermPane(targetPaneId, content);
|
|
1050
|
+
else if (mux === "herdr") await inputToHerdrPane(targetPaneId, content);
|
|
1051
|
+
else await inputToTmuxPane(targetPaneId, content);
|
|
1052
|
+
}
|
|
1053
|
+
async function focusFirstSuccessPane(mux, targetPanes, failedPanes) {
|
|
1054
|
+
const firstSuccessPane = targetPanes.find((p) => !failedPanes.includes(p));
|
|
1055
|
+
if (firstSuccessPane) if (mux === "tmux") await focusPane$1(firstSuccessPane);
|
|
1056
|
+
else if (mux === "wezterm") await focusPane(firstSuccessPane);
|
|
1057
|
+
else await focusPane$2(firstSuccessPane);
|
|
1058
|
+
}
|
|
1059
|
+
async function handleContentDelivery(content, mux, targetPanes) {
|
|
1060
|
+
if (!content) return {
|
|
1061
|
+
successCount: 0,
|
|
1062
|
+
totalCount: 0,
|
|
1063
|
+
allSuccess: true,
|
|
1064
|
+
allFailed: false,
|
|
1065
|
+
failedPanes: []
|
|
1066
|
+
};
|
|
1067
|
+
if (targetPanes.length === 0) {
|
|
1068
|
+
try {
|
|
1069
|
+
await copyToClipboard(content);
|
|
1070
|
+
logger$7.info("Content copied to clipboard.");
|
|
1071
|
+
} catch (error) {
|
|
1072
|
+
logger$7.warn(`Failed to copy to clipboard: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1073
|
+
}
|
|
1074
|
+
return {
|
|
1075
|
+
successCount: 0,
|
|
1076
|
+
totalCount: 0,
|
|
1077
|
+
allSuccess: true,
|
|
1078
|
+
allFailed: false,
|
|
1079
|
+
failedPanes: []
|
|
1080
|
+
};
|
|
1081
|
+
}
|
|
1082
|
+
const results = [];
|
|
1083
|
+
for (const targetPane of targetPanes) try {
|
|
1084
|
+
await inputContentToPane(content, mux, targetPane);
|
|
1085
|
+
results.push({
|
|
1086
|
+
pane: targetPane,
|
|
1087
|
+
success: true
|
|
1088
|
+
});
|
|
1089
|
+
} catch (error) {
|
|
1090
|
+
logger$7.warn(`Failed to send to pane ${targetPane}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1091
|
+
results.push({
|
|
1092
|
+
pane: targetPane,
|
|
1093
|
+
success: false
|
|
1094
|
+
});
|
|
1095
|
+
}
|
|
1096
|
+
const successCount = results.filter((r) => r.success).length;
|
|
1097
|
+
const failedPanes = results.filter((r) => !r.success).map((r) => r.pane);
|
|
1098
|
+
const allSuccess = successCount === targetPanes.length;
|
|
1099
|
+
const allFailed = successCount === 0;
|
|
1100
|
+
if (allSuccess) logger$7.info("Content sent successfully to all panes!");
|
|
1101
|
+
else if (allFailed) {
|
|
1102
|
+
logger$7.error("All target panes failed to receive content.");
|
|
1103
|
+
logger$7.info("Falling back to clipboard...");
|
|
1104
|
+
await copyToClipboard(content);
|
|
1105
|
+
logger$7.info("Content copied to clipboard.");
|
|
1106
|
+
} else logger$7.warn(`Content sent to ${successCount}/${targetPanes.length} panes. Failed panes: ${failedPanes.join(", ")}`);
|
|
1107
|
+
return {
|
|
1108
|
+
successCount,
|
|
1109
|
+
totalCount: targetPanes.length,
|
|
1110
|
+
allSuccess,
|
|
1111
|
+
allFailed,
|
|
1112
|
+
failedPanes
|
|
1113
|
+
};
|
|
1114
|
+
}
|
|
1115
|
+
|
|
796
1116
|
//#endregion
|
|
797
1117
|
//#region src/modes/input.ts
|
|
798
|
-
const logger$
|
|
1118
|
+
const logger$6 = getLogger(["editprompt", "input"]);
|
|
799
1119
|
async function runInputMode(rawContent, autoSend, sendKey, sendKeyDelay) {
|
|
800
1120
|
const content = processContent(rawContent);
|
|
801
1121
|
if (!content) {
|
|
802
|
-
logger$
|
|
1122
|
+
logger$6.info("No content to send. Exiting.");
|
|
803
1123
|
return;
|
|
804
1124
|
}
|
|
805
1125
|
const config = readSendConfig();
|
|
@@ -808,44 +1128,51 @@ async function runInputMode(rawContent, autoSend, sendKey, sendKeyDelay) {
|
|
|
808
1128
|
if (config.mux === "tmux") {
|
|
809
1129
|
currentPaneId = await getCurrentPaneId$1();
|
|
810
1130
|
isEditor = await isEditorPane(currentPaneId);
|
|
811
|
-
} else {
|
|
1131
|
+
} else if (config.mux === "wezterm") {
|
|
812
1132
|
currentPaneId = await getCurrentPaneId();
|
|
813
1133
|
isEditor = isEditorPaneFromConf(currentPaneId);
|
|
1134
|
+
} else {
|
|
1135
|
+
currentPaneId = await getCurrentPaneId$2();
|
|
1136
|
+
isEditor = isEditorPaneFromConf$1(currentPaneId);
|
|
814
1137
|
}
|
|
815
1138
|
if (!isEditor) {
|
|
816
|
-
logger$
|
|
1139
|
+
logger$6.error("Current pane is not an editor pane");
|
|
817
1140
|
process.exit(1);
|
|
818
1141
|
}
|
|
819
1142
|
let targetPanes;
|
|
820
1143
|
if (config.mux === "tmux") targetPanes = await getTargetPaneIds$1(currentPaneId);
|
|
821
|
-
else targetPanes = await getTargetPaneIds(currentPaneId);
|
|
1144
|
+
else if (config.mux === "wezterm") targetPanes = await getTargetPaneIds(currentPaneId);
|
|
1145
|
+
else targetPanes = await getTargetPaneIds$2(currentPaneId);
|
|
822
1146
|
if (targetPanes.length === 0) {
|
|
823
|
-
logger$
|
|
1147
|
+
logger$6.error("No target panes registered for this editor pane");
|
|
824
1148
|
process.exit(1);
|
|
825
1149
|
}
|
|
826
1150
|
if (autoSend) {
|
|
827
|
-
const key = sendKey || (config.mux === "wezterm" ? "\\r" : "C-m");
|
|
1151
|
+
const key = sendKey || (config.mux === "wezterm" ? "\\r" : config.mux === "herdr" ? "enter" : "C-m");
|
|
828
1152
|
const delay = /\.(png|webp|avif|jpe?g|gif)\b/i.test(content) ? sendKeyDelay ?? 1e3 : 200;
|
|
829
1153
|
let successCount = 0;
|
|
830
1154
|
for (const targetPane of targetPanes) try {
|
|
831
1155
|
if (config.mux === "wezterm") {
|
|
832
1156
|
await inputToWeztermPane(targetPane, content);
|
|
833
1157
|
await sendKeyToWeztermPane(targetPane, key, delay);
|
|
1158
|
+
} else if (config.mux === "herdr") {
|
|
1159
|
+
await inputToHerdrPane(targetPane, content);
|
|
1160
|
+
await sendKeyToHerdrPane(targetPane, key, delay);
|
|
834
1161
|
} else {
|
|
835
1162
|
await inputToTmuxPane(targetPane, content);
|
|
836
1163
|
await sendKeyToTmuxPane(targetPane, key, delay);
|
|
837
1164
|
}
|
|
838
1165
|
successCount++;
|
|
839
1166
|
} catch (error) {
|
|
840
|
-
logger$
|
|
1167
|
+
logger$6.error(`Failed to send to pane ${targetPane}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
841
1168
|
}
|
|
842
1169
|
if (config.alwaysCopy) {
|
|
843
1170
|
await copyToClipboard(content);
|
|
844
|
-
logger$
|
|
1171
|
+
logger$6.info("Also copied to clipboard.");
|
|
845
1172
|
}
|
|
846
|
-
if (successCount > 0) logger$
|
|
1173
|
+
if (successCount > 0) logger$6.info("Content sent and submitted successfully!");
|
|
847
1174
|
else {
|
|
848
|
-
logger$
|
|
1175
|
+
logger$6.error("All target panes failed to receive content");
|
|
849
1176
|
process.exit(1);
|
|
850
1177
|
}
|
|
851
1178
|
return;
|
|
@@ -854,12 +1181,12 @@ async function runInputMode(rawContent, autoSend, sendKey, sendKeyDelay) {
|
|
|
854
1181
|
const result = await handleContentDelivery(content, config.mux, targetPanes);
|
|
855
1182
|
if (config.alwaysCopy && !result.allFailed) {
|
|
856
1183
|
await copyToClipboard(content);
|
|
857
|
-
logger$
|
|
1184
|
+
logger$6.info("Also copied to clipboard.");
|
|
858
1185
|
}
|
|
859
1186
|
if (result.successCount > 0) await focusFirstSuccessPane(config.mux, targetPanes, result.failedPanes);
|
|
860
1187
|
if (result.allFailed) process.exit(1);
|
|
861
1188
|
} catch (error) {
|
|
862
|
-
logger$
|
|
1189
|
+
logger$6.error(`${error instanceof Error ? error.message : "Unknown error"}`);
|
|
863
1190
|
process.exit(1);
|
|
864
1191
|
}
|
|
865
1192
|
}
|
|
@@ -887,13 +1214,13 @@ const inputCommand = define({
|
|
|
887
1214
|
});
|
|
888
1215
|
const rawContent = extractRawContent(ctx.rest, ctx.positionals);
|
|
889
1216
|
if (rawContent === void 0) {
|
|
890
|
-
logger$
|
|
891
|
-
logger$
|
|
892
|
-
logger$
|
|
1217
|
+
logger$6.error("Content is required for input command");
|
|
1218
|
+
logger$6.error("Usage: editprompt input \"your content\"");
|
|
1219
|
+
logger$6.error(" or: editprompt input -- \"your content\"");
|
|
893
1220
|
process.exit(1);
|
|
894
1221
|
}
|
|
895
1222
|
if (ctx.values["send-key"] && !ctx.values["auto-send"]) {
|
|
896
|
-
logger$
|
|
1223
|
+
logger$6.error("--send-key requires --auto-send to be enabled");
|
|
897
1224
|
process.exit(1);
|
|
898
1225
|
}
|
|
899
1226
|
const config = readSendConfig();
|
|
@@ -987,8 +1314,9 @@ async function openEditorAndGetContent(editorOption, envVars, sendConfig) {
|
|
|
987
1314
|
|
|
988
1315
|
//#endregion
|
|
989
1316
|
//#region src/modes/openEditor.ts
|
|
990
|
-
const logger$
|
|
1317
|
+
const logger$5 = getLogger(["editprompt", "open"]);
|
|
991
1318
|
async function runOpenEditorMode(options) {
|
|
1319
|
+
let herdrEditorPaneId;
|
|
992
1320
|
if (options.targetPanes.length > 0 && options.mux === "tmux") try {
|
|
993
1321
|
await markAsEditorPane$1(await getCurrentPaneId$1(), options.targetPanes);
|
|
994
1322
|
} catch {}
|
|
@@ -996,16 +1324,21 @@ async function runOpenEditorMode(options) {
|
|
|
996
1324
|
const currentPaneId = await getCurrentPaneId();
|
|
997
1325
|
await markAsEditorPane(currentPaneId, options.targetPanes);
|
|
998
1326
|
} catch {}
|
|
1327
|
+
else if (options.targetPanes.length > 0 && options.mux === "herdr") try {
|
|
1328
|
+
const currentPaneId = await getCurrentPaneId$2();
|
|
1329
|
+
herdrEditorPaneId = currentPaneId;
|
|
1330
|
+
await markAsEditorPane$2(currentPaneId, options.targetPanes);
|
|
1331
|
+
} catch {}
|
|
999
1332
|
try {
|
|
1000
1333
|
const sendConfig = {
|
|
1001
1334
|
mux: options.mux,
|
|
1002
1335
|
alwaysCopy: options.alwaysCopy,
|
|
1003
1336
|
sendKeyDelay: Number.parseInt(process.env.EDITPROMPT_SEND_KEY_DELAY || "", 10) || 1e3
|
|
1004
1337
|
};
|
|
1005
|
-
logger$
|
|
1338
|
+
logger$5.info("Opening editor...");
|
|
1006
1339
|
const content = await openEditorAndGetContent(options.editor, options.env, sendConfig);
|
|
1007
1340
|
if (!content) {
|
|
1008
|
-
logger$
|
|
1341
|
+
logger$5.info("No content entered. Exiting.");
|
|
1009
1342
|
return;
|
|
1010
1343
|
}
|
|
1011
1344
|
try {
|
|
@@ -1014,12 +1347,12 @@ async function runOpenEditorMode(options) {
|
|
|
1014
1347
|
console.log(content);
|
|
1015
1348
|
if (options.alwaysCopy && !result.allFailed) {
|
|
1016
1349
|
await copyToClipboard(content);
|
|
1017
|
-
logger$
|
|
1350
|
+
logger$5.info("Also copied to clipboard.");
|
|
1018
1351
|
}
|
|
1019
1352
|
if (options.targetPanes.length > 0 && result.successCount > 0) await focusFirstSuccessPane(options.mux, options.targetPanes, result.failedPanes);
|
|
1020
1353
|
if (!result.allSuccess) process.exit(1);
|
|
1021
1354
|
} catch (error) {
|
|
1022
|
-
logger$
|
|
1355
|
+
logger$5.error(`${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1023
1356
|
process.exit(1);
|
|
1024
1357
|
}
|
|
1025
1358
|
} finally {
|
|
@@ -1029,6 +1362,9 @@ async function runOpenEditorMode(options) {
|
|
|
1029
1362
|
else if (options.targetPanes.length > 0 && options.mux === "wezterm") try {
|
|
1030
1363
|
for (const targetPane of options.targetPanes) await clearEditorPaneId(targetPane);
|
|
1031
1364
|
} catch {}
|
|
1365
|
+
else if (options.targetPanes.length > 0 && options.mux === "herdr") try {
|
|
1366
|
+
for (const targetPane of options.targetPanes) await clearEditorPaneId$2(targetPane, herdrEditorPaneId);
|
|
1367
|
+
} catch {}
|
|
1032
1368
|
}
|
|
1033
1369
|
}
|
|
1034
1370
|
const openCommand = define({
|
|
@@ -1042,12 +1378,7 @@ const openCommand = define({
|
|
|
1042
1378
|
"log-file": ARG_LOG_FILE,
|
|
1043
1379
|
quiet: ARG_QUIET,
|
|
1044
1380
|
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
|
-
}
|
|
1381
|
+
env: ARG_ENV
|
|
1051
1382
|
},
|
|
1052
1383
|
async run(ctx) {
|
|
1053
1384
|
setupLogger({
|
|
@@ -1067,10 +1398,10 @@ const openCommand = define({
|
|
|
1067
1398
|
|
|
1068
1399
|
//#endregion
|
|
1069
1400
|
//#region src/modes/register.ts
|
|
1070
|
-
const logger$
|
|
1401
|
+
const logger$4 = getLogger(["editprompt", "register"]);
|
|
1071
1402
|
async function runRegisterMode(options) {
|
|
1072
1403
|
if (options.targetPanes.length === 0) {
|
|
1073
|
-
logger$
|
|
1404
|
+
logger$4.error("--target-pane is required for register command");
|
|
1074
1405
|
process.exit(1);
|
|
1075
1406
|
}
|
|
1076
1407
|
let editorPaneId;
|
|
@@ -1078,29 +1409,37 @@ async function runRegisterMode(options) {
|
|
|
1078
1409
|
else if (options.mux === "tmux") {
|
|
1079
1410
|
editorPaneId = await getCurrentPaneId$1();
|
|
1080
1411
|
if (!await isEditorPane(editorPaneId)) {
|
|
1081
|
-
logger$
|
|
1412
|
+
logger$4.error("Current pane is not an editor pane. Please run this command from an editor pane or specify --editor-pane.");
|
|
1082
1413
|
process.exit(1);
|
|
1083
1414
|
}
|
|
1084
1415
|
} else if (options.mux === "wezterm") {
|
|
1085
1416
|
editorPaneId = await getCurrentPaneId();
|
|
1086
1417
|
if (!isEditorPaneFromConf(editorPaneId)) {
|
|
1087
|
-
logger$
|
|
1418
|
+
logger$4.error("Current pane is not an editor pane. Please run this command from an editor pane or specify --editor-pane.");
|
|
1419
|
+
process.exit(1);
|
|
1420
|
+
}
|
|
1421
|
+
} else if (options.mux === "herdr") {
|
|
1422
|
+
editorPaneId = await getCurrentPaneId$2();
|
|
1423
|
+
if (!isEditorPaneFromConf$1(editorPaneId)) {
|
|
1424
|
+
logger$4.error("Current pane is not an editor pane. Please run this command from an editor pane or specify --editor-pane.");
|
|
1088
1425
|
process.exit(1);
|
|
1089
1426
|
}
|
|
1090
1427
|
} else {
|
|
1091
|
-
logger$
|
|
1428
|
+
logger$4.error("Unsupported multiplexer");
|
|
1092
1429
|
process.exit(1);
|
|
1093
1430
|
}
|
|
1094
1431
|
try {
|
|
1095
1432
|
let existingPanes = [];
|
|
1096
1433
|
if (options.mux === "tmux") existingPanes = await getTargetPaneIds$1(editorPaneId);
|
|
1097
1434
|
else if (options.mux === "wezterm") existingPanes = await getTargetPaneIds(editorPaneId);
|
|
1435
|
+
else if (options.mux === "herdr") existingPanes = await getTargetPaneIds$2(editorPaneId);
|
|
1098
1436
|
const mergedTargetPanes = [...new Set([...existingPanes, ...options.targetPanes])];
|
|
1099
1437
|
if (options.mux === "tmux") await markAsEditorPane$1(editorPaneId, mergedTargetPanes);
|
|
1100
1438
|
else if (options.mux === "wezterm") await markAsEditorPane(editorPaneId, mergedTargetPanes);
|
|
1101
|
-
|
|
1439
|
+
else if (options.mux === "herdr") await markAsEditorPane$2(editorPaneId, mergedTargetPanes);
|
|
1440
|
+
logger$4.info(`Editor pane ${editorPaneId} registered with target panes: ${mergedTargetPanes.join(", ")}`);
|
|
1102
1441
|
} catch (error) {
|
|
1103
|
-
logger$
|
|
1442
|
+
logger$4.error(`${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1104
1443
|
process.exit(1);
|
|
1105
1444
|
}
|
|
1106
1445
|
}
|
|
@@ -1135,15 +1474,21 @@ const registerCommand = define({
|
|
|
1135
1474
|
|
|
1136
1475
|
//#endregion
|
|
1137
1476
|
//#region src/modes/resume.ts
|
|
1138
|
-
const logger$
|
|
1477
|
+
const logger$3 = getLogger(["editprompt", "resume"]);
|
|
1139
1478
|
async function runResumeMode(targetPane, mux) {
|
|
1479
|
+
if (mux === "herdr") try {
|
|
1480
|
+
process.exit(await resumeEditorPane(targetPane) ? 0 : 1);
|
|
1481
|
+
} catch (error) {
|
|
1482
|
+
logger$3.debug("Herdr resume failed: {error}", { error });
|
|
1483
|
+
process.exit(1);
|
|
1484
|
+
}
|
|
1140
1485
|
if (mux === "wezterm") {
|
|
1141
1486
|
const currentPaneId = await getCurrentPaneId();
|
|
1142
1487
|
if (isEditorPaneFromConf(currentPaneId)) {
|
|
1143
|
-
logger$
|
|
1488
|
+
logger$3.debug("Current pane is an editor pane");
|
|
1144
1489
|
const originalTargetPaneIds = await getTargetPaneIds(currentPaneId);
|
|
1145
1490
|
if (originalTargetPaneIds.length === 0) {
|
|
1146
|
-
logger$
|
|
1491
|
+
logger$3.debug("No target pane IDs found for editor pane");
|
|
1147
1492
|
process.exit(1);
|
|
1148
1493
|
}
|
|
1149
1494
|
let focused = false;
|
|
@@ -1153,20 +1498,20 @@ async function runResumeMode(targetPane, mux) {
|
|
|
1153
1498
|
break;
|
|
1154
1499
|
}
|
|
1155
1500
|
if (!focused) {
|
|
1156
|
-
logger$
|
|
1501
|
+
logger$3.debug("All target panes do not exist");
|
|
1157
1502
|
process.exit(1);
|
|
1158
1503
|
}
|
|
1159
1504
|
process.exit(0);
|
|
1160
1505
|
}
|
|
1161
|
-
logger$
|
|
1506
|
+
logger$3.debug("Current pane is not an editor pane");
|
|
1162
1507
|
const editorPaneId = await getEditorPaneId(targetPane);
|
|
1163
|
-
logger$
|
|
1508
|
+
logger$3.debug("wezterm editorPaneId: {editorPaneId}", { editorPaneId });
|
|
1164
1509
|
if (editorPaneId === "") {
|
|
1165
|
-
logger$
|
|
1510
|
+
logger$3.debug("Editor pane ID not found");
|
|
1166
1511
|
process.exit(1);
|
|
1167
1512
|
}
|
|
1168
1513
|
if (!await checkPaneExists(editorPaneId)) {
|
|
1169
|
-
logger$
|
|
1514
|
+
logger$3.debug("Editor pane does not exist");
|
|
1170
1515
|
await clearEditorPaneId(targetPane);
|
|
1171
1516
|
process.exit(1);
|
|
1172
1517
|
}
|
|
@@ -1174,7 +1519,7 @@ async function runResumeMode(targetPane, mux) {
|
|
|
1174
1519
|
await focusPane(editorPaneId);
|
|
1175
1520
|
process.exit(0);
|
|
1176
1521
|
} catch (error) {
|
|
1177
|
-
logger$
|
|
1522
|
+
logger$3.debug("Can't focus editorPaneId: {editorPaneId}, error: {error}", {
|
|
1178
1523
|
editorPaneId,
|
|
1179
1524
|
error
|
|
1180
1525
|
});
|
|
@@ -1225,10 +1570,10 @@ const resumeCommand = define({
|
|
|
1225
1570
|
|
|
1226
1571
|
//#endregion
|
|
1227
1572
|
//#region src/modes/press.ts
|
|
1228
|
-
const logger$
|
|
1573
|
+
const logger$2 = getLogger(["editprompt", "press"]);
|
|
1229
1574
|
async function runPressMode(key, delay = 0) {
|
|
1230
1575
|
if (!key) {
|
|
1231
|
-
logger$
|
|
1576
|
+
logger$2.error("Key is required");
|
|
1232
1577
|
process.exit(1);
|
|
1233
1578
|
}
|
|
1234
1579
|
const config = readSendConfig();
|
|
@@ -1237,32 +1582,37 @@ async function runPressMode(key, delay = 0) {
|
|
|
1237
1582
|
if (config.mux === "tmux") {
|
|
1238
1583
|
currentPaneId = await getCurrentPaneId$1();
|
|
1239
1584
|
isEditor = await isEditorPane(currentPaneId);
|
|
1240
|
-
} else {
|
|
1585
|
+
} else if (config.mux === "wezterm") {
|
|
1241
1586
|
currentPaneId = await getCurrentPaneId();
|
|
1242
1587
|
isEditor = isEditorPaneFromConf(currentPaneId);
|
|
1588
|
+
} else {
|
|
1589
|
+
currentPaneId = await getCurrentPaneId$2();
|
|
1590
|
+
isEditor = isEditorPaneFromConf$1(currentPaneId);
|
|
1243
1591
|
}
|
|
1244
1592
|
if (!isEditor) {
|
|
1245
|
-
logger$
|
|
1593
|
+
logger$2.error("Current pane is not an editor pane");
|
|
1246
1594
|
process.exit(1);
|
|
1247
1595
|
}
|
|
1248
1596
|
let targetPanes;
|
|
1249
1597
|
if (config.mux === "tmux") targetPanes = await getTargetPaneIds$1(currentPaneId);
|
|
1250
|
-
else targetPanes = await getTargetPaneIds(currentPaneId);
|
|
1598
|
+
else if (config.mux === "wezterm") targetPanes = await getTargetPaneIds(currentPaneId);
|
|
1599
|
+
else targetPanes = await getTargetPaneIds$2(currentPaneId);
|
|
1251
1600
|
if (targetPanes.length === 0) {
|
|
1252
|
-
logger$
|
|
1601
|
+
logger$2.error("No target panes registered for this editor pane");
|
|
1253
1602
|
process.exit(1);
|
|
1254
1603
|
}
|
|
1255
1604
|
let successCount = 0;
|
|
1256
1605
|
for (const targetPane of targetPanes) try {
|
|
1257
1606
|
if (config.mux === "wezterm") await sendKeyToWeztermPane(targetPane, key, delay);
|
|
1607
|
+
else if (config.mux === "herdr") await sendKeyToHerdrPane(targetPane, key, delay);
|
|
1258
1608
|
else await sendKeyToTmuxPane(targetPane, key, delay);
|
|
1259
1609
|
successCount++;
|
|
1260
1610
|
} catch (error) {
|
|
1261
|
-
logger$
|
|
1611
|
+
logger$2.warn(`Failed to send key to pane ${targetPane}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1262
1612
|
}
|
|
1263
|
-
if (successCount > 0) logger$
|
|
1613
|
+
if (successCount > 0) logger$2.info("Key sent successfully!");
|
|
1264
1614
|
else {
|
|
1265
|
-
logger$
|
|
1615
|
+
logger$2.error("All target panes failed to receive key");
|
|
1266
1616
|
process.exit(1);
|
|
1267
1617
|
}
|
|
1268
1618
|
}
|
|
@@ -1286,8 +1636,8 @@ const pressCommand = define({
|
|
|
1286
1636
|
});
|
|
1287
1637
|
const key = extractRawContent(ctx.rest, ctx.positionals);
|
|
1288
1638
|
if (key === void 0 || key === "") {
|
|
1289
|
-
logger$
|
|
1290
|
-
logger$
|
|
1639
|
+
logger$2.error("Key is required for press command");
|
|
1640
|
+
logger$2.error("Usage: editprompt press -- \"Tab\"");
|
|
1291
1641
|
process.exit(1);
|
|
1292
1642
|
}
|
|
1293
1643
|
await runPressMode(key, ctx.values.delay ? Number(ctx.values.delay) : 0);
|
|
@@ -1296,9 +1646,9 @@ const pressCommand = define({
|
|
|
1296
1646
|
|
|
1297
1647
|
//#endregion
|
|
1298
1648
|
//#region src/modes/stash.ts
|
|
1299
|
-
const logger = getLogger(["editprompt", "stash"]);
|
|
1649
|
+
const logger$1 = getLogger(["editprompt", "stash"]);
|
|
1300
1650
|
function getStashKey(mux, targetPaneId) {
|
|
1301
|
-
return `${mux}.targetPane.pane_${targetPaneId}.stash`;
|
|
1651
|
+
return `${mux === "herdr" ? getStorageNamespace() : mux}.targetPane.pane_${targetPaneId}.stash`;
|
|
1302
1652
|
}
|
|
1303
1653
|
async function pushStash(mux, targetPaneId, content) {
|
|
1304
1654
|
const key = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -1345,19 +1695,23 @@ async function getTargetPaneForStash() {
|
|
|
1345
1695
|
if (config.mux === "tmux") {
|
|
1346
1696
|
currentPaneId = await getCurrentPaneId$1();
|
|
1347
1697
|
isEditor = await isEditorPane(currentPaneId);
|
|
1348
|
-
} else {
|
|
1698
|
+
} else if (config.mux === "wezterm") {
|
|
1349
1699
|
currentPaneId = await getCurrentPaneId();
|
|
1350
1700
|
isEditor = isEditorPaneFromConf(currentPaneId);
|
|
1701
|
+
} else {
|
|
1702
|
+
currentPaneId = await getCurrentPaneId$2();
|
|
1703
|
+
isEditor = isEditorPaneFromConf$1(currentPaneId);
|
|
1351
1704
|
}
|
|
1352
1705
|
if (!isEditor) {
|
|
1353
|
-
logger.error("Current pane is not an editor pane");
|
|
1706
|
+
logger$1.error("Current pane is not an editor pane");
|
|
1354
1707
|
process.exit(1);
|
|
1355
1708
|
}
|
|
1356
1709
|
let targetPanes;
|
|
1357
1710
|
if (config.mux === "tmux") targetPanes = await getTargetPaneIds$1(currentPaneId);
|
|
1358
|
-
else targetPanes = await getTargetPaneIds(currentPaneId);
|
|
1711
|
+
else if (config.mux === "wezterm") targetPanes = await getTargetPaneIds(currentPaneId);
|
|
1712
|
+
else targetPanes = await getTargetPaneIds$2(currentPaneId);
|
|
1359
1713
|
if (targetPanes.length === 0) {
|
|
1360
|
-
logger.error("No target panes registered for this editor pane");
|
|
1714
|
+
logger$1.error("No target panes registered for this editor pane");
|
|
1361
1715
|
process.exit(1);
|
|
1362
1716
|
}
|
|
1363
1717
|
return {
|
|
@@ -1368,13 +1722,13 @@ async function getTargetPaneForStash() {
|
|
|
1368
1722
|
async function runPush(rest, positionals) {
|
|
1369
1723
|
const rawContent = extractRawContent(rest, positionals);
|
|
1370
1724
|
if (rawContent === void 0 || rawContent.trim() === "") {
|
|
1371
|
-
logger.error("Content is required for stash push");
|
|
1372
|
-
logger.error("Usage: editprompt stash push -- \"your content\"");
|
|
1725
|
+
logger$1.error("Content is required for stash push");
|
|
1726
|
+
logger$1.error("Usage: editprompt stash push -- \"your content\"");
|
|
1373
1727
|
process.exit(1);
|
|
1374
1728
|
}
|
|
1375
1729
|
const { mux, targetPaneId } = await getTargetPaneForStash();
|
|
1376
1730
|
const key = await pushStash(mux, targetPaneId, rawContent);
|
|
1377
|
-
logger.info("Stashed with key: {key}", { key });
|
|
1731
|
+
logger$1.info("Stashed with key: {key}", { key });
|
|
1378
1732
|
}
|
|
1379
1733
|
async function runList() {
|
|
1380
1734
|
const { mux, targetPaneId } = await getTargetPaneForStash();
|
|
@@ -1385,8 +1739,8 @@ async function runApply(key) {
|
|
|
1385
1739
|
const { mux, targetPaneId } = await getTargetPaneForStash();
|
|
1386
1740
|
const content = getStashContent(mux, targetPaneId, key);
|
|
1387
1741
|
if (content === "") {
|
|
1388
|
-
if (key) logger.error("No stash entry found with key: {key}", { key });
|
|
1389
|
-
else logger.error("No stash entries found");
|
|
1742
|
+
if (key) logger$1.error("No stash entry found with key: {key}", { key });
|
|
1743
|
+
else logger$1.error("No stash entries found");
|
|
1390
1744
|
process.exit(1);
|
|
1391
1745
|
}
|
|
1392
1746
|
process.stdout.write(content);
|
|
@@ -1394,18 +1748,18 @@ async function runApply(key) {
|
|
|
1394
1748
|
async function runDrop(key) {
|
|
1395
1749
|
const { mux, targetPaneId } = await getTargetPaneForStash();
|
|
1396
1750
|
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");
|
|
1751
|
+
if (key) logger$1.error("No stash entry found with key: {key}", { key });
|
|
1752
|
+
else logger$1.error("No stash entries found");
|
|
1399
1753
|
process.exit(1);
|
|
1400
1754
|
}
|
|
1401
|
-
logger.info("Stash entry dropped");
|
|
1755
|
+
logger$1.info("Stash entry dropped");
|
|
1402
1756
|
}
|
|
1403
1757
|
async function runPop(key) {
|
|
1404
1758
|
const { mux, targetPaneId } = await getTargetPaneForStash();
|
|
1405
1759
|
const content = getStashContent(mux, targetPaneId, key);
|
|
1406
1760
|
if (content === "") {
|
|
1407
|
-
if (key) logger.error("No stash entry found with key: {key}", { key });
|
|
1408
|
-
else logger.error("No stash entries found");
|
|
1761
|
+
if (key) logger$1.error("No stash entry found with key: {key}", { key });
|
|
1762
|
+
else logger$1.error("No stash entries found");
|
|
1409
1763
|
process.exit(1);
|
|
1410
1764
|
}
|
|
1411
1765
|
process.stdout.write(content);
|
|
@@ -1469,14 +1823,107 @@ const stashCommand = define({
|
|
|
1469
1823
|
await runPop(parseKeyOption(subArgs));
|
|
1470
1824
|
break;
|
|
1471
1825
|
default:
|
|
1472
|
-
logger.error("Unknown subcommand '{subcommand}'", { subcommand });
|
|
1473
|
-
logger.error("");
|
|
1826
|
+
logger$1.error("Unknown subcommand '{subcommand}'", { subcommand });
|
|
1827
|
+
logger$1.error("");
|
|
1474
1828
|
showHelp();
|
|
1475
1829
|
process.exit(1);
|
|
1476
1830
|
}
|
|
1477
1831
|
}
|
|
1478
1832
|
});
|
|
1479
1833
|
|
|
1834
|
+
//#endregion
|
|
1835
|
+
//#region src/modes/toggle.ts
|
|
1836
|
+
const logger = getLogger(["editprompt", "toggle"]);
|
|
1837
|
+
const DEFAULT_EDITOR_PANE_ROWS = 12;
|
|
1838
|
+
function buildOpenEditorArgv(options) {
|
|
1839
|
+
const invocation = options.invocation ?? {
|
|
1840
|
+
execPath: process.execPath,
|
|
1841
|
+
scriptPath: process.argv[1]
|
|
1842
|
+
};
|
|
1843
|
+
if (!invocation.scriptPath) throw new Error("Cannot determine the editprompt entrypoint");
|
|
1844
|
+
const argv = [
|
|
1845
|
+
invocation.execPath,
|
|
1846
|
+
invocation.scriptPath,
|
|
1847
|
+
"open",
|
|
1848
|
+
"--mux",
|
|
1849
|
+
options.mux,
|
|
1850
|
+
"--target-pane",
|
|
1851
|
+
options.targetPane
|
|
1852
|
+
];
|
|
1853
|
+
if (options.editor) argv.push("--editor", options.editor);
|
|
1854
|
+
if (options.alwaysCopy) argv.push("--always-copy");
|
|
1855
|
+
for (const env of options.env ?? []) argv.push("--env", env);
|
|
1856
|
+
if (options.logFile) argv.push("--log-file", options.logFile);
|
|
1857
|
+
if (options.quiet) argv.push("--quiet");
|
|
1858
|
+
if (options.verbose) argv.push("--verbose");
|
|
1859
|
+
return argv;
|
|
1860
|
+
}
|
|
1861
|
+
async function runToggleMode(options, herdrApi = herdr_exports) {
|
|
1862
|
+
if (options.mux !== "herdr") throw new Error("toggle currently supports only the Herdr multiplexer");
|
|
1863
|
+
if (!Number.isInteger(options.paneRows) || options.paneRows <= 0) throw new Error("--pane-rows must be a positive integer");
|
|
1864
|
+
if (await herdrApi.resumeEditorPane(options.targetPane)) return;
|
|
1865
|
+
const launchEnv = {};
|
|
1866
|
+
if (process.env.NODE_NO_WARNINGS !== void 0) launchEnv.NODE_NO_WARNINGS = process.env.NODE_NO_WARNINGS;
|
|
1867
|
+
const editorPaneId = await herdrApi.splitEditorPane(options.targetPane, options.paneRows, process.env.HERDR_ACTIVE_PANE_CWD, launchEnv);
|
|
1868
|
+
try {
|
|
1869
|
+
await herdrApi.runCommandInPane(editorPaneId, buildOpenEditorArgv(options));
|
|
1870
|
+
} catch (error) {
|
|
1871
|
+
try {
|
|
1872
|
+
await herdrApi.closePane(editorPaneId);
|
|
1873
|
+
} catch (closeError) {
|
|
1874
|
+
logger.warn("Failed to close editor pane after launch failure: {error}", { error: closeError });
|
|
1875
|
+
}
|
|
1876
|
+
throw error;
|
|
1877
|
+
}
|
|
1878
|
+
}
|
|
1879
|
+
const toggleCommand = define({
|
|
1880
|
+
name: "toggle",
|
|
1881
|
+
description: "Open or focus an editor pane",
|
|
1882
|
+
args: {
|
|
1883
|
+
mux: ARG_MUX,
|
|
1884
|
+
"target-pane": ARG_TARGET_PANE_SINGLE,
|
|
1885
|
+
"pane-rows": {
|
|
1886
|
+
description: "Desired rows for the Herdr editor pane",
|
|
1887
|
+
type: "number",
|
|
1888
|
+
default: DEFAULT_EDITOR_PANE_ROWS
|
|
1889
|
+
},
|
|
1890
|
+
editor: ARG_EDITOR,
|
|
1891
|
+
"always-copy": ARG_ALWAYS_COPY,
|
|
1892
|
+
env: ARG_ENV,
|
|
1893
|
+
"log-file": ARG_LOG_FILE,
|
|
1894
|
+
quiet: ARG_QUIET,
|
|
1895
|
+
verbose: ARG_VERBOSE
|
|
1896
|
+
},
|
|
1897
|
+
async run(ctx) {
|
|
1898
|
+
const logFile = ctx.values["log-file"];
|
|
1899
|
+
const quiet = Boolean(ctx.values.quiet);
|
|
1900
|
+
const verbose = Boolean(ctx.values.verbose);
|
|
1901
|
+
setupLogger({
|
|
1902
|
+
quiet,
|
|
1903
|
+
verbose,
|
|
1904
|
+
logFile
|
|
1905
|
+
});
|
|
1906
|
+
const targetPane = validateTargetPane(ctx.values["target-pane"], "toggle");
|
|
1907
|
+
const mux = validateMux(ctx.values.mux);
|
|
1908
|
+
try {
|
|
1909
|
+
await runToggleMode({
|
|
1910
|
+
mux,
|
|
1911
|
+
targetPane,
|
|
1912
|
+
paneRows: Number(ctx.values["pane-rows"]),
|
|
1913
|
+
alwaysCopy: Boolean(ctx.values["always-copy"]),
|
|
1914
|
+
editor: ctx.values.editor,
|
|
1915
|
+
env: ctx.values.env,
|
|
1916
|
+
logFile,
|
|
1917
|
+
quiet,
|
|
1918
|
+
verbose
|
|
1919
|
+
});
|
|
1920
|
+
} catch (error) {
|
|
1921
|
+
logger.error(error instanceof Error ? error.message : String(error));
|
|
1922
|
+
process.exit(1);
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
});
|
|
1926
|
+
|
|
1480
1927
|
//#endregion
|
|
1481
1928
|
//#region src/index.ts
|
|
1482
1929
|
await cli(process.argv.slice(2), {
|
|
@@ -1505,6 +1952,7 @@ await cli(process.argv.slice(2), {
|
|
|
1505
1952
|
open: openCommand,
|
|
1506
1953
|
register: registerCommand,
|
|
1507
1954
|
resume: resumeCommand,
|
|
1955
|
+
toggle: toggleCommand,
|
|
1508
1956
|
input: inputCommand,
|
|
1509
1957
|
press: pressCommand,
|
|
1510
1958
|
collect: collectCommand,
|