#![deny(missing_docs)]
#![forbid(unsafe_code)]
#![cfg_attr(test, allow(clippy::unwrap_used, clippy::expect_used, clippy::panic))]
mod command;
mod error;
mod response;
pub use command::{
ApprovalAction, ApproveServerCommandDriftReq, ApproveToolDriftReq, ApproveToolReq,
BindServerSandboxProfileReq, Capability, ExportFormat, ExportSessionReplayReq, FtsSearchReq,
GetApprovalDetailReq, GetEventDetailReq, GetSandboxProfileReq, GetServerOnboardingReq,
ListPendingApprovalsReq, ListPrivacyFindingsReq, ListRecentEventsReq, ListSessionsReq,
RejectServerCommandDriftReq, RejectToolDriftReq, ReplaySessionReq, ResolveApprovalReq,
UiCommand, UpsertSandboxProfileReq,
};
pub use error::UiError;
pub use response::{
ApprovalDetailDto, ApprovalResolutionDto, ApprovalSummary, ChainVerifyReport, EventDetail,
EventSummary, PrivacyFindingDto, PrivacyFindingsDto, RedactionScanSummaryDto,
SandboxProfileUpsertDto, SecretBindingSummary, SessionExportDto, SessionReplay, SessionSummary,
UiResponse,
};
pub const ITERATION: &str = "I08a";
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn required_capability_read_for_all_read_commands() {
let reads = [
UiCommand::VerifyChain,
UiCommand::ListServers,
UiCommand::ListPendingToolApprovals,
UiCommand::ListDriftedTools,
UiCommand::ListDriftedServers,
UiCommand::ListSandboxProfiles,
UiCommand::ListRecentEvents(Default::default()),
UiCommand::GetEventDetail(GetEventDetailReq { event_id: 1 }),
UiCommand::FtsSearch(FtsSearchReq {
query: "x".into(),
limit: 10,
}),
UiCommand::ListPendingApprovals(Default::default()),
UiCommand::GetApprovalDetail(GetApprovalDetailReq {
approval_id: "a".into(),
}),
UiCommand::ListSessions(Default::default()),
UiCommand::ReplaySession(ReplaySessionReq {
session_id: "s".into(),
verify: false,
}),
UiCommand::GetServerOnboarding(GetServerOnboardingReq {
server_id: "s".into(),
}),
UiCommand::GetSandboxProfile(GetSandboxProfileReq {
profile_id: "p".into(),
}),
];
for c in reads {
assert_eq!(
c.required_capability(),
Capability::Read,
"{c:?} should be Read"
);
}
}
#[test]
fn required_capability_write_for_all_write_commands() {
use vigil_runner_types::{RunnerKind, RunnerSpecific, SandboxProfile};
let writes = [
UiCommand::ResolveApproval(ResolveApprovalReq {
approval_id: "a".into(),
action: ApprovalAction::Approve,
scope: None,
resolved_by: "u".into(),
reason: None,
}),
UiCommand::ApproveTool(ApproveToolReq {
server_id: "s".into(),
tool_name: "t".into(),
}),
UiCommand::ApproveToolDrift(ApproveToolDriftReq {
server_id: "s".into(),
tool_name: "t".into(),
new_hash: "h".into(),
}),
UiCommand::RejectToolDrift(RejectToolDriftReq {
server_id: "s".into(),
tool_name: "t".into(),
}),
UiCommand::ApproveServerCommandDrift(ApproveServerCommandDriftReq {
server_id: "s".into(),
}),
UiCommand::RejectServerCommandDrift(RejectServerCommandDriftReq {
server_id: "s".into(),
}),
UiCommand::UpsertSandboxProfile(UpsertSandboxProfileReq {
profile: SandboxProfile {
id: "p".into(),
read_dirs: vec![],
write_dirs: vec![],
allow_hosts: vec![],
env_inherit: false,
wall_ms: 1000,
memory_mb: 64,
},
}),
UiCommand::BindServerSandboxProfile(BindServerSandboxProfileReq {
server_id: "s".into(),
profile_id: Some("p".into()),
}),
];
let _ = RunnerKind::Native;
let _ = RunnerSpecific::Native {
rlimit_placeholder: None,
};
for c in writes {
assert_eq!(
c.required_capability(),
Capability::Write,
"{c:?} should be Write"
);
}
}
#[test]
fn ui_command_serde_roundtrip() {
let c = UiCommand::ListRecentEvents(ListRecentEventsReq {
session_id: Some("sid".into()),
event_type_filter: Some(vec!["decision.recorded".into()]),
limit: 100,
});
let s = serde_json::to_string(&c).unwrap();
let back: UiCommand = serde_json::from_str(&s).unwrap();
assert_eq!(c, back);
}
}