Commit Graph

1755 Commits

Author SHA1 Message Date
Ben Gao b8439c16fc fix(runtime): don't clear active_turn in interrupt_turn
Clearing active_turn immediately breaks is_interrupt_requested detection
in monitor_turn, causing turn status to be Completed instead of Interrupted.

Let monitor_turn handle the cleanup after it detects the interrupt flag
and performs full finalization with correct status, usage, and error.
2026-05-30 19:25:23 -07:00
Ben Gao 549ab8a834 fix(runtime): use consistent error handling for user input API
- Change 'not loaded' to 'not found' in submit_user_input and
  cancel_user_input so map_thread_err correctly maps to 404
- Use map_thread_err in submit_user_input API endpoint for
  consistent error response (404 for missing thread, 409 for
  conflict, etc.) instead of always returning 500
2026-05-30 19:25:23 -07:00
Ben Gao 5994a408a2 fix(runtime): remove redundant turn finalization from interrupt_turn
The monitor_turn loop already handles full turn finalization when the
engine shuts down after cancellation, including saving turn status,
usage, error, emitting turn.completed, and clearing active_turn.

Having interrupt_turn also save turn status and emit turn.completed
causes duplicate SSE events and loses usage/error data that
monitor_turn would have captured from TurnComplete.

Keep only the active_turn cleanup so the 409 error is resolved while
monitor_turn remains the single source of truth for turn completion.
2026-05-30 19:25:23 -07:00
Ben Gao af36756e06 feat(runtime): bridge user-input events and API to external GUI clients
Add SSE event forwarding for UserInputRequired, REST endpoint for submitting user input responses, timeout protection for await_user_input, and fix interrupt_turn to clear active_turn immediately.
2026-05-30 19:25:23 -07:00
hexin d7b6c80ec8 fix(fetch_url): optionally trust fake-ip placeholder ranges to avoid SSRF false-positives
The DNS-resolution SSRF guard in `validate_dns_resolved_ip` rejects any
hostname that resolves into a restricted IP range. Under a transparent-proxy
/ TUN setup running in `fake-ip` mode, the local resolver maps *every*
hostname to a reserved placeholder range (commonly `198.18.0.0/15`), so the
guard rejects all outbound `fetch_url` requests even though the proxy will
route them correctly.

Add a narrowly-scoped, opt-in trust list on `NetworkPolicyDecider`:

- `with_trusted_fakeip_cidrs(&["198.18.0.0/15"])` registers IPv4 CIDR ranges
  to treat as benign fake-ip placeholders (default: empty — no behavior
  change unless the embedder configures it).
- `is_trusted_fakeip_addr(ip)` matches only those configured ranges.

`validate_dns_resolved_ip` now allows a resolved IP if it is either in a
configured fake-ip range or the host is on the existing trusted-proxy list.
Real private/loopback/link-local/cloud-metadata IPs match neither and stay
blocked, so this does not widen SSRF exposure for default configurations.
Includes CIDR parsing/containment helpers and a unit test covering the
placeholder-allowed / real-private-blocked / nothing-configured cases.
2026-05-30 19:25:12 -07:00
hexin d31caf40c5 fix(web_search): decode HTML entities in Bing result URLs
Bing wraps every SERP result URL in a `/ck/a?...&u=<base64>` click-tracking
redirect, and in the raw HTML the separators are `&amp;` entities.
normalize_bing_url parsed the href without decoding entities first, so
extract_query_param looked for `u` while the actual key was `amp;u`. The
base64 redirect target was never recovered: every result collapsed to a
`bing.com` root domain, is_likely_spam_results rejected the whole batch,
and Bing — the default backend — returned zero results.

Decode HTML entities before extracting the redirect target. Adds a
regression test.
2026-05-30 19:23:16 -07:00
liushiao a800f7469e fix(tui): clear footer cells before rendering spans 2026-05-30 19:23:13 -07:00
liushiao 95a737b592 fix(tui): clear footer row before rendering statusline 2026-05-30 19:23:13 -07:00
Hunter Bown 0c446bf4c5 fix(tui): pin header to absolute top row with defensive two-pass layout
The header bar was reported to appear vertically centered on macOS
Terminal.app with large blank space above and below. While the existing
Constraint::Min(1) layout with default Flex::Start should place the
header at row 0, some ratatui/flex interactions can produce unexpected
centering on certain terminal sizes.

