Skip to content

fix(deps): cap mcp <2 (fixes broken dg mcp), commit uv.lock, require twine >=7 - #95

Merged
GregHolmes merged 1 commit into
mainfrom
chore/dependency-audit
Aug 18, 2026
Merged

fix(deps): cap mcp <2 (fixes broken dg mcp), commit uv.lock, require twine >=7#95
GregHolmes merged 1 commit into
mainfrom
chore/dependency-audit

Conversation

@GregHolmes

Copy link
Copy Markdown
Contributor

Audit of outdated dependencies turned up a live user-facing bug, so this PR leads with the fix.

1. dg mcp is broken for every new install 🔴

deepgram-mcp 0.1.1 declares an unbounded mcp>=1.0.0. mcp 2.0 removed streamablehttp_client from mcp.client.streamable_http, which deepgram-mcp still imports — so a fresh pip install deepctl resolves mcp 2.0.0 and:

$ dg mcp
Error running MCP proxy: cannot import name 'streamablehttp_client' from 'mcp.client.streamable_http'

Reproduced in a clean venv against the released 0.2.27 wheel — this is not caused by this branch.

Why tests didn't catch it: all 1052 unit tests pass, because they mock run_proxy. Only a live invocation fails. (Those coroutine 'run_proxy' was never awaited warnings in the suite are that mock.)

Fix: cap mcp>=1.0.0,<2.0.0 in deepctl-cmd-mcp until deepgram-mcp supports 2.x. Verified dg mcp returns a valid initialize response on mcp 1.29.0.

2. Nothing was pinned across environments

uv.lock had been gitignored since the initial commit, and CI ran uv sync --group testing with no lock — so local, CI, the publish-action image and end users each resolved independently. That is the same class of problem behind both this mcp break and the 0.2.27 publish failure.

  • Commit uv.lock
  • CI now uses uv sync --group testing --locked, so drift shows up as a reviewable diff instead of a surprise

Note this fixes dev/CI reproducibility only — it does not constrain end users. Upper bounds in pyproject.toml (item 1) are the only thing that protects them.

3. twine>=7.0.0 for dev

twine <7 rejects Metadata-Version: 2.5 (emitted by hatchling) — the exact cause of the failed 0.2.27 publish. The venv had twine 6.2.0, so make verify-packages would have caught it locally, while CI's fresh pip install twine always got 7.x and always passed. Raising the floor keeps local verification equal to what actually publishes.

Verification

  • ruff format / ruff check / mypy clean (on ruff 0.16.3, up from 0.15.21)
  • 1052 passed, 6 skipped
  • dg mcp initialize verified live on mcp 1.29.0
  • Full 68-check live API smoke suite passes (STT files/URLs/live-stream/mic, TTS Aura + Flux incl. --speed/--expressivity, read, account, api, mcp)
  • Lockfile also moves websockets 16.1 → 17.0.1; verified Flux TTS streaming and live STT both work on it

Deliberately not included

Three related dependency-hygiene fixes surfaced while auditing outdated deps.

1. `dg mcp` is broken for every new install. deepgram-mcp declares an
   unbounded `mcp>=1.0.0`, and mcp 2.0 removed `streamablehttp_client` from
   `mcp.client.streamable_http`, which deepgram-mcp still imports. A fresh
   `pip install deepctl` therefore resolves mcp 2.0.0 and `dg mcp` dies with an
   ImportError. Reproduced against the released 0.2.27 wheel in a clean venv.
   The 1052 unit tests pass regardless because they mock `run_proxy`, so only a
   live invocation catches it. Cap `mcp>=1.0.0,<2.0.0` in deepctl-cmd-mcp until
   deepgram-mcp supports 2.x.

2. uv.lock was gitignored since the initial commit, so nothing pinned versions
   across environments: local, CI, the publish action image and end users all
   resolved independently. Commit the lock and switch CI to
   `uv sync --group testing --locked` so runs are reproducible and dependency
   drift arrives as a reviewable diff instead of a surprise.

