1pub(crate) mod bench;
33pub(crate) mod brief;
34pub(crate) mod capabilities;
35pub(crate) mod command_graph;
36pub(crate) mod commit;
37pub(crate) mod completion;
38pub(crate) mod continuity;
39pub(crate) mod convergence;
40pub(crate) mod dashboard;
41pub(crate) mod delivery;
42pub(crate) mod devcontext;
43pub(crate) mod devtask;
44pub(crate) mod distribution;
45pub(crate) mod economics;
46pub(crate) mod entity;
47pub(crate) mod env;
48pub(crate) mod evidence;
49pub(crate) mod executions;
50pub(crate) mod generate;
51pub(crate) mod guard;
52pub(crate) mod intent;
53pub(crate) mod knowledge;
54pub(crate) mod mcp;
55pub(crate) mod mesh;
56pub(crate) mod models;
57pub(crate) mod monitor;
58pub(crate) mod offload;
59pub(crate) mod pack;
60pub(crate) mod product;
61pub(crate) mod prs;
62pub(crate) mod quality;
63pub(crate) mod reasoning;
64pub(crate) mod release;
65pub(crate) mod rules;
66pub(crate) mod scope;
67pub(crate) mod serve;
68pub(crate) mod served;
69pub(crate) mod shell;
70pub(crate) mod skills;
71pub(crate) mod web;
72pub(crate) mod why;
73pub(crate) mod worktree;
74
75use crate::cli::{Cli, Command};
76use crate::error::Result;
77
78pub fn run(cli: Cli) -> Result<u8> {
80 match cli.command {
81 Command::Mcp(args) => mcp::run(args),
82 Command::Serve(args) => serve::run(args),
83 Command::Capabilities(args) => capabilities::run(args),
84 Command::Generate(args) => generate::run(args),
85 Command::Bench(args) => bench::run(args),
86 Command::Scope(args) => scope::run(args),
87 Command::Web(args) => web::run(args),
88 Command::Why(args) => why::run(args),
89 Command::Devtask(args) => devtask::run(args),
90 Command::Distribution(args) => distribution::run(args),
91 Command::Env(args) => env::run(args),
92 Command::Commands(args) => command_graph::run(args),
93 Command::Completion(args) => completion::run(args),
94 Command::Worktree(args) => worktree::run(args),
95 Command::Prs(args) => prs::run(args),
96 Command::Offload(args) => offload::run(args),
97 Command::Convergence(args) => convergence::run(args),
98 Command::Commit(args) => commit::run(args),
99 Command::Product(args) => product::run(args),
100 Command::Release(args) => release::run(args),
101 Command::Quality(args) => quality::run(args),
102 Command::Run(args) => executions::run(args),
103 Command::Executions(args) => executions::executions(args),
104 Command::Devcontext(args) => devcontext::run(args),
105 Command::Guard(args) => guard::run(args),
106 Command::Mesh(args) => mesh::run(args),
107 Command::Monitor(args) => monitor::run(args),
108 Command::Models(args) => models::run(args),
109 Command::Reasoning(args) => reasoning::run(args),
110 Command::Evidence(args) => evidence::run(args),
111 Command::Served(args) => served::run(args),
112 Command::Rules(args) => rules::run(args),
113 Command::Intent(args) => intent::run(args),
114 Command::Delivery(args) => delivery::run(args),
115 Command::Economics(args) => economics::run(args),
116 Command::Entity(args) => entity::run(args),
117 Command::Shell(args) => shell::run(args),
118 Command::Pack(args) => pack::run(args),
119 Command::Dashboard(args) => dashboard::run(args),
120 Command::Brief(args) => brief::run(args),
121 Command::Skills(args) => skills::run(args),
122 Command::Knowledge(args) => knowledge::run(args),
123 Command::Continuity(args) => continuity::run(args),
124 }
125}
126
127#[cfg(test)]
128mod tests {
129 use super::*;
130 use clap::Parser;
131
132 #[test]
133 fn every_command_the_command_line_parses_reaches_a_dispatch_arm() {
134 type Case = (&'static [&'static str], fn(&Command) -> bool);
139 let cases: &[Case] = &[
140 (&["majordomus", "mcp"], |c| matches!(c, Command::Mcp(_))),
141 (&["majordomus", "monitor", "--follow"], |c| {
142 matches!(c, Command::Monitor(_))
143 }),
144 (&["majordomus", "serve"], |c| matches!(c, Command::Serve(_))),
145 (&["majordomus", "serve", "status"], |c| {
146 matches!(c, Command::Serve(_))
147 }),
148 (&["majordomus", "capabilities", "list"], |c| {
149 matches!(c, Command::Capabilities(_))
150 }),
151 (&["majordomus", "generate"], |c| {
152 matches!(c, Command::Generate(_))
153 }),
154 (&["majordomus", "bench", "coverage"], |c| {
155 matches!(c, Command::Bench(_))
156 }),
157 (&["majordomus", "scope"], |c| matches!(c, Command::Scope(_))),
158 (&["majordomus", "web", "list"], |c| {
159 matches!(c, Command::Web(_))
160 }),
161 (&["majordomus", "why", "list"], |c| {
162 matches!(c, Command::Why(_))
163 }),
164 (&["majordomus", "intent", "list"], |c| {
165 matches!(c, Command::Intent(_))
166 }),
167 (&["majordomus", "skills", "status"], |c| {
168 matches!(c, Command::Skills(_))
169 }),
170 (&["majordomus", "devtask", "issue", "I0001"], |c| {
171 matches!(c, Command::Devtask(_))
172 }),
173 (&["majordomus", "devtask", "milestone", "foundation"], |c| {
174 matches!(c, Command::Devtask(_))
175 }),
176 (&["majordomus", "distribution", "show"], |c| {
177 matches!(c, Command::Distribution(_))
178 }),
179 (&["majordomus", "worktree", "status"], |c| {
180 matches!(c, Command::Worktree(_))
181 }),
182 (&["majordomus", "quality", "report"], |c| {
183 matches!(c, Command::Quality(_))
184 }),
185 (&["majordomus", "economics", "summary"], |c| {
186 matches!(c, Command::Economics(_))
187 }),
188 (&["majordomus", "dashboard", "overview"], |c| {
189 matches!(c, Command::Dashboard(_))
190 }),
191 (&["majordomus", "brief", "--line"], |c| {
192 matches!(c, Command::Brief(_))
193 }),
194 (
195 &["majordomus", "devcontext", "compile", "--issue", "I1"],
196 |c| matches!(c, Command::Devcontext(_)),
197 ),
198 (&["majordomus", "knowledge", "status"], |c| {
199 matches!(c, Command::Knowledge(_))
200 }),
201 (
202 &["majordomus", "knowledge", "record", "e1-0123456789ab"],
203 |c| matches!(c, Command::Knowledge(_)),
204 ),
205 (&["majordomus", "continuity", "status"], |c| {
206 matches!(c, Command::Continuity(_))
207 }),
208 (
209 &["majordomus", "continuity", "resume", "--record", "a1b2"],
210 |c| matches!(c, Command::Continuity(_)),
211 ),
212 ];
213 for (argv, is_expected) in cases {
214 let cli =
215 Cli::try_parse_from(*argv).unwrap_or_else(|e| panic!("{}: {e}", argv.join(" ")));
216 assert!(
217 is_expected(&cli.command),
218 "{} dispatched elsewhere",
219 argv.join(" ")
220 );
221 }
222 }
223
224 #[test]
225 fn a_command_line_nothing_declares_is_refused_rather_than_dispatched() {
226 assert!(Cli::try_parse_from(["majordomus", "nonesuch"]).is_err());
227 assert!(
228 Cli::try_parse_from(["majordomus"]).is_err(),
229 "a command is required"
230 );
231 }
232}