diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ef4721095..1d3e1b229b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **BREAKING:** after consumers re-vendor the shared gh-aw `apm.md`, its import requires an explicit `target` instead of deprecated `all`; `apm-action` otherwise writes `all` into the isolated `apm.yml`, where it degrades to auto-detection without harness markers. Set the workflow engine's target and recompile; see the [gh-aw migration recipe](https://microsoft.github.io/apm/integrations/gh-aw/#shared-apmmd-import-recommended). (#2706) - Re-vendored shared gh-aw workflows now default to APM 0.28.0 for both pack and restore, the version used for the recorded `microsoft/apm-action@v1.10.0` compatibility proof, not the latest CLI release; an explicit `apm-version` still overrides it. (#2706) +### Fixed + +- User-scope hook commands now anchor to `$HOME` on POSIX hosts instead of the installing host's home prefix, so a `~/.claude/settings.json` kept in a dotfiles repo stops churning between machines; Windows targets, single-quoted references, and dynamic config roots outside the home directory keep absolute paths. (closes #2821) (#2944) + ### Security - The shared gh-aw APM pack job now declares `contents: read` (previously `permissions: {}`), the minimum the explicit built-in-token path needs. No write scope is added, and the token is not forwarded to restore or agent jobs. (#2706) diff --git a/docs/src/content/docs/producer/author-primitives/hooks-and-commands.md b/docs/src/content/docs/producer/author-primitives/hooks-and-commands.md index 3d9a758d24..5e4dd3b1de 100644 --- a/docs/src/content/docs/producer/author-primitives/hooks-and-commands.md +++ b/docs/src/content/docs/producer/author-primitives/hooks-and-commands.md @@ -285,9 +285,19 @@ agent a procedure" fits a skill -- and reaches every harness. alias) for scripts that ship inside the package, using the quoting forms described above. Plain absolute paths break on consumers' machines. - **Hook script path resolution.** `apm install -g` (user-scope) - rewrites `${PLUGIN_ROOT}` and relative `./` references to absolute - paths so Claude Code and Copilot CLI can execute scripts regardless - of the working directory. Project-scope `apm install` (no `-g`) keeps + rewrites `${PLUGIN_ROOT}` and relative `./` references so Claude Code + and Copilot CLI can execute scripts regardless of the working + directory. On POSIX hosts the rewritten path is anchored to `$HOME` + (for example `$HOME/.claude/hooks//run.sh`), which the shell + expands at invocation time, so a user-scope config kept in a dotfiles + repo stays valid on a host with a different home directory. Because the + anchor resolves late, the hook runs the script under whatever `HOME` the + launching shell provides -- keep `HOME` pointing at the installing user's + home when a wrapper script, service, or CI job invokes the harness. + Windows keeps the absolute form, and so do single-quoted references (a + shell does not expand `$HOME` inside single quotes) and a dynamic target + root outside the home directory (for example `CLAUDE_CONFIG_DIR`). + Project-scope `apm install` (no `-g`) keeps non-Claude command paths repo-relative. Claude project hooks use `CLAUDE_PROJECT_DIR` (or `$env:CLAUDE_PROJECT_DIR` for PowerShell) so checked-in settings remain portable while hooks can run from outside the diff --git a/docs/src/content/docs/reference/targets-matrix.md b/docs/src/content/docs/reference/targets-matrix.md index ccc077370b..39e51c0995 100644 --- a/docs/src/content/docs/reference/targets-matrix.md +++ b/docs/src/content/docs/reference/targets-matrix.md @@ -126,8 +126,9 @@ GitHub Copilot (CLI and IDE). `instructions` from all packages are concatenated into `~/.copilot/copilot-instructions.md` (Copilot CLI reads only that single file at user scope). User-scope deploys land under `~/.copilot/`, not - `~/.github/`; hook script commands are written as absolute paths so Copilot - CLI can invoke them from any working directory. + `~/.github/`; hook script commands are anchored so Copilot CLI can invoke + them from any working directory -- `$HOME`-relative on POSIX hosts, absolute + on Windows and for single-quoted references. - **Global compile.** `apm compile -g` can also render global instructions to `~/.copilot/AGENTS.md` for root-context readers that honor `AGENTS.md`. diff --git a/packages/apm-guide/.apm/skills/apm-usage/package-authoring.md b/packages/apm-guide/.apm/skills/apm-usage/package-authoring.md index 3a4fa46d4f..fb7fb17d7e 100644 --- a/packages/apm-guide/.apm/skills/apm-usage/package-authoring.md +++ b/packages/apm-guide/.apm/skills/apm-usage/package-authoring.md @@ -219,8 +219,13 @@ merged target keeps APM reconciliation ownership in a sibling `apm-hooks.json` sidecar, so clones, contributors, and CI runners do not see the installer's machine-local absolute prefix. `apm install -g` (user-scope, e.g. `~/.claude/settings.json`) rewrites `${PLUGIN_ROOT}` and relative `./` -references to absolute paths because the user-scope config is read -without a fixed cwd. If a manifest in `hooks/` or `.apm/hooks/` uses +references so the user-scope config resolves without a fixed cwd: on POSIX +hosts the rewritten path is anchored to `$HOME` (for example +`$HOME/.claude/hooks//run.sh`), which the invoking shell expands, so the +merged file stays identical across machines. Windows keeps the absolute form, +and so do single-quoted references (a shell does not expand `$HOME` inside +single quotes) and dynamic target roots outside the home directory such as +`CLAUDE_CONFIG_DIR`. If a manifest in `hooks/` or `.apm/hooks/` uses `./hooks/