@@ -21,7 +21,7 @@ use bashkit::{
2121 Bash as RustBash , BashTool as RustBashTool , Builtin , BuiltinContext , BuiltinRegistry ,
2222 Credential , ExecResult as RustExecResult , ExecutionLimits , ExtFunctionResult ,
2323 FileSystem as BashFileSystem , FileType , InMemoryFs , Metadata , MontyObject , NetworkAllowlist ,
24- OutputCallback , PosixFs , PythonExternalFnHandler , PythonLimits , RealFs , RealFsMode ,
24+ OutputCallback , PosixFs , PythonExternalFnHandler , RealFs , RealFsMode ,
2525 ScriptedTool as RustScriptedTool , SnapshotOptions as RustSnapshotOptions , Tool , ToolArgs ,
2626 ToolDef , ToolRequest , async_trait,
2727} ;
@@ -1283,6 +1283,8 @@ fn apply_network_options(
12831283/// Options for creating a Bash or BashTool instance.
12841284#[ napi( object) ]
12851285pub struct BashOptions {
1286+ /// Named resource-policy baseline. Individual options override its fields.
1287+ pub profile : Option < ExecutionProfileName > ,
12861288 pub username : Option < String > ,
12871289 pub hostname : Option < String > ,
12881290 /// Initial working directory for the shell (mirrors `Bash::builder().cwd()`).
@@ -1337,6 +1339,25 @@ pub struct BashOptions {
13371339 pub network : Option < NetworkOptions > ,
13381340}
13391341
1342+ /// Typed named execution-profile selector.
1343+ #[ napi( string_enum) ]
1344+ #[ derive( Debug , Clone , Copy ) ]
1345+ pub enum ExecutionProfileName {
1346+ Hardened ,
1347+ Standard ,
1348+ Interactive ,
1349+ }
1350+
1351+ impl From < ExecutionProfileName > for bashkit:: ExecutionProfileName {
1352+ fn from ( value : ExecutionProfileName ) -> Self {
1353+ match value {
1354+ ExecutionProfileName :: Hardened => Self :: Hardened ,
1355+ ExecutionProfileName :: Standard => Self :: Standard ,
1356+ ExecutionProfileName :: Interactive => Self :: Interactive ,
1357+ }
1358+ }
1359+ }
1360+
13401361/// One simple command found by `analyze()`.
13411362///
13421363/// `name` and each entry of `args` are `null` when the word is not fully
@@ -1448,6 +1469,7 @@ pub struct SnapshotOptions {
14481469fn default_opts ( ) -> BashOptions {
14491470 BashOptions {
14501471 username : None ,
1472+ profile : None ,
14511473 hostname : None ,
14521474 cwd : None ,
14531475 env : None ,
@@ -1519,6 +1541,7 @@ struct SharedState {
15191541 in_sync_execute_depth : Arc < AtomicUsize > ,
15201542 async_execute_semaphore : Arc < Semaphore > ,
15211543 username : Option < String > ,
1544+ profile : Option < ExecutionProfileName > ,
15221545 hostname : Option < String > ,
15231546 cwd : Option < String > ,
15241547 env : Option < HashMap < String , String > > ,
@@ -3410,7 +3433,7 @@ impl ScriptedTool {
34103433
34113434/// Build `ExecutionLimits` from the limit fields stored in `SharedState`.
34123435fn build_limits ( state : & SharedState ) -> ExecutionLimits {
3413- let mut limits = ExecutionLimits :: new ( ) ;
3436+ let mut limits = core_profile ( state ) . execution_limits ( ) . clone ( ) ;
34143437 if let Some ( v) = state. max_commands {
34153438 limits = limits. max_commands ( v as usize ) ;
34163439 }
@@ -3451,7 +3474,7 @@ fn build_limits(state: &SharedState) -> ExecutionLimits {
34513474}
34523475
34533476fn derive_sqlite_limits ( state : & SharedState ) -> bashkit:: SqliteLimits {
3454- let mut limits = bashkit :: SqliteLimits :: default ( ) ;
3477+ let mut limits = core_profile ( state ) . sqlite_limits ( ) . clone ( ) ;
34553478 if let Some ( ms) = state. timeout_ms {
34563479 limits = limits. max_duration ( std:: time:: Duration :: from_millis ( u64:: from ( ms) ) ) ;
34573480 }
@@ -3464,8 +3487,18 @@ fn derive_sqlite_limits(state: &SharedState) -> bashkit::SqliteLimits {
34643487 limits
34653488}
34663489
3490+ fn core_profile ( state : & SharedState ) -> bashkit:: ExecutionProfile {
3491+ bashkit:: ExecutionProfile :: named (
3492+ state
3493+ . profile
3494+ . map ( Into :: into)
3495+ . unwrap_or ( bashkit:: ExecutionProfileName :: Standard ) ,
3496+ )
3497+ }
3498+
34673499fn build_bash_from_state ( state : & SharedState ) -> RustBash {
3468- let mut builder = RustBash :: builder ( ) ;
3500+ let profile = core_profile ( state) ;
3501+ let mut builder = RustBash :: builder ( ) . profile ( profile. clone ( ) ) ;
34693502
34703503 if let Some ( ref u) = state. username {
34713504 builder = builder. username ( u) ;
@@ -3525,7 +3558,7 @@ fn build_bash_from_state(state: &SharedState) -> RustBash {
35253558 Box :: pin ( async move { h ( name, args, kwargs) . await } )
35263559 } ) ;
35273560 builder = builder. python_with_external_handler (
3528- PythonLimits :: default ( ) ,
3561+ profile . python_limits ( ) . clone ( ) ,
35293562 fn_names,
35303563 python_handler,
35313564 ) ;
@@ -3587,6 +3620,7 @@ fn shared_state_from_opts(
35873620 in_sync_execute_depth : Arc :: new ( AtomicUsize :: new ( 0 ) ) ,
35883621 async_execute_semaphore : Arc :: new ( Semaphore :: new ( MAX_PENDING_ASYNC_EXECUTIONS ) ) ,
35893622 username : opts. username . clone ( ) ,
3623+ profile : opts. profile ,
35903624 hostname : opts. hostname . clone ( ) ,
35913625 cwd : opts. cwd . clone ( ) ,
35923626 env : opts. env . clone ( ) ,
@@ -3640,6 +3674,7 @@ fn shared_state_from_opts(
36403674 in_sync_execute_depth : tmp. in_sync_execute_depth ,
36413675 async_execute_semaphore : Arc :: new ( Semaphore :: new ( MAX_PENDING_ASYNC_EXECUTIONS ) ) ,
36423676 username : opts. username ,
3677+ profile : opts. profile ,
36433678 hostname : opts. hostname ,
36443679 cwd : opts. cwd ,
36453680 env : opts. env ,
0 commit comments