editprompt 0.0.6 → 0.1.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.
Files changed (3) hide show
  1. package/README.md +45 -29
  2. package/dist/index.js +39 -15
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  A CLI tool that lets you write prompts for CLI tools using your favorite text editor. Originally designed for [Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview), but works with any CLI process.
4
4
 
5
+ https://github.com/user-attachments/assets/01bcda7c-7771-4b33-bf5c-629812d45cc4
6
+
5
7
  ## Features
6
8
 
7
9
  - 🖊️ **Editor Integration**: Use your preferred text editor to write prompts
@@ -36,6 +38,10 @@ editprompt -e nvim
36
38
  editprompt --process gemini
37
39
  editprompt -p gemini
38
40
 
41
+ # Send content to a specific tmux pane
42
+ editprompt --target-pane %45
43
+ editprompt -t %45
44
+
39
45
  # Show help
40
46
  editprompt --help
41
47
 
@@ -43,15 +49,39 @@ editprompt --help
43
49
  editprompt --version
44
50
  ```
45
51
 
46
- It is useful to configure tmux as follows.
52
+ ### Tmux Integration
53
+
54
+ editprompt offers two modes for tmux integration:
55
+
56
+ #### Recommended: Direct Pane Targeting
57
+ Use `--target-pane #{pane_id}` to automatically send content back to the pane where you triggered the command. This is useful when using Claude Code, etc. in multiple panes.
47
58
 
59
+ **Split window version:**
60
+ ```tmux
61
+ bind -n M-q run-shell 'tmux split-window -v -l 20 \
62
+ -c "#{pane_current_path}" \
63
+ "editprompt --editor nvim --target-pane #{pane_id}"'
64
+ ```
65
+
66
+ **Popup version:**
67
+ ```tmux
68
+ bind -n M-q run-shell 'tmux display-popup -E \
69
+ -d "#{pane_current_path}" \
70
+ -w 80% -h 65% \
71
+ "editprompt --editor nvim --target-pane #{pane_id}"'
72
+ ```
73
+
74
+ #### Alternative: Process Auto-detection
75
+ Let editprompt automatically detect and select target processes:
76
+
77
+ **Split window version:**
48
78
  ```tmux
49
79
  bind -n M-q split-window -v -l 10 \
50
80
  -c '#{pane_current_path}' \
51
81
  'editprompt --editor nvim'
52
82
  ```
53
83
 
54
- If you prefer popup, you can configure it as follows.
84
+ **Popup version:**
55
85
  ```tmux
56
86
  bind -n M-q display-popup -E \
57
87
  -d '#{pane_current_path}' \
@@ -62,25 +92,13 @@ bind -n M-q display-popup -E \
62
92
 
63
93
  1. **Opens your editor** with a temporary markdown file
64
94
  2. **Write your prompt** and save/exit the editor
65
- 3. **Detects target processes** running on your system (default: claude)
66
- 4. **Sends the prompt** using the best available method:
67
- - 🎯 **Tmux sessions**: Direct input via `tmux send-keys`
68
- - 📋 **Clipboard**: Copies content as final fallback
69
-
70
- ### Process Selection
95
+ 3. **Sends the prompt** using one of two modes:
96
+ - 🎯 **Direct pane mode** (`--target-pane`): Sends directly to specified tmux pane
97
+ - 🔍 **Process detection mode**: Finds target processes and sends via tmux or clipboard
98
+ 4. **Fallback strategy** ensures delivery:
99
+ - Tmux integration (preferred)
100
+ - Clipboard copy (fallback)
71
101
 
72
- When multiple processes are detected, you'll see an interactive selection menu:
73
-
74
- ```
75
- ? Select a process:
76
- 1. PID: 12345 | Tmux: main:0.1 | Directory: /home/user/project1
77
- 2. PID: 67890 | Directory: /home/user/project2
78
- ```
79
-
80
- The display shows:
81
- - **PID**: Process ID
82
- - **Tmux**: Session, window, and pane (if running in tmux)
83
- - **Directory**: Working directory of the process
84
102
 
85
103
  ## Configuration
86
104
 
@@ -96,11 +114,7 @@ editprompt respects the following editor priority:
96
114
 
97
115
  - `EDITOR`: Your preferred text editor
98
116
 
99
- ## Requirements
100
-
101
- - Node.js 18+ or Bun
102
- - Target CLI process (default: `claude` command)
103
- - Optional: tmux (for direct session integration)
117
+ ---
104
118
 
105
119
  ## Development
106
120
 
@@ -141,12 +155,14 @@ src/
141
155
 
142
156
  ### Tmux Integration
143
157
 
144
- When the target process is running in a tmux session, editprompt uses `tmux send-keys` to send input directly to the appropriate pane. This provides seamless integration without disrupting your existing session.
158
+ editprompt supports two tmux integration modes:
159
+
160
+ - **Direct pane targeting** (`--target-pane`): Bypasses process detection and sends content directly to specified pane ID
161
+ - **Process-based targeting**: Detects target processes and links them to tmux panes for delivery
145
162
 
146
163
  ### Fallback Strategy
147
164
 
148
- editprompt implements fallback strategy:
165
+ editprompt implements a robust fallback strategy:
149
166
 
150
167
  1. **Tmux Integration**: Direct input to tmux panes (when available)
151
- <!-- 2. **New Process**: Launch new Claude instance with piped input -->
152
- 2. **Clipboard**: Copy content to clipboard with error notification
168
+ 2. **Clipboard**: Copy content to clipboard with user notification
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ import find from "find-process";
10
10
  import inquirer from "inquirer";
11
11
 
12
12
  //#region package.json
13
- var version = "0.0.6";
13
+ var version = "0.1.0";
14
14
 
15
15
  //#endregion
16
16
  //#region src/config/constants.ts
@@ -169,11 +169,20 @@ async function sendToTmuxPane(session, window, pane, content) {
169
169
  const target = `${session}:${window}.${pane}`;
170
170
  await execAsync(`tmux send-keys -t '${target}' '${content.replace(/'/g, "'\\''")}'`);
