omh 0.2.0

Launch any coding harness, in a sandbox, with your setup already there.
//! The definitions omh ships — adapters, editors, the base set — embedded in
//! the binary at compile time.
//!
//! They used to be read from `env!("CARGO_MANIFEST_DIR")` at *runtime*, which
//! is the build machine's source path. On the machine that built it that path
//! exists and everything works; anywhere else `read_dir` fails, the error is
//! discarded, and `omh init` delivers nothing while reporting success. A
//! downloaded binary got `no usable base manifest in … — run omh init` from
//! `omh init` itself, and zero adapters with no message at all.
//!
//! A `cargo install` would have escaped it, but only by accident: cargo leaves
//! the extracted crate under `~/.cargo/registry/src/`, so the baked path would
//! have resolved for as long as that directory survived — and it is a cache.
//! Stated as reasoning rather than history: omh has never been published, so
//! nobody has actually been bitten this way. The measured case was a binary
//! separated from the tree it was built in.
//!
//! Embedding is what makes the binary the unit of distribution. Note that the
//! files still land on disk in `~/.omh` exactly as before — the base set stays
//! reviewable by the people it is imposed on, which was always the point of
//! shipping it as data. Only where `init` copies *from* has changed.

/// One shipped file: what it is called, and what is in it.
///
/// Named fields rather than a tuple because both halves are `&'static str`, so
/// a table that swapped them would type-check and install files named after
/// their own contents.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct File {
    pub name: &'static str,
    pub contents: &'static str,
}

// Generated by build.rs: the `Shipped` enum, `ALL`, and `Shipped::files`.
// A directory omh does not ship is not a value this module can be handed, so
// there is no unknown-kind error to raise, propagate, or test.
include!(concat!(env!("OUT_DIR"), "/bundled.rs"));

#[cfg(test)]
mod tests {
    use super::*;

    /// What ships and what is in the repo are the same set.
    ///
    /// This is not the guard against the bug that prompted the change — no
    /// in-process test can be, because during `cargo test` the source tree is
    /// right there and the old code worked fine. That one is a CI job that
    /// runs the built binary with no checkout at all.
    ///
    /// What this catches is the next failure: a `.toml` added to the repo that
    /// `build.rs` does not pick up, which would ship an omh missing an adapter
    /// while every other test stayed green.
    #[test]
    fn everything_in_the_repo_is_embedded_byte_for_byte() {
        let root = std::path::Path::new(env!("CARGO_MANIFEST_DIR"));
        for kind in ALL {
            let mut on_disk: Vec<String> = std::fs::read_dir(root.join(kind.dir()))
                .unwrap()
                .map(|e| e.unwrap().path())
                .filter(|p| p.extension().is_some_and(|x| x == "toml"))
                .map(|p| p.file_name().unwrap().to_string_lossy().into_owned())
                .collect();
            on_disk.sort();

            let names: Vec<String> = kind.files().iter().map(|f| f.name.to_string()).collect();
            assert_eq!(
                names,
                on_disk,
                "{}: the binary and the repo disagree about what omh ships",
                kind.dir()
            );

            for file in kind.files() {
                let disk = std::fs::read_to_string(root.join(kind.dir()).join(file.name)).unwrap();
                assert_eq!(
                    file.contents,
                    disk,
                    "{}/{} was embedded stale",
                    kind.dir(),
                    file.name
                );
            }
        }
    }

    /// A directory that embedded as empty would install nothing and say so
    /// nowhere — the exact shape of the bug this module exists to remove.
    /// `build.rs` asserts it too; this is the half that fails in a test run
    /// rather than only on a machine that rebuilds.
    #[test]
    fn no_shipped_directory_is_empty() {
        for kind in ALL {
            assert!(!kind.files().is_empty(), "{} embedded as empty", kind.dir());
        }
    }

    /// `omh <anything>` is a harness, so a missing adapter is not a small loss.
    #[test]
    fn the_adapters_omh_launches_are_among_them() {
        let names: Vec<&str> = Shipped::Adapters.files().iter().map(|f| f.name).collect();
        assert!(names.contains(&"claude.toml"), "got: {names:?}");
        assert!(names.contains(&"opencode.toml"), "got: {names:?}");
    }

    /// Every shipped file is a `.toml`, which `install_bundled` relies on when
    /// it names a backup `<file>.toml.yours`.
    #[test]
    fn every_shipped_file_is_a_toml() {
        for kind in ALL {
            for file in kind.files() {
                assert!(file.name.ends_with(".toml"), "{}/{}", kind.dir(), file.name);
            }
        }
    }
}