Gunnar

nordisk/gunnar-ui

Cargo.toml

[workspace]
resolver = "2"
members = [
    "crates/gunnar-ui-server", # the BFF: passkey sessions, REST + SSE, the sshsig signer
    "crates/gunnar-public-site", # gunnar.rs's public face (llms.txt, robots, sitemap, public pages); only behind gunnar-ui-server `public-site`
    "crates/gunnar-mcp",       # the MCP connector (/mcp + its OAuth 2.1 server); only behind gunnar-ui-server `mcp`
    "crates/gunnar-ui-web",    # the console: Leptos 0.8, client-side rendered, bundled by trunk
    "crates/gunnar-ui-recipe",      # THE BUILD DECLARATION: every build point of both halves, in Rust
    "crates/gunnar-ui-build-thing", # its wasm32 cdylib shim + the `emit` door (nothing depends on it)
    "xtask",                   # repository tasks (`cargo xtask publish`). Zero dependencies; nothing depends on it.
]

[workspace.package]
authors = ["Rickard Ernst Björn Lundin <rickard@ignalina.dk>", "Vetra Automation AB", "Ignalina ApS"]
license = "AGPL-3.0-only"
version = "1.5.0"
edition = "2021"
rust-version = "1.85"
repository = "https://git.gunnar.rs/nordisk/gunnar-ui"
publish = false

# Profiles live at the workspace root because cargo ignores `[profile.*]` in a
# member manifest, and `lto` is not a legal per-package override key. Without
# this the wasm bundle ships at release defaults and roughly doubles in size.
[profile.release]
lto = true
codegen-units = 1

[profile.release.package.gunnar-ui-web]
opt-level = "z"

[workspace.dependencies]
# The BFF speaks native gRPC to gunnar. tonic 0.14 against gunnar's 0.13 server
# is deliberate: the wire format does not depend on either side's tonic version,
# and holger runs the same skew in production.
tonic = { version = "0.14", features = ["transport", "codegen"] }
tonic-prost = "0.14"
prost = "0.14"
# protox's prost-types major MUST equal tonic-prost-build's, or `compile_fds`
# does not type-check. protox 0.7/0.8 are prost-types 0.13; only 0.9+ is 0.14.
protox = "0.9"
tonic-prost-build = "0.14"

anyhow = "1"
serde = { version = "1", features = ["derive"] }
serde_json = "1"

# Every service in the suite goes through skidbladnir (systemd/initrc units,
# install/uninstall). This console was the last one that did not: until
# 2026-09-13 it shipped a hand-written `deploy/gunnar-ui.service` that a ~200
# line bash script `cp`ed into /etc/systemd/system, and that script was the only
# way to deploy it at all.
#
# A crates.io VERSION, not `path = "../Skidbladnir"`, for the reason monetize's
# manifest records: cargo reads a path dependency's manifest at RESOLVE time, so
# that spelling would make a Skidbladnir checkout a hard requirement of `cargo
# metadata` on this whole workspace — and this repository's own rule is that
# `git clone && cargo build -p gunnar-ui-server` must succeed with no sibling
# checkouts (see the gunnar-forge comment in crates/gunnar-ui-server/Cargo.toml).
#
# 0.1.16 is what monetize is on, so the suite holds one version of the installer.
# `default-features = false`: the unit generation, the D-Bus systemd control and
# the guarded uninstall are the always-on core; the PKI, znippy and container
# halves are not what a console needs.
skidbladnir = { version = "0.2", default-features = false }

# ── nornir-build-thing / nornir-git: W3 crypto-bump bridge (2026-10-02) ────────
# The PUBLISHED nornir-build-thing pulls nornir-git on russh 0.61, whose
# `ecdsa =0.17.0-rc.18` cannot coexist with the stable RustCrypto set — the
# workspace does not resolve. edda's nornir-git is on russh 0.63 but unpublished.
# LOCAL-DEV bridge onto the sibling edda (a foreign-fork release blocker by
# `patch_fork_blockers`) — DROP it the moment edda publishes nornir-git /
# nornir-build-thing on russh 0.63.
[patch.crates-io]
nornir-build-thing = { path = "../edda/crates/nornir-build-thing" }
nornir-git = { path = "../edda/crates/nornir-git" }
nornir-xtask-support = { path = "../edda/crates/nornir-xtask-support" }