smriti/cli/smriti_cli/skill_pack/renderer.py
Himanshu Dongre ec0139f707 Add Smriti agent skill pack source and renderer
The skill pack is an instruction file installed into an agent host's
project directory so Smriti's workflow lives in the agent's system
context instead of documentation nobody reads. A single versioned
template.md renders for both Claude Code (MCP-primary) and Codex
(CLI-primary) via a pure-function substituter, keeping content in
sync mechanically across targets.

template.md contains 15 sections. The load-bearing one is Section 5,
When NOT to checkpoint, with equal weight to Section 4. Agents are
told explicitly not to checkpoint after every small step, not to
produce end-of-session blobs, not to treat commits as a save button,
not to stack commits on inconsistent state, not to restate existing
state, and not to checkpoint just because the user asked when there
is no real inflection point. A frequency target (2-4 checkpoints per
4-hour session) and a three-question signal test give agents concrete
criteria for every call.

Other sections cover the read-state-first reflex, when to fork, when
to review, when to compare, when to restore, drift detection,
explicit anti-patterns (HANDOFF.md, silent state reads, inconsistent
author_agent, /chat/send), and the phrases the agent should say out
loud so the human watching has an audit trail.

Renderer API (all pure functions): load_template, get_version, render,
install. install is version-aware: refuses to overwrite a destination
whose installed version is >= the template version unless force=True.
Dry-run mode returns the rendered content without writing.

Content-integrity tests parametrized over both targets assert that
every anti-pattern rule, the signal test, the frequency target, and
the drift-detection guidance appear in the rendered output. If a
future template edit drops any of them, tests fail loudly.

22 skill pack tests, all green.
2026-04-12 02:07:47 +05:30

239 lines
7.9 KiB
Python

"""Skill pack renderer + installer.
Pure functions — no LLM calls, no network, no global state. The
renderer reads the single source-of-truth `template.md`, substitutes
a small set of placeholders based on the target's primary mode, and
returns the rendered markdown as a string. The installer writes the
result to the target's default destination (or an override) with
version-aware refusal to overwrite.
Template syntax:
{{display_name}}
→ replaced with the target's display_name ("Claude Code" or "Codex")
{{primary_mode}}
→ replaced with "mcp" or "cli"
{{mcp:some text}}{{cli:other text}}
→ paired blocks. For target primary_mode="mcp" the whole pair
becomes "some text"; for primary_mode="cli" it becomes
"other text". Either block may be empty. Both blocks must
appear together — an unmatched block raises ValueError at
render time so typos in the template fail loudly in tests.
The version is stored in frontmatter as:
---
smriti_skill_pack_version: 1.0
...
---
The installer reads the existing destination's frontmatter (if any),
compares versions as strings (lexicographic — "1.0" < "1.1" < "1.10"
works for the foreseeable skill pack version series), and refuses to
overwrite a destination whose version is >= the template's version
unless `force=True` is passed.
"""
from __future__ import annotations
import re
from dataclasses import dataclass
from pathlib import Path
from typing import Literal, Optional
from .targets import SkillTarget, get_target
_TEMPLATE_PATH = Path(__file__).parent / "template.md"
_VERSION_RE = re.compile(
r"^smriti_skill_pack_version:\s*([^\n]+)$",
re.MULTILINE,
)
# Matches a paired {{mcp:...}}{{cli:...}} block. The `?` suffix on the
# inner `.` quantifiers makes them non-greedy so multiple pairs on the
# same line (or line-wrapped pairs) do not collapse into one giant
# match. Empty bodies are allowed.
_PAIRED_BLOCK_RE = re.compile(
r"\{\{mcp:(.*?)\}\}\{\{cli:(.*?)\}\}",
re.DOTALL,
)
# Matches any leftover unpaired block — if this matches after
# _PAIRED_BLOCK_RE has been applied, the template has a typo.
_UNPAIRED_BLOCK_RE = re.compile(
r"\{\{(?:mcp|cli):[^}]*\}\}",
re.DOTALL,
)
Action = Literal["created", "overwritten", "dry_run", "skipped"]
@dataclass
class InstallResult:
"""Result of a skill pack install attempt.
- action: what happened. "skipped" means the destination already
had a same-or-newer version and `force` was not set; nothing was
written.
- previous_version: the version read from the destination before
the install attempt, or None if the destination did not exist
or had no version frontmatter.
- content: the rendered content that was (or would have been)
written. Useful for `--dry-run` and for the MCP tool which
returns the content without writing.
"""
target: SkillTarget
destination: Path
action: Action
version: str
previous_version: Optional[str]
content: str
def load_template() -> str:
"""Read the raw template.md from the installed package."""
return _TEMPLATE_PATH.read_text(encoding="utf-8")
def get_version(content: Optional[str] = None) -> str:
"""Return the `smriti_skill_pack_version` value from the template
frontmatter. Raises ValueError if the frontmatter is missing so
missing-version bugs fail loudly during development rather than
installing an unversioned skill pack.
"""
text = content if content is not None else load_template()
m = _VERSION_RE.search(text)
if not m:
raise ValueError(
"Skill pack template is missing `smriti_skill_pack_version` "
"frontmatter. Every template.md must start with a YAML "
"frontmatter block that pins the version."
)
return m.group(1).strip()
def render(target_key: str) -> str:
"""Render the template for a specific target.
The same template.md renders for every target; placeholders and
`{{mcp:...}}{{cli:...}}` blocks control the primary-mode-specific
variations. The content (workflow heuristics, anti-patterns,
when-not-to-checkpoint rules) is identical across targets — only
the tool notation and display name differ.
"""
target = get_target(target_key)
template = load_template()
return _substitute_placeholders(template, target)
def _substitute_placeholders(template: str, target: SkillTarget) -> str:
"""Apply the template substitutions for a target. Pure function.
Steps:
1. Replace every {{mcp:X}}{{cli:Y}} paired block with X or Y
depending on target.primary_mode.
2. Replace {{display_name}} → target.display_name.
3. Replace {{primary_mode}} → target.primary_mode.
4. Assert no unmatched paired blocks remain — if any do, the
template has a typo and the renderer fails loudly with the
location context.
"""
def pick(match: re.Match[str]) -> str:
mcp_body, cli_body = match.group(1), match.group(2)
return mcp_body if target.primary_mode == "mcp" else cli_body
out = _PAIRED_BLOCK_RE.sub(pick, template)
out = out.replace("{{display_name}}", target.display_name)
out = out.replace("{{primary_mode}}", target.primary_mode)
leftover = _UNPAIRED_BLOCK_RE.search(out)
if leftover:
# Provide a snippet of context so the error is actionable.
start = max(0, leftover.start() - 30)
end = min(len(out), leftover.end() + 30)
raise ValueError(
f"Skill pack template contains an unmatched "
f"{{mcp:...}}/{{cli:...}} block. Matched fragment: "
f"{leftover.group(0)!r}. Context: ...{out[start:end]!r}..."
)
return out
def install(
target_key: str,
destination: Optional[Path] = None,
*,
force: bool = False,
dry_run: bool = False,
) -> InstallResult:
"""Install the rendered skill pack for a target.
Args:
target_key: "claude-code" or "codex".
destination: Override the target's default destination path.
When None, uses `target.default_destination` relative to
the current working directory.
force: Overwrite an existing same-or-newer version. Default
False: refuse and return `action="skipped"`.
dry_run: Render the content and return it, but do not write
to disk. Default False.
Returns:
InstallResult describing what happened.
"""
target = get_target(target_key)
dest = Path(destination) if destination is not None else target.default_destination
content = render(target_key)
current_version = get_version(content)
previous_version: Optional[str] = None
if dest.exists():
try:
existing = dest.read_text(encoding="utf-8")
except (OSError, UnicodeDecodeError):
existing = ""
m = _VERSION_RE.search(existing)
if m:
previous_version = m.group(1).strip()
if (
previous_version is not None
and not force
and previous_version >= current_version
):
return InstallResult(
target=target,
destination=dest,
action="skipped",
version=current_version,
previous_version=previous_version,
content=content,
)
if dry_run:
return InstallResult(
target=target,
destination=dest,
action="dry_run",
version=current_version,
previous_version=previous_version,
content=content,
)
dest.parent.mkdir(parents=True, exist_ok=True)
dest.write_text(content, encoding="utf-8")
return InstallResult(
target=target,
destination=dest,
action="overwritten" if previous_version else "created",
version=current_version,
previous_version=previous_version,
content=content,
)