[package]
name = "kanade-agent"
description = "Windows-side resident daemon for the kanade endpoint-management system. Subscribes to commands.* over NATS, runs scripts, publishes WMI inventory + heartbeats, watches for self-updates"
readme = "../../README.md"
version.workspace      = true
edition.workspace      = true
rust-version.workspace = true
license.workspace      = true
repository.workspace   = true
homepage.workspace     = true
authors.workspace      = true
keywords.workspace     = true
categories.workspace   = true

[dependencies]
kanade-shared = { workspace = true }

anyhow     = { workspace = true }
async-nats = { workspace = true }
base64     = { workspace = true }
bytes      = { workspace = true }
chrono     = { workspace = true }
clap       = { workspace = true }
futures    = { workspace = true }
humantime  = { workspace = true }
rand       = { workspace = true }
serde      = { workspace = true }
serde_json = { workspace = true }
sha2       = { workspace = true }
tokio      = { workspace = true }
tokio-cron-scheduler = { workspace = true }
tracing    = { workspace = true }
tracing-appender   = { workspace = true }
tracing-subscriber = { workspace = true }
uuid       = { workspace = true }
sysinfo    = { workspace = true }

[dev-dependencies]
tempfile = "3.27.0"
# Integration test harness (Issue #141) needs to talk to the same
# broker the agent does — pin to workspace `async-nats` so wire
# protocol stays in lockstep.
async-nats = { workspace = true }
# JetStream bootstrap helper lives in kanade-shared. Reuse from the
# integration tests instead of duplicating the stream / KV catalogue.
kanade-shared = { workspace = true }
# Allocate a free TCP port per spawned nats-server so multiple
# integration tests can run in parallel without colliding.
portpicker = "0.1.1"
# Skip integration tests cleanly when `nats-server` isn't in PATH
# (developer running `--ignored` on a fresh checkout).
which = "8.0.2"
# Workspace deps used by integration tests but already in
# [dependencies] don't need re-declaration; the agent's own
# integration tests inherit them.

[target.'cfg(target_os = "windows")'.dependencies]
# wmi crate dropped in v0.12.0 — inventory now shells out to
# powershell.exe to get past WBEM_E_INVALID_CLASS under LocalSystem.
# SCM (Service Control Manager) integration. Without this the agent
# runs under sc.exe but never calls StartServiceCtrlDispatcher, so
# Windows times out after 30 s and marks the service "did not respond"
# (Event ID 7009). The crate provides the dispatcher + control-handler
# scaffolding plus the typed status struct (Running / Stopped + accepted
# control codes) that SCM expects.
windows-service = "0.8.1"
# v0.21: CreateProcessAsUserW + WTSQueryUserToken for run_as: user /
# system_gui. Feature flags scope the binding to just what we need.
windows = { version = "0.62.2", features = [
    "Win32_Foundation",
    "Win32_Security",
    # SDDL → SECURITY_DESCRIPTOR for the KLP Named Pipe ACL (SPEC
    # §2.12.1: `Authenticated Users RW, deny Anonymous`). Needs
    # `ConvertStringSecurityDescriptorToSecurityDescriptorW` from
    # the Authorization sub-feature.
    "Win32_Security_Authorization",
    "Win32_Storage_FileSystem",
    "Win32_System_Environment",
    "Win32_System_IO",
    "Win32_System_Pipes",
    "Win32_System_RemoteDesktop",
    "Win32_System_StationsAndDesktops",
    "Win32_System_Threading",
] }

[target.'cfg(target_os = "windows")'.build-dependencies]
# Embeds VERSIONINFO into the .exe at build time so backend's upload
# endpoint can read ProductVersion via `pelite` without spawning the
# binary. See build.rs.
winres = { workspace = true }
