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.

Files changed (241) hide show
  1. {kodit-0.3.4 → kodit-0.3.5}/PKG-INFO +2 -1
  2. {kodit-0.3.4 → kodit-0.3.5}/README.md +1 -0
  3. {kodit-0.3.4 → kodit-0.3.5}/docs/reference/configuration/index.md +28 -0
  4. {kodit-0.3.4 → kodit-0.3.5}/docs/reference/deployment/docker-compose.yaml +5 -0
  5. {kodit-0.3.4 → kodit-0.3.5}/docs/reference/deployment/kubernetes.yaml +6 -0
  6. {kodit-0.3.4 → kodit-0.3.5}/docs/reference/indexing/index.md +18 -0
  7. kodit-0.3.5/docs/reference/sync/index.md +79 -0
  8. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/_version.py +2 -2
  9. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/app.py +23 -4
  10. kodit-0.3.5/src/kodit/application/services/sync_scheduler.py +128 -0
  11. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/cli.py +103 -28
  12. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/config.py +15 -0
  13. kodit-0.3.5/tests/kodit/application/services/__init__.py +1 -0
  14. kodit-0.3.5/tests/kodit/application/services/test_sync_scheduler.py +396 -0
  15. {kodit-0.3.4 → kodit-0.3.5}/.claude/commands/debug.md +0 -0
  16. {kodit-0.3.4 → kodit-0.3.5}/.claude/commands/new-requirement.md +0 -0
  17. {kodit-0.3.4 → kodit-0.3.5}/.claude/commands/refactor.md +0 -0
  18. {kodit-0.3.4 → kodit-0.3.5}/.claude/commands/update-docs.md +0 -0
  19. {kodit-0.3.4 → kodit-0.3.5}/.claude/settings.json +0 -0
  20. {kodit-0.3.4 → kodit-0.3.5}/.cursor/rules/kodit.mdc +0 -0
  21. {kodit-0.3.4 → kodit-0.3.5}/.cursor/rules/style.mdc +0 -0
  22. {kodit-0.3.4 → kodit-0.3.5}/.dockerignore +0 -0
  23. {kodit-0.3.4 → kodit-0.3.5}/.github/CODE_OF_CONDUCT.md +0 -0
  24. {kodit-0.3.4 → kodit-0.3.5}/.github/CONTRIBUTING.md +0 -0
  25. {kodit-0.3.4 → kodit-0.3.5}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  26. {kodit-0.3.4 → kodit-0.3.5}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  27. {kodit-0.3.4 → kodit-0.3.5}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  28. {kodit-0.3.4 → kodit-0.3.5}/.github/dependabot.yml +0 -0
  29. {kodit-0.3.4 → kodit-0.3.5}/.github/workflows/docker.yaml +0 -0
  30. {kodit-0.3.4 → kodit-0.3.5}/.github/workflows/docs.yaml +0 -0
  31. {kodit-0.3.4 → kodit-0.3.5}/.github/workflows/pull_request.yaml +0 -0
  32. {kodit-0.3.4 → kodit-0.3.5}/.github/workflows/pypi-test.yaml +0 -0
  33. {kodit-0.3.4 → kodit-0.3.5}/.github/workflows/pypi.yaml +0 -0
  34. {kodit-0.3.4 → kodit-0.3.5}/.github/workflows/test.yaml +0 -0
  35. {kodit-0.3.4 → kodit-0.3.5}/.gitignore +0 -0
  36. {kodit-0.3.4 → kodit-0.3.5}/.python-version +0 -0
  37. {kodit-0.3.4 → kodit-0.3.5}/.vscode/launch.json +0 -0
  38. {kodit-0.3.4 → kodit-0.3.5}/.vscode/settings.json +0 -0
  39. {kodit-0.3.4 → kodit-0.3.5}/CLAUDE.md +0 -0
  40. {kodit-0.3.4 → kodit-0.3.5}/Dockerfile +0 -0
  41. {kodit-0.3.4 → kodit-0.3.5}/LICENSE +0 -0
  42. {kodit-0.3.4 → kodit-0.3.5}/alembic.ini +0 -0
  43. {kodit-0.3.4 → kodit-0.3.5}/docs/MIGRATION_TO_INDEX_AGGREGATE.md +0 -0
  44. {kodit-0.3.4 → kodit-0.3.5}/docs/_index.md +0 -0
  45. {kodit-0.3.4 → kodit-0.3.5}/docs/demos/_index.md +0 -0
  46. {kodit-0.3.4 → kodit-0.3.5}/docs/demos/go-simple-microservice/index.md +0 -0
  47. {kodit-0.3.4 → kodit-0.3.5}/docs/demos/knock-knock-auth/index.md +0 -0
  48. {kodit-0.3.4 → kodit-0.3.5}/docs/developer/index.md +0 -0
  49. {kodit-0.3.4 → kodit-0.3.5}/docs/getting-started/_index.md +0 -0
  50. {kodit-0.3.4 → kodit-0.3.5}/docs/getting-started/installation/index.md +0 -0
  51. {kodit-0.3.4 → kodit-0.3.5}/docs/getting-started/integration/index.md +0 -0
  52. {kodit-0.3.4 → kodit-0.3.5}/docs/getting-started/quick-start/index.md +0 -0
  53. {kodit-0.3.4 → kodit-0.3.5}/docs/reference/_index.md +0 -0
  54. {kodit-0.3.4 → kodit-0.3.5}/docs/reference/deployment/index.md +0 -0
  55. {kodit-0.3.4 → kodit-0.3.5}/docs/reference/mcp/index.md +0 -0
  56. {kodit-0.3.4 → kodit-0.3.5}/docs/reference/telemetry/index.md +0 -0
  57. {kodit-0.3.4 → kodit-0.3.5}/pyproject.toml +0 -0
  58. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/.gitignore +0 -0
  59. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/__init__.py +0 -0
  60. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/application/__init__.py +0 -0
  61. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/application/factories/__init__.py +0 -0
  62. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/application/factories/code_indexing_factory.py +0 -0
  63. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/application/services/__init__.py +0 -0
  64. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/application/services/code_indexing_application_service.py +0 -0
  65. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/database.py +0 -0
  66. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/domain/__init__.py +0 -0
  67. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/domain/entities.py +0 -0
  68. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/domain/errors.py +0 -0
  69. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/domain/interfaces.py +0 -0
  70. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/domain/protocols.py +0 -0
  71. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/domain/services/__init__.py +0 -0
  72. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/domain/services/bm25_service.py +0 -0
  73. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/domain/services/embedding_service.py +0 -0
  74. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/domain/services/enrichment_service.py +0 -0
  75. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/domain/services/index_query_service.py +0 -0
  76. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/domain/services/index_service.py +0 -0
  77. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/domain/value_objects.py +0 -0
  78. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/__init__.py +0 -0
  79. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/bm25/__init__.py +0 -0
  80. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/bm25/bm25_factory.py +0 -0
  81. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/bm25/local_bm25_repository.py +0 -0
  82. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/bm25/vectorchord_bm25_repository.py +0 -0
  83. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/cloning/__init__.py +0 -0
  84. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/cloning/git/__init__.py +0 -0
  85. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/cloning/git/working_copy.py +0 -0
  86. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/cloning/metadata.py +0 -0
  87. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/embedding/__init__.py +0 -0
  88. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/embedding/embedding_factory.py +0 -0
  89. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/embedding/embedding_providers/__init__.py +0 -0
  90. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/embedding/embedding_providers/batching.py +0 -0
  91. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/embedding/embedding_providers/hash_embedding_provider.py +0 -0
  92. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/embedding/embedding_providers/local_embedding_provider.py +0 -0
  93. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/embedding/embedding_providers/openai_embedding_provider.py +0 -0
  94. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/embedding/local_vector_search_repository.py +0 -0
  95. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/embedding/vectorchord_vector_search_repository.py +0 -0
  96. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/enrichment/__init__.py +0 -0
  97. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/enrichment/enrichment_factory.py +0 -0
  98. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/enrichment/local_enrichment_provider.py +0 -0
  99. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/enrichment/null_enrichment_provider.py +0 -0
  100. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/enrichment/openai_enrichment_provider.py +0 -0
  101. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/git/__init__.py +0 -0
  102. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/git/git_utils.py +0 -0
  103. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/ignore/__init__.py +0 -0
  104. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/ignore/ignore_pattern_provider.py +0 -0
  105. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/indexing/__init__.py +0 -0
  106. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/indexing/auto_indexing_service.py +0 -0
  107. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/indexing/fusion_service.py +0 -0
  108. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/indexing/indexing_factory.py +0 -0
  109. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/mappers/__init__.py +0 -0
  110. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/mappers/index_mapper.py +0 -0
  111. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/slicing/__init__.py +0 -0
  112. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/slicing/language_detection_service.py +0 -0
  113. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/slicing/slicer.py +0 -0
  114. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/sqlalchemy/__init__.py +0 -0
  115. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/sqlalchemy/embedding_repository.py +0 -0
  116. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/sqlalchemy/entities.py +0 -0
  117. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/sqlalchemy/index_repository.py +0 -0
  118. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/ui/__init__.py +0 -0
  119. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/ui/progress.py +0 -0
  120. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/infrastructure/ui/spinner.py +0 -0
  121. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/log.py +0 -0
  122. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/mcp.py +0 -0
  123. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/middleware.py +0 -0
  124. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/migrations/README +0 -0
  125. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/migrations/__init__.py +0 -0
  126. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/migrations/env.py +0 -0
  127. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/migrations/script.py.mako +0 -0
  128. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/migrations/versions/4073b33f9436_add_file_processing_flag.py +0 -0
  129. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/migrations/versions/4552eb3f23ce_add_summary.py +0 -0
  130. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/migrations/versions/7c3bbc2ab32b_add_embeddings_table.py +0 -0
  131. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/migrations/versions/85155663351e_initial.py +0 -0
  132. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/migrations/versions/9e53ea8bb3b0_add_authors.py +0 -0
  133. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/migrations/versions/__init__.py +0 -0
  134. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/migrations/versions/c3f5137d30f5_index_all_the_things.py +0 -0
  135. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/reporting.py +0 -0
  136. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/utils/__init__.py +0 -0
  137. {kodit-0.3.4 → kodit-0.3.5}/src/kodit/utils/path_utils.py +0 -0
  138. {kodit-0.3.4 → kodit-0.3.5}/tests/__init__.py +0 -0
  139. {kodit-0.3.4 → kodit-0.3.5}/tests/conftest.py +0 -0
  140. {kodit-0.3.4 → kodit-0.3.5}/tests/docker-smoke.sh +0 -0
  141. {kodit-0.3.4 → kodit-0.3.5}/tests/experiments/__init__.py +0 -0
  142. {kodit-0.3.4 → kodit-0.3.5}/tests/experiments/cline_prompt_tests/__init__.py +0 -0
  143. {kodit-0.3.4 → kodit-0.3.5}/tests/experiments/cline_prompt_tests/cline_prompt.txt +0 -0
  144. {kodit-0.3.4 → kodit-0.3.5}/tests/experiments/cline_prompt_tests/cline_prompt_test.py +0 -0
  145. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/__init__.py +0 -0
  146. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/application/__init__.py +0 -0
  147. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/application/test_code_indexing_application_service.py +0 -0
  148. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/cli_test.py +0 -0
  149. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/config_test.py +0 -0
  150. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/domain/__init__.py +0 -0
  151. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/domain/bm25_domain_service_test.py +0 -0
  152. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/domain/enrichment_domain_service_test.py +0 -0
  153. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/domain/entities_test.py +0 -0
  154. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/domain/services/__init__.py +0 -0
  155. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/domain/services/index_service_test.py +0 -0
  156. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/domain/test_embedding_service.py +0 -0
  157. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/domain/test_language_mapping.py +0 -0
  158. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/domain/test_multi_search_result.py +0 -0
  159. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/e2e.py +0 -0
  160. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/__init__.py +0 -0
  161. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/bm25/__init__.py +0 -0
  162. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/bm25/local_bm25_repository_test.py +0 -0
  163. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/bm25/vectorchord_bm25_repository_test.py +0 -0
  164. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/cloning/git_cloning/__init__.py +0 -0
  165. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/cloning/git_cloning/working_copy_test.py +0 -0
  166. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/embedding/__init__.py +0 -0
  167. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/embedding/embedding_factory_test.py +0 -0
  168. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/embedding/embedding_provider/__init__.py +0 -0
  169. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/embedding/embedding_provider/test_hash_embedding_provider.py +0 -0
  170. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/embedding/embedding_provider/test_local_embedding_provider.py +0 -0
  171. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/embedding/embedding_provider/test_openai_embedding_provider.py +0 -0
  172. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/embedding/test_batching.py +0 -0
  173. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/embedding/test_embedding_integration.py +0 -0
  174. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/embedding/test_local_vector_search_repository.py +0 -0
  175. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/embedding/test_vectorchord_vector_search_repository.py +0 -0
  176. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/enrichment/__init__.py +0 -0
  177. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/enrichment/enrichment_provider/__init__.py +0 -0
  178. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/enrichment/enrichment_provider/test_local_enrichment_provider.py +0 -0
  179. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/enrichment/enrichment_provider/test_null_enrichment_provider.py +0 -0
  180. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/enrichment/enrichment_provider/test_openai_enrichment_provider.py +0 -0
  181. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/enrichment/test_enrichment_factory.py +0 -0
  182. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/indexing/__init__.py +0 -0
  183. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/indexing/test_auto_indexing_service.py +0 -0
  184. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/mappers/__init__.py +0 -0
  185. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/mappers/test_index_mapper.py +0 -0
  186. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/__init__.py +0 -0
  187. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/__init__.py +0 -0
  188. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/c/main.c +0 -0
  189. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/c/models.c +0 -0
  190. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/c/models.h +0 -0
  191. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/c/utils.c +0 -0
  192. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/c/utils.h +0 -0
  193. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/cpp/main.cpp +0 -0
  194. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/cpp/models.cpp +0 -0
  195. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/cpp/models.hpp +0 -0
  196. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/cpp/utils.cpp +0 -0
  197. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/cpp/utils.hpp +0 -0
  198. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/csharp/Main.cs +0 -0
  199. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/csharp/Models.cs +0 -0
  200. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/csharp/Utils.cs +0 -0
  201. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/css/components.css +0 -0
  202. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/css/main.css +0 -0
  203. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/css/utilities.css +0 -0
  204. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/go/main.go +0 -0
  205. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/go/models.go +0 -0
  206. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/go/utils.go +0 -0
  207. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/html/components.html +0 -0
  208. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/html/forms.html +0 -0
  209. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/html/main.html +0 -0
  210. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/java/Main.java +0 -0
  211. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/java/Models.java +0 -0
  212. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/java/Utils.java +0 -0
  213. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/javascript/main.js +0 -0
  214. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/javascript/models.js +0 -0
  215. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/javascript/utils.js +0 -0
  216. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/python/__init__.py +0 -0
  217. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/python/main.py +0 -0
  218. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/python/models.py +0 -0
  219. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/python/utils.py +0 -0
  220. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/rust/main.rs +0 -0
  221. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/rust/models.rs +0 -0
  222. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/data/rust/utils.rs +0 -0
  223. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/slicing/slicer_test.py +0 -0
  224. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/snippets/__init__.py +0 -0
  225. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/snippets/csharp.cs +0 -0
  226. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/snippets/golang.go +0 -0
  227. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/snippets/javascript.js +0 -0
  228. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/snippets/knock_knock_server.py +0 -0
  229. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/snippets/python.py +0 -0
  230. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/snippets/typescript.tsx +0 -0
  231. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/sqlalchemy/__init__.py +0 -0
  232. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/infrastructure/sqlalchemy/test_embedding_repository.py +0 -0
  233. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/log_test.py +0 -0
  234. {kodit-0.3.4 → kodit-0.3.5}/tests/kodit/mcp_test.py +0 -0
  235. {kodit-0.3.4 → kodit-0.3.5}/tests/performance/__init__.py +0 -0
  236. {kodit-0.3.4 → kodit-0.3.5}/tests/performance/similarity.py +0 -0
  237. {kodit-0.3.4 → kodit-0.3.5}/tests/smoke.sh +0 -0
  238. {kodit-0.3.4 → kodit-0.3.5}/tests/utils/__init__.py +0 -0
  239. {kodit-0.3.4 → kodit-0.3.5}/tests/utils/test_path_utils.py +0 -0
  240. {kodit-0.3.4 → kodit-0.3.5}/tests/vectorchord-smoke.sh +0 -0
  241. {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.4
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
+ ```
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.3.4'
21
- __version_tuple__ = version_tuple = (0, 3, 4)
20
+ __version__ = version = '0.3.5'
21
+ __version_tuple__ = version_tuple = (0, 3, 5)
@@ -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 auto-indexing service
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
- # Start auto-indexing service
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, or index data sources."""
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
- log.info("Auto-indexing configuration", config=app_context.auto_indexing)
93
- if not app_context.auto_indexing or not app_context.auto_indexing.sources:
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
- auto_sources = app_context.auto_indexing.sources
97
- click.echo(f"Auto-indexing {len(auto_sources)} configured sources...")
98
- sources = [source.uri for source in auto_sources]
190
+
191
+ if sync:
192
+ await _handle_sync(service, index_query_service, sources)
193
+ return
99
194
 
100
195
  if not sources:
101
- log_event("kodit.cli.index.list")
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."""