ao_core/shell.rs
1//! Shell escaping utilities.
2//!
3//! Single canonical implementation of POSIX single-quote shell escaping,
4//! consolidating the per-plugin copies previously in `runtime-tmux`,
5//! `agent-codex`, `agent-aider`, and `ao-cli`.
6
7/// POSIX single-quote shell escape.
8///
9/// Wraps `s` in single quotes and replaces any embedded `'` with `'\''`.
10/// Always produces a quoted result — the always-wrap strategy is the safest
11/// default: it is correct for all strings including empty ones and avoids
12/// "safe-char set" disputes between callers.
13///
14/// Mirrors `shellEscape` from `packages/core/src/utils.ts`.
15pub fn shell_escape(s: &str) -> String {
16 format!("'{}'", s.replace('\'', r#"'\''"#))
17}
18
19#[cfg(test)]
20mod tests {
21 use super::shell_escape;
22
23 #[test]
24 fn plain_string_is_wrapped() {
25 assert_eq!(shell_escape("hello"), "'hello'");
26 }
27
28 #[test]
29 fn empty_string_becomes_two_quotes() {
30 assert_eq!(shell_escape(""), "''");
31 }
32
33 #[test]
34 fn single_quote_is_escaped() {
35 assert_eq!(shell_escape("it's"), "'it'\\''s'");
36 }
37
38 #[test]
39 fn spaces_and_metacharacters_are_quoted() {
40 assert_eq!(shell_escape("hello world"), "'hello world'");
41 assert_eq!(shell_escape("$VAR"), "'$VAR'");
42 }
43}