fix(qmd): pin Homebrew node@24 for build and status on macOS

`qmd status` aborted with ERR_DLOPEN_FAILED — better-sqlite3 was compiled
against NODE_MODULE_VERSION 137 (node@24) but the validate-status task ran
under nvm's Node 20 (NODE_MODULE_VERSION 115), because the user's PATH puts
nvm node ahead of Homebrew and the task pinned no PATH.

Pin `/opt/homebrew/bin` (node@24) ahead of nvm on Darwin for the npm
install, npm build, and validate-status tasks so the native module is
built and loaded against one consistent Node ABI — the same node@24 the
launchd plist already uses. Linux PATH is left unchanged via an
ansible_os_family conditional.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Haitao Pan 2026-06-22 12:43:05 +08:00
parent d9033960fd
commit 6091b9dbcf

View File

@ -126,6 +126,13 @@
ansible.builtin.command:
cmd: npm install
chdir: "{{ qmd_source_dir }}"
# Pin Homebrew node@24 ahead of any nvm/other node on Darwin so the native
# better-sqlite3 module is compiled against the same Node ABI that the
# launchd service and `qmd status` run with. Otherwise a host with nvm node
# first builds the module for the wrong NODE_MODULE_VERSION and qmd aborts
# with ERR_DLOPEN_FAILED. Linux PATH is left untouched.
environment:
PATH: "{{ '/opt/homebrew/bin:/usr/local/bin:' if ansible_os_family == 'Darwin' else '' }}{{ ansible_env.PATH }}"
become: true
become_user: "{{ qmd_user }}"
when:
@ -136,6 +143,8 @@
ansible.builtin.command:
cmd: npm run build
chdir: "{{ qmd_source_dir }}"
environment:
PATH: "{{ '/opt/homebrew/bin:/usr/local/bin:' if ansible_os_family == 'Darwin' else '' }}{{ ansible_env.PATH }}"
become: true
become_user: "{{ qmd_user }}"
when:
@ -296,7 +305,11 @@
- name: Validate QMD status
ansible.builtin.command:
cmd: "{{ qmd_binary_path }} status"
# qmd's /bin/sh wrapper invokes `node`; on Darwin pin Homebrew node@24 first
# so it matches the ABI better-sqlite3 was built with (see npm tasks above),
# instead of falling through to an nvm node and failing ERR_DLOPEN_FAILED.
environment:
PATH: "{{ '/opt/homebrew/bin:/usr/local/bin:' if ansible_os_family == 'Darwin' else '' }}{{ ansible_env.PATH }}"
HOME: "{{ qmd_home }}"
QMD_EMBED_API_BASE_URL: "{{ qmd_embed_api_base_url }}"
QMD_EMBED_MODEL: "{{ qmd_embed_model }}"