Deploy instructions to .claude/rules/ for Claude Code#527
Conversation
Agent-Logs-Url: https://github.com/microsoft/apm/sessions/13cf381a-2289-43c1-8769-19ff7c42f188 Co-authored-by: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com>
Add Claude Code as an instruction deployment target. `apm install` now deploys .instructions.md files to .claude/rules/*.md when a .claude/ directory exists, converting applyTo: frontmatter to Claude's native paths: format. Agent-Logs-Url: https://github.com/microsoft/apm/sessions/13cf381a-2289-43c1-8769-19ff7c42f188 Co-authored-by: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com>
.claude/rules/ for Claude Code
There was a problem hiding this comment.
Pull request overview
Adds Claude Code as an apm install instructions deployment target by deploying .instructions.md as Claude rules under .claude/rules/, including a frontmatter conversion from applyTo: to Claude’s paths: format. This aligns instruction deployment behavior across Copilot/Cursor/Claude using the existing target-driven integrator architecture.
Changes:
- Add
instructionsprimitive mapping for the Claude target (.claude/rules/*.md,format_id="claude_rules"). - Implement Claude rules content conversion + integrate/sync wrappers in
InstructionIntegrator, and route managed files via a new bucket alias. - Add tests, documentation updates, and a changelog entry.
Reviewed changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/integration/test_instruction_integrator.py | Adds unit + integration tests for Claude rules conversion, deploy, collisions, and sync behavior. |
| tests/unit/integration/test_data_driven_dispatch.py | Extends bucket parity/alias assertions and verifies .claude/rules/ partition routing. |
| src/apm_cli/integration/targets.py | Registers Claude instructions deployment mapping (rules, .md, claude_rules). |
| src/apm_cli/integration/instruction_integrator.py | Adds claude_rules transform/copy + dispatch, and updates sync legacy pattern selection. |
| src/apm_cli/integration/base_integrator.py | Adds bucket alias instructions_claude -> rules_claude for partition routing. |
| src/apm_cli/commands/install.py | Updates install log label to show rule(s) for claude_rules (and cursor rules). |
| docs/src/content/docs/integrations/ide-tool-integration.md | Documents .claude/rules/*.md as the destination for instructions (rules). |
| CHANGELOG.md | Adds an Unreleased entry describing Claude rules deployment support. |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
@copilot fix the tests - certainly we broke it by accepting the PR review comment (read it) which I judged legit. See if there is more to it than that. |
…estion The accepted PR review changed legacy_pattern from "*.md" to None for Claude rules to avoid deleting user-authored .md files. Update the test to verify the new intentional behavior: legacy fallback preserves files when managed_files is None. Agent-Logs-Url: https://github.com/microsoft/apm/sessions/aa461ca4-e9eb-4adf-bef4-b8118f4780d4 Co-authored-by: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com>
Fixed in 0f6201a. The accepted review suggestion changed |
Introduce TargetProfile.for_scope() and resolve_targets() so scope resolution happens exactly once -- no parameter threading, no caller responsibility. This supersedes PRs #536 and #537 and folds in #527. Scope resolution: - for_scope(user_scope) returns a frozen copy with root_dir resolved and unsupported primitives filtered out - resolve_targets() is the single entry point combining detection, scope resolution, and primitive filtering - Integrators read target.root_dir directly -- always correct - partition_managed_files() uses longest-prefix-match routing, fixing .config/opencode/ multi-level root paths - validate_deploy_path() derives prefixes from resolved targets - Uninstall Phase 2 re-integration uses resolved targets, eliminating wrong-path deployment bug Claude Code instructions (#527): - Deploy .instructions.md to .claude/rules/*.md with applyTo: to paths: frontmatter conversion - Legacy glob disabled for .claude/rules/ to protect user .md files - 22 new tests for conversion, integration, sync, and partition Copilot CLI user-scope fix (#536): - Add instructions to unsupported_user_primitives (per official docs) - Fix resolve_dependencies to use apm_dir at user scope Fixes #530 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Folded into #542 which adds this feature alongside the scope-resolution architecture refactor. All 22 tests and the full implementation are included. Thank you! |
Introduce TargetProfile.for_scope() and resolve_targets() so scope resolution happens exactly once -- no parameter threading, no caller responsibility. This supersedes PRs #536 and #537 and folds in #527. Scope resolution: - for_scope(user_scope) returns a frozen copy with root_dir resolved and unsupported primitives filtered out - resolve_targets() is the single entry point combining detection, scope resolution, and primitive filtering - Integrators read target.root_dir directly -- always correct - partition_managed_files() uses longest-prefix-match routing, fixing .config/opencode/ multi-level root paths - validate_deploy_path() derives prefixes from resolved targets - Uninstall Phase 2 re-integration uses resolved targets, eliminating wrong-path deployment bug Claude Code instructions (#527): - Deploy .instructions.md to .claude/rules/*.md with applyTo: to paths: frontmatter conversion - Legacy glob disabled for .claude/rules/ to protect user .md files - 22 new tests for conversion, integration, sync, and partition Copilot CLI user-scope fix (#536): - Add instructions to unsupported_user_primitives (per official docs) - Fix resolve_dependencies to use apm_dir at user scope Fixes #530 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: scope-resolved target profiles + Claude Code instructions Introduce TargetProfile.for_scope() and resolve_targets() so scope resolution happens exactly once -- no parameter threading, no caller responsibility. This supersedes PRs #536 and #537 and folds in #527. Scope resolution: - for_scope(user_scope) returns a frozen copy with root_dir resolved and unsupported primitives filtered out - resolve_targets() is the single entry point combining detection, scope resolution, and primitive filtering - Integrators read target.root_dir directly -- always correct - partition_managed_files() uses longest-prefix-match routing, fixing .config/opencode/ multi-level root paths - validate_deploy_path() derives prefixes from resolved targets - Uninstall Phase 2 re-integration uses resolved targets, eliminating wrong-path deployment bug Claude Code instructions (#527): - Deploy .instructions.md to .claude/rules/*.md with applyTo: to paths: frontmatter conversion - Legacy glob disabled for .claude/rules/ to protect user .md files - 22 new tests for conversion, integration, sync, and partition Copilot CLI user-scope fix (#536): - Add instructions to unsupported_user_primitives (per official docs) - Fix resolve_dependencies to use apm_dir at user scope Fixes #530 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: address PR review -- trie routing, legacy prefix cleanup, CHANGELOG refs - Replace O(M*P) sorted-prefix scan with O(depth) trie lookup in partition_managed_files (reviewer comment 1) - Use default KNOWN_TARGETS for uninstall partition so legacy deployed_files from buggy user-scope installs are still bucketed and cleaned up (reviewer comment 2) - Remove targets= from orphan validate_deploy_path so legacy .github/ paths from old user-scope installs can be cleaned up (reviewer comment 3) - Fix CHANGELOG PR references to use #542 (reviewer comment 4) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: dynamic skill sync prefixes + uninstall Phase 2 targets Fix #538: pass resolved targets to skill_integrator.integrate_package_skill() in uninstall Phase 2 so user-scope re-integration deploys to .copilot/skills/ not .github/skills/. Add auto_create guard to copy_skill_to_target(). Fix #539: refactor sync_integration() to derive skill prefixes dynamically from targets instead of hardcoded .github/skills/, .claude/skills/, etc. User-scope paths like .copilot/skills/ and .config/opencode/skills/ are now handled correctly. Pass resolved targets from uninstall engine. 9 new tests covering resolved-target routing, auto_create guards, user-scope manifest removal, legacy cleanup, and cross-tool guards. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Initial plan * Initial plan for Claude Code .claude/rules/ instruction deployment Agent-Logs-Url: https://github.com/microsoft/apm/sessions/13cf381a-2289-43c1-8769-19ff7c42f188 Co-authored-by: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com> * Deploy instructions to .claude/rules/ for Claude Code Add Claude Code as an instruction deployment target. `apm install` now deploys .instructions.md files to .claude/rules/*.md when a .claude/ directory exists, converting applyTo: frontmatter to Claude's native paths: format. Agent-Logs-Url: https://github.com/microsoft/apm/sessions/13cf381a-2289-43c1-8769-19ff7c42f188 Co-authored-by: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com> * Update src/apm_cli/integration/instruction_integrator.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Fix test for Claude rules legacy fallback after accepting review suggestion The accepted PR review changed legacy_pattern from "*.md" to None for Claude rules to avoid deleting user-authored .md files. Update the test to verify the new intentional behavior: legacy fallback preserves files when managed_files is None. Agent-Logs-Url: https://github.com/microsoft/apm/sessions/aa461ca4-e9eb-4adf-bef4-b8118f4780d4 Co-authored-by: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* fix: scope-resolved target profiles + Claude Code instructions Introduce TargetProfile.for_scope() and resolve_targets() so scope resolution happens exactly once -- no parameter threading, no caller responsibility. This supersedes PRs #536 and #537 and folds in #527. Scope resolution: - for_scope(user_scope) returns a frozen copy with root_dir resolved and unsupported primitives filtered out - resolve_targets() is the single entry point combining detection, scope resolution, and primitive filtering - Integrators read target.root_dir directly -- always correct - partition_managed_files() uses longest-prefix-match routing, fixing .config/opencode/ multi-level root paths - validate_deploy_path() derives prefixes from resolved targets - Uninstall Phase 2 re-integration uses resolved targets, eliminating wrong-path deployment bug Claude Code instructions (#527): - Deploy .instructions.md to .claude/rules/*.md with applyTo: to paths: frontmatter conversion - Legacy glob disabled for .claude/rules/ to protect user .md files - 22 new tests for conversion, integration, sync, and partition Copilot CLI user-scope fix (#536): - Add instructions to unsupported_user_primitives (per official docs) - Fix resolve_dependencies to use apm_dir at user scope Fixes #530 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: address PR review -- trie routing, legacy prefix cleanup, CHANGELOG refs - Replace O(M*P) sorted-prefix scan with O(depth) trie lookup in partition_managed_files (reviewer comment 1) - Use default KNOWN_TARGETS for uninstall partition so legacy deployed_files from buggy user-scope installs are still bucketed and cleaned up (reviewer comment 2) - Remove targets= from orphan validate_deploy_path so legacy .github/ paths from old user-scope installs can be cleaned up (reviewer comment 3) - Fix CHANGELOG PR references to use #542 (reviewer comment 4) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: dynamic skill sync prefixes + uninstall Phase 2 targets Fix #538: pass resolved targets to skill_integrator.integrate_package_skill() in uninstall Phase 2 so user-scope re-integration deploys to .copilot/skills/ not .github/skills/. Add auto_create guard to copy_skill_to_target(). Fix #539: refactor sync_integration() to derive skill prefixes dynamically from targets instead of hardcoded .github/skills/, .claude/skills/, etc. User-scope paths like .copilot/skills/ and .config/opencode/skills/ are now handled correctly. Pass resolved targets from uninstall engine. 9 new tests covering resolved-target routing, auto_create guards, user-scope manifest removal, legacy cleanup, and cross-tool guards. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Description
apm installdeploys.instructions.mdfiles to.github/instructions/(Copilot) and.cursor/rules/(Cursor) but silently skips.claude/rules/for Claude Code. This adds Claude Code as an instruction deployment target, convertingapplyTo:frontmatter to Claude's nativepaths:format per the Claude Code rules spec.Mapping:
python.instructions.mdwithapplyTo: "**/*.py"deploys as.claude/rules/python.mdwith:Instructions without
applyTo:become unconditional rules (no frontmatter).Changes:
targets.py: Add"instructions"primitive to Claude target —PrimitiveMapping("rules", ".md", "claude_rules")instruction_integrator.py: Add_convert_to_claude_rules()(applyTo:→paths:YAML list),copy_instruction_claude(), legacy wrappers. Generalize filename rename and content-transform dispatch to be format-driven rather than Cursor-specific. Legacy glob fallback is disabled for Claude rules (legacy_pattern = None) to avoid deleting user-authored.mdfiles under.claude/rules/base_integrator.py: Addinstructions_claude→rules_claudebucket alias for partition routinginstall.py: Extend log label to showrule(s)forclaude_rulesformat.claude/rules/*.mdto Claude primitives table inide-tool-integration.mdNo new dependencies. Uninstall/sync works automatically via the existing target-driven API —
sync_for_target()andpartition_managed_files()pick up the new primitive fromKNOWN_TARGETS.Type of change
Testing
22 new tests:
TestConvertToClaudeRules(7 — frontmatter conversion edge cases),TestClaudeRulesIntegration(11 — deploy, rename, collision, managed-file overwrite),TestClaudeRulesSyncIntegration(4 — manifest removal, legacy fallback preservation of user files). Updatedtest_data_driven_dispatch.pywith bucket key parity, alias, and partition routing assertions.