Commit Graph

2241 Commits

Author SHA1 Message Date
Hunter B 0d66ef34d1 feat(hooks): add turn_end observer hook
Harvested the narrow Rust/docs slice of PR #2578 by @AresNing for #1364. The event uses the maintained structured observer path: JSON stdin, stdout ignored, warn-only failures, and no ability to block or mutate the turn.

The hook fires after post-turn app state, usage totals, cost, notification, receipt, and queue-recovery state are updated, before queued follow-up dispatch. Docs, RFC notes, /hooks discovery, and v0.9 tracking now describe the observer-only contract.

Co-authored-by: AresNing <49557311+AresNing@users.noreply.github.com>
2026-06-04 00:09:01 -07:00
Hunter B 586640a437 feat(config): add typed harness posture profiles
Harvested from PR #2741 by @idling11 for #2693, with review fixes folded in: typed compaction/tool/safety enums, no silent unknown-kind fallback, unknown profile keys rejected, and whole-struct equality for future reload/runtime checks.

Co-authored-by: idling11 <8055620+idling11@users.noreply.github.com>
2026-06-04 00:00:22 -07:00
Hunter B 13cabac077 docs(config): clarify provider path suffix support
Records that #2506/#2508 are superseded by the safer #2558 path_suffix implementation, credits the original #1874 report and follow-up PR review trail, and documents that suffix overrides only affect chat completions while model and beta paths keep built-in routing.
2026-06-03 23:56:40 -07:00
Hunter B f5e6d46848 docs: add agent stewardship guidance 2026-06-03 23:52:31 -07:00
Hunter B e18f072a5a perf(context): cache project context with content signatures
Harvested from PR #2636 by @HUQIANTAO with widened cache invalidation for constitution files, generated context, trust state, canonical paths, and same-length overwrites.

Co-authored-by: HUQIANTAO <58421104+HUQIANTAO@users.noreply.github.com>
2026-06-03 23:49:08 -07:00
Hunter B 6a7063c912 ci(ohos): guard unsupported target dependencies 2026-06-03 23:41:21 -07:00
Hunter B 8d9cd44078 fix(tui): make queued follow-up edits recoverable 2026-06-03 23:36:42 -07:00
Hunter B 5d006a901e docs: record superseded transcript collapse PR 2026-06-03 23:32:29 -07:00
Hunter B 5b3ee9db67 fix(tasks): fail stale running tasks after restart
Refs #1786.

Reported by @bevis-wong. This lands the durable restart-safety slice: persisted running tasks and running tool rows are marked failed with a recovery note instead of being requeued as live work after a prior process exits.
2026-06-03 23:30:16 -07:00
Hunter B ad3d61936b feat(subagent): preserve checkpoints for timeout continuation
Refs #2029.

Reported by @qiyuanlicn. This lands live per-step API-timeout checkpoint continuation and preserves checkpoint metadata through projections, transcripts, and persistence; cold-restart child-task rehydration remains out of scope.
2026-06-03 23:27:20 -07:00
Hunter B 3cb49233ee feat(sidebar): show full details for truncated rows
Harvested from PR #2734 by @idling11 with reviewer fixes for row-source fidelity, row-authoritative hit testing, and display-width popover sizing.

Refs #2694.

Co-authored-by: idling11 <8055620+idling11@users.noreply.github.com>
2026-06-03 23:26:08 -07:00
Hunter B 185beb5c12 docs: expand v0.9 stewardship README
Describe the v0.9 continuity track, bounded project-context work, contribution review posture, and visible current-track credits.
2026-06-03 23:13:12 -07:00
Hunter B 8d4eb0c2c9 fix(context): bound auto-generated project context
Refs #697 and #1827.

Reported by @NASLXTO and @wuxixing. Prior context-cap and startup-diagnosis work by @linzhiqin2003 and @merchloubna70-dot shaped this fallback.
2026-06-03 23:10:50 -07:00
Hunter B e14fc4712c fix(tui): label pending input delivery modes
Harvested from PR #2532 by @cyq1017.

