rubber-ducky 1.6.0__py3-none-any.whl → 1.6.1__py3-none-any.whl

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.
ducky/ducky.py CHANGED
@@ -554,7 +554,7 @@ class InlineInterface:
554
554
  if self.crumb_manager.has_crumb(first_word):
555
555
  # Extract additional arguments after the crumb name
556
556
  parts = stripped.split()
557
- args = parts[1:] if len(parts) > 1 else None
557
+ args = parts[1:]
558
558
  await self._use_crumb(first_word, args)
559
559
  return
560
560
 
@@ -1195,7 +1195,7 @@ async def ducky() -> None:
1195
1195
  first_arg = args.single_prompt[0]
1196
1196
  if crumb_manager.has_crumb(first_arg):
1197
1197
  # Extract crumb arguments (everything after the crumb name)
1198
- crumb_args = args.single_prompt[1:] if len(args.single_prompt) > 1 else None
1198
+ crumb_args = args.single_prompt[1:]
1199
1199
 
1200
1200
  crumb = crumb_manager.get_crumb(first_arg)
1201
1201
  if crumb:
@@ -1243,7 +1243,7 @@ async def ducky() -> None:
1243
1243
 
1244
1244
 
1245
1245
  def substitute_placeholders(command: str, args: list[str]) -> str:
1246
- """Replace ${VAR} placeholders in command with provided arguments.
1246
+ """Replace ${VAR} and $var placeholders in command with provided arguments.
1247
1247
 
1248
1248
  Args:
1249
1249
  command: The command string with placeholders
