murk-cli 0.10.2

Encrypted secrets manager for developers — one file, age encryption, git-friendly
Documentation
[workspace]
members = [".", "node"]
exclude = ["fuzz"]

[workspace.package]
version = "0.10.2"

[package]
name = "murk-cli"
version.workspace = true
edition = "2024"
rust-version = "1.89"
description = "Encrypted secrets manager for developers — one file, age encryption, git-friendly"
license = "MIT OR Apache-2.0"
repository = "https://github.com/interrupted-inc/murk"
keywords = ["secrets", "encryption", "age", "dotenv", "security"]
categories = ["command-line-utilities", "cryptography"]
exclude = ["CLAUDE.md", "AGENTS.md", "SPEC.md"]

[lints.clippy]
# Secret-handling guardrail: dbg! prints the Debug of any value — including a
# decrypted secret — and must never ship. It is allow-by-default (restriction
# group), so `-D warnings` alone won't catch it; deny it explicitly. Source-level
# invariants clippy can't express live in tests/invariants.rs.
dbg_macro = "deny"

[lib]
name = "murk_cli"
path = "src/lib.rs"

[[bin]]
name = "murk"
path = "src/main.rs"

# Dev-only: renders docs/cli-reference.md from the clap model. Gated behind the
# `doc-gen` feature so it is skipped by a normal build/release.
[[bin]]
name = "gen-docs"
path = "src/bin/gen-docs.rs"
required-features = ["doc-gen"]

[dependencies]
age = { version = "0.12.1", features = ["ssh", "plugin", "cli-common"] }
ureq = "3"
base64 = "0.23.0"
bech32 = "0.12.0"
bip39 = "2.2.2"
clap = { version = "4.6.1", features = ["derive", "env"] }
chrono = { version = "0.4", default-features = false, features = ["clock"] }
colored = "3"
rand = "0.10.1"
rpassword = "7"
serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0.150"
sha2 = "0.11.0"
blake3 = "1"
ed25519-dalek = "3"
# OpenSSH private-key parsing for ssh-ed25519 vault signing. RSA/encryption
# features are deliberately off: we only need ed25519, and keeping RSA out avoids
# widening the Marvin-attack surface (RUSTSEC-2023-0071, already tracked in deny.toml).
ssh-key = { version = "0.6", default-features = false, features = ["ed25519", "alloc"] }
constant_time_eq = "0.4"
tempfile = "3.27.0"
clap_complete = "4.6.5"
# Dev-only doc generation (the `doc-gen` feature + `gen-docs` bin). Optional so
# the shipped `murk` binary never links them.
clap-markdown = { version = "0.1.5", optional = true }
clap_mangen = { version = "0.3.0", optional = true }
fs2 = "0.4.3"
pyo3 = { version = "0.29", features = ["extension-module", "abi3-py39"], optional = true }
walkdir = "2.5.0"
zeroize = "1"
# `murk mcp` — an in-process MCP (Model Context Protocol) stdio server for AI
# agents. rmcp is the official Rust MCP SDK; tokio + tracing are
# scoped to that subcommand only (the rest of murk stays sync). Default features
# (incl. base64) are off — we only need the server, tool macros, the stdio
# transport, and JSON-schema generation for tool parameters. schemars is a direct
# dep so the `JsonSchema` derive on tool request structs resolves (rmcp's own
# examples do the same). The async stack is dormant during normal commands.
rmcp = { version = "3.0.0", default-features = false, features = ["server", "macros", "transport-io", "schemars"] }
tokio = { version = "1", features = ["rt-multi-thread", "macros", "process", "time", "io-util"] }
tracing = "0.1.44"
tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt"] }
schemars = "1"

[target.'cfg(unix)'.dependencies]
libc = "0.2"

[features]
default = []
python = ["pyo3"]
# Build the gen-docs tool that renders the CLI reference, env reference,
# completions, and man pages from the clap model. Off by default so a normal
# build/release never pulls the doc-gen-only crates.
doc-gen = ["dep:clap-markdown", "dep:clap_mangen"]

[dev-dependencies]
assert_cmd = "2"
assert_fs = "1"
predicates = "3"
# Property-based invariant tests (roundtrip, tamper-evidence, scope isolation)
# for the crypto/MAC core — see src/property_tests.rs. Also the corpus that a
# `cargo mutants` run should not leave survivors in.
proptest = "1"
# Client-side rmcp, test-only: an integration test drives `murk mcp` as a child
# process over the official SDK's MCP client. Cargo unions these with the
# server-side features above for test builds; a normal/release build ignores
# dev-dependencies, so the shipped binary keeps only the server features.
rmcp = { version = "3.0.0", default-features = false, features = ["client", "transport-child-process"] }