From 6420a54abf9e091614da51efb8eb4615ed4def6c Mon Sep 17 00:00:00 2001 From: hosted-fornet Date: Mon, 12 Jan 2026 14:49:46 -0800 Subject: [PATCH 1/9] bump version to 3.2.1 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 158e1198..dea7042e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2282,7 +2282,7 @@ dependencies = [ [[package]] name = "kit" -version = "3.2.0" +version = "3.2.1" dependencies = [ "alloy", "alloy-sol-macro", diff --git a/Cargo.toml b/Cargo.toml index 134716f8..8575f125 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "kit" authors = ["Sybil Technologies AG"] -version = "3.2.0" +version = "3.2.1" edition = "2021" description = "Development toolkit for Hyperware" homepage = "https://hyperware.ai" From bbaef056837e3b5aedb593055ed3c824197fbf2e Mon Sep 17 00:00:00 2001 From: hosted-fornet Date: Mon, 12 Jan 2026 14:51:19 -0800 Subject: [PATCH 2/9] build: allow non-hyperapps in hyperapp-containing package --- src/build/caller_utils_generator.rs | 97 ++++++++++++++++++++--------- 1 file changed, 69 insertions(+), 28 deletions(-) diff --git a/src/build/caller_utils_generator.rs b/src/build/caller_utils_generator.rs index c5884c78..2cf11feb 100644 --- a/src/build/caller_utils_generator.rs +++ b/src/build/caller_utils_generator.rs @@ -254,42 +254,74 @@ struct SignatureStruct { args_comment: Option, // Parsed from // args: (name: type, ...) comment } -// Find all interface imports in the world WIT file +// Find all interface imports in the selected world WIT file(s) #[instrument(level = "trace", skip_all)] -fn find_interfaces_in_world(api_dir: &Path) -> Result> { - debug!(dir = ?api_dir, "Finding interface imports in world definitions"); - let mut interfaces = Vec::new(); +fn find_interfaces_in_world(api_dir: &Path, world_name: &str) -> Result> { + debug!(dir = ?api_dir, world = %world_name, "Finding interface imports in world definitions"); + let mut world_defs: HashMap = HashMap::new(); - // Find world definition files + // Index world definition files by world name for entry in WalkDir::new(api_dir) .max_depth(1) .into_iter() .filter_map(Result::ok) { let path = entry.path(); + if !(path.is_file() && path.extension().map_or(false, |ext| ext == "wit")) { + continue; + } + let Ok(content) = fs::read_to_string(path) else { + continue; + }; + if !content.contains("world ") { + continue; + } + if let Some(world_line) = content.lines().find(|line| line.trim().starts_with("world ")) { + if let Some(name) = world_line.trim().split_whitespace().nth(1) { + let clean_name = name.trim_end_matches(" {").trim_start_matches('%'); + world_defs.insert(clean_name.to_string(), content); + debug!(file = %path.display(), world = %clean_name, "Indexed world definition"); + } + } + } - if path.is_file() && path.extension().map_or(false, |ext| ext == "wit") { - if let Ok(content) = fs::read_to_string(path) { - if content.contains("world ") { - debug!(file = %path.display(), "Analyzing world definition file for imports"); - - // Extract import statements - for line in content.lines() { - let line = line.trim(); - if line.starts_with("import ") && line.ends_with(";") { - let interface = line - .trim_start_matches("import ") - .trim_end_matches(";") - .trim(); - - interfaces.push(interface.to_string()); - debug!(interface = %interface, "Found interface import"); - } - } - } + let mut interfaces = Vec::new(); + let mut visited = std::collections::HashSet::new(); + let mut stack = vec![world_name.to_string()]; + + while let Some(current_world) = stack.pop() { + let clean_world = current_world.trim_start_matches('%').to_string(); + if !visited.insert(clean_world.clone()) { + continue; + } + let Some(content) = world_defs.get(&clean_world) else { + debug!(world = %clean_world, "World definition not found for imports"); + continue; + }; + + debug!(world = %clean_world, "Analyzing world definition file for imports"); + for line in content.lines() { + let line = line.trim(); + if line.starts_with("import ") && line.ends_with(';') { + let interface = line + .trim_start_matches("import ") + .trim_end_matches(';') + .trim() + .trim_start_matches('%'); + interfaces.push(interface.to_string()); + debug!(interface = %interface, "Found interface import"); + } else if line.starts_with("include ") && line.ends_with(';') { + let include_world = line + .trim_start_matches("include ") + .trim_end_matches(';') + .trim() + .trim_start_matches('%') + .to_string(); + stack.push(include_world); } } } + debug!(count = interfaces.len(), interfaces = ?interfaces, "Found interface imports"); Ok(interfaces) } @@ -620,8 +652,8 @@ crate-type = ["cdylib", "lib"] "types" }; - // Get all interfaces from the world file - let interface_imports = find_interfaces_in_world(api_dir)?; + // Get all interfaces from the selected world + let interface_imports = find_interfaces_in_world(api_dir, world_name)?; // Store all types from each interface let mut interface_types: HashMap> = HashMap::new(); @@ -638,8 +670,17 @@ crate-type = ["cdylib", "lib"] // Exclude world definition files if let Ok(content) = fs::read_to_string(path) { if !content.contains("world ") { - debug!(file = %path.display(), "Adding WIT file for parsing"); - wit_files.push(path.to_path_buf()); + let interface_name = path.file_stem().unwrap().to_string_lossy(); + let interface_name = interface_name.trim_start_matches('%'); + if interface_imports + .iter() + .any(|i| i.trim_start_matches('%') == interface_name) + { + debug!(file = %path.display(), "Adding WIT file for parsing"); + wit_files.push(path.to_path_buf()); + } else { + debug!(file = %path.display(), "Skipping WIT file not in selected world"); + } } else { debug!(file = %path.display(), "Skipping world definition WIT file"); } From 54d4cc971ad3b5b9f1f856550bec10dfc899fa82 Mon Sep 17 00:00:00 2001 From: hosted-fornet Date: Mon, 12 Jan 2026 14:55:45 -0800 Subject: [PATCH 3/9] build: fix compiler error --- src/build/caller_utils_generator.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/build/caller_utils_generator.rs b/src/build/caller_utils_generator.rs index 2cf11feb..39a3447d 100644 --- a/src/build/caller_utils_generator.rs +++ b/src/build/caller_utils_generator.rs @@ -276,12 +276,14 @@ fn find_interfaces_in_world(api_dir: &Path, world_name: &str) -> Result Date: Mon, 12 Jan 2026 15:08:17 -0800 Subject: [PATCH 4/9] build: remove ambiguity of caller-utils Address import --- src/build/caller_utils_generator.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/build/caller_utils_generator.rs b/src/build/caller_utils_generator.rs index 39a3447d..9d29929c 100644 --- a/src/build/caller_utils_generator.rs +++ b/src/build/caller_utils_generator.rs @@ -484,8 +484,8 @@ fn generate_async_function(signature: &SignatureStruct) -> Option { if field.wit_type == "string" { target_param = "&str"; } else { - // Use hyperware_process_lib::Address instead of WitAddress - target_param = "&Address"; + // Use a distinct alias for hyperware_process_lib::Address to avoid WIT name clashes + target_param = "&ProcessAddress"; } } else if field.name == "returning" { return_type = rust_type; @@ -778,7 +778,7 @@ crate-type = ["cdylib", "lib"] // Add global imports lib_rs.push_str("pub use hyperware_process_lib::hyperapp::AppSendError;\n"); lib_rs.push_str("pub use hyperware_process_lib::hyperapp::send;\n"); - lib_rs.push_str("pub use hyperware_process_lib::{Address, Request};\n"); + lib_rs.push_str("pub use hyperware_process_lib::{Address as ProcessAddress, Request};\n"); lib_rs.push_str("use serde_json::json;\n\n"); // Add interface use statements From e07483f252f6511fe2e174391023d5141f2945fb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 12 Jan 2026 23:08:42 +0000 Subject: [PATCH 5/9] Format Rust code using rustfmt --- src/build/caller_utils_generator.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/build/caller_utils_generator.rs b/src/build/caller_utils_generator.rs index 9d29929c..272ae7df 100644 --- a/src/build/caller_utils_generator.rs +++ b/src/build/caller_utils_generator.rs @@ -280,7 +280,11 @@ fn find_interfaces_in_world(api_dir: &Path, world_name: &str) -> Result Date: Tue, 13 Jan 2026 10:05:09 -0800 Subject: [PATCH 6/9] setup: hardcode wasm-tools to working version --- src/setup/mod.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/setup/mod.rs b/src/setup/mod.rs index 6d948c67..0a2a509a 100644 --- a/src/setup/mod.rs +++ b/src/setup/mod.rs @@ -20,6 +20,7 @@ const MINIMUM_NPM_MINOR: u32 = 0; pub const REQUIRED_PY_MAJOR: u32 = 3; pub const MINIMUM_PY_MINOR: u32 = 10; pub const REQUIRED_PY_PACKAGE: &str = "componentize-py==0.11.0"; +const WASM_TOOLS_VERSION: &str = "v1.225.0"; #[derive(Clone)] pub enum Dependency { @@ -476,7 +477,11 @@ fn install_deps(deps: Vec, verbose: bool, toolchain: &str) -> Result Dependency::RustWasm32Wasi => { call_rustup("target add wasm32-wasip1", verbose, toolchain)? } - Dependency::WasmTools => call_cargo("install wasm-tools", verbose, toolchain)?, + Dependency::WasmTools => call_cargo( + &format!("install wasm-tools --version {WASM_TOOLS_VERSION}"), + verbose, + toolchain, + )?, Dependency::Foundry => install_foundry(verbose)?, Dependency::Docker => {} } From 41ed3b3a0289d0c351fcde8c2c6a4a8eff45ca03 Mon Sep 17 00:00:00 2001 From: hosted-fornet Date: Tue, 13 Jan 2026 10:09:10 -0800 Subject: [PATCH 7/9] setup: fix wasm-tools version number --- src/setup/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/setup/mod.rs b/src/setup/mod.rs index 0a2a509a..419a601b 100644 --- a/src/setup/mod.rs +++ b/src/setup/mod.rs @@ -20,7 +20,7 @@ const MINIMUM_NPM_MINOR: u32 = 0; pub const REQUIRED_PY_MAJOR: u32 = 3; pub const MINIMUM_PY_MINOR: u32 = 10; pub const REQUIRED_PY_PACKAGE: &str = "componentize-py==0.11.0"; -const WASM_TOOLS_VERSION: &str = "v1.225.0"; +const WASM_TOOLS_VERSION: &str = "1.225.0"; #[derive(Clone)] pub enum Dependency { From be3b667fb2d470c7eac4eebbcb5e0b9d035fdd48 Mon Sep 17 00:00:00 2001 From: hosted-fornet Date: Tue, 13 Jan 2026 10:16:35 -0800 Subject: [PATCH 8/9] setup: fix wasm-tools deps --- src/setup/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/setup/mod.rs b/src/setup/mod.rs index 419a601b..fdc83bc0 100644 --- a/src/setup/mod.rs +++ b/src/setup/mod.rs @@ -478,7 +478,7 @@ fn install_deps(deps: Vec, verbose: bool, toolchain: &str) -> Result call_rustup("target add wasm32-wasip1", verbose, toolchain)? } Dependency::WasmTools => call_cargo( - &format!("install wasm-tools --version {WASM_TOOLS_VERSION}"), + &format!("install wasm-tools --locked --version {WASM_TOOLS_VERSION}"), verbose, toolchain, )?, From 4f7b25625bcc12a9b318d32aad506214ab52fc17 Mon Sep 17 00:00:00 2001 From: hosted-fornet Date: Tue, 13 Jan 2026 11:22:01 -0800 Subject: [PATCH 9/9] add appendix for deps --- README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/README.md b/README.md index 9ad217d8..031eb52d 100644 --- a/README.md +++ b/README.md @@ -96,3 +96,29 @@ NodeJS (v18 or higher) and NPM are required to build and develop the UI. The UI is written in React with Vite as the bundler + reloader. To use `npm start` instead of `npm run dev`, use `kit dev-ui --release`. + +## Appendix: Deps for Debian/Ubuntu + +```bash +apt update +DEBIAN_FRONTEND=noninteractive apt install -y curl git build-essential pkg-config libssl-dev libclang-dev python3 python3-venv + +curl https://sh.rustup.rs -sSf | sh -s -- -y +. ~/.bashrc +cargo install --git https://github.com/hyperware-ai/kit --locked +kit setup -d --non-interactive +. ~/.bashrc +``` + +## Appendix: Deps for macOS + +```bash +xcode-select --install +brew install pkg-config llvm openssl@3 python@3.12 libusb + +curl https://sh.rustup.rs -sSf | sh -s -- -y +. ~/.bashrc +cargo install --git https://github.com/hyperware-ai/kit --locked +kit setup -d --non-interactive +. ~/.bashrc +```