Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions src/specify_cli/integrations/cline/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,14 @@ def _rewrite_handoff_references(content: str) -> str:
content,
)

def post_process_content(self, content: str) -> str:
"""Apply Cline-specific transformations to command content."""
def post_process_command_content(self, content: str) -> str:
"""Apply Cline-specific transformations to command content.

Overrides the ``IntegrationBase`` hook of the same name so that
``CommandRegistrar.register_commands()`` (which dispatches to
``post_process_command_content``) applies these transforms to
extension/preset command files too, not just core commands.
"""
updated = self._inject_hook_command_note(content)
updated = self._rewrite_handoff_references(updated)
return updated
Expand Down Expand Up @@ -169,7 +175,7 @@ def setup(
content_bytes = path.read_bytes()
content = content_bytes.decode("utf-8")

updated = self.post_process_content(content)
updated = self.post_process_command_content(content)

if updated != content:
path.write_bytes(updated.encode("utf-8"))
Expand Down
31 changes: 31 additions & 0 deletions tests/test_post_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,3 +243,34 @@ def test_plain_template_unchanged(
assert output_file.exists(), f"Output file missing for {agent}"
content = output_file.read_text(encoding="utf-8")
assert body_text.strip() in content, f"Body text missing in {agent} output"


class TestClineRealPostProcess:
"""Cline's real command-content transforms (hook-command note + handoff
dot->hyphen rewrite) must run for extension/preset commands registered via
CommandRegistrar. This exercises the REAL method (not a monkeypatched
marker), so it fails if Cline's override does not match the base hook name
the registrar dispatches to (post_process_command_content)."""

def test_cline_transforms_applied_via_registrar(
self, tmp_path, registrar, ext_dir
):
ext, cmd_dir = ext_dir
body = (
"- For each executable hook, output the following:\n"
"agent: speckit.foo\n"
)
_write_cmd(cmd_dir, body=body)

commands = [{"name": "speckit.test.review", "file": "commands/review.md"}]
registrar.register_commands("cline", commands, "test-ext", ext, tmp_path)

outputs = list((tmp_path / ".clinerules" / "workflows").rglob("*.md"))
assert outputs, "no cline command file was written"
content = outputs[0].read_text(encoding="utf-8")

# _inject_hook_command_note fired (its note text contains "replace dots")
assert "replace dots" in content
# _rewrite_handoff_references rewrote the dotted agent handoff
assert "agent: speckit-foo" in content
assert "agent: speckit.foo" not in content