From 4839c8d593e6b787a0485efc503267958cd0100d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Olveck=C3=BD?= Date: Thu, 15 Oct 2026 07:44:19 +0000 Subject: [PATCH 1/3] feat: hide extension functions in component exports by default Add a checkbox to the component Exports tab to show the -obelisk-ext, -obelisk-stub and -obelisk-schedule interfaces. --- .../webui/src/components/component_detail.rs | 41 ++++++++++++++++--- crates/webui/styles/pages/_deployment.scss | 7 ++++ 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/crates/webui/src/components/component_detail.rs b/crates/webui/src/components/component_detail.rs index 88899da..4bfcbf5 100644 --- a/crates/webui/src/components/component_detail.rs +++ b/crates/webui/src/components/component_detail.rs @@ -269,6 +269,7 @@ pub fn component_detail( let wit_state = use_state(|| None); let wit_loaded = use_state(|| false); let selected_tab = use_state(|| ComponentDetailTab::Exports); + let show_extensions = use_state(|| false); let deployment_config = use_state(|| None::, String>>); // Fetch raw WIT only when its tab is selected. @@ -390,7 +391,18 @@ pub fn component_detail( } }); - let exports = map_interfaces_to_fn_details(component.exported_fns(), InterfaceFilter::All); + let has_extensions = component + .exported_fns() + .iter() + .any(|fn_detail| fn_detail.ffqn.ifc_fqn.is_extension()); + let exports = map_interfaces_to_fn_details( + component.exported_fns(), + if *show_extensions { + InterfaceFilter::All + } else { + InterfaceFilter::WithoutExtensions + }, + ); let render_exported_ifc_with_fns = |ifc_fqn: &IfcFqnName, fn_details: &[FunctionMetadataLite]| { let exported_fn_details = fn_details @@ -433,15 +445,32 @@ pub fn component_detail( .iter() .map(|(ifc_fqn, fn_details)| render_exported_ifc_with_fns(ifc_fqn, fn_details)) .collect::>(); - let exported_functions = if exported_ifcs_fns.is_empty() { - html! { + let on_show_extensions_change = { + let show_extensions = show_extensions.clone(); + Callback::from(move |e: Event| { + let input: web_sys::HtmlInputElement = e.target_unchecked_into(); + show_extensions.set(input.checked()); + }) + }; + let exported_functions = html! { <> + if has_extensions { + + } + if exported_ifcs_fns.is_empty() {

{"This component does not export any functions."}

+ } else { + { for exported_ifcs_fns } } - } else { - html! { <>{ for exported_ifcs_fns } } - }; + }; let dependencies = || { let connections = component_connections(component, deployment_components); diff --git a/crates/webui/styles/pages/_deployment.scss b/crates/webui/styles/pages/_deployment.scss index 5d65df5..c7fde3b 100644 --- a/crates/webui/styles/pages/_deployment.scss +++ b/crates/webui/styles/pages/_deployment.scss @@ -303,6 +303,13 @@ .component-detail-tabs { margin-top: $spacing-sm; } .component-detail-tab-content { min-height: 0; } + + .component-show-extensions { + display: inline-flex; + align-items: center; + gap: $spacing-xs; + margin: $spacing-sm 0; + } } .deployment-component-search { From 558458b62a1dcd4750f3ceead813490cd3708b89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Olveck=C3=BD?= Date: Thu, 15 Oct 2026 07:46:22 +0000 Subject: [PATCH 2/3] feat: show WASM component sources as non-expandable binaries The Sources tab listed the WASM component as an expandable source, fetching and rendering binary content. Show it as a static row instead. --- .../webui/src/components/component_detail.rs | 11 +++++-- .../src/components/deployment_config_view.rs | 33 +++++++++++++++---- .../src/components/deployment_diff_page.rs | 1 + crates/webui/styles/pages/_definitions.scss | 15 ++++++++- 4 files changed, 49 insertions(+), 11 deletions(-) diff --git a/crates/webui/src/components/component_detail.rs b/crates/webui/src/components/component_detail.rs index 4bfcbf5..e90a0d4 100644 --- a/crates/webui/src/components/component_detail.rs +++ b/crates/webui/src/components/component_detail.rs @@ -184,11 +184,16 @@ fn component_file_sources(files: &[ComponentFileRef]) -> Vec { return None; } let file = &file_ref.file; + let content = if role == ComponentFileRole::WasmComponent { + SourceContent::Binary + } else { + SourceContent::FetchFile { + digest: file.digest.clone(), + } + }; Some(SourceView { file_name: file.path.clone(), - content: SourceContent::FetchFile { - digest: file.digest.clone(), - }, + content, metadata: Some(SourceMetadata { role: component_file_role_label(role), entrypoint: role == ComponentFileRole::JsEntrypoint, diff --git a/crates/webui/src/components/deployment_config_view.rs b/crates/webui/src/components/deployment_config_view.rs index e0e6df0..f54e3d9 100644 --- a/crates/webui/src/components/deployment_config_view.rs +++ b/crates/webui/src/components/deployment_config_view.rs @@ -78,6 +78,8 @@ pub enum SourceContent { Fetch { file: String, }, + /// A binary file such as a WASM component, listed but not displayable. + Binary, } const SOURCE_MARKER: &str = "(source rendered below)"; @@ -432,7 +434,9 @@ pub fn collapsible_source( .as_ref() .and_then(|result| result.as_ref().as_ref().ok()) .cloned(), - SourceContent::Oci { .. } | SourceContent::ExternalPath { .. } => None, + SourceContent::Oci { .. } + | SourceContent::ExternalPath { .. } + | SourceContent::Binary => None, }?; let language = PathBuf::from(&source.file_name) .extension() @@ -444,11 +448,20 @@ pub fn collapsible_source( }, ); + if source.content == SourceContent::Binary { + return html! { +
+
{ source_summary_contents(source) }
+
+ }; + } + let body = if !*opened { html! {} } else { let source_available = match &source.content { SourceContent::Inline(_) => true, + SourceContent::Binary => unreachable!("binary sources return early"), SourceContent::Oci { image } => { return html! {
@@ -518,16 +531,22 @@ fn source_summary(source: &SourceView) -> Html { .is_some_and(|metadata| metadata.entrypoint); html! { - { &source.file_name } - if let Some(metadata) = &source.metadata { - - } + { source_summary_contents(source) } } } +fn source_summary_contents(source: &SourceView) -> Html { + html! { <> + { &source.file_name } + if let Some(metadata) = &source.metadata { + + } + } +} + #[derive(Properties, PartialEq)] pub struct DeploymentConfigViewProps { pub sections: Vec, diff --git a/crates/webui/src/components/deployment_diff_page.rs b/crates/webui/src/components/deployment_diff_page.rs index f72ce11..e7d6faa 100644 --- a/crates/webui/src/components/deployment_diff_page.rs +++ b/crates/webui/src/components/deployment_diff_page.rs @@ -430,6 +430,7 @@ async fn resolve_source(source: SourceView, component_id: Option) - SourceContent::ExternalPath { path } => ResolvedSource::Note(format!( "Source is read at runtime from the external path `{path}`." )), + SourceContent::Binary => ResolvedSource::Note("Binary file, not shown.".to_string()), SourceContent::FetchFile { digest } => rest::deployments::file(&digest) .await .map(ResolvedSource::Text) diff --git a/crates/webui/styles/pages/_definitions.scss b/crates/webui/styles/pages/_definitions.scss index 490ea52..718a018 100644 --- a/crates/webui/styles/pages/_definitions.scss +++ b/crates/webui/styles/pages/_definitions.scss @@ -96,7 +96,8 @@ border-radius: $border-radius-lg; background: $color-bg-primary; - > summary { + > summary, + > .source-summary { display: flex; align-items: center; gap: $spacing-sm; @@ -130,6 +131,18 @@ } } + > .source-summary { + cursor: default; + + &::before { + visibility: hidden; + } + + &:hover { + background: $color-bg-secondary; + } + } + &[open] { > summary { border-bottom: 1px solid $color-border-primary; From 18e28d7f67cd89bd42dbac0ef83e7b0f64a2b23c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Olveck=C3=BD?= Date: Thu, 15 Oct 2026 08:04:20 +0000 Subject: [PATCH 3/3] feat: show backtrace sources of WASM activities Obelisk now accepts `backtrace.sources` on `activity_wasm` components. --- crates/webui/src/components/deployment_config_view.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/webui/src/components/deployment_config_view.rs b/crates/webui/src/components/deployment_config_view.rs index f54e3d9..165a61f 100644 --- a/crates/webui/src/components/deployment_config_view.rs +++ b/crates/webui/src/components/deployment_config_view.rs @@ -226,7 +226,10 @@ pub fn build_sections_from_manifest(manifest: &Value, files: &[FileRefSer]) -> V let Some(tables) = manifest.get(toml_key).and_then(Value::as_array) else { continue; }; - let has_backtrace = matches!(*toml_key, "workflow_wasm" | "webhook_endpoint_wasm"); + let has_backtrace = matches!( + *toml_key, + "activity_wasm" | "workflow_wasm" | "webhook_endpoint_wasm" + ); let has_script = matches!( *toml_key, "workflow_js" | "activity_js" | "activity_exec" | "webhook_endpoint_js"