3. Require `twine>=7.0.0` for dev. twine <7 rejects `Metadata-Version: 2.5`
   (emitted by hatchling), which is what failed the 0.2.27 publish. The venv
   had twine 6.2.0, so `make verify-packages` would have caught this locally,
   while CI's fresh `pip install twine` always got 7.x and always passed.
   Raising the floor keeps local verification equal to what actually publishes.

Verified: ruff/mypy clean, 1052 tests pass, `dg mcp` returns a valid initialize
response on mcp 1.29.0, and the full 68-check live API smoke suite passes.
@GregHolmes
GregHolmes force-pushed the chore/dependency-audit branch from 0e87bdf to 4ac4633 Compare August 18, 2026 09:45
@GregHolmes
GregHolmes merged commit 997cd36 into main Aug 18, 2026
39 checks passed
@GregHolmes
GregHolmes deleted the chore/dependency-audit branch August 18, 2026 10:03
@github-actions github-actions Bot mentioned this pull request Aug 18, 2026
GregHolmes added a commit that referenced this pull request Aug 18, 2026
… npm alerts (#96)

Stacked on #95 (base is `chore/dependency-audit`, so review that one
first).

## 1. Heap analytics is broken in production right now 🔴

The inline Heap loader in `index.astro` is a **JavaScript syntax
error**. The minified snippet ends:

```js
...o<p.length;o++)heap[o]=n(p[o]);      // ← missing the closing `}`
```

The official snippet ends `heap[o]=n(p[o])};`. Without it, the outer
`heap.load=function(e,t){` is never closed — **4 `{` vs 3 `}`**. So the
script fails to parse, `heap.load` is never defined, and
`heap.load("765739241")` on the next line never runs.

**Confirmed against live production HTML**, not just source:

```
$ curl -s https://cli.deepgram.com | ...
tail: ...o<p.length;o++)heap[o]=n(p[o]);
braces: {=4 }=3 balanced=False
```

So Heap has collected nothing since #76 shipped it. GA4 (a separate
script block) is unaffected.

Astro 6 passed the malformed raw text through silently; **astro 7's
stricter compiler is what exposed it** (`Expected } but found EOF`). I
found it because the upgrade build failed.

## 2. astro 6 → 7 + toolchain, clearing every npm alert

| package | from | to |
|---|---|---|
| astro | 6.1.6 | **7.2.2** (pulls vite 8) |
| tailwindcss / @tailwindcss/vite | 4.2.2 | 4.3.3 |
| @astrojs/sitemap | 3.7.2 | 3.7.3 |
| sharp / svgo | — | via `npm audit fix` |

`npm audit`: **20 vulnerabilities (11 high, 6 moderate, 3 low) → 0**.

## Verification — the upgrade is output-neutral

Diffed the astro 7 build against an astro 6 baseline of the same commit:

- **Identical file set** (only content-hash asset names differ; astro 7
renames the CSS pattern)
- **`og-image.png` byte-identical** — the `@resvg/resvg-js` native path
is unaffected
- **Identical structure**: 654 tags, 19 links, 39 svg paths, 5 scripts,
37 headings, **5711 visible characters** — all unchanged
- `index.html` is 1075 bytes smaller, purely astro 7 output formatting
- Advertised CLI version still resolves correctly from root
`pyproject.toml`

## Worth a look before merge

