kodit 0.3.4__tar.gz → 0.3.5__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.
Potentially problematic release.
This version of kodit might be problematic. Click here for more details.
- {kodit-0.3.4 → kodit-0.3.5}/PKG-INFO +2 -1
- {kodit-0.3.4 → kodit-0.3.5}/README.md +1 -0
- {kodit-0.3.4 → kodit-0.3.5}/docs/reference/configuration/index.md +28 -0
- {kodit-0.3.4 → kodit-0.3.5}/docs/reference/deployment/docker-compose.yaml +5 -0
- {kodit-0.3.4 → kodit-0.3.5}/docs/reference/deployment/kubernetes.yaml +6 -0
- {kodit-0.3.4 → kodit-0.3.5}/docs/reference/indexing/index.md +18 -0
- kodit-0.3.5/docs/reference/sync/index.md +79 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/_version.py +2 -2
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/app.py +23 -4
- kodit-0.3.5/src/kodit/application/services/sync_scheduler.py +128 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/cli.py +103 -28
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/config.py +15 -0
- kodit-0.3.5/tests/kodit/application/services/__init__.py +1 -0
- kodit-0.3.5/tests/kodit/application/services/test_sync_scheduler.py +396 -0
- {kodit-0.3.4 → kodit-0.3.5}/.claude/commands/debug.md +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/.claude/commands/new-requirement.md +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/.claude/commands/refactor.md +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/.claude/commands/update-docs.md +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/.claude/settings.json +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/.cursor/rules/kodit.mdc +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/.cursor/rules/style.mdc +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/.dockerignore +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/.github/CODE_OF_CONDUCT.md +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/.github/CONTRIBUTING.md +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/.github/dependabot.yml +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/.github/workflows/docker.yaml +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/.github/workflows/docs.yaml +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/.github/workflows/pull_request.yaml +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/.github/workflows/pypi-test.yaml +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/.github/workflows/pypi.yaml +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/.github/workflows/test.yaml +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/.gitignore +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/.python-version +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/.vscode/launch.json +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/.vscode/settings.json +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/CLAUDE.md +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/Dockerfile +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/LICENSE +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/alembic.ini +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/docs/MIGRATION_TO_INDEX_AGGREGATE.md +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/docs/_index.md +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/docs/demos/_index.md +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/docs/demos/go-simple-microservice/index.md +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/docs/demos/knock-knock-auth/index.md +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/docs/developer/index.md +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/docs/getting-started/_index.md +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/docs/getting-started/installation/index.md +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/docs/getting-started/integration/index.md +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/docs/getting-started/quick-start/index.md +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/docs/reference/_index.md +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/docs/reference/deployment/index.md +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/docs/reference/mcp/index.md +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/docs/reference/telemetry/index.md +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/pyproject.toml +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/.gitignore +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/application/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/application/factories/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/application/factories/code_indexing_factory.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/application/services/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/application/services/code_indexing_application_service.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/database.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/domain/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/domain/entities.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/domain/errors.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/domain/interfaces.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/domain/protocols.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/domain/services/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/domain/services/bm25_service.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/domain/services/embedding_service.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/domain/services/enrichment_service.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/domain/services/index_query_service.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/domain/services/index_service.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/domain/value_objects.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/bm25/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/bm25/bm25_factory.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/bm25/local_bm25_repository.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/bm25/vectorchord_bm25_repository.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/cloning/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/cloning/git/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/cloning/git/working_copy.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/cloning/metadata.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/embedding/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/embedding/embedding_factory.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/embedding/embedding_providers/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/embedding/embedding_providers/batching.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/embedding/embedding_providers/hash_embedding_provider.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/embedding/embedding_providers/local_embedding_provider.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/embedding/embedding_providers/openai_embedding_provider.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/embedding/local_vector_search_repository.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/embedding/vectorchord_vector_search_repository.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/enrichment/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/enrichment/enrichment_factory.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/enrichment/local_enrichment_provider.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/enrichment/null_enrichment_provider.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/enrichment/openai_enrichment_provider.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/git/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/git/git_utils.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/ignore/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/ignore/ignore_pattern_provider.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/indexing/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/indexing/auto_indexing_service.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/indexing/fusion_service.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/indexing/indexing_factory.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/mappers/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/mappers/index_mapper.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/slicing/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/slicing/language_detection_service.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/slicing/slicer.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/sqlalchemy/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/sqlalchemy/embedding_repository.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/sqlalchemy/entities.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/sqlalchemy/index_repository.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/ui/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/ui/progress.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/ui/spinner.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/log.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/mcp.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/middleware.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/migrations/README +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/migrations/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/migrations/env.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/migrations/script.py.mako +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/migrations/versions/4073b33f9436_add_file_processing_flag.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/migrations/versions/4552eb3f23ce_add_summary.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/migrations/versions/7c3bbc2ab32b_add_embeddings_table.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/migrations/versions/85155663351e_initial.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/migrations/versions/9e53ea8bb3b0_add_authors.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/migrations/versions/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/migrations/versions/c3f5137d30f5_index_all_the_things.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/reporting.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/utils/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/src/kodit/utils/path_utils.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/conftest.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/docker-smoke.sh +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/experiments/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/experiments/cline_prompt_tests/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/experiments/cline_prompt_tests/cline_prompt.txt +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/experiments/cline_prompt_tests/cline_prompt_test.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/application/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/application/test_code_indexing_application_service.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/cli_test.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/config_test.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/domain/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/domain/bm25_domain_service_test.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/domain/enrichment_domain_service_test.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/domain/entities_test.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/domain/services/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/domain/services/index_service_test.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/domain/test_embedding_service.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/domain/test_language_mapping.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/domain/test_multi_search_result.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/e2e.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/bm25/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/bm25/local_bm25_repository_test.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/bm25/vectorchord_bm25_repository_test.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/cloning/git_cloning/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/cloning/git_cloning/working_copy_test.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/embedding/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/embedding/embedding_factory_test.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/embedding/embedding_provider/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/embedding/embedding_provider/test_hash_embedding_provider.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/embedding/embedding_provider/test_local_embedding_provider.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/embedding/embedding_provider/test_openai_embedding_provider.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/embedding/test_batching.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/embedding/test_embedding_integration.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/embedding/test_local_vector_search_repository.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/embedding/test_vectorchord_vector_search_repository.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/enrichment/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/enrichment/enrichment_provider/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/enrichment/enrichment_provider/test_local_enrichment_provider.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/enrichment/enrichment_provider/test_null_enrichment_provider.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/enrichment/enrichment_provider/test_openai_enrichment_provider.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/enrichment/test_enrichment_factory.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/indexing/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/indexing/test_auto_indexing_service.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/mappers/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/mappers/test_index_mapper.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/c/main.c +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/c/models.c +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/c/models.h +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/c/utils.c +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/c/utils.h +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/cpp/main.cpp +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/cpp/models.cpp +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/cpp/models.hpp +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/cpp/utils.cpp +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/cpp/utils.hpp +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/csharp/Main.cs +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/csharp/Models.cs +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/csharp/Utils.cs +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/css/components.css +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/css/main.css +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/css/utilities.css +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/go/main.go +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/go/models.go +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/go/utils.go +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/html/components.html +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/html/forms.html +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/html/main.html +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/java/Main.java +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/java/Models.java +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/java/Utils.java +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/javascript/main.js +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/javascript/models.js +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/javascript/utils.js +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/python/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/python/main.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/python/models.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/python/utils.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/rust/main.rs +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/rust/models.rs +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/rust/utils.rs +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/slicer_test.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/snippets/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/snippets/csharp.cs +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/snippets/golang.go +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/snippets/javascript.js +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/snippets/knock_knock_server.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/snippets/python.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/snippets/typescript.tsx +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/sqlalchemy/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/sqlalchemy/test_embedding_repository.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/log_test.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/mcp_test.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/performance/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/performance/similarity.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/smoke.sh +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/utils/__init__.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/utils/test_path_utils.py +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/tests/vectorchord-smoke.sh +0 -0
- {kodit-0.3.4 → kodit-0.3.5}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kodit
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.5
|
|
4
4
|
Summary: Code indexing for better AI code generation
|
|
5
5
|
Project-URL: Homepage, https://docs.helixml.tech/kodit/
|
|
6
6
|
Project-URL: Documentation, https://docs.helixml.tech/kodit/
|
|
@@ -102,6 +102,7 @@ code. This index is used to build a snippet library, ready for ingestion into an
|
|
|
102
102
|
- **NEW in 0.3**: Index private repositories via a PAT
|
|
103
103
|
- **NEW in 0.3**: Improved progress monitoring and reporting during indexing
|
|
104
104
|
- **NEW in 0.3**: Advanced code slicing infrastructure with Tree-sitter parsing
|
|
105
|
+
- **NEW in 0.4**: Automatic periodic sync to keep indexes up-to-date
|
|
105
106
|
|
|
106
107
|
### MCP Server
|
|
107
108
|
|
|
@@ -49,6 +49,7 @@ code. This index is used to build a snippet library, ready for ingestion into an
|
|
|
49
49
|
- **NEW in 0.3**: Index private repositories via a PAT
|
|
50
50
|
- **NEW in 0.3**: Improved progress monitoring and reporting during indexing
|
|
51
51
|
- **NEW in 0.3**: Advanced code slicing infrastructure with Tree-sitter parsing
|
|
52
|
+
- **NEW in 0.4**: Automatic periodic sync to keep indexes up-to-date
|
|
52
53
|
|
|
53
54
|
### MCP Server
|
|
54
55
|
|
|
@@ -117,6 +117,34 @@ DB_URL=postgresql+asyncpg://postgres:mysecretpassword@localhost:5432/kodit
|
|
|
117
117
|
DEFAULT_SEARCH_PROVIDER=vectorchord
|
|
118
118
|
```
|
|
119
119
|
|
|
120
|
+
## Configuring Sync
|
|
121
|
+
|
|
122
|
+
### Periodic Sync Configuration
|
|
123
|
+
|
|
124
|
+
Kodit can automatically sync all indexed codebases at regular intervals to keep them up-to-date with the latest changes. This is especially useful for server deployments where multiple users are working with the same codebases.
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# Enable/disable periodic sync (default: true)
|
|
128
|
+
SYNC_PERIODIC_ENABLED=true
|
|
129
|
+
|
|
130
|
+
# Sync interval in seconds (default: 1800 = 30 minutes)
|
|
131
|
+
SYNC_PERIODIC_INTERVAL_SECONDS=1800
|
|
132
|
+
|
|
133
|
+
# Number of retry attempts for failed syncs (default: 3)
|
|
134
|
+
SYNC_PERIODIC_RETRY_ATTEMPTS=3
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
The sync scheduler will:
|
|
138
|
+
- Run automatically in the background when the server starts
|
|
139
|
+
- Sync all existing indexes at the configured interval
|
|
140
|
+
- Handle failures gracefully with retry logic
|
|
141
|
+
- Log detailed progress and results
|
|
142
|
+
- Shut down cleanly when the server stops
|
|
143
|
+
|
|
144
|
+
{{< info >}}
|
|
145
|
+
**Note**: The sync scheduler only syncs existing indexes. It does not create new indexes for repositories that haven't been indexed yet.
|
|
146
|
+
{{< /info >}}
|
|
147
|
+
|
|
120
148
|
## Configuring Enrichment
|
|
121
149
|
|
|
122
150
|
### Default Enrichment Provider
|
|
@@ -34,6 +34,11 @@ services:
|
|
|
34
34
|
AUTO_INDEXING_SOURCES_1_URI: https://github.com/fastapi/fastapi
|
|
35
35
|
AUTO_INDEXING_SOURCES_2_URI: https://github.com/helix-ml/kodit
|
|
36
36
|
|
|
37
|
+
# Sync configuration
|
|
38
|
+
SYNC_PERIODIC_ENABLED: true
|
|
39
|
+
SYNC_PERIODIC_INTERVAL_SECONDS: 1800 # 30 minutes
|
|
40
|
+
SYNC_PERIODIC_RETRY_ATTEMPTS: 3
|
|
41
|
+
|
|
37
42
|
vectorchord:
|
|
38
43
|
image: tensorchord/vchord-suite:pg17-20250601
|
|
39
44
|
environment:
|
|
@@ -81,6 +81,12 @@ spec:
|
|
|
81
81
|
value: "https://github.com/pydantic/pydantic"
|
|
82
82
|
- name: AUTO_INDEXING_SOURCES_1_URI
|
|
83
83
|
value: "https://github.com/helix-ml/kodit"
|
|
84
|
+
- name: SYNC_PERIODIC_ENABLED
|
|
85
|
+
value: "true"
|
|
86
|
+
- name: SYNC_PERIODIC_INTERVAL_SECONDS
|
|
87
|
+
value: "1800" # 30 minutes
|
|
88
|
+
- name: SYNC_PERIODIC_RETRY_ATTEMPTS
|
|
89
|
+
value: "3"
|
|
84
90
|
ports:
|
|
85
91
|
- containerPort: 8080
|
|
86
92
|
readinessProbe:
|
|
@@ -332,6 +332,24 @@ Kodit shows progress during indexing operations:
|
|
|
332
332
|
- Snippet extraction progress
|
|
333
333
|
- Index building progress (BM25, embeddings)
|
|
334
334
|
|
|
335
|
+
### Automatic Sync
|
|
336
|
+
|
|
337
|
+
For server deployments, Kodit includes an automatic sync scheduler that keeps your indexes up-to-date:
|
|
338
|
+
|
|
339
|
+
- **Periodic sync**: Automatically re-indexes all existing sources at configurable intervals
|
|
340
|
+
- **Failure handling**: Gracefully handles sync failures with retry logic
|
|
341
|
+
- **Background operation**: Runs in the background without blocking the MCP server
|
|
342
|
+
- **Configurable timing**: Adjust sync frequency based on your needs
|
|
343
|
+
|
|
344
|
+
See the [Sync Configuration](/kodit/reference/sync/index.md) documentation for detailed setup instructions.
|
|
345
|
+
|
|
346
|
+
The sync scheduler is enabled by default and will:
|
|
347
|
+
|
|
348
|
+
- Start automatically when you run `kodit serve`
|
|
349
|
+
- Sync all existing indexes every 30 minutes by default
|
|
350
|
+
- Log detailed progress and results
|
|
351
|
+
- Retry failed operations up to 3 times by default
|
|
352
|
+
|
|
335
353
|
## Privacy and Security
|
|
336
354
|
|
|
337
355
|
### Local Processing
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Sync
|
|
3
|
+
description: Automatic synchronization of indexed codebases
|
|
4
|
+
weight: 3
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Kodit includes an automatic sync scheduler that keeps your indexed codebases up-to-date with the latest changes. This is especially useful for server deployments where multiple users are working with the same codebases.
|
|
8
|
+
|
|
9
|
+
## How Sync Works
|
|
10
|
+
|
|
11
|
+
The sync scheduler runs as a background service that:
|
|
12
|
+
|
|
13
|
+
1. **Periodically checks** all existing indexes at a configurable interval
|
|
14
|
+
2. **Syncs each index** by pulling the latest changes from the source repository
|
|
15
|
+
3. **Updates the search index** with any new or modified code snippets
|
|
16
|
+
4. **Handles failures gracefully** with configurable retry attempts
|
|
17
|
+
5. **Logs detailed progress** for monitoring and debugging
|
|
18
|
+
|
|
19
|
+
## Configuration
|
|
20
|
+
|
|
21
|
+
### Environment Variables
|
|
22
|
+
|
|
23
|
+
Configure the sync scheduler using these environment variables:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Enable/disable periodic sync (default: true)
|
|
27
|
+
SYNC_PERIODIC_ENABLED=true
|
|
28
|
+
|
|
29
|
+
# Sync interval in seconds (default: 1800 = 30 minutes)
|
|
30
|
+
SYNC_PERIODIC_INTERVAL_SECONDS=1800
|
|
31
|
+
|
|
32
|
+
# Number of retry attempts for failed syncs (default: 3)
|
|
33
|
+
SYNC_PERIODIC_RETRY_ATTEMPTS=3
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Common Configuration Examples
|
|
37
|
+
|
|
38
|
+
#### Quick Development Setup
|
|
39
|
+
|
|
40
|
+
For rapid development with frequent changes:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
SYNC_PERIODIC_ENABLED=true
|
|
44
|
+
SYNC_PERIODIC_INTERVAL_SECONDS=300 # 5 minutes
|
|
45
|
+
SYNC_PERIODIC_RETRY_ATTEMPTS=1
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
#### Production Server Setup
|
|
49
|
+
|
|
50
|
+
For production deployments with stable codebases:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
SYNC_PERIODIC_ENABLED=true
|
|
54
|
+
SYNC_PERIODIC_INTERVAL_SECONDS=3600 # 1 hour
|
|
55
|
+
SYNC_PERIODIC_RETRY_ATTEMPTS=3
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
#### Disable Sync
|
|
59
|
+
|
|
60
|
+
If you prefer to sync manually:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
SYNC_PERIODIC_ENABLED=false
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Limitations
|
|
67
|
+
|
|
68
|
+
- **Only syncs existing indexes**: The sync scheduler does not create new indexes for repositories that haven't been indexed yet
|
|
69
|
+
- **Sequential processing**: Indexes are synced one at a time to avoid overwhelming the system
|
|
70
|
+
- **No conflict resolution**: If there are conflicts during sync, the operation may fail and require manual intervention
|
|
71
|
+
|
|
72
|
+
## Manual Sync
|
|
73
|
+
|
|
74
|
+
You can also manually sync indexes using the CLI:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# Sync all indexes
|
|
78
|
+
kodit index --sync
|
|
79
|
+
```
|
|
@@ -6,28 +6,47 @@ from contextlib import asynccontextmanager
|
|
|
6
6
|
from asgi_correlation_id import CorrelationIdMiddleware
|
|
7
7
|
from fastapi import FastAPI
|
|
8
8
|
|
|
9
|
+
from kodit.application.services.sync_scheduler import SyncSchedulerService
|
|
9
10
|
from kodit.config import AppContext
|
|
10
11
|
from kodit.infrastructure.indexing.auto_indexing_service import AutoIndexingService
|
|
11
12
|
from kodit.mcp import mcp
|
|
12
13
|
from kodit.middleware import ASGICancelledErrorMiddleware, logging_middleware
|
|
13
14
|
|
|
14
|
-
# Global
|
|
15
|
+
# Global services
|
|
15
16
|
_auto_indexing_service: AutoIndexingService | None = None
|
|
17
|
+
_sync_scheduler_service: SyncSchedulerService | None = None
|
|
16
18
|
|
|
17
19
|
|
|
18
20
|
@asynccontextmanager
|
|
19
21
|
async def app_lifespan(_: FastAPI) -> AsyncIterator[None]:
|
|
20
|
-
"""Manage application lifespan for auto-indexing."""
|
|
21
|
-
global _auto_indexing_service # noqa: PLW0603
|
|
22
|
-
|
|
22
|
+
"""Manage application lifespan for auto-indexing and sync."""
|
|
23
|
+
global _auto_indexing_service, _sync_scheduler_service # noqa: PLW0603
|
|
24
|
+
|
|
23
25
|
app_context = AppContext()
|
|
24
26
|
db = await app_context.get_db()
|
|
27
|
+
|
|
28
|
+
# Start auto-indexing service
|
|
25
29
|
_auto_indexing_service = AutoIndexingService(
|
|
26
30
|
app_context=app_context,
|
|
27
31
|
session_factory=db.session_factory,
|
|
28
32
|
)
|
|
29
33
|
await _auto_indexing_service.start_background_indexing()
|
|
34
|
+
|
|
35
|
+
# Start sync scheduler service
|
|
36
|
+
if app_context.sync.enabled:
|
|
37
|
+
_sync_scheduler_service = SyncSchedulerService(
|
|
38
|
+
app_context=app_context,
|
|
39
|
+
session_factory=db.session_factory,
|
|
40
|
+
)
|
|
41
|
+
_sync_scheduler_service.start_periodic_sync(
|
|
42
|
+
interval_seconds=app_context.sync.interval_seconds
|
|
43
|
+
)
|
|
44
|
+
|
|
30
45
|
yield
|
|
46
|
+
|
|
47
|
+
# Stop services
|
|
48
|
+
if _sync_scheduler_service:
|
|
49
|
+
await _sync_scheduler_service.stop_periodic_sync()
|
|
31
50
|
if _auto_indexing_service:
|
|
32
51
|
await _auto_indexing_service.stop()
|
|
33
52
|
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"""Service for scheduling periodic sync operations."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
from collections.abc import Callable
|
|
5
|
+
from contextlib import suppress
|
|
6
|
+
|
|
7
|
+
import structlog
|
|
8
|
+
from sqlalchemy.ext.asyncio import AsyncSession
|
|
9
|
+
|
|
10
|
+
from kodit.application.factories.code_indexing_factory import (
|
|
11
|
+
create_code_indexing_application_service,
|
|
12
|
+
)
|
|
13
|
+
from kodit.config import AppContext
|
|
14
|
+
from kodit.domain.services.index_query_service import IndexQueryService
|
|
15
|
+
from kodit.infrastructure.indexing.fusion_service import ReciprocalRankFusionService
|
|
16
|
+
from kodit.infrastructure.sqlalchemy.index_repository import SqlAlchemyIndexRepository
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class SyncSchedulerService:
|
|
20
|
+
"""Service for scheduling periodic sync operations."""
|
|
21
|
+
|
|
22
|
+
def __init__(
|
|
23
|
+
self,
|
|
24
|
+
app_context: AppContext,
|
|
25
|
+
session_factory: Callable[[], AsyncSession],
|
|
26
|
+
) -> None:
|
|
27
|
+
"""Initialize the sync scheduler service."""
|
|
28
|
+
self.app_context = app_context
|
|
29
|
+
self.session_factory = session_factory
|
|
30
|
+
self.log = structlog.get_logger(__name__)
|
|
31
|
+
self._sync_task: asyncio.Task | None = None
|
|
32
|
+
self._shutdown_event = asyncio.Event()
|
|
33
|
+
|
|
34
|
+
def start_periodic_sync(self, interval_seconds: float = 1800) -> None:
|
|
35
|
+
"""Start periodic sync of all indexes."""
|
|
36
|
+
self.log.info("Starting periodic sync", interval_seconds=interval_seconds)
|
|
37
|
+
|
|
38
|
+
self._sync_task = asyncio.create_task(self._sync_loop(interval_seconds))
|
|
39
|
+
|
|
40
|
+
async def stop_periodic_sync(self) -> None:
|
|
41
|
+
"""Stop the periodic sync task."""
|
|
42
|
+
self.log.info("Stopping periodic sync")
|
|
43
|
+
self._shutdown_event.set()
|
|
44
|
+
|
|
45
|
+
if self._sync_task and not self._sync_task.done():
|
|
46
|
+
self._sync_task.cancel()
|
|
47
|
+
with suppress(asyncio.CancelledError):
|
|
48
|
+
await self._sync_task
|
|
49
|
+
|
|
50
|
+
async def _sync_loop(self, interval_seconds: float) -> None:
|
|
51
|
+
"""Run the sync loop at the specified interval."""
|
|
52
|
+
while not self._shutdown_event.is_set():
|
|
53
|
+
try:
|
|
54
|
+
await self._perform_sync()
|
|
55
|
+
except Exception as e:
|
|
56
|
+
self.log.exception("Sync operation failed", error=e)
|
|
57
|
+
|
|
58
|
+
# Wait for the interval or until shutdown
|
|
59
|
+
try:
|
|
60
|
+
await asyncio.wait_for(
|
|
61
|
+
self._shutdown_event.wait(), timeout=interval_seconds
|
|
62
|
+
)
|
|
63
|
+
# If we reach here, shutdown was requested
|
|
64
|
+
break
|
|
65
|
+
except TimeoutError:
|
|
66
|
+
# Continue to next sync cycle
|
|
67
|
+
continue
|
|
68
|
+
|
|
69
|
+
async def _perform_sync(self) -> None:
|
|
70
|
+
"""Perform a sync operation on all indexes."""
|
|
71
|
+
self.log.info("Starting sync operation")
|
|
72
|
+
|
|
73
|
+
async with self.session_factory() as session:
|
|
74
|
+
# Create services
|
|
75
|
+
service = create_code_indexing_application_service(
|
|
76
|
+
app_context=self.app_context,
|
|
77
|
+
session=session,
|
|
78
|
+
)
|
|
79
|
+
index_query_service = IndexQueryService(
|
|
80
|
+
index_repository=SqlAlchemyIndexRepository(session=session),
|
|
81
|
+
fusion_service=ReciprocalRankFusionService(),
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
# Get all existing indexes
|
|
85
|
+
all_indexes = await index_query_service.list_indexes()
|
|
86
|
+
|
|
87
|
+
if not all_indexes:
|
|
88
|
+
self.log.info("No indexes found to sync")
|
|
89
|
+
return
|
|
90
|
+
|
|
91
|
+
self.log.info("Syncing indexes", count=len(all_indexes))
|
|
92
|
+
|
|
93
|
+
success_count = 0
|
|
94
|
+
failure_count = 0
|
|
95
|
+
|
|
96
|
+
# Sync each index
|
|
97
|
+
for index in all_indexes:
|
|
98
|
+
try:
|
|
99
|
+
self.log.info(
|
|
100
|
+
"Syncing index",
|
|
101
|
+
index_id=index.id,
|
|
102
|
+
source=str(index.source.working_copy.remote_uri),
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
await service.run_index(index, progress_callback=None)
|
|
106
|
+
success_count += 1
|
|
107
|
+
|
|
108
|
+
self.log.info(
|
|
109
|
+
"Index sync completed",
|
|
110
|
+
index_id=index.id,
|
|
111
|
+
source=str(index.source.working_copy.remote_uri),
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
except Exception as e:
|
|
115
|
+
failure_count += 1
|
|
116
|
+
self.log.exception(
|
|
117
|
+
"Index sync failed",
|
|
118
|
+
index_id=index.id,
|
|
119
|
+
source=str(index.source.working_copy.remote_uri),
|
|
120
|
+
error=e,
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
self.log.info(
|
|
124
|
+
"Sync operation completed",
|
|
125
|
+
total=len(all_indexes),
|
|
126
|
+
success=success_count,
|
|
127
|
+
failures=failure_count,
|
|
128
|
+
)
|
|
@@ -63,11 +63,105 @@ def cli(
|
|
|
63
63
|
ctx.obj = config
|
|
64
64
|
|
|
65
65
|
|
|
66
|
+
async def _handle_auto_index(
|
|
67
|
+
app_context: AppContext,
|
|
68
|
+
sources: list[str], # noqa: ARG001
|
|
69
|
+
) -> list[str]:
|
|
70
|
+
"""Handle auto-index option and return sources to process."""
|
|
71
|
+
log = structlog.get_logger(__name__)
|
|
72
|
+
log.info("Auto-indexing configuration", config=app_context.auto_indexing)
|
|
73
|
+
if not app_context.auto_indexing or not app_context.auto_indexing.sources:
|
|
74
|
+
click.echo("No auto-index sources configured.")
|
|
75
|
+
return []
|
|
76
|
+
auto_sources = app_context.auto_indexing.sources
|
|
77
|
+
click.echo(f"Auto-indexing {len(auto_sources)} configured sources...")
|
|
78
|
+
return [source.uri for source in auto_sources]
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
async def _handle_sync(
|
|
82
|
+
service: Any,
|
|
83
|
+
index_query_service: IndexQueryService,
|
|
84
|
+
sources: list[str],
|
|
85
|
+
) -> None:
|
|
86
|
+
"""Handle sync operation."""
|
|
87
|
+
log = structlog.get_logger(__name__)
|
|
88
|
+
log_event("kodit.cli.index.sync")
|
|
89
|
+
|
|
90
|
+
# Get all existing indexes
|
|
91
|
+
all_indexes = await index_query_service.list_indexes()
|
|
92
|
+
|
|
93
|
+
if not all_indexes:
|
|
94
|
+
click.echo("No existing indexes found to sync.")
|
|
95
|
+
return
|
|
96
|
+
|
|
97
|
+
# Filter indexes if specific sources are provided
|
|
98
|
+
indexes_to_sync = all_indexes
|
|
99
|
+
if sources:
|
|
100
|
+
# Filter indexes that match the provided sources
|
|
101
|
+
source_uris = set(sources)
|
|
102
|
+
indexes_to_sync = [
|
|
103
|
+
index for index in all_indexes
|
|
104
|
+
if str(index.source.working_copy.remote_uri) in source_uris
|
|
105
|
+
]
|
|
106
|
+
|
|
107
|
+
if not indexes_to_sync:
|
|
108
|
+
click.echo(
|
|
109
|
+
f"No indexes found for the specified sources: {', '.join(sources)}"
|
|
110
|
+
)
|
|
111
|
+
return
|
|
112
|
+
|
|
113
|
+
click.echo(f"Syncing {len(indexes_to_sync)} indexes...")
|
|
114
|
+
|
|
115
|
+
# Sync each index
|
|
116
|
+
for index in indexes_to_sync:
|
|
117
|
+
click.echo(f"Syncing: {index.source.working_copy.remote_uri}")
|
|
118
|
+
|
|
119
|
+
# Create progress callback for this sync operation
|
|
120
|
+
progress_callback = create_multi_stage_progress_callback()
|
|
121
|
+
|
|
122
|
+
try:
|
|
123
|
+
await service.run_index(index, progress_callback)
|
|
124
|
+
click.echo(f"✓ Sync completed: {index.source.working_copy.remote_uri}")
|
|
125
|
+
except Exception as e:
|
|
126
|
+
log.exception("Sync failed", index_id=index.id, error=e)
|
|
127
|
+
click.echo(
|
|
128
|
+
f"✗ Sync failed: {index.source.working_copy.remote_uri} - {e}"
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
async def _handle_list_indexes(index_query_service: IndexQueryService) -> None:
|
|
133
|
+
"""Handle listing all indexes."""
|
|
134
|
+
log_event("kodit.cli.index.list")
|
|
135
|
+
# No source specified, list all indexes
|
|
136
|
+
indexes = await index_query_service.list_indexes()
|
|
137
|
+
headers: list[str | Cell] = [
|
|
138
|
+
"ID",
|
|
139
|
+
"Created At",
|
|
140
|
+
"Updated At",
|
|
141
|
+
"Source",
|
|
142
|
+
"Num Snippets",
|
|
143
|
+
]
|
|
144
|
+
data = [
|
|
145
|
+
[
|
|
146
|
+
index.id,
|
|
147
|
+
index.created_at,
|
|
148
|
+
index.updated_at,
|
|
149
|
+
index.source.working_copy.remote_uri,
|
|
150
|
+
len(index.source.working_copy.files),
|
|
151
|
+
]
|
|
152
|
+
for index in indexes
|
|
153
|
+
]
|
|
154
|
+
click.echo(Table(headers=headers, data=data))
|
|
155
|
+
|
|
156
|
+
|
|
66
157
|
@cli.command()
|
|
67
158
|
@click.argument("sources", nargs=-1)
|
|
68
159
|
@click.option(
|
|
69
160
|
"--auto-index", is_flag=True, help="Index all configured auto-index sources"
|
|
70
161
|
)
|
|
162
|
+
@click.option(
|
|
163
|
+
"--sync", is_flag=True, help="Sync existing indexes with their remotes"
|
|
164
|
+
)
|
|
71
165
|
@with_app_context
|
|
72
166
|
@with_session
|
|
73
167
|
async def index(
|
|
@@ -76,8 +170,9 @@ async def index(
|
|
|
76
170
|
sources: list[str],
|
|
77
171
|
*, # Force keyword-only arguments
|
|
78
172
|
auto_index: bool,
|
|
173
|
+
sync: bool,
|
|
79
174
|
) -> None:
|
|
80
|
-
"""List indexes,
|
|
175
|
+
"""List indexes, index data sources, or sync existing indexes."""
|
|
81
176
|
log = structlog.get_logger(__name__)
|
|
82
177
|
service = create_code_indexing_application_service(
|
|
83
178
|
app_context=app_context,
|
|
@@ -89,36 +184,16 @@ async def index(
|
|
|
89
184
|
)
|
|
90
185
|
|
|
91
186
|
if auto_index:
|
|
92
|
-
|
|
93
|
-
if not
|
|
94
|
-
click.echo("No auto-index sources configured.")
|
|
187
|
+
sources = await _handle_auto_index(app_context, sources)
|
|
188
|
+
if not sources:
|
|
95
189
|
return
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
190
|
+
|
|
191
|
+
if sync:
|
|
192
|
+
await _handle_sync(service, index_query_service, sources)
|
|
193
|
+
return
|
|
99
194
|
|
|
100
195
|
if not sources:
|
|
101
|
-
|
|
102
|
-
# No source specified, list all indexes
|
|
103
|
-
indexes = await index_query_service.list_indexes()
|
|
104
|
-
headers: list[str | Cell] = [
|
|
105
|
-
"ID",
|
|
106
|
-
"Created At",
|
|
107
|
-
"Updated At",
|
|
108
|
-
"Source",
|
|
109
|
-
"Num Snippets",
|
|
110
|
-
]
|
|
111
|
-
data = [
|
|
112
|
-
[
|
|
113
|
-
index.id,
|
|
114
|
-
index.created_at,
|
|
115
|
-
index.updated_at,
|
|
116
|
-
index.source.working_copy.remote_uri,
|
|
117
|
-
len(index.source.working_copy.files),
|
|
118
|
-
]
|
|
119
|
-
for index in indexes
|
|
120
|
-
]
|
|
121
|
-
click.echo(Table(headers=headers, data=data))
|
|
196
|
+
await _handle_list_indexes(index_query_service)
|
|
122
197
|
return
|
|
123
198
|
# Handle source indexing
|
|
124
199
|
for source in sources:
|
|
@@ -81,6 +81,18 @@ class AutoIndexingConfig(BaseModel):
|
|
|
81
81
|
return v
|
|
82
82
|
|
|
83
83
|
|
|
84
|
+
class PeriodicSyncConfig(BaseModel):
|
|
85
|
+
"""Configuration for periodic/scheduled syncing."""
|
|
86
|
+
|
|
87
|
+
enabled: bool = Field(default=True, description="Enable periodic sync")
|
|
88
|
+
interval_seconds: float = Field(
|
|
89
|
+
default=1800, description="Interval between automatic syncs in seconds"
|
|
90
|
+
)
|
|
91
|
+
retry_attempts: int = Field(
|
|
92
|
+
default=3, description="Number of retry attempts for failed syncs"
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
|
|
84
96
|
class CustomAutoIndexingEnvSource(EnvSettingsSource):
|
|
85
97
|
"""Custom environment source for parsing AutoIndexingConfig."""
|
|
86
98
|
|
|
@@ -173,6 +185,9 @@ class AppContext(BaseSettings):
|
|
|
173
185
|
auto_indexing: AutoIndexingConfig | None = Field(
|
|
174
186
|
default=AutoIndexingConfig(), description="Auto-indexing configuration"
|
|
175
187
|
)
|
|
188
|
+
periodic_sync: PeriodicSyncConfig = Field(
|
|
189
|
+
default=PeriodicSyncConfig(), description="Periodic sync configuration"
|
|
190
|
+
)
|
|
176
191
|
_db: Database | None = None
|
|
177
192
|
|
|
178
193
|
def model_post_init(self, _: Any) -> None:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Test modules for application services."""
|