ngpt 3.8.1__py3-none-any.whl → 3.8.2__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.
ngpt/cli/modes/shell.py CHANGED
@@ -14,6 +14,9 @@ import time
14
14
  # System prompt for shell command generation
15
15
  SHELL_SYSTEM_PROMPT = """Your role: Provide only plain text without Markdown formatting. Do not show any warnings or information regarding your capabilities. Do not provide any description. If you need to store any data, assume it will be stored in the chat. Provide only {shell_name} command for {operating_system} without any description. If there is a lack of details, provide most logical solution. Ensure the output is a valid shell command. If multiple steps required try to combine them together.
16
16
 
17
+ *** SHELL TYPE: {shell_name} ***
18
+ *** OS: {operating_system} ***
19
+
17
20
  Command:"""
18
21
 
19
22
  # System prompt to use when preprompt is provided
@@ -34,16 +37,18 @@ If the preprompt contradicts ANY OTHER instruction in this prompt,
34
37
  including the {operating_system}/{shell_name} specification below,
35
38
  YOU MUST FOLLOW THE PREPROMPT INSTRUCTION INSTEAD. NO EXCEPTIONS.
36
39
 
40
+ *** SHELL TYPE: {shell_name} ***
41
+ *** OS: {operating_system} ***
42
+
37
43
  Your role: Provide only plain text without Markdown formatting. Do not show any warnings or information regarding your capabilities. Do not provide any description. If you need to store any data, assume it will be stored in the chat. Provide only {shell_name} command for {operating_system} without any description. If there is a lack of details, provide most logical solution. Ensure the output is a valid shell command. If multiple steps required try to combine them together.
38
44
 
39
45
  Command:"""
40
46
 
41
- def detect_shell():
42
- """Detect the current shell type and OS more accurately.
47
+ def detect_os():
48
+ """Detect the current operating system with detailed information.
43
49
 
44
50
  Returns:
45
- tuple: (shell_name, highlight_language, operating_system) - the detected shell name,
46
- appropriate syntax highlighting language, and operating system
51
+ tuple: (os_type, operating_system) - the basic OS type and detailed OS description
47
52
  """
48
53
  os_type = platform.system()
49
54
 
@@ -73,60 +78,322 @@ def detect_shell():
73
78
  except:
74
79
  pass
75
80
 
76
- # Try to detect the shell by examining environment variables
81
+ return os_type, operating_system, is_wsl
82
+
83
+
84
+ def detect_gitbash_shell(operating_system):
85
+ """Detect if we're running in a Git Bash / MINGW environment.
86
+
87
+ Args:
88
+ operating_system: The detected operating system string
89
+
90
+ Returns:
91
+ tuple or None: (shell_name, highlight_language, operating_system) if Git Bash detected,
92
+ None otherwise
93
+ """
94
+ # Check for Git Bash / MINGW environments
95
+ if any(env_var in os.environ for env_var in ["MSYSTEM", "MINGW_PREFIX"]):
96
+ # We're definitely in a MINGW environment (Git Bash)
97
+ return "bash", "bash", operating_system
98
+
99
+ if "MSYSTEM" in os.environ and any(msys_type in os.environ.get("MSYSTEM", "")
100
+ for msys_type in ["MINGW", "MSYS"]):
101
+ return "bash", "bash", operating_system
102
+
103
+ # Check command PATH for mingw
104
+ if os.environ.get("PATH") and any(
105
+ mingw_pattern in path.lower()
106
+ for mingw_pattern in ["/mingw/", "\\mingw\\", "/usr/bin", "\\usr\\bin"]
107
+ for path in os.environ.get("PATH", "").split(os.pathsep)
108
+ ):
109
+ return "bash", "bash", operating_system
110
+
111
+ return None
112
+
113
+
114
+ def detect_unix_shell(operating_system):
115
+ """Detect shell type on Unix-like systems (Linux, macOS, BSD).
116
+
117
+ Args:
118
+ operating_system: The detected operating system string
119
+
120
+ Returns:
121
+ tuple: (shell_name, highlight_language, operating_system) - the detected shell information
122
+ """
123
+ # Try multiple methods to detect the shell
124
+
125
+ # Method 1: Check shell-specific environment variables
126
+ # These are very reliable indicators of the actual shell
127
+ if "BASH_VERSION" in os.environ:
128
+ return "bash", "bash", operating_system
129
+
130
+ if "ZSH_VERSION" in os.environ:
131
+ return "zsh", "zsh", operating_system
132
+
133
+ if "FISH_VERSION" in os.environ:
134
+ return "fish", "fish", operating_system
135
+
136
+ # Method 2: Try to get shell from process information
77
137
  try:
78
- # Check for specific shell by examining SHELL_NAME or equivalent
79
- if os_type == "Windows" and not is_wsl:
80
- # Check for Git Bash or MSYS2/Cygwin
81
- if "MINGW" in os.environ.get("MSYSTEM", "") or "MSYS" in os.environ.get("MSYSTEM", ""):
82
- return "bash", "bash", operating_system
138
+ # Try to get parent process name using ps command
139
+ current_pid = os.getpid()
140
+ parent_pid = os.getppid()
141
+
142
+ # Method 2a: Try to get the parent process command line from /proc
143
+ try:
144
+ with open(f'/proc/{parent_pid}/cmdline', 'r') as f:
145
+ cmdline = f.read().split('\0')
146
+ if cmdline and cmdline[0]:
147
+ cmd = os.path.basename(cmdline[0])
148
+ if "zsh" in cmd:
149
+ return "zsh", "zsh", operating_system
150
+ elif "bash" in cmd:
151
+ return "bash", "bash", operating_system
152
+ elif "fish" in cmd:
153
+ return "fish", "fish", operating_system
154
+ except:
155
+ pass
156
+
157
+ # Method 2b: Try using ps command with different formats
158
+ for fmt in ["comm=", "command=", "args="]:
159
+ try:
160
+ ps_cmd = ["ps", "-p", str(parent_pid), "-o", fmt]
161
+ result = subprocess.run(ps_cmd, capture_output=True, text=True)
162
+ process_info = result.stdout.strip()
83
163
 
84
- # Check if we're in Git Bash by examining PATH for /mingw/
85
- if any("/mingw/" in path.lower() for path in os.environ.get("PATH", "").split(os.pathsep)):
86
- return "bash", "bash", operating_system
164
+ if process_info:
165
+ if "zsh" in process_info.lower():
166
+ return "zsh", "zsh", operating_system
167
+ elif "bash" in process_info.lower():
168
+ return "bash", "bash", operating_system
169
+ elif "fish" in process_info.lower():
170
+ return "fish", "fish", operating_system
171
+ elif any(sh in process_info.lower() for sh in ["csh", "tcsh"]):
172
+ shell_name = "csh" if "csh" in process_info.lower() else "tcsh"
173
+ return shell_name, "csh", operating_system
174
+ elif "ksh" in process_info.lower():
175
+ return "ksh", "ksh", operating_system
176
+ except:
177
+ continue
178
+
179
+ # Method 2c: Try to find parent shell by traversing process hierarchy
180
+ # This handles Python wrappers, uv run, etc.
181
+ for _ in range(5): # Check up to 5 levels up the process tree
182
+ try:
183
+ # Try to get process command
184
+ ps_cmd = ["ps", "-p", str(parent_pid), "-o", "comm="]
185
+ result = subprocess.run(ps_cmd, capture_output=True, text=True)
186
+ process_name = result.stdout.strip()
187
+
188
+ # If it's a known shell, return it
189
+ if process_name:
190
+ process_basename = os.path.basename(process_name)
191
+ if "bash" in process_basename:
192
+ return "bash", "bash", operating_system
193
+ elif "zsh" in process_basename:
194
+ return "zsh", "zsh", operating_system
195
+ elif "fish" in process_basename:
196
+ return "fish", "fish", operating_system
197
+ elif any(sh in process_basename for sh in ["csh", "tcsh"]):
198
+ return process_basename, "csh", operating_system
199
+ elif "ksh" in process_basename:
200
+ return process_basename, "ksh", operating_system
87
201
 