171
171
  }
172
+ async function sendToSpecificPane(paneId, content) {
173
+ const tempContent = content.replace(/'/g, "'\\''");
174
+ await execAsync(`tmux load-buffer -b editprompt - <<< '${tempContent}'`);
175
+ await execAsync(`tmux paste-buffer -d -t '${paneId}' -b editprompt`);
176
+ }
172
177
  async function copyToClipboard(content) {
173
178
  await clipboardy.write(content);
174
179
  }
175
- async function sendContentToProcess(process$1, content) {
180
+ async function sendContentToProcess(process$1, content, targetPaneId) {
176
181
  try {
182
+ if (targetPaneId) {
183
+ await sendToSpecificPane(targetPaneId, content);
184
+ return;
185
+ }
177
186
  if (process$1.tmuxSession && process$1.tmuxWindow && process$1.tmuxPane) {
178
187
  await sendToTmuxPane(process$1.tmuxSession, process$1.tmuxWindow, process$1.tmuxPane, content);
179
188
  return;
@@ -226,6 +235,11 @@ await cli(argv, {
226
235
  short: "p",
227
236
  description: "Process name to target (default: claude)",
228
237
  type: "string"
238
+ },
239
+ "target-pane": {
240
+ short: "t",
241
+ description: "Target tmux pane ID to send content to",
242
+ type: "string"
229
243
  }
230
244
  },
231
245
  async run(ctx) {
@@ -236,20 +250,30 @@ await cli(argv, {
236
250
  console.log("No content entered. Exiting.");
237
251
  return;
238
252
  }
239
- const processName = ctx.values.process || DEFAULT_PROCESS_NAME;
240
- console.log(`Searching for ${processName} processes...`);
241
- const processes = await findTargetProcesses(processName);
242
- if (processes.length === 0) console.log(`No ${processName} process found.`);
243
- else {
244
- const selectedProcess = await selectProcess(processes);
245
- if (!selectedProcess) return;
246
- const processInfo = [`PID ${selectedProcess.pid}`];
247
- if (selectedProcess.tmuxSession) processInfo.push(`Tmux: ${selectedProcess.tmuxSession}:${selectedProcess.tmuxWindow}.${selectedProcess.tmuxPane}`);
248
- if (selectedProcess.cwd) processInfo.push(`Directory: ${selectedProcess.cwd}`);
249
- console.log(`Selected process: ${processInfo.join(" | ")}`);
250
- console.log(`Sending content to ${processName} process...`);
251
- await sendContentToProcess(selectedProcess, content);
253
+ const targetPane = ctx.values["target-pane"];
254
+ if (targetPane) {
255
+ console.log("Sending content to specified pane...");
256
+ await sendContentToProcess({
257
+ pid: 0,
258
+ name: "direct-pane"
259
+ }, content, targetPane);
252
260
  console.log("Content sent successfully!");
261
+ } else {
262
+ const processName = ctx.values.process || DEFAULT_PROCESS_NAME;
263
+ console.log(`Searching for ${processName} processes...`);
264
+ const processes = await findTargetProcesses(processName);
265
+ if (processes.length === 0) console.log(`No ${processName} process found.`);
266
+ else {
267
+ const selectedProcess = await selectProcess(processes);
268
+ if (!selectedProcess) return;
269
+ const processInfo = [`PID ${selectedProcess.pid}`];
270
+ if (selectedProcess.tmuxSession) processInfo.push(`Tmux: ${selectedProcess.tmuxSession}:${selectedProcess.tmuxWindow}.${selectedProcess.tmuxPane}`);
271
+ if (selectedProcess.cwd) processInfo.push(`Directory: ${selectedProcess.cwd}`);
272
+ console.log(`Selected process: ${processInfo.join(" | ")}`);
273
+ console.log(`Sending content to ${processName} process...`);
274
+ await sendContentToProcess(selectedProcess, content);
275
+ console.log("Content sent successfully!");
276
+ }
253
277
  }
254
278
  } catch (error) {
255
279
  console.error(`Error: ${error instanceof Error ? error.message : "Unknown error"}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "editprompt",
3
- "version": "0.0.6",
3
+ "version": "0.1.0",
4
4
  "author": "eetann",
5
5
  "description": "A CLI tool that lets you write prompts for CLI tools using your favorite text editor",
6
6
  "license": "MIT",