mirror of
https://github.com/obra/superpowers
synced 2026-07-24 19:44:29 +00:00
b6613057ae
The 20-test suite still exercised the dead on_session_start/inject_message mechanism (17 failures against the rewritten plugin). Rewritten for the real contract: pre_llm_call registration + first-turn-only context return, register_skill receiving pathlib.Path (the conftest mock now raises on str, mirroring hermes' AttributeError that silently disables a plugin), both install layouts resolving skills, loud failure when skills are missing, tool mapping sourced verbatim from hermes-tools.md, and a bootstrap-size guard against hermes' 10k-char context spill threshold. 19 tests, passing. Install docs collapse into the README section per maintainer direction: docs/README.hermes.md and .hermes-plugin/INSTALL.md are gone; the README carries the two-line install plus the compaction caveat. plugin.yaml version aligned to 6.1.1.
31 lines
929 B
Python
31 lines
929 B
Python
from pathlib import Path
|
|
|
|
import pytest
|
|
from unittest.mock import MagicMock
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_ctx():
|
|
ctx = MagicMock()
|
|
ctx._hooks = {}
|
|
ctx._skills = {}
|
|
|
|
def register_hook(event, fn):
|
|
ctx._hooks[event] = fn
|
|
|
|
def register_skill(name, path):
|
|
# Mimic hermes' real register_skill, which calls path.exists() and
|
|
# therefore breaks on a str (the bug that silently disabled the whole
|
|
# plugin, found 2026-07-23). Keeping that fidelity here means a
|
|
# regression to str paths fails these tests instead of failing
|
|
# silently inside hermes.
|
|
if not isinstance(path, Path):
|
|
raise AttributeError(
|
|
f"register_skill requires a pathlib.Path, got {type(path).__name__}"
|
|
)
|
|
ctx._skills[name] = path
|
|
|
|
ctx.register_hook.side_effect = register_hook
|
|
ctx.register_skill.side_effect = register_skill
|
|
return ctx
|