rubber-ducky 1.6.5__py3-none-any.whl → 1.6.7__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
@@ -14,7 +14,7 @@ from pathlib import Path
14
14
  from textwrap import dedent
15
15
  from typing import Any, Dict, List
16
16
 
17
- __version__ = "1.6.4"
17
+ __version__ = "1.6.5"
18
18
 
19
19
  from .config import ConfigManager
20
20
  from .crumb import CrumbManager
@@ -1170,6 +1170,51 @@ def copy_to_clipboard(text: str) -> bool:
1170
1170
  return False
1171
1171
 
1172
1172
 
1173
+ def check_for_updates() -> None:
1174
+ """Check PyPI for updates and notify user if a new version is available.
1175
+
1176
+ Checks once per day and caches the result to avoid excessive requests.
1177
+ """
1178
+ from datetime import datetime, timedelta
1179
+ import urllib.request
1180
+ import json
1181
+
1182
+ cache_file = HISTORY_DIR / "version_check_cache"
1183
+
1184
+ # Check if we've already checked today
1185
+ if cache_file.exists():
1186
+ try:
1187
+ last_check = datetime.fromtimestamp(cache_file.stat().st_mtime)
1188
+ if datetime.now() - last_check < timedelta(days=1):
1189
+ return # Already checked today
1190
+ except Exception:
1191
+ pass
1192
+
1193
+ try:
1194
+ # Query PyPI for latest version
1195
+ req = urllib.request.Request(
1196
+ "https://pypi.org/pypi/rubber-ducky/json",
1197
+ headers={"User-Agent": f"rubber-ducky/{__version__}"}
1198
+ )
1199
+
1200
+ with urllib.request.urlopen(req, timeout=3) as response:
1201
+ data = json.loads(response.read())
1202
+ latest_version = data["info"]["version"]
1203
+
1204
+ if latest_version != __version__:
1205
+ console.print(
1206
+ f"\n[dim]A new version is available: {latest_version} "
1207
+ f"(you have {__version__}). "
1208
+ f"Run: uv tool upgrade rubber-ducky[/dim]\n"
1209
+ )
1210
+
1211
+ # Update cache file timestamp
1212
+ cache_file.touch()
1213
+ except Exception:
1214
+ # Silently fail if no internet or PyPI is down
1215
+ pass
1216
+
1217
+
1173
1218
  def confirm(prompt: str, default: bool = False) -> bool:
1174
1219
  suffix = " [Y/n]: " if default else " [y/N]: "
1175
1220
  try:
@@ -1219,6 +1264,12 @@ async def ducky() -> None:
1219
1264
  action="store_true",
1220
1265
  help="Suppress startup messages and help text",
1221
1266
  )
1267
+ parser.add_argument(
1268
+ "--upgrade",
1269
+ "-u",
1270
+ action="store_true",
1271
+ help="Upgrade rubber-ducky to the latest version using uv",
1272
+ )
1222
1273
  parser.add_argument(
1223
1274
  "single_prompt",
1224
1275
  nargs="*",
@@ -1227,9 +1278,35 @@ async def ducky() -> None:
1227
1278
  )
1228
1279
  args = parser.parse_args()
1229
1280
 
1281
+ # Handle upgrade request immediately
1282
+ if args.upgrade:
1283
+ console.print("Upgrading rubber-ducky...", style="yellow")
1284
+ try:
1285
+ result = subprocess.run(
1286
+ ["uv", "tool", "upgrade", "rubber-ducky"],
1287
+ capture_output=True,
1288
+ text=True,
1289
+ check=True
1290
+ )
1291
+ console.print(result.stdout, style="dim")
1292
+ console.print("Upgrade complete!", style="green")
1293
+ except subprocess.CalledProcessError as e:
1294
+ console.print(f"Upgrade failed: {e.stderr}", style="red")
1295
+ except FileNotFoundError:
1296
+ console.print("uv not found. Please install uv to use --upgrade.", style="red")
1297
+ return
1298
+
1230
1299
  ensure_history_dir()
1231
1300
  logger = ConversationLogger(CONVERSATION_LOG_FILE)
1232
1301
 
1302
+ # Check for updates in background (non-blocking, runs once per day)
1303
+ # Skip if quiet mode, piped input, or single prompt (faster paths)
1304
+ check_piped = not sys.stdin.isatty()
1305
+ if not args.quiet and not args.single_prompt and not check_piped:
1306
+ # Run in a thread to not block startup
1307
+ import threading
1308
+ threading.Thread(target=check_for_updates, daemon=True).start()
1309
+
1233
1310
  # Load the last used model from config if no model is specified
1234
1311
  config_manager = ConfigManager()
1235
1312
  last_model, last_host = config_manager.get_last_model()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rubber-ducky
3
- Version: 1.6.5
3
+ Version: 1.6.7
4
4
  Summary: Quick CLI do-it-all tool. Use natural language to spit out bash commands
5
5
  Requires-Python: >=3.10
6
6
  Description-Content-Type: text/markdown
@@ -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=2qe1ygshf0bN1rrrmr3keuTrIsZUC3ERofeKY-b51kg,54035
4
+ ducky/ducky.py,sha256=pplx1lRnhpNoLn8prrfHL6FTZ0wAy0eRh-mN8lD7jxQ,56844
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.5.dist-info/licenses/LICENSE,sha256=gQ1rCmw18NqTk5GxG96F6vgyN70e1c4kcKUtWDwdNaE,1069
9
- rubber_ducky-1.6.5.dist-info/METADATA,sha256=9WRMuq3Nr4OmafgqrhjrEDw8avnTcF9uDJtdy_u88a8,6638
10
- rubber_ducky-1.6.5.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
11
- rubber_ducky-1.6.5.dist-info/entry_points.txt,sha256=WPnVUUNvWdMDcBlCo8JCzkLghGllMX5QVZyQghyq85Q,75
12
- rubber_ducky-1.6.5.dist-info/top_level.txt,sha256=hid_mDkugR6XIeravFKuzcRPpuN_ylN3ejC_06Fmnb4,15
13
- rubber_ducky-1.6.5.dist-info/RECORD,,
8
+ rubber_ducky-1.6.7.dist-info/licenses/LICENSE,sha256=gQ1rCmw18NqTk5GxG96F6vgyN70e1c4kcKUtWDwdNaE,1069
9
+ rubber_ducky-1.6.7.dist-info/METADATA,sha256=fL3iPBr_3-vD67NtoGsX5xEKpFsDdY_wejVTID3rStg,6638
10
+ rubber_ducky-1.6.7.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
11
+ rubber_ducky-1.6.7.dist-info/entry_points.txt,sha256=WPnVUUNvWdMDcBlCo8JCzkLghGllMX5QVZyQghyq85Q,75
12
+ rubber_ducky-1.6.7.dist-info/top_level.txt,sha256=hid_mDkugR6XIeravFKuzcRPpuN_ylN3ejC_06Fmnb4,15
13
+ rubber_ducky-1.6.7.dist-info/RECORD,,