fix(install): emit "apm compile" hint for project-scope Gemini/agents/claude installs (#2057)#2115
Open
sergio-sisternes-epam wants to merge 2 commits into
Conversation
After 'apm install <local-gemini-package>' on project scope, AGENTS.md / GEMINI.md never received the installed instructions because the user had no signal that 'apm compile' was required. User-scope installs already had _hint_global_root_context(); project-scope had no equivalent. Changes: - Add _has_dep_instruction_files(ctx) -- lightweight scan of apm_modules/ for *.instructions.md under .apm/instructions/ subtrees. - Add _hint_project_compile_needed(ctx) -- fires on project-scope installs when a compile-only target family (gemini, agents, claude) is active and dep instruction files are present; emits a one-line hint pointing at 'apm compile'. - Wire both into run(): USER -> _hint_global_root_context, PROJECT -> _hint_project_compile_needed, None -> neither. - Extend _FakeCtx in test_finalize_phase.py with dry_run, targets, and apm_modules_dir fields so existing tests continue to pass. - Add 11 new unit tests in TestHintProjectCompileNeeded covering the fire/no-fire conditions, plus a run()-level routing test. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR improves the apm install DevX for project-scope installs targeting compile-only harness families (gemini / agents / claude) by adding a post-install hint to run apm compile when dependency instruction files were installed but won’t be surfaced until compilation.
Changes:
- Added a lightweight scan of
apm_modules/for dependency*.instructions.mdfiles under.apm/instructions/, and a new project-scope hint hook that emits a singleapm compilereminder. - Updated
finalize.run()hint routing to call the new project-scope hook forInstallScope.PROJECTwhile keeping the existing user-scopeapm compile -ghint forInstallScope.USER. - Extended unit tests to cover the new project-scope hint behavior and updated the finalize phase test context stub accordingly.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/apm_cli/install/phases/finalize.py | Adds _has_dep_instruction_files() + _hint_project_compile_needed() and routes PROJECT-scope installs to emit a compile reminder. |
| tests/unit/install/phases/test_finalize_user_compile.py | Adds new tests for the project-scope compile hint and updates run() routing expectations. |
| tests/unit/install/test_finalize_phase.py | Updates the _FakeCtx stub with new fields needed by the updated finalize phase logic. |
…aude family) The previous message named only 'AGENTS.md / GEMINI.md' but the hint also fires for the claude compile family (CLAUDE.md). Using the generic term 'root context files' matches the docstring and covers all three families correctly. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
fix(install): emit "apm compile" hint for project-scope Gemini/agents/claude installs (#2057)
TL;DR
After
apm install <local-gemini-package>on project scope, nothing told the user to runapm compile— so GEMINI.md never received the installed instructions. This PR adds apost-install hint for project-scope compile-only targets (gemini, agents, claude), mirroring
the user-scope hint introduced in #1632. No behavior change for existing flows.
Note
Closes #2057. The compile path itself is not broken —
apm compilealways worked correctly;the gap was purely a missing UX signal after
apm install.Problem (WHY)
apm install <gemini-pkg>on project scope exits 0 with no guidance. GEMINI.md remainsa thin
@./AGENTS.mdstub; AGENTS.md is never updated. The user's dep instructions sitsilently in
apm_modules/_local/<name>/.apm/instructions/until they discoverapm compileindependently. Reported by Windows user on APM 0.24.0 in issue [BUG] Gemini instructions are not compiled into GEMINI.md when installing a local package #2057.
finalize.run()already called_hint_global_root_context()forInstallScope.USER(added in feat(compile): explicit
apm compile -g+ install-time hint for global root context #1632, c4aa1c58), but theInstallScope.PROJECTbranch had no equivalent. The routing was:if USER: hint; # else: nothing.apm install(no compile step needed). Gemini/agents/claude are compile-only by design: the
targets.pyTargetProfile for gemini has no
"instructions"key. This difference is not surfaced to the user.Why these matter: the DevX promise is that APM is "pragmatic as npm" — first-run flows must not silently succeed while leaving configuration incomplete.
Approach (WHAT)
_has_dep_instruction_files(ctx)— lightweightrglobscan ofapm_modules/for*.instructions.mdunder.apm/instructions/subtrees._hint_project_compile_needed(ctx)— fires when a compile-only family target (gemini, agents, claude) is active AND dep instruction files exist inapm_modules/; emits one info line pointing atapm compile.finalize.run()routing:if USER → _hint_global_root_context; elif PROJECT → _hint_project_compile_needed.None-scope installs remain silent (intentional — see Trade-offs).Implementation (HOW)
src/apm_cli/install/phases/finalize.py— Two new functions added before_hint_global_root_context._has_dep_instruction_filesscansctx.apm_modules_dir(orproject_root/apm_modules) viarglobwith a path-parts guard._hint_project_compile_neededreuses the existing_ROOT_CONTEXT_ONLY_FAMILIESand_ROOT_CONTEXT_HINT_EXCLUDED_TARGETSconstants; guards ondry_run,installed_count, andfor_scope(user_scope=False).run()routing updated from a bareif USERtoif USER / elif PROJECT.tests/unit/install/phases/test_finalize_user_compile.py— Module docstring andtest_project_scope_no_hintupdated to reflect the new routing. 11 new tests added inTestHintProjectCompileNeeded: fire condition (gemini + instructions), six no-fire conditions (copilot, no files, dry-run, zero-count, excluded target name), and arun()-level routing assertion.tests/unit/install/test_finalize_phase.py—_FakeCtxdataclass gaineddry_run: bool = False,targets: list = [], andapm_modules_dir: Any = Noneso existingrun()tests continue to pass when_hint_project_compile_neededis now reached for PROJECT-scoped contexts.Diagrams
Legend:
finalize.run()post-install hint routing — dashed borders mark the two new nodes added by this PR.flowchart LR run["finalize.run()"] --> scope{"ctx.scope?"} scope -->|"USER"| global["_hint_global_root_context()"] scope -->|"PROJECT"| project["_hint_project_compile_needed()"] scope -->|"None / other"| noop["(no hint)"] project --> check1{"compile-only target active?"} check1 -->|"No"| noop check1 -->|"Yes"| check2{"dep .instructions.md in apm_modules/?"} check2 -->|"No"| noop check2 -->|"Yes"| emit["emit: Run 'apm compile' hint on logger"] classDef new stroke-dasharray: 5 5; class project,check1,check2,emit new;Trade-offs
apm compilebecausecompilation is a separate, explicit user action — consistent with the user-scope model
from feat(compile): explicit
apm compile -g+ install-time hint for global root context #1632 and the PROSE principle"favor small, chainable primitives."
elif PROJECTnot bareelse.None-scope contexts are transitional / test-only; silentlyhinting there would produce noise in edge cases without confirmed user benefit.
rglobis bounded toapm_modules/and returns on thefirst match, keeping it O(1) for the common case. No discovery package is imported; imports stay lazy.
Benefits
[i] Instructions installed for Gemini CLI. Run 'apm compile' to update AGENTS.md / GEMINI.md.— no silent success, no manual discovery of
apm compilerequired.project installs, and dry-run installs.
Validation
Lint mirror (all green)
Unit tests — 1,777 passed
New hint tests specifically:
Smoke test — hint fires on install
Scenario Evidence
apm install <gemini-pkg>, user immediately sees a "Run 'apm compile'" hint — no silent successtests/unit/install/phases/test_finalize_user_compile.py::TestHintProjectCompileNeeded::test_hint_fires_for_compile_only_target_with_instruction_filestest_run_calls_project_hint_for_project_scope(regression-trap for #2057)test_hint_not_fired_for_copilot_targettest_hint_not_fired_for_excluded_target_nameinstalled_count == 0) installs remain silenttest_hint_not_fired_on_dry_runtest_hint_not_fired_when_nothing_installedapm compile -ghint (no regression)tests/unit/install/phases/test_finalize_user_compile.py::TestFinalizeRunIntegration::test_user_scope_hint_calledHow to test
.apm/instructions/rules.instructions.md. Runapm install ./packageand confirm the output containsRun 'apm compile'.apm compilein the same dir and confirm AGENTS.md contains the instruction content. GEMINI.md should contain@./AGENTS.md.apm install --dry-run ./packagewith the Gemini package; confirm no hint.uv run --extra dev pytest tests/unit/install/phases/test_finalize_user_compile.py -q— expect 20 passed.Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com