Commit Graph

1615 Commits

Author SHA1 Message Date
Hunter Bown 9540af268f fix(tests): update save-default-path test for managed sessions dir
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.
2026-05-26 13:45:18 -05:00
Hunter Bown b9596a9640 fix(tui): flush active cell before inserting steer message in transcript
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.
2026-05-26 13:39:57 -05:00
Hunter Bown 0251b4e8e8 refactor: migrate snapshot and skill_state paths to ~/.codewhale
- 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).
2026-05-26 13:39:01 -05:00
Hunter Bown 1893f797fb docs: update CHANGELOG for v0.8.47 work
Add entries for deadlock fix (#1856), composer text selection (#2228),
and project context loading tracing (#2227). Add community credits for
@Fire-dtx and @imkingjh999.
2026-05-26 13:25:55 -05:00
Hunter Bown a554aa9603 feat(project-context): add tracing log when context file is loaded
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.
2026-05-26 13:20:25 -05:00
Hunter Bown 84463711b4 feat(composer): mouse + keyboard text selection with copy/cut
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>
2026-05-26 13:14:55 -05:00
Hunter Bown a06bbe57a6 fix(tools): replace cross-await RwLock with Semaphore to prevent deadlock
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>
2026-05-26 13:09:48 -05:00
Hunter Bown aa83446d6b fix(tests): use cat instead of true in wlcopy test to avoid EPIPE
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.
2026-05-26 12:23:49 -05:00
Hunter Bown e5e34d4063 fix: resolve clippy warnings for Rust 1.95 — vec_init_then_push, unnecessary_map_or 2026-05-26 12:13:30 -05:00
Hunter Bown e59925f8f1 chore: finalize v0.8.46 release — docs refresh, web branding, redirect worker
- Update all three READMEs with binary-pair install instructions
- Update INSTALL.md for platform archive + binary pair language
- Regenerate facts.generated.ts for v0.8.46 (14 crates, 70 tools)
- Rename CF worker project to codewhale-web, add codewhale.net routes
- Add web/redirect worker for deepseek-tui.com → codewhale.net
2026-05-26 12:06:31 -05:00
Hunter Bown 117c7071b5 Merge branch 'release/v0.8.46' 2026-05-26 12:00:08 -05:00
Hunter Bown 2ef1c3666f chore: bump release lane to 0.8.46 2026-05-26 11:52:48 -05:00
Hunter Bown 586f3f325e test: align windows notification fallback 2026-05-26 11:32:31 -05:00
Hunter Bown 003a81d37d test: align macos CI assertions 2026-05-26 11:21:18 -05:00
Hunter Bown 4426d38d65 chore: remove unused website/ — superseded by Next.js app
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>
2026-05-26 11:16:19 -05:00
Hunter Bown 5774c7d2e2 fix: restore project config guardrails 2026-05-26 11:13:38 -05:00
Hunter Bown 3d8a6cffc5 fix: unblock Windows checkout and version drift 2026-05-26 11:05:55 -05:00
Hunter Bown 39ad3f5527 docs: condense README narrative — shorter, focused on trust/jurisdiction/recursion
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.
2026-05-26 11:02:43 -05:00
Hunter Bown a0ab16a814 fix: sync CHANGELOGs, add v0.8.46 community credits, remove invalid '...' file
- 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
2026-05-26 10:54:19 -05:00
Hunter Bown 34ee957e5e style: fix rustfmt issues from community PR merges 2026-05-26 10:52:13 -05:00
Hunter Bown 1d9917d3f2 fix: resolve compilation errors and clippy warnings from community PR merges
- 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.
2026-05-26 10:50:16 -05:00
Ben Younes 73085e6e69 feat(cli): add thread clear-name to remove a custom thread title (1600) (#1939)
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>
2026-05-26 10:38:31 -05:00
kunpeng-ai-lab c97c3a7a04 Summarize Cargo failures in tool metadata (#1973)
* Summarize cargo failures in tool metadata

* fix: preserve shell summaries for cargo failures

---------

Co-authored-by: Codex <codex@local>
2026-05-26 10:38:27 -05:00
kunpeng-ai-lab 16728360f1 Expose apply_patch preflight metadata (#1971)
* Expose apply_patch preflight metadata

* test: harden apply_patch preflight metadata

---------

Co-authored-by: Codex <codex@local>
2026-05-26 10:38:23 -05:00
Quentin Lian dca48545df fix(tui): upgrade portable-pty to 0.9 for LoongArch64 support (#1992)
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
2026-05-26 10:38:17 -05:00
Shen Bowen b6afb4c030 refactor: extract file-tree key handling into key_actions module (#2042)
* refactor: extract file-tree key handling into key_actions module

* refactor: simplify file_tree_key with early Esc return and let-else binding

* fix: address review comments on file-tree key_actions refactor

Restore file_tree_visible guard, remove stale KeyActionResult docs, unify format string style.
2026-05-26 10:38:12 -05:00
New2Niu d1b5cf6f1c feat: fuzzy command (#2043)
Co-authored-by: lei <liulei@8531.cn>
2026-05-26 10:38:07 -05:00
Hunter Bown 3e09e1c77b docs: add v0.8.46 contributors to all three READMEs 2026-05-26 10:37:26 -05:00
Hunter Bown e2eff3956c docs(install): add macOS Gatekeeper quarantine workaround (#2139)
Harvested from PR #2139 (copilot-swe-agent). README changes skipped
to preserve the narrative harness section.

Co-authored-by: copilot-swe-agent[bot]
2026-05-26 10:32:07 -05:00
Saieswar d3adc6a0f1 docs: add review pipeline documentation closes #2177 (#2178)
* docs: add review pipeline documentation closes #2177

* docs: remove escape characters and update cargo fmt command

* docs: remove locked and warning flags from clippy command based on bot review
2026-05-26 10:31:37 -05:00
hexin 4f3a0c3cfc feat(engine): allow DEEPSEEK_MAX_OUTPUT_TOKENS env override for tight-context providers (#2147)
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>
2026-05-26 10:31:26 -05:00
dongchao 60a3069705 fix(paste): defer large-paste @file consolidation to submit time (#2168) 2026-05-26 10:31:21 -05:00
Justin Gao 0611b86863 feat: session token breakdown in footer and /status (#2152)
* 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
2026-05-26 10:31:15 -05:00
Zhao Xiaohong ee03d1fd80 feat(web): add Metaso as a web search provider (metaso.cn) (#2059)
Adds Metaso AI Search as a new SearchProvider option alongside Bing,
DuckDuckGo, Tavily, and Bocha.

Co-authored-by: Zhao Xiaohong <zhaoxiaohong@metasota.ai>
2026-05-26 10:31:09 -05:00
庄表伟 bba5617942 Improve update release channels (#2145)
* Improve update release channels

* Address update channel review feedback

* Prevent beta update downgrades
2026-05-26 10:30:58 -05:00
hexin 795de325d7 fix(grep_files): wrap walk in spawn_blocking + 30s timeout (#2146)
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>
2026-05-26 10:30:52 -05:00
Hanmiao Li 81480ba099 fix: vLLM provider — pass through reasoning_effort, downgrade max to high (#2169) (#2170) 2026-05-26 10:30:47 -05:00
Shen Bowen d107b7468d fix(paste): preserve Enter suppression window after non-char keys during paste (#2174)
* 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.
2026-05-26 10:30:42 -05:00
Sskift 2c12371257 fix(cli): avoid default env overrides for profiles (#2119)
* fix(cli): avoid default env overrides for profiles

* test(cli): lock auth mode profile handoff behavior

* test(cli): restore prompt flag coverage

---------

Co-authored-by: liushiao <liushiao@bytedance.com>
2026-05-26 10:30:36 -05:00
Lellansin Huang e03f7f945d fix(tui): skip project-scope config merge when workspace is home directory (#2055)
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.
2026-05-26 10:30:31 -05:00
PMX b4d1bce58b fix: Homebrew formula downloads legacy shim instead of codewhale dispatcher (#2105)
The formula downloaded deepseek-macos-arm64 (the deprecation shim) as the
main binary.  After the rebranding, deepseek is just a wrapper that spawns
codewhale, but codewhale was never installed — causing "codewhale not
found on PATH" for every Homebrew user.

Now the formula downloads codewhale-* as the primary binary and installs
all four artifacts: codewhale, codewhale-tui, deepseek (legacy shim), and
deepseek-tui (legacy TUI shim).

Closes #2104

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 10:30:25 -05:00
nanookclaw d022d2b293 fix: show search provider in doctor output (#2135)
Signed-off-by: Nanook <nanookclaw@users.noreply.github.com>
Co-authored-by: Nanook <nanookclaw@users.noreply.github.com>
2026-05-26 10:30:20 -05:00
bluth 5e53866cc9 fix(feishu): reply inside thread/topic instead of creating standalone topics (#2148)
When running in a Feishu thread-enabled group (话题群), every bot
response — status messages, approval prompts, streaming progress,
turn results — was sent via the Lark SDK's `create` API which spawns
a new standalone topic.  The user sees a cluttered group with orphan
topics for each intermediate bot message.

Root cause: `sendText()` only called `client.im.message.create()`
with a bare `chat_id`, never passing any reply context.  The Feishu
`reply` API was completely unused.

Fix (two changes, one site each):

1. **lib.mjs — incomingIdentity()**: expose `parentId`, `rootId`,
   `threadId` from the raw Feishu message event so callers can
   determine thread context.  (Not consumed directly yet, but
   available for future use.)

2. **index.mjs**:
   - `handleIncomingMessage()`: store the latest incoming
     `messageId` as `replyToMessageId` in the per-chat thread store.
   - `sendText()`: look up `replyToMessageId` from the thread store;
     when present, call `client.im.message.reply()` instead of
     `create()`.  This keeps ALL bot responses nested under the
     original user message inside the same topic.

No config changes needed.  New chats automatically start using the
reply path; existing chats without a `replyToMessageId` in the store
fall back to the old `create` behaviour.

/ 修复飞书话题群中 bot 消息新建独立话题的问题。所有回复改为使用 reply API
/ 在原话题内嵌套回复,而非通过 create API 创建新话题。
2026-05-26 10:29:08 -05:00
dongchao 5fcb399a38 fix(rlm): route large stdout/stderr via var_handle instead of inlining (#2163) 2026-05-26 10:29:03 -05:00
dongchao 87f7f05fee fix: improve user feedback during long operations and on turn completion (#2166)
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.
2026-05-26 10:28:58 -05:00
Paulo Aboim Pinto cd357de0c8 feat: QoL — taskbar progress, animated title spinner, and configurable completion sound (#1871) 2026-05-26 10:28:21 -05:00
Hunter Bown 9f5c552ae1 docs: rewrite harness section — Constitution as jurisdiction, prefix-cache open-book test
Replace the feature-grid format with a narrative that leads with the
core problem the harness solves: conflicting information at scale.
Frame the Constitution as a formal jurisdiction framework (LLM-as-judge),
describe V4's prefix caching as what makes recursive constitutional
reference practical (open-book test, not closed-book), and explain that
the explicit authority structure enables honest failure feedback.

Cut: memory/handoffs (table stakes), /statusline chip (internal),
theme picker, desktop notifications (clutter).
2026-05-26 10:26:54 -05:00
Hunter Bown 99b3d17ddf docs: correct sub-agent event and OS sandboxing claims in all READMEs 2026-05-26 10:11:02 -05:00
dongchao 5fcc460c33 fix(runtime): truncate assistant summary on UTF-8 char boundary to prevent CJK panic (#2167) 2026-05-26 10:10:06 -05:00
dongchao 7c0e242895 fix(edit_file): always retry fuzzy fallback on first search miss (#2154) 2026-05-26 10:10:01 -05:00