feat(maestro): bind a TUI key to resume a dormant session
Adds DaemonClient::resume_session (POST /api/sessions/:id/resume) and a new ResumeHighlighted action, bound to `u` by default (#166, #169).
This commit is contained in:
@@ -141,6 +141,16 @@ impl DaemonClient {
|
||||
json(check(resp).await?).await
|
||||
}
|
||||
|
||||
/// `POST /api/sessions/:id/resume` (#166): respawn a dormant session
|
||||
/// under its own uuid and sidecar. Refused with `409` (`already_running`
|
||||
/// / `cwd_missing`) when there is nothing a respawn could fix.
|
||||
pub async fn resume_session(&self, id: Uuid) -> Result<Session, ClientError> {
|
||||
let resp = self
|
||||
.send(Method::POST, &routes::session_resume(id), &[], None::<&()>)
|
||||
.await?;
|
||||
json(check(resp).await?).await
|
||||
}
|
||||
|
||||
/// `POST /api/sessions/:id/activity` (#105): report an agent-observed
|
||||
/// state. The daemon holds it above its own inference for a TTL, then
|
||||
/// resumes inference. Answers `204 No Content`.
|
||||
|
||||
@@ -51,6 +51,9 @@ pub enum Action {
|
||||
/// Rename the highlighted session (#125): opens a prompt pre-filled with
|
||||
/// its current name.
|
||||
RenameHighlighted,
|
||||
/// Resume the highlighted dormant session (#166, #169): respawns it
|
||||
/// under its own uuid and sidecar via `POST /api/sessions/:id/resume`.
|
||||
ResumeHighlighted,
|
||||
|
||||
// Chrome
|
||||
/// Open the `ctrl-k` command bar (`docs/COMMAND-BAR.md`) — a query line
|
||||
@@ -105,6 +108,7 @@ impl Action {
|
||||
Action::FastForwardSpawn => "Create session with defaults".into(),
|
||||
Action::KillHighlighted => "Kill selected session".into(),
|
||||
Action::RenameHighlighted => "Rename selected session".into(),
|
||||
Action::ResumeHighlighted => "Resume dormant session".into(),
|
||||
Action::OpenCommandBar => "Go to a session".into(),
|
||||
Action::SendLiteralCtrlK => "Send literal Ctrl-K to session".into(),
|
||||
Action::SendLiteralLeader => "Send literal leader key to session".into(),
|
||||
@@ -134,6 +138,7 @@ impl Action {
|
||||
"FastForwardSpawn" => return Ok(Action::FastForwardSpawn),
|
||||
"KillHighlighted" => return Ok(Action::KillHighlighted),
|
||||
"RenameHighlighted" => return Ok(Action::RenameHighlighted),
|
||||
"ResumeHighlighted" => return Ok(Action::ResumeHighlighted),
|
||||
"OpenCommandBar" => return Ok(Action::OpenCommandBar),
|
||||
"SendLiteralCtrlK" => return Ok(Action::SendLiteralCtrlK),
|
||||
"SendLiteralLeader" => return Ok(Action::SendLiteralLeader),
|
||||
@@ -192,6 +197,16 @@ mod tests {
|
||||
assert_eq!(Action::parse(" Noop ").unwrap(), Action::Noop);
|
||||
}
|
||||
|
||||
/// #169: resume is its own verb, distinct from rename/kill, so a dormant
|
||||
/// session's sidebar card has a keyboard-reachable resume.
|
||||
#[test]
|
||||
fn parses_resume_highlighted() {
|
||||
assert_eq!(
|
||||
Action::parse("ResumeHighlighted").unwrap(),
|
||||
Action::ResumeHighlighted
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn help_labels_are_plain_language() {
|
||||
assert_eq!(Action::EnterInsert.help_label(), "Send keys to session");
|
||||
|
||||
@@ -59,6 +59,8 @@ const DEFAULT_NORMAL: &[(&str, &str)] = &[
|
||||
("N", "FastForwardSpawn"),
|
||||
("x", "KillHighlighted"),
|
||||
("r", "RenameHighlighted"),
|
||||
// Resume a dormant session (#166, #169).
|
||||
("u", "ResumeHighlighted"),
|
||||
// Focus
|
||||
("ctrl-w h", "FocusSidebar"),
|
||||
// Session scrollback
|
||||
@@ -257,6 +259,10 @@ mod tests {
|
||||
cfg.keymap.resolve(Mode::Normal, "N"),
|
||||
Some(Action::FastForwardSpawn),
|
||||
);
|
||||
assert_eq!(
|
||||
cfg.keymap.resolve(Mode::Normal, "u"),
|
||||
Some(Action::ResumeHighlighted),
|
||||
);
|
||||
}
|
||||
|
||||
/// AoE-style defaults (#shortcuts): `q` and `tab` are bare because Normal
|
||||
|
||||
Reference in New Issue
Block a user