* fix(hook): resolve canonical repo root + guard read-only FTS ensure (#1224)
Two bugs in the Claude Code hook + query layer integration:
1. `findGitNexusDir` (in `gitnexus/hooks/claude/gitnexus-hook.cjs` and
`gitnexus-claude-plugin/hooks/gitnexus-hook.js`) walked upward from
cwd looking for a non-registry `.gitnexus/`. In linked git worktrees
created via `git worktree add`, the canonical repo's `.gitnexus/`
never sits above the worktree path, so the walk silently fails and
neither augmentation nor staleness notifications fire.
Fix: keep the cwd-walk as the fast path, then fall back to
`git rev-parse --git-common-dir` to resolve the shared `.git/`
directory (which lives inside the canonical repo across all linked
worktrees) and walk up from its parent. Returns null cleanly when
`git` isn't on PATH or cwd isn't inside any working tree.
2. `ensureFTSIndex` in the LadybugDB adapter rethrew when the active
connection is read-only (e.g. the MCP query pool, which opens DBs
read-only by design). Defensive callers used to surface five
"Cannot execute write operations in a read-only database" warnings
per query.
Fix: extract `isReadOnlyDbError` (mirroring the existing
`isDbBusyError` discriminator) and have `ensureFTSIndex` catch the
read-only error, cache the key, and return silently. Index creation
is owned by `gitnexus analyze` on a writable connection — the
ensure call is safely a no-op on the read pool. Lock / busy /
"already exists" / schema errors continue to propagate.
Tests:
- `test/unit/hooks.test.ts`: new "Linked git worktree resolution"
block exercises both hooks against a real linked worktree to confirm
PostToolUse stale notifications fire, plus a negative case when the
canonical repo has no `.gitnexus/`.
- `test/unit/lbug-readonly-error.test.ts`: new file unit-tests the
`isReadOnlyDbError` discriminator (positive matches, case
insensitivity, non-Error inputs, and unrelated errors that must
still surface — lock contention, "already exists", schema misses).
- `test/integration/lbug-core-adapter.test.ts`: extends the existing
FTS coverage with an idempotency assertion for `ensureFTSIndex` to
pin the read-only guard's success-path contract.
Verified with `npx tsc --noEmit` and `vitest run` on the affected
files (hooks + readonly + lbug-core-adapter + bm25-search +
lbug-extension-loader + lbug-embedding-hashes — 136 tests pass).
Build: `npm run build` succeeds.
Closes#1224
* fix(local-backend): cover supported vector path
Add the supported-platform regression assertion for QUERY_VECTOR_INDEX and align the unsupported VECTOR diagnostic wording with platform policy.
Made-with: Cursor
---------
Co-authored-by: Gergo Magyar <gergomagyar@icloud.com>
* fix(hooks): ignore global registry during staleness checks
* test(hooks): cover indexed repos under global registry
---------
Co-authored-by: laplace young <yangqk12@whu.edu.cn>
* feat: configure prettier with pre-commit hook integration
Add prettier, lint-staged, and prettier-plugin-tailwindcss at the repo
root with husky pre-commit hook integration. Moves husky from
gitnexus/ to root package.json for reliable hook installation.
- Root package.json with prepare/format/format:check scripts
- .prettierrc with endOfLine:lf and tailwindStylesheet for TW v4
- .prettierignore excluding fixtures, vendor, generated, *.d.ts, *.md
- .gitattributes enforcing LF line endings for Windows consistency
- Pre-commit hook uses direct node_modules/.bin/ paths (no npx)
* style: apply prettier formatting to entire codebase
One-time bulk format. No logic changes.
Use .git-blame-ignore-revs to skip this commit in git blame.
* chore: add .git-blame-ignore-revs for prettier format commit
* perf: pre-commit hook runs only tests related to staged files
Use vitest --related to scope test execution to tests that import
the changed files, instead of running the full suite on every commit.
* perf: remove vitest from pre-commit hook, keep in CI only
Pre-commit now runs lint-staged + tsc only. Tests run in CI
(ci-tests.yml) where they belong — keeps commits fast.
* ci: add prettier format check to quality workflow
PRs will now fail if code isn't formatted with prettier.
Adds PostToolUse hook that detects stale GitNexus index after git mutations (commit, merge, rebase, cherry-pick, pull) and notifies the agent to reindex. Uses lightweight staleness check (git rev-parse HEAD vs meta.json) instead of running gitnexus analyze synchronously, avoiding KuzuDB corruption and 120s blocks. Security and cross-platform hardening: remove shell:true from all spawnSync calls, use .cmd extensions on Windows, add path.isAbsolute(cwd) guards, fix setup.ts path escaping with JSON.stringify, use sendHookResponse() consistently. Includes 73 regression tests.
- Hook config goes in ~/.claude/settings.json (not hooks.json)
- Matcher uses string format ("Grep|Glob|Bash") per new Claude Code schema
- Rename gitnexus-hook.js → gitnexus-hook.cjs for CommonJS compatibility
- Fix setup.ts: correct hook filename and timeout (8000ms instead of 10ms)
- Bump to v1.1.9 and publish to npm
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>