A hive publishing its own status needs the same connect the controller already has - mint an authelia token, present it at CONNECT for the callout responder, let async-nats re-run the callback per attempt. Only the use differs: the controller reads, a hive writes. Copying it would put credential handling in two places, and a token-refresh fix would then have to be found twice. That is the same reasoning that already put hive-sock-client in its own crate rather than in each daemon that speaks to a unix socket. `from_env` takes a prefix rather than hardcoding SWARM_CONTROLLER_*: the variables belong to the consuming unit, since a NixOS module sets them alongside its other options. What is shared is the RULE - all four together or none at all - not the spelling. The half-set case gains a test, because it is the case the rule exists for and it previously had none. No jetstream/kv feature on the crate: it ends at a connected client, and what a consumer does with it should be visible in that consumer's own Cargo.toml. Behaviour-preserving, and proven that way rather than by inspection: the full behavioural gate (real nats-server, credential rotation, mutation) is 20/0 unchanged, and the controller's own tests still pass.
163 lines
4.9 KiB
TOML
163 lines
4.9 KiB
TOML
[workspace]
|
|
resolver = "3"
|
|
members = [
|
|
"hive-agent",
|
|
"hive-agent-mcp",
|
|
"hive-agent-sock",
|
|
"hive-core-agent-sock",
|
|
"hive-bash-mcp",
|
|
"hive-c0re",
|
|
"hive-screen-mcp",
|
|
"hive-forge",
|
|
"hive-forge-notify",
|
|
"hive-host-sock",
|
|
"hive-jobq",
|
|
"hive-jobq-wire",
|
|
"hive-matrix-mcp",
|
|
"hive-metric",
|
|
"hive-priv",
|
|
"hive-priv-sock",
|
|
"hive-sh4re",
|
|
"hive-sock-client",
|
|
"hive-types",
|
|
"hivectl",
|
|
"swarm-controller",
|
|
"swarm-nats-auth",
|
|
"swarm-queue-client",
|
|
"swarmctl",
|
|
]
|
|
|
|
[workspace.package]
|
|
edition = "2024"
|
|
version = "0.1.0"
|
|
|
|
[workspace.lints.clippy]
|
|
# Pedantic is a hard error (locally + in CI): we want pedantic lints
|
|
# gated, so a toolchain bump that adds a new one reds the build until the
|
|
# code is updated rather than sliding in unnoticed. Priority -1 keeps the
|
|
# specific allows below winning over the group.
|
|
pedantic = { level = "deny", priority = -1 }
|
|
# Tolerated stylistic pedantic lints (noisy, not actionable).
|
|
missing_errors_doc = "allow"
|
|
missing_panics_doc = "allow"
|
|
module_name_repetitions = "allow"
|
|
must_use_candidate = "allow"
|
|
|
|
[workspace.lints.rustdoc]
|
|
# Doc-link rot has no other discoverer: clippy does not read intra-doc
|
|
# links, `cargo test` does not, and nothing else builds docs. A `[`Foo`]`
|
|
# pointing at a renamed, moved or deleted item renders as plain text and
|
|
# misleads the next reader — worse than no link, since it names something
|
|
# and so sends them looking.
|
|
#
|
|
# Here rather than in `RUSTDOCFLAGS` on the CI check, so a plain local
|
|
# `cargo doc` fails the same way CI does. A gate you only meet in CI is a
|
|
# gate you meet too late.
|
|
broken_intra_doc_links = "deny"
|
|
private_intra_doc_links = "deny"
|
|
invalid_html_tags = "deny"
|
|
redundant_explicit_links = "deny"
|
|
bare_urls = "deny"
|
|
unescaped_backticks = "deny"
|
|
|
|
[workspace.dependencies]
|
|
anyhow = "1"
|
|
libc = "0.2"
|
|
axum = { version = "0.8", features = ["ws"] }
|
|
base64 = "0.22"
|
|
bcrypt = "0.19"
|
|
chrono = { version = "0.4", default-features = false, features = [
|
|
"clock",
|
|
"serde",
|
|
"std",
|
|
] }
|
|
clap = { version = "4", features = ["derive"] }
|
|
clap_complete = "4"
|
|
enumflags2 = { version = "0.7.12", features = ["serde"] }
|
|
indicatif = "0.18"
|
|
hive-sh4re = { path = "hive-sh4re" }
|
|
hive-agent-sock = { path = "hive-agent-sock" }
|
|
hive-jobq = { path = "hive-jobq" }
|
|
hive-jobq-wire = { path = "hive-jobq-wire" }
|
|
hive-core-agent-sock = { path = "hive-core-agent-sock" }
|
|
hive-claude = "0.1"
|
|
hive-host-sock = { path = "hive-host-sock" }
|
|
hive-priv-sock = { path = "hive-priv-sock" }
|
|
hive-sock-client = { path = "hive-sock-client" }
|
|
hive-types = { path = "hive-types" }
|
|
swarm-queue-client = { path = "swarm-queue-client" }
|
|
thiserror = "2"
|
|
tower-http = { version = "0.7", features = ["fs"] }
|
|
uuid = { version = "1", features = ["v4"] }
|
|
rmcp = { version = "2", default-features = false, features = [
|
|
"server",
|
|
"macros",
|
|
"transport-io",
|
|
"transport-streamable-http-server",
|
|
] }
|
|
rusqlite = { version = "0.37" }
|
|
schemars = "1.0"
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
similar = "2"
|
|
tokio = { version = "1", features = [
|
|
"fs",
|
|
"io-util",
|
|
"macros",
|
|
"net",
|
|
"process",
|
|
"rt-multi-thread",
|
|
"signal",
|
|
"sync",
|
|
"time",
|
|
] }
|
|
tokio-stream = { version = "0.1", features = ["sync"] }
|
|
tracing = "0.1"
|
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
|
reqwest = { version = "0.13", default-features = false, features = [
|
|
# RFC 7662 introspection posts an urlencoded body; without this,
|
|
# `.form()` does not exist and the alternative is percent-encoding a
|
|
# credential by hand.
|
|
"form",
|
|
"json",
|
|
"rustls",
|
|
] }
|
|
hyper = { version = "1", features = ["client", "http1"] }
|
|
hyper-util = { version = "0.1", features = ["tokio"] }
|
|
http-body-util = "0.1"
|
|
forgejo-api = { version = "0.11", default-features = false, features = [
|
|
"rustls-tls",
|
|
] }
|
|
url = "2"
|
|
time = { version = "0.3", default-features = false, features = [
|
|
"formatting",
|
|
"parsing",
|
|
] }
|
|
petgraph = { version = "0.8", default-features = false, features = ["std"] }
|
|
matrix-sdk = { version = "0.18", default-features = false, features = [
|
|
"sqlite",
|
|
"markdown",
|
|
"e2e-encryption",
|
|
] }
|
|
futures-util = "0.3"
|
|
hmac = "0.13"
|
|
sha2 = "0.11"
|
|
# The NATS protocol client, for the swarm queue's auth-callout responder.
|
|
# `default-features = false` because the default set is broad - jetstream, kv,
|
|
# object-store, websockets, service - and a callout responder speaks none of
|
|
# them. What is named is the whole requirement: the server generation we
|
|
# deploy, nkey auth, and a TLS backend.
|
|
async-nats = { version = "0.50", default-features = false, features = [
|
|
"server_2_14",
|
|
"nkeys",
|
|
"ring",
|
|
] }
|
|
data-encoding = "2"
|
|
# The nkey *format* - ed25519 + base32 + CRC16. The primitives are already in
|
|
# the tree; the format is not, and hand-rolling a key format on an auth path
|
|
# is how you get a CRC bug nobody reviews.
|
|
nkeys = "0.4"
|
|
# A TEST ORACLE, not a runtime dependency - see swarm-nats-auth's respond.rs.
|
|
nats-jwt = "0.3"
|
|
utoipa = { version = "5", features = ["axum_extras", "chrono"] }
|
|
utoipa-axum = "0.2"
|