Skip to main content

agent_shell_parser/parse/
mod.rs

1//! Shell command parsing and structural analysis.
2//!
3//! This module is **policy-free** — it decomposes shell commands into
4//! structured representations but makes no allow/deny decisions.
5//! Consumers (agent-jj, cc-toolgate) build policy on top.
6//!
7//! ## Entry points
8//!
9//! - [`parse_with_substitutions`] — decompose a compound shell command
10//!   into a recursive [`ParsedPipeline`] tree.
11//! - [`parse_command`] — structurally parse a single command into
12//!   [`ParsedCommand`] with ordered [`CommandArg`]s (flags and positionals
13//!   in source order).
14//! - [`resolve_command`] — strip transparent wrappers (env, sudo, etc.)
15//!   and classify unanalyzable patterns (eval, source, shell -c).
16//!
17//! ## Design principles
18//!
19//! - **Parser annotates, consumer decides.** The library classifies
20//!   commands; the consumer interprets classifications as policy.
21//! - **Schema-free argument parsing.** `ParsedCommand` identifies flags
22//!   syntactically (`-` prefix). Flag-value association requires the
23//!   consumer's knowledge of the command's schema. Arguments are kept
24//!   in source order so consumers can walk them with schema awareness.
25//! - **Fail-closed on ambiguity.** Parse errors and unresolvable
26//!   patterns (dynamic `$cmd`, eval) are surfaced, not hidden.
27
28mod redirect;
29mod resolve;
30pub mod shell;
31mod subst;
32pub mod tokenize;
33pub mod types;
34mod walk;
35
36pub use resolve::{default_command_config, resolve_command, resolve_command_with, strip_with_spec};
37pub use shell::{dump_ast, has_output_redirection, parse_with_substitutions};
38pub use tokenize::{
39    base_command, command_characteristics, env_vars, find_base_command, parse_command, tokenize,
40};
41pub use types::{
42    CommandArg, CommandCharacteristics, CommandConfig, IndirectExecution, Operator, ParseError,
43    ParsedCommand, ParsedFlag, ParsedPipeline, Redirection, ResolvedCommand, ShellSegment,
44    SubstitutionSpan, UnanalyzableCommand, WrapperSpec,
45};