feat(infra): tmp partagé inter-projets géré par IdeA (handles opaques, leases, GC, projection sandbox) — #189 (QA verte)

- Domaine: port ManagedTempStore + modèle (handle opaque, kind Directory/File, état Active/Released, allocation/lease, expiry).
- Application: use cases Allocate/Resolve/Release/GcManagedTemp, horodatés via Clock.
- Infrastructure: impl FS FsManagedTempStore sous app_data_dir/managed-tmp (root global inter-projets, métadonnées par handle, GC des leases expirés/libérés).
- Exposition MCP contrôlée (ManagedTempToolProvider, catalogue) + câblage sandbox: les agents résolvent un handle au lieu d'inventer un path libre.
- Tests: application/infrastructure managed_temp.
This commit is contained in:
2026-08-13 13:34:33 +02:00
parent d7dfbcdfcb
commit fdca55ecd4
22 changed files with 2000 additions and 72 deletions

View File

@ -45,29 +45,31 @@ use crate::dto::{
parse_layout_id, parse_memory_slug, parse_model_server_id, parse_node_id, parse_profile_id,
parse_project_id, parse_session_id, parse_skill_id, parse_task_id, parse_template_id,
parse_ticket_id, save_model_server_input, AgentDriftListDto, AgentDto, AgentListDto,
AppExitWorkGuardStateDto, AssignSkillRequestDto, AttachBackgroundTaskResultDto,
AttachLiveAgentRequestDto, AttachLiveAgentResponseDto, BackgroundTaskDto, CellKind,
ChangeAgentProfileDto, ChangeAgentProfileRequestDto, ChatAttachmentDto, ChatAttachmentInputDto,
ChatDraftScopeRequestDto, ChatPromptAttachmentDto, CloneOpenCodeProfileFromSeedRequestDto,
CloneProfileFromSeedRequestDto, ConfigureProfilesRequestDto, ConversationDetailsDto,
CreateAgentFromTemplateRequestDto, CreateAgentRequestDto, CreateLayoutRequestDto,
CreateLayoutResultDto, CreateMemoryRequestDto, CreateProjectRequestDto, CreateSkillRequestDto,
CreateTemplateRequestDto, DeleteLayoutRequestDto, DeleteLayoutResultDto,
DeliveredDelegationRequestDto, DetectProfilesRequestDto, DetectProfilesResponseDto,
EmbedderEnginesDto, EmbedderProfileDto, EmbedderProfileListDto, ErrorDto,
ExecuteSlashCommandRequestDto, ExecuteSlashCommandResponseDto, FirstRunStateDto,
FrontAttachedRequestDto, GitBranchesDto, GitCheckoutRequestDto, GitCommitDto, GitCommitListDto,
GitCommitRequestDto, GitStageRequestDto, GitStatusListDto, GraphCommitListDto,
HealthRequestDto, HealthResponseDto, ImportChatAttachmentsRequestDto,
ImportChatAttachmentsResponseDto, InspectConversationRequestDto, InterruptAgentRequestDto,
LaunchAgentRequestDto, LayoutDto, LayoutOperationDto, ListLayoutsDto, LiveAgentListDto,
MemoryDto, MemoryIndexDto, MemoryLinksDto, MemoryListDto, ModelServerConfigDto,
ModelServerConfigListDto, OpenCodeProviderListDto, OpenTerminalRequestDto,
PreviewModelServerCommandDto, ProfileDto, ProfileListDto, ProfileModelCatalogDto, ProjectDto,
ProjectListDto, ProjectMcpToolPermissionsDto, ProjectPermissionsDto,
ProjectSystemPermissionsDto, ProjectWorkStateDto, ReadAgentContextResponseDto,
ReadChatDraftResponseDto, ReadConversationPageRequestDto, ReattachChatDto, ReattachResultDto,
RecallMemoryRequestDto, RenameLayoutRequestDto, ReplyChunk, ResizeTerminalRequestDto,
AllocateManagedTempRequestDto, AppExitWorkGuardStateDto, AssignSkillRequestDto,
AttachBackgroundTaskResultDto, AttachLiveAgentRequestDto, AttachLiveAgentResponseDto,
BackgroundTaskDto, CellKind, ChangeAgentProfileDto, ChangeAgentProfileRequestDto,
ChatAttachmentDto, ChatAttachmentInputDto, ChatDraftScopeRequestDto, ChatPromptAttachmentDto,
CloneOpenCodeProfileFromSeedRequestDto, CloneProfileFromSeedRequestDto,
ConfigureProfilesRequestDto, ConversationDetailsDto, CreateAgentFromTemplateRequestDto,
CreateAgentRequestDto, CreateLayoutRequestDto, CreateLayoutResultDto, CreateMemoryRequestDto,
CreateProjectRequestDto, CreateSkillRequestDto, CreateTemplateRequestDto,
DeleteLayoutRequestDto, DeleteLayoutResultDto, DeliveredDelegationRequestDto,
DetectProfilesRequestDto, DetectProfilesResponseDto, EmbedderEnginesDto, EmbedderProfileDto,
EmbedderProfileListDto, ErrorDto, ExecuteSlashCommandRequestDto,
ExecuteSlashCommandResponseDto, FirstRunStateDto, FrontAttachedRequestDto, GitBranchesDto,
GitCheckoutRequestDto, GitCommitDto, GitCommitListDto, GitCommitRequestDto, GitStageRequestDto,
GitStatusListDto, GraphCommitListDto, HealthRequestDto, HealthResponseDto,
ImportChatAttachmentsRequestDto, ImportChatAttachmentsResponseDto,
InspectConversationRequestDto, InterruptAgentRequestDto, LaunchAgentRequestDto, LayoutDto,
LayoutOperationDto, ListLayoutsDto, LiveAgentListDto, ManagedTempGcResponseDto,
ManagedTempHandleRequestDto, ManagedTempLeaseDto, ManagedTempLeaseResponseDto, MemoryDto,
MemoryIndexDto, MemoryLinksDto, MemoryListDto, ModelServerConfigDto, ModelServerConfigListDto,
OpenCodeProviderListDto, OpenTerminalRequestDto, PreviewModelServerCommandDto, ProfileDto,
ProfileListDto, ProfileModelCatalogDto, ProjectDto, ProjectListDto,
ProjectMcpToolPermissionsDto, ProjectPermissionsDto, ProjectSystemPermissionsDto,
ProjectWorkStateDto, ReadAgentContextResponseDto, ReadChatDraftResponseDto,
ReadConversationPageRequestDto, ReattachChatDto, ReattachResultDto, RecallMemoryRequestDto,
RenameLayoutRequestDto, ReplyChunk, ResizeTerminalRequestDto,
ResolveAgentPermissionsRequestDto, ResolveAgentPermissionsResponseDto,
ResolveAgentSystemPermissionsRequestDto, ResolvedAgentSystemPermissionsDto,
ResumableAgentListDto, SaveChatDraftRequestDto, SaveEmbedderProfileRequestDto,
@ -2310,6 +2312,96 @@ pub async fn clear_chat_draft(
.map_err(ErrorDto::from)
}
/// `managed_temp_allocate` — allocate an IdeA-managed temporary file/directory.
///
/// # Errors
/// Returns an [`ErrorDto`] for malformed ids, invalid TTL/purpose, or store failure.
#[tauri::command]
pub async fn managed_temp_allocate(
request: AllocateManagedTempRequestDto,
state: State<'_, AppState>,
) -> Result<ManagedTempLeaseResponseDto, ErrorDto> {
let owner_project_id = request
.owner_project_id
.as_deref()
.map(parse_project_id)
.transpose()?;
let output = state
.allocate_managed_temp
.execute(application::AllocateManagedTempInput {
owner_project_id,
kind: request.kind,
purpose: request.purpose,
ttl_ms: request.ttl_ms,
})
.await
.map_err(ErrorDto::from)?;
Ok(ManagedTempLeaseResponseDto {
lease: ManagedTempLeaseDto::from(output.lease),
})
}
/// `managed_temp_resolve` — resolve an active IdeA-managed temporary handle.
///
/// # Errors
/// Returns an [`ErrorDto`] for malformed handles, missing/released/expired handles,
/// or store failure.
#[tauri::command]
pub async fn managed_temp_resolve(
request: ManagedTempHandleRequestDto,
state: State<'_, AppState>,
) -> Result<ManagedTempLeaseResponseDto, ErrorDto> {
let output = state
.resolve_managed_temp
.execute(application::ResolveManagedTempInput {
handle: request.handle,
})
.await
.map_err(ErrorDto::from)?;
Ok(ManagedTempLeaseResponseDto {
lease: ManagedTempLeaseDto::from(output.lease),
})
}
/// `managed_temp_release` — release one IdeA-managed temporary handle.
///
/// # Errors
/// Returns an [`ErrorDto`] for malformed handles, missing handles, or store failure.
#[tauri::command]
pub async fn managed_temp_release(
request: ManagedTempHandleRequestDto,
state: State<'_, AppState>,
) -> Result<ManagedTempLeaseResponseDto, ErrorDto> {
let output = state
.release_managed_temp
.execute(application::ReleaseManagedTempInput {
handle: request.handle,
})
.await
.map_err(ErrorDto::from)?;
Ok(ManagedTempLeaseResponseDto {
lease: ManagedTempLeaseDto::from(output.lease),
})
}
/// `managed_temp_gc` — delete released or expired managed temporary allocations.
///
/// # Errors
/// Returns an [`ErrorDto`] for store failure.
#[tauri::command]
pub async fn managed_temp_gc(
state: State<'_, AppState>,
) -> Result<ManagedTempGcResponseDto, ErrorDto> {
let output = state
.gc_managed_temp
.execute()
.await
.map_err(ErrorDto::from)?;
Ok(ManagedTempGcResponseDto {
deleted: output.report.deleted,
})
}
/// `agent_send` — send a prompt to a live **structured** (chat) session and pump
/// the turn's reply events to the frontend over `on_reply` (ARCHITECTURE §17.7).
///