deepctl-cmd-update 0.2.7__tar.gz → 0.2.8__tar.gz

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 (17) hide show
  1. {deepctl_cmd_update-0.2.7 → deepctl_cmd_update-0.2.8}/PKG-INFO +2 -2
  2. {deepctl_cmd_update-0.2.7 → deepctl_cmd_update-0.2.8}/pyproject.toml +2 -2
  3. {deepctl_cmd_update-0.2.7 → deepctl_cmd_update-0.2.8}/src/deepctl_cmd_update/command.py +2 -2
  4. {deepctl_cmd_update-0.2.7 → deepctl_cmd_update-0.2.8}/src/deepctl_cmd_update/installation.py +31 -5
  5. {deepctl_cmd_update-0.2.7 → deepctl_cmd_update-0.2.8}/src/deepctl_cmd_update/plugin_update_check.py +2 -2
  6. {deepctl_cmd_update-0.2.7 → deepctl_cmd_update-0.2.8}/src/deepctl_cmd_update/startup_check.py +15 -1
  7. {deepctl_cmd_update-0.2.7 → deepctl_cmd_update-0.2.8}/src/deepctl_cmd_update/version_check.py +4 -2
  8. {deepctl_cmd_update-0.2.7 → deepctl_cmd_update-0.2.8}/src/deepctl_cmd_update.egg-info/PKG-INFO +2 -2
  9. {deepctl_cmd_update-0.2.7 → deepctl_cmd_update-0.2.8}/src/deepctl_cmd_update.egg-info/requires.txt +1 -1
  10. {deepctl_cmd_update-0.2.7 → deepctl_cmd_update-0.2.8}/README.md +0 -0
  11. {deepctl_cmd_update-0.2.7 → deepctl_cmd_update-0.2.8}/setup.cfg +0 -0
  12. {deepctl_cmd_update-0.2.7 → deepctl_cmd_update-0.2.8}/src/deepctl_cmd_update/__init__.py +0 -0
  13. {deepctl_cmd_update-0.2.7 → deepctl_cmd_update-0.2.8}/src/deepctl_cmd_update/models.py +0 -0
  14. {deepctl_cmd_update-0.2.7 → deepctl_cmd_update-0.2.8}/src/deepctl_cmd_update.egg-info/SOURCES.txt +0 -0
  15. {deepctl_cmd_update-0.2.7 → deepctl_cmd_update-0.2.8}/src/deepctl_cmd_update.egg-info/dependency_links.txt +0 -0
  16. {deepctl_cmd_update-0.2.7 → deepctl_cmd_update-0.2.8}/src/deepctl_cmd_update.egg-info/entry_points.txt +0 -0
  17. {deepctl_cmd_update-0.2.7 → deepctl_cmd_update-0.2.8}/src/deepctl_cmd_update.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepctl-cmd-update
3
- Version: 0.2.7
3
+ Version: 0.2.8
4
4
  Summary: Update command for deepctl
5
5
  Author-email: Deepgram <devrel@deepgram.com>
6
6
  Maintainer-email: Deepgram <devrel@deepgram.com>
@@ -15,7 +15,7 @@ Classifier: Programming Language :: Python :: 3.12
15
15
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
16
  Requires-Python: >=3.10
17
17
  Description-Content-Type: text/markdown
18
- Requires-Dist: deepctl-core>=0.1.10
18
+ Requires-Dist: deepctl-core>=0.3.1
19
19
  Requires-Dist: click>=8.0.0
20
20
  Requires-Dist: pydantic>=2.0.0
21
21
  Requires-Dist: rich>=13.0.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "deepctl-cmd-update"
