/swarm [N] <task> is a high-fanout overlay on the current mode (Agent/Plan/YOLO),
NOT a fourth mode. It mirrors the proven /agent command pattern: it emits a
model instruction to decompose the task, fan out one headless sub-agent per
subtask via agent_open (role/agent_type per subtask, max_depth N for nesting),
run them concurrently, and synthesize from each worker's result SUMMARY (not its
transcript) — the isolation pattern that keeps the orchestrator light.
Registered with aliases fanout/qun; CmdSwarmDescription was already localized in
all locales. Validated by the command-registry completeness tests (unique
names/aliases, complete metadata); broad commands suite 431/0.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
While a turn is in flight (`is_loading`), the model/permission surface the
engine is acting on must not shift underneath it. User-initiated mode cycling
(cycle_mode / cycle_mode_reverse) and thinking cycling (cycle_effort) are now
refused with a concise status message ("… is locked while a turn is running —
press Esc to interrupt first") and the selection stays put (the chip "twitches"
back rather than moving). Internal set_mode transitions (YOLO/plan) are
unaffected — only the user gestures are guarded.
Unit-tested: locked while is_loading, works again once idle. Persistent
busy/free chip styling is left for a visual-review pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The fleet-foundation provider expansion added Anthropic/Zai/Stepfun/Minimax as
recognized providers (auth parser + PROVIDER_LIST), but also flipped all four to
TUI-supported in provider_is_supported_by_tui — making every ProviderKind
supported, killing the rejection path and breaking three build_tui_command
rejection tests (the flip had no positive test, so it was an unverified side
effect).
Anthropic speaks the native Messages API, not the OpenAI-compatible shape the
interactive loop expects, so it stays exec-only (as it was on origin):
`codewhale --provider anthropic` is rejected with a hint to use
`codewhale exec --provider anthropic`. Zai (GLM/Z.AI — the v0.8.60 headline),
Stepfun, and Minimax are OpenAI-compatible and remain interactively supported.
Restores the rejection guard and the 3 tests (now 95/0 in codewhale-cli).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds a verifiable dogfood smoke that drives several concurrent exec-style
workers (three healthy + one injected-failure that emits an error event and
exits non-zero) through the real host adapter, asserting distinct terminal
pass/fail outcomes — no external services, no model calls, no codewhale binary.
Documents the automated CI smoke vs the manual `codewhale fleet run` path in
the dogfood spec, and is honest that the manager run-loop cutover to drive real
FleetExecutor workers is still in progress.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds FleetExecutor: drives a worker as a local `codewhale exec` subprocess via
the existing host adapter, incrementally drains its stream-json output into
FleetWorkerEventPayload ledger events, and finalizes the terminal outcome from
the process exit. The worker's heavy runtime/tool construction lives in its own
process, so the orchestrator only ingests a compact event stream — the
isolation pattern that keeps fanout light (per Codex/Kimi/Claude Code).
Verified end-to-end by an integration test that runs a REAL subprocess emitting
stream-json (standing in for `codewhale exec`) through the real adapter and
asserts RunningTool + terminal Completed events flow out — no codewhale binary
needed. 8 executor tests pass; the 58 existing fleet tests stay green
(executor is not yet wired into `codewhale fleet run`, so no behavior change).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A fleet worker IS a headless `codewhale exec` run — not a separate execution
engine. New crates/tui/src/fleet/executor.rs provides the bridge:
- build_worker_exec_command: FleetTaskSpec + FleetExecConfig ->
`codewhale exec --auto --output-format stream-json [--model/--allowed-tools/
--disallowed-tools/--max-turns/--append-system-prompt] <prompt>`. Secrets are
never on argv (worker resolves its own config/keyring).
- map_exec_stream_line: maps the worker's stream-json events
({"type":"tool_use"|"content"|"tool_result"|"done"|"error"}) into
FleetWorkerEventPayload so the durable ledger persists the worker's OWN event
vocabulary (collapses the translation layer toward identity).
- classify_worker_exit: process exit -> terminal Completed/Failed/Cancelled.
This is the substrate for replacing the local simulation with real headless
workers. fleet_task_prompt is now pub(crate). 7 new unit tests; building blocks
only (no behavior change yet) so the 58 existing fleet tests stay green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Refs #1310.
Adds the direct minimax provider slot, auth/config/env bindings, model aliases, docs, and picker/status surfaces. MiniMax requests now set reasoning_split and preserve reasoning_details history so thinking stays out of answer text.
Also updates Moonshot/Kimi reasoning classification for the Kimi Code route so reasoning_content streams into Thinking cells instead of inline prose.
Removing Paste from the sidebar menu (#3065) left rows with no copy
path at all — sidebar text can't be mouse-selected. Right-clicking a
sidebar row now offers Copy, which writes the row's untruncated text
plus its hover detail to the clipboard via a new
ContextMenuAction::CopyText. Run stays first for clickable rows.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Work panel: hovering the '+N more checklist items' overflow row now
reveals the omitted checklist items in the popover, so a
height-constrained panel no longer hides work items with no way to
inspect them (#3063).
- Agents panel: the compact agent label row's hover text now carries a
full dossier — id, role, status, elapsed time, step count, objective
(new SidebarAgentRow field, from SubAgentAssignment), branch, and
untruncated progress. Compact rows stay unchanged.
- Detail-row hover keeps the full progress text instead of the
summarized form.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The loading mouse filter (should_drop_loading_mouse_motion) dropped all
Drag events while app.is_loading unless a transcript selection or
scrollbar drag was active. A sidebar resize started on the handle
(Down passes the filter) then never received its Drag events, leaving
the resize wedged mid-gesture during live runs (#3063, symptom of the
#3096 subagent-runtime pressure on the TUI).
- Allow Drag events through the loading filter while
app.sidebar_resizing is set.
- Clear last_sidebar_area / last_sidebar_handle_area and any in-flight
resize when the sidebar is hidden or doesn't fit, so stale handle
hit-areas can't capture clicks.
- Tests: resize down/drag/up while loading, mouse-up outside the
handle still ends the resize.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
cargo clippy --workspace -D warnings fails on three pre-existing spots
newly flagged by the current toolchain: unnecessary_sort_by in
context_report, question_mark in the provider fallback chain, and
unnecessary_map_or in the empty-state widget check. Apply the
mechanical fixes clippy suggests; no behavior change.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The release branch already ships the slim-prompt intent in a stronger
form than #3010 — compose_default_static_layers appends no personality
overlay at all (voice/tone guidance is folded into the constitution
preamble), where the PR only emptied the Calm arm. Carry over the PR's
regression test, which derives its assertion from calm.md itself so a
future re-inclusion of the overlay text fails loudly.
Harvested from PR #3010 by @894876246
Co-authored-by: Hanmiao Li <894876246@qq.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The release branch independently evolved the sessions API from #2808
(POST /v1/sessions creates from a thread, /v1/sessions/{id}/resume-thread
resumes), but the turn-rewind and snapshot-restore endpoints never
landed. Port them onto the current thread model:
- POST /v1/threads/{id}/undo — fork at the Nth-from-last user message
and return the dropped user text for input pre-population.
- POST /v1/threads/{id}/patch-undo — restore the newest differing
tool:/pre-turn: workspace snapshot (same target selection as the
TUI's patch_undo), then fork the conversation; reports the file
rollback result alongside the forked thread.
- POST /v1/threads/{id}/retry — fork and immediately start a turn
re-using the dropped user text (or an override prompt), adapted to
the extended StartTurnRequest (dynamic_tools, environment_id).
- POST /v1/snapshots/{id}/restore — restore a workspace snapshot by id.
fork_at_user_message and its tests were already present; this adds the
HTTP surface plus endpoint tests for undo/patch-undo/retry/restore.
Harvested from PR #2808 by @bengao168
Co-authored-by: Ben Gao <bengao168@msn.com>
Co-authored-by: Hunter Bown <hmbown@gmail.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Port /voice, /voice-send, and /voice-control into the command strategy
registry as groups/core/voice.rs. The handlers only flip App state
(voice_enabled, voice_send_enabled, voice_control_enabled) and emit the
new AppAction::VoiceCapture; the UI event loop performs the actual
record + transcribe cycle so credentials come from the live Config
(deepseek_api_key/deepseek_base_url) instead of auth fields cached on
App, and no audio is ever recorded by the registry smoke tests.
- voice.toggle hotbar action dispatches the real /voice command and
reports voice_enabled as its active state, replacing the placeholder.
- Recording uses sox/rec/arecord with RMS-based silence detection;
transcription posts input_audio blocks to the provider chat
completions API (async reqwest — the blocking client would panic
inside the tokio event loop).
- Transcripts insert at the composer cursor via App::insert_str. With
/voice-send enabled, a transcript ending in "send it" / 发送 strips
the suffix and submits; a bare "send it" submits the current composer
content. With /voice-control enabled, transcription runs through the
AI dictation pipeline that sees the composer text.
- Failures (no recorder, no API key, short recording, network) surface
as localized status messages and disarm voice input.
- Localized command help and status strings for all seven shipped
locales; /voice now appears in the command palette.
Harvested from PR #3051 by @huqiantao
Co-authored-by: huqiantao <huqiantao@users.noreply.github.com>
Co-authored-by: Hunter B <hmbown@gmail.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>