use std::path::Path;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Seed {
pub source: String,
pub fact: String,
}
pub fn program(command: &str) -> Option<&str> {
let word = command.split_whitespace().find(|w| !is_assignment(w))?;
is_program_name(word).then_some(word)
}
fn is_program_name(word: &str) -> bool {
!word.is_empty()
&& word
.chars()
.all(|c| c.is_ascii_alphanumeric() || matches!(c, '_' | '-' | '.' | '/' | '+'))
}
fn is_assignment(word: &str) -> bool {
match word.split_once('=') {
Some((name, _)) => {
!name.is_empty()
&& !name.starts_with(|c: char| c.is_ascii_digit())
&& name.chars().all(|c| c.is_alphanumeric() || c == '_')
}
None => false,
}
}
#[cfg(test)]
pub(crate) fn shipped() -> Vec<crate::stack::Definition> {
crate::stack::load_dir(Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/stacks")))
.expect("the shipped stacks must load")
}
pub fn preferred_harness(
candidates: &[String],
installed_on_host: &dyn Fn(&str) -> bool,
) -> Option<String> {
candidates
.iter()
.find(|c| installed_on_host(c))
.or_else(|| candidates.first())
.cloned()
}
pub fn seeds(defs: &[crate::stack::Definition], repo: &Path) -> Vec<Seed> {
let mut out = Vec::new();
if let Ok(readme) = std::fs::read_to_string(repo.join("README.md")) {
if let Some(line) = readme
.lines()
.map(|l| l.trim().trim_start_matches('>').trim())
.find(|l| {
!l.is_empty()
&& !l.starts_with('#')
&& !l.starts_with("[!")
&& !l.starts_with("![")
&& !l.starts_with("---")
})
{
out.push(Seed {
source: "README.md".into(),
fact: line.to_string(),
});
}
}
for def in crate::stack::detected(defs, repo) {
out.push(Seed {
source: def.marker.clone(),
fact: format!("stack: {}", def.name),
});
}
for rules in ["AGENTS.md", "CLAUDE.md"] {
if let Ok(body) = std::fs::read_to_string(repo.join(rules)) {
if !body.trim().is_empty() {
out.push(Seed {
source: rules.into(),
fact: format!("existing conventions ({} lines)", body.lines().count()),
});
}
}
}
out
}
#[cfg(test)]
mod tests {
use super::*;
use std::path::PathBuf;
fn repo(files: &[(&str, &str)]) -> (tempfile::TempDir, PathBuf) {
let dir = tempfile::tempdir().unwrap();
let root = dir.path().join("repo");
std::fs::create_dir_all(&root).unwrap();
for (name, body) in files {
let p = root.join(name);
std::fs::create_dir_all(p.parent().unwrap()).unwrap();
std::fs::write(p, body).unwrap();
}
(dir, root)
}
#[test]
fn the_program_a_command_needs_is_the_word_that_runs() {
for (command, want) in [
("cargo test", "cargo"),
("npm run format", "npm"),
("pytest", "pytest"),
("ruff format .", "ruff"),
("go test ./...", "go"),
("gofmt -w .", "gofmt"),
] {
assert_eq!(program(command), Some(want), "for {command:?}");
}
}
#[test]
fn a_command_we_cannot_read_names_no_program_rather_than_a_wrong_one() {
assert_eq!(program(""), None, "an empty command runs nothing");
assert_eq!(program(" "), None, "and neither does whitespace");
assert_eq!(program("RUST_LOG=debug cargo test"), Some("cargo"));
assert_eq!(program("FOO=1 BAR=2 pytest"), Some("pytest"));
assert_eq!(program("FOO=1"), None, "assignments alone run nothing");
}
#[test]
fn a_word_carrying_shell_syntax_names_no_program() {
for command in [
"$(which cargo) test",
"${CARGO:-cargo} test",
"`which cargo` test",
"2FOO=1 cargo test",
"cargo|tee test",
"cargo&&true",
] {
assert_eq!(program(command), None, "for {command:?}");
}
}
#[test]
fn an_ordinary_program_name_still_resolves() {
for (command, want) in [
("./scripts/test.sh", "./scripts/test.sh"),
("python3.11 -m pytest", "python3.11"),
("g++ -o x x.cc", "g++"),
("/usr/local/bin/cargo test", "/usr/local/bin/cargo"),
("cargo-nextest run", "cargo-nextest"),
] {
assert_eq!(program(command), Some(want), "for {command:?}");
}
}
#[test]
fn a_manifest_identifies_the_stack() {
let (_d, r) = repo(&[("Cargo.toml", "[package]")]);
let defs = shipped();
let found = crate::stack::detected(&defs, &r);
assert_eq!(found.len(), 1);
assert_eq!(found[0].name, "rust");
}
#[test]
fn a_polyglot_repo_reports_every_stack() {
let (_d, r) = repo(&[("Cargo.toml", ""), ("package.json", "{}")]);
let defs = shipped();
let names: std::collections::BTreeSet<_> = crate::stack::detected(&defs, &r)
.into_iter()
.map(|s| s.name.clone())
.collect();
assert_eq!(
names,
["rust", "node"].map(String::from).into_iter().collect()
);
}
#[test]
fn no_marker_means_no_stack_rather_than_a_guess() {
let (_d, r) = repo(&[("README.md", "hello")]);
let defs = shipped();
assert!(crate::stack::detected(&defs, &r).is_empty());
}
fn candidates() -> Vec<String> {
vec!["claude".into(), "opencode".into()]
}
#[test]
fn host_evidence_picks_the_default_harness() {
let pick = preferred_harness(&candidates(), &|h| h == "opencode");
assert_eq!(pick.as_deref(), Some("opencode"));
}
#[test]
fn nothing_installed_still_yields_a_default() {
let pick = preferred_harness(&candidates(), &|_| false);
assert_eq!(pick.as_deref(), Some("claude"));
}
#[test]
fn no_adapters_means_no_preference() {
assert_eq!(preferred_harness(&[], &|_| true), None);
}
#[test]
fn seeds_are_derived_from_what_the_repo_already_says() {
let (_d, r) = repo(&[
("README.md", "# omh\n\noh-my-zsh for agentic coding.\n"),
("Cargo.toml", "[package]\nname = \"omh\""),
]);
let s = seeds(&shipped(), &r);
assert!(
s.iter().any(|x| x.fact.contains("oh-my-zsh")),
"README should seed the project description: {s:?}"
);
assert!(
s.iter().any(|x| x.fact.contains("rust")),
"stack should be seeded: {s:?}"
);
}
#[test]
fn a_blockquote_tagline_is_read_as_prose() {
let (_d, r) = repo(&[("README.md", "# omh\n\n> Launch any coding harness.\n")]);
let s = seeds(&shipped(), &r);
let fact = &s
.iter()
.find(|x| x.source == "README.md")
.expect("README seed")
.fact;
assert_eq!(
fact, "Launch any coding harness.",
"markdown syntax is not the fact"
);
}
#[test]
fn a_badge_line_is_not_mistaken_for_a_description() {
let (_d, r) = repo(&[(
"README.md",
"# p\n\n[](https://ci)\n\nA real description.\n",
)]);
let s = seeds(&shipped(), &r);
let fact = &s
.iter()
.find(|x| x.source == "README.md")
.expect("README seed")
.fact;
assert_eq!(fact, "A real description.");
}
#[test]
fn every_seed_cites_its_source() {
let (_d, r) = repo(&[("README.md", "# p\n\nA thing.\n"), ("go.mod", "module x")]);
for seed in seeds(&shipped(), &r) {
assert!(!seed.source.is_empty(), "unsourced seed: {seed:?}");
}
}
#[test]
fn an_empty_repo_seeds_nothing_rather_than_inventing() {
let (_d, r) = repo(&[]);
assert!(seeds(&shipped(), &r).is_empty());
}
#[test]
fn existing_rules_are_seeded_so_conventions_survive() {
let (_d, r) = repo(&[("AGENTS.md", "# Rules\n\nTDD always.\n")]);
let s = seeds(&shipped(), &r);
assert!(
s.iter().any(|x| x.source.contains("AGENTS.md")),
"got: {s:?}"
);
}
}