feat: add main features

Agents for developpement added + frontend add + backend added. Git viewer created + agent and template creator + layout and project creator
This commit is contained in:
2026-06-06 01:27:01 +02:00
parent 55b3bee2c8
commit 307ae71857
273 changed files with 48740 additions and 0 deletions

View File

@ -0,0 +1,6 @@
//! Window/tab use cases (ARCHITECTURE §6, §10; L10). Detaching a tab into a new
//! OS window, persisting the workspace.
mod usecases;
pub use usecases::{MoveTabToNewWindow, MoveTabToNewWindowInput, MoveTabToNewWindowOutput};

View File

@ -0,0 +1,73 @@
//! Window/tab use cases (ARCHITECTURE §6, §10; L10).
//!
//! [`MoveTabToNewWindow`] detaches a tab into a new OS window. The topology
//! change is the pure [`Workspace::move_tab_to_new_window`] domain operation; the
//! use case only loads/persists the workspace and mints the new window id.
use std::sync::Arc;
use domain::ids::{TabId, WindowId};
use domain::layout::Workspace;
use domain::ports::{IdGenerator, ProjectStore};
use crate::error::AppError;
/// Input for [`MoveTabToNewWindow::execute`].
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MoveTabToNewWindowInput {
/// The tab to detach into its own new window.
pub tab_id: TabId,
}
/// Output of [`MoveTabToNewWindow::execute`].
#[derive(Debug, Clone, PartialEq)]
pub struct MoveTabToNewWindowOutput {
/// The id minted for the new window.
pub new_window_id: WindowId,
/// The resulting workspace (already persisted).
pub workspace: Workspace,
}
/// Detaches a tab into a freshly-created window and persists the workspace.
pub struct MoveTabToNewWindow {
store: Arc<dyn ProjectStore>,
ids: Arc<dyn IdGenerator>,
}
impl MoveTabToNewWindow {
/// Builds the use case from its ports.
#[must_use]
pub fn new(store: Arc<dyn ProjectStore>, ids: Arc<dyn IdGenerator>) -> Self {
Self { store, ids }
}
/// Executes the detach.
///
/// # Errors
/// - [`AppError::NotFound`] if the tab is not in the workspace,
/// - [`AppError::Invalid`] if the resulting window is invalid,
/// - [`AppError::Store`] on persistence failure.
pub async fn execute(
&self,
input: MoveTabToNewWindowInput,
) -> Result<MoveTabToNewWindowOutput, AppError> {
let workspace = self.store.load_workspace().await?;
let new_window_id = WindowId::from_uuid(self.ids.new_uuid());
let workspace = workspace
.move_tab_to_new_window(input.tab_id, new_window_id)
.map_err(|e| match e {
domain::layout::LayoutError::TabNotFound(t) => {
AppError::NotFound(format!("tab {t}"))
}
other => AppError::Invalid(other.to_string()),
})?;
self.store.save_workspace(&workspace).await?;
Ok(MoveTabToNewWindowOutput {
new_window_id,
workspace,
})
}
}