88
- # Check for WSL within Windows
89
- if "WSL" in os.environ.get("PATH", "") or "Microsoft" in os.environ.get("PATH", ""):
202
+ # Check if we've reached init/systemd (PID 1)
203
+ if parent_pid <= 1:
204
+ break
205
+
206
+ # Move up to next parent
207
+ try:
208
+ # Get the parent of our current parent
209
+ with open(f'/proc/{parent_pid}/status', 'r') as f:
210
+ for line in f:
211
+ if line.startswith('PPid:'):
212
+ parent_pid = int(line.split()[1])
213
+ break
214
+ except:
215
+ break # Can't determine next parent, stop here
216
+ except:
217
+ break
218
+ except:
219
+ # Process detection failed, continue with other methods
220
+ pass
221
+
222
+ # Method 3: Try running a command that prints info about the parent shell
223
+ try:
224
+ # Get parent's process ID and use it to get more info
225
+ cmd = f"ps -p $PPID -o cmd="
226
+ result = subprocess.run(['bash', '-c', cmd], capture_output=True, text=True, timeout=1)
227
+ parent_cmd = result.stdout.strip()
228
+
229
+ if "zsh" in parent_cmd.lower():
230
+ return "zsh", "zsh", operating_system
231
+ elif "bash" in parent_cmd.lower():
232
+ return "bash", "bash", operating_system
233
+ elif "fish" in parent_cmd.lower():
234
+ return "fish", "fish", operating_system
235
+ except:
236
+ pass
237
+
238
+ # Method 4: Check for shell-specific environment variables beyond the basic ones
239
+ try:
240
+ for env_var in os.environ:
241
+ if env_var.startswith("BASH_"):
90
242
  return "bash", "bash", operating_system
243
+ elif env_var.startswith("ZSH_"):
244
+ return "zsh", "zsh", operating_system
245
+ elif env_var.startswith("FISH_"):
246
+ return "fish", "fish", operating_system
247
+ except:
248
+ pass
249
+
250
+ # Method 5: Check SHELL environment variable
251
+ if os.environ.get("SHELL"):
252
+ shell_path = os.environ.get("SHELL")
253
+ shell_name = os.path.basename(shell_path)
254
+
255
+ # Match against known shell types - use exact matches first
256
+ if shell_name == "zsh":
257
+ return "zsh", "zsh", operating_system
258
+ elif shell_name == "bash":
259
+ return "bash", "bash", operating_system
260
+ elif shell_name == "fish":
261
+ return "fish", "fish", operating_system
262
+ elif shell_name in ["csh", "tcsh"]:
263
+ return shell_name, "csh", operating_system
264
+ elif shell_name == "ksh":
265
+ return shell_name, "ksh", operating_system
91
266
 
92
- # Check for explicit shell path in environment
93
- if os.environ.get("SHELL"):
94
- shell_path = os.environ.get("SHELL").lower()
95
- if "bash" in shell_path:
96
- return "bash", "bash", operating_system
97
- elif "zsh" in shell_path:
98
- return "zsh", "zsh", operating_system
99
- elif "powershell" in shell_path:
100
- return "powershell.exe", "powershell", operating_system
101
- elif "cmd" in shell_path:
267
+ # If no exact match, try substring
268
+ if "zsh" in shell_name:
269
+ return "zsh", "zsh", operating_system
270
+ elif "bash" in shell_name:
271
+ return "bash", "bash", operating_system
272
+ elif "fish" in shell_name:
273
+ return "fish", "fish", operating_system
274
+ elif any(sh in shell_name for sh in ["csh", "tcsh"]):
275
+ return shell_name, "csh", operating_system
276
+ elif "ksh" in shell_name:
277
+ return shell_name, "ksh", operating_system
278
+
279
+ # Fallback: default to bash for Unix-like systems if all else fails
280
+ return "bash", "bash", operating_system
281
+
282
+
283
+ def detect_windows_shell(operating_system):
284
+ """Detect shell type on Windows systems.
285
+
286
+ Args:
287
+ operating_system: The detected operating system string
288
+
289
+ Returns:
290
+ tuple: (shell_name, highlight_language, operating_system) - the detected shell information
291
+ """
292
+ # First check for the process name - most reliable indicator
293
+ try:
294
+ # Check parent process name for the most accurate detection
295
+ if os.name == 'nt':
296
+ import ctypes
297
+ from ctypes import wintypes
298
+
299
+ # Get parent process ID
300
+ GetCurrentProcessId = ctypes.windll.kernel32.GetCurrentProcessId
301
+ GetCurrentProcess = ctypes.windll.kernel32.GetCurrentProcess
302
+ GetProcessTimes = ctypes.windll.kernel32.GetProcessTimes
303
+ OpenProcess = ctypes.windll.kernel32.OpenProcess
304
+ GetModuleFileNameEx = ctypes.windll.psapi.GetModuleFileNameExW
305
+ QueryFullProcessImageName = ctypes.windll.kernel32.QueryFullProcessImageNameW
306
+ CloseHandle = ctypes.windll.kernel32.CloseHandle
307
+
308
+ # Try to get process path
309
+ try:
310
+ # First try to check current process executable name
311
+ process_path = sys.executable.lower()
312
+ if "powershell" in process_path:
313
+ if "pwsh" in process_path:
314
+ return "pwsh", "powershell", operating_system
315
+ else:
316
+ return "powershell.exe", "powershell", operating_system
317
+ elif "cmd.exe" in process_path:
102
318
  return "cmd.exe", "batch", operating_system
