Commit Graph

783 Commits

Author SHA1 Message Date
Hunter Bown 4f77c625fd fix(tui): forward-port v0.8.16 hotfix to main
Forward-port the v0.8.16 RLM/sub-agent hotfix onto main after tagging the release branch.
2026-05-07 00:04:31 -05:00
Hunter Bown c7ed05a07c feat(api): default DeepSeek to beta endpoint
Closes #941.\n\nRefs #938, #939, #940.
2026-05-06 21:24:59 -05:00
Hunter Bown 0ee298bd77 docs: update thanks and package-manager notes (#943) 2026-05-06 21:23:48 -05:00
Hunter Bown 0ee4c81ac0 fix(theme): auto-adapt palette for light terminals (#931)
Closes #899.

Detects light terminal profiles from COLORFGBG, keeps the existing dark theme as the fallback, and maps DeepSeek dark-palette cells to readable light surfaces in the existing ColorCompatBackend.

Local verification:
- cargo fmt --all -- --check
- cargo test -p deepseek-tui palette --all-features
- cargo test -p deepseek-tui color_compat --all-features
- cargo build

CI: all required checks passed on #931.
2026-05-06 20:55:30 -05:00
Hunter Bown ebcffaadf9 feat(compaction): add /anchor compaction facts (#930)
Integrates source PR #525 by @shentoumengxin.

Adds `/anchor` for critical user facts that should survive compaction via `.deepseek/anchors.md`. Keeps `/pin` unregistered so the resident-context `/pin` lane remains available, and renders anchors as structured bullets in compaction summaries instead of raw separator text.

Local verification:
- cargo fmt --all -- --check
- cargo test -p deepseek-tui anchor --all-features
- cargo build

CI: all required checks passed on #930.

Co-authored-by: ZZHAsus <3075047037@qq.com>
2026-05-06 20:45:22 -05:00
Hunter Bown 29d57c7518 ci(release): build linux artifacts natively (#928) 2026-05-06 20:34:05 -05:00
Hunter Bown ed5eb4f7c4 ci(release): bound zig download retries (#926) 2026-05-06 20:26:21 -05:00
Reid 78c415f40c feat(provider): add Ollama provider support (#921)
Source PR: #921 by @reidliu41.
Closes #908.

Local verification:
- cargo test --workspace --all-features ollama
- cargo fmt --all -- --check
- cargo build

Co-authored-by: reidliu41 <reid201711@gmail.com>
2026-05-06 20:16:46 -05:00
Hunter Bown 8a0a166b9c ci(release): retry zig install from fixed tarball (#925) 2026-05-06 20:10:32 -05:00
Hunter Bown da047c44ff feat(tui): notification_condition override + assistant text in OSC 9 body (#920)
* feat(tui): add `notification_condition` override + assistant text in body (#820)

`[notifications]` already controls method (auto/osc9/bel/off), the
`threshold_secs` gate, and the `include_summary` body. Some users
want a simpler high-level switch — "always notify on every turn" or
"never notify" — without having to know the lower-level fields.

This adds a single optional `[tui].notification_condition` field:

  - `"always"` — notify on every successful turn (no duration
    threshold). The configured `[notifications].method` and
    `include_summary` flag are still respected.
  - `"never"`  — suppress all turn-completion notifications.
  - omitted    — fall back to the existing `[notifications]` defaults
    (the v0.8.15 behavior is unchanged).

The OSC 9 / BEL body now also carries the assistant's reply text,
sanitized and truncated to 360 characters, with a fallback to the
latest assistant message in `api_messages` when the streaming buffer
was empty (e.g. a tool-only turn). When `include_summary = true`,
the elapsed/cost line is appended on a new line.

Drive-by: drop the unused `Method::from_str` helper (the new code
match-arms over the typed `NotificationMethod` enum, so the parser
helper had no remaining callers).

Differences from upstream #820:
- Keeps the `[notifications]` section in `config.example.toml`
  (with `notification_condition` documented as an opt-in override)
  rather than deleting the existing block. This avoids breaking
  configs that already set `[notifications].method` etc.
- Drops the unrelated `#[allow(dead_code)]` on
  `schema_migration::registry`.
- Threads `Option<CostEstimate>` through the helper (the cost
  surface changed from `Option<f64>` since #820 was authored).

Tests:
- `notification_settings_*` (3) — `always` keeps the configured
  method, `never` returns `None`, missing override falls back.
- `completed_turn_notification_*` (4) — streaming text wins, falls
  back to latest assistant message, default placeholder, and 360-char
  truncation with `...`.

Integrates #820.

Co-authored-by: zero <1603852@qq.com>
Co-authored-by: zerx-lab <161401688+zerx-lab@users.noreply.github.com>

* style: fmt — collapse short test message helper calls

---------

Co-authored-by: zero <1603852@qq.com>
Co-authored-by: zerx-lab <161401688+zerx-lab@users.noreply.github.com>
2026-05-06 19:29:02 -05:00
Hunter Bown 1dcb90760e feat(prompts): inject deterministic Environment block (#813) (#922)
Replace the model's first-message language detection with a
deterministic `## Environment` block at the top of the workspace-
static portion of the system prompt. The block lists:

  - lang: resolved BCP-47 tag (`en`, `zh-Hans`, `ja`, `pt-BR`)
  - platform: `std::env::consts::OS`
  - shell: `$SHELL` (or `unknown`)
  - pwd: workspace path

`base.md`'s `## Language` directive now points the model at the
`lang` field instead of asking it to guess from the user's first
turn. When `lang` is missing or ambiguous the existing detect-from-
writing fallback still applies.

The block is injected at "step 2.25" in the prompt builder — after
mode prompt + project context, before the configured `instructions`
files and the skills section — so it lives in the same workspace-
static cache layer as the surrounding blocks. All four inputs
(locale tag, platform, shell, pwd) are resolved once per session
and stay byte-stable across turns, preserving prefix-cache hits.

`render_environment_block` is intentionally I/O-free: callers pass
the resolved locale tag in `PromptSessionContext.locale_tag` /
`EngineConfig.locale_tag`. `resolve_locale(...)` is invoked once
when constructing the engine config in `tui::ui`, `runtime_threads`,
and `run_exec_agent`.

Tests:
- `render_environment_block_lists_supplied_locale_and_workspace`
- `environment_block_is_inserted_into_system_prompt`

Verified:
- `cargo test -p deepseek-tui --bin deepseek-tui` (2224 passed)
- `cargo test -p deepseek-tui-core --test snapshot --locked`
- `cargo clippy -p deepseek-tui --all-targets -- -D warnings`
- `cargo fmt --all -- --check`

Integrates #813.

Co-authored-by: lloydzhou <lloydzhou@qq.com>
2026-05-06 19:28:17 -05:00
Hunter Bown 4eaeae91b5 feat(fork): print confirmation with new session id (#600) (#919)
After `deepseek fork` saves the forked session, surface the source
session title and the truncated source/new session ids so the user
sees what was created before the TUI takes over the screen.

Implementation differs slightly from the original PR:
- Reuse the existing `session_manager::truncate_id` helper instead of
  defining a second copy in `main.rs`.
- Guard against an empty saved-title string so the line stays
  readable for unnamed sessions.

This is a UX-only addition that does not address the broader
`/fork` request from #576; that one is asking for an in-TUI fork
picker, which is out of scope for v0.8.15.

Integrates #600.

Co-authored-by: macworkers <Mann_Juarezxgs@cash4u.com>
2026-05-06 19:22:36 -05:00
Hunter Bown 1122bb0333 fix(command-safety): reject null bytes in shell commands (#706) (#918)
Null bytes embedded in command strings can be used to slip past
parsers that treat them as terminators while shells still see the
trailing payload. The existing analyzer already blocks `\n` / `\r`
multi-line input but lets `\0` through; add a matching dangerous
classification beside it.

This PR intentionally takes only the null-byte slice from #706. The
broader `command.contains("eval")` / `command.contains("exec ")`
guard from the same PR is *not* applied because it false-positives on
routine commands such as `cargo run -- eval` (the offline eval
harness) or any binary whose name contains `eval` (`evaluator.py`,
`primeval`). A regression test pins that behavior.

Tests:
- `test_null_byte_is_blocked` — `ls\0 -la` and `echo hello\0world`
  classified as Dangerous.
- `test_eval_substring_is_not_misclassified` — `cargo run --bin
  deepseek -- eval` and `python evaluator.py` are *not* Dangerous.

Integrates #706.

Co-authored-by: 浩淼的mac <haomiaodemac@haomiaodemacdeMacBook-Air.local>
2026-05-06 19:22:33 -05:00
Hunter Bown 785f5c625f docs: list deepseek update in README command tables (#838) (#917)
Surface the existing `deepseek update` self-update command in the
English and Chinese README command listings so users can discover it
without reading source. The `deepseek update` subcommand has shipped
since the dispatcher gained `crates/cli/src/update.rs`.

This integration takes only the README slice from #838. The startup
GitHub-Releases polling check from the same PR is intentionally
deferred until it can be made opt-in / config-backed without adding
unconditional network calls or perceptible startup latency.

Integrates #838.

Co-authored-by: leo119 <leo.hou0924@gmail.com>
2026-05-06 19:22:29 -05:00
Hunter Bown afe99f2b64 feat(runtime): add optional API token guard (#916)
Integrates #856 as a focused runtime API security slice.

Default local behavior remains unchanged. `/v1/*` routes require a token only when `--auth-token` or `DEEPSEEK_RUNTIME_TOKEN` is set, and `/health` remains public for readiness checks.

Co-authored-by: Zhuoran Deng <dengzhuoran9@gmail.com>
2026-05-06 18:37:36 -05:00
Hunter Bown 8ad007903b chore: update locked security dependencies (#915)
Integrates #879 safe lockfile dependency updates.

Regenerated the dependency bumps on current main so workspace crates stay on v0.8.15. The Dockerfile edits from #879 were intentionally left out because they pin stale Debian package versions and add an invalid trailing `MD []` instruction.

Co-authored-by: RinZ27 <222222878+RinZ27@users.noreply.github.com>
2026-05-06 18:27:50 -05:00
Hunter Bown 633092167c feat(config): support custom HTTP headers (#914)
Integrates the useful custom HTTP header support from #881 onto current main.

- support root, provider-specific, and DEEPSEEK_HTTP_HEADERS overrides
- apply validated extra headers to model API requests while preserving protected Authorization and Content-Type defaults
- document the config shape in README, config.example.toml, and docs/CONFIGURATION.md

Co-authored-by: Desheng <8596814+dst1213@users.noreply.github.com>
2026-05-06 18:13:18 -05:00
Hunter Bown 8b9590b82b feat(tui): polish transcript rendering (#912)
* feat(tui): polish transcript rendering

* fix(tui): satisfy transcript clippy lint
2026-05-06 18:09:42 -05:00
Hunter Bown 40ea89f6ce fix(tui): show tiny footer costs (#913) 2026-05-06 18:08:13 -05:00
Hunter Bown bea917a034 fix(tui): smooth footer wave animation
## Summary
- replace the footer spacer crest hops with a full-width phase-shifted wave
- update footer animation tests to assert repaint-cadence movement and multiple wave heights

## Test plan
- cargo fmt --all -- --check
- git diff --check
- cargo test -p deepseek-tui working_strip --all-features
- cargo test -p deepseek-tui footer --all-features
- PR CI: lint, Ubuntu/macOS/Windows tests, npm wrapper smoke, version drift, GitGuardian
2026-05-06 17:47:06 -05:00
YuanSheng Wang 8cf3745cd6 feat(tui): render markdown tables with borders
## Summary
- render markdown table groups with top, middle, and bottom box-drawing borders
- preserve separator rows as table structure instead of dropping them
- update markdown rendering tests for bordered tables

## Test plan
- cargo fmt --all -- --check
- git diff --check
- cargo test -p deepseek-tui table --all-features
2026-05-06 17:39:35 -05:00
Hunter Bown b59012e765 fix(tui): forward resize dimensions to ratatui viewport
@imakid reported on Windows PowerShell that clicking the OS restore
button (maximize → windowed) during a long task turns the entire
terminal black, unrecoverable until Ctrl+C. The "refreshing context"
chip in the footer indicates the freeze coincides with a compaction
summary call (engine state `CoherenceState::RefreshingContext`).

Hypothesis (no Windows dev box, awaiting @imakid confirmation):

* Symptom 1 — "transcript stops refreshing" — is the expected
  no-stream window during the side-channel compaction summary call.
  Tokens don't stream until the summary returns and the next assistant
  turn resumes. That's not a bug, but the UI doesn't currently surface
  the distinction well.

* Symptom 2 — "black screen on restore-from-maximized" — most likely
  comes from a Windows ConHost transient: `crossterm::terminal::size()`
  briefly returns stale (maximized) dimensions during the
  maximize→windowed transition, while the `Event::Resize(w, h)`
  payload itself already carries the correct post-restore size. The
  current handler does `terminal.clear() + terminal.draw()` and
  relies on ratatui's internal autoresize, which calls
  `crossterm::terminal::size()` — meaning we paint a frame sized to
  the stale dimensions into the post-restore viewport, leaving most
  of the visible area unpainted (the user-reported black screen).

The change forwards the event-reported `(w, h)` to ratatui via
`Terminal::resize(Rect)` before the clear+draw, so the viewport
commit always uses the OS-truthful new size regardless of whether
`crossterm::terminal::size()` has caught up. This is a defensive
change everywhere — the event payload is authoritative on every
platform — and it specifically addresses the Windows ConHost stale-
size race.

Also widens the resize tracing event to include `coherence_state`
and `use_alt_screen` so the next user bug report includes the
context we'd ask for in triage.

Tests
=====

`chat_widget_renders_cleanly_after_resize_during_refreshing_context`
pins the renderer-side invariant: a resize cycle that arrives while
`coherence_state == RefreshingContext` must produce non-empty frames
at every cycled width, and must not mutate the engine's
coherence_state. The actual fix lives in the event-handler size
forwarding; the test guards the renderer's no-empty-buffer contract
so a future regression that gates layout on coherence state would be
caught immediately.

What this PR does NOT change
============================

* No platform-specific code path. The fix is universal — passing the
  event-reported size to ratatui is correct everywhere; Windows just
  happens to be where the bug manifests today.
* No change to the freeze symptom directly. If symptom 1 is the
  expected compaction-summary no-stream window, the right
  follow-up is a UX cue ("compacting context, please hold") rather
  than a bugfix.

@imakid — please test by installing this branch:

    cargo install --git https://github.com/Hmbown/DeepSeek-TUI.git \\
        --branch fix/582-powershell-resize

Then run a long task, click the OS restore button mid-task, and
confirm whether the black-screen symptom is gone. If it still
reproduces, please run with `RUST_LOG=deepseek_tui=debug` and post
the resize lines from the log so we can see the dimensions
crossterm/ratatui actually saw.

Verification
============

* `cargo fmt --all -- --check` clean.
* `cargo clippy -p deepseek-tui --bin deepseek-tui --all-features
  --locked -- -D warnings` clean.
* `cargo test -p deepseek-tui --bin deepseek-tui --locked` →
  2029 passed, 2 ignored.

Refs #582.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 17:29:00 -05:00
Hunter Bown b4867b835d fix: smooth streaming and release UX slices
* fix(streaming): drip text grapheme by grapheme

* fix(snapshot): exclude generated artifacts by default

* fix(tui): fill panel and footer backgrounds
2026-05-06 17:23:02 -05:00
Hunter Bown ccb4662c2a fix(auth): recover keyring credentials into config (#909) 2026-05-06 16:59:35 -05:00
Hunter Bown 206e74fe13 Merge pull request #906 from Hmbown/fix/cli-print-error-chain
fix(cli): print full anyhow chain on error exit (#767)
2026-05-06 15:17:46 -05:00
Hunter Bown d70bec6ac5 fix(cli): print full anyhow chain on error exit (#767)
The dispatcher's top-level error handler prints `"error: {err}"`,
which is anyhow's bare Display. anyhow's Display only renders the
top-level context message and drops every cause beneath it. Users hit
"failed to parse config at <path>" with zero hint about the actual
TOML error (line/column, expected token, missing quote, BOM, etc.).

This is the gap reported in #767: the OP got
`error: failed to parse config at C:\Users\y1547\.deepseek\config.toml`
with nothing else, while a separate code path that uses a different
formatter shows a rich `Caused by: TOML parse error at line 1, column
20 ...` chain. Maintainer was unable to triage without the underlying
parse error.

Print the full chain by iterating `err.chain().skip(1)` after the
top-level message. Output for the issue's case becomes:

  error: failed to parse config at C:\Users\y1547\.deepseek\config.toml
    caused by: TOML parse error at line N, column M
      | (snippet from toml-rs)

Tests: regression test pins the chain semantics so a future refactor
of the print path can't silently drop causes again.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-06 15:17:21 -05:00
Hunter Bown 8da5189787 Merge pull request #905 from Hmbown/fix/jetbrains-default-mouse-off
fix(tui): default mouse capture off in JetBrains JediTerm (#878, #898)
2026-05-06 15:13:09 -05:00
Hunter Bown 88c2a06024 fix(tui): default mouse capture off in JetBrains JediTerm (#878, #898)
JetBrains' JediTerm — the terminal embedded in PyCharm, IDEA, CLion,
WebStorm, GoLand, etc. — advertises mouse support but forwards SGR
mouse-event escape sequences as raw input characters rather than
interpreting them. Users see the composer auto-fill with garbled
characters when they move the mouse over the TUI window. The
workaround was already a one-flag fix (`--no-mouse-capture` or
`[tui] mouse_capture = false` in config) but discovering it required
finding a maintainer comment on a related issue.

Auto-detect via `TERMINAL_EMULATOR=JetBrains-JediTerm` (the env var
JediTerm sets) and default `mouse_capture` off for that environment,
mirroring the existing Windows handling. Explicit `--mouse-capture`
or `[tui] mouse_capture = true` still wins, so power users who don't
hit the issue can opt back in.

Implementation:
- `default_mouse_capture_enabled` now takes `terminal_emulator: Option<&str>`
  so the function is pure and trivially testable. The CLI entry point
  reads the env var once and passes it through.
- `should_use_mouse_capture` keeps the same public signature; tests
  call `should_use_mouse_capture_with` which takes the env explicitly,
  removing test sensitivity to the host's actual TERMINAL_EMULATOR.
- Match is `eq_ignore_ascii_case` because JetBrains has occasionally
  varied the casing across releases.

Tests:
- 4 new tests covering JetBrains default-off, case-insensitive match,
  CLI override, and config-file override.
- Existing 6 mouse-capture tests retained, all passing.
- `cargo test -p deepseek-tui --bin deepseek-tui --all-features
  terminal_mode_tests --locked` → 10/10 pass.
- `cargo clippy -p deepseek-tui --bins --all-features --locked --
  -D warnings` clean.
- `cargo fmt --all -- --check` clean.

Docs in `docs/MODES.md` and `docs/CONFIGURATION.md` updated.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-06 15:12:47 -05:00
Hunter Bown 3bb269bbd4 Merge pull request #904 from Hmbown/fix/onboarding-chmod-best-effort
fix(onboarding): make chmod hardening best-effort (#897)
2026-05-06 15:09:22 -05:00
Hunter Bown 7de35dda5b fix(onboarding): make chmod hardening best-effort (#897)
When the onboarding flow writes the API key under `~/.deepseek/`, the
parent-dir and config-file chmod are propagated as hard errors if they
fail. On Docker-on-Windows where the container mounts `$USERPROFILE\
.deepseek` to `/home/deepseek/.deepseek`, the bind-mounted NTFS volume
can't accept Unix chmod, so `set_permissions` returns EPERM and the
user sees `Failed to save API key: Failed to set permissions on
/home/deepseek/.deepseek` — even though the directory and the secret
file were already created successfully.

The chmod is a hardening pass: the dir already lives under the user's
home and the file is created with `O_CREAT | mode(0o600)` via
OpenOptions. On filesystems where Unix permissions don't apply at all
(Docker bind-mount of NTFS, network shares, FAT, certain CI volumes),
the host's native ACL model is doing access control regardless. So
demote the chmod to best-effort on Unix: warn loudly via
`tracing::warn!` for security-sensitive operators who run with
`RUST_LOG=warn`, then continue.

Three sites:
- `config::ensure_parent_dir` — parent-dir 0o700 hardening
- `config::write_config_file_secure` — file 0o600 hardening
- `secrets::FileKeyringStore::store_unlocked` — file 0o600 hardening
  (the parent-dir chmod here was already best-effort via `let _ =`)

Tests:
- `cargo test -p deepseek-secrets --all-features --locked` → 16/16 pass
  (including `file_store_round_trips_with_secure_perms` which still
  asserts mode 0o600 on a normal Linux test FS)
- `cargo test -p deepseek-tui --bin deepseek-tui --all-features
  save_api_key --locked` → 5/5 pass
- `cargo clippy -p deepseek-tui -p deepseek-secrets --all-features
  --locked -- -D warnings` clean
- `cargo fmt --all -- --check` clean

The GitBash paste failure mode reported in the same issue is a terminal
quirk (GitBash on Windows doesn't reliably forward Ctrl+V to TUI apps);
PowerShell + Shift+Insert work, as the reporter discovered. Not in
scope here.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-06 15:08:56 -05:00
Hunter Bown c277100e3b Merge pull request #903 from Hmbown/fix/global-claude-skills-dir
feat(skills): discover global ~/.claude/skills (#902)
2026-05-06 15:01:27 -05:00
Hunter Bown 58f52c7725 feat(skills): discover global ~/.claude/skills (#902)
The skill registry already walks workspace-local `.claude/skills` for
Claude Code interop, plus global `~/.agents/skills` and
`~/.deepseek/skills`. Picking up the global `~/.claude/skills` brings
DeepSeek TUI in line with the broader Claude-ecosystem convention so
users can inherit skills installed for other Claude-compatible tools
without re-authoring them in DeepSeek's native layout.

Adds `claude_global_skills_dir()` mirroring `agents_global_skills_dir()`
and inserts it into `skills_directories()` between the agentskills.io
global and the DeepSeek-native global. Workspace candidates still win
on name conflicts; first-match-wins is preserved.

Tests:
- claude_global_skills_dir_returns_home_relative_path
- existing_skill_dirs_orders_globals_agents_then_claude_then_deepseek
- All 55 pre-existing skills tests still pass

Docs synced (README publishing-skills section, CONFIGURATION).
docs/COMPETITIVE_ANALYSIS.md already advertised this lookup; this
brings the implementation in line with the documented contract.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-06 15:00:51 -05:00
Hunter Bown bf609465c1 Merge pull request #901 from y0sif/feat/parent-resume-on-subagent-complete
fix(engine): wake parent turn loop on sub-agent completion (#756)
2026-05-06 14:56:32 -05:00
Hunter Bown c068a0a619 Merge pull request #895 from Hmbown/release/v0.8.15-prep
chore(release): prepare v0.8.15
2026-05-06 11:18:41 -05:00
y0sif cae4ca3c0f fix(engine): wake parent turn loop on sub-agent completion (#756)
The parent agent's turn ends right after `agent_spawn` returns
`status: Running`, leaving children to finish in the background with no
path back into the parent's inference loop. The model has to be poked
by a human before it resumes the plan.

Wire a wakeup channel from `run_subagent_task` into the engine's turn
loop. When the model produces no more tool calls but direct children
are still running, the loop now blocks on the next completion (with
cancel and steer escape hatches), drains all pending sentinels, and
re-enters inference with the existing `<deepseek:subagent.done>`
elements injected as user messages. This fulfils the contract already
documented in `prompts/base.md` (lines 189-205): the parent is promised
it'll see the sentinel when a child finishes.

The async `agent_spawn` semantics from #239 are preserved — only direct
children fire on the channel (gated by `spawn_depth == 1`), so
grandchildren spawned recursively don't flood the parent.
2026-05-06 19:14:27 +03:00
Hunter Bown 1043374e6a chore(release): prepare v0.8.15 2026-05-06 11:06:00 -05:00
Hunter Bown bf8fd3e452 Merge pull request #893 from Hmbown/codex/fix-865-current-date-meta
fix(engine): include current date in turn metadata
2026-05-06 11:00:32 -05:00
Hunter Bown 141db1442a Merge pull request #892 from Hmbown/codex/fix-env-key-auth-runtime
fix(auth): explain env-only key failures in runtime
2026-05-06 11:00:15 -05:00
Hunter Bown 41deddf912 Merge pull request #887 from Hmbown/codex/fix-872-windows-utf8
fix(tui): set Windows console to UTF-8
2026-05-06 11:00:04 -05:00
Hunter Bown a20589325f fix(engine): include current date in turn metadata 2026-05-06 10:52:08 -05:00
Hunter Bown a989617269 fix(tui): set Windows console to UTF-8 2026-05-06 10:50:46 -05:00
Hunter Bown 8f4d4874cd fix(auth): explain env-only key failures in runtime 2026-05-06 10:49:54 -05:00
Hunter Bown 6a9c0c5022 Merge pull request #890 from Hmbown/codex/fix-settings-env-test-race
test(settings): serialize TUI prefs path env test
2026-05-06 10:49:08 -05:00
Hunter Bown ebc0da3374 test(settings): serialize tui prefs path env test 2026-05-06 10:40:59 -05:00
Hunter Bown b60568dfc0 fix(cli): keep Windows resume picker in dispatcher
fix(cli): keep Windows resume picker in dispatcher
2026-05-06 10:27:24 -05:00
Reid 93cfb83a67 fix(tui): persist workspace trust in global config
fix(tui): persist workspace trust in global config
2026-05-06 10:24:55 -05:00
GK012 9a7cd9f937 fix(npm): add --version fallback in wrapper
fix(npm): add --version fallback in wrapper
2026-05-06 10:19:05 -05:00
Hunter Bown 7def57203f fix(tui): stop stealing Ctrl+E from composer
fix(tui): stop stealing Ctrl+E from composer
2026-05-06 10:13:00 -05:00
junskyeed d4185ede5a fix(engine): cap API request max_tokens
fix(engine): cap API request max_tokens without affecting internal context budget
2026-05-06 09:59:22 -05:00
xieshutao 686393dae3 fix(skills): accept plain markdown SKILL files (#869)
Accepts SKILL.md files without YAML frontmatter by using the first Markdown H1 heading as the skill name. This lets compatible plain Markdown skill files show up instead of being skipped with parse warnings.\n\nI added a small maintainer test commit to keep the command tests hermetic and cover both the plain-heading fallback and missing-heading warning path.\n\nVerification:\n- cargo test -p deepseek-tui skills --all-features\n- cargo fmt --all -- --check\n- git diff --check xieshutao/main...HEAD\n- cargo clippy -p deepseek-tui --all-targets --all-features -- -D warnings\n- GitGuardian Security Checks passed
2026-05-06 09:44:34 -05:00