Skip to content

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
mainfrom
sergio-sisternes-epam-fix-gemini-instructions-local-package
Open

fix(install): emit "apm compile" hint for project-scope Gemini/agents/claude installs (#2057)#2115
sergio-sisternes-epam wants to merge 2 commits into
mainfrom
sergio-sisternes-epam-fix-gemini-instructions-local-package

Conversation

@sergio-sisternes-epam

Copy link
Copy Markdown
Collaborator

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 run
apm compile — so GEMINI.md never received the installed instructions. This PR adds a
post-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 compile always 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 remains
    a thin @./AGENTS.md stub; AGENTS.md is never updated. The user's dep instructions sit
    silently in apm_modules/_local/<name>/.apm/instructions/ until they discover apm compile
    independently. 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() for InstallScope.USER
    (added in feat(compile): explicit apm compile -g + install-time hint for global root context #1632, c4aa1c58), but the
    InstallScope.PROJECT branch had no equivalent. The routing was:
    if USER: hint; # else: nothing.
  • [!] Copilot/cursor/kiro deploy instructions to per-file rules directories during apm install
    (no compile step needed). Gemini/agents/claude are compile-only by design: the targets.py
    TargetProfile 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)

# Fix
1 Add _has_dep_instruction_files(ctx) — lightweight rglob scan of apm_modules/ for *.instructions.md under .apm/instructions/ subtrees.
2 Add _hint_project_compile_needed(ctx) — fires when a compile-only family target (gemini, agents, claude) is active AND dep instruction files exist in apm_modules/; emits one info line pointing at apm compile.
3 Update 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_files scans ctx.apm_modules_dir (or project_root/apm_modules) via rglob with a path-parts guard. _hint_project_compile_needed reuses the existing _ROOT_CONTEXT_ONLY_FAMILIES and _ROOT_CONTEXT_HINT_EXCLUDED_TARGETS constants; guards on dry_run, installed_count, and for_scope(user_scope=False). run() routing updated from a bare if USER to if USER / elif PROJECT.

  • tests/unit/install/phases/test_finalize_user_compile.py — Module docstring and test_project_scope_no_hint updated to reflect the new routing. 11 new tests added in TestHintProjectCompileNeeded: fire condition (gemini + instructions), six no-fire conditions (copilot, no files, dry-run, zero-count, excluded target name), and a run()-level routing assertion.

  • tests/unit/install/test_finalize_phase.py_FakeCtx dataclass gained dry_run: bool = False, targets: list = [], and apm_modules_dir: Any = None so existing run() tests continue to pass when _hint_project_compile_needed is 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;
Loading

Trade-offs

  • Hint-only, no auto-compile. Chose hint; rejected auto-triggering apm compile because
    compilation 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 PROJECT not bare else. None-scope contexts are transitional / test-only; silently
    hinting there would produce noise in edge cases without confirmed user benefit.
  • Filesystem scan at end of install. The rglob is bounded to apm_modules/ and returns on the
    first match, keeping it O(1) for the common case. No discovery package is imported; imports stay lazy.

Benefits

  1. Users who install a local Gemini/agents/claude package immediately see
    [i] Instructions installed for Gemini CLI. Run 'apm compile' to update AGENTS.md / GEMINI.md.
    — no silent success, no manual discovery of apm compile required.
  2. Zero behavior change for existing user-scope installs, copilot/cursor/kiro
    project installs, and dry-run installs.
  3. 1,777 unit tests pass; full lint mirror (ruff + pylint R0801 + auth-signal check) is green.

Validation

Lint mirror (all green)
$ uv run --extra dev ruff check src/ tests/ && uv run --extra dev ruff format --check src/ tests/ \
  && uv run --extra dev python -m pylint --disable=all --enable=R0801 \
     --min-similarity-lines=10 --fail-on=R0801 src/apm_cli/ \
  && bash scripts/lint-auth-signals.sh

All checks passed!
1417 files already formatted

Your code has been rated at 10.00/10 (previous run: 10.00/10, +0.00)

[+] auth-signal lint clean
Unit tests — 1,777 passed
$ uv run --extra dev pytest tests/unit/install/ -q
1777 passed in 18.59s

New hint tests specifically:

$ uv run --extra dev pytest tests/unit/install/phases/test_finalize_user_compile.py \
    tests/unit/install/test_finalize_phase.py -q
41 passed in 0.30s
Smoke test — hint fires on install
[i] Instructions installed for gemini. Run 'apm compile' to update AGENTS.md / GEMINI.md.
[*] Installed 1 APM dependency in 0.1s.

compile hint shown: True

Scenario Evidence

# Scenario (user promise) Principle(s) Test(s) proving it Type
1 After apm install <gemini-pkg>, user immediately sees a "Run 'apm compile'" hint — no silent success DevX tests/unit/install/phases/test_finalize_user_compile.py::TestHintProjectCompileNeeded::test_hint_fires_for_compile_only_target_with_instruction_files
test_run_calls_project_hint_for_project_scope (regression-trap for #2057)
unit
2 Copilot/cursor/kiro project installs do NOT show the hint (no spurious guidance for targets that deploy instructions natively) DevX, Multi-harness support test_hint_not_fired_for_copilot_target
test_hint_not_fired_for_excluded_target_name
unit
3 Dry-run and no-op (installed_count == 0) installs remain silent DevX, Governed by policy test_hint_not_fired_on_dry_run
test_hint_not_fired_when_nothing_installed
unit
4 User-scope installs still see their existing apm compile -g hint (no regression) DevX tests/unit/install/phases/test_finalize_user_compile.py::TestFinalizeRunIntegration::test_user_scope_hint_called unit

How to test

  • In a temp dir, create a Gemini-target local package with a .apm/instructions/rules.instructions.md. Run apm install ./package and confirm the output contains Run 'apm compile'.
  • Run apm compile in the same dir and confirm AGENTS.md contains the instruction content. GEMINI.md should contain @./AGENTS.md.
  • Repeat with a Copilot-target package; confirm no compile hint appears in the output.
  • Run apm install --dry-run ./package with the Gemini package; confirm no hint.
  • Run 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

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>
Copilot AI review requested due to automatic review settings July 10, 2026 09:48

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.md files under .apm/instructions/, and a new project-scope hint hook that emits a single apm compile reminder.
  • Updated finalize.run() hint routing to call the new project-scope hook for InstallScope.PROJECT while keeping the existing user-scope apm compile -g hint for InstallScope.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.

Comment thread src/apm_cli/install/phases/finalize.py
…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>
@sergio-sisternes-epam sergio-sisternes-epam added the panel-review Trigger the apm-review-panel gh-aw workflow label Jul 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

panel-review Trigger the apm-review-panel gh-aw workflow

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Gemini instructions are not compiled into GEMINI.md when installing a local package

2 participants