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>
- Add model_visible() hook to ToolSpec trait (default true)
- Override model_visible() -> false on todo_write, todo_add, todo_update, todo_list
- Checklist variants remain model-visible as the canonical surface
- Legacy todo_* calls still work for saved transcript replay
- Return _deprecation metadata with use_instead and removed_in=0.9.0
- Update prompts to recommend checklist_* only
- Update TOOL_SURFACE.md with v0.9.0 deprecation notes
- Add tests for hidden catalog, compat alias behavior, and metadata
Verification: cargo test -p codewhale-tui -- todo, cargo clippy -D warnings
* feat(tui): add command palette voice input
* feat(rlm): expose active session objects
* fix(tui): do not restore slash commands as retry drafts
* fix(config): expose voice input settings rows
* fix: sync ActiveTurnState.auto_approve when remember is set
When a user checks 'Remember for this tool' and approves a tool call,
remember_thread_auto_approve() only persisted thread.auto_approve to disk
but did not update the in-memory ActiveTurnState for the current turn.
This meant subsequent tool calls within the same turn would still require
manual approval, making the remember checkbox appear non-functional.
Now remember_thread_auto_approve() also sets
ActiveTurnState.auto_approve = true, so active_turn_flags() returns
the correct value and the approval_decision() logic auto-approves
remaining tool calls in the current turn.
(cherry picked from commit 2ccf048c8984d61e3341a4304d0796a1f965d3e7)
* test(runtime): cover remembered auto approve on active turn
---------
Co-authored-by: Ben Gao <bengao168@msn.com>
- New github_close_pr tool distinct from github_close_issue; proper PR wording
in tool output, audit records, and gh pr close (not issue close)
- handle_read detects art_/call_/SHA refs and points to retrieve_tool_result
with copy-pasteable hints; error messages show correct tool for each ref type
- Shell delta tool results include the command field so the UI can resolve
task_id-only exec cells when the completion metadata arrives
- Sidebar background shell tasks show the actual command on the primary row
instead of just the task ID; task ID stays available as dim detail
- Tool routing falls back to task_id when exec_shell_wait has no command,
then updates when the completion carries command metadata
- Plan mode prompt explains update_plan as the handoff signal; model waits
for user action instead of continuing to tool around
- Base prompt clarifies handle_read scope (var_handles only) vs
retrieve_tool_result (artifacts/tool-result refs)
- New tests: close_pr_schema, close distinction wording, handle_read artifact
detection, shell_wait task_id fallback, sidebar background task labels
Sweep brand mentions of `DeepSeek TUI` / `deepseek-tui` / bare
`deepseek` (the dispatcher binary) across all user-facing docs to
the new `codewhale` brand. The DeepSeek **provider** integration is
left untouched throughout: env vars (`DEEPSEEK_*`), model IDs
(`deepseek-v4-pro`, `deepseek-v4-flash`, `deepseek-chat`,
`deepseek-reasoner`), the `api.deepseek.com` host, the
`~/.deepseek/` config dir, and the `--provider deepseek` argument
value all keep the legacy spelling.
Anti-scope items deliberately left as the legacy `deepseek-tui`:
- Homebrew tap and formula (`Hmbown/homebrew-deepseek-tui`,
`brew install deepseek-tui`, `scoop install deepseek-tui`). The
tap rename ships separately.
- Docker image (`ghcr.io/hmbown/deepseek-tui`). Image-tag rename
ships separately.
- CNB mirror namespace (`cnb.cool/deepseek-tui.com/DeepSeek-TUI`).
Third-party hosted path.
- Security contact email (`security@deepseek-tui.com`).
- GitHub repo URL (`Hmbown/DeepSeek-TUI`).
New artifact:
- `docs/REBRAND.md` documents what changed, what didn't, the
deprecation window, and migration commands for npm / Cargo /
Homebrew / manual installs.
CHANGELOG entries:
- Root `CHANGELOG.md` and `crates/tui/CHANGELOG.md` both gain a
new `[Unreleased]` section describing the rename and the one-
release deprecation window. Historical entries are untouched.
Issue templates:
- `.github/ISSUE_TEMPLATE/bug_report.md` and `feature_request.md`
refer to "codewhale" / `codewhale --version` instead of the old
brand name in their environment fields.
The rebrand sweep was driven by a perl script with bulk patterns
(`deepseek-tui` -> `codewhale-tui`, `DeepSeek TUI` -> `codewhale`,
bare `deepseek` -> `codewhale` with provider/model/host/env-var/
config-path negative lookbehind/lookahead) followed by targeted
reverts for the anti-scope items above. Output was visually
reviewed file-by-file before committing.
Verified:
- `cargo check --workspace --all-targets --locked` — pass.
- `cargo test --workspace --all-features --locked` — pass (no
test source touched here; suite stayed green to confirm no
doc-from-string assertions broke).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The role taxonomy expansion in #404 added Implementer + Verifier as
distinct postures alongside General / Explore / Plan / Review /
Custom. The issue body explicitly lists \`docs/AGENTS.md or
docs/SUBAGENTS.md\` as a target file; this commit creates that file.
Coverage:
- Role taxonomy table — stance, write/shell access, typical use per
role.
- "When to pick which role" — narrative guidance the model can read
if the role choice isn't obvious.
- Alias map — every accepted spelling routed to a canonical role,
matching what \`SubAgentType::from_str\` accepts.
- Concurrency cap — the 10-by-default value, the
\`[subagents].max_concurrent\` knob, and the running-only
semantics (#509).
- Lifecycle — Pending → Running → terminal states, plus
\`Interrupted\` after a process restart.
- Session boundaries (#405) — \`session_boot_id\` mechanics,
default current-session filter, \`include_archived=true\` escape
hatch, pre-#405 record handling.
- Output contract — the SUMMARY/CHANGES/EVIDENCE/RISKS/BLOCKERS
format every sub-agent must produce.
- Memory + \`remember\` integration (#489) — sub-agents inherit the
parent's memory file when memory is enabled and can append durable
notes.
- Implementation notes — source path, persisted state file,
is_running semantics, RwLock pattern.
Cross-link added in \`docs/TOOL_SURFACE.md\` so the sub-agent section
points to this doc.
No Rust code changed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bundles the v0.8.8 stabilization fixes that were already implemented in the
working tree, plus the workflow/doc reconciliation called out in #507.
### Sub-agent runtime fixes
- **#509** Default sub-agent cap raised to 10 (configurable via
`[subagents].max_concurrent` in `config.toml`, hard ceiling 20). The
running-count calculation now ignores non-running, no-handle, and finished
handles so completed agents stop counting against the cap.
- **#510** `SharedSubAgentManager` is now `Arc<RwLock<...>>`; the read paths
that previously held a `Mutex` for inspection now take a read lock,
eliminating the multi-agent fan-out UI freeze.
- **#511** `compact_tool_result_for_context` summarizes `agent_result` /
`agent_wait` payloads before they are folded into the parent context.
- **#512** RLM tool cards map to `ToolFamily::Rlm` and render `rlm`, not
`swarm`. Stale "swarm" wording cleaned in docs/comments/tests.
- **#513** (foreground stopgap only) Foreground RLM work is visible in the
Agents sidebar projection. Full async RLM lifecycle remains v0.8.9 — the
issue stays open with a refined scope.
### TUI / UX fixes
- **#487** Offline composer queue is now session-scoped; legacy unscoped
queues fail closed.
- **#488** Composer Option+Backspace deletes by word; cross-platform key
routing helpers added.
- **#443/#444** Keyboard enhancement flags pop on normal AND panic exit; the
raw-mode startup probe is now bounded by a configurable timeout.
- **#449** Production footer reads statusline colors from `app.ui_theme`
rather than the bespoke palette.
- **#506** `display_path_with_home` no longer mutates `HOME` in tests; the
flake on shared-env CI is gone.
### Self-update / packaging
- **#503** `update.rs` arch mapping uses release-asset naming (`arm64`/`x64`)
instead of the raw Rust constants. The platform-asset selector also rejects
`.sha256` siblings as primary binaries. Tests now live alongside the source
in `mod tests` (the `#[path]`-based integration test was removed because it
duplicated test runs and forced a `pub(crate)` helper that no real caller
used).
- **`Max 5 in flight` wording updated** in `agent_spawn` description,
`prompts/base.md`, and `docs/TOOL_SURFACE.md` so the model sees the real
default cap (10) and the configuration knob name.
### CI / release docs (#507)
- Pruned three duplicated/dead workflows: `crates-publish.yml`, `parity.yml`,
`publish-npm.yml`. Their gates already run in `ci.yml` for every push/PR.
- `release.yml` build job now allows `parity` to be skipped (it only runs on
tag push), unblocking `workflow_dispatch` reruns. The job still fails
closed on a real parity failure.
- `RELEASE_RUNBOOK.md` reconciled: crate publishing is documented as the
manual `scripts/release/publish-crates.sh` flow (no automated workflow);
references to the deleted workflows removed.
- `CLAUDE.md` notes the `RELEASE_TAG_PAT` requirement for the auto-tag →
release.yml chain (without it, the tag is created but `release.yml` does
not fire) and documents the `workflow_dispatch` parity-skip behavior.
### Docs
- `docs/COMPETITIVE_ANALYSIS.md` added — capability matrix vs OpenCode and
Codex CLI, gap analysis, and recommended implementation order.
### Verification (this branch)
- `cargo fmt --all -- --check` ✓
- `cargo check --workspace --all-targets --locked` ✓
- `cargo clippy --workspace --all-targets --all-features --locked -- -D warnings` ✓
- `cargo test --workspace --all-features --locked` ✓ (1809 + supporting)
- Parity gates ✓ (snapshot, parity_protocol, parity_state)
- `cargo build --release --locked -p deepseek-tui-cli -p deepseek-tui` ✓
- Lockfile drift guard ✓
- `deepseek doctor --json` clean
- `deepseek eval` (offline harness) success=true, 0 tool errors
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Issues #202, #203, #204, #205:
- Cycle/seam triggers use active request input size + response
headroom reserve, not lifetime cumulative API usage.
- V4 hard-cycle headroom calibrated around fixed TURN_MAX_OUTPUT_TOKENS
plus CONTEXT_HEADROOM_TOKENS safety buffer.
- /tokens, /cost, footer/header labels, and docs now separate
active context, turn telemetry, cumulative usage, cache hit/miss,
context percent, and cost.
- Foreground exec_shell timeout output tells the model the process
was killed and suggests task_shell_start or background exec_shell
plus poll/wait.
- Added regression tests for active-token basis, V4 headroom,
seam trigger basis, footer label behavior, and shell timeout
recovery metadata.
- Preserved #200/#201 policy: V4 default is append-only,
prefix-cache preserving; replacement compaction, Flash seams,
and capacity intervention remain opt-in.
Add `wrap_with_deprecation_notice` helper in the subagent module that
merges a `_deprecation` block into a ToolResult's metadata. Applied
exclusively on alias invocations:
- `spawn_agent` → use `agent_spawn` (removed in v0.8.0)
- `delegate_to_agent` → use `agent_spawn` (removed in v0.8.0)
- `close_agent` → use `agent_cancel` (removed in v0.8.0)
- `send_input` → use `agent_send_input` (removed in v0.8.0)
Canonical names are unaffected. Each alias invocation also emits a
`tracing::warn` so the deprecation appears in audit logs. Documents
the deprecation schedule in `docs/TOOL_SURFACE.md`. Four unit tests
verify the notice shape and that canonical tools stay clean.
Refs #72
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tool-surface audit pass:
- FILE OPERATIONS rewritten so each line states the niche, not just the
verb. read_file mentions PDF auto-extraction + `pages` slicing.
- New SEARCH section consolidates grep_files / file_search / web_search /
fetch_url so the model sees them next to each other and picks the
right one. fetch_url (#33) added; previously absent from the prompt.
- request_user_input pulled out of FILE OPERATIONS into its own USER
section — it never belonged there.
- SUB-AGENTS list shrinks by 3: drops `spawn_agent` (use `agent_spawn`),
`close_agent` (use `agent_cancel`), and the `agent_assign /
assign_agent` dual-name. The underlying dispatchers still resolve those
names, so existing sessions don't break — they just no longer
pollute the model's tool list.
Adds `docs/TOOL_SURFACE.md` with the rationale, the v0.5.1 final
surface, and the dropped aliases. Calls out that grep_files is pure-Rust
(no rg/grep shell-out, so the "fall back to grep" AC from #35 is
vacuously satisfied — the tool has no shell dependency to fall back from).
Closes#35.