diff options
| author | Tony Solomonik <tony.solomonik@gmail.com> | 2026-07-11 01:19:51 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-07-11 01:19:51 +0300 |
| commit | 3b8aeee166d1594e1f8e41631a51748104d76834 (patch) | |
| tree | ed48557099286612d8851f4036aaf12eea4b37c0 /src/detect | |
| parent | 15c046a1bd08d0bb485ccbe20d5ff0c3d7bc8554 (diff) | |
feat: add maki agent support (#1302)
* feat: add maki detection support
Maki always draws a one-line status bar at the bottom of the screen, so the manifest reads just that row: a braille spinner before the `[BUILD]`/`[PLAN]`/`[BASH]` mode label means working, the bare label means idle.
Blocked states come from the panels that replace the input box, the `Permission Required` dialog with its `y Allow`/`n Deny` hint rows and the `Plan complete` form. Maki emits no OSC title or progress, so these screen rules are the only evidence.
Also wires `maki` through process-name identification, per-agent sound overrides, and the website manifest catalog.
* docs: stage maki detection docs
Diffstat (limited to 'src/detect')
| -rw-r--r-- | src/detect/manifest.rs | 1 | ||||
| -rw-r--r-- | src/detect/manifests/maki.toml | 68 | ||||
| -rw-r--r-- | src/detect/mod.rs | 10 |
3 files changed, 78 insertions, 1 deletions
diff --git a/src/detect/manifest.rs b/src/detect/manifest.rs index f798e871..736be823 100644 --- a/src/detect/manifest.rs +++ b/src/detect/manifest.rs @@ -251,6 +251,7 @@ const BUNDLED_MANIFESTS: &[(&str, &str)] = &[ ("kilo", include_str!("manifests/kilo.toml")), ("kimi", include_str!("manifests/kimi.toml")), ("kiro", include_str!("manifests/kiro.toml")), + ("maki", include_str!("manifests/maki.toml")), ("opencode", include_str!("manifests/opencode.toml")), ("pi", include_str!("manifests/pi.toml")), ("qodercli", include_str!("manifests/qodercli.toml")), diff --git a/src/detect/manifests/maki.toml b/src/detect/manifests/maki.toml new file mode 100644 index 00000000..5c58404a --- /dev/null +++ b/src/detect/manifests/maki.toml @@ -0,0 +1,68 @@ +id = "maki" +version = "2026.07.09.2" +min_engine_version = 1 +updated_at = "2026-07-09T00:00:00Z" + +# Maki renders a persistent one-line status bar on the bottom row. It starts +# with the mode label "[BUILD]", "[PLAN]", or "[BASH]" when idle and gets a +# leading braille spinner cell while the agent is streaming. Permission +# requests and the plan-complete form replace the input box above the status +# bar. Maki does not set OSC title or OSC 9;4 progress. + +[[rules]] +id = "permission_prompt" +state = "blocked" +priority = 980 +region = "whole_recent" +visible_blocker = true +contains = ["permission required"] +any = [ + { contains = ["y allow", "n deny"] }, + { contains = ["confirm allow"] }, + { contains = ["confirm deny"] }, + { contains = ["enter deny", "esc cancel"] }, +] + +[[rules]] +id = "plan_complete_form" +state = "blocked" +priority = 970 +region = "whole_recent" +visible_blocker = true +contains = ["plan complete", "enter confirm"] +any = [ + { contains = ["space toggle parallel"] }, + { contains = ["edit plan"] }, +] + +[[rules]] +id = "status_bar_spinner_working" +state = "working" +priority = 900 +region = "bottom_non_empty_lines(1)" +visible_working = true +line_regex = ['^( [\x{2800}-\x{28FF}]){1,2} \[(BUILD|PLAN|BASH)\]'] + +[[rules]] +id = "status_bar_idle" +state = "idle" +priority = 850 +region = "bottom_non_empty_lines(1)" +visible_idle = true +line_regex = ['^ \[(BUILD|PLAN|BASH)\]'] + +# On narrow panes the right side of the status bar overwrites the mode label, +# so fall back to the prompt chevron above the input box border. The not-gates +# keep this from matching the streaming placeholder or a status bar that still +# shows the spinner. +[[rules]] +id = "prompt_box_idle" +state = "idle" +priority = 840 +region = "bottom_non_empty_lines(3)" +visible_idle = true +line_regex = ['^❯ '] +not = [ + { contains = ["queue another prompt"] }, + { line_regex = ['^( [\x{2800}-\x{28FF}]){1,2} '] }, +] diff --git a/src/detect/mod.rs b/src/detect/mod.rs index 3520f010..7657ae35 100644 --- a/src/detect/mod.rs +++ b/src/detect/mod.rs @@ -61,10 +61,11 @@ pub enum Agent { Hermes, Kilo, Qodercli, + Maki, } impl Agent { - pub const SCREEN_MANIFEST_AGENTS: [Self; 18] = [ + pub const SCREEN_MANIFEST_AGENTS: [Self; 19] = [ Self::Pi, Self::Claude, Self::Codex, @@ -83,6 +84,7 @@ impl Agent { Self::Hermes, Self::Kilo, Self::Qodercli, + Self::Maki, ]; } @@ -108,6 +110,7 @@ pub fn agent_label(agent: Agent) -> &'static str { Agent::Hermes => "hermes", Agent::Kilo => "kilo", Agent::Qodercli => "qodercli", + Agent::Maki => "maki", } } @@ -134,6 +137,7 @@ pub fn parse_agent_label(agent: &str) -> Option<Agent> { "hermes" | "hermes-agent" => Some(Agent::Hermes), "kilo" | "kilo-code" | "kilo code" => Some(Agent::Kilo), "qodercli" | "qoderclicn" | "qoder" | "qodercn" => Some(Agent::Qodercli), + "maki" => Some(Agent::Maki), _ => None, } } @@ -164,6 +168,7 @@ pub fn identify_agent(process_name: &str) -> Option<Agent> { "hermes" | "hermes-agent" => Some(Agent::Hermes), "kilo" | "kilo-code" | "kilo code" => Some(Agent::Kilo), "qodercli" | "qoderclicn" | "qoder" | "qodercn" => Some(Agent::Qodercli), + "maki" => Some(Agent::Maki), _ => None, } } @@ -642,6 +647,7 @@ mod tests { assert_eq!(identify_agent("hermes-agent"), Some(Agent::Hermes)); assert_eq!(identify_agent("kilo"), Some(Agent::Kilo)); assert_eq!(identify_agent("kilo-code"), Some(Agent::Kilo)); + assert_eq!(identify_agent("maki"), Some(Agent::Maki)); } #[test] @@ -666,6 +672,7 @@ mod tests { assert_eq!(parse_agent_label("kiro-cli"), Some(Agent::Kiro)); assert_eq!(parse_agent_label("grok-build"), Some(Agent::Grok)); assert_eq!(parse_agent_label("hermes-agent"), Some(Agent::Hermes)); + assert_eq!(parse_agent_label("maki"), Some(Agent::Maki)); assert_eq!(parse_agent_label("kilo-code"), Some(Agent::Kilo)); } @@ -681,6 +688,7 @@ mod tests { assert_eq!(agent_label(Agent::Kiro), "kiro"); assert_eq!(agent_label(Agent::Grok), "grok"); assert_eq!(agent_label(Agent::Hermes), "hermes"); + assert_eq!(agent_label(Agent::Maki), "maki"); assert_eq!(agent_label(Agent::Kilo), "kilo"); } |
