[0.26.1] - 2026-06-05
Theme: GitFlow + non-Python UX patch. Four bug fixes from continued fabricOS dogfood — all paths where codeindex silently no-op'd or warned about state that wasn't real. No contract changes.
Fixed
codeindex hooks install post-commitnow warns when.codeindex.yamldisables the hook (GH #87):codeindex initships the yaml withhooks.post_commit.enabled: falseby default, so the installed.git/hooks/post-commitwrapper would check the flag at runtime and silently no-op. The install command printed ✓, the user committed code, andREADME_AI.mdnever updated — classic "installed but not working" trap. New_maybe_warn_post_commit_disabledhelper reads the yaml after install; whenpost_commit.enabledis false (or absent), prints an actionable reminder with the exact yaml snippet to flip. No behavior change to the install itself — patch-safe. (The doubly-opt-in default itself is a separate contract question deliberately deferred from this patch; the reminder is enough to unblock the first-time path.)codeindex initno longer false-flags installed TS/JS parsers as missing + install hint matches the documented pipx path (GH #86):init_wizard.PARSER_PACKAGESenumerated only python/php/java even though scanner gained TS/JS parsers (#73) and the parser modules exist undersrc/codeindex/parsers/{typescript,javascript}/. Result on a TS-only project:init --yesprintedWarning: Missing parsers for: javascript, typescriptdespitepipx inject ai-codeindex tree-sitter-{typescript,javascript}confirming the packages were already installed. Worse, the hint saidInstall with: pip install ai-codeindex[...]— contradicts the entire documented install path (pipx install ai-codeindexeverywhere else in CLAUDE.md, README, hooks/index SKILL) and doesn't even work cleanly for a pipx-managed env. Fix: extendPARSER_PACKAGESto include typescript/javascript; change the install hint topipx inject ai-codeindex tree-sitter-<lang> [tree-sitter-<lang2>...](matches the rest of the doc surface). New structural testtest_parser_package_map_covers_scanner_supported_setlocks the invariant — adding a language to scanner.py without exposing it viaPARSER_PACKAGESwill fail the test, preventing the GH #86 drift class from recurring (same pattern as the #73 structural guard).scan-all --aino longer caches AI refusal text asenrichment: ok(GH #85): when the configured AI backend declined to answer for a directory (e.g. haiku returning "I don't see any file names or symbol names provided…"), Phase 2 wrote the refusal verbatim into the directory'sREADME_AI.mdblockquote AND stamped<!-- enrichment: ok -->. Subsequentscan-all --airuns saw theokmarker, skipped re-enrichment, and the garbage description stuck in the cache forever. Newenricher.looks_like_refusal(text)helper detects common refusal prefixes (case-insensitive:I don't,I cannot,I'm unable,no file,insufficient context,as an AI, etc.); when matched, the directory is markedfailed (reason: ai-refused)so the next run retries automatically (idempotent re-enrichment policy already in place). Refusal-pattern detection happens on the cleaned/truncated AI output (~80 chars) — refusal phrasing always lives in the first ~30 chars so truncation doesn't blind the check.- Post-commit hook now fires on merge commits (GH #84): the shell wrapper's loop guard used
git diff-tree --no-commit-id --name-only -r HEAD, which returns empty on merge commits by default —-mis required to enumerate per-parent changes. Empty →NON_DOC_FILESempty → wrapper exits 0 without delegating tocodeindex hooks run post-commit. Net effect on GitFlow projects:README_AI.mdfiles never auto-updated on PR merges (the commits that actually bring new code tomain/develop). Reported live on fabricOS HEAD171702b(Merge PR #7). Fix: add-mto the diff-tree command. Verified against a real merge commit in this repo (e240ba0— Merge develop for 0.26.0 release): old logic saw 0 files, new logic sees the 20 files actually changed. New regression test intests/test_cli_hooks.py::TestHookGeneration::test_post_commit_loop_guard_handles_merge_commitslocks both directions (rejects the broken pattern, requires either-morgit show --name-only).