use anyhow::Result;
use owo_colors::OwoColorize;
use crate::output::{self, Format};
use crate::render::markdown;
use crate::render::theme;
pub const GUIDE: &str = include_str!("../../AGENT.md");
pub fn run(format: Format) -> Result<()> {
if format.is_json() {
output::emit(&serde_json::json!({
"version": env!("CARGO_PKG_VERSION"),
"markdown": GUIDE,
}));
return Ok(());
}
println!();
println!("{}", markdown::body(GUIDE));
println!();
println!(
" {}",
"`fundaia schema --json` es la superficie entera, comando por comando."
.style(theme::muted()),
);
println!();
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_should_warn_that_creating_a_service_deploys_it() {
assert!(GUIDE.contains("Creating a service deploys it."));
}
#[test]
fn it_should_say_what_the_exit_codes_mean() {
assert!(GUIDE.contains("The exit code says which kind of failure it was"));
}
#[test]
fn it_should_send_a_caller_that_speaks_mcp_to_the_instance_instead() {
assert!(GUIDE.contains("/api/infra/mcp"));
}
#[test]
fn it_should_say_that_nothing_ever_prompts() {
assert!(GUIDE.contains("Nothing ever prompts."));
}
#[test]
fn it_should_say_that_a_confirmation_is_the_name_and_not_a_yes() {
assert!(GUIDE.contains("the name of the\n thing, not a `yes`"));
}
#[test]
fn it_should_close_every_delimiter_on_the_line_that_opened_it() {
let wrapped: Vec<&str> = GUIDE
.lines()
.filter(|line| line.matches('`').count() % 2 != 0 || unbalanced_bold(line))
.collect();
assert_eq!(wrapped, Vec::<&str>::new());
}
fn unbalanced_bold(line: &str) -> bool {
line.matches("**").count() % 2 != 0
}
#[test]
fn it_should_name_no_command_the_parser_does_not_accept() {
let parser = crate::built();
let invented: Vec<&str> = commands_named_in(GUIDE)
.into_iter()
.filter(|named| {
!parser
.get_subcommands()
.any(|command| command.get_name() == *named)
})
.collect();
assert_eq!(invented, Vec::<&str>::new());
}
fn commands_named_in(text: &str) -> Vec<&str> {
text.split("fundaia ")
.skip(1)
.filter_map(|after| after.split([' ', '`', '\n', ',', '.']).next())
.filter(|word| !word.is_empty() && !word.starts_with('<'))
.collect()
}
}