Skip to content

Commit 1294d43

Browse files
committed
fix: replace $ARGUMENTS with {{parameters}} in Forge templates
- Add replacement of $ARGUMENTS to {{parameters}} after template processing - Use arg_placeholder from config (Copilot's cleaner approach) - Remove unused 'import re' from _apply_forge_transformations() - Enhance tests to verify $ARGUMENTS replacement works correctly - All 11 tests pass Fixes template processing to ensure Forge receives user-supplied parameters correctly.
1 parent f5fbfce commit 1294d43

File tree

2 files changed

+31
-7
lines changed

2 files changed

+31
-7
lines changed

src/specify_cli/integrations/forge/__init__.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ def setup(
8282
# Process template with Forge-specific argument placeholder
8383
processed = self.process_template(raw, self.key, script_type, arg_placeholder)
8484

85+
# Ensure any remaining $ARGUMENTS placeholders are converted to the
86+
# Forge argument placeholder ({{parameters}} by default)
87+
processed = processed.replace("$ARGUMENTS", arg_placeholder)
88+
8589
# Apply Forge-specific transformations
8690
processed = self._apply_forge_transformations(processed, src_file.stem)
8791

@@ -102,8 +106,6 @@ def _apply_forge_transformations(self, content: str, template_name: str) -> str:
102106
1. Strip 'handoffs' frontmatter key
103107
2. Inject 'name' field if missing
104108
"""
105-
import re
106-
107109
# Parse frontmatter
108110
lines = content.split('\n')
109111
if not lines or lines[0].strip() != '---':

tests/integrations/test_integration_forge.py

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ def test_templates_are_processed(self, tmp_path):
110110
assert "{SCRIPT}" not in content, f"{cmd_file.name} has unprocessed {{SCRIPT}}"
111111
assert "__AGENT__" not in content, f"{cmd_file.name} has unprocessed __AGENT__"
112112
assert "{ARGS}" not in content, f"{cmd_file.name} has unprocessed {{ARGS}}"
113-
# Note: $ARGUMENTS may appear in template content (examples, instructions)
114-
# The placeholder that gets replaced is {ARGS}, not $ARGUMENTS
113+
# Check Forge-specific: $ARGUMENTS should be replaced with {{parameters}}
114+
assert "$ARGUMENTS" not in content, f"{cmd_file.name} has unprocessed $ARGUMENTS"
115115
# Frontmatter sections should be stripped
116116
assert "\nscripts:\n" not in content
117117
assert "\nagent_scripts:\n" not in content
@@ -134,11 +134,33 @@ def test_forge_specific_transformations(self, tmp_path):
134134
assert "\nhandoffs:" not in content, f"{cmd_file.name} has unstripped 'handoffs' key"
135135

136136
def test_uses_parameters_placeholder(self, tmp_path):
137-
"""Verify Forge config specifies {{parameters}} as the args placeholder."""
137+
"""Verify Forge replaces $ARGUMENTS with {{parameters}} in generated files."""
138138
from specify_cli.integrations.forge import ForgeIntegration
139139
forge = ForgeIntegration()
140+
140141
# The registrar_config should specify {{parameters}}
141142
assert forge.registrar_config["args"] == "{{parameters}}"
142143

143-
# When process_template is called, it should replace {ARGS} with {{parameters}}
144-
# Note: $ARGUMENTS in template content is intentional (examples/instructions)
144+
# Generate files and verify $ARGUMENTS is replaced with {{parameters}}
145+
from specify_cli.integrations.manifest import IntegrationManifest
146+
m = IntegrationManifest("forge", tmp_path)
147+
forge.setup(tmp_path, m)
148+
commands_dir = tmp_path / ".forge" / "commands"
149+
150+
# Check all generated command files
151+
for cmd_file in commands_dir.glob("speckit.*.md"):
152+
content = cmd_file.read_text(encoding="utf-8")
153+
# $ARGUMENTS should be replaced with {{parameters}}
154+
assert "$ARGUMENTS" not in content, (
155+
f"{cmd_file.name} still contains $ARGUMENTS - it should be replaced with {{{{parameters}}}}"
156+
)
157+
# At least some files should have {{parameters}} (those with user input sections)
158+
# We'll check the checklist file specifically as it has a User Input section
159+
160+
# Verify checklist specifically has {{parameters}} in the User Input section
161+
checklist = commands_dir / "speckit.checklist.md"
162+
if checklist.exists():
163+
content = checklist.read_text(encoding="utf-8")
164+
assert "{{parameters}}" in content, (
165+
"checklist should contain {{parameters}} in User Input section"
166+
)

0 commit comments

Comments
 (0)