Restructure the render layout into a defensive two-pass system:
1. First pass: split the terminal into header (Length(1)) + body (Min(1))
   with explicit Flex::Start, pinning the header to the absolute top.
2. Second pass: split the body area for chat, preview, composer, footer.

This guarantees the header is never vertically centered regardless of
ratatui Flex defaults or terminal dimensions.

Fixes #1834
2026-05-30 19:23:09 -07:00
hqt 72798e5b69 fix: upsert_thread will not set current_leaf_id now, clear_messages will also clean current_leaf_id,
update tests
2026-05-30 19:23:07 -07:00
hqt 042b4b2f50 fix: fix sort of list_messages to ASC, use id to sort and use transaction in init, update tests 2026-05-30 19:23:07 -07:00
hqt 7993f97f88 feat(state): add parent_entry_id on the message table for fork support 2026-05-30 19:23:07 -07:00
hexin 3aea6d29a2 feat(prompts): support inline string sources in EngineConfig.instructions
EngineConfig.instructions was Vec<PathBuf>, which forces embedders that
compute instructions at runtime to stage content to a disk file just to
satisfy the path API. That has two awkward side-effects:

1. The disk file looks like editable config but gets overwritten on
   every launch, confusing for users browsing the install dir.
2. Multi-engine setups need per-engine paths to avoid `rehydrate`
   re-reading the wrong session's content across concurrent engines.

Add an `InstructionSource` enum (`File(PathBuf)` / `Inline { name,
content }`) covering both shapes. `render_instructions_block` dispatches:
File sources read disk (original behavior preserved), Inline sources use
the content directly with `name` becoming the `<instructions source=...>`
attribute.

`From<PathBuf> for InstructionSource` is provided so the existing CLI /
runtime call sites upgrade with a single `.into_iter().map(Into::into).
collect()` chain — no behavior change for callers passing paths.

