aboutsummaryrefslogtreecommitdiff
path: root/crates/dinggerd/src/importance.rs
diff options
context:
space:
mode:
authorIgor Soarez <igor@soarez.org>2026-10-26 16:32:18 +0200
committerIgor Soarez <igor@soarez.org>2026-10-26 16:32:18 +0200
commit185af91b4d525db6c192a050b53615772fb5fe11 (patch)
tree6db92db4042dddcc5fee13d02943447ba9df5f2d /crates/dinggerd/src/importance.rs
parent1eb0ac3705276c6f81f44487c7e99c24a302d4d5 (diff)
importance: mark an agent high, normal, or low
within a status, more important agents are listed first, and so jumped to first; status stays first. a high agent shows a bold ! before its name, a low agent's name is lightly dimmed with "low" on its second line, and it makes no sound (it still notifies and waits in line). in pi, /importance high|normal|low (completes the levels; none once one is typed out, so Enter runs it). the extension saves it in the session as a custom entry (dingger-importance), so /reload, restarts, /resume and restore bring it back; /new starts at normal. it shows a level other than normal in pi's footer, emits dingger:importance { level } for other extensions, and sends it with every report. for other agents, `dingger importance [level] [--pane]`; it refuses a pi that reports itself, whose saved level would win. the daemon stays the one writer of pane state: it writes @dingger_importance (unset for normal), which goes with the agent and survives a daemon restart. `dingger status` marks high and low. tests: e2e step 21 (order, the option, no sound for low, the menu bar, the command, the extension through a harness that now matches pi's extension API), a DINGGER_SOUND seam so sounds are observable, and a status-line check that read the counts once (flaky) now polls. pi-live: /importance in real pi 1.4, its footer and session entry, and the level after a restore; every pi there now uses the test's agent directory (a restored pi read the user's). negative controls fail each part.
Diffstat (limited to 'crates/dinggerd/src/importance.rs')
-rw-r--r--crates/dinggerd/src/importance.rs65
1 files changed, 65 insertions, 0 deletions
diff --git a/crates/dinggerd/src/importance.rs b/crates/dinggerd/src/importance.rs
new file mode 100644
index 0000000..2480d3e
--- /dev/null
+++ b/crates/dinggerd/src/importance.rs
@@ -0,0 +1,65 @@
+//! An agent's importance, set by the user: high, normal (the default), or
+//! low. It orders agents within a status (the list, and so the jump), and
+//! a low agent makes no sound.
+//!
+//! It belongs to the agent's conversation: pi's extension saves it in the
+//! session and reports it (`/importance`); other agents get it from
+//! `dingger importance`. The daemon writes it to the pane option
+//! `@dingger_importance` (unset for normal), which goes with the agent.
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)]
+pub enum Importance {
+ Low,
+ #[default]
+ Normal,
+ High,
+}
+
+impl Importance {
+ pub fn parse(value: &str) -> Option<Importance> {
+ match value.trim() {
+ "low" => Some(Importance::Low),
+ "normal" => Some(Importance::Normal),
+ "high" => Some(Importance::High),
+ _ => None,
+ }
+ }
+
+ /// A pane option's value: unset (empty) or anything unknown is normal.
+ pub fn from_option(value: &str) -> Importance {
+ Importance::parse(value).unwrap_or_default()
+ }
+
+ pub fn label(self) -> &'static str {
+ match self {
+ Importance::Low => "low",
+ Importance::Normal => "normal",
+ Importance::High => "high",
+ }
+ }
+
+ /// The pane option's value: normal leaves it unset.
+ pub fn option_value(self) -> &'static str {
+ match self {
+ Importance::Normal => "",
+ other => other.label(),
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn levels_order_and_round_trip_through_the_option() {
+ assert!(Importance::High > Importance::Normal && Importance::Normal > Importance::Low);
+ for level in [Importance::Low, Importance::Normal, Importance::High] {
+ assert_eq!(Importance::from_option(level.option_value()), level);
+ assert_eq!(Importance::parse(level.label()), Some(level));
+ }
+ assert_eq!(Importance::from_option(""), Importance::Normal, "unset is normal");
+ assert_eq!(Importance::from_option("urgent"), Importance::Normal);
+ assert_eq!(Importance::parse("urgent"), None);
+ }
+}