* fix(web_search): add timeout floor and retry for Volcengine provider
Volcengine's Responses API pipeline (web search + model inference +
JSON generation) can exceed the default 15 s timeout on complex
queries, causing ~50% of requests to fail with transport errors.
Changes:
- Enforce a 60 s minimum timeout for the Volcengine provider
- Separate connect_timeout (15 s) from total request timeout
- Retry transient transport errors up to 3 times (1 s / 2 s backoff)
- Add TCP keepalive, HTTP/2 keepalive, and User-Agent headers
matching the patterns used in client.rs
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: raise Volcengine timeout floor to 90 s
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: correct stale comment — floor is 90 s, not 60 s
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(web_search): tighten Volcengine retry semantics
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Hunter B <hmbown@gmail.com>
* ci: add clippy and docs checks to PR CI workflow
- Add 'cargo clippy --workspace --all-features --locked -- -D warnings' step
to the lint job (previously only ran in release.yml)
- Enable docs job on all triggers (push/PR), not just weekly schedule
to catch broken doc links before merge
- Add clippy component to rust-toolchain setup
* ci: revert docs job to schedule-only (pre-existing broken links in tui crate)
* ci: install Linux deps before clippy
---------
Co-authored-by: Hu Qiantao <huqiantao@HudeMacBook-Air.local>
Co-authored-by: Hunter B <hmbown@gmail.com>
Add a dedicated GitHub Actions workflow for the Next.js web frontend
that runs on changes to the web/ directory:
- ESLint checks via 'npm run lint'
- TypeScript type checking via 'tsc --noEmit'
- Runs on push to main and PRs targeting main
- Uses npm cache for faster dependency installation
Co-authored-by: Hu Qiantao <huqiantao@HudeMacBook-Air.local>
* refactor(palette): remove unused backward-compat aliases and add module docs
- Remove DEEPSEEK_AQUA_RGB, DEEPSEEK_NAVY_RGB, DEEPSEEK_AQUA, DEEPSEEK_NAVY
(unused backward-compatible aliases with no references in production code)
- Add module-level doc comment explaining the three-layer palette organization:
RGB tuples, semantic Color constants, and backward-compat aliases
- Note that some constants are kept for design-system completeness
* fix: remove deprecated color audit test (DEEPSEEK_AQUA no longer exists)
* fix: remove unused import in palette_audit test
---------
Co-authored-by: Hu Qiantao <huqiantao@HudeMacBook-Air.local>
* fix: use effective_model_for_budget instead of raw model in compaction_config
When model is set to 'auto', self.model holds the literal string 'auto',
which gets passed to the API as the model name in compaction requests.
DeepSeek's API rejects 'auto' with HTTP 400 since it's not a recognized
model ID.
effective_model_for_budget() resolves 'auto' to the last effective model
or falls back to DEFAULT_TEXT_MODEL, ensuring compaction always sends a
concrete model name.
* test(tui): cover auto model compaction config
---------
Co-authored-by: codgo <anbiaoren@gie777.com>
Co-authored-by: Hunter B <hmbown@gmail.com>
* docs(secrets): add doc comments to all public types
* docs(protocol): add doc comments to all public types
* style(protocol): run rustfmt on docs
---------
Co-authored-by: Hu Qiantao <huqiantao@HudeMacBook-Air.local>
Co-authored-by: Hunter B <hmbown@gmail.com>
* docs(hooks): add doc comments to all public types
* docs(hooks): clarify sink error handling
---------
Co-authored-by: Hu Qiantao <huqiantao@HudeMacBook-Air.local>
Co-authored-by: Hunter B <hmbown@gmail.com>
Add doc comments to all public types in the tui-core crate:
- Pane enum and all 6 variants
- UiEvent enum and all 13 variants
- UiEffect enum and all 4 variants
- UiState struct and all 8 fields
- UiState::reduce and UiState::snapshot methods
Co-authored-by: Hu Qiantao <huqiantao@HudeMacBook-Air.local>
* test(web): add unit tests for pure helper functions
Add vitest configuration and tests for:
- relativeTime: time formatting (just now, minutes, hours, days, months, years)
- lastPageFromLink: GitHub Link header pagination parsing
These are the first tests for the web frontend. The test framework
(vitest) was already in package.json but had no config or test files.
* test(web): exercise real GitHub helpers
---------
Co-authored-by: Hu Qiantao <huqiantao@HudeMacBook-Air.local>
Co-authored-by: Hunter B <hmbown@gmail.com>
* refactor(tools): replace manual Display impl with thiserror derive
Replace the hand-rolled Display implementation for ToolError with
thiserror derive macros. The thiserror crate is already a workspace
dependency. Error messages remain identical (verified by existing
test tool_error_display_matches_legacy_text).
This reduces boilerplate and ensures consistency with other error
types in the codebase (secrets, state crates already use thiserror).
* chore: add thiserror to Cargo.lock
---------
Co-authored-by: Hu Qiantao <huqiantao@HudeMacBook-Air.local>
* docs(core): add doc comments to all public types
Add doc comments to all public types in the core crate:
- InitialHistory enum and variants
- NewThread struct and fields
- JobStatus enum and variants
- JobRetryMetadata struct and fields
- JobHistoryEntry struct and fields
- JobRecord struct and fields
- JobManager struct
- ThreadManager struct
- Runtime struct
* docs(core): add doc comments to all public types
---------
Co-authored-by: Hu Qiantao <huqiantao@HudeMacBook-Air.local>
Add doc comments to all public structs, enums, traits, and methods:
- McpServerConfig, ToolFilter, McpServerDefinition
- McpStartupStatus, McpStartupUpdateEvent, McpStartupFailure, McpStartupCompleteEvent
- McpToolDescriptor, McpResourceDescriptor
- McpManagedClient trait and all its methods
- InMemoryMcpClient and its builder methods
- McpManager and all its public methods
- run_stdio_server function
Co-authored-by: Hu Qiantao <huqiantao@HudeMacBook-Air.local>
Harvests the UnixSocketHookSink work from #2333 while moving app-server socket configuration to the separate [hook_sinks] table, requiring an explicit socket path, and adding regression coverage for macOS-safe socket paths and lifecycle [hooks] preservation.
Prevent inline skill slash completions from opening while editing arguments for an existing slash command.
This keeps `/attach /path/to/image.png` usable without showing skill entries after the path slash, while
preserving inline skill completions in normal message text.
Adds a regression test for `/attach /`.
Hardens the tool override path from #2420 so a broken replacement override cannot silently fall through to the original built-in tool.
Validation:
- git diff --check
- CARGO_TARGET_DIR=/Volumes/VIXinSSD/codewhale-target/fix-plugin-override cargo test -p codewhale-tui tools::registry --all-features
- CARGO_TARGET_DIR=/Volumes/VIXinSSD/codewhale-target/fix-plugin-override cargo test -p codewhale-tui tools::plugin --all-features
Add Volcengine (火山引擎) as a new SearchProvider in web_search tool.
Uses Volcengine's Responses API with `tools: [{type: "web_search"}]`
and strict JSON prompt constraints to extract structured search results.
- Free tier: 20K queries/month per API key
- API key resolution: [search] api_key → VOLCENGINE_API_KEY →
VOLCENGINE_ARK_API_KEY → ARK_API_KEY env vars
- Select via `DEEPSEEK_SEARCH_PROVIDER=volcengine` or
`[search] provider = "volcengine"` in config.toml
Co-authored-by: Cursor <cursoragent@cursor.com>
Supersedes #2224.
Updates the transitive web lockfile entry for `qs` from 6.15.1 to 6.15.2 while keeping the current-main diff limited to the `node_modules/qs` metadata.
Validation:
- git diff --check
- npm --prefix web ci --ignore-scripts
- npm --prefix web run lint
Harvested from #2391 with thanks to @wplll.
Tracks a cache warmup key across provider, model, base URL, static prefix, tool catalog, project pack, and skills hashes; records base URL and tool catalog from completed turns; reports whether /cache inspect still matches the last warmup key; and computes the warmup key from the actual warmup request sent to the provider.
Validation:
- cargo fmt --all -- --check
- git diff --check
- CARGO_TARGET_DIR=/Volumes/VIXinSSD/codewhale-target/harvest-2391-rebase cargo test -p codewhale-tui warmup_status --all-features
- CARGO_TARGET_DIR=/Volumes/VIXinSSD/codewhale-target/harvest-2391-rebase cargo test -p codewhale-tui cache_inspect --all-features
Harvested from #2390 with thanks to @wplll.
Records the actual tool catalog used by the last model request, reports that catalog in /cache inspect JSON and text output, and includes review hardening for stale catalog clearing, JSON/verbose flag handling, and CJK-aware token estimates.
Validation:
- cargo fmt --all -- --check
- CARGO_TARGET_DIR=/Volumes/VIXinSSD/codewhale-target/harvest-2390 cargo test -p codewhale-tui cache_inspect --all-features
Harvested from #2377 with thanks to @buko.
Threads the parent MCP tool pool into child SubAgentRuntime construction and registers MCP-backed tools for child agents when MCP is enabled, while leaving the broader mention-browser/provider/config work for focused follow-ups.
Validation:
- cargo fmt --all -- --check
- CARGO_TARGET_DIR=/Volumes/VIXinSSD/codewhale-pr2377-target cargo test -p codewhale-tui tools::subagent
- CARGO_TARGET_DIR=/Volumes/VIXinSSD/codewhale-target/harvest-2377-recheck cargo test -p codewhale-tui tools::subagent --all-features
Harvested from #2343 with thanks to @lucaszhu-hue.
Registers AtlasCloud static model rows for Pro and Flash resolution, adds provider-hinted alias coverage, and updates neutral provider docs and env examples while leaving promotional assets/copy out.
Harvested from #2393 with thanks to @wplll.
Strengthens the tool-result dedup regression coverage by exercising repeated medium-sized outputs that are above the dedup threshold but below the truncation budget.
Harvested from #2392 with thanks to @wplll.
Makes project context pack path ordering deterministic across Unix and Windows-style separators while keeping README/config/source entries prioritized before general directory noise.
Harvested from #2402 with thanks to @axobase001.
Keeps `allow_shell` guidance visible for gated shell tools even when missing-tool suggestions exist, removes the nonexistent task_shell_cancel matcher, and broadens regression coverage.
Partially addresses #2328.
Harvested from #2415 with thanks to @axobase001.
Keeps the denser mobile QR renderer and replaces the fixed binding-warning sleep with health polling plus an explicit timeout failure path, so slow starts fail with the useful cause instead of drifting into misleading assertions.
Follow-up to #2403.
Harvested from #2408 with thanks to @axobase001.
Adds regression coverage proving tty:true shell commands receive a controlling terminal, with a longer wait margin so the test is stable on slower CI hosts.
Partially addresses #2372.
Harvested from #2405 with thanks to @axobase001.\n\nCompacts the statusline token chip to use the short label while preserving the existing token detail and adding focused coverage for the rendered label.\n\nPartially addresses #2309.