aboutsummaryrefslogtreecommitdiff
path: root/crates/dinggerd/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/dinggerd/src')
-rw-r--r--crates/dinggerd/src/hooks.rs30
-rw-r--r--crates/dinggerd/src/watcher.rs7
2 files changed, 35 insertions, 2 deletions
diff --git a/crates/dinggerd/src/hooks.rs b/crates/dinggerd/src/hooks.rs
index aeb3285..c9825dd 100644
--- a/crates/dinggerd/src/hooks.rs
+++ b/crates/dinggerd/src/hooks.rs
@@ -32,6 +32,9 @@
//! Or that it failed, with the `error` as one readable line: the agent is
//! done, and the alert says it failed and why.
//!
+//! A pi report carries the session's `name` ("" for none): the agent's
+//! name, whatever its terminal title says.
+//!
//! It also carries the `draft` in the agent's input box ("" for none), for
//! marking a draft you left behind; never logged. And `context`: how full
//! the agent's context window is, in percent, as pi's footer shows it (""
@@ -83,6 +86,8 @@ struct PaneReports {
draft: Option<String>,
/// How full its context window is: whole percent ("" when unknown).
context: Option<String>,
+ /// The agent's session name, as reported ("" for none).
+ name: Option<String>,
/// The error that ended its last failed run, as one line.
error: Option<String>,
/// When the last report arrived.
@@ -189,6 +194,8 @@ struct HookParams {
aborted: Option<bool>,
#[serde(default)]
error: Option<String>,
+ #[serde(default)]
+ name: Option<String>,
}
fn handle_stream(stream: UnixStream) {
@@ -259,6 +266,7 @@ fn handle_stream(stream: UnixStream) {
context: params.context,
aborted: params.aborted == Some(true),
error: params.error,
+ name: params.name,
};
record(params.pane_id, state, reported);
wake();
@@ -278,6 +286,7 @@ struct Reported {
aborted: bool,
/// The error the run this report ends failed with.
error: Option<String>,
+ name: Option<String>,
}
/// A reported state, and whether it ends a run the user cancelled.
@@ -344,6 +353,9 @@ fn record(pane_id: String, state: Option<AgentState>, reported: Reported) {
if let Some(draft) = reported.draft {
pane.draft = Some(draft_line(&draft));
}
+ if let Some(name) = reported.name {
+ pane.name = Some(draft_line(&name));
+ }
if let Some(context) = reported.context {
pane.context = Some(context_percent(&context));
}
@@ -358,6 +370,12 @@ fn context_percent(value: &str) -> String {
}
}
+/// The pane's agent's session name ("" for none), if its extension
+/// reports it.
+pub fn name(pane_id: &str) -> Option<String> {
+ reports().get(pane_id).and_then(|pane| pane.name.clone())
+}
+
/// The error the pane's agent's last failed run ended with.
pub fn error(pane_id: &str) -> Option<String> {
reports().get(pane_id).and_then(|pane| pane.error.clone())
@@ -528,6 +546,18 @@ mod tests {
}
#[test]
+ fn a_reported_name_is_kept_as_one_line_until_reported_again() {
+ let named = |name: &str| Reported { name: Some(name.into()), ..Default::default() };
+ assert_eq!(super::name("%t9"), None, "an extension that does not report it");
+ record("%t9".into(), None, named("Fix the\nsidecar"));
+ assert_eq!(super::name("%t9").as_deref(), Some("Fix the sidecar"));
+ record("%t9".into(), None, Reported::default());
+ assert_eq!(super::name("%t9").as_deref(), Some("Fix the sidecar"), "kept by a report without one");
+ record("%t9".into(), None, named(""));
+ assert_eq!(super::name("%t9").as_deref(), Some(""), "unnamed");
+ }
+
+ #[test]
fn a_failed_run_ends_in_a_failed_idle_observation_with_its_error() {
let failed = |error: &str| Reported { error: Some(error.into()), ..Default::default() };
record("%t8".into(), Some(AgentState::Working), failed("not the end of a run"));
diff --git a/crates/dinggerd/src/watcher.rs b/crates/dinggerd/src/watcher.rs
index 9bad1fe..1cd282b 100644
--- a/crates/dinggerd/src/watcher.rs
+++ b/crates/dinggerd/src/watcher.rs
@@ -503,8 +503,11 @@ impl Watcher {
change("@dingger_since", &pane.written_since, track.since.map(|s| s.to_string()).unwrap_or_default());
change("@dingger_error", &pane.written_error, error.to_string());
change("@agent", &pane.written_agent, pane.agent.map(detect_core::agent_label).unwrap_or("").to_string());
- let name = crate::names::display_name(pane.agent, &pane.pane_title, &pane.cwd, host_name())
- .unwrap_or_default();
+ // The name its extension reports ("" for an unnamed session), else
+ // what the terminal title says (anyone can set a title).
+ let name = hooks::name(&pane.pane_id).unwrap_or_else(|| {
+ crate::names::display_name(pane.agent, &pane.pane_title, &pane.cwd, host_name()).unwrap_or_default()
+ });
change("@agent_name", &pane.written_name, name);
// The session reference, for restore; it goes with the agent.
match (pane.agent, hooks::session(&pane.pane_id)) {