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.
Update all three READMEs (en, zh-CN, ja-JP) to use the canonical
~/.codewhale paths for config, skills, and Docker volume mounts, with
legacy ~/.deepseek noted as a compatibility fallback. The state-root
migration has been underway since v0.8.44 — the docs now reflect it.
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).
Add entries for deadlock fix (#1856), composer text selection (#2228),
and project context loading tracing (#2227). Add community credits for
@Fire-dtx and @imkingjh999.
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.
The static website/ HTML files were the original codewhale.net surface
before the Next.js app under web/ took over. They have not been deployed
in some time and are now mirrored in the new dedicated site repo
(Hmbown/codewhalesites) only as far as history matters.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the dense 85-line 'What Is It' section with a tight 15-line
version using a three-column table:
- Start with trust — the 'A' preamble
- Clear jurisdiction — Constitution with nine tiers of authority
- Recursive improvement — V4 helps write the harness, loop tightens
All three languages (EN, zh-CN, ja-JP) updated. Contributors preserved.
- 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>