v0.9.0 stewardship integration#2762
Draft
Hmbown wants to merge 260 commits into
Draft
Conversation
- Add scroll state field to PlanPromptView with PgUp/PgDn, Ctrl+U/D/F/B, Home/End, gg/G vim-style keybindings - Show scroll indicator footer when content overflows the popup - Add confirming_exit state: Esc while scrolled asks for confirmation before discarding, preventing accidental exits on long plans - Clamp scroll in render() so overscroll doesn't hide bottom options - Use wrapped_line_count() with UnicodeWidthStr for accurate overflow detection with CJK characters - Add 11 unit tests covering scroll, keybindings, and exit confirmation
- Use word-wrapping-aware line count to prevent underestimating scroll range (gemini-code-assist / greptile-apps) - Merge PLAN_OPTIONS, PLAN_SHORTCUTS, PLAN_SHORT_LABELS into PlanOption struct (gemini-code-assist) - Remove dead Esc code in handle_key (greptile-apps) - Guard gg/G with modifier checks (gemini-code-assist) - Increase PgUp/PgDn scroll amount from 6 to 12 (greptile-apps) - Use u16::try_from for scroll value to avoid silent truncation (greptile-apps) - Update related unit tests for new scroll values
… key Use clamped (effective) scroll instead of raw `self.scroll` in the Esc handler so a short plan that fits entirely (max_scroll == 0) never triggers the "exit without implementing?" dialog when the user pressed a scroll key (PgDn/Ctrl-D/G/End) beforehand.
…e wrap width - wrapped_line_count: compute leading-space width via UnicodeWidthStr instead of byte length, so non-ASCII leading whitespace is measured correctly. - render: hoist popup_area / content_width computation above plan rendering so wrap_text can share the same content_width derived from the actual popup geometry instead of a magic 68.
…rome - Clear pending_g when Esc triggers the exit-confirmation prompt so a stray 'g' press does not leak into and survive the confirmation dialog. - Move render_modal_chrome into the else branch so only one call fires per render pass, eliminating a shadow artifact when confirming_exit is active.
…nder work - wrap_text: replace chars().count() with UnicodeWidthStr::width() so CJK text is wrapped by display columns, consistent with wrapped_line_count and ratatui's Paragraph::wrap. Also fix the hard-split loop to use exclusive byte ranges (..end) instead of inclusive (..=i) so multi-byte UTF-8 prefixes are always valid. - render: hoist the confirming_exit branch to an early return so the plan-content construction (lines, scroll bounds, footer) is skipped entirely when the confirmation dialog is visible.
…breaks at script boundaries
Wrap plan steps via wrap_text() before rendering, breaking only on display-width overflow, not on Latin/CJK Unicode word boundaries. Switch main render path from Wrap { trim: true } to Wrap { trim: false } since all content is pre-wrapped. Replace wrapped_line_count() with lines.len() for accurate scroll bounds. Keep confirm-exit dialog on Wrap { trim: true } (English-only, no risk).
#2683) Subagent aliases: - Legacy names (agent_spawn, agent_result, agent_cancel, resume_agent, agent_list, agent_send_input, agent_assign, agent_wait, delegate_to_agent) are already NOT registered — they exist as dead code with #[allow(dead_code)] since v0.8.33 - Add test verifying model catalog only advertises canonical subagent tools: agent_open, agent_eval, agent_close, tool_agent Shell aliases: - Hide exec_wait from model catalog (legacy alias for exec_shell_wait) - Hide exec_interact from model catalog (legacy alias for exec_shell_interact) - Both remain callable for saved transcript replay - Add test verifying shell aliases are hidden but callable Verification: cargo test -p codewhale-tui --locked (4040 passed), cargo clippy -D warnings
Root cause: AgentComplete unconditionally calls resume_terminal() even when the terminal was never paused, causing a secondary EnterAlternateScreen on Windows that creates a new buffer whose width may differ from the window width. Additionally, ColorCompatBackend had no terminal_size cache, so size() fell through to crossterm::terminal::size() which on Windows returns the WinAPI buffer width rather than the window width. Changes: - AgentComplete: add event_broker.is_paused() guard - resume_terminal(): cache real terminal size before reset_viewport - Resize handler: also set terminal_size alongside forced_size - subagent_routing: 3x mark_history_updated -> bump_history_cell(idx) - color_compat: add terminal_size field, set_terminal_size(), fix size() fallback priority (forced_size > terminal_size) - tests: 3 unit tests for size() fallback chain Review feedback addressed: - forced_size now takes priority over terminal_size (gemini-code-assist) - Redundant map lookups removed in subagent_routing (both bots) - set_terminal_size moved before reset_terminal_viewport (greptile-apps) (cherry picked from commit 4463c46)
Harvested from PR #2502 by @HUQIANTAO Co-authored-by: HUQIANTAO <58421104+HUQIANTAO@users.noreply.github.com>
Place user text before volatile turn metadata in outgoing user-message content arrays so provider prefix caches can continue matching the stable user-input prefix across date, model-route, and working-set changes. Also adds wire-level coverage proving tail-positioned turn metadata serializes after user text while preserving turn-meta deduplication. Harvested from PR #2517 by @HUQIANTAO Co-authored-by: HUQIANTAO <58421104+HUQIANTAO@users.noreply.github.com>
Harvest the HarmonyOS/OpenHarmony port from PR #2634 and make it publish-safe by target-gating unsupported host dependencies out of the OHOS TUI graph. Self-update is disabled on OHOS, PTY shell mode reports unsupported, and Starlark execpolicy parsing returns an explicit unsupported-platform error until upstream starlark/rustyline/nix support catches up. Add OHOS SDK setup docs and launcher scripts, install the rustls ring provider for rustls-no-provider entrypoints, and keep the packaged codewhale-tui OHOS graph free of starlark, rustyline, nix@0.28, portable-pty, and arboard. Validation: cargo fmt --all -- --check; git diff --check; git diff --cached --check; cargo check -p codewhale-cli --locked; cargo check -p codewhale-app-server --locked; cargo check -p codewhale-tui --locked; cargo test -p codewhale-cli --locked update::tests::; cargo test -p codewhale-release --locked; cargo test -p codewhale-tui --locked background_tty_command_has_controlling_terminal; cargo test -p codewhale-tui --locked clipboard; cargo package -p codewhale-tui --allow-dirty --no-verify --locked; packaged OHOS cargo tree checks. OHOS target check still requires a loaded OpenHarmony SDK/sysroot and currently stops in ring with missing assert.h when CC/CFLAGS/linker are unset. Harvested from PR #2634 by @shenjackyuanjie. Co-authored-by: shenjackyuanjie <54507071+shenjackyuanjie@users.noreply.github.com>
Extend the #2730 settings migration harvest with the missing platform-config fallback display assertion from review, and keep the v0.9 execution map/changelog credit current. Validation: cargo fmt --all -- --check; git diff --check; cargo test -p codewhale-tui --bin codewhale-tui --locked settings_ -- --nocapture; cargo test -p codewhale-tui --bin codewhale-tui --locked display_localizes_header_and_config_file_label -- --nocapture. Harvested from PR #2730 by @xyuai. Co-authored-by: xyuai <281015099+xyuai@users.noreply.github.com>
Add AUTHOR_MAP plus a lightweight co-author trailer checker so harvested commits use numeric GitHub noreply identities, reject bot/tool trailers, and require machine-readable credit when a commit says it was harvested from a PR.
Also normalize the local unpushed v0.9 harvest range so existing contributor authors/trailers for HUQIANTAO, Implementist, jrcjrcc, xyuai, cyq1017, idling11, and shenjackyuanjie use GitHub-mappable identities before the branch is published.
Validation: python3 scripts/check-coauthor-trailers.py --author-map .github/AUTHOR_MAP --range origin/main..HEAD --check-authors; python3 -m py_compile scripts/check-coauthor-trailers.py; ruby -e 'require "yaml"; YAML.load_file(".github/workflows/ci.yml")'; git diff --check; negative in-process validation for raw email, missing harvested credit, and bot author cases.
Harvest the UpdateThreadRequest workspace field from PR #2640 while keeping the engine-cache correctness fix: PATCH /v1/threads/{id} now persists workspace changes, emits the workspace change in thread.updated, rejects empty paths, rejects workspace changes while a turn is active, and evicts idle cached engines so the next turn starts in the new workspace. Validation: cargo fmt --all -- --check; git diff --check; cargo test -p codewhale-tui --bin codewhale-tui --locked update_thread_workspace -- --nocapture; cargo clippy -p codewhale-tui --locked -- -D warnings; python3 scripts/check-coauthor-trailers.py --author-map .github/AUTHOR_MAP --range origin/main..HEAD --check-authors. Harvested from PR #2640 by @gaord. Co-authored-by: gaord <9567937+gaord@users.noreply.github.com>
Harvested from PR #2733 by @idling11. Adds richer update_plan artifact fields for grounded Plan-mode review, renders them in the transcript and Plan confirmation prompt, and carries them through /relay, fork-state, and saved-session replay. Verification: cargo test -p codewhale-tui --bin codewhale-tui --locked plan_ -- --nocapture Verification: cargo test -p codewhale-tui --bin codewhale-tui --locked relay_slash_command_routes_to_session_relay_instruction -- --nocapture Verification: cargo clippy -p codewhale-tui --locked -- -D warnings Co-authored-by: idling11 <8055620+idling11@users.noreply.github.com>
… management 1. Fix Mutex lock().unwrap() in MCP server (mcp_server.rs:384,434) - Use unwrap_or_else(|e| e.into_inner()) to recover from poisoned locks - Previously, a single panic while holding the lock would cascade to all threads 2. Fix std::thread::spawn in async code (hooks.rs:1055) - Replace std::thread::spawn with tokio::task::spawn_blocking - Respects tokio's thread pool limits instead of creating unbounded OS threads - Fire-and-forget hook execution now properly managed by tokio runtime 3. Fix dropped JoinHandle in SSE loop (mcp.rs:647) - Store the JoinHandle in SseTransport struct - Enables detection of SSE loop termination - Prevents silent connection loss without structured error reporting 4. Fix std::sync::Mutex poison handling in cost_status (cost_status.rs:28-58) - Use unwrap_or_else(|e| e.into_inner()) to recover from poisoned locks - Previously, a panic while holding the lock silently lost all subsequent cost data - Cost tracking now survives mutex poisoning 5. Fix .expect() in tracing writer (runtime_log.rs:162) - Replace expect() with fallback chain: try_clone -> reopen file -> stderr - Prevents panicking inside tracing subscriber on fd exhaustion - Previously, EMFILE during logging would crash the application
1. Replace let-else with if-let-Some to avoid compilation error - let-else with return would return from the entire function - if-let-Some correctly assigns to tool_registry and continues 2. Preserve original goal_objective_for_prompt behavior - Return None (not fallback) when objective exists but goal is inactive - Use state.is_active().then() to match original semantics
1. Fix whitespace bypass in normalize_command (execpolicy/lib.rs:446)
- Collapse internal whitespace to prevent 'git status' bypassing 'git status'
- split_whitespace().join(' ') normalizes all whitespace
2. Fix 'never'/'deny' approval mapping (app-server/lib.rs:287)
- Map to AskForApproval::Never instead of OnRequest
- 'never'/'deny' should forbid commands, not prompt for approval
3. Optimize prefix matching (execpolicy/lib.rs:355, bash_arity.rs:375)
- Avoid format! allocation on every check
- Use byte comparison for space boundary check
Replace platform-specific std::os::unix::io::FromRawFd with Box<dyn std::io::Write + Send> return type. This compiles on Windows, macOS, and Linux without unsafe code. The closure now returns a boxed writer that is either: - The cloned file handle (success case) - A reopened file handle (clone failed) - stderr (last resort, prevents panic)
- Add tracing.workspace = true to crates/core/Cargo.toml (required for tracing::warn! in lib.rs:752) - Apply cargo fmt formatting to engine.rs, mcp.rs, tool_execution.rs, config/lib.rs
The test at line 4768 was missing the new sse_task field added to SseTransport. Add a dummy tokio::spawn task for the test.
Required for tracing::error! in persist_config error handling.
tokio::task::spawn_blocking requires a running tokio runtime, which breaks tests that call hook functions outside a tokio context. Since hooks are fire-and-forget (no JoinHandle needed), std::thread::spawn is the correct choice.
Mechanical rustfmt of the runtime_prompt tests rewritten in PR #2874 (LeoAlex0). No logic change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… approval mapping
… join handles)
…ders in /model picker
carloslindhstrom-code
approved these changes
Jun 7, 2026
Harvests 7 safe fixes from PR #2880 by @HUQIANTAO: tool-name hex-digit guard, token-usage u32 clamp, read-file line usize::try_from, grep context-lines cap, UTF-8 PDF trim, run_skill dedup, and Volcengine/SiliconflowCn reasoning_content support. Excludes the DeepSeek stream-stop change and the unwired prompt_persist module (deferred for separate review). Co-Authored-By: HUQIANTAO <58421104+HUQIANTAO@users.noreply.github.com>
Harvested from PR #2884 by @ousamabenyounes. Drops the orphan desktop tray.rs module (dead code, never wired) from that PR. Co-Authored-By: Ben Younes <2910651+ousamabenyounes@users.noreply.github.com>
Harvested from PR #2885 by @greyfreedom. Wires ask-rules into the app-server and core ExecPolicyEngine (previously inert). Removes the original PR's NeedsApproval arm that incorrectly allow-listed the working directory as a network host. Co-Authored-By: greyfreedom <11493871+greyfreedom@users.noreply.github.com>
The 1ms heartbeat timeout raced the synchronous touch()->cleanup() gap on loaded CI runners (Windows scheduler can deschedule >1ms), intermittently reaping the just-touched agent so cleanup() returned 1. Widen the timeout to 50ms and the staleness sleep to 150ms to keep the logic exercised without the timing race. Addresses CI flakiness under the v0.9.0 stabilization gate (#2721). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Current verification
./scripts/release/check-versions.sh./scripts/release/verify-workspace-version.sh 0.9.0git diff --checkcargo fmt --all -- --checkcargo clippy --workspace --all-targets --all-features --locked -- -D warningscargo test --workspace --all-targets --all-features --locked --quietnpm test --prefix npm/codewhalecargo build --release --locked -p codewhale-cli -p codewhale-tui0.9.0 (fde931ee89e7).target/v0.9.0-local-assetsfor maintainer testing only.Contributor stewardship
workflow_run, provider calls, worktree application, and runtime replay remain deferred until cancellation, replay, and worktree semantics are airtight.Maintainer notes