Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion app/src/ai/agent_sdk/driver/harness/claude_transcript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,6 @@ pub(crate) fn read_envelope(
/// - `<config_root>/projects/<encoded_cwd>/<uuid>.jsonl` - main transcript
/// - `<config_root>/projects/<encoded_cwd>/<uuid>/subagents/<stem>.jsonl` - subagents
/// - `<config_root>/todos/<stem>.json` - per-agent todo lists

fn validated_stem<'a>(stem: &'a str, field_name: &str) -> Result<&'a str> {
anyhow::ensure!(!stem.is_empty(), "{field_name} stem cannot be empty");
let path = Path::new(stem);
Expand Down
1 change: 1 addition & 0 deletions app/src/ai/coven_brand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub(crate) const OPENCOVEN_WARNING: ColorU = ColorU {

/// Brand muted text colour (`#5A5A65`) — used for closed-session status
/// dots and secondary metadata in Coven session rows.
#[allow(dead_code)]
pub(crate) const OPENCOVEN_MUTED: ColorU = ColorU {
r: 90,
g: 90,
Expand Down
9 changes: 9 additions & 0 deletions app/src/browser/browser_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,18 +144,25 @@ impl BrowserTab {
true
}

// Tab pin + favicon accessors/mutators are scaffolding for an upcoming
// tab-strip UI revision; no caller wires them yet but they're read by
// the matching BrowserModel helpers below.
#[allow(dead_code)]
pub fn pinned(&self) -> bool {
self.pinned
}

#[allow(dead_code)]
pub fn favicon(&self) -> Option<&str> {
self.favicon.as_deref()
}

#[allow(dead_code)]
fn set_pinned(&mut self, pinned: bool) {
self.pinned = pinned;
}

#[allow(dead_code)]
fn set_favicon(&mut self, favicon: Option<String>) {
self.favicon = favicon;
}
Expand Down Expand Up @@ -324,6 +331,7 @@ impl BrowserModel {
self.tabs[idx].replace_current_url(url)
}

#[allow(dead_code)]
pub fn set_pinned(&mut self, id: TabId, pinned: bool) -> bool {
let Some(idx) = self.index_of(id) else {
return false;
Expand All @@ -332,6 +340,7 @@ impl BrowserModel {
true
}

#[allow(dead_code)]
pub fn set_favicon(&mut self, id: TabId, favicon: Option<String>) -> bool {
let Some(idx) = self.index_of(id) else {
return false;
Expand Down
49 changes: 29 additions & 20 deletions app/src/browser/browser_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,13 +392,11 @@ impl BrowserView {
editor
});

ctx.subscribe_to_view(&find_editor, move |view, _, event, ctx| {
match event {
EditorEvent::Edited(_) => view.handle_find_query_changed(ctx),
EditorEvent::Enter => view.handle_action(&BrowserViewAction::FindNext, ctx),
EditorEvent::Escape => view.handle_action(&BrowserViewAction::CloseFind, ctx),
_ => {}
}
ctx.subscribe_to_view(&find_editor, move |view, _, event, ctx| match event {
EditorEvent::Edited(_) => view.handle_find_query_changed(ctx),
EditorEvent::Enter => view.handle_action(&BrowserViewAction::FindNext, ctx),
EditorEvent::Escape => view.handle_action(&BrowserViewAction::CloseFind, ctx),
_ => {}
});

Self {
Expand Down Expand Up @@ -512,13 +510,11 @@ impl BrowserView {
editor
});

ctx.subscribe_to_view(&find_editor, move |view, _, event, ctx| {
match event {
EditorEvent::Edited(_) => view.handle_find_query_changed(ctx),
EditorEvent::Enter => view.handle_action(&BrowserViewAction::FindNext, ctx),
EditorEvent::Escape => view.handle_action(&BrowserViewAction::CloseFind, ctx),
_ => {}
}
ctx.subscribe_to_view(&find_editor, move |view, _, event, ctx| match event {
EditorEvent::Edited(_) => view.handle_find_query_changed(ctx),
EditorEvent::Enter => view.handle_action(&BrowserViewAction::FindNext, ctx),
EditorEvent::Escape => view.handle_action(&BrowserViewAction::CloseFind, ctx),
_ => {}
});

Self {
Expand Down Expand Up @@ -567,7 +563,10 @@ impl BrowserView {

fn zoom_in(&mut self, ctx: &mut ViewContext<Self>) {
let tab_id = self.model.active_tab().id();
let cur = *self.tab_zoom_steps.get(&tab_id).unwrap_or(&DEFAULT_ZOOM_STEP);
let cur = *self
.tab_zoom_steps
.get(&tab_id)
.unwrap_or(&DEFAULT_ZOOM_STEP);
let next = zoom_step_in(cur);
if next == cur {
return;
Expand All @@ -579,7 +578,10 @@ impl BrowserView {

fn zoom_out(&mut self, ctx: &mut ViewContext<Self>) {
let tab_id = self.model.active_tab().id();
let cur = *self.tab_zoom_steps.get(&tab_id).unwrap_or(&DEFAULT_ZOOM_STEP);
let cur = *self
.tab_zoom_steps
.get(&tab_id)
.unwrap_or(&DEFAULT_ZOOM_STEP);
let next = zoom_step_out(cur);
if next == cur {
return;
Expand Down Expand Up @@ -936,6 +938,7 @@ impl BrowserView {
}
}

#[allow(clippy::too_many_arguments)]
fn render_toolbar_button(
&self,
icon: Icon,
Expand Down Expand Up @@ -1289,6 +1292,7 @@ impl BrowserView {
.finish()
}

#[allow(clippy::too_many_arguments)]
fn render_tab_chip(
&self,
idx: usize,
Expand Down Expand Up @@ -1324,7 +1328,7 @@ impl BrowserView {
Icon::X,
TAB_CLOSE_BUTTON_SIZE,
close_mouse,
chip_text_color.into(),
chip_text_color,
)
.with_tooltip(move || {
ui_builder
Expand Down Expand Up @@ -1474,13 +1478,15 @@ impl TypedActionView for BrowserView {
}
BrowserViewAction::ToggleFind => self.toggle_find(ctx),
BrowserViewAction::CloseFind => self.close_find(ctx),
BrowserViewAction::FindNext => {
BrowserViewAction::FindNext =>
{
#[cfg(not(target_family = "wasm"))]
Comment on lines 1479 to 1483
if let Some(webview) = self.active_webview() {
webview.borrow().find_next();
}
}
BrowserViewAction::FindPrev => {
BrowserViewAction::FindPrev =>
{
#[cfg(not(target_family = "wasm"))]
Comment on lines 1486 to 1490
if let Some(webview) = self.active_webview() {
webview.borrow().find_prev();
Expand All @@ -1503,7 +1509,10 @@ impl BackingView for BrowserView {
_ctx: &AppContext,
) -> Vec<MenuItem<BrowserViewAction>> {
let tab_id = self.model.active_tab().id();
let cur = *self.tab_zoom_steps.get(&tab_id).unwrap_or(&DEFAULT_ZOOM_STEP);
let cur = *self
.tab_zoom_steps
.get(&tab_id)
.unwrap_or(&DEFAULT_ZOOM_STEP);
let pct = (zoom_level_for_step(cur) * 100.0).round() as i32;
let reset_label = format!("Reset zoom ({pct}%)");
let modifier = if cfg!(target_os = "macos") {
Expand Down
6 changes: 6 additions & 0 deletions app/src/browser/downloads.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
// Helpers are consumed by `browser/webview_host.rs`, which is itself
// scaffolding for the in-progress download pipeline. Until that pipeline
// gets wired up to a real wry handler, the call chain is unreachable from
// production code paths, so allow dead_code at the module level.
#![allow(dead_code)]

//! Download destination resolution for the embedded browser pane.
//!
//! wry exposes `with_download_started_handler` (a `Fn(url, &mut PathBuf)
Expand Down
6 changes: 6 additions & 0 deletions app/src/browser/find.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ pub(crate) fn clear_script() -> &'static str {

/// Shape of the JSON message the find script posts back via
/// `window.ipc.postMessage`. See `assets/bundled/js/find.js`.
//
// Constructed only by serde inside webview_host's macOS-gated IPC
// handler; on Linux/Windows the type compiles but nothing deserializes
// into it. Allowed at the struct level until the non-macOS wry wiring
// lands.
#[allow(dead_code)]
#[derive(Debug, Clone, Deserialize)]
pub(crate) struct FindResultsMessage {
pub kind: String,
Expand Down
5 changes: 5 additions & 0 deletions app/src/browser/popup_policy.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
// Consumed by `browser/webview_host.rs`'s in-progress popup wiring; until
// that handler is hooked to wry, the call chain is unreachable from
// production paths.
#![allow(dead_code)]

//! Policy decisions for popups (`window.open` / `target="_blank"`) inside
//! the embedded browser pane.
//!
Expand Down
18 changes: 16 additions & 2 deletions app/src/browser/webview_host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ use super::browser_model::TabId;
#[cfg(target_os = "macos")]
use super::downloads;
#[cfg(not(target_family = "wasm"))]
use super::find::{self, FindResultsMessage};
#[cfg(not(target_family = "wasm"))]
use super::find;
#[cfg(target_os = "macos")]
use super::find::FindResultsMessage;
#[cfg(target_os = "macos")]
use super::popup_policy::{self, Decision};

/// Events the native webview layer can push back to `BrowserView`.
Expand All @@ -21,6 +23,13 @@ use super::popup_policy::{self, Decision};
/// receiver doesn't need a parallel mapping. Popup events don't carry a
/// `TabId` — the host treats them as "open a new tab" and the new tab gets
/// its own id.
//
// Variants are constructed only by the macOS-gated `attach_if_needed`
// path (wry handlers); `browser_view.rs` matches on them cross-platform,
// so on Linux/Windows builds the variants compile but never get
// constructed. Allowed at the enum level until the non-macOS wry wiring
// lands.
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub(crate) enum NativeWebViewEvent {
/// Document title changed (raw from WKWebView).
Expand All @@ -44,6 +53,11 @@ pub(crate) enum NativeWebViewEvent {
#[cfg(not(target_family = "wasm"))]
pub(crate) type SharedWebContext = Rc<RefCell<wry::WebContext>>;

// `tab_id`, `event_tx`, and `web_context` are read only by the macOS
// `attach_if_needed` path; on Linux/Windows builds they get stored at
// construction but never read. Allowed at the struct level until the
// non-macOS wry wiring lands.
#[allow(dead_code)]
pub(crate) struct NativeBrowserWebView {
tab_id: TabId,
#[cfg(not(target_family = "wasm"))]
Expand Down
14 changes: 14 additions & 0 deletions app/src/cli_chat/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,28 @@
//!
//! See `specs/castcodes-chat-panel/PRODUCT.md` and `TECH.md`.

// The chat panel feature is half-wired: model/store/view layers are in
// tree but no caller binds them to a live `CLIAgentSessionsModel` yet.
// Until that wiring lands, scaffolding accessors / strings / setup
// helpers are unconstructed. Allow at each submodule declaration so the
// scaffolding compiles without churn.
#[allow(dead_code)]
pub mod conversation;
#[allow(dead_code)]
pub mod entry;
#[allow(dead_code)]
pub mod feature_flag;
#[allow(dead_code)]
pub mod model;
#[allow(dead_code)]
pub mod paths;
#[allow(dead_code)]
pub mod store;
#[allow(dead_code)]
pub mod store_schema;
#[allow(dead_code)]
pub mod strings;
#[allow(dead_code)]
pub mod view;

pub use model::ChatModel;
Expand Down
2 changes: 1 addition & 1 deletion app/src/cli_chat/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ impl ChatStore {
)?;

let convs = stmt
.query_map([], |row| row_to_conversation(row))?
.query_map([], row_to_conversation)?
.collect::<rusqlite::Result<Vec<_>>>()?;

let mut result = Vec::with_capacity(convs.len());
Expand Down
4 changes: 2 additions & 2 deletions app/src/cli_chat/store_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ pub fn migrate(conn: &Connection) -> Result<()> {
return Err(rusqlite::Error::InvalidQuery);
}

for v in (current as usize)..MIGRATIONS.len() {
for stmt in MIGRATIONS[v] {
for (v, migration) in MIGRATIONS.iter().enumerate().skip(current as usize) {
for stmt in *migration {
conn.execute(stmt, [])?;
}
conn.execute(
Expand Down
1 change: 1 addition & 0 deletions app/src/cli_chat/view/empty_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use warpui::fonts::FamilyId;
use crate::cli_chat::strings;

/// Which empty state to display.
#[allow(clippy::enum_variant_names)]
pub(crate) enum EmptyKind {
/// No conversations at all — invite the user to run a CLI.
NoHistory,
Expand Down
2 changes: 1 addition & 1 deletion app/src/cli_chat/view/model_picker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub fn render(view: &ChatPanelView, app: &AppContext) -> Box<dyn Element> {

// Determine the label for the current agent/model.
let chat = view.chat_model.as_ref(app);
let label = current_agent_model_label(chat.binding(), &chat, app);
let label = current_agent_model_label(chat.binding(), chat, app);

let label_element = Text::new(label, font_family, font_size).finish();

Expand Down
16 changes: 4 additions & 12 deletions app/src/pane_group/pane/browser_pane.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,7 @@ impl BrowserPane {
/// platform notes). It is accepted unconditionally so callers don't
/// need to cfg-gate; on wasm it is discarded because there is no
/// WebKit data store to scope.
pub fn new<V: View>(
url: Option<String>,
session_id: String,
ctx: &mut ViewContext<V>,
) -> Self {
pub fn new<V: View>(url: Option<String>, session_id: String, ctx: &mut ViewContext<V>) -> Self {
let view = ctx.add_typed_action_view(move |ctx| {
#[cfg(not(target_family = "wasm"))]
{
Expand All @@ -62,8 +58,8 @@ impl BrowserPane {
session_id: String,
ctx: &mut ViewContext<V>,
) -> Self {
let view = ctx
.add_typed_action_view(move |ctx| BrowserView::from_state(state, &session_id, ctx));
let view =
ctx.add_typed_action_view(move |ctx| BrowserView::from_state(state, &session_id, ctx));
Self::from_view(view, ctx)
}

Expand Down Expand Up @@ -142,11 +138,7 @@ impl PaneContent for BrowserPane {
self.view.as_ref(ctx).is_being_dragged()
}

fn on_workspace_tab_visibility_changed(
&self,
visible: bool,
ctx: &mut ViewContext<PaneGroup>,
) {
fn on_workspace_tab_visibility_changed(&self, visible: bool, ctx: &mut ViewContext<PaneGroup>) {
let browser_view = self.browser_view(ctx);
browser_view.update(ctx, |view, _ctx| view.set_workspace_tab_visible(visible));
}
Expand Down
4 changes: 3 additions & 1 deletion app/src/server/server_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,9 @@ pub enum ServerApiEvent {
UserAccountDisabled,
/// The current bearer token was refreshed.
AccessTokenRefreshed {
#[cfg_attr(target_family = "wasm", allow(dead_code))]
// Currently only the Debug impl reads this; consumers don't yet
// observe the refreshed value. Allow until a consumer wires up.
#[allow(dead_code)]
token: String,
},
}
Expand Down
3 changes: 3 additions & 0 deletions app/src/settings/import/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ use super::{alacritty_parser::AlacrittyConfig, model::TerminalType};
#[cfg(target_os = "macos")]
use super::iterm_parser::ITermProfile;

// Theme imports surface this enum once per UI action, so the size delta
// between variants isn't a hot-path concern — allow the lint here.
#[allow(clippy::large_enum_variant)]
#[derive(Debug)]
pub enum ThemeType {
LightAndDark { light: WarpTheme, dark: WarpTheme },
Expand Down
10 changes: 2 additions & 8 deletions app/src/settings_view/import_theme_modal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,7 @@ impl ImportThemeBody {
ctx.emit(ImportThemeBodyEvent::Close);
}
Ok(_) => {
self.show_error =
Some("No color blocks were found in the theme.".to_string());
self.show_error = Some("No color blocks were found in the theme.".to_string());
ctx.notify();
}
Err(e) => {
Expand Down Expand Up @@ -282,12 +281,7 @@ impl View for ImportThemeBody {

// ── Status line ───────────────────────────────────────────────────
let (status_text, status_color, has_light, has_dark) = match &self.state {
FetchState::Idle => (
String::new(),
theme.disabled_ui_text_color(),
false,
false,
),
FetchState::Idle => (String::new(), theme.disabled_ui_text_color(), false, false),
FetchState::Fetching => (
"Fetching theme…".to_string(),
theme.disabled_ui_text_color(),
Expand Down
Loading
Loading