feat(skills): store immutable plugin upstream snapshots

This commit is contained in:
2026-06-16 11:42:46 +08:00
parent 41b45e0423
commit 094dde0b81
5 changed files with 386 additions and 4 deletions

View File

@ -84,6 +84,7 @@ class SkillVersion:
summary: str = ""
tool_hints: list[str] = field(default_factory=list)
provenance: dict[str, Any] = field(default_factory=dict)
tree_hash: str = ""
def to_dict(self) -> dict[str, Any]:
return {
@ -100,6 +101,7 @@ class SkillVersion:
"summary": self.summary,
"tool_hints": list(self.tool_hints),
"provenance": dict(self.provenance),
"tree_hash": self.tree_hash,
}
@classmethod
@ -118,6 +120,48 @@ class SkillVersion:
summary=str(payload.get("summary") or ""),
tool_hints=_coerce_string_list(payload.get("tool_hints")),
provenance=dict(payload.get("provenance") or {}),
tree_hash=str(payload.get("tree_hash") or ""),
)
@dataclass(slots=True)
class SkillUpstreamSnapshot:
skill_name: str
source_kind: str
source_id: str
source_version: str
source_path: str
skill_content_hash: str
skill_tree_hash: str
created_at: str
frontmatter: dict[str, Any] = field(default_factory=dict)
staged_root: Any | None = field(default=None, repr=False, compare=False)
def to_dict(self) -> dict[str, Any]:
return {
"skill_name": self.skill_name,
"source_kind": self.source_kind,
"source_id": self.source_id,
"source_version": self.source_version,
"source_path": self.source_path,
"skill_content_hash": self.skill_content_hash,
"skill_tree_hash": self.skill_tree_hash,
"created_at": self.created_at,
"frontmatter": dict(self.frontmatter),
}
@classmethod
def from_dict(cls, payload: dict[str, Any]) -> "SkillUpstreamSnapshot":
return cls(
skill_name=str(payload["skill_name"]),
source_kind=str(payload.get("source_kind") or ""),
source_id=str(payload.get("source_id") or ""),
source_version=str(payload.get("source_version") or ""),
source_path=str(payload.get("source_path") or ""),
skill_content_hash=str(payload.get("skill_content_hash") or ""),
skill_tree_hash=str(payload.get("skill_tree_hash") or ""),
created_at=str(payload.get("created_at") or ""),
frontmatter=dict(payload.get("frontmatter") or {}),
)