Releases: dreamlx/codeindex
Release v0.26.1
[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).
Release v0.26.0
[0.26.0] - 2026-06-01
Theme: dogfood-driven CLI bug sweep. Five user-reported issues from fabricOS dogfood — mostly UX cliffs in init and list-dirs on non-Python projects, plus a navigation-correctness bug in nav-level README_AI.md. One contract change in init --yes so first scan-all --ai works out of the box.
Changed
codeindex init --yesnow seeds the recommendedai_command(GH #75): the generated.codeindex.yamlincludesai_command: 'claude -p "{prompt}" --model haiku --allowedTools "Read"'so the firstcodeindex scan-all --aiworks without "AI not configured" — the path thecodeindex:indexskill recommends by default. The documented default inDEFAULT_CONFIG_TEMPLATEand the actually-written value now share a single source of truth (config.RECOMMENDED_AI_COMMAND). Contract change vs pre-0.26: AI used to be opt-in at both layers (yaml absent AND--aiflag required); now opt-in lives only at the CLI flag —--aiis still required to spend tokens, but the yaml no longer blocks first-try success. The pre-existing regression testtest_generated_config_no_ai_commandwas renamed totest_generated_config_seeds_recommended_ai_commandand inverted to lock the new contract.
Fixed
codeindex initCLAUDE.md injection drops hardcoded.py / .php / .javaexamples and alternate-backend boilerplate (GH #77, partial): the injected## codeindexsection used to instruct users to "read the actual.py/.php/.java/ etc." — wrong on TS / Swift / Go projects — and listedopencode run/gemini -pas ai_command alternatives in every project's CLAUDE.md regardless of which backend the user actually chose. Template now uses language-neutral wording ("read the source files") and links the backend-swap recipe tocodeindex --helpinstead of inlining all options. Two regression tests (test_build_section_does_not_hardcode_language_extensions,test_build_section_does_not_advertise_alternative_backends) lock these absences. Deferred to a follow-up: zh/en locale detection (#77 also asked for the injection to match the host CLAUDE.md's language; that's a distinct design question — heuristic vs--langflag vs dual templates — and out of this PR's scope).codeindex list-dirsno longer silently returns empty when configuredlanguagesdoesn't match present files (GH #74): previously,list-dirsprinted nothing and exited 0 whenever the language filter excluded everything — indistinguishable from "nothing to index" and the single worst UX class (agents loop through--help/docs/doctor/pipx listdebugging; humans give up). Newscanner.diagnose_language_mismatchhelper walks the include roots, counts actual file extensions, and identifies which codeindex-supported languages would cover them. Whenlist-dirsreturns empty AND files-with-known-extensions are present, it now raises aClickExceptionto stderr with the configuredlanguages, the top file types seen, and the specific languages to add (e.g. "addtypescript / javascriptto.codeindex.yamllanguages:"). Truly empty include roots stay silent + exit 0 — preserving scripts that pipelist-dirsas a "anything to index?" probe.codeindex initnow detects TypeScript / JavaScript projects (GH #73):init_wizard.pycarried a stale localLANGUAGE_EXTENSIONSmap listing only Python / PHP / Java behind a "no parser yet" comment, despitescanner.pyhaving gained TS/JS parsers (and full parser modules existing undersrc/codeindex/parsers/typescript/). On a TS-only repo,detect_languages()returned[]→ nolanguages:block was written → at scan time the runtime defaulted toDEFAULT_LANGUAGES=["python"]→ 0 files matched → silentlist-dirsempty (the user-visible symptom). Fix importsLANGUAGE_EXTENSIONSfromscanner.pyas the single source of truth, so any language the scanner supports is now also detectable by init. Verified end-to-end on a TS fixture (init --yeswriteslanguages: [typescript],list-dirsreturns the include root). A new structural testtest_init_language_set_covers_scanner_supported_setlocks the invariant — adding a language to scanner.py will fail this test until init can also see it, preventing the drift class from recurring.- Navigation-level
README_AI.mdno longer flattens descendant files into## Files(GH #76): nav-level scans are recursive (per the GH #45 stats note), soparse_resultsincludes every descendant.NavigationGeneratorwas iterating them withresult.path.nameonly — dropping the path prefix — so a subdir file likesrc/components/ui/badge.tsxshowed up insrc/README_AI.md's## Filesas barebadge.tsx. Any agent readingsrc/README_AI.mdthen issuingRead src/badge.tsxgot a 404 (or worse: a confident wrong-file Read on a name collision). Fix filtersparse_resultstor.path.parent == dir_pathbefore grouping. Each subdir's files remain available via that subdir's ownREADME_AI.md. Verified on fabricOS:src/README_AI.md ## Filesshrank from 33 flattened entries to the single real direct childmain.tsx. Test helpers_make_result/_create_mock_parse_resultgained an optionalparent_dirkwarg so fixtures pass through the new filter when atmp_pathis the dir under test. - Structural rewrites no longer wipe AI enrichment (GH #38): a
scan-all --airun injects an<!-- enrichment: ok -->marker and a> descriptionblockquote, but any later structural-only write — a post-commit hook runningscan-allwithout--ai, or Phase 1 of the next--airun — used to erase both. The idempotent cache then went cold, so the nextscan-all --aire-paid the full N AI calls instead of restoring from cache.SmartWriter.write_readmenow captures the ok marker + blockquote before overwriting and re-injects them, so the cache stays warm across non-AI invocations. Unenriched READMEs are untouched (no fabricated marker).
Release v0.25.0
[0.25.0] - 2026-05-26
Theme: distribution split — pipx CLI + Claude Code plugin. See release notes + ADR-006.
Changed
codeindex initis now minimal (B1): creates only project-scoped scaffolding —.codeindex.yaml, a codeindex section injected into the project'sCLAUDE.md, and a.gitignoreentry. It no longer createsCODEINDEX.mdor installs git hooks. Hooks are opt-in viacodeindex hooks install; Claude Code users get richerCLAUDE.mdupkeep via the plugin.inithas never touched~/.claude/*and a regression test now locks that invariant.- Recommended install is
pipx install ai-codeindex(B2): the README leads with pipx (isolated CLI env, no dependency conflicts);pip install --useris the fallback. Added a China-mirror footnote (pipx install --index-url https://pypi.org/simple/ ai-codeindex) for when a local mirror lags upstream PyPI.
Added
- Claude Code plugin (dreamlx/codeindex-claude): bundles the four skills (
codeindex:arch/:index/:hooks/:update-guide) plus a SessionStart hook that checks the CLI is onPATH. Install with/plugin marketplace add dreamlx/codeindex-claude+/plugin install codeindex@codeindex-claude. This replaces the in-reposkills/install.shmechanism. The plugin skills orchestrate the CLI — e.g.codeindex:update-guidedrivescodeindex claude-md update,codeindex:hooksdrivescodeindex hooks install— so the CLI commands remain first-class (see ADR-006 "engine vs affordance"). codeindex doctor: read-only health/sync diagnostic. Reports the installed CLI version,.codeindex.yamlpresence + language-parser health, the projectCLAUDE.mdcodeindex-section version vs the CLI, and — when a Claude Code environment is detected — the installedcodeindex-claudeplugin version. Each problem prints an actionable fix (pipx inject …for missing parsers,codeindex claude-md updatefor a stale section,/plugin install …when the plugin is absent). Editor-agnostic: the plugin section is skipped silently when~/.claude/pluginsdoesn't exist, so Cursor / bare-CLI users get a clean report. Exits non-zero when an error-level finding (e.g. a configured language with no installed parser) is present, so it's CI-usable. Never mutates anything. This is the single place that answers "am I up to date across the two artifacts, and what do I upgrade?"
Deprecated
skills/directory +skills/install.sh(B4): the old skill installer now warns and defaults to abort, pointing users to the plugin. The directory is removed in v1.0. (Note: thecodeindex claude-mdandcodeindex hooksCLI commands are not deprecated — they are the engine the plugin skills ride on. An earlier plan to deprecate them was reverted; see ADR-006.)
Release v0.24.0
[0.24.0] - 2026-05-25
Theme: navigation contract — see release notes + ADR-005.
Added
- Navigation-contract disclaimer at top of every
README_AI.md(<!-- codeindex navigation index — agent: drill into source via Read/Grep for precise mechanism; do not treat this as final word. -->). Injected by all 5 generation sites (writers/{overview,navigation,detailed}_generator.py,hierarchical.py,writer.pybase+fallback) via the newwriters.NAVIGATION_DISCLAIMERconstant. Tells AI agents to use the index as orientation only and verify details in source. Backed by Phase F benchmark (2026-05): when agents over-trusted oversized READMEs they returned wrong answers on 3/15 detail questions while running faster — the speed gain hid quality loss. Renderers ignore the HTML comment so human-facing markdown is unchanged.cli_symbols.pyPurpose-section parser is unaffected (comments don't interfere with markdown section detection). enricher.mark_enrichment_status(): Records AI enrichment outcome as<!-- enrichment: ok | failed (reason: ...) -->HTML comment under the Generated header inREADME_AI.md. Lets AI consumers distinguish "structural-only by config" (no marker) from "enrichment attempted and failed" (marker with reason).enricher.build_safe_subdir_context(): Builds AI-enrichment prompt context fromDirectoryTree.get_children()(bare subdir names only). Used by_enrich_directories_with_aiahead ofextract_summary_from_readme. Closes a prompt-injection chain where README markdown — containing AI-generated descriptions sourced from arbitrary source docstrings — was regex-extracted and fed into the next enrichment prompt. The README-parsing path remains as fallback for dirs without indexed children.- Idempotent
scan-all --aire-runs: Phase 2 now snapshots existing enrichment state (enricher.extract_blockquote_description()+enricher.has_successful_enrichment()) before Phase 1 rewrites READMEs, then re-injects cached descriptions for already-ok dirs without firing fresh AI calls. After a transient-failure scenario (e.g. claude-API rate limit on N/M dirs), the user just re-runscodeindex scan-all --aiand only the previously-failed dirs hit the AI backend; successes cost zero tokens. Use--retry-allto force a real AI call for every dir. - Failure-summary hint: When Phase 2 has any failed dirs, prints a short list plus actionable next steps (retry /
--retry-all/ switchai_commandtoclaude --model haiku/opencode/gemini). Per design: no auto-fallback — surface the options, let the user choose.
Changed
- AI enrichment error surfaces stderr:
scan-all --aipreviously logged opaque⚠ <dir>: AI errorand droppedinvoke_result.error. Now logs⚠ <dir>: AI error — <first line of stderr>and writes the same reason into the directory's README viamark_enrichment_status(..., "failed", reason=...). Successful enrichment writes<!-- enrichment: ok -->. - Documentation: removed
--fallbackfrom recommended commands (CLAUDE.md, requirements-workflow.md, pypi-release-guide.md). Flag has been deprecated since structural mode became default; the hidden flag still accepts/warns for backward compat.
Fixed
- Navigation-level READMEs double-counted files and symbols (GH #45).
NavigationGeneratorwas adding child-README aggregates on top ofparse_results, butcli_scan.pyruns navigation-level scans withrecursive=True— soparse_resultsalready covered descendants. Result: nav-level**Files**/**Symbols**were inflated (e.g.src/codeindex/parsers/showedFiles: 64instead of the true 34). Overview-level aggregation is unchanged (that path scans non-recursively and legitimately needs to sum child stats). Bug introduced in 1355b0a (pre-v0.18.0); became more visible in v0.24.0 because the 10KBmax_readme_sizecap bumped more dirs into the navigation tier.
Release v0.23.2
[0.23.2] - 2026-04-14
Changed
- Hook shebangs:
#!/bin/zsh→#!/usr/bin/env bashfor cross-platform portability. - Unified hook install:
make install-hooksnow delegates tocodeindex hooks install --all. - Post-commit logging: stderr redirected to
~/.codeindex/hooks/post-commit.loginstead of/dev/null. - Debug detection: Replaced ~50 lines of regex-based L2 check with ruff
T201/T100rules.
Added
hook-common.shversioned: Added toscripts/hooks/and auto-copied oncodeindex hooks install.- mypy: Added as dev dependency with baseline config; CI runs informational type check on core modules.
- Coverage gate: CI enforces
--cov-fail-under=78to prevent coverage regression. make typecheck: New Makefile target for mypy on core modules.
Release v0.23.1
[0.23.1] - 2026-03-15
Added
codeindex claude-md update/statusCLI commands: Manage codeindex section in project CLAUDE.md with version tracking.- Startup version-outdated hint: Every
codeindexCLI invocation checks if CLAUDE.md section is outdated and prints a reminder. - Unified
claude_md.pymodule: Single source of truth for CLAUDE.md injection, replacing fragmented hooks.py + init_wizard.py logic.
Changed
- CLAUDE.md template simplified: 130 lines → 22 lines. Removed hardcoded paths, language support table, and verbose configuration examples.
- Unified marker format:
<!-- codeindex:start v{version} -->with backward compatibility for old markers without version. init_wizard.pyinjection: Now delegates toclaude_md.pymodule instead of inline template.
Fixed
- Dead code cleanup: Removed
hooks.pypost_install_update_guide()(181 lines) that was never wired to pip entry points. - Dead import fix:
cli_config.pyreferenced non-existentinstall_hooksfromhooks.py, now uses correctinstall_hookfromcli_hooks.py.
Release v0.23.0
[0.23.0] - 2026-03-12
Added
-
AI-Enhanced Module Descriptions (Epic #25, Stories 25.1–25.3): Redefine
--aimode from full AI takeover to structural + AI micro-enhancement.- Blockquote description support:
extract_module_description()now reads> descriptionas Strategy 0 (highest priority) - AI enrichment module (
src/codeindex/enricher.py): Generates one-line functional descriptions per module using symbol names + file names - Concise prompt design: ~200-400 tokens per directory, ≤30 char output, 10-20x cheaper than old
--aimode - Batch AI calls: Groups multiple directories per AI invocation to reduce overhead
- scan-all auto-AI: Automatically enables Phase 2 AI enrichment when
ai_commandis configured (no--aiflag needed) --no-aiopt-out: Explicitly disable AI enrichment for structural-only output--ai/--no-aimutual exclusion: Clear error when both flags are used
- Blockquote description support:
-
Post-commit hook thin wrapper (Issue #30 fix): Redesigned hook architecture for maintainability.
- Thin shell wrapper (~30 lines): Only handles loop guard + venv activation
- Python logic via
codeindex hooks run post-commit: All business logic in upgradeable Python - Upgrade path:
pip install --upgrade ai-codeindexauto-updates hook behavior (no reinstall needed) - No custom AI prompts: Uses
codeindex scanpipeline, eliminating commit changelog noise
Fixed
- AI mode commit changelog noise (#30): Post-commit hook no longer injects git diff into custom AI prompts. Uses standard
codeindex scanpipeline instead. - Enricher prompt accuracy: Improved from "20 chars/brief" to "30 chars/concise" for better description quality.
Changed
--no-aiflag: Changed from hidden/deprecated to active opt-out flag for scan-all.- Post-commit hook generation:
_generate_post_commit_script()now generates thin wrapper delegating to Python. - Documentation: All hook and scan-all docs rewritten for AI CLI agent readers.
Technical Details
- New module:
src/codeindex/enricher.py— AI enrichment withenrich_directory()and_enrich_directories_with_ai() - New CLI subcommand:
codeindex hooks run post-commit— Python-side post-commit logic - New tests: 15 tests (7 scan-all auto-AI + 8 post-commit hook)
- Total tests: 1532 passed
Release v0.22.2
[0.22.2] - 2026-03-08
Added
-
Post-install hook for automatic CLAUDE.md updates (Epic #25, Story #26): Automatically updates
~/.claude/CLAUDE.mdafterpip install --upgrade ai-codeindex.- Marker-based injection: Idempotent updates using
<!-- CODEINDEX_GUIDE_START vX.X.X -->markers - Version detection: Automatically extracts and updates version numbers
- Backup creation: Creates timestamped backups before modification (
CLAUDE.md.backup.YYYYMMDD_HHMMSS) - CI environment detection: Skips updates in GitHub Actions, GitLab CI, Jenkins, CircleCI, and generic CI environments
- Silent failure handling: Gracefully handles permission errors and missing directories
- Content preservation: Preserves user customizations before/after guide section
- Template system: Uses
src/codeindex/templates/claude_md_core.mdfor guide content
- Marker-based injection: Idempotent updates using
-
Core guide template (
src/codeindex/templates/claude_md_core.md): Comprehensive codeindex usage guide for Claude Code users.- Complete command reference: All core commands (scan, tech-debt, symbols, index, status)
- Language support table: 9 languages with version information
- Best practices: AI Code integration workflow and tips
- Auto-updated on install: Version number dynamically replaced from package metadata
Technical Details
-
Implementation:
src/codeindex/hooks.pywith 4 core functions:_is_ci_environment(): CI/CD detection (6 environment variables)_extract_version_from_file(): Regex-based version extraction_inject_core_guide(): Marker-based content replacementpost_install_update_guide(): Main hook orchestration
-
Test coverage: 87% (21 tests: 18 unit + 3 integration)
-
Documentation: ADR 004 (
docs/architecture/adr/004-automatic-claude-md-update.md) -
/codeindex-update-guideskill (Epic #25, Story #27): Interactive Claude Code skill for deep CLAUDE.md customization.- Project analysis: Detects languages (10 extensions), .codeindex.yaml, LoomGraph integration
- Personalized suggestions: Profile-based recommendations (Swift docs, LoomGraph tips, version updates)
- Version diff: Markdown-formatted comparison between old and new versions
- Language table diff: Highlights newly supported languages
- Selective updates: Apply all or choose specific suggestions
- Backup & rollback: Timestamped backups with one-command restore
- Implementation:
src/codeindex/skill_helpers.pywith 9 helper functions - Test coverage: 80% (25 unit tests)
Release v0.20.0
[0.20.0] - 2026-02-20
Added
- Enhanced tech-debt detection (#20): Expanded from 2 to 5 detection dimensions with language-aware thresholds.
- Long method/function detection: >80 lines (MEDIUM), >150 lines (HIGH)
- Too many top-level functions: >15 functions per file (MEDIUM)
- High import coupling: >8 internal/relative imports (MEDIUM)
- Language-aware file size thresholds: Compact languages (Python/TS/JS: 800/1500/2500) vs verbose languages (PHP/Java/Go: 1500/2500/5000)
- 3-tier file size detection: medium_file/large_file/super_large_file
- 2-tier God Class detection: warning at >20 methods (MEDIUM), critical at >50 (CRITICAL)
- 25 new tests, 55 total tech-debt tests
Changed
- SmartWriter refactored into modular
writers/package:core.py,detailed_generator.py,navigation_generator.py,overview_generator.py,utils.py. Originalsmart_writer.pyreduced from 864 to thin re-export wrapper. - FileSizeClassifier thresholds lowered: super_large 5000→2500, large 2000→1500, medium added at 800 lines.
Release v0.19.0
[0.19.0] - 2026-02-19
Added
- TypeScript/JavaScript language support (Epic 20): Full parsing for
.ts,.tsx,.js,.jsxfiles using tree-sitter-typescript and tree-sitter-javascript. SingleTypeScriptParserclass handles all 4 file types with 3 grammar variants (typescript, tsx, javascript).- Symbol extraction: classes, functions, methods, interfaces, enums, type aliases, const/let/var declarations, arrow functions, getter/setters, abstract classes, generics
- Import/export extraction: ES module imports (named, default, namespace, side-effect), CommonJS
require(), type-only imports, re-exports, barrel exports - Inheritance extraction: class extends, implements, interface extends (single and multiple)
- Call extraction: function calls, method calls, static calls, constructor calls (
new), chained calls - TS-specific features: decorators, React JSX/TSX components, namespaces, ambient declarations (.d.ts)
- 77 new tests (68 unit + 9 integration), all passing
- New optional dependency group:
pip install ai-codeindex[typescript]installs tree-sitter-typescript and tree-sitter-javascript - Scanner support:
typescriptandjavascriptinLANGUAGE_EXTENSIONSand.codeindex.yamlconfig - CLI integration:
codeindex parse file.tsproduces JSON output with full symbol/import/call data