Skip to content

release: deepseek-tui 0.4.7 + Devin .env empty-key fix#19

Merged
Hmbown merged 1 commit into
mainfrom
codex/release-0.4.7
Apr 25, 2026
Merged

release: deepseek-tui 0.4.7 + Devin .env empty-key fix#19
Hmbown merged 1 commit into
mainfrom
codex/release-0.4.7

Conversation

@Hmbown

@Hmbown Hmbown commented Apr 25, 2026

Copy link
Copy Markdown
Owner

Summary

  • Bumps workspace + npm wrapper version 0.4.60.4.7 so the release workflow can ship a fresh tag (the prior v0.4.6 release run failed at the parity gate; that tag is intentionally left in place).
  • Fixes the .env.example / apply_env_overrides bug Devin flagged on PR #18.

Bug fix

A new user following setup --status guidance (cp .env.example .env) would hit a startup crash:

  1. .env.example:7 had an uncommented DEEPSEEK_API_KEY= placeholder.
  2. dotenvy::dotenv() loaded the empty value into the process env.
  3. apply_env_overrides (crates/tui/src/config.rs) unconditionally set config.api_key = Some("").
  4. Config::validate() then bailed with api_key cannot be empty string.

The facade crate (crates/config/src/lib.rs:557-559) already filters empty values; the TUI's override path did not. This PR aligns the two and comments out the placeholder.

Changes

  • .env.example: DEEPSEEK_API_KEY=# DEEPSEEK_API_KEY=.
  • crates/tui/src/config.rs::apply_env_overrides: only override config.api_key when the env value is non-empty after trim.
  • New regression test apply_env_overrides_ignores_empty_api_key.
  • Cargo.toml, Cargo.lock, npm/deepseek-tui/package.json (version + deepseekBinaryVersion) bumped to 0.4.7.

Test plan

  • cargo fmt --all -- --check
  • cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
  • cargo test --workspace --all-features --locked — 781 passed (one new regression test)
  • Release gate workflow expected to pass on the resulting v0.4.7 tag (parity broke previously on fmt; main HEAD is fmt-clean since Verify app smoke and add NIM env support #18).

After merge, push tag v0.4.7 to trigger the release workflow which builds platform binaries, creates a GH release, and publishes the npm wrapper via OIDC Trusted Publishing.


Open in Devin Review

Bump workspace version 0.4.6 -> 0.4.7 and ship the bug fix flagged by Devin
on PR #18: an uncommented `DEEPSEEK_API_KEY=` line in .env.example caused
`cp .env.example .env` to load an empty key, which `apply_env_overrides`
then propagated into the config and `Config::validate()` rejected on
startup with "api_key cannot be empty string".

- .env.example: comment out the empty `DEEPSEEK_API_KEY=` placeholder.
- crates/tui/src/config.rs: skip empty `DEEPSEEK_API_KEY` env values in
  `apply_env_overrides`, matching the facade's empty-string filter.
- Add `apply_env_overrides_ignores_empty_api_key` regression test.
- Bump Cargo.toml workspace version, npm wrapper version + binary version,
  and Cargo.lock.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 2 additional findings.

Open in Devin Review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the project version to 0.4.7 and modifies the configuration logic to ignore empty 'DEEPSEEK_API_KEY' environment variables. Review feedback recommends trimming the API key before it is stored to prevent authentication failures from accidental whitespace. Furthermore, it is suggested to use the 'tempfile' crate in the added test case for safer and more idiomatic temporary directory handling.

Comment thread crates/tui/src/config.rs
Comment on lines +731 to 735
if let Ok(value) = std::env::var("DEEPSEEK_API_KEY")
&& !value.trim().is_empty()
{
config.api_key = Some(value);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

It's recommended to trim the API key before storing it in the configuration. Environment variables, especially those loaded from .env files, can often contain accidental leading or trailing whitespace which might cause authentication issues with the API provider.

Suggested change
if let Ok(value) = std::env::var("DEEPSEEK_API_KEY")
&& !value.trim().is_empty()
{
config.api_key = Some(value);
}
if let Ok(value) = std::env::var("DEEPSEEK_API_KEY")
&& !value.trim().is_empty()
{
config.api_key = Some(value.trim().to_string());
}

Comment thread crates/tui/src/config.rs
Comment on lines +1562 to +1572
let nanos = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_nanos();
let temp_root = env::temp_dir().join(format!(
"deepseek-tui-empty-key-{}-{}",
std::process::id(),
nanos
));
fs::create_dir_all(&temp_root)?;
let _guard = EnvGuard::new(&temp_root);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The test manually constructs a temporary directory path and creates it without ensuring cleanup. Using tempfile::tempdir() is a safer and more idiomatic approach in Rust; it automatically handles unique naming and deletes the directory when the returned TempDir object is dropped, preventing temporary file accumulation.

Suggested change
let nanos = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_nanos();
let temp_root = env::temp_dir().join(format!(
"deepseek-tui-empty-key-{}-{}",
std::process::id(),
nanos
));
fs::create_dir_all(&temp_root)?;
let _guard = EnvGuard::new(&temp_root);
let temp_dir = tempfile::tempdir()?;
let _guard = EnvGuard::new(temp_dir.path());

@Hmbown
Hmbown merged commit ba59f20 into main Apr 25, 2026
12 checks passed
@Hmbown
Hmbown deleted the codex/release-0.4.7 branch April 25, 2026 18:23
Hmbown added a commit that referenced this pull request Apr 25, 2026
release: deepseek-tui 0.4.7 + Devin .env empty-key fix
Hmbown pushed a commit that referenced this pull request Jul 7, 2026
Security/infra (deep-dive #1-#5, #14-#15, #19-#21, #25, #33-#34, #36-#37, #42):
- require bearer token on /v1/chat/completions; real 4xx/5xx statuses
- request body (16 MiB) and SSE frame bounds; graceful shutdown on
  SIGTERM/ctrl-c; constant-time token compare; stdio config get redacts
  secrets; stdio shutdown reaps the runtime child; RuntimeBridge::drop no
  longer blocks the runtime thread
- user-layer ExecPolicy rules outrank agent-layer; chained commands no
  longer propose trusted-prefix amendments
- atomic config save with one-time backup on all platforms; atomic secrets
  writes with fsync; empty ProviderChain no longer panics

Core/state/mcp (deep-dive #10-#13, #16-#18):
- paused jobs persist as Paused across restarts; unarchive refreshes the
  in-memory cache; tool dispatch timeout with error frame; MCP
  notifications get no JSON-RPC response; checkpoint parse errors
  propagate instead of loading empty state; session index compacts at
  threshold; thread-goal usage recording no longer self-deadlocks the
  state store

Also adds Zai GLM-5-Turbo and OpenRouter z-ai/glm-5.2 to the bundled
catalog (picker/router drift).
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