- Local build ran on **Node 24**; `netlify.toml` pins `NODE_VERSION =
22`. Astro 7 supports both, but a staging deploy is the real check — and
staging fires automatically on merge to `main`.
- Production only deploys on a root `v*` release **after** PyPI publish,
so this cannot ship a version-skewed page.
- Someone should confirm in Heap that data starts arriving once this
deploys — and that the missing history is understood.
GregHolmes added a commit that referenced this pull request Aug 18, 2026
…o json across account commands (#97)

Split out from #96 deliberately: that PR was a verified output-neutral
toolchain upgrade, this one changes content **and** fixes an output bug.
#95 and #96 are now merged, so this sits on current `main`.

## 1. Seven advertised commands don't work 🔴

The `ALL COMMANDS` cards used a subcommand style the CLI has never had.
Each was verified to fail:

| Page said | CLI response |
|---|---|
| `dg keys create "ci-runner"` | `No such command 'keys create'` |
| `dg projects list` | `No such command 'projects list'` |
| `dg members list` | `No such command 'members list'` |
| `dg models list --type stt` | `No such command 'models list'` |
| `dg requests list --limit 20 -o json` | `No such command 'requests
list'` |
| `dg completion install --shell zsh` | `No such command 'completion
install'` |
| `dg api GET /v1/projects` | `Got unexpected extra argument
(/v1/projects)` |

These commands are **flag-based**. The page was already internally
inconsistent — its FAQ text used the correct forms (`dg projects
--list`, `dg keys --create --comment`, `dg api /v1/projects --jq`) while
the cards used the broken style. Fixed to the verified forms.

## 2. Stale after the Flux changes (#89, #92)

The page said *"Generate speech with Aura voices"* with **zero**
mentions of Flux, even though `dg speak` now defaults to
`flux-alexis-en`. None of the new capabilities appeared anywhere
(`--speed`, `--expressivity`, `--redact`, `--numerals`,
`flux-general-en` all scored 0).

- **speak** — Flux documented as the default engine, new cards for
`--speed` / `--expressivity`, plus an explicit Aura card so `-m
aura-2-*` stays discoverable
- **listen** — new cards for `--redact` / `--numerals` and Flux STT
streaming, noting it is **streaming-only**
- **hero terminal** — a default `dg speak` now reports `flux-alexis-en`,
not `aura-2-asteria-en`

## 3. Missing commands added

`profiles`, `logout`, `ffprobe`, `debug browser`, `debug probe` had no
cards. **27 → 36 cards.**

## 4. llms.txt / llms-full.txt

These feed AI crawlers and had the same staleness, plus **a model name
that doesn't exist** (`aura-2-en-us` — confirmed rejected by the API,
rc=2). Corrected to real ids and added the new flag rows.

## 5. `-o json` now honored across list/detail commands (fixed here)

While verifying, I found `-o json` was **not honored consistently** —
several commands printed a Rich table or human text on stdout, ignoring
the flag and corrupting anything piped into `jq`. This PR fixes it
across `requests`, `read`, `models`, `projects`, `members`, `usage`, and
`billing` (+ `deepctl-core` exports `get_output_format`):

- Human tables/summaries are now gated on `get_output_format() ==
"default"`; for json/yaml/csv the framework serialises the returned
result to stdout.
- All status/progress chrome ("Fetching…", "Analyzing text…", errors)
moved to a stderr `Console`, so stdout stays clean.
- `requests --show` now returns a structured `RequestDetailResult` (the
full request detail) instead of a bare "displayed" message, so json/yaml
output is actually useful.

Verified live against the installed CLI + a real key: `dg -o json models
| jq`, `… projects --list`, `… requests --limit`, and `… read
--sentiment` all emit **pure JSON on stdout** with status text on
stderr.

## Tests

Added output-format gating tests for the three rendering shapes — table
(`requests`, `models`), list (`projects`, new test file), and inline
(`read`): each asserts that json mode writes **nothing** to the stdout
console while still returning a fully-populated result, and that default
mode still renders. Full suite green (`make check` + `uv run pytest`).

## Verification

Every card invocation was run against the installed CLI (`--help`-level
parse plus live runs for `--redact pci --numerals`,
`--speed`/`--expressivity`, and every model id including a
live-synthesis check that `aura-2-en-us` is rejected). Build passes; all
seven stale forms confirmed absent from the built output and the new
content confirmed present (including in the bundled hero-animation JS).
GregHolmes added a commit that referenced this pull request Aug 18, 2026
CI installs with `uv sync --group testing --locked`, and uv.lock pins the
version of all 31 workspace members. release-please bumps those versions in
each pyproject.toml (plus src/deepctl/__init__.py and the manifest) but has no
updater for uv.lock, so the lock still claimed deepctl 0.2.27 while
pyproject.toml said 0.2.28. `--locked` refuses to resolve against a stale lock,
so every job failed at the install step before running a single test -- 32
failing checks that looked like test failures but were not.