7
- version = "0.2.7" # x-release-please-version
7
+ version = "0.2.8" # x-release-please-version
8
8
  description = "Update command for deepctl"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -22,7 +22,7 @@ classifiers = [
22
22
  keywords = ["deepgram", "cli", "update", "self-update"]
23
23
  requires-python = ">=3.10"
24
24
  dependencies = [
25
- "deepctl-core>=0.1.10",
25
+ "deepctl-core>=0.3.1",
26
26
  "click>=8.0.0",
27
27
  "pydantic>=2.0.0",
28
28
  "rich>=13.0.0",
@@ -147,7 +147,7 @@ class UpdateCommand(BaseCommand):
147
147
  "update.installation_method", install_info.method.value
148
148
  )
149
149
  config._set_config_value("update.installation_path", install_info.path)
150
- config.save()
150
+ config.save(implicit=True)
151
151
 
152
152
  # Display installation info
153
153
  console.print(f"Installation method: [cyan]{install_info.method}[/cyan]")
@@ -210,7 +210,7 @@ class UpdateCommand(BaseCommand):
210
210
 
211
211
  # Clear version cache
212
212
  config._set_config_value("update.cached_version_info", None)
213
- config.save()
213
+ config.save(implicit=True)
214
214
 
215
215
  return UpdateResult(
216
216
  success=True,
@@ -7,6 +7,7 @@ import sys
7
7
  from enum import Enum
8
8
  from pathlib import Path
9
9
 
10
+ from deepctl_core._launcher import get_launcher, launched_via_npm
10
11
  from pydantic import BaseModel
11
12
 
12
13
 
@@ -20,6 +21,7 @@ class InstallMethod(str, Enum):
20
21
  UV_TOOL = "uv_tool"
21
22
  UVX = "uvx"
22
23
  PIPX_RUN = "pipx_run"
24
+ NPM = "npm"
23
25
  SYSTEM = "system"
24
26
  DEVELOPMENT = "development"
25
27
  UNKNOWN = "unknown"
@@ -96,7 +98,7 @@ class InstallationDetector:
96
98
  "--upgrade",
97
99
  "deepctl",
98
100
  ],
99
- InstallMethod.HOMEBREW: ["brew", "upgrade", "deepctl"],
101
+ InstallMethod.HOMEBREW: ["brew", "upgrade", "deepgram"],
100
102
  InstallMethod.UV_TOOL: [
101
103
  "uv",
102
104
  "tool",
@@ -105,6 +107,7 @@ class InstallationDetector:
105
107
  ],
106
108
  InstallMethod.UVX: None, # Ephemeral, no update needed
107
109
  InstallMethod.PIPX_RUN: None, # Ephemeral, no update needed
110
+ InstallMethod.NPM: None, # Updated through npm, see instructions
108
111
  InstallMethod.SYSTEM: None, # Handled separately
109
112
  InstallMethod.DEVELOPMENT: None, # Can't auto-update
110
113
  InstallMethod.UNKNOWN: None,
@@ -121,7 +124,23 @@ class InstallationDetector:
121
124
  Human-readable update instructions
122
125
  """
123
126
  if info.method == InstallMethod.HOMEBREW:
124
- return "Please update using Homebrew: brew upgrade deepctl"
127
+ return "Please update using Homebrew: brew update && brew upgrade deepgram"
128
+
129
+ # The launcher's venv or uv cache is private to it, so pip/uv run
130
+ # from inside would update the wrong thing; only npm can update it.
131
+ if info.method == InstallMethod.NPM:
132
+ if get_launcher() == "npx":
133
+ return (
134
+ "Running via npx. Use the latest version with: "
135
+ "npx @deepgram/cli@latest"
136
+ )
137
+ return (
138
+ "Installed via npm. Update with: "
139
+ "npm install -g @deepgram/cli@latest "
140
+ "(or run npx @deepgram/cli@latest). "
141
+ "If @deepgram/cli is a dependency of your project, update it "
142
+ "there instead: npm install @deepgram/cli@latest"
143
+ )
125
144
 
126
145
  if info.method == InstallMethod.UVX:
127
146
  return (
@@ -138,7 +157,9 @@ class InstallationDetector:
138
157
  if info.method == InstallMethod.SYSTEM:
139
158
  # Try to detect the system package manager
140
159
  if sys.platform.startswith("darwin"):
141
- return "Please update using Homebrew: brew upgrade deepctl"
160
+ return (
161
+ "Please update using Homebrew: brew update && brew upgrade deepgram"
162
+ )
142
163
  elif sys.platform.startswith("linux"):
143
164
  # Check for common package managers
144
165
  if Path("/etc/debian_version").exists():
@@ -261,8 +282,8 @@ class InstallationDetector:
261
282
  ) -> InstallMethod:
262
283
  """Detect the installation method.
263
284
 
264
- Priority: development > oneshot > homebrew > uv_tool > pipx >
265
- uv > system > pip > unknown
285
+ Priority: npm > development > oneshot > homebrew > uv_tool >
286
+ pipx > uv > system > pip > unknown
266
287
 
267
288
  Args:
268
289
  package_location: Path to package
@@ -272,6 +293,11 @@ class InstallationDetector:
272
293
  Returns:
273
294
  Detected installation method
274
295
  """
296
+ # The npm launcher runs deepctl through uv or its own venv, which
297
+ # would otherwise be detected as uvx or pip.
298
+ if launched_via_npm():
299
+ return InstallMethod.NPM
300
+
275
301
  # Development installation
276
302
  if is_editable:
277
303
  return InstallMethod.DEVELOPMENT
@@ -261,7 +261,7 @@ def print_pending_plugin_notifications() -> None:
261
261
  u = updates[0]
262
262
  sys.stderr.write(
263
263
  f"\033[33mPlugin update available: {u['name']} {u['current']} → {u['latest']}"
264
- f" — run 'deepctl plugin update {u['name']}' to upgrade\033[0m\n"
264
+ f" — run 'dg plugin update {u['name']}' to upgrade\033[0m\n"
265
265
  )
266
266
  else:
267
267
  sys.stderr.write("\033[33mPlugin updates available:\033[0m\n")
@@ -270,7 +270,7 @@ def print_pending_plugin_notifications() -> None:
270
270
  f"\033[33m {u['name']} {u['current']} → {u['latest']}\033[0m\n"
271
271
  )
272
272
  sys.stderr.write(
273
- "\033[33mRun 'deepctl plugin update <name>' to upgrade\033[0m\n"
273
+ "\033[33mRun 'dg plugin update <name>' to upgrade\033[0m\n"
274
274
  )
275
275
  except (BrokenPipeError, OSError, ValueError):
276
276
  # The output stream closed (e.g. an MCP host disconnected stdio
@@ -15,6 +15,8 @@ import time
15
15
  from pathlib import Path
16
16
  from typing import Any
17
17
 
18
+ from deepctl_core._launcher import launched_via_npm, npm_upgrade_command
19
+
18
20
  # Sentinel used when the background check is suppressed or has no result
19
21
  _NO_RESULT: dict[str, Any] = {}
20
22
 
@@ -42,8 +44,20 @@ def _is_ci() -> bool:
42
44
  return any(os.environ.get(v) for v in _CI_ENV_VARS)
43
45
 
44
46
 
47
+ def upgrade_hint() -> str:
48
+ """Return the command a user should run to upgrade deepctl."""
49
+ if launched_via_npm():
50
+ return npm_upgrade_command()
51
+ return "dg update"
52
+
53
+
45
54
  def _is_oneshot() -> bool:
46
55
  """Return True if running in an ephemeral one-shot environment."""
56
+ # The npm launcher often runs deepctl through `uv tool run`, which looks
57
+ # one-shot, but the npm install itself persists and is pinned to one
58
+ # version, so its users do need to hear about updates.
59
+ if launched_via_npm():
60
+ return False
47
61
  # uvx
48
62
  if "UV_INTERNAL__PARENT_INTERPRETER" in os.environ:
49
63
  return True
@@ -200,7 +214,7 @@ def print_pending_notification() -> None:
200
214
  try:
201
215
  sys.stderr.write(
202
216
  f"\n\033[33m Update available: {current} → {latest}"
203
- f" — run \033[1mdg update\033[0m\033[33m to upgrade\033[0m\n\n"
217
+ f" — run \033[1m{upgrade_hint()}\033[0m\033[33m to upgrade\033[0m\n\n"
204
218
  )
205
219
  except (BrokenPipeError, OSError, ValueError):
206
220
  # The output stream closed (e.g. an MCP host disconnected stdio
@@ -7,6 +7,8 @@ from deepctl_core import Config
7
7
  from packaging import version
8
8
  from pydantic import BaseModel, Field
9
9
 
10
+ from .startup_check import upgrade_hint
11
+
10
12
 
11
13
  class VersionInfo(BaseModel):
12
14
  """Version information from PyPI."""
@@ -245,7 +247,7 @@ class VersionChecker:
245
247
  self.config._set_config_value(
246
248
  "update.cached_version_info", info.model_dump(mode="json")
247
249
  )
248
- self.config.save()
250
+ self.config.save(implicit=True)
249
251
 
250
252
 
251
253
  def format_version_message(info: VersionInfo) -> str:
@@ -270,5 +272,5 @@ def format_version_message(info: VersionInfo) -> str:
270
272
  else:
271
273
  message += f" (released {days_old} days ago)"
272
274
 
273
- message += "\nRun 'dg update' to upgrade"
275
+ message += f"\nRun '{upgrade_hint()}' to upgrade"
274
276
  return message
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepctl-cmd-update
3
- Version: 0.2.7
3
+ Version: 0.2.8
4
4
  Summary: Update command for deepctl
5
5
  Author-email: Deepgram <devrel@deepgram.com>
6
6
  Maintainer-email: Deepgram <devrel@deepgram.com>
@@ -15,7 +15,7 @@ Classifier: Programming Language :: Python :: 3.12
15
15
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
16
  Requires-Python: >=3.10
17
17
  Description-Content-Type: text/markdown
18
- Requires-Dist: deepctl-core>=0.1.10
18
+ Requires-Dist: deepctl-core>=0.3.1
19
19
  Requires-Dist: click>=8.0.0
20
20
  Requires-Dist: pydantic>=2.0.0
21
21
  Requires-Dist: rich>=13.0.0
@@ -1,4 +1,4 @@
1
- deepctl-core>=0.1.10
1
+ deepctl-core>=0.3.1
2
2
  click>=8.0.0
3
3
  pydantic>=2.0.0
4
4
  rich>=13.0.0