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:
92
crates/domain/src/template.rs
Normal file
92
crates/domain/src/template.rs
Normal file
@ -0,0 +1,92 @@
|
||||
//! Agent templates (global IDE store) and their monotonic versioning.
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::error::DomainError;
|
||||
use crate::ids::{ProfileId, TemplateId};
|
||||
use crate::markdown::MarkdownDoc;
|
||||
|
||||
/// Monotonically increasing template version.
|
||||
///
|
||||
/// Invariant (enforced via [`TemplateVersion::next`]): a version only ever
|
||||
/// increases by one when the template content changes (ARCHITECTURE §8.1).
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||
#[serde(transparent)]
|
||||
pub struct TemplateVersion(pub u64);
|
||||
|
||||
impl TemplateVersion {
|
||||
/// The initial version assigned to a freshly created template.
|
||||
pub const INITIAL: Self = Self(1);
|
||||
|
||||
/// Returns the next version (current + 1).
|
||||
#[must_use]
|
||||
pub const fn next(self) -> Self {
|
||||
Self(self.0 + 1)
|
||||
}
|
||||
|
||||
/// Returns the raw version number.
|
||||
#[must_use]
|
||||
pub const fn get(self) -> u64 {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for TemplateVersion {
|
||||
fn default() -> Self {
|
||||
Self::INITIAL
|
||||
}
|
||||
}
|
||||
|
||||
/// A reusable agent template stored in the global IDE store.
|
||||
///
|
||||
/// Invariants:
|
||||
/// - `name` non-empty,
|
||||
/// - `version` is monotonic; bumping is done via [`AgentTemplate::with_updated_content`].
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct AgentTemplate {
|
||||
/// Stable identifier.
|
||||
pub id: TemplateId,
|
||||
/// Display name.
|
||||
pub name: String,
|
||||
/// Markdown content.
|
||||
pub content_md: MarkdownDoc,
|
||||
/// Current version.
|
||||
pub version: TemplateVersion,
|
||||
/// Default runtime profile for agents created from this template.
|
||||
pub default_profile_id: ProfileId,
|
||||
}
|
||||
|
||||
impl AgentTemplate {
|
||||
/// Builds a validated template at [`TemplateVersion::INITIAL`].
|
||||
///
|
||||
/// # Errors
|
||||
/// Returns [`DomainError::EmptyField`] if `name` is empty.
|
||||
pub fn new(
|
||||
id: TemplateId,
|
||||
name: impl Into<String>,
|
||||
content_md: MarkdownDoc,
|
||||
default_profile_id: ProfileId,
|
||||
) -> Result<Self, DomainError> {
|
||||
let name = name.into();
|
||||
crate::validation::non_empty(&name, "template.name")?;
|
||||
Ok(Self {
|
||||
id,
|
||||
name,
|
||||
content_md,
|
||||
version: TemplateVersion::INITIAL,
|
||||
default_profile_id,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns a copy of this template with new content and the version bumped
|
||||
/// by one, preserving the monotonic-version invariant.
|
||||
#[must_use]
|
||||
pub fn with_updated_content(&self, content_md: MarkdownDoc) -> Self {
|
||||
Self {
|
||||
content_md,
|
||||
version: self.version.next(),
|
||||
..self.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user