This is the first release PR since uv.lock was committed in #95 (997cd36); the
previous one (#90, 76ccdaf) predates it. Every future release PR will hit the
same wall until release.yml regenerates the lock itself.

`uv lock` changed only the 11 workspace member versions -- no third-party
dependency drift -- and all 31 now agree with .release-please-manifest.json.
GregHolmes added a commit that referenced this pull request Aug 18, 2026
0.2.27 was tagged on 2026-08-17 but its publish step failed on
Metadata-Version 2.5 (fixed afterwards by #94 and #95), so it never reached
PyPI. Everyone upgrading therefore goes 0.2.26 -> 0.2.28 and receives the
0.2.27 changes in this release, while the generated notes list only commits
made since the v0.2.27 tag.

The gap matters most for #89, which changed the default `dg speak` model from
Aura 2 to Flux TTS: a user whose synthesised audio changes after this upgrade
would find nothing in the 0.2.28 notes to explain it. Also records the six
packages that reach PyPI for the first time here, having been tagged in the
failed cycle.

Mirrored into the release PR body so the published release notes and the
committed changelog match.
GregHolmes added a commit that referenced this pull request Aug 19, 2026
🤖 I have created a release *beep* *boop*
---


<details><summary>0.3.0</summary>

## [0.3.0](v0.2.27...v0.3.0)
(2026-08-19)


### ⚠ BREAKING CHANGES

* `dg` now exits non-zero when a command fails: 1 for errors (including
crashes and usage errors), 2 for user interrupt, 0 on success. Every
command previously exited 0 regardless of outcome, so scripts and CI
steps that ignored the exit code will surface failures they were
silently swallowing. No command that succeeds changes its exit code.

### Bug Fixes

* correct web command examples, document Flux TTS/STT, and honor -o json
across account commands
([#97](#97))
([55984ec](55984ec))
* dependency floors that let dg update skip this release, and exit-code
+ error-stream correctness
([#102](#102))
([fd1e8a4](fd1e8a4))
* **deps:** cap mcp &lt;2 (fixes broken dg mcp), commit uv.lock, require
twine &gt;=7 ([#95](#95))
([997cd36](997cd36))
* **deps:** raise deepctl-core floor to 0.2.16 in the eight packages
that import get_status_console
([98f9e91](98f9e91))
* **deps:** raise root dependency floors to the versions this release
publishes
([c0b0023](c0b0023))
* exit 1, not 2, when a command crashes or is misused
([914e132](914e132))
* keep exit 2 when Ctrl-C interrupts a running command
([b0e80e2](b0e80e2))
* **keys:** honor -o json so stdout stays parseable (completes the
[#97](#97) sweep)
([#101](#101))
([e430a77](e430a77))
* **release:** bump pypi-publish action to v1.14.2 for Metadata-Version
2.5 ([#94](#94))
([582cd83](582cd83))
* send root error and interrupt output to stderr, not stdout
([f4b7c48](f4b7c48))
* **web:** repair broken Heap snippet, upgrade astro 6→7, clear all 20
npm alerts ([#96](#96))
([11928fe](11928fe))


### Behavior changes

Alongside the exit-code change above, upgrading to 0.3.0 changes these:

* The full exit-code contract is now enforced end to end: `0` = success,
`1` = error, `2` = user interrupt. Crashes **and usage errors** (bad
flag, unknown command, bare `dg`) exit `1`; `2` is reserved for
cancellation, so Ctrl-C during a running command and Ctrl-D at a prompt
both still exit `2`.
* Error and cancellation messages are written to **stderr** instead of
stdout. `dg -o json …` therefore keeps stdout machine-readable when a
command fails — previously a failure printed `Error: …` prose to stdout,
so a script piping stdout into `jq` parsed the error text instead of
JSON. Successful commands still write their payload to stdout.
* `-o yaml` and `-o csv` no longer drop square-bracketed text from
values. Output was passed through a renderer that read `[...]` as style
markup and deleted it, so an API key comment of `[ci] runner` was
emitted as `runner`. Long values are also no longer hard-wrapped
mid-field.
* `dg keys --delete KEY_ID` now asks for confirmation on stderr instead
of always reporting `Cancelled by user` without deleting. In a
non-interactive context it exits `1` and tells you to pass `--yes`.
* `dg keys --create --dry-run` now reports what it would create. It
previously failed with an internal `TypeError`.

### Previously unreleased

0.2.27 was tagged on 2026-08-17 but never reached PyPI — its publish
step failed with `InvalidDistribution: Invalid distribution metadata:
'2.5' is not a valid metadata version`, which
[#94](#94) and
[#95](#95) then fixed. PyPI
therefore goes straight from 0.2.26 to 0.3.0, and this release is the
first published build to include the 0.2.27 changes:

* SDK 7.7.0 — Flux TTS controls, Flux STT fix, listen redact/numerals
([#92](#92))
([50d96cf](50d96cf))
* **speak:** default to Flux TTS (`flux-alexis-en`) instead of Aura 2
([#89](#89))
([5a0b698](5a0b698)).
This changes the default model for `dg speak`, so synthesised audio
differs unless you pass an `aura-*` model explicitly.
* **mcp:** swallow broken/closed-pipe on dg mcp startup notifications
and error path ([#88](#88))
([b24396e](b24396e))

Six packages tagged in that cycle also reach PyPI for the first time
here: `deepctl-cmd-listen` 0.0.14, `deepctl-cmd-login` 0.1.17,
`deepctl-cmd-skills` 0.0.7, `deepctl-cmd-speak` 0.0.4,
`deepctl-cmd-update` 0.2.6 and `deepctl-telemetry` 0.0.6.

Because 0.2.27 never published, `dg update` on pip also had to be
repaired for this release to arrive at all: root's inter-package
dependency floors were lower than the versions being published, so pip's
default `only-if-needed` strategy left most sub-packages stale and `dg
--version` reported the new number while the fixes never landed. Floors
now match the published versions exactly.
</details>

<details><summary>deepctl-core: 0.2.16</summary>

##
[0.2.16](deepctl-core-v0.2.15...deepctl-core-v0.2.16)
(2026-08-19)


### Bug Fixes

* correct web command examples, document Flux TTS/STT, and honor -o json
across account commands
([#97](#97))
([55984ec](55984ec))
* **keys:** honor -o json so stdout stays parseable (completes the
[#97](#97) sweep)
([#101](#101))
([e430a77](e430a77))


### Behavior changes

* Commands now map their result status to a process exit code (`error` →
`1`, `cancelled` → `2`, otherwise `0`), and
`BaseCommand.exit_code_for()` exposes that mapping. Exit codes were
previously discarded, so every command exited `0`.
* `-o yaml` and `-o csv` payloads are written verbatim; the renderer no
longer interprets `[...]` as markup or wraps long values.
* New `get_status_console()` returns the shared stderr console for
status output. Commands should use it instead of declaring their own.
Packages that import it require `deepctl-core>=0.2.16`.
</details>

<details><summary>deepctl-cmd-projects: 0.2.0</summary>

##
[0.2.0](deepctl-cmd-projects-v0.1.13...deepctl-cmd-projects-v0.2.0)
(2026-08-19)


### ⚠ BREAKING CHANGES

* `dg` now exits non-zero when a command fails: 1 for errors (including
crashes and usage errors), 2 for user interrupt, 0 on success. Every
command previously exited 0 regardless of outcome, so scripts and CI
steps that ignored the exit code will surface failures they were
silently swallowing. No command that succeeds changes its exit code.

### Bug Fixes

* correct web command examples, document Flux TTS/STT, and honor -o json
across account commands
([#97](#97))
([55984ec](55984ec))
* dependency floors that let dg update skip this release, and exit-code
+ error-stream correctness
([#102](#102))
([fd1e8a4](fd1e8a4))
* **deps:** raise deepctl-core floor to 0.2.16 in the eight packages
that import get_status_console
([98f9e91](98f9e91))
* **keys:** honor -o json so stdout stays parseable (completes the
[#97](#97) sweep)
([#101](#101))
([e430a77](e430a77))
</details>

<details><summary>deepctl-cmd-usage: 0.2.0</summary>

##
[0.2.0](deepctl-cmd-usage-v0.1.13...deepctl-cmd-usage-v0.2.0)
(2026-08-19)


### ⚠ BREAKING CHANGES

* `dg` now exits non-zero when a command fails: 1 for errors (including
crashes and usage errors), 2 for user interrupt, 0 on success. Every
command previously exited 0 regardless of outcome, so scripts and CI
steps that ignored the exit code will surface failures they were
silently swallowing. No command that succeeds changes its exit code.

### Bug Fixes

* correct web command examples, document Flux TTS/STT, and honor -o json
across account commands
([#97](#97))
([55984ec](55984ec))
* dependency floors that let dg update skip this release, and exit-code
+ error-stream correctness
([#102](#102))
([fd1e8a4](fd1e8a4))
* **deps:** raise deepctl-core floor to 0.2.16 in the eight packages
that import get_status_console
([98f9e91](98f9e91))
* **keys:** honor -o json so stdout stays parseable (completes the
[#97](#97) sweep)
([#101](#101))
([e430a77](e430a77))
</details>

<details><summary>deepctl-cmd-mcp: 0.1.15</summary>

##
[0.1.15](deepctl-cmd-mcp-v0.1.14...deepctl-cmd-mcp-v0.1.15)
(2026-08-19)


### Bug Fixes

* **deps:** cap mcp &lt;2 (fixes broken dg mcp), commit uv.lock, require
twine &gt;=7 ([#95](#95))
([997cd36](997cd36))
</details>

<details><summary>deepctl-cmd-models: 0.1.0</summary>

##
[0.1.0](deepctl-cmd-models-v0.0.2...deepctl-cmd-models-v0.1.0)
(2026-08-19)


### ⚠ BREAKING CHANGES

* `dg` now exits non-zero when a command fails: 1 for errors (including
crashes and usage errors), 2 for user interrupt, 0 on success. Every
command previously exited 0 regardless of outcome, so scripts and CI
steps that ignored the exit code will surface failures they were
silently swallowing. No command that succeeds changes its exit code.

### Bug Fixes

* correct web command examples, document Flux TTS/STT, and honor -o json
across account commands
([#97](#97))
([55984ec](55984ec))
* dependency floors that let dg update skip this release, and exit-code
+ error-stream correctness
([#102](#102))
([fd1e8a4](fd1e8a4))
* **deps:** raise deepctl-core floor to 0.2.16 in the eight packages
that import get_status_console
([98f9e91](98f9e91))
* **keys:** honor -o json so stdout stays parseable (completes the
[#97](#97) sweep)
([#101](#101))
([e430a77](e430a77))
</details>

<details><summary>deepctl-cmd-keys: 0.1.0</summary>

##
[0.1.0](deepctl-cmd-keys-v0.0.3...deepctl-cmd-keys-v0.1.0)
(2026-08-19)


### ⚠ BREAKING CHANGES

* `dg` now exits non-zero when a command fails: 1 for errors (including
crashes and usage errors), 2 for user interrupt, 0 on success. Every
command previously exited 0 regardless of outcome, so scripts and CI
steps that ignored the exit code will surface failures they were
silently swallowing. No command that succeeds changes its exit code.

### Bug Fixes

* dependency floors that let dg update skip this release, and exit-code
+ error-stream correctness
([#102](#102))
([fd1e8a4](fd1e8a4))
* **deps:** raise deepctl-core floor to 0.2.16 in the eight packages
that import get_status_console
([98f9e91](98f9e91))
* **keys:** honor -o json so stdout stays parseable (completes the
[#97](#97) sweep)
([#101](#101))
([e430a77](e430a77))
</details>

<details><summary>deepctl-cmd-read: 0.1.0</summary>

##
[0.1.0](deepctl-cmd-read-v0.0.2...deepctl-cmd-read-v0.1.0)
(2026-08-19)


### ⚠ BREAKING CHANGES

* `dg` now exits non-zero when a command fails: 1 for errors (including
crashes and usage errors), 2 for user interrupt, 0 on success. Every
command previously exited 0 regardless of outcome, so scripts and CI
steps that ignored the exit code will surface failures they were
silently swallowing. No command that succeeds changes its exit code.

### Bug Fixes

* correct web command examples, document Flux TTS/STT, and honor -o json
across account commands
([#97](#97))
([55984ec](55984ec))
* dependency floors that let dg update skip this release, and exit-code
+ error-stream correctness
([#102](#102))
([fd1e8a4](fd1e8a4))
* **deps:** raise deepctl-core floor to 0.2.16 in the eight packages
that import get_status_console
([98f9e91](98f9e91))
* **keys:** honor -o json so stdout stays parseable (completes the
[#97](#97) sweep)
([#101](#101))
([e430a77](e430a77))
</details>

<details><summary>deepctl-cmd-requests: 0.1.0</summary>

##
[0.1.0](deepctl-cmd-requests-v0.0.2...deepctl-cmd-requests-v0.1.0)
(2026-08-19)


### ⚠ BREAKING CHANGES

* `dg` now exits non-zero when a command fails: 1 for errors (including
crashes and usage errors), 2 for user interrupt, 0 on success. Every
command previously exited 0 regardless of outcome, so scripts and CI
steps that ignored the exit code will surface failures they were
silently swallowing. No command that succeeds changes its exit code.

### Bug Fixes

* correct web command examples, document Flux TTS/STT, and honor -o json
across account commands
([#97](#97))
([55984ec](55984ec))
* dependency floors that let dg update skip this release, and exit-code
+ error-stream correctness
([#102](#102))
([fd1e8a4](fd1e8a4))
* **deps:** raise deepctl-core floor to 0.2.16 in the eight packages
that import get_status_console
([98f9e91](98f9e91))
* **keys:** honor -o json so stdout stays parseable (completes the
[#97](#97) sweep)
([#101](#101))
([e430a77](e430a77))
</details>

<details><summary>deepctl-cmd-billing: 0.1.0</summary>

##
[0.1.0](deepctl-cmd-billing-v0.0.2...deepctl-cmd-billing-v0.1.0)
(2026-08-19)


### ⚠ BREAKING CHANGES

* `dg` now exits non-zero when a command fails: 1 for errors (including
crashes and usage errors), 2 for user interrupt, 0 on success. Every
command previously exited 0 regardless of outcome, so scripts and CI
steps that ignored the exit code will surface failures they were
silently swallowing. No command that succeeds changes its exit code.

### Bug Fixes

* correct web command examples, document Flux TTS/STT, and honor -o json
across account commands
([#97](#97))
([55984ec](55984ec))
* dependency floors that let dg update skip this release, and exit-code
+ error-stream correctness
([#102](#102))
([fd1e8a4](fd1e8a4))
* **deps:** raise deepctl-core floor to 0.2.16 in the eight packages
that import get_status_console
([98f9e91](98f9e91))
* **keys:** honor -o json so stdout stays parseable (completes the
[#97](#97) sweep)
([#101](#101))
([e430a77](e430a77))
</details>

<details><summary>deepctl-cmd-members: 0.1.0</summary>

##
[0.1.0](deepctl-cmd-members-v0.0.3...deepctl-cmd-members-v0.1.0)
(2026-08-19)


### ⚠ BREAKING CHANGES

* `dg` now exits non-zero when a command fails: 1 for errors (including
crashes and usage errors), 2 for user interrupt, 0 on success. Every
command previously exited 0 regardless of outcome, so scripts and CI
steps that ignored the exit code will surface failures they were
silently swallowing. No command that succeeds changes its exit code.

### Bug Fixes

* correct web command examples, document Flux TTS/STT, and honor -o json
across account commands
([#97](#97))
([55984ec](55984ec))
* dependency floors that let dg update skip this release, and exit-code
+ error-stream correctness
([#102](#102))
([fd1e8a4](fd1e8a4))
* **deps:** raise deepctl-core floor to 0.2.16 in the eight packages
that import get_status_console
([98f9e91](98f9e91))
* **keys:** honor -o json so stdout stays parseable (completes the
[#97](#97) sweep)
([#101](#101))
([e430a77](e430a77))
</details>

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant