feat: unify native/web app core and split runtime adapters#41
Conversation
Summary by CodeRabbit
WalkthroughBehold: the monolithal TUI was split into a shared app_core and two runtimes (native TUI and wasm/web). Models and indexing/search were centralized, platform-specific binaries and deps added, and documentation plus a web entrypoint (index.html) introduced. No hidden opinions. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Browser as Browser (DOM)
participant Wasm as Ratzilla (WASM)
participant Reducer as Input Reducer (app_core)
participant AppState as AppState (Shared)
participant Fetcher as Data Loader (web/native)
participant Renderer as UI Renderer (Terminal/DOM)
Browser->>Wasm: DOM Key/Mouse Event
Wasm->>Reducer: AppKeyEvent / AppMouseEvent
Reducer->>AppState: mutate(state) (focus, filter, select)
AppState->>AppState: update caches & display
alt dataset action
AppState->>Fetcher: request(version/reload)
Fetcher->>AppState: Root JSON (with progress updates)
AppState->>AppState: build_index (progress)
end
AppState->>Renderer: render frame
Renderer->>Browser: DOM/Terminal update
sequenceDiagram
autonumber
participant User as User
participant Native as Native Runtime (cbn-tui)
participant Core as Shared Core (app_core)
participant Data as Data Service / CDN
participant Term as Terminal
User->>Native: CLI args / events
Native->>Core: AppState::new(...)
Native->>Data: fetch_root / load local
Data->>Core: Root -> index items (with index_item calls)
Core->>Term: render progress & frames
User->>Native: keyboard/mouse
Native->>Core: handle_key_event / handle_mouse_event
Core->>Term: redraw
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@Cargo.toml`:
- Around line 17-39: The ratatui feature "layout-cache" in the
[target.'cfg(target_arch = "wasm32")'.dependencies] block may require std and
thus may be inappropriate for no_std wasm builds; inspect the ratatui = {
version = "0.30.0", default-features = false, features = ["all-widgets",
"layout-cache"] } entry and either remove "layout-cache" or enable std (or
switch to a wasm target that supports std, e.g., wasm32-wasi) depending on
whether your wasm target supports std; update the features for the ratatui
dependency accordingly to avoid pulling in std-only functionality when targeting
no_std wasm.
In `@index.html`:
- Around line 7-10: The external Fira Code stylesheet link (the <link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/fira_code.min.css"
/> tag) relies on Cloudflare CDN and may fail offline; update the HTML to
provide resilience by adding a local fallback: include a local `@font-face` (or
local stylesheet) for Fira Code in your assets and alter the document to prefer
the local file when available (or add a <link rel="preload"> plus a small inline
CSS font-family fallback stack that includes monospace), and ensure the
font-family usages reference the fallback stack so the page degrades gracefully
if the CDN resource is unavailable.
- Around line 33-46: The `#grid` rule contains duplicated width and height
declarations—remove the earlier redundant width: 100% and height: 100% entries
so only the intended final values remain (retain one width declaration and
height: 100vh); locate the CSS rule for the selector `#grid` and delete the
duplicate lines to avoid dead code and clarify intent.
In `@src/app_core/reducer.rs`:
- Around line 372-415: Ctrl-click currently sets app.filter_text =
format!("i:{}", final_val) which filters by id only; change it to include the
item type to avoid collisions by building a type token (prefer the matched
span's type metadata if available, e.g., span.span_type or
span.span.entity_type; if not present, derive a type from target_path's first
segment) and then set app.filter_text = format!("t:{} i:{}", type_token,
final_val); keep updating app.filter_cursor, call app.update_filter() and
app.focus_pane(FocusPane::Details) as before.
In `@src/model.rs`:
- Around line 61-100: The deserializer requires Proxy.build_number as String
which will fail if the root JSON omits it; change Proxy.build_number to
Option<String>, treat missing value as empty string by using unwrap_or_default()
when initializing build_number and tag_name (e.g., let build_number =
proxy.build_number.unwrap_or_default(); let mut tag_name =
build_number.clone();), and then construct BuildInfo with that build_number
value so deserialization succeeds on missing fields; update all references in
the impl Deserialize for BuildInfo to use proxy.build_number.unwrap_or_default()
(and replace proxy.build_number.clone() uses) accordingly.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@index.html`:
- Around line 7-10: Add a short explanatory HTML comment immediately before the
<link> tag (the element with href
"https://cdnjs.cloudflare.com/ajax/libs/juliamono/0.061/juliamono-regular.css")
that documents why the font is loaded from Cloudflare CDN and the trade-offs
(e.g., improved load performance and caching vs. external
request/privacy/availability risks and fallback considerations), so future
maintainers understand the decision and can change to a self-hosted or
alternative approach if needed.
Summary
src/app_core(state, reducer, input model, indexing helpers)src/runtime/nativeandsrc/runtime/webcbn-weband update trunkdata-binwiringmodelmodule and update matcher/search/index/ui usage to consume shared typesapp_core::web_mouse)docs/skills/web-native-parity/SKILL.mdand runtime-priority note inAGENTS.mdWhy
This minimizes divergence between TUI and web by keeping behavior in shared code and leaving runtime files as thin adapters.
Validation
cargo fmt --allcargo test --offlinecargo check --offline --features web --bin cbn-web --target wasm32-unknown-unknown