diff --git a/Cargo.lock b/Cargo.lock index c5161024f..2eeb74bb4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3088,15 +3088,6 @@ dependencies = [ "include_dir", ] -[[package]] -name = "op-app" -version = "0.8.0" -dependencies = [ - "op-editor-ui", - "op-host-native", - "op-host-web", -] - [[package]] name = "op-cli" version = "0.8.0" @@ -3307,6 +3298,13 @@ dependencies = [ "web-sys", ] +[[package]] +name = "op-host-web-server" +version = "0.8.0" +dependencies = [ + "op-web-daemon", +] + [[package]] name = "op-i18n" version = "0.8.0" diff --git a/Cargo.toml b/Cargo.toml index a0def9bd8..dc81962ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ exclude = [ # is always `cargo build -p op-host-web --target wasm32-unknown-unknown`. CI and # the `package.json` cargo:* scripts are unaffected: they all pass `--workspace` # explicitly, which overrides `default-members`. -default-members = ["crates/op-host-desktop", "crates/op-cli"] +default-members = ["crates/op-host-desktop", "crates/op-cli", "crates/op-host-web-server"] [workspace.package] version = "0.8.0" diff --git a/crates/op-host-web-server/Cargo.toml b/crates/op-host-web-server/Cargo.toml new file mode 100644 index 000000000..92c75d1a0 --- /dev/null +++ b/crates/op-host-web-server/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "op-host-web-server" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +description = "OpenPencil headless web/MCP server binary — links op-web-daemon only, no winit/skia-GL" + +[[bin]] +name = "op-host-web-server" +path = "src/main.rs" + +[dependencies] +op-web-daemon = { path = "../op-web-daemon" } diff --git a/crates/op-host-web-server/src/main.rs b/crates/op-host-web-server/src/main.rs new file mode 100644 index 000000000..8a2b40aa9 --- /dev/null +++ b/crates/op-host-web-server/src/main.rs @@ -0,0 +1,78 @@ +//! Headless OpenPencil web / MCP server binary. +//! +//! Links only `op-web-daemon` (the extracted headless daemon) — no +//! winit / glutin / muda / accesskit adapters / skia-GL — so the +//! container / server image stays GUI-free. It mirrors the `--serve-web` +//! / `--mcp` / `--mcp-http` argv arms the desktop binary's +//! `run_cli_if_requested` dispatcher routes, but here that IS the whole +//! program: there is no GUI fallback, so an unknown / missing mode is a +//! usage error rather than "open the editor window". + +use std::path::PathBuf; +use std::process::exit; + +fn main() { + let mut args = std::env::args().skip(1); + let Some(first) = args.next() else { + eprintln!( + "op-host-web-server: missing mode. Usage:\n \ + --serve-web [doc] [--host ] headless web-canvas daemon\n \ + --mcp JSON-RPC stdio MCP server\n \ + --mcp-http Streamable-HTTP MCP server" + ); + exit(2); + }; + match first.as_str() { + "--serve-web" => { + // `--serve-web [doc] [--host ]`: doc optional + // (empty document otherwise); `--host` opts in to a + // non-loopback bind. + let (port, path, host) = op_web_daemon::web_canvas_server::parse_serve_web_args(args) + .unwrap_or_else(|e| { + eprintln!("op-host-web-server --serve-web: {e}"); + exit(2); + }); + if let Err(e) = op_web_daemon::web_canvas_server::run_web_canvas(path, port, &host) { + eprintln!("op-host-web-server --serve-web: {e}"); + exit(1); + } + } + "--mcp" => { + let Some(path) = args.next() else { + eprintln!("op-host-web-server --mcp: missing arg"); + exit(2); + }; + if let Err(e) = op_web_daemon::mcp_serve::run(PathBuf::from(path)) { + eprintln!("op-host-web-server --mcp: {e}"); + exit(1); + } + } + "--mcp-http" => { + let Some(port_arg) = args.next() else { + eprintln!("op-host-web-server --mcp-http: missing arg"); + exit(2); + }; + let Ok(port) = port_arg.parse::() else { + eprintln!( + "op-host-web-server --mcp-http: must be a u16, got {port_arg:?}" + ); + exit(2); + }; + let Some(path) = args.next() else { + eprintln!("op-host-web-server --mcp-http: missing arg"); + exit(2); + }; + if let Err(e) = op_web_daemon::mcp_serve::run_http(PathBuf::from(path), port) { + eprintln!("op-host-web-server --mcp-http: {e}"); + exit(1); + } + } + other => { + eprintln!( + "op-host-web-server: unknown mode {other:?} \ + (expected --serve-web / --mcp / --mcp-http)" + ); + exit(2); + } + } +}