New test `render_instructions_block_handles_inline_source` covers Inline
empty / oversize-truncate / File+Inline mixed-ordering. The 5 existing
`render_instructions_block_*` tests are updated to use `.into()` on
`PathBuf` and continue to assert File-variant behavior.
2026-05-30 19:23:03 -07:00
Paulo Aboim Pinto 568fbe2c54 feat: enforce allowed tools for custom commands 2026-05-30 19:23:00 -07:00
Hunter Bown 2e73634ab0 fix(tui): make sidebar failure clearing order-aware 2026-05-30 19:22:02 -07:00
Hunter Bown da3a0efeef fix(tui): clear stale tool failures from sidebar (#1884)
Deduplicate failures per tool name, clear stale failures when
the same tool succeeds, and cap visible failures at 2 so old
failures don't crowd the sidebar after the task moves on.
2026-05-30 19:22:02 -07:00
lei 88d8ba853a fix: test 2026-05-30 19:21:59 -07:00
lei f889948c0e fix: format 2026-05-30 19:21:59 -07:00
lei 5b0bc68c88 fix: format 2026-05-30 19:21:59 -07:00
lei 0597e5fc00 fix: review 2026-05-30 19:21:59 -07:00
lei 23eac3346e feat: macos display notification 2026-05-30 19:21:59 -07:00
Hunter Bown c206c30693 fix(runtime): preserve session tool detail fields 2026-05-30 19:21:56 -07:00
Ben Gao 53fb8b3150 fix(session): serialize tool_use/tool_result blocks in session detail API 2026-05-30 19:21:56 -07:00
Hanmiao Li 1f569d5a00 fix: address code review — preserve indentation, remove per-line alloc, rename test for accuracy (#2266) 2026-05-30 19:21:52 -07:00
Hanmiao Li 59e31737d0 fix: clean PDF-extracted text to reduce TUI clutter — collapse blank lines, strip NUL, normalize spaces (#2226) 2026-05-30 19:21:52 -07:00
Hunter Bown f077d87970 fix(tui): require uploaded release assets 2026-05-30 19:19:26 -07:00
Hunter Bown b6edd87135 fix(tui): make update hint transient 2026-05-30 19:19:26 -07:00
Hunter Bown 78f8e11952 test(tui): cover terminal theme palette remap 2026-05-30 19:19:23 -07:00
liushiao b370d6f618 refactor(tui): use Magenta + DarkGray for Terminal theme accents
Adopt Gemini code-assist review on PR #1831:

- mode_plan: Yellow -> Magenta. Plan chip now contrasts with
  status_warning (still Yellow) so the two never visually collide
  in the status row.
- status_ready: Reset -> DarkGray. Ready chip now reads as a
  distinct subdued accent instead of blending into body text
  (which also resolves to Reset on this theme).

No surface change otherwise -- backgrounds and body text still use
Color::Reset to inherit the host terminal's color scheme.
2026-05-30 19:19:23 -07:00
liushiao 0ea84dce7d feat(tui): add "Terminal" theme that fully inherits the host terminal's colors
Adds a new selectable theme `terminal` (alongside System / Whale / Whale
Light / Grayscale / Catppuccin / Tokyo Night / Dracula / Gruvbox) that
paints every surface with `Color::Reset` instead of any RGB so the
host terminal's own background, foreground, and palette show through.

The existing `system` theme only chose between two RGB themes (Whale dark
or Whale Light) based on COLORFGBG / macOS appearance — useful, but it
still painted brand-colored RGB surfaces. Users with custom terminal
themes (Solarized, Nord, transparent backgrounds, custom Ghostty/iTerm
schemes) had no way to make the TUI respect their terminal palette.

Implementation:
- New `TERMINAL_UI_THEME` const where every `*_bg` and most text slots
  are `Color::Reset`, and accents (mode_agent/yolo/plan, status_working,
  status_warning) use ANSI named colors so they also inherit the user's
  terminal palette rather than DeepSeek brand RGB.
- `ThemeId::Terminal` plumbed through `from_name` / `name` /
  `display_name` / `tagline` / `ui_theme` / `SELECTABLE_THEMES`, and
  registered in `normalize_theme_name` with aliases `term`,
  `transparent`, `follow-terminal`, `inherit` so existing
  user-friendly config strings just work.
- `theme_remap_active(Terminal) → true` so the existing per-cell remap
  in `ColorCompatBackend` rewrites every hard-coded palette constant
  (`DEEPSEEK_INK`, `DEEPSEEK_SLATE`, `BORDER_COLOR`, `TEXT_BODY`, …) to
  `Color::Reset`. Without this, the many render sites that reach for
  the named palette constants directly would still paint brand RGB.
- `theme_green` / `theme_red` return `Color::Green` / `Color::Red`
  for Terminal so diff "+"/"−" stay green/red but follow the user's
  terminal palette.
- `theme_diff_added_bg` / `theme_diff_deleted_bg` return `Color::Reset`
  for Terminal — diff highlight is conveyed by foreground color only.
- The new theme is the second entry in `SELECTABLE_THEMES` (right after
  System) so it surfaces prominently in the `/theme` picker.

theme_picker tests: the new theme is inserted in row 2 of
`SELECTABLE_THEMES`, which shifts the indices three existing tests
relied on — `arrow_down_previews_next_theme`,
`enter_commits_with_persist_true`, and `digit_jumps_to_row` — so those
expectations are updated to match the new ordering. No production
behavior change in those tests, just index arithmetic.

Default (`theme = "system"`) is unchanged; existing users see no
difference. Users who want full terminal pass-through opt in via
`/theme` or `theme = "terminal"` in settings.toml.
2026-05-30 19:19:23 -07:00
Hunter Bown 95e13155a5 fix(tui): retry composer history atomic writes 2026-05-30 19:19:20 -07:00
Paulo Aboim Pinto e3899091e5 fix(tui): use raw args for cmd payloads 2026-05-30 19:18:38 -07:00
Paulo Aboim Pinto 8104c4789f fix(tui): handle bash on windows separately 2026-05-30 19:18:38 -07:00
Paulo Aboim Pinto 4fb6a2268a fix(tui): tighten shell review followups 2026-05-30 19:18:38 -07:00
Paulo Aboim Pinto 0ca7d3cc9f test(tui): make shell helpers match detected shell 2026-05-30 19:18:38 -07:00
Paulo Aboim Pinto ec643c5054 fix(tui): align shell tests with detected shell 2026-05-30 19:18:38 -07:00
Paulo Aboim Pinto f1afcf316f fix(tui): restore raw mode conditionally 2026-05-30 19:18:38 -07:00
Paulo Aboim Pinto ab95512c8f fix(tui): gate Windows shell detection 2026-05-30 19:18:38 -07:00
Paulo Aboim Pinto 45e7b12583 style(tui): format shell dispatcher stack 2026-05-30 19:18:38 -07:00
Paulo Aboim Pinto 6e5d8ddf01 feat(shell_dispatcher): harden PowerShell detection and add execution logging
- find_exe(): fall back to known install dirs when PATH lookup fails
  (C:\Program Files\PowerShell\7, System32\WindowsPowerShell\v1.0)
- Encoding prefix: use idiomatic [Console]::OutputEncoding for PowerShell
  instead of cmd.exe chcp 65001 >NUL
- Execution logging: write exec via <ShellKind> entries to
  SHELL_DISPATCHER_LOG when set
- System prompt: use ShellDispatcher detection instead of raw $SHELL
  so model knows it has PowerShell and generates native cmdlets
- display_command(): strip PowerShell encoding prefix for display
- Add tests for find_exe PATH + known-dir fallback

Refs #1779
2026-05-30 19:18:38 -07:00
Paulo Aboim Pinto 29625945de feat: add ShellDispatcher for shell-agnostic command execution
Introduces a central shell abstraction that replaces hardcoded
Command::new("cmd") / Command::new("sh") across the execution path.

- Shell detection at startup (pwsh -> powershell -> cmd -> sh)
- Correct quoting per shell (PowerShell uses -NoProfile -Command)
- Scope guards restore crossterm raw mode on all spawn paths (#1690)
- Direct program+args builder for sandbox ExecEnv integration

Files:
- crates/tui/src/shell_dispatcher.rs (new, 12 tests)
- crates/tui/src/main.rs (register module)
- crates/tui/src/eval.rs (exec_shell delegates to dispatcher)
- crates/tui/src/sandbox/mod.rs (CommandSpec::shell uses dispatcher)
- crates/tui/src/tools/shell.rs (raw mode guards on all spawn paths)

Closes #1690
Refs #1779
2026-05-30 19:18:38 -07:00
reidliu41 e32bd1af6d feat(update): add check-only release diagnostics
Add `codewhale update --check` so users can compare the installed version with
  the latest release without downloading or replacing binaries.

  Surface the same release check in `codewhale doctor`, and share release lookup,
  mirror handling, timeout, and version comparison logic between update and doctor.
2026-05-30 19:18:34 -07:00
LING71671 56d62edad4 fix(prompt): make tool taxonomy mode-aware 2026-05-30 19:18:31 -07:00
LING71671 a8c2728f54 feat(prompt): add core tool taxonomy block 2026-05-30 19:18:31 -07:00
Paulo Aboim Pinto bed328b7b5 test(tui): cover windows verbose state restore 2026-05-30 19:17:59 -07:00
Paulo Aboim Pinto 79cb61c1ac fix(tui): gate verbose snapshot helper on windows 2026-05-30 19:17:59 -07:00
Paulo Aboim Pinto e70f456abd fix(tui): preserve verbose state across windows alt-screen 2026-05-30 19:17:59 -07:00
Paulo Aboim Pinto 2077644ac2 fix(tui): gate verbose suppression behind alt-screen 2026-05-30 19:17:59 -07:00
Paulo Aboim Pinto 007140ec9e fix: suppress verbose CLI logging on Windows alt-screen to prevent TUI leak, restore on cleanup
On Windows, stderr cannot be redirected to the log file (no dup2). Suppress verbose CLI logging once the alt-screen is active so eprintln! calls from crate::logging don't leak into the TUI buffer. Also restores verbose logging on all cleanup paths after leaving alt-screen.
2026-05-30 19:17:59 -07:00
Zhuoran Deng 57625af4f8 docs(docker): tighten toolbox compose defaults 2026-05-30 19:17:55 -07:00