Skip to main content

ninox_core/
lib.rs

1pub mod brain;
2pub mod brain_archive;
3pub mod client;
4pub mod config;
5pub mod embeddings;
6pub mod events;
7pub mod github;
8pub mod harness;
9pub mod hooks;
10pub mod inbox;
11pub mod lifecycle;
12pub mod messaging;
13pub mod plugin;
14pub mod pty;
15pub mod store;
16pub mod tmux;
17pub mod types;
18
19pub use brain::{BrainEntry, BrainIndex, QueryFilters};
20pub use config::{AppConfig, ThemeVariant};
21pub use events::{Engine, Event};
22pub use store::Store;
23pub use types::*;
24
25/// Convert a name into a tmux/URL-safe session ID.
26///
27/// Lowercases, maps non-alphanumeric chars to hyphens, and collapses consecutive
28/// hyphens. Returns an empty string if the input contains no alphanumeric chars.
29///
30/// Examples: `"ATH-123 auth fix"` → `"ath-123-auth-fix"`, `"my feature"` → `"my-feature"`
31pub fn slugify(s: &str) -> String {
32    s.to_lowercase()
33        .chars()
34        .map(|c| if c.is_ascii_alphanumeric() { c } else { '-' })
35        .collect::<String>()
36        .split('-')
37        .filter(|p| !p.is_empty())
38        .collect::<Vec<_>>()
39        .join("-")
40}
41
42#[cfg(test)]
43mod tests {
44    use super::*;
45
46    #[test]
47    fn slugify_ticket_id() {
48        assert_eq!(slugify("ATH-123"), "ath-123");
49    }
50
51    #[test]
52    fn slugify_spaced_name() {
53        assert_eq!(slugify("auth fix"), "auth-fix");
54    }
55
56    #[test]
57    fn slugify_ticket_with_description() {
58        assert_eq!(slugify("ATH-123 auth fix"), "ath-123-auth-fix");
59    }
60
61    #[test]
62    fn slugify_collapses_consecutive_separators() {
63        assert_eq!(slugify("my  feature!"), "my-feature");
64    }
65
66    #[test]
67    fn slugify_already_clean() {
68        assert_eq!(slugify("my-feature"), "my-feature");
69    }
70
71    #[test]
72    fn slugify_empty_returns_empty() {
73        assert_eq!(slugify(""), "");
74        assert_eq!(slugify("---"), "");
75    }
76}