loopflow 0.9.10

Run steps and flows with coding agents
Documentation
//! Built-in step definitions and system docs embedded in the binary.
//!
//! Registration is automatic: drop a file into the right builtins/
//! subdirectory and build.rs generates the HashMap entries.

/// Bundled LOOPFLOW.md system documentation.
pub const LOOPFLOW_DOC: &str = include_str!("builtins/LOOPFLOW.md");

/// Bundled RLM.md — recursive language model instructions for agents.
pub const RLM_DOC: &str = include_str!("builtins/RLM.md");

/// Bundled VOICE.md — default voice/tone guidance for agent output.
pub const VOICE_DOC: &str = include_str!("builtins/VOICE.md");

/// Surface instruction prompts, one per surface variant.
pub const SURFACE_HEADLESS: &str = include_str!("builtins/surfaces/headless.md");
pub const SURFACE_CLI: &str = include_str!("builtins/surfaces/cli.md");
pub const SURFACE_CONCERTO_MAC: &str = include_str!("builtins/surfaces/concerto_mac.md");
pub const SURFACE_CONCERTO_IPHONE: &str = include_str!("builtins/surfaces/concerto_iphone.md");

/// Returns the content of a built-in step, if it exists.
pub fn get_builtin_step(name: &str) -> Option<&'static str> {
    BUILTIN_STEPS.get(name).copied()
}

/// Returns the content of a built-in flow, if it exists.
pub fn get_builtin_flow(name: &str) -> Option<&'static str> {
    BUILTIN_FLOWS.get(name).copied()
}

/// Returns the content of a built-in direction, if it exists.
pub fn get_builtin_direction(name: &str) -> Option<&'static str> {
    BUILTIN_DIRECTIONS.get(name).copied()
}

/// Returns the content of a built-in ops prompt, if it exists.
pub fn get_builtin_ops_prompt(name: &str) -> Option<&'static str> {
    BUILTIN_OPS_PROMPTS.get(name).copied()
}

/// List of all built-in step names.
pub fn builtin_step_names() -> Vec<&'static str> {
    BUILTIN_STEPS.keys().copied().collect()
}

/// List of all built-in flow names.
pub fn builtin_flow_names() -> Vec<&'static str> {
    BUILTIN_FLOWS.keys().copied().collect()
}

/// Iterate over all built-in flows as (name, yaml_content) pairs.
pub fn builtin_flow_entries() -> impl Iterator<Item = (&'static str, &'static str)> {
    BUILTIN_FLOWS.iter().map(|(k, v)| (*k, *v))
}

/// List of all built-in direction names.
pub fn builtin_direction_names() -> Vec<&'static str> {
    BUILTIN_DIRECTIONS.keys().copied().collect()
}

/// Returns the member direction names for a builtin group, if it exists.
pub fn builtin_direction_group(name: &str) -> Option<&'static Vec<&'static str>> {
    BUILTIN_DIRECTION_GROUPS.get(name)
}

/// List of all builtin direction group names.
pub fn builtin_direction_group_names() -> Vec<&'static str> {
    BUILTIN_DIRECTION_GROUPS.keys().copied().collect()
}

// Generated by build.rs — scans builtins/ subdirectories automatically.
include!(concat!(env!("OUT_DIR"), "/builtin_steps.rs"));
include!(concat!(env!("OUT_DIR"), "/builtin_flows.rs"));
include!(concat!(env!("OUT_DIR"), "/builtin_flow_categories.rs"));
include!(concat!(env!("OUT_DIR"), "/builtin_step_categories.rs"));
include!(concat!(env!("OUT_DIR"), "/builtin_directions.rs"));
include!(concat!(env!("OUT_DIR"), "/builtin_direction_groups.rs"));
include!(concat!(env!("OUT_DIR"), "/builtin_ops_prompts.rs"));

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

    const WAVE_AUTHORING_DOC: &str = include_str!("../../../../docs/wave-authoring.md");

    #[test]
    fn priority_guidance_is_embedded_in_prompts_and_docs() {
        let update_wave = get_builtin_step("update-wave").expect("update-wave prompt");
        let ingest = get_builtin_step("ingest").expect("ingest prompt");
        let design = get_builtin_step("design").expect("design prompt");
        let scan_waves = get_builtin_step("scan").expect("scan prompt");
        let split_wave = get_builtin_step("split-wave").expect("split-wave prompt");

        assert!(update_wave.contains("1-fix-broken-build.md"));
        assert!(update_wave.contains("4-*"));
        assert!(!update_wave.contains("numbered item files"));
        assert!(ingest.contains("highest-priority non-empty level"));
        assert!(design.contains("1-*.md"));
        assert!(scan_waves.contains("1-*` through `4-*"));
        assert!(!scan_waves.contains("All numbered item files"));
        assert!(split_wave.contains("Bucketed roadmap files"));
        assert!(WAVE_AUTHORING_DOC.contains("1-fix-crash-loop.md"));
        assert!(WAVE_AUTHORING_DOC.contains("2-daemon-integrity.md"));
        assert!(!WAVE_AUTHORING_DOC.contains("all `01-*` items complete"));
    }
}