Skip to content

fix: warn when instruction is missing required fields during apm compile#449

Open
alopezsanchez wants to merge 1 commit intomicrosoft:mainfrom
alopezsanchez:fix/warn-missing-applyto-on-compile
Open

fix: warn when instruction is missing required fields during apm compile#449
alopezsanchez wants to merge 1 commit intomicrosoft:mainfrom
alopezsanchez:fix/warn-missing-applyto-on-compile

Conversation

@alopezsanchez
Copy link
Contributor

@alopezsanchez alopezsanchez commented Mar 25, 2026

Description

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

Type of change

  • Bug fix
  • New feature
  • Documentation
  • Maintenance / refactor

Testing

  • Tested locally
  • All existing tests pass
  • Added tests for new functionality (if applicable)

…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
Copilot AI review requested due to automatic review settings March 25, 2026 16:58

# Common error handling for both compilation modes
# Note: Warnings are handled by professional formatters for distributed mode
if config.strategy != "distributed" or single_agents:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 applyTo is 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.

"""
from .distributed_compiler import DistributedAgentsCompiler

self.validate_primitives(primitives)
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

validate_primitives() is documented to return validation errors, and the single-file path captures/propagates those return values into self.errors. In _compile_distributed() / _compile_claude_md() the return value is ignored, so any future (or existing) validation logic that returns errors would be silently dropped for these modes. Capture the returned list and extend self.errors (matching _compile_single_file()), or alternatively update validate_primitives() to have a warning-only contract and return type to avoid API inconsistency.

Suggested change
self.validate_primitives(primitives)
validation_errors = self.validate_primitives(primitives)
self.errors.extend(validation_errors)

Copilot uses AI. Check for mistakes.
Returns:
CompilationResult: Result of the CLAUDE.md compilation.
"""
self.validate_primitives(primitives)
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

validate_primitives() is documented to return validation errors, and the single-file path captures/propagates those return values into self.errors. In _compile_distributed() / _compile_claude_md() the return value is ignored, so any future (or existing) validation logic that returns errors would be silently dropped for these modes. Capture the returned list and extend self.errors (matching _compile_single_file()), or alternatively update validate_primitives() to have a warning-only contract and return type to avoid API inconsistency.

Suggested change
self.validate_primitives(primitives)
self.errors.extend(self.validate_primitives(primitives))

Copilot uses AI. Check for mistakes.

compiler = AgentsCompiler(str(self.temp_path))
config = CompilationConfig(
dry_run=True, resolve_links=False, strategy="distributed"
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is named/scoped to “distributed compile”, but CompilationConfig defaults target="all" (per the provided context), so compiler.compile() will also run the CLAUDE.md compilation path and merge results. That makes the test less isolated and can mask which target actually produced the warning. Set target="vscode"/"agents" explicitly so the test exercises only the distributed AGENTS.md path.

Suggested change
dry_run=True, resolve_links=False, strategy="distributed"
dry_run=True,
resolve_links=False,
strategy="distributed",
target="agents",

Copilot uses AI. Check for mistakes.
Comment on lines +883 to +888
original_dir = os.getcwd()
try:
os.chdir(project_with_bad_instruction)
result = runner.invoke(
cli, ["compile", "--target", "vscode", "--dry-run"]
)
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines +880 to +909
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)
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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}"
)

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants