WIP simplifying load/startup

This commit is contained in:
John Lancaster
2026-07-26 17:23:39 -05:00
parent 5e20f69cfe
commit 42ea105bee
30 changed files with 855 additions and 766 deletions
+29 -23
View File
@@ -2,12 +2,13 @@ import re
from collections.abc import Mapping
from pathlib import PurePosixPath
from types import MappingProxyType
from typing import Annotated
from typing import ClassVar
from typing import Final
from pydantic import BaseModel
from pydantic import BeforeValidator
from pydantic import ConfigDict
from pydantic import field_validator
SKILL_ID_RE: Final[re.Pattern[str]] = re.compile(r"^[a-z][a-z0-9-]*$")
SEMVER_RE: Final[re.Pattern[str]] = re.compile(r"^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:[-+][0-9A-Za-z.-]+)?$")
@@ -29,30 +30,35 @@ def frozen_mapping[K, V](value: Mapping[K, V] | None = None) -> Mapping[K, V]:
return MappingProxyType(dict(value) if value is not None else {})
def parse_docs_path(value: str | PurePosixPath) -> PurePosixPath:
raw = value.as_posix() if isinstance(value, PurePosixPath) else value
if "\\" in raw:
raise ValueError("docs path must use POSIX separators")
path = PurePosixPath(raw)
if path.is_absolute() or ".." in path.parts:
raise ValueError("path must be a docs-relative path")
if path.as_posix() != raw:
raise ValueError("path must be normalized")
if path.suffix.lower() != ".md":
raise ValueError("path must point to a markdown file")
return path
def parse_reference_path(value: str | PurePosixPath) -> PurePosixPath:
path = parse_docs_path(value)
if len(path.parts) < 2 or path.parts[0] != "references":
raise ValueError("reference path must stay under references/")
return path
type DocsPath = Annotated[PurePosixPath, BeforeValidator(parse_docs_path)]
type ReferencePath = Annotated[PurePosixPath, BeforeValidator(parse_reference_path)]
class ReferenceEntry(StrictFrozenModel):
"""Reference metadata for a markdown file within a skill."""
path: str
path: ReferencePath
mime_type: str = "text/markdown"
title: str | None = None
@field_validator("path")
@classmethod
def validate_reference_path(cls, value: str) -> str:
path = PurePosixPath(value)
if path.is_absolute() or ".." in path.parts:
raise ValueError("reference path must be a relative in-skill path")
if not str(path).startswith("references/"):
raise ValueError("reference path must stay under references/")
if path.suffix.lower() != ".md":
raise ValueError("reference path must target a markdown file")
return path.as_posix()
def _normalize_docs_path(path: str) -> str:
normalized = PurePosixPath(path)
if normalized.is_absolute() or ".." in normalized.parts:
raise ValueError("path must be a normalized docs-relative path")
if normalized.suffix.lower() != ".md":
raise ValueError("path must point to a markdown file")
return normalized.as_posix()
+2 -2
View File
@@ -1,6 +1,5 @@
import re
from collections.abc import Mapping
from pathlib import PurePosixPath
from typing import TYPE_CHECKING
import yaml
@@ -10,6 +9,7 @@ from pydantic import model_validator
from .common import SEMVER_RE
from .common import SKILL_ID_RE
from .common import DocsPath
from .common import StrictFrozenModel
from .common import frozen_mapping
@@ -103,7 +103,7 @@ class StoredPrompt(StrictFrozenModel):
"""Normalized prompt document content with path and frontmatter for storage in the registry."""
prompt_id: str
relpath: PurePosixPath
relpath: DocsPath
content: str
frontmatter: PromptFrontmatter
+10 -5
View File
@@ -3,17 +3,22 @@ from collections.abc import Mapping
from pydantic import Field
from pydantic import field_validator
from .common import DocsPath
from .common import StrictFrozenModel
from .common import frozen_mapping
from .prompt import PromptArgumentEntry
def _empty_docs_mapping() -> Mapping[DocsPath, str]:
return frozen_mapping()
class ReferenceRecord(StrictFrozenModel):
"""Registry record for a resolved skill reference document."""
ref_id: str
uri: str
relpath: str
relpath: DocsPath
mime_type: str
title: str | None
content: str
@@ -29,7 +34,7 @@ class SkillRecord(StrictFrozenModel):
tags: tuple[str, ...]
capabilities: tuple[str, ...]
document_uri: str
document_relpath: str
document_relpath: DocsPath
document_content: str
references: Mapping[str, ReferenceRecord] = Field(default_factory=frozen_mapping)
@@ -74,7 +79,7 @@ class PromptRecord(StrictFrozenModel):
capabilities: tuple[str, ...]
arguments: Mapping[str, PromptArgumentEntry] = Field(default_factory=frozen_mapping)
document_uri: str
document_relpath: str
document_relpath: DocsPath
document_content: str
@field_validator("arguments", mode="before")
@@ -196,8 +201,8 @@ class DocsRegistry(StrictFrozenModel):
skills_by_id: Mapping[str, SkillRecord] = Field(default_factory=frozen_mapping)
skills_in_load_order: tuple[str, ...]
skills_summary_in_load_order: tuple[SkillSummaryRecord, ...]
docs_markdown_by_path: Mapping[str, str] = Field(default_factory=frozen_mapping)
docs_markdown_path_index: tuple[str, ...]
docs_markdown_by_path: Mapping[DocsPath, str] = Field(default_factory=_empty_docs_mapping)
docs_markdown_path_index: tuple[DocsPath, ...]
tag_to_skill_ids: Mapping[str, tuple[str, ...]] = Field(default_factory=frozen_mapping)
capability_to_skill_ids: Mapping[str, tuple[str, ...]] = Field(default_factory=frozen_mapping)
prompts_by_id: Mapping[str, PromptRecord] = Field(default_factory=frozen_mapping)
+3 -3
View File
@@ -1,5 +1,4 @@
from collections.abc import Mapping
from pathlib import PurePosixPath
import yaml
from pydantic import Field
@@ -8,6 +7,7 @@ from pydantic import model_validator
from .common import SEMVER_RE
from .common import SKILL_ID_RE
from .common import DocsPath
from .common import ReferenceEntry
from .common import StrictFrozenModel
from .common import frozen_mapping
@@ -91,7 +91,7 @@ class StoredSkillReference(StrictFrozenModel):
"""Structured representation of a skill reference markdown document."""
ref_id: str
relpath: PurePosixPath
relpath: DocsPath
content: str
entry: ReferenceEntry
@@ -100,7 +100,7 @@ class StoredSkill(StrictFrozenModel):
"""Structured representation of a skill markdown document."""
skill_id: str
relpath: PurePosixPath
relpath: DocsPath
content: str
frontmatter: SkillFrontmatter
references: Mapping[str, StoredSkillReference] = Field(default_factory=frozen_mapping)