editprompt 1.3.0 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +33 -0
  2. package/dist/index.js +147 -74
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -202,6 +202,39 @@ This sends the content to the target pane (or clipboard) while keeping your edit
202
202
 
203
203
  For Neovim users, we recommend using [editprompt.nvim](https://github.com/eetann/editprompt.nvim) for easy setup. For manual configuration, see [docs/neovim.md](docs/neovim.md).
204
204
 
205
+ ### Key Sending (press)
206
+
207
+ Send individual key inputs to the target pane without leaving your editor. Useful for responding to AI agent selection prompts (e.g., choosing option 1, 2, 3, 4) without switching panes.
208
+
209
+ ```bash
210
+ # Send a character key
211
+ editprompt press -- 1
212
+
213
+ # Send special keys (tmux format)
214
+ editprompt press -- Tab
215
+ editprompt press -- Up
216
+ editprompt press -- C-m # Enter
217
+ editprompt press -- C-c # Ctrl+C
218
+
219
+ # Send with delay
220
+ editprompt press --delay 500 -- Tab
221
+ ```
222
+
223
+ **Key differences from `input`:**
224
+
225
+ - No Enter key is automatically appended
226
+ - Focus stays on the editor pane (no pane switching)
227
+ - Designed for single key inputs, not text content
228
+
229
+ **Key notation** depends on your multiplexer:
230
+
231
+ | Key | tmux | WezTerm |
232
+ | ------------- | ------------- | ------------------- |
233
+ | Enter | `C-m` | `\r` |
234
+ | Tab | `Tab` | `\t` |
235
+ | Escape | `Escape` | `\x1b` |
236
+ | Arrow Up/Down | `Up` / `Down` | `\x1b[A` / `\x1b[B` |
237
+
205
238
  ### Quote Workflow Setup
206
239
 
207
240
  #### Collecting Quotes in tmux Copy Mode
package/dist/index.js CHANGED
@@ -7,6 +7,7 @@ import { promisify } from "node:util";
7
7
  import Conf from "conf";
8
8
  import clipboardy from "clipboardy";
9
9
  import { mkdir, readFile, writeFile } from "node:fs/promises";
10
+ import { randomBytes } from "node:crypto";
10
11
  import { tmpdir } from "node:os";
11
12
  import { join } from "node:path";
12
13
 
@@ -71,12 +72,12 @@ function setupLogger(options = {}) {
71
72
 
72
73
  //#endregion
73
74
  //#region package.json
74
- var version = "1.3.0";
75
+ var version = "1.4.1";
75
76
 
76
77
  //#endregion
77
78
  //#region src/modules/tmux.ts
78
79
  const execAsync$1 = promisify(exec);
79
- const logger$10 = getLogger(["editprompt", "tmux"]);
80
+ const logger$11 = getLogger(["editprompt", "tmux"]);
80
81
  async function getCurrentPaneId$1() {
81
82
  const envPaneId = process.env.TMUX_PANE?.trim();
82
83
  if (envPaneId) return envPaneId;
@@ -157,7 +158,7 @@ async function sendKeyToTmuxPane(paneId, key, delay = 1e3) {
157
158
  async function inputToTmuxPane(paneId, content) {
158
159
  await execAsync$1(`tmux if-shell -t '${paneId}' '[ "#{pane_in_mode}" = "1" ]' "copy-mode -q -t '${paneId}'"`);
159
160
  await execAsync$1(`tmux send-keys -t '${paneId}' -- '${content.replace(/'/g, "'\\''")}'`);
160
- logger$10.debug("Content sent to tmux pane: {paneId}", { paneId });
161
+ logger$11.debug("Content sent to tmux pane: {paneId}", { paneId });
161
162
  }
162
163
 
163
164
  //#endregion
@@ -167,7 +168,7 @@ const conf = new Conf({ projectName });
167
168
 
168
169
  //#endregion
169
170
  //#region src/modules/wezterm.ts
170
- const logger$9 = getLogger(["editprompt", "wezterm"]);
171
+ const logger$10 = getLogger(["editprompt", "wezterm"]);
171
172
  const execAsync = promisify(exec);
172
173
  async function getCurrentPaneId() {
173
174
  try {
@@ -175,26 +176,26 @@ async function getCurrentPaneId() {
175
176
  const activePane = JSON.parse(stdout).find((pane) => pane.is_active === true);
176
177
  return String(activePane?.pane_id);
177
178
  } catch (error) {
178
- logger$9.debug("getCurrentPaneId failed: {error}", { error });
179
+ logger$10.debug("getCurrentPaneId failed: {error}", { error });
179
180
  return "";
180
181
  }
181
182
  }
182
183
  async function checkPaneExists(paneId) {
183
184
  try {
184
185
  const { stdout } = await execAsync("wezterm cli list --format json");
185
- logger$9.debug("wezterm cli list output: {stdout}", { stdout });
186
+ logger$10.debug("wezterm cli list output: {stdout}", { stdout });
186
187
  return JSON.parse(stdout).some((pane) => String(pane.pane_id) === paneId);
187
188
  } catch (error) {
188
- logger$9.debug("checkPaneExists failed: {error}", { error });
189
+ logger$10.debug("checkPaneExists failed: {error}", { error });
189
190
  return false;
190
191
  }
191
192
  }
192
193
  async function saveEditorPaneId(targetPaneId, editorPaneId) {
193
- logger$9.debug("Saving editor pane ID to conf key: wezterm.targetPane.pane_{targetPaneId}", { targetPaneId });
194
+ logger$10.debug("Saving editor pane ID to conf key: wezterm.targetPane.pane_{targetPaneId}", { targetPaneId });
194
195
  try {
195
196
  conf.set(`wezterm.targetPane.pane_${targetPaneId}`, { editorPaneId });
196
197
  } catch (error) {
197
- logger$9.debug("saveEditorPaneId failed: {error}", { error });
198
+ logger$10.debug("saveEditorPaneId failed: {error}", { error });
198
199
  }
199
200
  }
200
201
  async function getEditorPaneId(targetPaneId) {
@@ -203,7 +204,7 @@ async function getEditorPaneId(targetPaneId) {
203
204
  if (typeof data === "object" && data !== null && "editorPaneId" in data) return String(data.editorPaneId);
204
205
  return "";
205
206
  } catch (error) {
206
- logger$9.debug("getEditorPaneId failed: {error}", { error });
207
+ logger$10.debug("getEditorPaneId failed: {error}", { error });
207
208
  return "";
208
209
  }
209
210
  }
@@ -213,7 +214,7 @@ async function clearEditorPaneId(targetPaneId) {
213
214
  conf.delete(`wezterm.targetPane.pane_${targetPaneId}`);
214
215
  if (editorPaneId) conf.delete(`wezterm.editorPane.pane_${editorPaneId}`);
215
216
  } catch (error) {
216
- logger$9.debug("clearEditorPaneId failed: {error}", { error });
217
+ logger$10.debug("clearEditorPaneId failed: {error}", { error });
217
218
  }
218
219
  }
219
220
  async function focusPane(paneId) {
@@ -225,7 +226,7 @@ async function markAsEditorPane(editorPaneId, targetPaneIds) {
225
226
  conf.set(`wezterm.editorPane.pane_${editorPaneId}`, { targetPaneIds: uniqueTargetPaneIds });
226
227
  for (const targetPaneId of uniqueTargetPaneIds) await saveEditorPaneId(targetPaneId, editorPaneId);
227
228
  } catch (error) {
228
- logger$9.debug("markAsEditorPane failed: {error}", { error });
229
+ logger$10.debug("markAsEditorPane failed: {error}", { error });
229
230
  }
230
231
  }
231
232
  async function getTargetPaneIds(editorPaneId) {
@@ -237,7 +238,7 @@ async function getTargetPaneIds(editorPaneId) {
237
238
  }
238
239
  return [];
239
240
  } catch (error) {
240
- logger$9.debug("getTargetPaneIds failed: {error}", { error });
241
+ logger$10.debug("getTargetPaneIds failed: {error}", { error });
241
242
  return [];
242
243
  }
243
244
  }
@@ -245,7 +246,7 @@ function isEditorPaneFromConf(paneId) {
245
246
  try {
246
247
  return conf.has(`wezterm.editorPane.pane_${paneId}`);
247
248
  } catch (error) {
248
- logger$9.debug("isEditorPaneFromConf failed: {error}", { error });
249
+ logger$10.debug("isEditorPaneFromConf failed: {error}", { error });
249
250
  return false;
250
251
  }
251
252
  }
@@ -263,7 +264,7 @@ async function appendToQuoteText(paneId, content) {
263
264
  } else newData = { quote_text: content };
264
265
  conf.set(`wezterm.targetPane.pane_${paneId}`, newData);
265
266
  } catch (error) {
266
- logger$9.debug("appendToQuoteText failed: {error}", { error });
267
+ logger$10.debug("appendToQuoteText failed: {error}", { error });
267
268
  }
268
269
  }
269
270
  async function getQuoteText(paneId) {
@@ -272,7 +273,7 @@ async function getQuoteText(paneId) {
272
273
  if (typeof data === "object" && data !== null && "quote_text" in data) return String(data.quote_text);
273
274
  return "";
274
275
  } catch (error) {
275
- logger$9.debug("getQuoteText failed: {error}", { error });
276
+ logger$10.debug("getQuoteText failed: {error}", { error });
276
277
  return "";
277
278
  }
278
279
  }
@@ -281,7 +282,7 @@ async function clearQuoteText(paneId) {
281
282
  const key = `wezterm.targetPane.pane_${paneId}.quote_text`;
282
283
  if (conf.has(key)) conf.delete(key);
283
284
  } catch (error) {
284
- logger$9.debug("clearQuoteText failed: {error}", { error });
285
+ logger$10.debug("clearQuoteText failed: {error}", { error });
285
286
  }
286
287
  }
