deepctl-core 0.2.16__tar.gz → 0.2.17__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 (22) hide show
  1. {deepctl_core-0.2.16 → deepctl_core-0.2.17}/PKG-INFO +1 -1
  2. {deepctl_core-0.2.16 → deepctl_core-0.2.17}/pyproject.toml +1 -1
  3. {deepctl_core-0.2.16 → deepctl_core-0.2.17}/src/deepctl_core/__init__.py +2 -0
  4. {deepctl_core-0.2.16 → deepctl_core-0.2.17}/src/deepctl_core/output.py +24 -0
  5. {deepctl_core-0.2.16 → deepctl_core-0.2.17}/src/deepctl_core/plugin_manager.py +78 -3
  6. {deepctl_core-0.2.16 → deepctl_core-0.2.17}/src/deepctl_core.egg-info/PKG-INFO +1 -1
  7. {deepctl_core-0.2.16 → deepctl_core-0.2.17}/README.md +0 -0
  8. {deepctl_core-0.2.16 → deepctl_core-0.2.17}/setup.cfg +0 -0
  9. {deepctl_core-0.2.16 → deepctl_core-0.2.17}/src/deepctl_core/auth.py +0 -0
  10. {deepctl_core-0.2.16 → deepctl_core-0.2.17}/src/deepctl_core/base_command.py +0 -0
  11. {deepctl_core-0.2.16 → deepctl_core-0.2.17}/src/deepctl_core/base_group_command.py +0 -0
  12. {deepctl_core-0.2.16 → deepctl_core-0.2.17}/src/deepctl_core/client.py +0 -0
  13. {deepctl_core-0.2.16 → deepctl_core-0.2.17}/src/deepctl_core/config.py +0 -0
  14. {deepctl_core-0.2.16 → deepctl_core-0.2.17}/src/deepctl_core/models.py +0 -0
  15. {deepctl_core-0.2.16 → deepctl_core-0.2.17}/src/deepctl_core/plugin_env.py +0 -0
  16. {deepctl_core-0.2.16 → deepctl_core-0.2.17}/src/deepctl_core/py.typed +0 -0
  17. {deepctl_core-0.2.16 → deepctl_core-0.2.17}/src/deepctl_core/skill_generator.py +0 -0
  18. {deepctl_core-0.2.16 → deepctl_core-0.2.17}/src/deepctl_core/timing.py +0 -0
  19. {deepctl_core-0.2.16 → deepctl_core-0.2.17}/src/deepctl_core.egg-info/SOURCES.txt +0 -0
  20. {deepctl_core-0.2.16 → deepctl_core-0.2.17}/src/deepctl_core.egg-info/dependency_links.txt +0 -0
  21. {deepctl_core-0.2.16 → deepctl_core-0.2.17}/src/deepctl_core.egg-info/requires.txt +0 -0
  22. {deepctl_core-0.2.16 → deepctl_core-0.2.17}/src/deepctl_core.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepctl-core
3
- Version: 0.2.16
3
+ Version: 0.2.17
4
4
  Summary: Core components for deepctl
5
5
  Author-email: Deepgram <devrel@deepgram.com>
6
6
  Maintainer-email: Deepgram <devrel@deepgram.com>
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "deepctl-core"
7
- version = "0.2.16" # x-release-please-version
7
+ version = "0.2.17" # x-release-please-version
8
8
  description = "Core components for deepctl"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -24,6 +24,7 @@ from .output import (
24
24
  print_success,
25
25
  print_warning,
26
26
  setup_output,
27
+ update_output,
27
28
  )
28
29
  from .plugin_manager import PluginManager
