chore(fmt): apply cargo fmt for CI parity gate
This commit is contained in:
@@ -275,8 +275,10 @@ mod tests {
|
||||
r#"{"type":"input_text","text":"x"}"#
|
||||
);
|
||||
assert_eq!(
|
||||
serde_json::to_string(&DynamicToolCallContent::InputImage { image_url: "y".into() })
|
||||
.unwrap(),
|
||||
serde_json::to_string(&DynamicToolCallContent::InputImage {
|
||||
image_url: "y".into()
|
||||
})
|
||||
.unwrap(),
|
||||
r#"{"type":"input_image","image_url":"y"}"#
|
||||
);
|
||||
}
|
||||
@@ -293,7 +295,9 @@ mod tests {
|
||||
fn dynamic_tool_call_result_roundtrip_with_content() {
|
||||
let result = DynamicToolCallResult {
|
||||
success: true,
|
||||
content: vec![DynamicToolCallContent::InputText { text: "done".into() }],
|
||||
content: vec![DynamicToolCallContent::InputText {
|
||||
text: "done".into(),
|
||||
}],
|
||||
};
|
||||
|
||||
let serialized = serde_json::to_string(&result).unwrap();
|
||||
@@ -352,6 +356,9 @@ mod tests {
|
||||
"payload": {}
|
||||
}"#;
|
||||
let envelope: RuntimeEventEnvelope = serde_json::from_str(json).unwrap();
|
||||
assert_eq!(envelope.schema_version, RUNTIME_EVENT_ENVELOPE_SCHEMA_VERSION);
|
||||
assert_eq!(
|
||||
envelope.schema_version,
|
||||
RUNTIME_EVENT_ENVELOPE_SCHEMA_VERSION
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +127,11 @@ impl DefaultKeyringStore {
|
||||
#[cfg(any(
|
||||
target_os = "macos",
|
||||
target_os = "windows",
|
||||
all(target_os = "linux", not(target_env = "ohos"), not(target_env = "musl"))
|
||||
all(
|
||||
target_os = "linux",
|
||||
not(target_env = "ohos"),
|
||||
not(target_env = "musl")
|
||||
)
|
||||
))]
|
||||
{
|
||||
// `Entry::new` is enough to validate the native macOS/Windows
|
||||
@@ -156,7 +160,11 @@ impl DefaultKeyringStore {
|
||||
#[cfg(not(any(
|
||||
target_os = "macos",
|
||||
target_os = "windows",
|
||||
all(target_os = "linux", not(target_env = "ohos"), not(target_env = "musl"))
|
||||
all(
|
||||
target_os = "linux",
|
||||
not(target_env = "ohos"),
|
||||
not(target_env = "musl")
|
||||
)
|
||||
)))]
|
||||
{
|
||||
let _ = &self.service;
|
||||
@@ -170,7 +178,11 @@ impl KeyringStore for DefaultKeyringStore {
|
||||
#[cfg(any(
|
||||
target_os = "macos",
|
||||
target_os = "windows",
|
||||
all(target_os = "linux", not(target_env = "ohos"), not(target_env = "musl"))
|
||||
all(
|
||||
target_os = "linux",
|
||||
not(target_env = "ohos"),
|
||||
not(target_env = "musl")
|
||||
)
|
||||
))]
|
||||
{
|
||||
let entry = keyring::Entry::new(&self.service, key)
|
||||
@@ -184,7 +196,11 @@ impl KeyringStore for DefaultKeyringStore {
|
||||
#[cfg(not(any(
|
||||
target_os = "macos",
|
||||
target_os = "windows",
|
||||
all(target_os = "linux", not(target_env = "ohos"), not(target_env = "musl"))
|
||||
all(
|
||||
target_os = "linux",
|
||||
not(target_env = "ohos"),
|
||||
not(target_env = "musl")
|
||||
)
|
||||
)))]
|
||||
{
|
||||
let _ = key;
|
||||
@@ -196,7 +212,11 @@ impl KeyringStore for DefaultKeyringStore {
|
||||
#[cfg(any(
|
||||
target_os = "macos",
|
||||
target_os = "windows",
|
||||
all(target_os = "linux", not(target_env = "ohos"), not(target_env = "musl"))
|
||||
all(
|
||||
target_os = "linux",
|
||||
not(target_env = "ohos"),
|
||||
not(target_env = "musl")
|
||||
)
|
||||
))]
|
||||
{
|
||||
let entry = keyring::Entry::new(&self.service, key)
|
||||
@@ -208,7 +228,11 @@ impl KeyringStore for DefaultKeyringStore {
|
||||
#[cfg(not(any(
|
||||
target_os = "macos",
|
||||
target_os = "windows",
|
||||
all(target_os = "linux", not(target_env = "ohos"), not(target_env = "musl"))
|
||||
all(
|
||||
target_os = "linux",
|
||||
not(target_env = "ohos"),
|
||||
not(target_env = "musl")
|
||||
)
|
||||
)))]
|
||||
{
|
||||
let _ = (key, value);
|
||||
@@ -220,7 +244,11 @@ impl KeyringStore for DefaultKeyringStore {
|
||||
#[cfg(any(
|
||||
target_os = "macos",
|
||||
target_os = "windows",
|
||||
all(target_os = "linux", not(target_env = "ohos"), not(target_env = "musl"))
|
||||
all(
|
||||
target_os = "linux",
|
||||
not(target_env = "ohos"),
|
||||
not(target_env = "musl")
|
||||
)
|
||||
))]
|
||||
{
|
||||
let entry = keyring::Entry::new(&self.service, key)
|
||||
@@ -233,7 +261,11 @@ impl KeyringStore for DefaultKeyringStore {
|
||||
#[cfg(not(any(
|
||||
target_os = "macos",
|
||||
target_os = "windows",
|
||||
all(target_os = "linux", not(target_env = "ohos"), not(target_env = "musl"))
|
||||
all(
|
||||
target_os = "linux",
|
||||
not(target_env = "ohos"),
|
||||
not(target_env = "musl")
|
||||
)
|
||||
)))]
|
||||
{
|
||||
let _ = key;
|
||||
@@ -249,7 +281,11 @@ impl KeyringStore for DefaultKeyringStore {
|
||||
#[cfg(not(any(
|
||||
target_os = "macos",
|
||||
target_os = "windows",
|
||||
all(target_os = "linux", not(target_env = "ohos"), not(target_env = "musl"))
|
||||
all(
|
||||
target_os = "linux",
|
||||
not(target_env = "ohos"),
|
||||
not(target_env = "musl")
|
||||
)
|
||||
)))]
|
||||
fn unsupported_keyring_message() -> String {
|
||||
"system keyring backend is unsupported on this platform".to_string()
|
||||
|
||||
@@ -83,7 +83,10 @@ fn provider_fallback(app: &mut App, subcommand: Option<&str>) -> CommandResult {
|
||||
);
|
||||
};
|
||||
CommandResult::with_message_and_action(
|
||||
format!("Fallback chain reset to primary provider: {}.", primary.as_str()),
|
||||
format!(
|
||||
"Fallback chain reset to primary provider: {}.",
|
||||
primary.as_str()
|
||||
),
|
||||
AppAction::SwitchProvider {
|
||||
provider: primary,
|
||||
model: None,
|
||||
|
||||
@@ -1764,8 +1764,8 @@ fn resolve_cors_origins(config: &Config, flag_origins: &[String]) -> Vec<String>
|
||||
for o in flag_origins {
|
||||
push(o);
|
||||
}
|
||||
if let Ok(env_value) = std::env::var("CODEWHALE_CORS_ORIGINS")
|
||||
.or_else(|_| std::env::var("DEEPSEEK_CORS_ORIGINS"))
|
||||
if let Ok(env_value) =
|
||||
std::env::var("CODEWHALE_CORS_ORIGINS").or_else(|_| std::env::var("DEEPSEEK_CORS_ORIGINS"))
|
||||
{
|
||||
for piece in env_value.split(',') {
|
||||
push(piece);
|
||||
|
||||
@@ -528,7 +528,9 @@ pub async fn run_http_server(
|
||||
if let Some(token) = runtime_token.as_deref() {
|
||||
println!("Runtime API auth: generated bearer token for this process.");
|
||||
println!(" Authorization: Bearer {token}");
|
||||
println!(" Set CODEWHALE_RUNTIME_TOKEN (or DEEPSEEK_RUNTIME_TOKEN as an alias) or pass --auth-token for a stable token.");
|
||||
println!(
|
||||
" Set CODEWHALE_RUNTIME_TOKEN (or DEEPSEEK_RUNTIME_TOKEN as an alias) or pass --auth-token for a stable token."
|
||||
);
|
||||
}
|
||||
} else if auth_enabled {
|
||||
println!("Runtime API auth: bearer token required for /v1/* routes.");
|
||||
|
||||
@@ -3785,7 +3785,7 @@ mod tests {
|
||||
archived: false,
|
||||
system_prompt: None,
|
||||
task_id: None,
|
||||
..Default::default()
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -3893,7 +3893,7 @@ mod tests {
|
||||
archived: false,
|
||||
system_prompt: None,
|
||||
task_id: None,
|
||||
..Default::default()
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -3918,7 +3918,7 @@ mod tests {
|
||||
archived: false,
|
||||
system_prompt: None,
|
||||
task_id: None,
|
||||
..Default::default()
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -3985,7 +3985,7 @@ mod tests {
|
||||
archived: false,
|
||||
system_prompt: None,
|
||||
task_id: None,
|
||||
..Default::default()
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -4019,7 +4019,7 @@ mod tests {
|
||||
archived: false,
|
||||
system_prompt: None,
|
||||
task_id: None,
|
||||
..Default::default()
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -4082,7 +4082,7 @@ mod tests {
|
||||
archived: false,
|
||||
system_prompt: None,
|
||||
task_id: None,
|
||||
..Default::default()
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -4127,7 +4127,7 @@ mod tests {
|
||||
archived: false,
|
||||
system_prompt: None,
|
||||
task_id: None,
|
||||
..Default::default()
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -4172,7 +4172,7 @@ mod tests {
|
||||
archived: false,
|
||||
system_prompt: None,
|
||||
task_id: None,
|
||||
..Default::default()
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -4206,7 +4206,7 @@ mod tests {
|
||||
archived: false,
|
||||
system_prompt: None,
|
||||
task_id: None,
|
||||
..Default::default()
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -4257,7 +4257,7 @@ mod tests {
|
||||
archived: false,
|
||||
system_prompt: None,
|
||||
task_id: None,
|
||||
..Default::default()
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -4384,7 +4384,7 @@ mod tests {
|
||||
archived: false,
|
||||
system_prompt: None,
|
||||
task_id: None,
|
||||
..Default::default()
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -4460,7 +4460,7 @@ mod tests {
|
||||
archived: false,
|
||||
system_prompt: None,
|
||||
task_id: None,
|
||||
..Default::default()
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -4554,7 +4554,7 @@ mod tests {
|
||||
archived: false,
|
||||
system_prompt: None,
|
||||
task_id: None,
|
||||
..Default::default()
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -4642,7 +4642,7 @@ mod tests {
|
||||
archived: false,
|
||||
system_prompt: None,
|
||||
task_id: None,
|
||||
..Default::default()
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -4739,7 +4739,7 @@ mod tests {
|
||||
archived: false,
|
||||
system_prompt: None,
|
||||
task_id: None,
|
||||
..Default::default()
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -4821,7 +4821,7 @@ mod tests {
|
||||
archived: false,
|
||||
system_prompt: None,
|
||||
task_id: None,
|
||||
..Default::default()
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
let mut harness = install_mock_engine(&manager, &thread.id).await;
|
||||
@@ -4934,7 +4934,7 @@ mod tests {
|
||||
archived: false,
|
||||
system_prompt: None,
|
||||
task_id: None,
|
||||
..Default::default()
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
assert!(!manager.store.load_thread(&thread.id)?.auto_approve);
|
||||
@@ -5020,7 +5020,7 @@ mod tests {
|
||||
archived: false,
|
||||
system_prompt: None,
|
||||
task_id: None,
|
||||
..Default::default()
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -5107,7 +5107,7 @@ mod tests {
|
||||
archived: false,
|
||||
system_prompt: None,
|
||||
task_id: None,
|
||||
..Default::default()
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -5218,7 +5218,7 @@ mod tests {
|
||||
archived: false,
|
||||
system_prompt: None,
|
||||
task_id: None,
|
||||
..Default::default()
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -5734,7 +5734,7 @@ mod tests {
|
||||
archived: false,
|
||||
system_prompt: None,
|
||||
task_id: None,
|
||||
..Default::default()
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
seed_turns_with_user_messages(&manager, &thread.id, &["first", "second", "third"])?;
|
||||
@@ -5771,7 +5771,7 @@ mod tests {
|
||||
archived: false,
|
||||
system_prompt: None,
|
||||
task_id: None,
|
||||
..Default::default()
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
seed_turns_with_user_messages(&manager, &thread.id, &["a", "b", "c", "d"])?;
|
||||
@@ -5801,7 +5801,7 @@ mod tests {
|
||||
archived: false,
|
||||
system_prompt: None,
|
||||
task_id: None,
|
||||
..Default::default()
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
seed_turns_with_user_messages(&manager, &thread.id, &["only"])?;
|
||||
@@ -5828,7 +5828,7 @@ mod tests {
|
||||
archived: false,
|
||||
system_prompt: None,
|
||||
task_id: None,
|
||||
..Default::default()
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
let turn_ids = seed_turns_with_user_messages(&manager, &thread.id, &["x", "y", "z"])?;
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
v0.8.59
|
||||
|
||||
CodeWhale v0.8.59 is a stability and integration release that hardens the TUI,
|
||||
improves sidebar interactivity, localizes notifications, cleans up user-facing
|
||||
naming, and adds experimental config and runtime API foundations.
|
||||
|
||||
---
|
||||
|
||||
## TUI stability and interactivity
|
||||
|
||||
- **Sidebar resize stays live during active turns** — the split pane no longer
|
||||
freezes while the model is generating.
|
||||
- **Sidebar hover stays live while loading** — detail popovers update in real
|
||||
time instead of dropping mid-turn.
|
||||
- **Hover highlight cleared on exit** — stale highlight state no longer
|
||||
persists after leaving the sidebar.
|
||||
- **Ghostty motion override kept live** — mouse motion events continue to
|
||||
work correctly in Ghostty terminals.
|
||||
- **Mouse-report sanitizer added** — raw SGR mouse reports are sanitized
|
||||
defensively so corrupted composer input is blocked.
|
||||
- **Sidebar Copy action** — the right-click context menu now includes Copy
|
||||
alongside existing actions.
|
||||
- **Richer Work overflow and Agents hover detail** — sidebar detail
|
||||
popovers surface more information for Work and Agents entries.
|
||||
- **Provider-wait state is now observable** — the TUI shows route, idle
|
||||
budget, and fanout-preflight state during provider waits.
|
||||
- **fanout launches are queued behind a visible launch gate** — interactive
|
||||
fanout no longer stalls the TUI without feedback.
|
||||
|
||||
## Sub-agent safety and worker-ledger substrate
|
||||
|
||||
- **Sub-agents survive backgrounded waits** — worker cards are no longer
|
||||
dropped when the TUI yields during long waits.
|
||||
- **Interrupted sub-agent lifecycle events are emitted** — stale running
|
||||
cards are reconciled with actual state.
|
||||
- **Runtime-prompt stand-still guard** — the TUI no longer spins in an
|
||||
autonomous loop when the launch gate is closed.
|
||||
|
||||
## i18n and user-facing naming
|
||||
|
||||
- **Notifications are now localized** — notification text respects the
|
||||
configured language instead of always rendering in English.
|
||||
- **Tool family labels are localized** — 10 tool family labels now use
|
||||
MessageId-based i18n.
|
||||
- **Config editor labels are localized** — config section editor labels
|
||||
follow the configured language.
|
||||
- **"Bash" shown in user-facing UI** — shell execution is surfaced as "Bash"
|
||||
in the TUI while `exec_shell` remains the internal tool name.
|
||||
|
||||
## Provider and model updates
|
||||
|
||||
- **Kimi OAuth credentials aligned with Kimi Code** — the config path for
|
||||
Kimi OAuth credentials now matches the Kimi Code provider surface.
|
||||
- **Kimi K2.7 Code defaults added** — model metadata for Kimi K2.7 Code is
|
||||
included.
|
||||
- **SiliconFlow CN provider config split** — a separate provider entry for
|
||||
SiliconFlow China is available.
|
||||
- **Provider metadata registry refactored** — provider metadata is now
|
||||
data-driven and easier to extend.
|
||||
- **OpenRouter Nemotron preset fixed** — the invalid model ID is corrected.
|
||||
- **Provider fallback chain activated** — harvested from community PR #2773.
|
||||
|
||||
## Experimental config and runtime API
|
||||
|
||||
- **Experimental feature flags** — `[experimental]` config section for goal
|
||||
and WhaleFlow opt-ins, surfaced through normal config paths.
|
||||
- **Runtime API Phase 0 + Phase 1** — brand-neutral naming, capabilities
|
||||
advertisement, and dynamic tool protocol types for editor/GUI clients.
|
||||
- **Command strategy registry** — harvested from community PR #2851.
|
||||
- **Context source map report** — visibility into rules, tools, memory, and
|
||||
skills contributions to prompt cost.
|
||||
|
||||
## Community harvests
|
||||
|
||||
- **PR #3010** — lock slim default prompt with calm-overlay regression test.
|
||||
- **PR #2808** — thread undo/retry and snapshot restore endpoints.
|
||||
- **PR #3051** — voice input commands and hotbar integration.
|
||||
- **PR #2773** — activate provider fallback chain.
|
||||
- **PR #2851** — command strategy registry.
|
||||
|
||||
## Other fixes and improvements
|
||||
|
||||
- **macOS Command modifier normalized to Control** for keyboard shortcuts
|
||||
(#2938).
|
||||
- **Hotbar slots dispatched from number keys**.
|
||||
- **Thread goals persisted through the app server**.
|
||||
- **Concise verbosity mode added** to config.
|
||||
- **Workspace trust required for project hooks** — safety boundary
|
||||
enforced.
|
||||
- **Thread detail item reads batched** — N+1 query fix.
|
||||
- **Legacy deepseek users guided to codewhale** in update paths.
|
||||
- **Static Linux x64 musl binaries** now built.
|
||||
- **Approval rule metadata exposed at runtime**.
|
||||
- **Codex response errors clarified** in TUI.
|
||||
- **Microsoft Build Tools / cmake --build** shell compatibility fix.
|
||||
- **PDF extraction hardened** for non-Identity-H CMap fonts.
|
||||
|
||||
---
|
||||
|
||||
**Full headless sub-agents (fleet manager, worker runtime, durable inbox/ledger)
|
||||
are deferred to v0.8.60 / #3096.** The v0.8.59 release includes the
|
||||
sub-agent safety and worker-ledger substrate that v0.8.60 builds on.
|
||||
|
||||
**v0.8.60+ tracking issues remain open:**
|
||||
- #3096 — Full headless sub-agents and worker runtime
|
||||
- #1310 — MiniMax first-party provider
|
||||
- #3187 — Z.ai / StepFlash first-party providers
|
||||
Reference in New Issue
Block a user