* fix: devendor tree-sitter-proto install lifecycle to fix ENOTEMPTY on global upgrade
PR #843's preinstall cleanup hook cannot address the reported bug because
it runs on the NEW package's staging tree, not the OLD install being
removed. Issue #836 still reproduces on 1.6.2-rc.8.
Root cause: vendor/tree-sitter-proto was declared as `file:` dep with its
own `dependencies` and `install` script, so npm created
`vendor/tree-sitter-proto/node_modules/node-addon-api/` at install time,
which blocked npm's rmdir on global upgrade.
Changes:
- Strip `dependencies` and `install` script from the vendored sub-package's
package.json so npm no longer creates a nested node_modules or runs a
lifecycle script under vendor/.
- Hoist `node-addon-api` and `node-gyp-build` into gitnexus
optionalDependencies; npm resolves them at the consumer's top level.
- Add scripts/build-tree-sitter-proto.cjs modeled on patch-tree-sitter-swift.cjs.
Runs at gitnexus postinstall, best-effort: skips cleanly on missing
toolchain or --ignore-scripts so non-proto functionality keeps working.
- Remove scripts/preinstall-cleanup.cjs — dead code; cannot run against
the old install being removed.
- Keep .npmignore entries from PR #843 (tarball hygiene, still correct).
- Add explicit .gitignore rules for gitnexus/vendor/**/build and
gitnexus/vendor/**/node_modules (closes the repo-side hygiene gap).
- Add .github/workflows/ci-global-upgrade.yml: matrix smoke test that
installs the previously-published rc globally, upgrades to the packed
current branch, and verifies no vendor install-time artifacts survive.
Runs on macOS (reporter's platform), Linux, and Windows. Also includes
an --ignore-scripts degraded-mode lane. Wired into ci.yml gate.
Plan: docs/plans/2026-04-15-002-fix-tree-sitter-proto-vendor-deps-plan.md
Phase 1 (this commit) addresses the reported `node_modules/node-addon-api`
hazard. Phase 2 (follow-up) will migrate to prebuildify + prebuilt .node
binaries in the tarball — the 2026 canonical shape for tree-sitter
grammars, which eliminates the postinstall compile path entirely.
Refs #836
* fix(ci): ci-global-upgrade should be reusable-only and use setup-gitnexus
Three issues caught by CI on PR #846:
1. Concurrency linter rejected the `CIGU-` prefix (allowlist is
`${{ github.workflow }}` or substring `CI-`). The literal-prefix
guidance in ci.yml is specifically about disambiguating when
reusable workflows run in nested contexts, and ci-global-upgrade
doesn't need its own concurrency block at all — the caller
(ci.yml) already governs concurrency for nested invocations.
2. `npm install` in gitnexus/ runs `prepare: node scripts/build.js`,
which depends on gitnexus-shared/dist being built first. Other CI
jobs handle this via the setup-gitnexus composite action. Use it
here too (with build: 'false' — we only need the dep graph, then
npm pack runs prepack which builds gitnexus itself).
3. Removed `pull_request` and `workflow_dispatch` triggers. The
workflow is now pure `workflow_call` — invoked once from ci.yml
via `uses:`. This avoids the duplicate-run problem where both the
top-level pull_request trigger AND the nested workflow_call would
fire on every PR.
* fix(ci): relax vendor build/ guard and use bash shell on Windows
Two fixes for ci-global-upgrade failures on PR #846:
1. The guard after the upgrade step was rejecting vendor/tree-sitter-proto/build/
in the global install. That was too strict. The original #836 bug was
about vendor/tree-sitter-proto/node_modules/ specifically, not build/.
The build/ directory appears because node-gyp-build compiles through the
symlink npm creates at node_modules/gitnexus/node_modules/tree-sitter-proto,
and its contents are plain .node, .obj, .lib files that rmdir handles
without trouble. We know this empirically because the test got past the
upgrade step in the run where the old vendor/node_modules was present.
The guard now only flags nested node_modules, which is what the fix
actually removes.
2. The Windows --ignore-scripts lane failed with ENOENT when npm tried to
open the tarball. The path was computed in a bash step using $(pwd),
which on Windows returns /d/a/... form, but npm install ran in the
default cmd shell and received a mangled Windows path. Adding
shell: bash to the install steps keeps path handling consistent.