PR #2076 deferred planning/checklist tools (checklist_write, update_plan,
task_create, task_list, task_read) to reduce catalog tokens, but the system
prompt actively instructs the model to use these tools. Without them in the
active catalog, the model cannot call them until it first discovers them via
tool_search, which it is not prompted to do for planning tools.
Keep these tools in DEFAULT_ACTIVE_NATIVE_TOOLS so the model can follow
the Constitution's Regulations (Tier 3) and the Mode: YOLO instructions.
- Replace visible_line_char_ranges with wrap_input_lines_for_mouse for accurate mouse selection
- Clamp selection_anchor and cursor_position to char_count
- Clear selection on history navigation to prevent stale highlights
- Add test for history-navigation-clears-stale-selection
- Use OwnedRwLockReadGuard for parallel-safe tools, OwnedRwLockWriteGuard for serial
- Add TOOL_EXECUTION_LOCK_HELD task-local for reentrancy detection
- Add BlockingHandler test harness and parallel-vs-serial concurrency tests
- Line-wrap long function signatures and format arguments
- Fix bracket placement for early returns (consistent style)
- Use [!] instead of [✓] for network-denied skill sync
- Fix copy-selection ordering: clear after success, not always
Harvested and vetted — no malware, no external deps, no injection:
- #1859 (@harvey2011888): loop guard now reports Failed on halt
- #1870 (@victorcheng2333): honour DEEPSEEK_YOLO env on startup
- #1935 (@IIzzaya): replace [x] with [✓] completion markers
- #1837 (@PurplePulse): fix macOS title centering (pin to top)
- #1967 (@cyq1017): show base_url in /config view
- #1906 (@knqiufan): copy transcript without visual-wrap newlines
Also fix cycle_manager archive_dir_for to use resolve_state_dir
so recall_archive tests pass with the migrated sessions path.
Co-authored-by: victorcheng2333 <victorcheng2333@users.noreply.github.com>
Co-authored-by: IIzzaya <IIzzaya@users.noreply.github.com>
Co-authored-by: PurplePulse <PurplePulse@users.noreply.github.com>
Co-authored-by: cyq1017 <cyq1017@users.noreply.github.com>
Co-authored-by: knqiufan <knqiufan@users.noreply.github.com>
- Add CODEWHALE_RELEASE_BASE_URL as canonical env override for release
asset base URL (DEEPSEEK_TUI_RELEASE_BASE_URL and DEEPSEEK_RELEASE_BASE_URL
remain as legacy fallbacks).
- Add CODEWHALE_USE_CNB_MIRROR env var to auto-select the CNB (cnb.cool)
mirror for binary downloads, avoiding GitHub Releases timeouts in China.
- Update npm install scripts (artifacts.js) with the same env checks.
- Update Rust self-updater (update.rs) with new constants and env cascade.
Fixes#2222.
The /save command now writes to ~/.codewhale/sessions (or legacy
~/.deepseek/sessions) instead of the workspace root. Update the test
to set CODEWHALE_HOME to a temp directory and pre-create the sessions
subdirectory so resolve_state_dir picks the primary path.
Fixes the first failing test in #2223.
Steered/queued user messages were being inserted into app.history
before the active cell (holding streaming thinking/tool content) was
flushed, causing the user's message to render above (before) the
thinking block that chronologically preceded it.
Now call app.flush_active_cell() before app.add_message() in
steer_user_message(), matching the pattern used in MessageStarted
and MessageDelta handlers.
Fixes#2225.
- Add resolve_project_state_dir and ensure_project_state_dir to
codewhale-config, providing project-local .codewhale/.deepseek
resolution matching the home-directory pattern.
- Migrate snapshot paths to prefer ~/.codewhale/snapshots with
~/.deepseek/snapshots fallback (snapshot_base_with_home).
- Migrate skill_state.rs to use codewhale_config::ensure_state_dir
instead of hardcoded home.join(".deepseek").
- Update doc comments to reference canonical .codewhale paths.
Part of #2231 (state-root migration).
Emit a tracing::info! line with the file path and byte size when a
project context file (AGENTS.md, CLAUDE.md, etc.) is successfully loaded.
This helps users and maintainers verify which file was used during
prompt assembly, addressing the confusion reported in #2227.
Add mouse drag selection and Shift+Arrow text selection in the composer
input box. Ctrl+C copies selected text; Ctrl+X cuts (or toggles mode if
no selection). Selection highlighting uses the theme's selection_bg color.
Mouse coordinate mapping accounts for wrapping, scroll offset, and padding.
Also fix Home, End, Ctrl+A, and Ctrl+E to clear the selection anchor
before jumping, matching the existing Left/Right behavior. Without these
calls a stale anchor silently reforms a selection and can cause unintended
deletions on the next keystroke.
Harvested from #2228.
Co-authored-by: imkingjh999 <imkingjh999@users.noreply.github.com>
Replace `Arc<RwLock<()>>` in ToolCallRuntime with `Arc<Semaphore>` to
eliminate the risk of a tool re-entering and deadlocking on the same lock.
Parallel tools now acquire then immediately drop the permit, allowing
concurrent execution after any in-flight serial tool finishes. Serial
tools hold the permit for the full duration.
Fixes#2157. Harvested from #1856.
Co-authored-by: Fire-dtx <58944505+Fire-dtx@users.noreply.github.com>
The wlcopy_helper_succeeds_when_binary_returns_zero test used
`true` as a stand-in for wl-copy, but `true` exits immediately
without reading stdin. On Linux CI runners the process exits
before the parent can write to the pipe, producing EPIPE and
failing the is_ok() assertion.
Switch to `cat` which reads stdin until EOF (when the pipe is
closed) and then exits 0, faithfully modelling a successful
wl-copy invocation.
- Sync root and crate CHANGELOG.md for version drift check
- Add community contributor credits to [0.8.46] section
- Remove stray '...' file that broke Windows git checkout
- config/src/lib.rs: remove undefined has_api_key variable (#2062 conflict)
- ui.rs: clone receipt before move into set_receipt_text
- footer_ui.rs: convert &str to String for if/else type consistency
- rlm.rs: use ref bindings to avoid partial moves of stdout/stderr_preview
- file.rs: prefix unused fuzz variable
- update.rs: remove redundant borrows
- tests.rs: allow print_stderr on catalog metrics test function
All clippy warnings resolved. CI should go green.
Issue 1600 asks for full rename UX: set a custom title, remove it back
to `(unnamed)`. The set side already shipped as `deepseek thread
set-name <id> <name>`, but there was no inverse — users who wanted to
drop a no-longer-relevant title had to either edit the SQLite store by
hand or set a placeholder string.
Add `deepseek thread clear-name <id>`, mirroring the existing
`SetName` arm in `run_thread_command`: look up the thread, set
`name = None`, refresh `updated_at`, upsert. Printed confirmation is
`cleared name for <id>` so it stays distinguishable from the
`renamed` line emitted by `set-name`.
Snapshot help test and the parser-matrix test both gain the new
subcommand. No state-store changes: `upsert_thread` already accepts
`name: None` and `thread list` already prints `(unnamed)` when the
field is empty, so the round-trip is complete with this CLI-only
change.
Co-authored-by: Claude <noreply@anthropic.com>
portable-pty 0.8.1 depends on nix 0.25.1, which lacks loongarch64 in
its ioctl cfg blocks, causing a build failure on LoongArch64 Linux.
portable-pty 0.9.0 depends on nix ^0.28, which fully supports
loongarch64. The public API surface used by CodeWhale is unchanged.
Closes#1945
The `effective_max_output_tokens` heuristic defaults to 64K for any model
not in the known-context-window table. This is fine for DeepSeek's hosted
API (1M context) but causes immediate HTTP 400s on self-hosted providers
with tight `max-model-len`.
Example: vLLM serving Qwen3.6 with `--max-model-len 65536` rejects
requests because 64000 (output) + ~1500 (input) exceeds the limit by 1
token.
This change lets the operator set `DEEPSEEK_MAX_OUTPUT_TOKENS=16384` (or
whatever fits their deployment) to override the heuristic. The env var
takes precedence over the model-table lookup when set to a positive
integer; otherwise the existing behavior is preserved.
No new config struct field — env-only override keeps the public API
unchanged. Useful for embedded users (e.g. pinvou3) who need to control
output budget without forking the engine config schema.
Co-authored-by: hexin <he.xin@h3c.com>
* feat: session token breakdown in footer and /status
Add accumulated session token tracking with input / cache-hit / output
breakdown. Rebased from PR #1666 onto post-rebrand main (v0.8.45).
Changes:
- SessionState: new total_input_tokens, total_cache_hit_tokens,
total_cache_miss_tokens, total_output_tokens fields
- Turn outcome handler: accumulate per-turn token breakdown
- StatusItem::Tokens: new footer chip, enabled by default
- Footer chip: "12K in · 8.1K cch · 2.5K out" format
- /status: expanded with session input/cache/output rows
- /clear and /load: reset accumulated breakdown
* fix: address review feedback — current_session_id, cache guarding, DRY helper
- Restore app.current_session_id assignment accidentally dropped in
apply_loaded_session during rebase (P1: breaks startup-resume and
session-sync paths)
- Guard cache-hit/miss accumulation behind is_some() so providers
that omit cache telemetry don't inflate miss totals
- Extract SessionState::reset_token_breakdown() to avoid duplicating
the four-field reset in core/session/ui call sites
- Hide the "cch" segment from the footer token chip when no cache
data has been recorded
- Show "not reported" in /status session-cache row instead of
"0 hit / 0 miss" when no cache telemetry is available
Adds Metaso AI Search as a new SearchProvider option alongside Bing,
DuckDuckGo, Tavily, and Bocha.
Co-authored-by: Zhao Xiaohong <zhaoxiaohong@metasota.ai>
grep_files runs its directory walk and per-file regex synchronously inside
the async execute(). On a large tree this pins the runtime worker for
minutes, so the turn loop can't observe the cancel token and the stop
button stays unresponsive — the same failure file_search fixed in #2035.
Mirror that fix: move the blocking walk onto spawn_blocking, bounded by a
30s hard timeout with a biased select on the cancel token, via a
run_blocking_grep helper that parallels run_blocking_file_search. Output
and the existing per-file/per-line cancel checks are unchanged.
Co-authored-by: hexin <he.xin@h3c.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(paste): preserve Enter suppression window after non-char keys during paste
* chore(paste): add debug_assert for buffer precondition in deactivate_keep_window
Documents the invariant that buffer must be flushed before calling deactivate_keep_window. The assert fires in debug builds only, catching future misuse without masking upstream bugs.
When the workspace is the user's home directory, the project-scope
config file (~/.deepseek/config.toml) is also the global config file.
Skip the merge to avoid redundant processing and a misleading
"project-scope config key ignored" warning on every launch from ~.
Fixes the home-directory false-positive in the #417 deny-list
check: the deny-list correctly refuses dangerous keys at project
scope, but when cwd == $HOME the project file *is* the global file
so the warning is noise.
Three interrelated feedback issues resolved:
1. Windows desktop notifications (notifications.rs)
- resolve_method() now returns Method::Bel on Windows instead of
Method::Off, so windows_bell() (MessageBeep) fires a system
notification sound when a long turn completes.
2. Tool output summary truncation (history.rs)
- TOOL_TEXT_LIMIT increased from 180 to 300 characters, reducing
the chance that meaningful tool output is cut short in the
one-line summary shown in tool cards.
3. Turn completion status visibility (ui.rs)
- Added a push_status_toast(Info, 10s TTL) call alongside the
existing set_receipt_text() in the TurnComplete handler. The
receipt text is now visible in both the composer border (8s)
and the footer status bar (10s).
4. Footer working-time feedback (footer_ui.rs)
- Footer state label now includes elapsed seconds from
turn_started_at immediately, instead of waiting 30 seconds for
the stall_reason classification to kick in.
- When app.is_loading is true, the label shows elapsed time so
users see ongoing progress during model-loading phases.
* test(settings): handle TERM_PROGRAM env var in no_animations_env_recognises_truthy_spellings_only
Clear and restore TERM_PROGRAM environment variable during tests
to prevent low_motion being forced in vscode, ghostty and Termius.
* test(settings): handle other environment variables that can independently force low_motion in no_animations_env_recognises_truthy_spellings_only
---------
Co-authored-by: hqt <you@example.com>