103
-
104
- # Check for PowerShell vs CMD
319
+ except Exception as e:
320
+ pass
321
+
322
+ # If that fails, check environment variables that strongly indicate shell type
323
+ if "PROMPT" in os.environ and "$P$G" in os.environ.get("PROMPT", ""):
324
+ # CMD.exe uses $P$G as default prompt
325
+ return "cmd.exe", "batch", operating_system
326
+
105
327
  if os.environ.get("PSModulePath"):
106
- # Further distinguish PowerShell vs PowerShell Core
328
+ # PowerShell has this environment variable
107
329
  if "pwsh" in os.environ.get("PSModulePath", "").lower():
108
330
  return "pwsh", "powershell", operating_system
109
331
  else:
110
332
  return "powershell.exe", "powershell", operating_system
111
- else:
112
- return "cmd.exe", "batch", operating_system
333
+ except Exception as e:
334
+ # If process detection fails, continue with environment checks
335
+ pass
336
+
337
+ # Check for WSL within Windows
338
+ if any(("wsl" in path.lower() or "microsoft" in path.lower()) for path in os.environ.get("PATH", "").split(os.pathsep)):
339
+ return "bash", "bash", operating_system
340
+
341
+ # Check for explicit shell path in environment
342
+ if os.environ.get("SHELL"):
343
+ shell_path = os.environ.get("SHELL").lower()
344
+ if "bash" in shell_path:
345
+ return "bash", "bash", operating_system
346
+ elif "zsh" in shell_path:
347
+ return "zsh", "zsh", operating_system
348
+ elif "powershell" in shell_path:
349
+ return "powershell.exe", "powershell", operating_system
350
+ elif "cmd" in shell_path:
351
+ return "cmd.exe", "batch", operating_system
352
+
353
+ # Final fallback - Check common environment variables that indicate shell type
354
+ if "ComSpec" in os.environ:
355
+ comspec = os.environ.get("ComSpec", "").lower()
356
+ if "powershell" in comspec:
357
+ return "powershell.exe", "powershell", operating_system
358
+ elif "cmd.exe" in comspec:
359
+ return "cmd.exe", "batch", operating_system
360
+
361
+ # Last resort fallback to PowerShell (most common modern Windows shell)
362
+ return "powershell.exe", "powershell", operating_system
363
+
364
+
365
+ def detect_shell():
366
+ """Detect the current shell type and OS more accurately.
367
+
368
+ Returns:
369
+ tuple: (shell_name, highlight_language, operating_system) - the detected shell name,
370
+ appropriate syntax highlighting language, and operating system
371
+ """
372
+ try:
373
+ # First detect the OS
374
+ os_type, operating_system, is_wsl = detect_os()
375
+
376
+ # Use the appropriate detection method based on OS
377
+ if os_type in ["Linux", "Darwin", "FreeBSD"] or is_wsl:
378
+ return detect_unix_shell(operating_system)
379
+ elif os_type == "Windows":
380
+ # On Windows, first check for Git Bash / MINGW environment
381
+ gitbash_result = detect_gitbash_shell(operating_system)
382
+ if gitbash_result:
383
+ return gitbash_result
384
+
385
+ # If not Git Bash, use regular Windows shell detection
386
+ return detect_windows_shell(operating_system)
113
387
  else:
114
- # Unix-like systems - try to get more specific
115
- shell_path = os.environ.get("SHELL", "/bin/bash")
116
- shell_name = os.path.basename(shell_path)
117
-
118
- # Map shell name to syntax highlight language
119
- if shell_name == "zsh":
120
- return shell_name, "zsh", operating_system
121
- elif shell_name == "fish":
122
- return shell_name, "fish", operating_system
123
- elif "csh" in shell_name:
124
- return shell_name, "csh", operating_system
388
+ # Fallback for unknown OS types
389
+ if os_type == "Windows":
390
+ return "powershell.exe", "powershell", operating_system
125
391
  else:
