feat(hh): /pw command, RAM-only direnv autostart, robust lets-hack; coven→clergy
- add /pw (alias /password): reveal this room's password locally (never broadcast); surfaced in the F1 help overlay and the join hint - direnv-autostart/: cd-to-launch a single real-user session via direnv; password is minted in memory at launch (never written to disk, matching the RAM-only model) and scoped to the child process. setup.sh installs direnv, hooks bash/zsh, and `direnv allow`s the dir - lets-hack.sh: boot a FRESH server by default (replacing any live one) with a --reuse opt-out; add -h/--help/-help; guard against killing the tmux session you're attached to; switch-client into the coven when run inside tmux - rename coven→clergy across rust/python/scripts; tests/test_coven.py→test_clergy.py - snapshots in-progress hack-house client work (sandbox, themes, net, ui) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,9 +2,14 @@
|
||||
//! occult-monochrome: black ground, white/grey ink, ⛧ accents. Override with a
|
||||
//! TOML file via `--theme <path>`.
|
||||
|
||||
use anyhow::Context;
|
||||
use ratatui::style::Color;
|
||||
use serde::Deserialize;
|
||||
|
||||
/// Where the bundled `*.toml` vestments live, so `/theme <name>` can resolve a
|
||||
/// bare name to a file at runtime (mirrors sbx.rs's script path const).
|
||||
pub const THEMES_DIR: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/themes");
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(default)]
|
||||
pub struct Theme {
|
||||
@@ -18,8 +23,14 @@ pub struct Theme {
|
||||
pub system: Color,
|
||||
pub input: Color,
|
||||
pub roster_me: Color,
|
||||
/// Panel/background fill. `Reset` = the terminal's own background (no fill);
|
||||
/// a solid colour lifts the text onto a contrasting surface for legibility.
|
||||
pub bg: Color,
|
||||
/// Width of the roster column.
|
||||
pub roster_width: u16,
|
||||
/// Glyph flanking the "hack-house" title (and used for occult accents).
|
||||
/// Defaults to ⛧ (inverted pentagram); themes can pick their own sigil.
|
||||
pub sigil: String,
|
||||
}
|
||||
|
||||
impl Default for Theme {
|
||||
@@ -37,7 +48,9 @@ impl Default for Theme {
|
||||
system: Color::Rgb(0xb4, 0x6c, 0xff), // system / occult = purple
|
||||
input: Color::Rgb(0x39, 0xff, 0x14),
|
||||
roster_me: Color::Rgb(0xff, 0x39, 0xc0), // you / owner = hot magenta
|
||||
bg: Color::Reset, // ride the terminal's own black
|
||||
roster_width: 22,
|
||||
sigil: "⛧".into(), // inverted pentagram
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -47,6 +60,30 @@ impl Theme {
|
||||
let s = std::fs::read_to_string(path)?;
|
||||
Ok(toml::from_str(&s)?)
|
||||
}
|
||||
|
||||
/// Resolve a bare vestment name (e.g. "neon") to a bundled `themes/<name>.toml`.
|
||||
/// Used by the in-session `/theme` command for live switching.
|
||||
pub fn by_name(name: &str) -> anyhow::Result<Self> {
|
||||
let path = format!("{THEMES_DIR}/{name}.toml");
|
||||
Self::load(&path).with_context(|| format!("theme '{name}' ({path})"))
|
||||
}
|
||||
|
||||
/// Names of the bundled vestments, sorted, for `/theme` with no argument.
|
||||
pub fn available() -> Vec<String> {
|
||||
let mut names: Vec<String> = std::fs::read_dir(THEMES_DIR)
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.flatten()
|
||||
.filter_map(|e| {
|
||||
e.file_name()
|
||||
.to_str()
|
||||
.and_then(|f| f.strip_suffix(".toml"))
|
||||
.map(str::to_string)
|
||||
})
|
||||
.collect();
|
||||
names.sort();
|
||||
names
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user