Pending input rows now distinguish steer-pending, rejected-steer, and queued-follow-up states, with continuation rows aligned under the delivery label.

Refs #2054; leaves the broader cancel/edit affordance work open.

Co-authored-by: cyq1017 <61975706+cyq1017@users.noreply.github.com>
2026-06-03 22:19:22 -07:00
Hunter B 333275162f feat(runtime): save completed threads as sessions
Harvested from PR #2639 by @gaord.

Adds POST /v1/sessions for runtime clients to persist completed threads as managed saved sessions, with a 409 guard for queued or active turn/item state and focused session endpoint coverage.

Also makes MCP HTTP tests install the rustls ring provider before constructing reqwest clients so filtered no-provider test runs are deterministic.

Co-authored-by: gaord <9567937+gaord@users.noreply.github.com>
2026-06-03 22:16:02 -07:00
Hunter B e92202cabe docs(release): update v0.9 stabilization ledger 2026-06-03 22:04:48 -07:00
Hunter B c76ec47526 feat(transcript): collapse dense tool runs
Harvested from PR #2738 by @idling11.

Co-authored-by: idling11 <8055620+idling11@users.noreply.github.com>
2026-06-03 22:00:46 -07:00
Hunter B 55024a16d8 fix(subagent): inherit tool-agent model route
Harvested from PR #2736 by @h3c-hexin.

Co-authored-by: h3c-hexin <13790929+h3c-hexin@users.noreply.github.com>
2026-06-03 21:43:18 -07:00
Hunter B 9719b45cd3 fix(skills): merge configured and workspace skill dirs
Harvested from PR #2737 by @h3c-hexin.

Co-authored-by: h3c-hexin <13790929+h3c-hexin@users.noreply.github.com>
2026-06-03 21:39:15 -07:00
Hunter B 7ac8063b6b feat(plan): preserve rich PlanArtifact context
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>
2026-06-03 21:31:09 -07:00
Hunter B 66c88ddfae feat(runtime): allow thread workspace updates
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>
2026-06-03 21:11:55 -07:00
Hunter B 002f8f0ba1 ci: enforce mappable co-author credit
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.
2026-06-03 21:07:33 -07:00
Hunter B fb86737a8c test(settings): assert migrated settings display canonical path
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>
2026-06-03 21:02:46 -07:00
Hunter B 23c9481af1 feat: add HarmonyOS OpenHarmony support
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>
2026-06-03 21:02:46 -07:00
Hunter B 5f51f89c76 chore: seed APPROVED_CONTRIBUTORS with recurring contributors (>=2 merged PRs) 2026-06-03 21:02:46 -07:00
Hunter B 445a7c8171 ci: avoid duplicate PR gate comments 2026-06-03 21:02:45 -07:00
Hunter B 42d27c0095 ci: soften contribution intake gates 2026-06-03 21:02:45 -07:00
HUQIANTAO 98edba3683 refactor(engine): append turn metadata after user text
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>
2026-06-03 21:02:45 -07:00
Hunter B 60f8e7d62e refactor(web_run): split cache locks for page reads
Harvested from PR #2502 by @HUQIANTAO

Co-authored-by: HUQIANTAO <58421104+HUQIANTAO@users.noreply.github.com>
2026-06-03 21:02:45 -07:00
Hunter B 868f99b329 docs: update v0.9 PR harvest map 2026-06-03 21:02:45 -07:00
Hunter B 311eb4002b feat(tui): add bounded restore snapshot listing
Harvested from PR #2513 by @cyq1017.

Co-authored-by: cyq1017 <61975706+cyq1017@users.noreply.github.com>
2026-06-03 21:02:45 -07:00
Hunter B 111a805eb8 docs: mark mention depth hint harvested 2026-06-03 21:02:45 -07:00
Hunter B 5dc1a63cd4 docs: harvest provider fallback chain RFC
Harvested from PR #2581 by @idling11.