126
- # Default to bash for sh, bash, and other shells
127
- return shell_name, "bash", operating_system
392
+ return "bash", "bash", operating_system
128
393
  except Exception as e:
129
394
  # Fall back to simple detection if anything fails
395
+ os_type = platform.system()
396
+ operating_system = os_type
130
397
  if os_type == "Windows":
131
398
  return "powershell.exe", "powershell", operating_system
132
399
  else:
@@ -172,7 +439,7 @@ def setup_streaming(args, logger=None):
172
439
  elif args.no_stream:
173
440
  # Second priority: no-stream
174
441
  should_stream = False
175
- use_regular_prettify = False # No prettify if no streaming
442
+ use_regular_prettify = False # No prettify if no streaming
176
443
  elif args.prettify:
177
444
  # Third priority: prettify (requires disabling stream)
178
445
  if has_markdown_renderer(args.renderer):
@@ -240,8 +507,8 @@ def setup_streaming(args, logger=None):
240
507
  return (should_stream, use_stream_prettify, use_regular_prettify, stream_setup)
241
508
 
242
509
  def generate_with_model(client, prompt, messages, args, stream_setup,
243
- use_stream_prettify, should_stream, spinner_message="Generating...",
244
- temp_override=None, logger=None):
510
+ use_stream_prettify, should_stream, spinner_message="Generating...",
511
+ temp_override=None, logger=None):
245
512
  """Generate content using the model with proper streaming and spinner handling.
246
513
 
247
514
  Args:
@@ -537,7 +804,7 @@ def shell_mode(client, args, logger=None):
537
804
  # Add a small delay to ensure terminal rendering is complete,
538
805
  # especially important for stream-prettify mode
539
806
  if use_stream_prettify:
540
- time.sleep(0.2)
807
+ time.sleep(0.5)
541
808
 
542
809
  # Print prompt and flush to ensure it appears
543
810
  sys.stdout.write(prompt_text)
@@ -550,9 +817,9 @@ def shell_mode(client, args, logger=None):
550
817
  if response:
551
818
  response = response.lower()
552
819
  else:
553
- # If get_terminal_input fails, default to copy
554
- print("\nFailed to get terminal input. Defaulting to copy option.")
555
- response = 'c'
820
+ # If get_terminal_input fails, default to abort
821
+ print("\nFailed to get terminal input. Defaulting to abort option.")
822
+ response = 'a'
556
823
  except KeyboardInterrupt:
557
824
  print("\nCommand execution cancelled by user.")
558
825
  return
@@ -565,7 +832,21 @@ def shell_mode(client, args, logger=None):
565
832
  try:
566
833
  try:
567
834
  print("\nExecuting command... (Press Ctrl+C to cancel)")
568
- result = subprocess.run(command, shell=True, check=True, capture_output=True, text=True)
835
+
836
+ # Special handling for Windows PowerShell commands
837
+ if shell_name in ["powershell.exe", "pwsh"] and platform.system() == "Windows":
838
+ # Execute PowerShell commands properly on Windows
839
+ result = subprocess.run(
840
+ ["powershell.exe", "-Command", command],
841
+ shell=True,
842
+ check=True,
843
+ capture_output=True,
844
+ text=True
845
+ )
846
+ else:
847
+ # Regular command execution for other shells
848
+ result = subprocess.run(command, shell=True, check=True, capture_output=True, text=True)
849
+
569
850
  output = result.stdout
570
851
 
571
852
  # Log the command output if logging is enabled
ngpt/cli/ui.py CHANGED
@@ -159,10 +159,39 @@ def get_terminal_input():
159
159
  try:
160
160
  import msvcrt
161
161
  sys.stdout.flush()
162
- # Wait for a keypress
163
- char = msvcrt.getch().decode('utf-8').lower()
164
- print(char) # Echo the character
165
- return char
162
+
163
+ # Wait for a complete line (including Enter key)
164
+ input_chars = []
165
+ while True:
166
+ # Get a character
167
+ char = msvcrt.getch()
168
+
169
+ # If it's Enter (CR or LF), break the loop
170
+ if char in [b'\r', b'\n']:
171
+ print() # Move to the next line after Enter
172
+ break
173
+
174
+ # If it's backspace, handle it
175
+ if char == b'\x08':
176
+ if input_chars:
177
+ # Remove the last character
178
+ input_chars.pop()
179
+ # Erase the character on screen (backspace + space + backspace)
180
+ sys.stdout.write('\b \b')
181
+ sys.stdout.flush()
182
+ continue
183
+
184
+ # For regular characters, add to input and echo
185
+ try:
186
+ char_decoded = char.decode('utf-8').lower()
187
+ input_chars.append(char_decoded)
188
+ print(char_decoded, end='', flush=True) # Echo the character without newline
189
+ except UnicodeDecodeError:
190
+ # Skip characters that can't be decoded
191
+ continue
192
+
193
+ # Join all characters and return
194
+ return ''.join(input_chars).strip().lower()
166
195
  except ImportError:
167
196
  # Fallback if msvcrt is not available
168
197
  return None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ngpt
3
- Version: 3.8.1
3
+ Version: 3.8.2
4
4
  Summary: Swiss army knife for LLMs: powerful CLI and interactive chatbot in one package. Seamlessly work with OpenAI, Ollama, Groq, Claude, Gemini, or any OpenAI-compatible API to generate code, craft git commits, rewrite text, and execute shell commands.
5
5
  Project-URL: Homepage, https://github.com/nazdridoy/ngpt
6
6
  Project-URL: Repository, https://github.com/nazdridoy/ngpt
@@ -493,6 +493,8 @@ In interactive mode:
493
493
  - For security, your API key is not displayed when editing configurations
494
494
  - When removing a configuration, you'll be asked to confirm before deletion
495
495
 
496
+ ![ngpt-sh-c-a](https://raw.githubusercontent.com/nazdridoy/ngpt/main/previews/ngpt-sh-c-a.png)
497
+
496
498
  For more details on configuring nGPT, see the [Configuration Guide](https://nazdridoy.github.io/ngpt/configuration/).
497
499
 
498
500
  ### Configuration File
@@ -541,6 +543,146 @@ nGPT determines configuration values in the following order (highest priority fi
541
543
  4. Main configuration file `ngpt.conf` or `custom-config-file`
542
544
  5. Default values
543
545
 
546
+ ### Real-World Demonstrations with nGPT
547
+
548
+ Let's see nGPT in action! Here are some practical ways you can use it every day:
549
+
550
+ #### Quick Q&A and Coding
551
+
552
+ ```bash
553
+ # Get a quick explanation
554
+ ngpt "Explain the difference between threads and processes in Python"
555
+
556
+ # Generate code with real-time syntax highlighting
557
+ ngpt --code --stream-prettify "Write a Python function to reverse a linked list"
558
+ ```
559
+
560
+ With the `--code` flag, nGPT gives you clean code without explanations or markdown, just what you need to copy and paste into your project. The `--stream-prettify` option shows real-time syntax highlighting as the code comes in.
561
+
562
+ #### Shell Command Generation (OS-Aware)
563
+
564
+ ```bash
565
+ # Let nGPT generate the correct command for your OS
566
+ ngpt --shell "list all files in the current directory including hidden ones"
567
+ # On Linux/macOS: ls -la
568
+ # On Windows: dir /a
569
+ ```
570
+
571
+ One of my favorite features! No more Googling obscure command flags, nGPT generates the right command for your operating system. It'll even execute it for you if you approve.
572
+
573
+ ![ngpt-s-c](https://raw.githubusercontent.com/nazdridoy/ngpt/main/previews/ngpt-s-c.png)
574
+
575
+ #### Text Rewriting and Summarization
576
+
577
+ ```bash
578
+ # Pipe text to rewrite it (e.g., improve clarity)
579
+ echo "This is a rough draft of my email." | ngpt -r
580
+
581
+ # Summarize a file using the pipe placeholder
582
+ cat long-article.txt | ngpt --pipe "Summarize this document concisely: {}"
583
+ ```
584
+
585
+ The text rewriting feature is perfect for quickly improving documentation, emails, or reports. And with pipe placeholders, you can feed in content from files or other commands.
586
+
587
+ #### Git Commit Message Generation
588
+
589
+ ```bash
590
+ # Stage your changes
591
+ git add .
592
+
593
+ # Let nGPT generate a conventional commit message based on the diff
594
+ ngpt -g
595
+
596
+ # Generate git commit message from a diff file
597
+ ngpt -g --diff changes.diff
598
+ ```
599
+
600
+ This is a huge time-saver. nGPT analyzes your git diff and generates a properly formatted conventional commit message that actually describes what you changed. No more staring at the blank commit message prompt!
601
+
602
+ ![ngpt-g](https://raw.githubusercontent.com/nazdridoy/ngpt/main/previews/ngpt-g.png)
603
+
604
+ #### Web Search Integration
605
+
606
+ ```bash
607
+ # Ask questions that require up-to-date information
608
+ ngpt --web-search "What's the latest news about AI regulation?"
609
+ ```
610
+
611
+ The `--web-search` flag lets nGPT consult the web for recent information, making it useful for questions about current events or topics that might have changed since the AI's training data cutoff.
612
+
613
+ ![ngpt-w](https://raw.githubusercontent.com/nazdridoy/ngpt/main/previews/ngpt-w.png)
614
+
615
+ ### Real-World Integration Examples
616
+
617
+ Let's look at how nGPT can fit into your everyday workflow with some practical examples:
618
+
619
+ #### Developer Workflow
620
+
621
+ As a developer, I use nGPT throughout my day:
622
+
623
+ **Morning code review**:
624
+ ```bash
625
+ # Get explanations of complex code
626
+ git show | ngpt --pipe "Explain what this code change does and any potential issues: {}"
627
+ ```
628
+
629
+ **Debugging help**:
630
+ ```bash
631
+ # Help understand a cryptic error message
632
+ npm run build 2>&1 | grep Error | ngpt --pipe "What does this error mean and how can I fix it: {}"
633
+ ```
634
+
635
+ **Documentation generation**:
636
+ ```bash
637
+ # Generate JSDoc comments for functions
638
+ cat src/utils.js | ngpt --pipe "Write proper JSDoc comments for these functions: {}"
639
+ ```
640
+
641
+ **Commit messages**:
642
+ ```bash
643
+ # After finishing a feature
644
+ git add .
645
+ ngpt -g
646
+ ```
647
+
648
+ #### Writer's Assistant
649
+
650
+ For content creators and writers:
651
+
652
+ **Overcoming writer's block**:
653
+ ```bash
654
+ ngpt "Give me 5 different angles to approach an article about sustainable technology"
655
+ ```
656
+
657
+ **Editing assistance**:
658
+ ```bash
659
+ cat draft.md | ngpt -r
660
+ ```
661
+
662
+ **Research summaries**:
663
+ ```bash
664
+ curl -s https://example.com/research-paper.html | ngpt --pipe "Summarize the key findings from this research: {}"
665
+ ```
666
+
667
+ #### System Administrator
668
+
669
+ For sysadmins and DevOps folks:
670
+
671
+ **Generating complex commands**:
672
+ ```bash
673
+ ngpt -s "find all log files larger than 100MB that haven't been modified in the last 30 days"
674
+ ```
675
+
676
+ *Creating configuration files**:
677
+ ```bash
678
+ ngpt --code "Create a Docker Compose file for a Redis, PostgreSQL, and Node.js application"
679
+ ```
680
+
681
+ **Troubleshooting systems**:
682
+ ```bash
683
+ dmesg | tail -50 | ngpt --pipe "Explain what might be causing the issues based on these system logs: {}"
684
+ ```
685
+
544
686
  ## Contributing
545
687
 
546
688
  We welcome contributions to nGPT! Whether it's bug fixes, feature additions, or documentation improvements, your help is appreciated.
@@ -7,14 +7,14 @@ ngpt/cli/config_manager.py,sha256=NQQcWnjUppAAd0s0p9YAf8EyKS1ex5-0EB4DvKdB4dk,36
7
7
  ngpt/cli/formatters.py,sha256=HBYGlx_7eoAKyzfy0Vq5L0yn8yVKjngqYBukMmXCcz0,9401
8
8
  ngpt/cli/main.py,sha256=PVulo8Pm53-oQ2Pgc4G90YhwyPImt8j7HKmY38SJ7CM,28696
9
9
  ngpt/cli/renderers.py,sha256=m71BeUXKynpKKGXFzwRSW1XngvyKiZ_xEsdujUbU0MA,16597
10
- ngpt/cli/ui.py,sha256=tVJGTP1DWjCRq7ONFdOOKPHcVQz0MqiLyJtodKFabTk,9612
10
+ ngpt/cli/ui.py,sha256=4RFxIf51di5EsytVr7OoyCWF_d40KJ0Mbom0VWgPlCc,10870
11
11
  ngpt/cli/modes/__init__.py,sha256=KP7VR6Xw9k1p5Jcu0F38RDxSFvFIzH3j1ThDLNwznUI,363
12
12
  ngpt/cli/modes/chat.py,sha256=1mH3nTDwU52qQJRliNUAFSqJWyyiJ6j0T5uVso-VnxE,6828
13
13
  ngpt/cli/modes/code.py,sha256=QBFgMRPKJhxkYCmumoSkNSF15XNRGUDum5yuK8aBnyM,12662
14
14
  ngpt/cli/modes/gitcommsg.py,sha256=iTg3KlZwI0lGMcmUa62b0ashwLcxegdEEvT29PPtpBc,49595
15
15
  ngpt/cli/modes/interactive.py,sha256=TtBrZUX45CVfKOPvkb1ya7dIQhXLILtn7ajmfM9ohso,17419
16
16
  ngpt/cli/modes/rewrite.py,sha256=yPmJPPkMHNxrnV-eoM0j6lMNRhdSAMXmcw2s9xG6TIo,10918
17
- ngpt/cli/modes/shell.py,sha256=9Bg-uPDjNgSwLULRzRxDkBXjVd1yPZLZXG-V2kPFm2k,29929
17
+ ngpt/cli/modes/shell.py,sha256=nXkUbLLNdXQrdsOqGXMwdfnr2y7MtqbmBkYlwZbI5JA,41415
18
18
  ngpt/cli/modes/text.py,sha256=7t5WWXMFxGkBM5HMP4irbN9aQwxE2YgywjiVPep710k,6417
19
19
  ngpt/utils/__init__.py,sha256=_92f8eGMMOtQQA3uwgSRVwUEl1EIRFjWPUjcfGgI-eI,1244
20
20
  ngpt/utils/cli_config.py,sha256=Ug8cECBTIuzOwkBWidLTfs-OAdOsCMJ2bNa70pOADfw,11195
@@ -22,8 +22,8 @@ ngpt/utils/config.py,sha256=wsArA4osnh8fKqOvtsPqqBxAz3DpdjtaWUFaRtnUdyc,10452
22
22
  ngpt/utils/log.py,sha256=f1jg2iFo35PAmsarH8FVL_62plq4VXH0Mu2QiP6RJGw,15934
23
23
  ngpt/utils/pipe.py,sha256=qRHF-Ma7bbU0cOcb1Yhe4S-kBavivtnnvLA3EYS4FY4,2162
24
24
  ngpt/utils/web_search.py,sha256=w5ke4KJMRxq7r5jtbUXvspja6XhjoPZloVkZ0IvBXIE,30731
25
- ngpt-3.8.1.dist-info/METADATA,sha256=uiFcgSP1jz1ArOo1CUJ4FQvBZyo5Cq72_EdKzG8JEzM,24503
26
- ngpt-3.8.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
27
- ngpt-3.8.1.dist-info/entry_points.txt,sha256=SqAAvLhMrsEpkIr4YFRdUeyuXQ9o0IBCeYgE6AVojoI,44
28
- ngpt-3.8.1.dist-info/licenses/LICENSE,sha256=mQkpWoADxbHqE0HRefYLJdm7OpdrXBr3vNv5bZ8w72M,1065
29
- ngpt-3.8.1.dist-info/RECORD,,
25
+ ngpt-3.8.2.dist-info/METADATA,sha256=2LazTO2smhA2gBILZQ9vA0Xqqn2RByEIfclp999Y6KA,28919
26
+ ngpt-3.8.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
27
+ ngpt-3.8.2.dist-info/entry_points.txt,sha256=SqAAvLhMrsEpkIr4YFRdUeyuXQ9o0IBCeYgE6AVojoI,44
28
+ ngpt-3.8.2.dist-info/licenses/LICENSE,sha256=mQkpWoADxbHqE0HRefYLJdm7OpdrXBr3vNv5bZ8w72M,1065
29
+ ngpt-3.8.2.dist-info/RECORD,,
File without changes