fix: warn when instruction is missing required fields during apm compile#449
Conversation
…ompile Instructions without applyTo were silently dropped during 'apm compile' in distributed and claude modes because validate_primitives() was only called in the single-file path. This adds validation to all compilation modes and surfaces warnings through the CLI. - Call validate_primitives() in _compile_distributed() and _compile_claude_md() - Merge self.warnings into dry-run and normal compilation results - Remove distributed-mode warning suppression in CLI - Add unit and CLI integration tests for the warning
|
|
||
| # Common error handling for both compilation modes | ||
| # Note: Warnings are handled by professional formatters for distributed mode | ||
| if config.strategy != "distributed" or single_agents: |
There was a problem hiding this comment.
I'm not sure about this line, but it took me some time to realize that I was missing the applyTo field. The apm compile wasn't adding the instruction to the AGENTS/CLAUDE.md, and I didn't know why.
There was a problem hiding this comment.
Pull request overview
Fixes missing validation coverage in apm compile so instructions missing required fields (notably applyTo) are no longer silently dropped in distributed/claude compilation paths, and ensures warnings are surfaced through the CLI.
Changes:
- Run
validate_primitives()in distributed and CLAUDE.md compilation paths. - Merge compiler warnings/errors into compilation results (including dry-run).
- Add unit + CLI integration tests asserting warnings appear when
applyTois missing.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| tests/unit/compilation/test_compile_target_flag.py | Adds CLI-level tests that apm compile emits warnings for missing applyTo in distributed and claude targets. |
| tests/unit/compilation/test_compilation.py | Adds unit tests ensuring validation warnings propagate through distributed + claude compilation results. |
| src/apm_cli/compilation/agents_compiler.py | Invokes validation in more compilation modes and merges self.warnings/self.errors into results. |
| src/apm_cli/commands/compile/cli.py | Always prints warnings regardless of compilation strategy. |
| original_dir = os.getcwd() | ||
| try: | ||
| os.chdir(project_with_bad_instruction) | ||
| result = runner.invoke( | ||
| cli, ["compile", "--target", "vscode", "--dry-run"] | ||
| ) |
There was a problem hiding this comment.
These CLI tests mutate the process working directory, which is easy to get wrong and makes tests harder to compose. Prefer pytest’s monkeypatch.chdir(project_with_bad_instruction) (or CliRunner.isolated_filesystem() plus constructing the project inside it) to keep the cwd change scoped and automatically restored.
| self, runner, project_with_bad_instruction | ||
| ): | ||
| """Test that apm compile --dry-run warns about missing applyTo in distributed mode.""" | ||
| original_dir = os.getcwd() | ||
| try: | ||
| os.chdir(project_with_bad_instruction) | ||
| result = runner.invoke( | ||
| cli, ["compile", "--target", "vscode", "--dry-run"] | ||
| ) | ||
| assert "applyTo" in result.output, ( | ||
| f"Expected warning about missing 'applyTo' in CLI output, got:\n{result.output}" | ||
| ) | ||
| finally: | ||
| os.chdir(original_dir) | ||
|
|
||
| def test_cli_warns_missing_apply_to_claude( | ||
| self, runner, project_with_bad_instruction | ||
| ): | ||
| """Test that apm compile --target claude --dry-run warns about missing applyTo.""" | ||
| original_dir = os.getcwd() | ||
| try: | ||
| os.chdir(project_with_bad_instruction) | ||
| result = runner.invoke( | ||
| cli, ["compile", "--target", "claude", "--dry-run"] | ||
| ) | ||
| assert "applyTo" in result.output, ( | ||
| f"Expected warning about missing 'applyTo' in CLI output, got:\n{result.output}" | ||
| ) | ||
| finally: | ||
| os.chdir(original_dir) |
There was a problem hiding this comment.
These CLI tests mutate the process working directory, which is easy to get wrong and makes tests harder to compose. Prefer pytest’s monkeypatch.chdir(project_with_bad_instruction) (or CliRunner.isolated_filesystem() plus constructing the project inside it) to keep the cwd change scoped and automatically restored.
| self, runner, project_with_bad_instruction | |
| ): | |
| """Test that apm compile --dry-run warns about missing applyTo in distributed mode.""" | |
| original_dir = os.getcwd() | |
| try: | |
| os.chdir(project_with_bad_instruction) | |
| result = runner.invoke( | |
| cli, ["compile", "--target", "vscode", "--dry-run"] | |
| ) | |
| assert "applyTo" in result.output, ( | |
| f"Expected warning about missing 'applyTo' in CLI output, got:\n{result.output}" | |
| ) | |
| finally: | |
| os.chdir(original_dir) | |
| def test_cli_warns_missing_apply_to_claude( | |
| self, runner, project_with_bad_instruction | |
| ): | |
| """Test that apm compile --target claude --dry-run warns about missing applyTo.""" | |
| original_dir = os.getcwd() | |
| try: | |
| os.chdir(project_with_bad_instruction) | |
| result = runner.invoke( | |
| cli, ["compile", "--target", "claude", "--dry-run"] | |
| ) | |
| assert "applyTo" in result.output, ( | |
| f"Expected warning about missing 'applyTo' in CLI output, got:\n{result.output}" | |
| ) | |
| finally: | |
| os.chdir(original_dir) | |
| self, runner, project_with_bad_instruction, monkeypatch | |
| ): | |
| """Test that apm compile --dry-run warns about missing applyTo in distributed mode.""" | |
| monkeypatch.chdir(project_with_bad_instruction) | |
| result = runner.invoke(cli, ["compile", "--target", "vscode", "--dry-run"]) | |
| assert "applyTo" in result.output, ( | |
| f"Expected warning about missing 'applyTo' in CLI output, got:\n{result.output}" | |
| ) | |
| def test_cli_warns_missing_apply_to_claude( | |
| self, runner, project_with_bad_instruction, monkeypatch | |
| ): | |
| """Test that apm compile --target claude --dry-run warns about missing applyTo.""" | |
| monkeypatch.chdir(project_with_bad_instruction) | |
| result = runner.invoke(cli, ["compile", "--target", "claude", "--dry-run"]) | |
| assert "applyTo" in result.output, ( | |
| f"Expected warning about missing 'applyTo' in CLI output, got:\n{result.output}" | |
| ) |
|
@alopezsanchez happy to merge after we address the review comments, thank you very much! Will also need to ensure compatibility with claude's "paths" which is equivalent to "applyTo". |
…pile paths Address Copilot PR review comments: - Capture return value of validate_primitives() and extend self.errors in _compile_distributed() and _compile_claude_md(), matching the pattern already used in _compile_single_file() - Add target='agents' to test config to isolate distributed path testing
…note
Instructions without applyTo are valid -- they apply globally:
- Distributed compile: placed at project root
- Claude deploy: becomes unconditional rule (no paths: key)
- Copilot/Cursor: deployed verbatim
The warning message now reflects this ('will apply globally') instead of
implying applyTo is required. Suggestion updated to explain the choice.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Thanks @alopezsanchez -- the approach of surfacing I pushed one change to your branch: the warning message for missing
to:
Rationale:
The old message implied Also updated the suggestion helper to offer both options: add |
Description
Instructions without
applyTowere silently dropped duringapm compilein distributed and claude modes becausevalidate_primitives()was only called in the single-file path. This adds validation to all compilation modes and surfaces warnings through the CLI.validate_primitives()in_compile_distributed()and_compile_claude_md()self.warningsinto dry-run and normal compilation resultsType of change
Testing