"""Draft lifecycle for Beaver skills.""" from __future__ import annotations from uuid import uuid4 from beaver.skills.specs import SkillDraft, SkillSpecStore class DraftService: def __init__(self, store: SkillSpecStore) -> None: self.store = store def create_new_skill_draft( self, *, skill_name: str, proposed_content: str, proposed_frontmatter: dict, created_by: str, reason: str, trigger_run_id: str | None = None, trigger_session_id: str | None = None, evidence_refs: list[dict] | None = None, ) -> SkillDraft: draft = SkillDraft( draft_id=uuid4().hex, skill_name=skill_name, base_version=None, proposed_content=proposed_content, proposed_frontmatter=dict(proposed_frontmatter), created_at=_utc_now(), created_by=created_by, trigger_run_id=trigger_run_id, trigger_session_id=trigger_session_id, reason=reason, evidence_refs=list(evidence_refs or []), proposal_kind="new_skill", ) self.store.write_draft(draft) return draft def create_revision_draft( self, *, skill_name: str, base_version: str | None, proposed_content: str, proposed_frontmatter: dict, created_by: str, reason: str, trigger_run_id: str | None = None, trigger_session_id: str | None = None, evidence_refs: list[dict] | None = None, ) -> SkillDraft: draft = SkillDraft( draft_id=uuid4().hex, skill_name=skill_name, base_version=base_version, proposed_content=proposed_content, proposed_frontmatter=dict(proposed_frontmatter), created_at=_utc_now(), created_by=created_by, trigger_run_id=trigger_run_id, trigger_session_id=trigger_session_id, reason=reason, evidence_refs=list(evidence_refs or []), proposal_kind="revise_skill", ) self.store.write_draft(draft) return draft def create_merge_draft( self, *, skill_name: str, base_version: str | None, proposed_content: str, proposed_frontmatter: dict, created_by: str, reason: str, evidence_refs: list[dict] | None = None, ) -> SkillDraft: draft = self.create_revision_draft( skill_name=skill_name, base_version=base_version, proposed_content=proposed_content, proposed_frontmatter=proposed_frontmatter, created_by=created_by, reason=reason, evidence_refs=evidence_refs, ) draft.proposal_kind = "merge_skills" self.store.write_draft(draft) return draft def create_plugin_update_draft( self, *, skill_name: str, base_version: str, proposed_content: str, proposed_frontmatter: dict, created_by: str, reason: str, provenance: dict, evidence_refs: list[dict] | None = None, ) -> SkillDraft: draft = SkillDraft( draft_id=uuid4().hex, skill_name=skill_name, base_version=base_version, proposed_content=proposed_content, proposed_frontmatter=dict(proposed_frontmatter), created_at=_utc_now(), created_by=created_by, reason=reason, evidence_refs=list(evidence_refs or []), proposal_kind="plugin_skill_update", provenance=dict(provenance), ) self.store.write_draft(draft) return draft def create_retire_proposal( self, *, skill_name: str, base_version: str | None, created_by: str, reason: str, evidence_refs: list[dict] | None = None, ) -> SkillDraft: draft = SkillDraft( draft_id=uuid4().hex, skill_name=skill_name, base_version=base_version, proposed_content="", proposed_frontmatter={}, created_at=_utc_now(), created_by=created_by, reason=reason, evidence_refs=list(evidence_refs or []), proposal_kind="retire_skill", ) self.store.write_draft(draft) return draft def list_drafts(self, skill_name: str | None = None) -> list[SkillDraft]: return self.store.list_drafts(skill_name) def get_draft(self, skill_name: str, draft_id: str) -> SkillDraft | None: return self.store.read_draft(skill_name, draft_id) def delete_draft(self, skill_name: str, draft_id: str) -> bool: return self.store.delete_draft(skill_name, draft_id) def _utc_now() -> str: from datetime import datetime, timezone return datetime.now(timezone.utc).isoformat()