refactor: remove sandbox system and simplify agent architecture
Remove the entire sandbox security system including: - All sandbox-related Rust code and dependencies (gaol crate) - Sandbox command handlers and platform-specific implementations - Comprehensive test suite for sandbox functionality - Agent sandbox settings UI components Simplify agent configuration by removing sandbox and permission fields: - Remove sandbox_enabled, enable_file_read, enable_file_write, enable_network from agent configs - Update all CC agents to use simplified configuration format - Remove sandbox references from documentation and UI
This commit is contained in:
@@ -1,122 +0,0 @@
|
||||
import React from "react";
|
||||
import { Shield, FileText, Upload, Network, AlertTriangle } from "lucide-react";
|
||||
import { Card } from "@/components/ui/card";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { type Agent } from "@/lib/api";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
interface AgentSandboxSettingsProps {
|
||||
agent: Agent;
|
||||
onUpdate: (updates: Partial<Agent>) => void;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Component for managing per-agent sandbox permissions
|
||||
* Provides simple toggles for sandbox enable/disable and file/network permissions
|
||||
*/
|
||||
export const AgentSandboxSettings: React.FC<AgentSandboxSettingsProps> = ({
|
||||
agent,
|
||||
onUpdate,
|
||||
className
|
||||
}) => {
|
||||
const handleToggle = (field: keyof Agent, value: boolean) => {
|
||||
onUpdate({ [field]: value });
|
||||
};
|
||||
|
||||
return (
|
||||
<Card className={cn("p-4 space-y-4", className)}>
|
||||
<div className="flex items-center gap-2">
|
||||
<Shield className="h-5 w-5 text-amber-500" />
|
||||
<h4 className="font-semibold">Sandbox Permissions</h4>
|
||||
{!agent.sandbox_enabled && (
|
||||
<Badge variant="secondary" className="text-xs">
|
||||
Disabled
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
{/* Master sandbox toggle */}
|
||||
<div className="flex items-center justify-between p-3 rounded-lg border bg-muted/30">
|
||||
<div className="space-y-1">
|
||||
<Label className="text-sm font-medium">Enable Sandbox</Label>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Run this agent in a secure sandbox environment
|
||||
</p>
|
||||
</div>
|
||||
<Switch
|
||||
checked={agent.sandbox_enabled}
|
||||
onCheckedChange={(checked) => handleToggle('sandbox_enabled', checked)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Permission toggles - only visible when sandbox is enabled */}
|
||||
{agent.sandbox_enabled && (
|
||||
<div className="space-y-3 pl-4 border-l-2 border-amber-200">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
<FileText className="h-4 w-4 text-blue-500" />
|
||||
<div>
|
||||
<Label className="text-sm font-medium">File Read Access</Label>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Allow reading files and directories
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<Switch
|
||||
checked={agent.enable_file_read}
|
||||
onCheckedChange={(checked) => handleToggle('enable_file_read', checked)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
<Upload className="h-4 w-4 text-green-500" />
|
||||
<div>
|
||||
<Label className="text-sm font-medium">File Write Access</Label>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Allow creating and modifying files
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<Switch
|
||||
checked={agent.enable_file_write}
|
||||
onCheckedChange={(checked) => handleToggle('enable_file_write', checked)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
<Network className="h-4 w-4 text-purple-500" />
|
||||
<div>
|
||||
<Label className="text-sm font-medium">Network Access</Label>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Allow outbound network connections
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<Switch
|
||||
checked={agent.enable_network}
|
||||
onCheckedChange={(checked) => handleToggle('enable_network', checked)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Warning when sandbox is disabled */}
|
||||
{!agent.sandbox_enabled && (
|
||||
<div className="flex items-start gap-2 p-3 rounded-lg bg-amber-50 border border-amber-200 text-amber-800 dark:bg-amber-950/50 dark:border-amber-800 dark:text-amber-200">
|
||||
<AlertTriangle className="h-4 w-4 mt-0.5 flex-shrink-0" />
|
||||
<div className="text-xs">
|
||||
<p className="font-medium">Sandbox Disabled</p>
|
||||
<p>This agent will run with full system access. Use with caution.</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
};
|
@@ -9,7 +9,6 @@ import { api, type Agent } from "@/lib/api";
|
||||
import { cn } from "@/lib/utils";
|
||||
import MDEditor from "@uiw/react-md-editor";
|
||||
import { type AgentIconName } from "./CCAgents";
|
||||
import { AgentSandboxSettings } from "./AgentSandboxSettings";
|
||||
import { IconPicker, ICON_MAP } from "./IconPicker";
|
||||
|
||||
interface CreateAgentProps {
|
||||
@@ -48,10 +47,6 @@ export const CreateAgent: React.FC<CreateAgentProps> = ({
|
||||
const [systemPrompt, setSystemPrompt] = useState(agent?.system_prompt || "");
|
||||
const [defaultTask, setDefaultTask] = useState(agent?.default_task || "");
|
||||
const [model, setModel] = useState(agent?.model || "sonnet");
|
||||
const [sandboxEnabled, setSandboxEnabled] = useState(agent?.sandbox_enabled ?? true);
|
||||
const [enableFileRead, setEnableFileRead] = useState(agent?.enable_file_read ?? true);
|
||||
const [enableFileWrite, setEnableFileWrite] = useState(agent?.enable_file_write ?? true);
|
||||
const [enableNetwork, setEnableNetwork] = useState(agent?.enable_network ?? false);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [toast, setToast] = useState<{ message: string; type: "success" | "error" } | null>(null);
|
||||
@@ -81,11 +76,7 @@ export const CreateAgent: React.FC<CreateAgentProps> = ({
|
||||
selectedIcon,
|
||||
systemPrompt,
|
||||
defaultTask || undefined,
|
||||
model,
|
||||
sandboxEnabled,
|
||||
enableFileRead,
|
||||
enableFileWrite,
|
||||
enableNetwork
|
||||
model
|
||||
);
|
||||
} else {
|
||||
await api.createAgent(
|
||||
@@ -93,11 +84,7 @@ export const CreateAgent: React.FC<CreateAgentProps> = ({
|
||||
selectedIcon,
|
||||
systemPrompt,
|
||||
defaultTask || undefined,
|
||||
model,
|
||||
sandboxEnabled,
|
||||
enableFileRead,
|
||||
enableFileWrite,
|
||||
enableNetwork
|
||||
model
|
||||
);
|
||||
}
|
||||
|
||||
@@ -119,11 +106,7 @@ export const CreateAgent: React.FC<CreateAgentProps> = ({
|
||||
selectedIcon !== (agent?.icon || "bot") ||
|
||||
systemPrompt !== (agent?.system_prompt || "") ||
|
||||
defaultTask !== (agent?.default_task || "") ||
|
||||
model !== (agent?.model || "sonnet") ||
|
||||
sandboxEnabled !== (agent?.sandbox_enabled ?? true) ||
|
||||
enableFileRead !== (agent?.enable_file_read ?? true) ||
|
||||
enableFileWrite !== (agent?.enable_file_write ?? true) ||
|
||||
enableNetwork !== (agent?.enable_network ?? false)) &&
|
||||
model !== (agent?.model || "sonnet")) &&
|
||||
!confirm("You have unsaved changes. Are you sure you want to leave?")) {
|
||||
return;
|
||||
}
|
||||
@@ -309,29 +292,7 @@ export const CreateAgent: React.FC<CreateAgentProps> = ({
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Sandbox Settings */}
|
||||
<AgentSandboxSettings
|
||||
agent={{
|
||||
id: agent?.id,
|
||||
name,
|
||||
icon: selectedIcon,
|
||||
system_prompt: systemPrompt,
|
||||
default_task: defaultTask || undefined,
|
||||
model,
|
||||
sandbox_enabled: sandboxEnabled,
|
||||
enable_file_read: enableFileRead,
|
||||
enable_file_write: enableFileWrite,
|
||||
enable_network: enableNetwork,
|
||||
created_at: agent?.created_at || "",
|
||||
updated_at: agent?.updated_at || ""
|
||||
}}
|
||||
onUpdate={(updates) => {
|
||||
if ('sandbox_enabled' in updates) setSandboxEnabled(updates.sandbox_enabled!);
|
||||
if ('enable_file_read' in updates) setEnableFileRead(updates.enable_file_read!);
|
||||
if ('enable_file_write' in updates) setEnableFileWrite(updates.enable_file_write!);
|
||||
if ('enable_network' in updates) setEnableNetwork(updates.enable_network!);
|
||||
}}
|
||||
/>
|
||||
|
||||
|
||||
{/* System Prompt Editor */}
|
||||
<div className="space-y-2">
|
||||
@@ -377,4 +338,4 @@ export const CreateAgent: React.FC<CreateAgentProps> = ({
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
};
|
||||
|
@@ -314,9 +314,6 @@ export const GitHubAgentBrowser: React.FC<GitHubAgentBrowserProps> = ({
|
||||
</h3>
|
||||
<div className="flex items-center gap-2 mt-1">
|
||||
<Badge variant="outline">{selectedAgent.data.agent.model}</Badge>
|
||||
{selectedAgent.data.agent.sandbox_enabled && (
|
||||
<Badge variant="secondary">Sandbox</Badge>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -341,21 +338,7 @@ export const GitHubAgentBrowser: React.FC<GitHubAgentBrowserProps> = ({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Permissions */}
|
||||
<div>
|
||||
<h4 className="text-sm font-medium mb-2">Permissions</h4>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<Badge variant={selectedAgent.data.agent.enable_file_read ? "default" : "secondary"}>
|
||||
File Read: {selectedAgent.data.agent.enable_file_read ? "Yes" : "No"}
|
||||
</Badge>
|
||||
<Badge variant={selectedAgent.data.agent.enable_file_write ? "default" : "secondary"}>
|
||||
File Write: {selectedAgent.data.agent.enable_file_write ? "Yes" : "No"}
|
||||
</Badge>
|
||||
<Badge variant={selectedAgent.data.agent.enable_network ? "default" : "secondary"}>
|
||||
Network: {selectedAgent.data.agent.enable_network ? "Yes" : "No"}
|
||||
</Badge>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{/* Metadata */}
|
||||
<div className="text-xs text-muted-foreground">
|
||||
|
@@ -580,4 +580,4 @@ export const TimelineNavigator: React.FC<TimelineNavigatorProps> = ({
|
||||
</Dialog>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
};
|
||||
|
448
src/lib/api.ts
448
src/lib/api.ts
@@ -106,83 +106,6 @@ export interface ClaudeInstallation {
|
||||
source: string;
|
||||
}
|
||||
|
||||
// Sandbox API types
|
||||
export interface SandboxProfile {
|
||||
id?: number;
|
||||
name: string;
|
||||
description?: string;
|
||||
is_active: boolean;
|
||||
is_default: boolean;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface SandboxRule {
|
||||
id?: number;
|
||||
profile_id: number;
|
||||
operation_type: string;
|
||||
pattern_type: string;
|
||||
pattern_value: string;
|
||||
enabled: boolean;
|
||||
platform_support?: string;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface PlatformCapabilities {
|
||||
os: string;
|
||||
sandboxing_supported: boolean;
|
||||
operations: OperationSupport[];
|
||||
notes: string[];
|
||||
}
|
||||
|
||||
export interface OperationSupport {
|
||||
operation: string;
|
||||
support_level: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
// Sandbox violation types
|
||||
export interface SandboxViolation {
|
||||
id?: number;
|
||||
profile_id?: number;
|
||||
agent_id?: number;
|
||||
agent_run_id?: number;
|
||||
operation_type: string;
|
||||
pattern_value?: string;
|
||||
process_name?: string;
|
||||
pid?: number;
|
||||
denied_at: string;
|
||||
}
|
||||
|
||||
export interface SandboxViolationStats {
|
||||
total: number;
|
||||
recent_24h: number;
|
||||
by_operation: Array<{
|
||||
operation: string;
|
||||
count: number;
|
||||
}>;
|
||||
}
|
||||
|
||||
// Import/Export types
|
||||
export interface SandboxProfileExport {
|
||||
version: number;
|
||||
exported_at: string;
|
||||
platform: string;
|
||||
profiles: SandboxProfileWithRules[];
|
||||
}
|
||||
|
||||
export interface SandboxProfileWithRules {
|
||||
profile: SandboxProfile;
|
||||
rules: SandboxRule[];
|
||||
}
|
||||
|
||||
export interface ImportResult {
|
||||
profile_name: string;
|
||||
imported: boolean;
|
||||
reason?: string;
|
||||
new_name?: string;
|
||||
}
|
||||
|
||||
// Agent API types
|
||||
export interface Agent {
|
||||
id?: number;
|
||||
@@ -191,10 +114,6 @@ export interface Agent {
|
||||
system_prompt: string;
|
||||
default_task?: string;
|
||||
model: string;
|
||||
sandbox_enabled: boolean;
|
||||
enable_file_read: boolean;
|
||||
enable_file_write: boolean;
|
||||
enable_network: boolean;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
@@ -208,10 +127,6 @@ export interface AgentExport {
|
||||
system_prompt: string;
|
||||
default_task?: string;
|
||||
model: string;
|
||||
sandbox_enabled: boolean;
|
||||
enable_file_read: boolean;
|
||||
enable_file_write: boolean;
|
||||
enable_network: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -718,10 +633,6 @@ export const api = {
|
||||
* @param system_prompt - The system prompt for the agent
|
||||
* @param default_task - Optional default task
|
||||
* @param model - Optional model (defaults to 'sonnet')
|
||||
* @param sandbox_enabled - Optional sandbox enable flag
|
||||
* @param enable_file_read - Optional file read permission
|
||||
* @param enable_file_write - Optional file write permission
|
||||
* @param enable_network - Optional network permission
|
||||
* @returns Promise resolving to the created agent
|
||||
*/
|
||||
async createAgent(
|
||||
@@ -729,11 +640,7 @@ export const api = {
|
||||
icon: string,
|
||||
system_prompt: string,
|
||||
default_task?: string,
|
||||
model?: string,
|
||||
sandbox_enabled?: boolean,
|
||||
enable_file_read?: boolean,
|
||||
enable_file_write?: boolean,
|
||||
enable_network?: boolean
|
||||
model?: string
|
||||
): Promise<Agent> {
|
||||
try {
|
||||
return await invoke<Agent>('create_agent', {
|
||||
@@ -741,11 +648,7 @@ export const api = {
|
||||
icon,
|
||||
systemPrompt: system_prompt,
|
||||
defaultTask: default_task,
|
||||
model,
|
||||
sandboxEnabled: sandbox_enabled,
|
||||
enableFileRead: enable_file_read,
|
||||
enableFileWrite: enable_file_write,
|
||||
enableNetwork: enable_network
|
||||
model
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Failed to create agent:", error);
|
||||
@@ -761,10 +664,6 @@ export const api = {
|
||||
* @param system_prompt - The updated system prompt
|
||||
* @param default_task - Optional default task
|
||||
* @param model - Optional model
|
||||
* @param sandbox_enabled - Optional sandbox enable flag
|
||||
* @param enable_file_read - Optional file read permission
|
||||
* @param enable_file_write - Optional file write permission
|
||||
* @param enable_network - Optional network permission
|
||||
* @returns Promise resolving to the updated agent
|
||||
*/
|
||||
async updateAgent(
|
||||
@@ -773,11 +672,7 @@ export const api = {
|
||||
icon: string,
|
||||
system_prompt: string,
|
||||
default_task?: string,
|
||||
model?: string,
|
||||
sandbox_enabled?: boolean,
|
||||
enable_file_read?: boolean,
|
||||
enable_file_write?: boolean,
|
||||
enable_network?: boolean
|
||||
model?: string
|
||||
): Promise<Agent> {
|
||||
try {
|
||||
return await invoke<Agent>('update_agent', {
|
||||
@@ -786,11 +681,7 @@ export const api = {
|
||||
icon,
|
||||
systemPrompt: system_prompt,
|
||||
defaultTask: default_task,
|
||||
model,
|
||||
sandboxEnabled: sandbox_enabled,
|
||||
enableFileRead: enable_file_read,
|
||||
enableFileWrite: enable_file_write,
|
||||
enableNetwork: enable_network
|
||||
model
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Failed to update agent:", error);
|
||||
@@ -1092,337 +983,6 @@ export const api = {
|
||||
return invoke("search_files", { basePath, query });
|
||||
},
|
||||
|
||||
// Sandbox API methods
|
||||
|
||||
/**
|
||||
* Lists all sandbox profiles
|
||||
* @returns Promise resolving to an array of sandbox profiles
|
||||
*/
|
||||
async listSandboxProfiles(): Promise<SandboxProfile[]> {
|
||||
try {
|
||||
return await invoke<SandboxProfile[]>('list_sandbox_profiles');
|
||||
} catch (error) {
|
||||
console.error("Failed to list sandbox profiles:", error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a new sandbox profile
|
||||
* @param name - The profile name
|
||||
* @param description - Optional description
|
||||
* @returns Promise resolving to the created profile
|
||||
*/
|
||||
async createSandboxProfile(name: string, description?: string): Promise<SandboxProfile> {
|
||||
try {
|
||||
return await invoke<SandboxProfile>('create_sandbox_profile', { name, description });
|
||||
} catch (error) {
|
||||
console.error("Failed to create sandbox profile:", error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates a sandbox profile
|
||||
* @param id - The profile ID
|
||||
* @param name - The updated name
|
||||
* @param description - Optional description
|
||||
* @param is_active - Whether the profile is active
|
||||
* @param is_default - Whether the profile is the default
|
||||
* @returns Promise resolving to the updated profile
|
||||
*/
|
||||
async updateSandboxProfile(
|
||||
id: number,
|
||||
name: string,
|
||||
description: string | undefined,
|
||||
is_active: boolean,
|
||||
is_default: boolean
|
||||
): Promise<SandboxProfile> {
|
||||
try {
|
||||
return await invoke<SandboxProfile>('update_sandbox_profile', {
|
||||
id,
|
||||
name,
|
||||
description,
|
||||
is_active,
|
||||
is_default
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Failed to update sandbox profile:", error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Deletes a sandbox profile
|
||||
* @param id - The profile ID to delete
|
||||
* @returns Promise resolving when the profile is deleted
|
||||
*/
|
||||
async deleteSandboxProfile(id: number): Promise<void> {
|
||||
try {
|
||||
return await invoke('delete_sandbox_profile', { id });
|
||||
} catch (error) {
|
||||
console.error("Failed to delete sandbox profile:", error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets a single sandbox profile by ID
|
||||
* @param id - The profile ID
|
||||
* @returns Promise resolving to the profile
|
||||
*/
|
||||
async getSandboxProfile(id: number): Promise<SandboxProfile> {
|
||||
try {
|
||||
return await invoke<SandboxProfile>('get_sandbox_profile', { id });
|
||||
} catch (error) {
|
||||
console.error("Failed to get sandbox profile:", error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Lists rules for a sandbox profile
|
||||
* @param profileId - The profile ID
|
||||
* @returns Promise resolving to an array of rules
|
||||
*/
|
||||
async listSandboxRules(profileId: number): Promise<SandboxRule[]> {
|
||||
try {
|
||||
return await invoke<SandboxRule[]>('list_sandbox_rules', { profile_id: profileId });
|
||||
} catch (error) {
|
||||
console.error("Failed to list sandbox rules:", error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a new sandbox rule
|
||||
* @param profileId - The profile ID
|
||||
* @param operation_type - The operation type
|
||||
* @param pattern_type - The pattern type
|
||||
* @param pattern_value - The pattern value
|
||||
* @param enabled - Whether the rule is enabled
|
||||
* @param platform_support - Optional platform support JSON
|
||||
* @returns Promise resolving to the created rule
|
||||
*/
|
||||
async createSandboxRule(
|
||||
profileId: number,
|
||||
operation_type: string,
|
||||
pattern_type: string,
|
||||
pattern_value: string,
|
||||
enabled: boolean,
|
||||
platform_support?: string
|
||||
): Promise<SandboxRule> {
|
||||
try {
|
||||
return await invoke<SandboxRule>('create_sandbox_rule', {
|
||||
profile_id: profileId,
|
||||
operation_type,
|
||||
pattern_type,
|
||||
pattern_value,
|
||||
enabled,
|
||||
platform_support
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Failed to create sandbox rule:", error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates a sandbox rule
|
||||
* @param id - The rule ID
|
||||
* @param operation_type - The operation type
|
||||
* @param pattern_type - The pattern type
|
||||
* @param pattern_value - The pattern value
|
||||
* @param enabled - Whether the rule is enabled
|
||||
* @param platform_support - Optional platform support JSON
|
||||
* @returns Promise resolving to the updated rule
|
||||
*/
|
||||
async updateSandboxRule(
|
||||
id: number,
|
||||
operation_type: string,
|
||||
pattern_type: string,
|
||||
pattern_value: string,
|
||||
enabled: boolean,
|
||||
platform_support?: string
|
||||
): Promise<SandboxRule> {
|
||||
try {
|
||||
return await invoke<SandboxRule>('update_sandbox_rule', {
|
||||
id,
|
||||
operation_type,
|
||||
pattern_type,
|
||||
pattern_value,
|
||||
enabled,
|
||||
platform_support
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Failed to update sandbox rule:", error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Deletes a sandbox rule
|
||||
* @param id - The rule ID to delete
|
||||
* @returns Promise resolving when the rule is deleted
|
||||
*/
|
||||
async deleteSandboxRule(id: number): Promise<void> {
|
||||
try {
|
||||
return await invoke('delete_sandbox_rule', { id });
|
||||
} catch (error) {
|
||||
console.error("Failed to delete sandbox rule:", error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets platform capabilities for sandbox configuration
|
||||
* @returns Promise resolving to platform capabilities
|
||||
*/
|
||||
async getPlatformCapabilities(): Promise<PlatformCapabilities> {
|
||||
try {
|
||||
return await invoke<PlatformCapabilities>('get_platform_capabilities');
|
||||
} catch (error) {
|
||||
console.error("Failed to get platform capabilities:", error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Tests a sandbox profile
|
||||
* @param profileId - The profile ID to test
|
||||
* @returns Promise resolving to test result message
|
||||
*/
|
||||
async testSandboxProfile(profileId: number): Promise<string> {
|
||||
try {
|
||||
return await invoke<string>('test_sandbox_profile', { profile_id: profileId });
|
||||
} catch (error) {
|
||||
console.error("Failed to test sandbox profile:", error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
// Sandbox violation methods
|
||||
|
||||
/**
|
||||
* Lists sandbox violations with optional filtering
|
||||
* @param profileId - Optional profile ID to filter by
|
||||
* @param agentId - Optional agent ID to filter by
|
||||
* @param limit - Optional limit on number of results
|
||||
* @returns Promise resolving to array of violations
|
||||
*/
|
||||
async listSandboxViolations(profileId?: number, agentId?: number, limit?: number): Promise<SandboxViolation[]> {
|
||||
try {
|
||||
return await invoke<SandboxViolation[]>('list_sandbox_violations', {
|
||||
profile_id: profileId,
|
||||
agent_id: agentId,
|
||||
limit
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Failed to list sandbox violations:", error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Logs a sandbox violation
|
||||
* @param violation - The violation details
|
||||
* @returns Promise resolving when logged
|
||||
*/
|
||||
async logSandboxViolation(violation: {
|
||||
profileId?: number;
|
||||
agentId?: number;
|
||||
agentRunId?: number;
|
||||
operationType: string;
|
||||
patternValue?: string;
|
||||
processName?: string;
|
||||
pid?: number;
|
||||
}): Promise<void> {
|
||||
try {
|
||||
return await invoke('log_sandbox_violation', {
|
||||
profile_id: violation.profileId,
|
||||
agent_id: violation.agentId,
|
||||
agent_run_id: violation.agentRunId,
|
||||
operation_type: violation.operationType,
|
||||
pattern_value: violation.patternValue,
|
||||
process_name: violation.processName,
|
||||
pid: violation.pid
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Failed to log sandbox violation:", error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Clears old sandbox violations
|
||||
* @param olderThanDays - Optional days to keep (clears all if not specified)
|
||||
* @returns Promise resolving to number of deleted violations
|
||||
*/
|
||||
async clearSandboxViolations(olderThanDays?: number): Promise<number> {
|
||||
try {
|
||||
return await invoke<number>('clear_sandbox_violations', { older_than_days: olderThanDays });
|
||||
} catch (error) {
|
||||
console.error("Failed to clear sandbox violations:", error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets sandbox violation statistics
|
||||
* @returns Promise resolving to violation stats
|
||||
*/
|
||||
async getSandboxViolationStats(): Promise<SandboxViolationStats> {
|
||||
try {
|
||||
return await invoke<SandboxViolationStats>('get_sandbox_violation_stats');
|
||||
} catch (error) {
|
||||
console.error("Failed to get sandbox violation stats:", error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
// Import/Export methods
|
||||
|
||||
/**
|
||||
* Exports a single sandbox profile with its rules
|
||||
* @param profileId - The profile ID to export
|
||||
* @returns Promise resolving to export data
|
||||
*/
|
||||
async exportSandboxProfile(profileId: number): Promise<SandboxProfileExport> {
|
||||
try {
|
||||
return await invoke<SandboxProfileExport>('export_sandbox_profile', { profile_id: profileId });
|
||||
} catch (error) {
|
||||
console.error("Failed to export sandbox profile:", error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Exports all sandbox profiles
|
||||
* @returns Promise resolving to export data
|
||||
*/
|
||||
async exportAllSandboxProfiles(): Promise<SandboxProfileExport> {
|
||||
try {
|
||||
return await invoke<SandboxProfileExport>('export_all_sandbox_profiles');
|
||||
} catch (error) {
|
||||
console.error("Failed to export all sandbox profiles:", error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Imports sandbox profiles from export data
|
||||
* @param exportData - The export data to import
|
||||
* @returns Promise resolving to import results
|
||||
*/
|
||||
async importSandboxProfiles(exportData: SandboxProfileExport): Promise<ImportResult[]> {
|
||||
try {
|
||||
return await invoke<ImportResult[]>('import_sandbox_profiles', { export_data: exportData });
|
||||
} catch (error) {
|
||||
console.error("Failed to import sandbox profiles:", error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets overall usage statistics
|
||||
* @returns Promise resolving to usage statistics
|
||||
|
Reference in New Issue
Block a user