@@ -1254,16 +1254,17 @@ def substitute_placeholders(command: str, args: list[str]) -> str:
1254
1254
  """
1255
1255
  result = command
1256
1256
  arg_index = 0
1257
- placeholder_pattern = re.compile(r'\$\{([^}]+)\}')
1257
+ placeholder_pattern = re.compile(r'\$\{([^}]+)\}|\$(\w+)')
1258
1258
 
1259
1259
  def replace_placeholder(match: re.Match) -> str:
1260
1260
  nonlocal arg_index
1261
+ # Get the variable name from either ${VAR} or $var format
1262
+ var_name = match.group(1) or match.group(2)
1261
1263
  if arg_index < len(args):
1262
1264
  value = args[arg_index]
1263
1265
  arg_index += 1
1264
1266
  return value
1265
1267
  # Fallback to environment variable
1266
- var_name = match.group(1)
1267
1268
  return os.environ.get(var_name, match.group(0))
1268
1269
 
1269
1270
  result = placeholder_pattern.sub(replace_placeholder, result)
@@ -0,0 +1,317 @@
1
+ Metadata-Version: 2.4
2
+ Name: rubber-ducky
3
+ Version: 1.6.1
4
+ Summary: Quick CLI do-it-all tool. Use natural language to spit out bash commands
5
+ Requires-Python: >=3.10
6
+ Description-Content-Type: text/markdown
7
+ License-File: LICENSE
8
+ Requires-Dist: colorama>=0.4.6
9
+ Requires-Dist: fastapi>=0.115.11
10
+ Requires-Dist: ollama>=0.6.0
11
+ Requires-Dist: openai>=1.60.2
12
+ Requires-Dist: prompt-toolkit>=3.0.48
13
+ Requires-Dist: rich>=13.9.4
14
+ Requires-Dist: termcolor>=2.5.0
15
+ Dynamic: license-file
16
+
17
+ # Rubber Ducky
18
+
19
+ Turn natural language into bash commands without leaving your terminal.
20
+
21
+ Rubber Ducky is an inline terminal companion that transforms your prompts into runnable shell commands. Paste multi-line context, get smart suggestions, and execute commands instantly.
22
+
23
+ ---
24
+
25
+ ## Quick Start
26
+
27
+ ```bash
28
+ # Install globally (recommended)
29
+ uv tool install rubber-ducky
30
+
31
+ # Run interactively
32
+ ducky
33
+
34
+ # Quick one-shot
35
+ ducky "list all files larger than 10MB in current directory"
36
+
37
+ # From CLI with options
38
+ ducky --model qwen3
39
+ ducky --directory src
40
+ ducky --local
41
+
42
+ # Or use uvx (requires -- separator)
43
+ uvx rubber-ducky -- --model qwen3
44
+ ```
45
+
46
+ Both `ducky` and `rubber-ducky` executables work identically.
47
+
48
+ ### Requirements
49
+
50
+ - [Ollama](https://ollama.com) (running locally or using cloud models)
51
+ - Python 3.10+
52
+
53
+ ---
54
+
55
+ ## Features
56
+
57
+ - **Natural to Shell** - Describe what you want, get the bash command
58
+ - **Model Flexibility** - Switch between local Ollama models and cloud models
59
+ - **Crumbs** - Save and reuse commands with argument substitution
60
+ - **Piped Input** - Pipe output from other commands directly to ducky
61
+ - **Interactive REPL** - Rich terminal experience with history and shortcuts
62
+ - **Code Context** - Preload project code for AI awareness
63
+ - **Clipboard Support** - Copy commands across macOS, Windows, and Linux
64
+
65
+ ---
66
+
67
+ ## Key Concepts
68
+
69
+ ### REPL (Interactive Mode)
70
+
71
+ Launch `ducky` to start an inline session:
72
+
73
+ ```
74
+ ducky
75
+ ```
76
+
77
+ **Key controls:**
78
+ - `Enter` - Submit prompt
79
+ - `Ctrl+J` - Insert newline (for multi-line prompts)
80
+ - `Empty Enter` - Rerun last command or explain shell output
81
+ - `Ctrl+R` - Re-run last suggested command
82
+ - `Ctrl+S` - Copy last command to clipboard
83
+ - `!<cmd>` - Run shell command immediately
84
+ - `Arrow keys` - Browse history
85
+ - `Ctrl+D` - Exit
86
+
87
+ ### Models
88
+
89
+ Rubber Ducky supports both local and cloud models:
90
+
91
+ - `/model` - Interactive model selection
92
+ - `/local` - List local models (localhost:11434)
93
+ - `/cloud` - List cloud models (ollama.com)
94
+ - Last used model is saved automatically
95
+
96
+ **Startup flags:**
97
+ - `--local` / `-l` - Use local Ollama with qwen3 default
98
+ - `--model <name>` / `-m` - Specify model directly
99
+
100
+ ### Crumbs
101
+
102
+ Crumbs are saved command shortcuts. Store frequently-used commands or complex workflows:
103
+
104
+ ```
105
+ >> How do I list all running Python processes?
106
+ ...
107
+ Suggested: ps aux | grep python | grep -v grep
108
+ >> /crumb pyprocs
109
+ Saved crumb 'pyprocs'!
110
+ ```
111
+
112
+ **Invoke crumb:**
113
+ ```
114
+ >> pyprocs
115
+ Crumb: pyprocs
116
+ Command: ps aux | grep python | grep -v grep
117
+ ...
118
+ ```
119
+
120
+ **With argument substitution:**
121
+ ```bash
122
+ # Crumb command: git worktree add "../$var-$other" -b $var3
123
+ ducky at feature backend develop
124
+ # Executes: git worktree add "../feature-backend" -b develop
125
+ ```
126
+
127
+ ---
128
+
129
+ ## Usage Guide
130
+
131
+ ### Interactive Mode
132
+
133
+ Default mode. Perfect for development sessions.
134
+
135
+ ```bash
136
+ ducky
137
+ ```
138
+
139
+ Load code context for better suggestions:
140
+
141
+ ```bash
142
+ ducky --directory src
143
+ ```
144
+
145
+ ### Single-Shot Mode
146
+
147
+ Get one command suggestion and exit.
148
+
149
+ ```bash
150
+ ducky "find all TODO comments in src/"
151
+ ```
152
+
153
+ Copy to clipboard automatically:
154
+
155
+ ```bash
156
+ ducky "build and run tests"
157
+ ```
158
+
159
+ ### Piped Input
160
+
161
+ Process text from other commands:
162
+
163
+ ```bash
164
+ cat error.log | ducky "what's wrong here?"
165
+ git diff | ducky "summarize these changes"
166
+ ```
167
+
168
+ ### Run Without Confirmation
169
+
170
+ Auto-execute suggested commands:
171
+
172
+ ```bash
173
+ ducky --yolo "restart the nginx service"
174
+ ```
175
+
176
+ ---
177
+
178
+ ## Crumbs Quick Reference
179
+
180
+ | Command | Description |
181
+ |---------|-------------|
182
+ | `/crumbs` | List all saved crumbs |
183
+ | `/crumb <name>` | Save last command as crumb |
184
+ | `/crumb add <name> <cmd>` | Manually add crumb |
185
+ | `/crumb del <name>` | Delete crumb |
186
+ | `<name>` | Execute crumb |
187
+ | `/crumb help` | Detailed crumb help |
188
+
189
+ **Argument Substitution:**
190
+
191
+ Crumbs support `${VAR}` and `$var` placeholder styles:
192
+
193
+ ```bash
194
+ # Create crumb with placeholders
195
+ git worktree add "../$var-$other" -b $var3
196
+
197
+ # Invoke with arguments
198
+ ducky at feature backend develop
199
+ ```
200
+
201
+ Both styles are interchangeable.
202
+
203
+ ---
204
+
205
+ ## Command Reference
206
+
207
+ ### Inline Commands
208
+
209
+ | Command | Action |
210
+ |---------|--------|
211
+ | `/help` | Show all commands |
212
+ | `/clear` / `/reset` | Clear conversation history |
213
+ | `/model` | Select model (interactive) |
214
+ | `/local` | List local models |
215
+ | `/cloud` | List cloud models |
216
+ | `/run` / `:run` | Re-run last command |
217
+ | `/expand` | Show full output of last shell command |
218
+
219
+ ### CLI Flags
220
+
221
+ | Flag | Description |
222
+ |------|-------------|
223
+ | `--directory <path>` / `-d` | Preload code from directory |
224
+ | `--model <name>` / `-m` | Specify Ollama model |
225
+ | `--local` / `-l` | Use local Ollama (qwen3 default) |
226
+ | `--yolo` / `-y` | Auto-run without confirmation |
227
+ | `<prompt>` | Single prompt mode (copied to clipboard) |
228
+
229
+ ---
230
+
231
+ ## Tips & Tricks
232
+
233
+ ### Efficient Workflows
234
+
235
+ ```bash
236
+ # Preload project context
237
+ ducky --directory src
238
+
239
+ # Reuse complex commands with crumbs
240
+ docker ps | ducky "kill all containers"
241
+ >> /crumb killall
242
+
243
+ # Chain commands
244
+ !ls -la
245
+ ducksy "find large files"
246
+
247
+ # Use history
248
+ [↑] Recall previous prompts
249
+ [↓] Navigate command history
250
+ ```
251
+
252
+ ### Keyboard Shortcuts Reference
253
+
254
+ | Key | Action |
255
+ |-----|--------|
256
+ | `Enter` | Submit prompt |
257
+ | `Ctrl+J` | Insert newline |
258
+ | `Empty Enter` | Rerun last command or explain |
259
+ | `Ctrl+R` | Re-run last suggested command |
260
+ | `Ctrl+S` | Copy to clipboard |
261
+ | `Ctrl+D` | Exit |
262
+ | `!cmd` | Run shell command directly |
263
+
264
+ ### Crumb Patterns
265
+
266
+ ```bash
267
+ # Save after complex command
268
+ >> docker-compose up -d && wait && docker-compose logs
269
+ >> /crumb start-logs
270
+
271
+ # Manually add with arguments
272
+ >> /crumb add deploy-prod docker build -t app:latest && docker push app:latest
273
+
274
+ # Use for common workflows
275
+ >> ls -la
276
+ find . -type f -name "*.py" | xargs wc -l
277
+ >> /crumb count-py
278
+ ```
279
+
280
+ ---
281
+
282
+ ## Storage
283
+
284
+ Rubber Ducky stores data in `~/.ducky/`:
285
+
286
+ | File | Purpose |
287
+ |------|---------|
288
+ | `prompt_history` | readline-compatible history |
289
+ | `conversation.log` | JSON log of all interactions |
290
+ | `config` | User preferences (last model) |
291
+ | `crumbs.json` | Saved crumb shortcuts |
292
+
293
+ Delete the entire directory for a fresh start.
294
+
295
+ ---
296
+
297
+ ## Development
298
+
299
+ ```bash
300
+ # Clone and setup
301
+ git clone <repo>
302
+ cd ducky
303
+ uv sync
304
+
305
+ # Run
306
+ uv run ducky --help
307
+ uv run ducky
308
+
309
+ # Lint
310
+ uv run ruff check .
311
+ ```
312
+
313
+ ---
314
+
315
+ ## License
316
+
317
+ MIT © 2023 Parth Sareen
@@ -1,13 +1,13 @@
1
1
  ducky/__init__.py,sha256=2vLhJxOuJ3lnIeg5rmF6xUvybUT5Qhjej6AS0BeBASY,60
2
2
  ducky/config.py,sha256=Lh7xTUYh4i8Gxgrl0oTYadZB_72Wy2BKIqLCcDQduOA,2116
3
3
  ducky/crumb.py,sha256=7BlyjD81-cZptYxQM97y6gOGdVDBF2qzxW0xbPqbspE,2693
4
- ducky/ducky.py,sha256=mPxbfk9LVPpYUz9nh6zsgCH7K2S-HV46FniIVMJbHm8,47342
4
+ ducky/ducky.py,sha256=LMAp1ZV7dR-NR6uoSiUpfcanHXU1eRA55Q0jB_ViMwo,47374
5
5
  examples/POLLING_USER_GUIDE.md,sha256=rMEAczZhpgyJ9BgwHkN-SKwSdyas8nlw_CjpV7SFOLA,10685
6
6
  examples/mock-logs/info.txt,sha256=apJqEO__UM1R2_2x9MlQOA7XmxvLvbhRvOy-FAwrINo,258
7
7
  examples/mock-logs/mock-logs.sh,sha256=zM2JSaCR1eCQLlMvXDWjFnpxZTqrMpnFRa_SgNLPmBk,1132
8
- rubber_ducky-1.6.0.dist-info/licenses/LICENSE,sha256=gQ1rCmw18NqTk5GxG96F6vgyN70e1c4kcKUtWDwdNaE,1069
9
- rubber_ducky-1.6.0.dist-info/METADATA,sha256=_Q7V5YvGVeDVBPPkeeKbw5hiIFM2u1R0TnQm5_9JTtU,6733
10
- rubber_ducky-1.6.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
11
- rubber_ducky-1.6.0.dist-info/entry_points.txt,sha256=WPnVUUNvWdMDcBlCo8JCzkLghGllMX5QVZyQghyq85Q,75
12
- rubber_ducky-1.6.0.dist-info/top_level.txt,sha256=hid_mDkugR6XIeravFKuzcRPpuN_ylN3ejC_06Fmnb4,15
13
- rubber_ducky-1.6.0.dist-info/RECORD,,
8
+ rubber_ducky-1.6.1.dist-info/licenses/LICENSE,sha256=gQ1rCmw18NqTk5GxG96F6vgyN70e1c4kcKUtWDwdNaE,1069
9
+ rubber_ducky-1.6.1.dist-info/METADATA,sha256=lZZ9iHVNunf7cJuyN7lLQK9vA1WUBVX3SGGWG4c7Mok,6638
10
+ rubber_ducky-1.6.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
11
+ rubber_ducky-1.6.1.dist-info/entry_points.txt,sha256=WPnVUUNvWdMDcBlCo8JCzkLghGllMX5QVZyQghyq85Q,75
12
+ rubber_ducky-1.6.1.dist-info/top_level.txt,sha256=hid_mDkugR6XIeravFKuzcRPpuN_ylN3ejC_06Fmnb4,15
13
+ rubber_ducky-1.6.1.dist-info/RECORD,,
@@ -1,198 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: rubber-ducky
3
- Version: 1.6.0
4
- Summary: Quick CLI do-it-all tool. Use natural language to spit out bash commands
5
- Requires-Python: >=3.10
6
- Description-Content-Type: text/markdown
7
- License-File: LICENSE
8
- Requires-Dist: colorama>=0.4.6
9
- Requires-Dist: fastapi>=0.115.11
10
- Requires-Dist: ollama>=0.6.0
11
- Requires-Dist: openai>=1.60.2
12
- Requires-Dist: prompt-toolkit>=3.0.48
13
- Requires-Dist: rich>=13.9.4
14
- Requires-Dist: termcolor>=2.5.0
15
- Dynamic: license-file
16
-
17
- # Rubber Ducky
18
-
19
- Rubber Ducky is an inline terminal companion that turns natural language prompts into runnable shell commands. Paste multi-line context, get a suggested command, and run it without leaving your terminal.
20
-
21
- ## Quick Start
22
-
23
- | Action | Command |
24
- | --- | --- |
25
- | Install globally | `uv tool install rubber-ducky` |
26
- | Run once | `uvx rubber-ducky -- --help` |
27
- | Local install | `uv pip install rubber-ducky` |
28
-
29
- Requirements:
30
- - [Ollama](https://ollama.com) running locally or use cloud models
31
- - Model available via Ollama (default: `glm-4.7:cloud`)
32
-
33
- ## Usage
34
-
35
- ```
36
- ducky # interactive inline session
37
- ducky --directory src # preload code from a directory
38
- ducky --model qwen3 # use a different Ollama model
39
- ducky --local # use local models with qwen3 default
40
- ```
41
-
42
- Both `ducky` and `rubber-ducky` executables map to the same CLI, so `uvx rubber-ducky -- <args>` works as well.
43
-
44
- ### Inline Session (default)
45
-
46
- Launching `ducky` with no arguments opens the inline interface:
47
- - **Enter** submits; **Ctrl+J** inserts a newline (helpful when crafting multi-line prompts). Hitting **Enter on an empty prompt** reruns the latest suggested command; if none exists yet, it explains the most recent shell output.
48
- - **Ctrl+R** re-runs the last suggested command.
49
- - **Ctrl+S** copies the last suggested command to clipboard.
50
- - Prefix any line with **`!`** (e.g., `!ls -la`) to run a shell command immediately.
51
- - Arrow keys browse prompt history, backed by `~/.ducky/prompt_history`.
52
- - Every prompt, assistant response, and executed command is logged to `~/.ducky/conversation.log`.
53
- - Press **Ctrl+D** on an empty line to exit.
54
- - Non-interactive runs such as `cat prompt.txt | ducky` print one response (and suggested command) before exiting; if a TTY is available you'll be asked whether to run the suggested command immediately.
55
- - If `prompt_toolkit` is unavailable in your environment, Rubber Ducky falls back to a basic input loop (no history or shortcuts); install `prompt-toolkit>=3.0.48` to unlock the richer UI.
56
-
57
- `ducky --directory <path>` streams the contents of the provided directory to the assistant the next time you submit a prompt (the directory is read once at startup).
58
-
59
- ### Model Management
60
-
61
- Rubber Ducky now supports easy switching between local and cloud models:
62
- - **`/model`** - Interactive model selection between local and cloud models
63
- - **`/local`** - List and select from local models (localhost:11434)
64
- - **`/cloud`** - List and select from cloud models (ollama.com)
65
- - Last used model is automatically saved and loaded on startup
66
- - Type **`esc`** during model selection to cancel
67
-
68
- ### Additional Commands
69
-
70
- - **`/help`** - Show all available commands and shortcuts
71
- - **`/crumbs`** - List all saved crumb shortcuts
72
- - **`/crumb <name>`** - Save the last AI-suggested command as a named crumb
73
- - **`/crumb add <name> <command>`** - Manually add a crumb with a specific command
74
- - **`/crumb del <name>`** - Delete a saved crumb
75
- - **`<crumb-name>`** - Invoke a saved crumb (displays info and executes the command)
76
- - **`/clear`** or **`/reset`** - Clear conversation history
77
- - **`/run`** or **`:run`** - Re-run the last suggested command
78
-
79
- ## Crumbs
80
-
81
- Crumbs are saved command shortcuts that let you quickly reuse AI-generated bash commands without regenerating them each time. Perfect for frequently-used workflows or complex commands.
82
-
83
- ### Saving Crumbs
84
-
85
- When the AI suggests a command that you want to reuse:
86
-
87
- 1. Get a command suggestion from ducky
88
- 2. Save it immediately: `/crumb <name>`
89
- 3. Example:
90
- ```
91
- >> How do I list all Ollama processes?
92
- ...
93
- Suggested command: ps aux | grep -i ollama | grep -v grep
94
- >> /crumb ols
95
- Saved crumb 'ols'!
96
- Generating explanation...
97
- Explanation added: Finds and lists all running Ollama processes.
98
- ```
99
-
100
- The crumb is saved with:
101
- - The original command
102
- - An AI-generated one-line explanation
103
- - A timestamp
104
-
105
- ### Invoking Crumbs
106
-
107
- Simply type the crumb name in the REPL or use it as a CLI argument:
108
-
109
- **In REPL:**
110
- ```
111
- >> ols
112
-
113
- Crumb: ols
114
- Explanation: Finds and lists all running Ollama processes.
115
- Command: ps aux | grep -i ollama | grep -v grep
116
-
117
- $ ps aux | grep -i ollama | grep -v grep
118
- user123 12345 0.3 1.2 456789 98765 ? Sl 10:00 0:05 ollama serve
119
- ```
120
-
121
- **From CLI:**
122
- ```bash
123
- ducky ols # Runs the saved crumb and displays output
124
- ```
125
-
126
- When you invoke a crumb:
127
- 1. It displays the crumb name, explanation, and command
128
- 2. Automatically executes the command
129
- 3. Shows the output
130
-
131
- ### Managing Crumbs
132
-
133
- **List all crumbs:**
134
- ```bash
135
- >> /crumbs
136
- ```
137
-
138
- Output:
139
- ```
140
- Saved Crumbs
141
- =============
142
- ols | Finds and lists all running Ollama processes. | ps aux | grep -i ollama | grep -v grep
143
- test | Run tests and build project | pytest && python build.py
144
- deploy | Deploy to production | docker push app:latest
145
- ```
146
-
147
- **Manually add a crumb:**
148
- ```bash
149
- >> /crumb add deploy-prod docker build -t app:latest && docker push app:latest
150
- ```
151
-
152
- **Delete a crumb:**
153
- ```bash
154
- >> /crumb ols
155
- Deleted crumb 'ols'.
156
- ```
157
-
158
- ### Storage
159
-
160
- Crumbs are stored in `~/.ducky/crumbs.json` as JSON. Each crumb includes:
161
- - `prompt`: Original user prompt
162
- - `response`: AI's full response
163
- - `command`: The suggested bash command
164
- - `explanation`: AI-generated one-line summary
165
- - `created_at`: ISO timestamp
166
-
167
- **Example:**
168
- ```json
169
- {
170
- "ols": {
171
- "prompt": "How do I list all Ollama processes?",
172
- "response": "To list all running Ollama processes...",
173
- "command": "ps aux | grep -i ollama | grep -v grep",
174
- "explanation": "Finds and lists all running Ollama processes.",
175
- "created_at": "2024-01-05T10:30:00.000000+00:00"
176
- }
177
- }
178
- ```
179
-
180
- Delete `~/.ducky/crumbs.json` to clear all saved crumbs.
181
-
182
- ## Development (uv)
183
-
184
- ```
185
- uv sync
186
- uv run ducky --help
187
- ```
188
-
189
- `uv sync` creates a virtual environment and installs dependencies defined in `pyproject.toml` / `uv.lock`.
190
-
191
- ## Telemetry & Storage
192
-
193
- Rubber Ducky stores:
194
- - `~/.ducky/prompt_history`: readline-compatible history file.
195
- - `~/.ducky/conversation.log`: JSON lines with timestamps for prompts, assistant messages, and shell executions.
196
- - `~/.ducky/config`: User preferences including last selected model.
197
-
198
- No other telemetry is collected; delete the directory if you want a fresh slate.