287
288
  async function sendKeyToWeztermPane(paneId, key, delay = 1e3) {
@@ -290,7 +291,7 @@ async function sendKeyToWeztermPane(paneId, key, delay = 1e3) {
290
291
  }
291
292
  async function inputToWeztermPane(paneId, content) {
292
293
  await execAsync(`wezterm cli send-text --no-paste --pane-id '${paneId}' -- '${content.replace(/'/g, "'\\''")}'`);
293
- logger$9.debug("Content sent to wezterm pane: {paneId}", { paneId });
294
+ logger$10.debug("Content sent to wezterm pane: {paneId}", { paneId });
294
295
  }
295
296
 
296
297
  //#endregion
@@ -432,7 +433,7 @@ function processQuoteText(text, options) {
432
433
 
433
434
  //#endregion
434
435
  //#region src/modes/common.ts
435
- const logger$8 = getLogger(["editprompt", "delivery"]);
436
+ const logger$9 = getLogger(["editprompt", "delivery"]);
436
437
  function isMuxType(value) {
437
438
  return value === "tmux" || value === "wezterm";
438
439
  }
@@ -460,9 +461,9 @@ async function handleContentDelivery(content, mux, targetPanes) {
460
461
  if (targetPanes.length === 0) {
461
462
  try {
462
463
  await copyToClipboard(content);
463
- logger$8.info("Content copied to clipboard.");
464
+ logger$9.info("Content copied to clipboard.");
464
465
  } catch (error) {
465
- logger$8.warn(`Failed to copy to clipboard: ${error instanceof Error ? error.message : "Unknown error"}`);
466
+ logger$9.warn(`Failed to copy to clipboard: ${error instanceof Error ? error.message : "Unknown error"}`);
466
467
  }
467
468
  return {
468
469
  successCount: 0,
@@ -480,7 +481,7 @@ async function handleContentDelivery(content, mux, targetPanes) {
480
481
  success: true
481
482
  });
482
483
  } catch (error) {
483
- logger$8.warn(`Failed to send to pane ${targetPane}: ${error instanceof Error ? error.message : "Unknown error"}`);
484
+ logger$9.warn(`Failed to send to pane ${targetPane}: ${error instanceof Error ? error.message : "Unknown error"}`);
484
485
  results.push({
485
486
  pane: targetPane,
486
487
  success: false
@@ -490,13 +491,13 @@ async function handleContentDelivery(content, mux, targetPanes) {
490
491
  const failedPanes = results.filter((r) => !r.success).map((r) => r.pane);
491
492
  const allSuccess = successCount === targetPanes.length;
492
493
  const allFailed = successCount === 0;
493
- if (allSuccess) logger$8.info("Content sent successfully to all panes!");
494
+ if (allSuccess) logger$9.info("Content sent successfully to all panes!");
494
495
  else if (allFailed) {
495
- logger$8.error("All target panes failed to receive content.");
496
- logger$8.info("Falling back to clipboard...");
496
+ logger$9.error("All target panes failed to receive content.");
497
+ logger$9.info("Falling back to clipboard...");
497
498
  await copyToClipboard(content);
498
- logger$8.info("Content copied to clipboard.");
499
- } else logger$8.warn(`Content sent to ${successCount}/${targetPanes.length} panes. Failed panes: ${failedPanes.join(", ")}`);
499
+ logger$9.info("Content copied to clipboard.");
500
+ } else logger$9.warn(`Content sent to ${successCount}/${targetPanes.length} panes. Failed panes: ${failedPanes.join(", ")}`);
500
501
  return {
501
502
  successCount,
502
503
  totalCount: targetPanes.length,
@@ -508,7 +509,7 @@ async function handleContentDelivery(content, mux, targetPanes) {
508
509
 
509
510
  //#endregion
510
511
  //#region src/modes/args.ts
511
- const logger$7 = getLogger(["editprompt"]);
512
+ const logger$8 = getLogger(["editprompt"]);
512
513
  const ARG_MUX = {
513
514
  short: "m",
514
515
  description: "Multiplexer type (tmux or wezterm, default: tmux)",
@@ -560,14 +561,14 @@ const ARG_VERBOSE = {
560
561
  function validateMux(value) {
561
562
  const muxValue = value || "tmux";
562
563
  if (!isMuxType(muxValue)) {
563
- logger$7.error(`Invalid multiplexer type '${muxValue}'. Supported values: ${SUPPORTED_MUXES.join(", ")}`);
564
+ logger$8.error(`Invalid multiplexer type '${muxValue}'. Supported values: ${SUPPORTED_MUXES.join(", ")}`);
564
565
  process.exit(1);
565
566
  }
566
567
  return muxValue;
567
568
  }
568
569
  function validateTargetPane(value, commandName) {
569
570
  if (!value || typeof value !== "string") {
570
- logger$7.error(`--target-pane is required for ${commandName} command`);
571
+ logger$8.error(`--target-pane is required for ${commandName} command`);
571
572
  process.exit(1);
572
573
  }
573
574
  return value;
@@ -580,7 +581,7 @@ function normalizeTargetPanes(value) {
580
581
 
581
582
  //#endregion
582
583
  //#region src/modes/collect.ts
583
- const logger$6 = getLogger(["editprompt", "collect"]);
584
+ const logger$7 = getLogger(["editprompt", "collect"]);
584
585
  const SUPPORTED_OUTPUTS = ["buffer", "stdout"];
585
586
  async function readStdin() {
586
587
  return new Promise((resolve, reject) => {
@@ -604,7 +605,7 @@ function normalizeCollectOutputs(value) {
604
605
  const uniqueOutputs = [...new Set(outputs)];
605
606
  const invalid = uniqueOutputs.filter((v) => !SUPPORTED_OUTPUTS.includes(v));
606
607
  if (invalid.length > 0) {
607
- logger$6.error(`Invalid output(s) '${invalid.join(", ")}'. Supported values: ${SUPPORTED_OUTPUTS.join(", ")}`);
608
+ logger$7.error(`Invalid output(s) '${invalid.join(", ")}'. Supported values: ${SUPPORTED_OUTPUTS.join(", ")}`);
608
609
  process.exit(1);
609
610
  }
610
611
  return uniqueOutputs;
@@ -620,7 +621,7 @@ async function runCollectMode(mux, targetPaneId, rawContent, outputs = ["buffer"
620
621
  else if (mux === "wezterm") await appendToQuoteText(targetPaneId, processedText);
621
622
  } else if (output === "stdout") process.stdout.write(processedText);
622
623
  } catch (error) {
623
- logger$6.error(`${error instanceof Error ? error.message : "Unknown error"}`);
624
+ logger$7.error(`${error instanceof Error ? error.message : "Unknown error"}`);
624
625
  process.exit(1);
625
626
  }
626
627
  }
@@ -650,7 +651,7 @@ const collectCommand = define({
650
651
  if (mux === "wezterm") {
651
652
  rawContent = extractRawContent(ctx.rest, ctx.positionals);
652
653
  if (rawContent === void 0) {
653
- logger$6.error("Text content is required for collect mode with wezterm. Use: editprompt collect --mux wezterm --target-pane <id> -- \"<text>\"");
654
+ logger$7.error("Text content is required for collect mode with wezterm. Use: editprompt collect --mux wezterm --target-pane <id> -- \"<text>\"");
654
655
  process.exit(1);
655
656
  }
656
657
  }
@@ -677,7 +678,7 @@ function readSendConfig() {
677
678
 
678
679
  //#endregion
679
680
  //#region src/modes/dump.ts
680
- const logger$5 = getLogger(["editprompt", "dump"]);
681
+ const logger$6 = getLogger(["editprompt", "dump"]);
681
682
  async function runDumpMode() {
682
683
  try {
683
684
  const config = readSendConfig();
@@ -691,14 +692,14 @@ async function runDumpMode() {
691
692
  isEditor = isEditorPaneFromConf(currentPaneId);
692
693
  }
693
694
  if (!isEditor) {
694
- logger$5.error("Current pane is not an editor pane");
695
+ logger$6.error("Current pane is not an editor pane");
695
696
  process.exit(1);
696
697
  }
697
698
  let targetPanes;
698
699
  if (config.mux === "tmux") targetPanes = await getTargetPaneIds$1(currentPaneId);
699
700
  else targetPanes = await getTargetPaneIds(currentPaneId);
700
701
  if (targetPanes.length === 0) {
701
- logger$5.error("No target panes registered for this editor pane");
702
+ logger$6.error("No target panes registered for this editor pane");
702
703
  process.exit(1);
703
704
  }
704
705
  const quoteContents = [];
@@ -717,7 +718,7 @@ async function runDumpMode() {
717
718
  process.stdout.write(combinedContent.replace(/\n{3,}$/, "\n\n"));
718
719
  process.exit(0);
719
720
  } catch (error) {
720
- logger$5.error(`${error instanceof Error ? error.message : "Unknown error"}`);
721
+ logger$6.error(`${error instanceof Error ? error.message : "Unknown error"}`);
721
722
  process.exit(1);
722
723
  }
723
724
  }
@@ -749,11 +750,11 @@ function processContent(content) {
749
750
 
750
751
  //#endregion
751
752
  //#region src/modes/input.ts
752
- const logger$4 = getLogger(["editprompt", "input"]);
753
+ const logger$5 = getLogger(["editprompt", "input"]);
753
754
  async function runInputMode(rawContent, autoSend, sendKey, sendKeyDelay) {
754
755
  const content = processContent(rawContent);
755
756
  if (!content) {
756
- logger$4.info("No content to send. Exiting.");
757
+ logger$5.info("No content to send. Exiting.");
757
758
  return;
758
759
  }
759
760
  const config = readSendConfig();
@@ -767,14 +768,14 @@ async function runInputMode(rawContent, autoSend, sendKey, sendKeyDelay) {
767
768
  isEditor = isEditorPaneFromConf(currentPaneId);
768
769
  }
769
770
  if (!isEditor) {
770
- logger$4.error("Current pane is not an editor pane");
771
+ logger$5.error("Current pane is not an editor pane");
771
772
  process.exit(1);
772
773
  }
773
774
  let targetPanes;
774
775
  if (config.mux === "tmux") targetPanes = await getTargetPaneIds$1(currentPaneId);
775
776
  else targetPanes = await getTargetPaneIds(currentPaneId);
776
777
  if (targetPanes.length === 0) {
777
- logger$4.error("No target panes registered for this editor pane");
778
+ logger$5.error("No target panes registered for this editor pane");
778
779
  process.exit(1);
779
780
  }
780
781
  if (autoSend) {
@@ -791,15 +792,15 @@ async function runInputMode(rawContent, autoSend, sendKey, sendKeyDelay) {
791
792
  }
792
793
  successCount++;
793
794
  } catch (error) {
794
- logger$4.error(`Failed to send to pane ${targetPane}: ${error instanceof Error ? error.message : "Unknown error"}`);
795
+ logger$5.error(`Failed to send to pane ${targetPane}: ${error instanceof Error ? error.message : "Unknown error"}`);
795
796
  }
796
797
  if (config.alwaysCopy) {
797
798
  await copyToClipboard(content);
798
- logger$4.info("Also copied to clipboard.");
799
+ logger$5.info("Also copied to clipboard.");
799
800
  }
800
- if (successCount > 0) logger$4.info("Content sent and submitted successfully!");
801
+ if (successCount > 0) logger$5.info("Content sent and submitted successfully!");
801
802
  else {
802
- logger$4.error("All target panes failed to receive content");
803
+ logger$5.error("All target panes failed to receive content");
803
804
  process.exit(1);
804
805
  }
805
806
  return;
@@ -808,12 +809,12 @@ async function runInputMode(rawContent, autoSend, sendKey, sendKeyDelay) {
808
809
  const result = await handleContentDelivery(content, config.mux, targetPanes);
809
810
  if (config.alwaysCopy && !result.allFailed) {
810
811
  await copyToClipboard(content);
811
- logger$4.info("Also copied to clipboard.");
812
+ logger$5.info("Also copied to clipboard.");
812
813
  }
813
814
  if (result.successCount > 0) await focusFirstSuccessPane(config.mux, targetPanes, result.failedPanes);
814
815
  if (result.allFailed) process.exit(1);
815
816
  } catch (error) {
816
- logger$4.error(`${error instanceof Error ? error.message : "Unknown error"}`);
817
+ logger$5.error(`${error instanceof Error ? error.message : "Unknown error"}`);
817
818
  process.exit(1);
818
819
  }
819
820
  }
@@ -841,13 +842,13 @@ const inputCommand = define({
841
842
  });
842
843
  const rawContent = extractRawContent(ctx.rest, ctx.positionals);
843
844
  if (rawContent === void 0) {
844
- logger$4.error("Content is required for input command");
845
- logger$4.error("Usage: editprompt input \"your content\"");
846
- logger$4.error(" or: editprompt input -- \"your content\"");
845
+ logger$5.error("Content is required for input command");
846
+ logger$5.error("Usage: editprompt input \"your content\"");
847
+ logger$5.error(" or: editprompt input -- \"your content\"");
847
848
  process.exit(1);
848
849
  }
849
850
  if (ctx.values["send-key"] && !ctx.values["auto-send"]) {
850
- logger$4.error("--send-key requires --auto-send to be enabled");
851
+ logger$5.error("--send-key requires --auto-send to be enabled");
851
852
  process.exit(1);
852
853
  }
853
854
  const config = readSendConfig();
@@ -888,7 +889,7 @@ function getFormattedDateTime() {
888
889
  async function createTempFile() {
889
890
  const tempDir = join(tmpdir(), "editprompt-prompts");
890
891
  await mkdir(tempDir, { recursive: true });
891
- const filePath = join(tempDir, `${TEMP_FILE_PREFIX}${getFormattedDateTime()}${TEMP_FILE_EXTENSION}`);
892
+ const filePath = join(tempDir, `${TEMP_FILE_PREFIX}${getFormattedDateTime()}-${randomBytes(4).toString("hex")}${TEMP_FILE_EXTENSION}`);
892
893
  await writeFile(filePath, "", "utf-8");
893
894
  return filePath;
894
895
  }
@@ -947,7 +948,7 @@ async function openEditorAndGetContent(editorOption, envVars, sendConfig) {
947
948
 
948
949
  //#endregion
949
950
  //#region src/modes/openEditor.ts
950
- const logger$3 = getLogger(["editprompt", "open"]);
951
+ const logger$4 = getLogger(["editprompt", "open"]);
951
952
  async function runOpenEditorMode(options) {
952
953
  if (options.targetPanes.length > 0 && options.mux === "tmux") try {
953
954
  await markAsEditorPane$1(await getCurrentPaneId$1(), options.targetPanes);
@@ -962,10 +963,10 @@ async function runOpenEditorMode(options) {
962
963
  alwaysCopy: options.alwaysCopy,
963
964
  sendKeyDelay: Number.parseInt(process.env.EDITPROMPT_SEND_KEY_DELAY || "", 10) || 1e3
964
965
  };
965
- logger$3.info("Opening editor...");
966
+ logger$4.info("Opening editor...");
966
967
  const content = await openEditorAndGetContent(options.editor, options.env, sendConfig);
967
968
  if (!content) {
968
- logger$3.info("No content entered. Exiting.");
969
+ logger$4.info("No content entered. Exiting.");
969
970
  return;
970
971
  }
971
972
  try {
@@ -974,12 +975,12 @@ async function runOpenEditorMode(options) {
974
975
  console.log(content);
975
976
  if (options.alwaysCopy && !result.allFailed) {
976
977
  await copyToClipboard(content);
977
- logger$3.info("Also copied to clipboard.");
978
+ logger$4.info("Also copied to clipboard.");
978
979
  }
979
980
  if (options.targetPanes.length > 0 && result.successCount > 0) await focusFirstSuccessPane(options.mux, options.targetPanes, result.failedPanes);
980
981
  if (!result.allSuccess) process.exit(1);
981
982
  } catch (error) {
982
- logger$3.error(`${error instanceof Error ? error.message : "Unknown error"}`);
983
+ logger$4.error(`${error instanceof Error ? error.message : "Unknown error"}`);
983
984
  process.exit(1);
984
985
  }
985
986
  } finally {
@@ -1027,10 +1028,10 @@ const openCommand = define({
1027
1028
 
1028
1029
  //#endregion
1029
1030
  //#region src/modes/register.ts
1030
- const logger$2 = getLogger(["editprompt", "register"]);
1031
+ const logger$3 = getLogger(["editprompt", "register"]);
1031
1032
  async function runRegisterMode(options) {
1032
1033
  if (options.targetPanes.length === 0) {
1033
- logger$2.error("--target-pane is required for register command");
1034
+ logger$3.error("--target-pane is required for register command");
1034
1035
  process.exit(1);
1035
1036
  }
1036
1037
  let editorPaneId;
@@ -1038,17 +1039,17 @@ async function runRegisterMode(options) {
1038
1039
  else if (options.mux === "tmux") {
1039
1040
  editorPaneId = await getCurrentPaneId$1();
1040
1041
  if (!await isEditorPane(editorPaneId)) {
1041
- logger$2.error("Current pane is not an editor pane. Please run this command from an editor pane or specify --editor-pane.");
1042
+ logger$3.error("Current pane is not an editor pane. Please run this command from an editor pane or specify --editor-pane.");
1042
1043
  process.exit(1);
1043
1044
  }
1044
1045
  } else if (options.mux === "wezterm") {
1045
1046
  editorPaneId = await getCurrentPaneId();
1046
1047
  if (!isEditorPaneFromConf(editorPaneId)) {
1047
- logger$2.error("Current pane is not an editor pane. Please run this command from an editor pane or specify --editor-pane.");
1048
+ logger$3.error("Current pane is not an editor pane. Please run this command from an editor pane or specify --editor-pane.");
1048
1049
  process.exit(1);
1049
1050
  }
1050
1051
  } else {
1051
- logger$2.error("Unsupported multiplexer");
1052
+ logger$3.error("Unsupported multiplexer");
1052
1053
  process.exit(1);
1053
1054
  }
1054
1055
  try {
@@ -1058,9 +1059,9 @@ async function runRegisterMode(options) {
1058
1059
  const mergedTargetPanes = [...new Set([...existingPanes, ...options.targetPanes])];
1059
1060
  if (options.mux === "tmux") await markAsEditorPane$1(editorPaneId, mergedTargetPanes);
1060
1061
  else if (options.mux === "wezterm") await markAsEditorPane(editorPaneId, mergedTargetPanes);
1061
- logger$2.info(`Editor pane ${editorPaneId} registered with target panes: ${mergedTargetPanes.join(", ")}`);
1062
+ logger$3.info(`Editor pane ${editorPaneId} registered with target panes: ${mergedTargetPanes.join(", ")}`);
1062
1063
  } catch (error) {
1063
- logger$2.error(`${error instanceof Error ? error.message : "Unknown error"}`);
1064
+ logger$3.error(`${error instanceof Error ? error.message : "Unknown error"}`);
1064
1065
  process.exit(1);
1065
1066
  }
1066
1067
  }
@@ -1095,15 +1096,15 @@ const registerCommand = define({
1095
1096
 
1096
1097
  //#endregion
1097
1098
  //#region src/modes/resume.ts
1098
- const logger$1 = getLogger(["editprompt", "resume"]);
1099
+ const logger$2 = getLogger(["editprompt", "resume"]);
1099
1100
  async function runResumeMode(targetPane, mux) {
1100
1101
  if (mux === "wezterm") {
1101
1102
  const currentPaneId = await getCurrentPaneId();
1102
1103
  if (isEditorPaneFromConf(currentPaneId)) {
1103
- logger$1.debug("Current pane is an editor pane");
1104
+ logger$2.debug("Current pane is an editor pane");
1104
1105
  const originalTargetPaneIds = await getTargetPaneIds(currentPaneId);
1105
1106
  if (originalTargetPaneIds.length === 0) {
1106
- logger$1.debug("No target pane IDs found for editor pane");
1107
+ logger$2.debug("No target pane IDs found for editor pane");
1107
1108
  process.exit(1);
1108
1109
  }
1109
1110
  let focused = false;
@@ -1113,20 +1114,20 @@ async function runResumeMode(targetPane, mux) {
1113
1114
  break;
1114
1115
  }
1115
1116
  if (!focused) {
1116
- logger$1.debug("All target panes do not exist");
1117
+ logger$2.debug("All target panes do not exist");
1117
1118
  process.exit(1);
1118
1119
  }
1119
1120
  process.exit(0);
1120
1121
  }
1121
- logger$1.debug("Current pane is not an editor pane");
1122
+ logger$2.debug("Current pane is not an editor pane");
1122
1123
  const editorPaneId = await getEditorPaneId(targetPane);
1123
- logger$1.debug("wezterm editorPaneId: {editorPaneId}", { editorPaneId });
1124
+ logger$2.debug("wezterm editorPaneId: {editorPaneId}", { editorPaneId });
1124
1125
  if (editorPaneId === "") {
1125
- logger$1.debug("Editor pane ID not found");
1126
+ logger$2.debug("Editor pane ID not found");
1126
1127
  process.exit(1);
1127
1128
  }
1128
1129
  if (!await checkPaneExists(editorPaneId)) {
1129
- logger$1.debug("Editor pane does not exist");
1130
+ logger$2.debug("Editor pane does not exist");
1130
1131
  await clearEditorPaneId(targetPane);
1131
1132
  process.exit(1);
1132
1133
  }
@@ -1134,7 +1135,7 @@ async function runResumeMode(targetPane, mux) {
1134
1135
  await focusPane(editorPaneId);
1135
1136
  process.exit(0);
1136
1137
  } catch (error) {
1137
- logger$1.debug("Can't focus editorPaneId: {editorPaneId}, error: {error}", {
1138
+ logger$2.debug("Can't focus editorPaneId: {editorPaneId}, error: {error}", {
1138
1139
  editorPaneId,
1139
1140
  error
1140
1141
  });
@@ -1183,6 +1184,77 @@ const resumeCommand = define({
1183
1184
  }
1184
1185
  });
1185
1186
 
1187
+ //#endregion
1188
+ //#region src/modes/press.ts
1189
+ const logger$1 = getLogger(["editprompt", "press"]);
1190
+ async function runPressMode(key, delay = 0) {
1191
+ if (!key) {
1192
+ logger$1.error("Key is required");
1193
+ process.exit(1);
1194
+ }
1195
+ const config = readSendConfig();
1196
+ let currentPaneId;
1197
+ let isEditor;
1198
+ if (config.mux === "tmux") {
1199
+ currentPaneId = await getCurrentPaneId$1();
1200
+ isEditor = await isEditorPane(currentPaneId);
1201
+ } else {
1202
+ currentPaneId = await getCurrentPaneId();
1203
+ isEditor = isEditorPaneFromConf(currentPaneId);
1204
+ }
1205
+ if (!isEditor) {
1206
+ logger$1.error("Current pane is not an editor pane");
1207
+ process.exit(1);
1208
+ }
1209
+ let targetPanes;
1210
+ if (config.mux === "tmux") targetPanes = await getTargetPaneIds$1(currentPaneId);
1211
+ else targetPanes = await getTargetPaneIds(currentPaneId);
1212
+ if (targetPanes.length === 0) {
1213
+ logger$1.error("No target panes registered for this editor pane");
1214
+ process.exit(1);
1215
+ }
1216
+ let successCount = 0;
1217
+ for (const targetPane of targetPanes) try {
1218
+ if (config.mux === "wezterm") await sendKeyToWeztermPane(targetPane, key, delay);
1219
+ else await sendKeyToTmuxPane(targetPane, key, delay);
1220
+ successCount++;
1221
+ } catch (error) {
1222
+ logger$1.warn(`Failed to send key to pane ${targetPane}: ${error instanceof Error ? error.message : "Unknown error"}`);
1223
+ }
1224
+ if (successCount > 0) logger$1.info("Key sent successfully!");
1225
+ else {
1226
+ logger$1.error("All target panes failed to receive key");
1227
+ process.exit(1);
1228
+ }
1229
+ }
1230
+ const pressCommand = define({
1231
+ name: "press",
1232
+ description: "Send a key to target pane without Enter",
1233
+ args: {
1234
+ delay: {
1235
+ description: "Delay before sending key (milliseconds)",
1236
+ type: "string"
1237
+ },
1238
+ "log-file": ARG_LOG_FILE,
1239
+ quiet: ARG_QUIET,
1240
+ verbose: ARG_VERBOSE
1241
+ },
1242
+ async run(ctx) {
1243
+ setupLogger({
1244
+ quiet: Boolean(ctx.values.quiet),
1245
+ verbose: Boolean(ctx.values.verbose),
1246
+ logFile: ctx.values["log-file"]
1247
+ });
1248
+ const key = extractRawContent(ctx.rest, ctx.positionals);
1249
+ if (key === void 0 || key === "") {
1250
+ logger$1.error("Key is required for press command");
1251
+ logger$1.error("Usage: editprompt press -- \"Tab\"");
1252
+ process.exit(1);
1253
+ }
1254
+ await runPressMode(key, ctx.values.delay ? Number(ctx.values.delay) : 0);
1255
+ }
1256
+ });
1257
+
1186
1258
  //#endregion
1187
1259
  //#region src/modes/stash.ts
1188
1260
  const logger = getLogger(["editprompt", "stash"]);
@@ -1395,6 +1467,7 @@ await cli(process.argv.slice(2), {
1395
1467
  register: registerCommand,
1396
1468
  resume: resumeCommand,
1397
1469
  input: inputCommand,
1470
+ press: pressCommand,
1398
1471
  collect: collectCommand,
1399
1472
  dump: dumpCommand,
1400
1473
  stash: stashCommand
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "editprompt",
3
- "version": "1.3.0",
3
+ "version": "1.4.1",
4
4
  "description": "A CLI tool that lets you write prompts for CLI tools using your favorite text editor",
5
5
  "keywords": [
6
6
  "cli",