Co-authored-by: idling11 <8055620+idling11@users.noreply.github.com>
2026-06-03 21:02:45 -07:00
Hunter B 44ceabd606 docs: refresh README and v0.9 execution map 2026-06-03 21:02:45 -07:00
Hunter B 8502784218 fix(xiaomi-mimo): use token-plan api-key auth
Harvests the MiMo Token Plan auth-header behavior from #2627 while keeping Xiaomi env-key precedence unchanged so standard endpoints do not accidentally receive a Token Plan key.

Harvested from PR #2627 by @xyuai.

Co-authored-by: xyuai <281015099+xyuai@users.noreply.github.com>
2026-06-03 21:02:45 -07:00
Hunter B 159f509dd6 fix(tui): invalidate fanout card rows on sibling starts 2026-06-03 21:01:39 -07:00
jrcjrcc 7b2a7e513d fix: Windows sub-agent completion halves TUI render width
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 4463c46644a6e485e7e20dc2b19c29c2e8eb3c5c)
2026-06-03 21:01:39 -07:00
Hunter B 27db89c25d docs: update TOOL_SURFACE.md with v0.9.0 hidden-alias table (#2682, #2683) 2026-06-03 21:01:38 -07:00
Hunter B 4401f7a2e5 feat(tools): hide legacy subagent and shell aliases from model catalog (#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
2026-06-03 21:01:38 -07:00
Implementist 88422f3ad3 fix(plan_prompt): pre-wrap CJK+Latin mixed text to avoid forced line-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).
2026-06-03 21:01:38 -07:00
Implementist 966b5cf1fb refactor(plan_prompt): use display-width in wrap_text, skip wasted render 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.
2026-06-03 21:01:38 -07:00
Implementist e3a52555eb fix(plan_prompt): clear pending_g on Esc, deduplicate render_modal_chrome
- 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.
2026-06-03 21:01:38 -07:00
Implementist 47c071a0d5 chore: apply cargo fmt fix to plan_prompt.rs 2026-06-03 21:01:38 -07:00
Implementist 6d79d55b6c fix(plan_prompt): use display-width for leading spaces and de-hardcode 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.
2026-06-03 21:01:38 -07:00
Implementist 11c448d66e fix(plan_prompt): remove step truncation to allow content overflow into scroll region 2026-06-03 21:01:38 -07:00
Implementist 537a8bccf3 fix(tui): replace manual div_ceil with usize::div_ceil to satisfy clippy lint 2026-06-03 21:01:38 -07:00
Implementist 14db9b2466 fix(tui): avoid spurious exit-confirmation on short plan after scroll 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.
2026-06-03 21:01:38 -07:00
Implementist 1669e3c12e fix(tui): address code review feedback on plan prompt modal
- 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
2026-06-03 21:01:38 -07:00
Implementist 68784cff52 fix(tui): add scroll support to plan prompt modal
- 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
2026-06-03 21:01:38 -07:00
HUQIANTAO 863f55cc68 perf(history): simplify output_rows cache API and switch to FNV-1a
Three follow-ups to the previous perf commit:

1. Drop the rows_hash field on CacheEntry. The field was computed and
   stored but never read on the hot path; tests exercised it only to
   assert the cache returned a stable hash. After this change
   get_or_compute_rows returns just Vec<OutputRow>, halving the
   tuple-return ABI and removing one DefaultHasher::write pass on
   every cache miss.

2. Replace DefaultHasher (SipHash) with a hand-rolled FNV-1a 64-bit
   hash. SipHash is per-process-keyed and ~5-10x slower than FNV on
   the small-to-medium tool output strings we see at 120 FPS. FNV-1a
   has no per-process key, fits in 20 lines of pure-Rust, and a 64-bit
   collision space is more than wide enough for the per-process LRU's
   expected <= a few hundred entries. The cache is a correctness
   optimization, not a security boundary; collisions only cause a
   false miss, never wrong data.

3. Caller in tui::history::render_preserved_output_mode updated to
   the new Vec<OutputRow>-only signature. Two new tests cover the
   FNV-1a properties (length-suffix sensitivity, empty-input
   stability).
2026-06-03 21:01:38 -07:00