ai-codeindex 0.26.2__tar.gz → 0.27.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/CHANGELOG.md +21 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/PKG-INFO +1 -1
- ai_codeindex-0.27.0/docs/guides/graph-export.md +128 -0
- ai_codeindex-0.27.0/docs/releases/RELEASE_NOTES_v0.27.0.md +60 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/pyproject.toml +1 -1
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/README_AI.md +13 -12
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/cli.py +2 -0
- ai_codeindex-0.27.0/src/codeindex/cli_graph_export.py +65 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/cli_scan.py +8 -3
- ai_codeindex-0.27.0/src/codeindex/graph_buffer.py +116 -0
- ai_codeindex-0.27.0/src/codeindex/graph_export.py +269 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/invoker.py +103 -34
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parser.py +2 -0
- ai_codeindex-0.27.0/src/codeindex/parsers/README_AI.md +325 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/base.py +13 -7
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/java/README_AI.md +1 -1
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/java/__init__.py +13 -7
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/objc/README_AI.md +1 -1
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/objc/__init__.py +13 -7
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/php/README_AI.md +1 -1
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/php/__init__.py +13 -7
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/python/README_AI.md +1 -1
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/python/__init__.py +13 -7
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/typescript/README_AI.md +1 -1
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/typescript/__init__.py +24 -14
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/README_AI.md +102 -73
- ai_codeindex-0.27.0/tests/characterization/test_graphbuffer_baseline.py +147 -0
- ai_codeindex-0.27.0/tests/characterization/test_graphbuffer_equivalence.py +120 -0
- ai_codeindex-0.27.0/tests/fixtures/char_graphbuffer/golden/enrich_prompts.txt +19 -0
- ai_codeindex-0.27.0/tests/fixtures/char_graphbuffer/golden/frozen_ai_readmes.txt +120 -0
- ai_codeindex-0.27.0/tests/fixtures/char_graphbuffer/golden/project_symbols.md +37 -0
- ai_codeindex-0.27.0/tests/fixtures/char_graphbuffer/golden/structural_readmes.txt +114 -0
- ai_codeindex-0.27.0/tests/fixtures/char_graphbuffer/project/pysrc/models.py +16 -0
- ai_codeindex-0.27.0/tests/fixtures/char_graphbuffer/project/pysrc/service.py +45 -0
- ai_codeindex-0.27.0/tests/fixtures/char_graphbuffer/project/pysrc/util/helpers.py +13 -0
- ai_codeindex-0.27.0/tests/fixtures/char_graphbuffer/project/tssrc/api.ts +19 -0
- ai_codeindex-0.27.0/tests/fixtures/char_graphbuffer/project/tssrc/broken.ts +18 -0
- ai_codeindex-0.27.0/tests/fixtures/char_graphbuffer/project/tssrc/index.ts +29 -0
- ai_codeindex-0.27.0/tests/fixtures/char_graphbuffer/project/tssrc/nested/deep.ts +7 -0
- ai_codeindex-0.27.0/tests/fixtures/graph_export/export.ndjson +23 -0
- ai_codeindex-0.27.0/tests/fixtures/graph_export/project/app/service.py +22 -0
- ai_codeindex-0.27.0/tests/fixtures/graph_export/project/app/validators.py +6 -0
- ai_codeindex-0.27.0/tests/fixtures/graph_export/project/app/workers.py +15 -0
- ai_codeindex-0.27.0/tests/fixtures/graph_export/project/web/api.ts +9 -0
- ai_codeindex-0.27.0/tests/fixtures/graph_export/project/web/index.ts +7 -0
- ai_codeindex-0.27.0/tests/test_graph_export.py +158 -0
- ai_codeindex-0.27.0/tests/test_invoker_retry.py +91 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_java_error_recovery.py +12 -4
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_java_parser.py +4 -2
- ai_codeindex-0.27.0/tests/test_parser_partial_recovery.py +66 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_typescript_parser.py +56 -0
- ai_codeindex-0.26.2/src/codeindex/parsers/README_AI.md +0 -59
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/.editorconfig +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/.github/ISSUE_TEMPLATE/bug.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/.github/ISSUE_TEMPLATE/enhancement.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/.github/ISSUE_TEMPLATE/epic.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/.github/ISSUE_TEMPLATE/feature.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/.github/workflows/ci.yml +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/.github/workflows/publish.yml +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/.gitignore +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/.serena/.gitignore +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/.serena/memories/design_philosophy.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/.serena/memories/development_workflow.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/.serena/memories/project_overview.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/.serena/memories/release_automation.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/.serena/memories/suggested_commands.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/CLAUDE.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/CODE_OF_CONDUCT.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/CONTRIBUTING.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/FOR_LOOMGRAPH.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/LICENSE +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/Makefile +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/PROJECT_SYMBOLS.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/README.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/README_AI.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/README_zh.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/SECURITY.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/bench/.gitignore +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/bench/Makefile +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/bench/README.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/bench/grade.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/bench/questions.yaml.example +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/bench/report.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/bench/run_bench.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/bench/targets.yaml.example +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/README.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/architecture/adr/001-use-tree-sitter-for-parsing.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/architecture/adr/002-external-ai-cli-integration.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/architecture/adr/003-add-swift-objc-support.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/architecture/adr/004-automatic-claude-md-update.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/architecture/adr/005-navigation-disclaimer-and-readme-size-cap.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/architecture/adr/006-distribution-architecture-split.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/architecture/design/document-aggregation.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/architecture/design/initial-design.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/architecture/design/kiss-universal-description.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/architecture/design/parallel-strategy.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/architecture/design-philosophy.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/benchmark/2026-05-readme-impact.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/development/QUICK_START_RELEASE.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/development/claude-code-adoption-guide.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/development/claude-code-adoption-guide.zh.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/development/gitflow-workflow.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/development/github-issue-quick-reference.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/development/package-naming.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/development/pre-release-checklist.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/development/setup.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/development/team-workflow-guide.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/development/test-architecture.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/evaluation/before-after/README.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/evaluation/case-studies/php-payment-project.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/evaluation/loomgraph-efficiency-comparison.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/guides/advanced-usage.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/guides/claude-code-integration.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/guides/configuration.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/guides/contributing.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/guides/getting-started.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/guides/git-hooks-integration.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/guides/json-output-integration.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/guides/loomgraph-integration.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/planning/README.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/planning/ROADMAP.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/planning/executive-summary.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/releases/README.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/releases/RELEASE_NOTES_v0.10.0.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/releases/RELEASE_NOTES_v0.12.0.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/releases/RELEASE_NOTES_v0.12.1.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/releases/RELEASE_NOTES_v0.14.0.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/releases/RELEASE_NOTES_v0.15.0.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/releases/RELEASE_NOTES_v0.17.0.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/releases/RELEASE_NOTES_v0.17.2.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/releases/RELEASE_NOTES_v0.17.3.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/releases/RELEASE_NOTES_v0.18.0.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/releases/RELEASE_NOTES_v0.19.0.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/releases/RELEASE_NOTES_v0.2.0.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/releases/RELEASE_NOTES_v0.20.0.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/releases/RELEASE_NOTES_v0.23.1.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/releases/RELEASE_NOTES_v0.23.2.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/releases/RELEASE_NOTES_v0.24.0.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/releases/RELEASE_NOTES_v0.25.0.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/releases/RELEASE_NOTES_v0.3.0.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/releases/RELEASE_NOTES_v0.3.1.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/releases/RELEASE_NOTES_v0.3.2.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/releases/RELEASE_NOTES_v0.4.0.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/releases/RELEASE_NOTES_v0.5.0-beta1.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/releases/RELEASE_NOTES_v0.7.0.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/releases/RELEASE_NOTES_v0.8.0.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/docs/releases/RELEASE_NOTES_v0.9.0.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/examples/CLAUDE.md.php-project +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/examples/CLAUDE.md.template +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/examples/README.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/examples/README_AI.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/examples/ai-integration-guide.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/examples/frameworks/README_AI.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/examples/frameworks/template/README.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/examples/frameworks/template/README_AI.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/examples/frameworks/template/test_template_extractor.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/examples/frameworks/template/yourframework_extractor.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/examples/loomgraph_output.json +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/examples/loomgraph_php_output.json +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/examples/loomgraph_sample.php +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/examples/loomgraph_sample.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/examples/parse_integration_example.sh +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/examples/print_env.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/hooks/README.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/hooks/templates/post-commit-update-logic.sh +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/hooks/templates/post-commit-v4 +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/reports/swift-objc-support-analysis.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/reports/swift-poc-summary.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/reports/tech-debt-codeindex-v2.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/reports/tech-debt-codeindex.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/reports/tech-debt-loomgraph-v2.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/reports/tech-debt-loomgraph.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/reports/workflow-comparison.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/scripts/README.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/scripts/README_AI.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/scripts/bump_version.sh +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/scripts/check_docs_release.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/scripts/check_version_consistency.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/scripts/close-epic9-issues.sh +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/scripts/diagnose_ai_failures.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/scripts/hooks/hook-common.sh +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/scripts/hooks/pre-push +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/scripts/legacy/PROJECT_INDEX.json +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/scripts/legacy/README.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/scripts/legacy/hierarchical_strategy.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/scripts/pre_release_check.sh +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/scripts/release.sh +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/scripts/test_hook_e2e.sh +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/scripts/validate_php_project.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/skills/README.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/skills/create.sh +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/skills/install.sh +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/skills/src/mo-arch/SKILL.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/skills/src/mo-index/SKILL.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/README_AI.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/__init__.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/adaptive_config.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/adaptive_selector.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/ai_helper.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/claude_md.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/cli_claude_md.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/cli_common.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/cli_config.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/cli_config_commands.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/cli_docs.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/cli_hooks.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/cli_parse.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/cli_symbols.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/cli_tech_debt.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/config.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/config_help.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/directory_tree.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/docstring_processor.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/doctor.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/enricher.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/errors.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/extractors/README_AI.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/extractors/__init__.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/extractors/spring.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/extractors/thinkphp.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/file_classifier.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/framework_detect.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/hierarchical.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/hooks.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/incremental.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/init_wizard.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/objc_association.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parallel.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/__init__.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/java/calls.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/java/imports.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/java/inheritance.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/java/symbols.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/java_parser.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/objc/calls.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/objc/imports.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/objc/inheritance.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/objc/symbols.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/php/calls.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/php/imports.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/php/inheritance.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/php/symbols.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/python/calls.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/python/imports.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/python/inheritance.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/python/symbols.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/swift/README_AI.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/swift/__init__.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/swift/calls.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/swift/imports.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/swift/inheritance.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/swift/symbols.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/typescript/calls.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/typescript/imports.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/typescript/inheritance.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/typescript/symbols.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/parsers/utils.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/route_extractor.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/route_registry.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/scanner.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/semantic_extractor.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/skill_helpers.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/smart_writer.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/symbol_index.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/symbol_scorer.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/tech_debt.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/tech_debt_formatters.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/templates/README_AI.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/templates/__init__.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/templates/claude_md_core.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/test_smells.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/writer.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/writers/README_AI.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/writers/__init__.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/writers/core.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/writers/detailed_generator.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/writers/navigation_generator.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/writers/overview_generator.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/src/codeindex/writers/utils.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/test_generator/generator.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/test_generator/scripts/analyze_legacy_tests.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/test_generator/scripts/compare_coverage.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/test_generator/scripts/compare_test_results.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/test_generator/specs/java.yaml +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/test_generator/specs/php.yaml +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/test_generator/specs/python.yaml +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/test_generator/templates/inheritance_test.py.j2 +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/__init__.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/conftest.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/extractors/README_AI.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/extractors/__init__.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/extractors/test_spring.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/extractors/test_thinkphp.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/extractors/test_thinkphp_description.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/features/README.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/features/cli_scan_defaults.feature +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/features/help_system.feature +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/features/init_wizard.feature +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/features/symbol_overload_detection.feature +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/features/tech_debt_detection.feature +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/features/tech_debt_reporting.feature +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/fixtures/README_AI.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/fixtures/cli_parse/Controller.php +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/fixtures/cli_parse/README_AI.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/fixtures/cli_parse/Service.java +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/fixtures/cli_parse/Simple.java +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/fixtures/cli_parse/broken.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/fixtures/cli_parse/complete.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/fixtures/cli_parse/service.ts +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/fixtures/cli_parse/simple.php +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/fixtures/cli_parse/simple.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/fixtures/cli_parse/unsupported.txt +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/fixtures/java/enum.java +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/fixtures/java/generics.java +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/fixtures/java/imports.java +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/fixtures/java/interface.java +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/fixtures/java/record.java +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/fixtures/java/sealed_class.java +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/fixtures/java/simple_class.java +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/fixtures/java/spring/Application.java +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/fixtures/java/spring/User.java +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/fixtures/java/spring/UserController.java +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/fixtures/java/spring/UserRepository.java +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/fixtures/java/spring/UserService.java +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/fixtures/java/spring_controller.java +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/fixtures/typescript/app.js +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/fixtures/typescript/component.tsx +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/fixtures/typescript/service.ts +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/legacy/README.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/legacy/README_AI.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/legacy/test_hierarchical_test/level1/file1.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/legacy/test_hierarchical_test/level1/level2a/file2.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/legacy/test_hierarchical_test/level1/level2a/level3/file4.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/legacy/test_hierarchical_test/level1/level2b/file3.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/legacy/test_hierarchy_simple.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_adaptive_config.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_adaptive_selector.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_ai_helper.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_backward_compatibility.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_call_integration.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_claude_md.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_claude_md_injection.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_cli_config_gitignore.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_cli_debt_scan.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_cli_docstring_options.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_cli_hooks.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_cli_json.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_cli_parse.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_cli_scan_defaults_bdd.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_cli_tech_debt.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_config_adaptive.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_dataclass_structure.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_directory_tree.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_docstring_config.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_docstring_processor.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_doctor.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_enricher.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_enricher_integration.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_error_handling.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_file_classifier.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_help_system_bdd.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_hook_post_commit.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_hooks.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_hooks_config.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_hooks_integration.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_init_minimal_scope.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_init_wizard_bdd.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_integration_swift_objc.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_java_annotations.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_java_calls.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_java_edge_cases.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_java_generic_bounds.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_java_inheritance.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_java_lambda.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_java_lombok.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_java_module.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_java_spring.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_java_throws.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_json_output.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_lazy_loading.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_list_dirs_diagnostic.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_loomgraph_integration.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_objc_association_utils.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_parallel_scan.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_parser.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_parser_detection.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_parser_objc_association.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_parser_objc_basic.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_parser_objc_bridging.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_parser_objc_categories.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_parser_swift_docstrings.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_parser_swift_extensions.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_parser_swift_generics.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_parser_swift_inheritance.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_parser_swift_integration.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_parser_swift_poc.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_parser_swift_properties.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_parser_swift_property_wrappers.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_parser_swift_protocols.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_parser_swift_signatures.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_php_calls.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_php_comment_extraction.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_php_docstring_extraction.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_php_import_alias.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_php_inheritance.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_php_loomgraph_integration.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_project_index_semantic.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_python_calls.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_python_docstring_description.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_python_import_alias.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_python_inheritance.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_route_extractor.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_route_info.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_route_registry.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_route_table_description.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_route_table_display.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_scanall_auto_ai.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_scanner_passthrough.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_semantic_extractor.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_skill_helpers.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_smart_writer.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_smart_writer_adaptive.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_smart_writer_docstring.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_smart_writer_enriched.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_smart_writer_integration.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_smart_writer_semantic.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_story_4_4_integration.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_symbol_overload.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_symbol_scorer.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_tech_debt_bdd.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_tech_debt_detector.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_tech_debt_formatters.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_tech_debt_ios.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_tech_debt_java.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_tech_debt_reporter.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_test_smells.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_thinkphp_route_extractor.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_typescript_integration.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_windows_path_optimization.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/test_writer_preserves_enrichment.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/writers/README_AI.md +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/writers/__init__.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/writers/test_generators.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/tests/writers/test_utils.py +0 -0
- {ai_codeindex-0.26.2 → ai_codeindex-0.27.0}/uv.lock +0 -0
|
@@ -7,6 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.27.0] - 2026-06-28
|
|
11
|
+
|
|
12
|
+
**Theme**: graph-export + parser robustness. Ships the new `codeindex
|
|
13
|
+
graph-export` command — codeindex's write-once data contract with loomgraph
|
|
14
|
+
(ADR-007, gated GREEN/YELLOW by the LoomGraph#30 consumption spike) — plus
|
|
15
|
+
the in-run AI retry (#97) and the cross-language partial-parse recovery (#95)
|
|
16
|
+
that were sitting unreleased on master. graph-export is **additive**: it is a
|
|
17
|
+
standalone command, the new `GraphBuffer` IR (#101) it reuses is dormant
|
|
18
|
+
(unwired into `scan-all`), and existing `scan-all` / `parse` / `symbols`
|
|
19
|
+
output is unchanged. No migration needed.
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- **`codeindex graph-export` — write-once graph artifact for loomgraph** (GH #102, ADR-007, **experimental schema_version 0**): a standalone command that does its own clean whole-tree parse and dumps NDJSON of code entities (`class`/`function`/`method`, module-qualified id + `source_id` + first-line description + `provenance`) and `CALLS`/`INHERITS` edges. It is **decoupled from `scan-all`/README render** — the LoomGraph#30 consumption spike (verdict 🟡 YELLOW) justified the export but not the #101 render-flip, and the two are architecturally independent (export needs the buffer *populated*, not the render path *flipped*). The parser emits *file-local* names, so the export performs the only cross-file resolution pass: every edge carries a **`resolution_qualifier`** (`resolved` / `ambiguous` / `unresolved`, with `candidates` on ambiguous) so a consumer never reads an unresolved edge as real, plus **`dst_raw`** (the original best-effort name) so a consumer can still synthesise an external stub or filter framework noise when `dst` is null, and the meta header carries **`provenance_completeness`** flagging that AST extraction misses dynamic dispatch / reflection (the spike's E-class finding — an absent edge means "not statically resolvable", not "none"). Schema is experimental and Python-validated; a TS spot-check precedes any stable-contract promise. Reuses the #101 `GraphBuffer` purely as the parsed-data container; ships no persistent/mutable state (ADR-007).
|
|
24
|
+
- **`scan-all --ai` retries transient AI failures in-run** (GH #97): a serial enrichment pass that hit a one-off haiku timeout / rate-limit / 5xx previously lost that directory until a manual re-run (observed 12/50 transient failures in the GH #94 A/B). `invoke_ai_cli` now takes `max_attempts` (scan paths use 3) and retries with exponential backoff, but **only** on recognised-transient signals (`_is_transient`: timeout, rate-limit, 429, 502/503/529, overload, connection reset, …). Permanent failures — a misconfigured `ai_command` (`command not found`, exit 127) or any unlabeled non-zero exit — **fail fast** (single attempt) so they are not hammered N× across every directory. Not a backend/direct-API change: the agent-CLI invocation stays the only transport. Default `max_attempts=1` preserves single-shot behavior for every other caller.
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- **TypeScript parser no longer zeroes out a whole file on one unsupported construct** (GH #95): the bundled `tree-sitter-typescript` grammar (0.23.2 — the latest published, so this is *not* a stale pin but upstream grammar lag) does not parse some modern-TS constructs, e.g. `export type *` (TS 5.0) and generic-typed tagged templates like Prisma `$queryRaw<{...}[]>`...``. The parser bailed the moment `tree.root_node.has_error` was true, returning `symbols: []` — so a single unparseable line dropped the file's entire class/method set from `PROJECT_SYMBOLS.md` and its directory `README_AI.md` (hit 2/608 `.ts` files on a real monorepo, silently). tree-sitter error recovery is *local*, so the surrounding symbols are still in the tree. `TypeScriptParser.parse` now extracts symbols regardless of `has_error`, returns whatever is recoverable flagged with a new `ParseResult.partial=True`, and only surfaces the hard `error="Syntax error in source file"` when nothing at all could be recovered. Consumers that branch on `result.error` (enrichment, tech-debt, error counts) are unaffected — a partial file has `error=None` so its recovered symbols flow through. Verified: `LockController.ts` with a `$queryRaw<T>` line went from `symbols: []` to recovering its class + all 4 members.
|
|
29
|
+
- **Same partial-parse recovery applied to all remaining parsers** (GH #95 fast-follow): the identical `has_error` early-bail existed in `base` (used by Swift), `python`, `java`, `php`, and `objc`. All now extract regardless of `has_error`, return recoverable symbols flagged `partial=True`, and only emit the hard error when nothing is recoverable — so a single malformed construct no longer zeroes a whole file in any supported language. Cross-language regression test (`tests/test_parser_partial_recovery.py`) covers python/java/php/swift/objc; two Java tests that asserted the old all-or-nothing contract were updated to the graceful-degradation contract.
|
|
30
|
+
|
|
10
31
|
## [0.26.2] - 2026-06-22
|
|
11
32
|
|
|
12
33
|
**Theme**: enrichment-quality patch. `scan-all --ai` was silently writing punt
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# graph-export — codeindex → loomgraph data contract
|
|
2
|
+
|
|
3
|
+
> **Status: EXPERIMENTAL (`schema_version: 0`).** Validated on Python; a
|
|
4
|
+
> TypeScript spot-check precedes any stable-contract promise. Fields and
|
|
5
|
+
> format may change without deprecation while at version 0.
|
|
6
|
+
|
|
7
|
+
`codeindex graph-export` dumps a **write-once** NDJSON graph of the codebase
|
|
8
|
+
for downstream consumers (loomgraph) to read. Per [ADR-007](../architecture/adr/007-codeindex-stateless-graph-ownership.md)
|
|
9
|
+
codeindex stays a stateless emitter: this command holds **no** persistent or
|
|
10
|
+
mutable state — no `.db`, no incremental sync, no vector index.
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
codeindex graph-export --root . -o graph-export.ndjson
|
|
16
|
+
codeindex graph-export --root . -o - # stdout
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
It does its **own clean whole-tree parse** (every source file exactly once)
|
|
20
|
+
and is fully decoupled from `scan-all` / README rendering — running it never
|
|
21
|
+
touches `README_AI.md`.
|
|
22
|
+
|
|
23
|
+
## Format
|
|
24
|
+
|
|
25
|
+
NDJSON. Line 1 is the `meta` record; then `entity` records; then `edge`
|
|
26
|
+
records. All records carry a `type` tag.
|
|
27
|
+
|
|
28
|
+
```jsonc
|
|
29
|
+
{"type":"meta","schema_version":0,"generator":"codeindex","provenance_completeness":"ast-only: ..."}
|
|
30
|
+
{"type":"entity","id":"app.service.AuthService","entity_type":"class","source_id":"app/service.py:8","description":"Authenticates users.","provenance":"ast"}
|
|
31
|
+
{"type":"edge","kind":"CALLS","src":"app.service.AuthService.login","dst":"app.service.AuthService.authenticate","resolution_qualifier":"resolved","source_id":"app/service.py:15"}
|
|
32
|
+
{"type":"edge","kind":"CALLS","src":"app.workers.kickoff","dst":null,"resolution_qualifier":"ambiguous","candidates":["app.workers.Builder.run","app.workers.Packer.run"],"source_id":"app/workers.py:15"}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Naming convention (`id`)
|
|
36
|
+
|
|
37
|
+
Entity ids are **fully-qualified and path-derived**: the module is the file
|
|
38
|
+
path *relative to the scan root* with the extension dropped and `/` → `.`,
|
|
39
|
+
then the file-local symbol name appended. So `src/loomgraph/cli/_common.py`'s
|
|
40
|
+
`prepare_workspace_store` becomes `src.loomgraph.cli._common.prepare_workspace_store`.
|
|
41
|
+
|
|
42
|
+
Fully-qualified is deliberate — it resolves same-name collisions across
|
|
43
|
+
sibling classes/modules (the spike's F-class) and makes ownership explicit.
|
|
44
|
+
|
|
45
|
+
> **src-layout caveat.** Because the module is *path*-derived, not
|
|
46
|
+
> *import*-derived, a `src/`-layout project carries the layout dir in the id
|
|
47
|
+
> (`src.loomgraph.…`, where the real Python import path is `loomgraph.…`).
|
|
48
|
+
> codeindex does **not** strip it in v0 — there is no robust, config-free way
|
|
49
|
+
> to tell a layout dir (`src/`, strip) from a genuine top package (`app/`,
|
|
50
|
+
> keep). A consumer that maintains its own import-path index should normalise
|
|
51
|
+
> the layout prefix when ingesting these ids (it knows the project layout;
|
|
52
|
+
> codeindex, scanning a bare tree, does not). A codeindex-side `module_root` option is a
|
|
53
|
+
> possible v1 addition if multiple consumers need it.
|
|
54
|
+
|
|
55
|
+
### Entity
|
|
56
|
+
|
|
57
|
+
| field | meaning |
|
|
58
|
+
|---|---|
|
|
59
|
+
| `id` | fully-qualified, path-derived name (see above), e.g. `app.service.AuthService.login` |
|
|
60
|
+
| `entity_type` | `class` \| `function` \| `method` |
|
|
61
|
+
| `source_id` | `relpath:line` |
|
|
62
|
+
| `description` | first line of the docstring (may be empty) |
|
|
63
|
+
| `provenance` | `ast` (L1 structural) |
|
|
64
|
+
|
|
65
|
+
### Edge
|
|
66
|
+
|
|
67
|
+
| field | meaning |
|
|
68
|
+
|---|---|
|
|
69
|
+
| `kind` | `CALLS` \| `INHERITS` |
|
|
70
|
+
| `src` | resolved entity id of the caller / child class |
|
|
71
|
+
| `dst` | resolved entity id of the callee / parent, or `null` if not resolved |
|
|
72
|
+
| `dst_raw` | the original best-effort name the resolver tried (file-local). Always present; **load-bearing when `dst` is null** — it is the only record of *what* was called, so a consumer can synthesise an external stub or filter framework noise (e.g. `expect`, `Date.now`) |
|
|
73
|
+
| `resolution_qualifier` | `resolved` \| `ambiguous` \| `unresolved` |
|
|
74
|
+
| `candidates` | (ambiguous only) the entity ids the name could refer to |
|
|
75
|
+
| `source_id` | `relpath:line` of the call / class definition |
|
|
76
|
+
|
|
77
|
+
## Scope — a structural slice, not a full graph index
|
|
78
|
+
|
|
79
|
+
The export is codeindex's **structural slice** (L1+L2): real code symbols
|
|
80
|
+
(`class` / `function` / `method`) and their `CALLS` / `INHERITS` edges. It is
|
|
81
|
+
**not** a complete graph index and is **not** meant to replace a consumer's
|
|
82
|
+
own index.
|
|
83
|
+
|
|
84
|
+
Deliberately **not** emitted (the consumer synthesises these around the
|
|
85
|
+
slice during ingestion, per ADR-007):
|
|
86
|
+
|
|
87
|
+
- **file / module container nodes** — derivable from each entity's `source_id`.
|
|
88
|
+
Consequence: a `<module>`-level call has a `src` (the dotted module path)
|
|
89
|
+
with no backing `entity` record; that's expected, the consumer materialises
|
|
90
|
+
the container if it wants one. (`entity_type: "module"` may be added in v1
|
|
91
|
+
if synthesising modules proves painful downstream.)
|
|
92
|
+
- **external / stdlib stubs** — these are exactly where `unresolved` edges
|
|
93
|
+
point (see below); the consumer decides whether to materialise stub nodes.
|
|
94
|
+
|
|
95
|
+
This matches the LoomGraph#30 GREEN field set (which contained no module/file
|
|
96
|
+
nodes) and keeps the codeindex/loomgraph division clean: codeindex emits the
|
|
97
|
+
symbol-level truth, loomgraph builds the container + external + semantic
|
|
98
|
+
scaffolding on top.
|
|
99
|
+
|
|
100
|
+
## Consumer contract — read these two caveats
|
|
101
|
+
|
|
102
|
+
The parser emits **file-local** names; the export runs the only cross-file
|
|
103
|
+
resolution pass. Two metadata mechanisms exist because that resolution and
|
|
104
|
+
the underlying AST extraction are lossy — **a consumer that ignores them will
|
|
105
|
+
draw wrong conclusions**:
|
|
106
|
+
|
|
107
|
+
1. **`resolution_qualifier`** — never treat an `unresolved` or `ambiguous`
|
|
108
|
+
edge as a confirmed relationship. `unresolved` usually means external /
|
|
109
|
+
stdlib or a name not in the tree (with `dst: null`); `ambiguous` means the
|
|
110
|
+
name matched several entities (see `candidates`, `dst: null`). A **high
|
|
111
|
+
unresolved fraction is normal** — most calls in real code go to stdlib /
|
|
112
|
+
third-party / methods AST cannot statically resolve (≈59% on a real
|
|
113
|
+
loomgraph round-trip). The consumer owns the dangling-edge policy: drop,
|
|
114
|
+
keep as dangling, or materialise an external stub node as the `dst`.
|
|
115
|
+
codeindex emits no sentinel/placeholder entity — the entity set contains
|
|
116
|
+
only real code symbols.
|
|
117
|
+
2. **`provenance_completeness`** (meta) — extraction is AST-only. Dynamic
|
|
118
|
+
dispatch (`getattr` / duck-typing / event handlers), reflection /
|
|
119
|
+
metaclasses, and decorator wiring are **not** captured. An **absent edge
|
|
120
|
+
means "not statically resolvable", not "none"** — this was the decisive
|
|
121
|
+
finding of the LoomGraph#30 consumption spike.
|
|
122
|
+
|
|
123
|
+
## What this is NOT
|
|
124
|
+
|
|
125
|
+
Per ADR-007, codeindex does not own a persistent graph. No mutable `.db`,
|
|
126
|
+
incremental sync, corruption recovery, or `sqlite-vec` index — those, plus L3
|
|
127
|
+
(design-doc LLM extraction), are loomgraph's. This artifact is a one-shot
|
|
128
|
+
snapshot loomgraph reads (process-decoupled, decision (a)).
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Release Notes - v0.27.0
|
|
2
|
+
|
|
3
|
+
**Theme**: graph-export + parser robustness.
|
|
4
|
+
|
|
5
|
+
This release ships codeindex's first **write-once graph artifact** — the data
|
|
6
|
+
contract with loomgraph (per [ADR-007](../architecture/adr/007-codeindex-stateless-graph-ownership.md)) —
|
|
7
|
+
alongside the AI-retry and partial-parse robustness fixes that were sitting
|
|
8
|
+
unreleased on master.
|
|
9
|
+
|
|
10
|
+
> **Upgrade is safe and additive.** `graph-export` is a brand-new standalone
|
|
11
|
+
> command; the `GraphBuffer` IR it reuses is dormant (not wired into
|
|
12
|
+
> `scan-all`); and existing `scan-all` / `parse` / `symbols` output is
|
|
13
|
+
> unchanged. No migration, no cache flush needed.
|
|
14
|
+
|
|
15
|
+
## New: `codeindex graph-export`
|
|
16
|
+
|
|
17
|
+
A standalone command that does its own clean whole-tree parse and emits a
|
|
18
|
+
**write-once NDJSON** graph for downstream consumers (loomgraph):
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
codeindex graph-export --root . -o graph-export.ndjson
|
|
22
|
+
codeindex graph-export --root . -o - # stdout
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
- **Entities** — `class` / `function` / `method`, module-qualified id,
|
|
26
|
+
`source_id` (`relpath:line`), first-line description, `provenance`.
|
|
27
|
+
- **Edges** — `CALLS` / `INHERITS`, each carrying a `resolution_qualifier`
|
|
28
|
+
(`resolved` / `ambiguous` / `unresolved`) plus `dst_raw` (the original
|
|
29
|
+
name, load-bearing when `dst` is null) and `candidates` on ambiguous.
|
|
30
|
+
- **Meta** — `schema_version` + `provenance_completeness` flagging that AST
|
|
31
|
+
extraction does not capture dynamic dispatch / reflection.
|
|
32
|
+
|
|
33
|
+
**Status: experimental (`schema_version: 0`).** The schema may change without
|
|
34
|
+
deprecation while at version 0; validated on Python with a TypeScript
|
|
35
|
+
spot-check. Full contract + consumer caveats: [docs/guides/graph-export.md](../guides/graph-export.md).
|
|
36
|
+
|
|
37
|
+
Decoupling note: the LoomGraph#30 consumption spike (verdict 🟡 YELLOW)
|
|
38
|
+
justified this export but **not** an internal render-flip (#101 Phase 2);
|
|
39
|
+
the two are architecturally independent and the flip is deferred.
|
|
40
|
+
|
|
41
|
+
## Robustness (previously unreleased on master)
|
|
42
|
+
|
|
43
|
+
- **In-run AI retry/backoff** (#97): `scan-all --ai` now retries
|
|
44
|
+
*recognised-transient* failures (timeout / rate-limit / 5xx) with
|
|
45
|
+
exponential backoff (scan paths use 3 attempts); permanent failures
|
|
46
|
+
(e.g. misconfigured `ai_command`) still fail fast. Agent-CLI stays the
|
|
47
|
+
only transport.
|
|
48
|
+
- **Cross-language partial-parse recovery** (#95): a single unparseable
|
|
49
|
+
construct no longer zeroes a whole file's symbols. All parsers
|
|
50
|
+
(python / typescript / java / php / swift / objc) now return recoverable
|
|
51
|
+
symbols flagged `partial=True`, surfacing a hard error only when nothing
|
|
52
|
+
is recoverable.
|
|
53
|
+
|
|
54
|
+
## Internal
|
|
55
|
+
|
|
56
|
+
- **GraphBuffer IR** (#101): a per-run in-memory IR between parse and render,
|
|
57
|
+
shipped dormant (unwired) with a characterization safety net. Reused by
|
|
58
|
+
`graph-export`; no user-facing behavior change.
|
|
59
|
+
|
|
60
|
+
See [CHANGELOG.md](../../CHANGELOG.md) for the full entry list.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<!-- codeindex navigation index — agent: drill into source via Read/Grep for precise mechanism; do not treat this as final word. -->
|
|
2
|
-
<!-- Generated by codeindex (detailed) at 2026-06-
|
|
2
|
+
<!-- Generated by codeindex (detailed) at 2026-06-27T20:08:49.478875 -->
|
|
3
3
|
|
|
4
4
|
# codeindex
|
|
5
5
|
|
|
6
6
|
## Overview
|
|
7
7
|
|
|
8
|
-
- **Files**:
|
|
9
|
-
- **Symbols**:
|
|
8
|
+
- **Files**: 92
|
|
9
|
+
- **Symbols**: 599
|
|
10
10
|
|
|
11
11
|
## Files
|
|
12
12
|
|
|
@@ -125,6 +125,15 @@ _Documentation CLI commands for codeindex._
|
|
|
125
125
|
- `def docs()`
|
|
126
126
|
- `def show_ai_guide()`
|
|
127
127
|
|
|
128
|
+
### cli_graph_export.py
|
|
129
|
+
_CLI graph-export command — write-once graph artifact for loomgraph (GH #102).
|
|
130
|
+
|
|
131
|
+
Standalone (Path A): does its own clean whole-tree parse and dumps a
|
|
132
|
+
wr_
|
|
133
|
+
|
|
134
|
+
**Functions:**
|
|
135
|
+
- `def graph_export(root: Path, output: str, quiet: bool)`
|
|
136
|
+
|
|
128
137
|
### cli_hooks.py
|
|
129
138
|
_Git Hooks management module for codeindex.
|
|
130
139
|
|
|
@@ -337,15 +346,7 @@ _Configuration management for codeindex._
|
|
|
337
346
|
### config_help.py
|
|
338
347
|
_Configuration help documentation for codeindex (Epic 15 Story 15.3).
|
|
339
348
|
|
|
340
|
-
This module provides comprehensive help
|
|
341
|
-
co_
|
|
342
|
-
|
|
343
|
-
**Functions:**
|
|
344
|
-
- `def show_full_config_help() -> None`
|
|
345
|
-
- `def _show_param_section(param_name: str) -> None`
|
|
346
|
-
- `def explain_parameter(
|
|
347
|
-
param_name: str, current_value: Optional[any] = None, cpu_count: Optional[int] = None
|
|
348
|
-
|
|
349
|
+
This module provides comprehensive help documentatio
|
|
349
350
|
|
|
350
351
|
---
|
|
351
352
|
_Content truncated due to size limit. See individual module README files for details._
|
|
@@ -12,6 +12,7 @@ from .cli_claude_md import claude_md, print_outdated_warning
|
|
|
12
12
|
from .cli_config import doctor, init, list_dirs, status
|
|
13
13
|
from .cli_config_commands import config
|
|
14
14
|
from .cli_docs import docs
|
|
15
|
+
from .cli_graph_export import graph_export
|
|
15
16
|
from .cli_hooks import hooks
|
|
16
17
|
from .cli_parse import parse
|
|
17
18
|
from .cli_scan import scan, scan_all
|
|
@@ -44,6 +45,7 @@ main.add_command(affected)
|
|
|
44
45
|
main.add_command(tech_debt)
|
|
45
46
|
main.add_command(tech_debt, name="debt-scan") # Alias for backward compatibility (v0.22.0+)
|
|
46
47
|
main.add_command(hooks)
|
|
48
|
+
main.add_command(graph_export)
|
|
47
49
|
main.add_command(docs)
|
|
48
50
|
main.add_command(claude_md)
|
|
49
51
|
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"""CLI graph-export command — write-once graph artifact for loomgraph (GH #102).
|
|
2
|
+
|
|
3
|
+
Standalone (Path A): does its own clean whole-tree parse and dumps a
|
|
4
|
+
write-once NDJSON graph. Does not touch scan-all / README render.
|
|
5
|
+
See ``codeindex.graph_export`` and ADR-007.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
import click
|
|
11
|
+
|
|
12
|
+
from .cli_common import console
|
|
13
|
+
from .config import Config
|
|
14
|
+
from .graph_export import build_export, dump_ndjson, walk_and_parse
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@click.command(name="graph-export")
|
|
18
|
+
@click.option(
|
|
19
|
+
"--root",
|
|
20
|
+
type=click.Path(exists=True, file_okay=False, path_type=Path),
|
|
21
|
+
default=Path("."),
|
|
22
|
+
help="Project root to export (default: current directory).",
|
|
23
|
+
)
|
|
24
|
+
@click.option(
|
|
25
|
+
"--output",
|
|
26
|
+
"-o",
|
|
27
|
+
default="graph-export.ndjson",
|
|
28
|
+
help="Output NDJSON path, or '-' for stdout (default: graph-export.ndjson).",
|
|
29
|
+
)
|
|
30
|
+
@click.option("--quiet", "-q", is_flag=True, help="Minimal output.")
|
|
31
|
+
def graph_export(root: Path, output: str, quiet: bool):
|
|
32
|
+
"""Export the code graph (entities + CALLS/INHERITS edges) as write-once NDJSON.
|
|
33
|
+
|
|
34
|
+
EXPERIMENTAL (schema_version 0): the contract with loomgraph per ADR-007.
|
|
35
|
+
Each edge carries a resolution_qualifier (resolved / ambiguous / unresolved)
|
|
36
|
+
so a consumer never mistakes an unresolved edge for a real one.
|
|
37
|
+
"""
|
|
38
|
+
config_path = root / ".codeindex.yaml"
|
|
39
|
+
config = Config.load(config_path if config_path.exists() else None)
|
|
40
|
+
|
|
41
|
+
buffer = walk_and_parse(root, config)
|
|
42
|
+
model = build_export(buffer, root)
|
|
43
|
+
text = dump_ndjson(model)
|
|
44
|
+
|
|
45
|
+
if output == "-":
|
|
46
|
+
click.echo(text, nl=False)
|
|
47
|
+
return
|
|
48
|
+
|
|
49
|
+
out_path = Path(output)
|
|
50
|
+
if not out_path.is_absolute():
|
|
51
|
+
out_path = root / out_path
|
|
52
|
+
out_path.write_text(text, encoding="utf-8")
|
|
53
|
+
|
|
54
|
+
if not quiet:
|
|
55
|
+
n_amb = sum(
|
|
56
|
+
1 for e in model.edges if e.resolution_qualifier == "ambiguous"
|
|
57
|
+
)
|
|
58
|
+
n_unres = sum(
|
|
59
|
+
1 for e in model.edges if e.resolution_qualifier == "unresolved"
|
|
60
|
+
)
|
|
61
|
+
console.print(
|
|
62
|
+
f"[green]✓[/green] graph-export → {out_path} "
|
|
63
|
+
f"[dim]({len(model.entities)} entities, {len(model.edges)} edges; "
|
|
64
|
+
f"{n_amb} ambiguous, {n_unres} unresolved)[/dim]"
|
|
65
|
+
)
|
|
@@ -14,6 +14,7 @@ from .config import Config
|
|
|
14
14
|
from .directory_tree import DirectoryTree
|
|
15
15
|
from .docstring_processor import DocstringProcessor
|
|
16
16
|
from .invoker import (
|
|
17
|
+
AI_SCAN_MAX_ATTEMPTS,
|
|
17
18
|
clean_ai_output,
|
|
18
19
|
format_prompt,
|
|
19
20
|
invoke_ai_cli,
|
|
@@ -331,7 +332,9 @@ def _generate_ai_readme(
|
|
|
331
332
|
console.print(f" [dim]→ Invoking AI CLI (timeout: {timeout}s)...[/dim]")
|
|
332
333
|
console.print(f" [dim] Command: {config.ai_command[:50]}...[/dim]")
|
|
333
334
|
|
|
334
|
-
invoke_result = invoke_ai_cli(
|
|
335
|
+
invoke_result = invoke_ai_cli(
|
|
336
|
+
config.ai_command, prompt, timeout=timeout, max_attempts=AI_SCAN_MAX_ATTEMPTS
|
|
337
|
+
)
|
|
335
338
|
|
|
336
339
|
if not invoke_result.success:
|
|
337
340
|
console.print(f"[red]✗ AI CLI error:[/red] {invoke_result.error}")
|
|
@@ -775,8 +778,10 @@ def _enrich_directories_with_ai(
|
|
|
775
778
|
parent_name = dir_path.parent.name if dir_path.parent != dir_path else ""
|
|
776
779
|
prompt = build_enrich_prompt(dir_path.name, summary, parent_name)
|
|
777
780
|
|
|
778
|
-
# Invoke AI CLI
|
|
779
|
-
invoke_result = invoke_ai_cli(
|
|
781
|
+
# Invoke AI CLI (retry transient timeout / rate-limit in-run, GH #97)
|
|
782
|
+
invoke_result = invoke_ai_cli(
|
|
783
|
+
config.ai_command, prompt, timeout=timeout, max_attempts=AI_SCAN_MAX_ATTEMPTS
|
|
784
|
+
)
|
|
780
785
|
|
|
781
786
|
if not invoke_result.success:
|
|
782
787
|
reason = (invoke_result.error or "unknown").strip().split("\n")[0][:200]
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"""In-memory IR between parse and render (GH #101, ADR-007).
|
|
2
|
+
|
|
3
|
+
``GraphBuffer`` is a per-run, in-memory intermediate representation of a
|
|
4
|
+
scanned project. It sits between the *parse* stage and the README *render*
|
|
5
|
+
stage, decoupling :class:`~codeindex.writers.SmartWriter` from the live
|
|
6
|
+
scan/parse loop.
|
|
7
|
+
|
|
8
|
+
Scope — Phase 1 (strangler step), deliberately minimal:
|
|
9
|
+
|
|
10
|
+
* Holds one :class:`DirNode` per indexed directory: the render inputs
|
|
11
|
+
(``level``, ``parse_results``, ``child_dirs``) the renderer currently
|
|
12
|
+
consumes.
|
|
13
|
+
* Provides :func:`render_directory` — the seam the eventual SmartWriter flip
|
|
14
|
+
will call. Rendering *from* the buffer must stay byte-identical to the
|
|
15
|
+
direct ``parse -> write_readme`` path (proven by
|
|
16
|
+
``tests/characterization/test_graphbuffer_equivalence.py``).
|
|
17
|
+
|
|
18
|
+
Deliberately **out of scope** for Phase 1:
|
|
19
|
+
|
|
20
|
+
* The global call / inheritance graph and the write-once graph-export
|
|
21
|
+
artifact. Per ADR-007 that substrate is gated on LoomGraph#30 and is not
|
|
22
|
+
built until that consumption spike comes back GREEN.
|
|
23
|
+
* Wiring into the production ``scan-all`` loop (the flip). Until the buffer
|
|
24
|
+
is the renderer's source of truth, paying its RAM cost in production buys
|
|
25
|
+
nothing, so it stays test-only for now.
|
|
26
|
+
|
|
27
|
+
This module is pure data plus a thin adapter: no AI, no I/O of its own beyond
|
|
28
|
+
what :meth:`SmartWriter.write_readme` already performs.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
from __future__ import annotations
|
|
32
|
+
|
|
33
|
+
from dataclasses import dataclass, field
|
|
34
|
+
from pathlib import Path
|
|
35
|
+
|
|
36
|
+
from .parser import ParseResult
|
|
37
|
+
from .writers import LevelType, SmartWriter, WriteResult
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@dataclass
|
|
41
|
+
class DirNode:
|
|
42
|
+
"""One indexed directory's render inputs, captured in the buffer.
|
|
43
|
+
|
|
44
|
+
Attributes mirror exactly the arguments
|
|
45
|
+
:meth:`SmartWriter.write_readme` consumes, so the buffer is a faithful,
|
|
46
|
+
lossless capture of the renderer's input at the moment of the scan.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
path: Path
|
|
50
|
+
level: LevelType
|
|
51
|
+
parse_results: list[ParseResult] = field(default_factory=list)
|
|
52
|
+
child_dirs: list[Path] = field(default_factory=list)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class GraphBuffer:
|
|
56
|
+
"""Per-run, in-memory map of directory -> :class:`DirNode`.
|
|
57
|
+
|
|
58
|
+
Insertion is single-threaded *by contract*: callers may produce
|
|
59
|
+
``parse_results`` with a parallel pool, but each directory is recorded
|
|
60
|
+
once from a single collecting thread. The buffer performs no locking.
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
def __init__(self) -> None:
|
|
64
|
+
self._dirs: dict[Path, DirNode] = {}
|
|
65
|
+
|
|
66
|
+
def record_directory(
|
|
67
|
+
self,
|
|
68
|
+
dir_path: Path,
|
|
69
|
+
level: LevelType,
|
|
70
|
+
parse_results: list[ParseResult],
|
|
71
|
+
child_dirs: list[Path],
|
|
72
|
+
) -> DirNode:
|
|
73
|
+
"""Capture one directory's render inputs and return the node."""
|
|
74
|
+
node = DirNode(
|
|
75
|
+
path=dir_path,
|
|
76
|
+
level=level,
|
|
77
|
+
parse_results=list(parse_results),
|
|
78
|
+
child_dirs=list(child_dirs),
|
|
79
|
+
)
|
|
80
|
+
self._dirs[dir_path] = node
|
|
81
|
+
return node
|
|
82
|
+
|
|
83
|
+
def get(self, dir_path: Path) -> DirNode | None:
|
|
84
|
+
"""Return the buffered node for ``dir_path`` (or ``None``)."""
|
|
85
|
+
return self._dirs.get(dir_path)
|
|
86
|
+
|
|
87
|
+
def directories(self) -> list[DirNode]:
|
|
88
|
+
"""Return all buffered nodes (insertion order)."""
|
|
89
|
+
return list(self._dirs.values())
|
|
90
|
+
|
|
91
|
+
def __len__(self) -> int:
|
|
92
|
+
return len(self._dirs)
|
|
93
|
+
|
|
94
|
+
def __contains__(self, dir_path: object) -> bool:
|
|
95
|
+
return dir_path in self._dirs
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def render_directory(
|
|
99
|
+
writer: SmartWriter,
|
|
100
|
+
node: DirNode,
|
|
101
|
+
output_file: str = "README_AI.md",
|
|
102
|
+
) -> WriteResult:
|
|
103
|
+
"""Render one directory's README from a buffered :class:`DirNode`.
|
|
104
|
+
|
|
105
|
+
This is the seam the eventual SmartWriter flip will use: the renderer's
|
|
106
|
+
inputs come from the buffer, not from a fresh inline parse. It must stay
|
|
107
|
+
byte-identical to ``writer.write_readme(... parse_results ...)`` on the
|
|
108
|
+
same inputs.
|
|
109
|
+
"""
|
|
110
|
+
return writer.write_readme(
|
|
111
|
+
dir_path=node.path,
|
|
112
|
+
parse_results=node.parse_results,
|
|
113
|
+
level=node.level,
|
|
114
|
+
child_dirs=node.child_dirs,
|
|
115
|
+
output_file=output_file,
|
|
116
|
+
)
|