29
30
  from .timing import (
@@ -63,4 +64,5 @@ __all__ = [
63
64
  "print_timing_summary",
64
65
  "print_warning",
65
66
  "setup_output",
67
+ "update_output",
66
68
  ]
@@ -103,6 +103,30 @@ def setup_output(
103
103
  console.quiet = quiet
104
104
 
105
105
 
106
+ def update_output(
107
+ format_type: str | None = None,
108
+ quiet: bool | None = None,
109
+ verbose: bool | None = None,
110
+ ) -> None:
111
+ """Update parts of the global output configuration in place.
112
+
113
+ Unlike setup_output(), only the arguments actually provided change;
114
+ every other setting keeps its current value. The per-command
115
+ pass-through options use this so that ``dg models -o json`` has the
116
+ same effect as ``dg -o json models`` without resetting the quiet or
117
+ verbose state the root group already applied.
118
+ """
119
+ if format_type is not None:
120
+ if format_type == "default" and _output_config["agentic"]:
121
+ format_type = "json"
122
+ _output_config["format"] = format_type
123
+ if quiet is not None:
124
+ _output_config["quiet"] = quiet
125
+ console.quiet = quiet
126
+ if verbose is not None:
127
+ _output_config["verbose"] = verbose
128
+
129
+
106
130
  class OutputFormatter:
107
131
  """Formatter for different output types."""
108
132
 
@@ -7,12 +7,11 @@ from pathlib import Path
7
7
  from typing import Any, cast
8
8
 
9
9
  import click
10
- from rich.console import Console
11
10
 
12
11
  from .base_command import BaseCommand
13
12
  from .base_group_command import BaseGroupCommand
14
13
  from .models import ErrorResult, PluginInfo
15
- from .output import print_warning
14
+ from .output import print_warning, stderr_console
16
15
  from .plugin_env import (
17
16
  PLUGIN_VENV,
18
17
  get_plugin_state,
@@ -21,7 +20,9 @@ from .plugin_env import (
21
20
  )
22
21
  from .timing import TimingContext
23
22
 
24
- console = Console()
23
+ # Load errors are diagnostics: they go to stderr so a broken plugin can't
24
+ # corrupt `dg ... -o json` payloads on stdout.
25
+ console = stderr_console
25
26
 
26
27
 
27
28
  class PluginManager:
@@ -293,6 +294,80 @@ class PluginManager:
293
294
  help="Skip interactive prompts; use defaults for any optional features.",
294
295
  )(cmd)
295
296
 
297
+ # Accept the global output options after the subcommand as well.
298
+ cmd = self._add_global_passthrough_options(cmd)
299
+
300
+ return cmd
301
+
302
+ def _add_global_passthrough_options(self, cmd: click.Command) -> click.Command:
303
+ """Let the global output options work after the subcommand too.
304
+
305
+ The root group defines -o/--output, -q/--quiet and -v/--verbose, but
306
+ Click only parses group options that appear *before* the subcommand
307
+ name — so ``dg models -o json`` used to fail with "No such option
308
+ '-o'" while ``dg -o json models`` worked, and the error gave no hint.
309
+ These pass-through copies apply the same effect from the subcommand
310
+ position. A copy is only added when the command does not already
311
+ define the option name itself (for example, ``dg speak --output``
312
+ names an audio file and keeps its own meaning).
313
+ """
314
+ from .output import update_output
315
+
316
+ taken: set[str] = set()
317
+ for param in cmd.params:
318
+ taken.update(param.opts)
319
+ taken.update(param.secondary_opts)
320
+
321
+ def _apply_format(
322
+ _ctx: click.Context, _param: click.Parameter, value: str | None
323
+ ) -> None:
324
+ if value is not None:
325
+ update_output(format_type=value)
326
+
327
+ def _apply_quiet(
328
+ _ctx: click.Context, _param: click.Parameter, value: bool
329
+ ) -> None:
330
+ if value:
331
+ update_output(quiet=True)
332
+
333
+ def _apply_verbose(
334
+ _ctx: click.Context, _param: click.Parameter, value: bool
335
+ ) -> None:
336
+ if value:
337
+ update_output(verbose=True)
338
+
339
+ if not {"--output", "-o"} & taken:
340
+ cmd = click.option(
341
+ "--output",
342
+ "-o",
343
+ type=click.Choice(
344
+ ["json", "yaml", "table", "csv"], case_sensitive=False
345
+ ),
346
+ expose_value=False,
347
+ callback=_apply_format,
348
+ help="Output format (same as the global -o before the command).",
349
+ )(cmd)
350
+
351
+ if not {"--quiet", "-q"} & taken:
352
+ cmd = click.option(
353
+ "--quiet",
354
+ "-q",
355
+ is_flag=True,
356
+ expose_value=False,
357
+ callback=_apply_quiet,
358
+ help="Suppress non-essential output.",
359
+ )(cmd)
360
+
361
+ if not {"--verbose", "-v"} & taken:
362
+ cmd = click.option(
363
+ "--verbose",
364
+ "-v",
365
+ is_flag=True,
366
+ expose_value=False,
367
+ callback=_apply_verbose,
368
+ help="Enable verbose output.",
369
+ )(cmd)
370
+
296
371
  return cmd
297
372
 
298
373
  def _build_help_text(self, instance: Any) -> str:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepctl-core
3
- Version: 0.2.16
3
+ Version: 0.2.17
4
4
  Summary: Core components for deepctl
5
5
  Author-email: Deepgram <devrel@deepgram.com>
6
6
  Maintainer-email: Deepgram <devrel@deepgram.com>
File without changes
File without changes