etki 0.1.0a2__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.
Files changed (346) hide show
  1. etki-0.1.0a2/.claude/launch.json +14 -0
  2. etki-0.1.0a2/.dockerignore +12 -0
  3. etki-0.1.0a2/.env.example +41 -0
  4. etki-0.1.0a2/.github/ISSUE_TEMPLATE/adapter_proposal.yml +41 -0
  5. etki-0.1.0a2/.github/ISSUE_TEMPLATE/bug_report.yml +35 -0
  6. etki-0.1.0a2/.github/ISSUE_TEMPLATE/config.yml +8 -0
  7. etki-0.1.0a2/.github/ISSUE_TEMPLATE/feature_request.yml +22 -0
  8. etki-0.1.0a2/.github/PULL_REQUEST_TEMPLATE.md +14 -0
  9. etki-0.1.0a2/.github/workflows/ci.yml +58 -0
  10. etki-0.1.0a2/.github/workflows/docs.yml +26 -0
  11. etki-0.1.0a2/.github/workflows/release.yml +129 -0
  12. etki-0.1.0a2/.gitignore +32 -0
  13. etki-0.1.0a2/CHANGELOG.md +248 -0
  14. etki-0.1.0a2/CLAUDE.md +157 -0
  15. etki-0.1.0a2/CODE_OF_CONDUCT.md +67 -0
  16. etki-0.1.0a2/CONTRIBUTING.md +92 -0
  17. etki-0.1.0a2/Dockerfile +38 -0
  18. etki-0.1.0a2/Etki_Gelistirme_Plani.md +298 -0
  19. etki-0.1.0a2/Etki_GraphRAG_Hafiza_Plani.md +219 -0
  20. etki-0.1.0a2/Etki_Mimari_Dokuman.md +608 -0
  21. etki-0.1.0a2/Etki_Plugin_Gelistirme_Plani.md +277 -0
  22. etki-0.1.0a2/Etki_Plugin_Marketplace_Plani.md +198 -0
  23. etki-0.1.0a2/LICENSE +201 -0
  24. etki-0.1.0a2/PKG-INFO +245 -0
  25. etki-0.1.0a2/README.md +210 -0
  26. etki-0.1.0a2/SECURITY.md +22 -0
  27. etki-0.1.0a2/alembic/env.py +56 -0
  28. etki-0.1.0a2/alembic/script.py.mako +26 -0
  29. etki-0.1.0a2/alembic/versions/b41c7a2e9f10_user_projects.py +31 -0
  30. etki-0.1.0a2/alembic/versions/dfe7abcdd649_initial_schema.py +106 -0
  31. etki-0.1.0a2/alembic.ini +40 -0
  32. etki-0.1.0a2/config/connectors.deps.yaml +17 -0
  33. etki-0.1.0a2/config/connectors.docker.yaml +17 -0
  34. etki-0.1.0a2/config/connectors.etkibench.yaml +19 -0
  35. etki-0.1.0a2/config/connectors.example.yaml +25 -0
  36. etki-0.1.0a2/config/connectors.heldout.yaml +16 -0
  37. etki-0.1.0a2/config/connectors.shop.yaml +18 -0
  38. etki-0.1.0a2/config/domains/_common.hints.yaml +6 -0
  39. etki-0.1.0a2/config/domains/entegrasyon.md +9 -0
  40. etki-0.1.0a2/config/domains/eticaret.hints.yaml +5 -0
  41. etki-0.1.0a2/config/domains/eticaret.md +8 -0
  42. etki-0.1.0a2/config/domains/kurumsal.md +8 -0
  43. etki-0.1.0a2/config/domains/saglik.md +8 -0
  44. etki-0.1.0a2/config/projects.demo.yaml +24 -0
  45. etki-0.1.0a2/config/projects.yaml +75 -0
  46. etki-0.1.0a2/docker-compose.demo.yml +24 -0
  47. etki-0.1.0a2/docker-compose.yml +42 -0
  48. etki-0.1.0a2/docs/DEMO_TALEPLER.md +94 -0
  49. etki-0.1.0a2/docs/KVKK.md +42 -0
  50. etki-0.1.0a2/docs/MCP.md +75 -0
  51. etki-0.1.0a2/docs/RUNBOOK.md +166 -0
  52. etki-0.1.0a2/docs/adapters.md +246 -0
  53. etki-0.1.0a2/docs/compliance.md +101 -0
  54. etki-0.1.0a2/docs/concepts.md +140 -0
  55. etki-0.1.0a2/docs/demo.gif +0 -0
  56. etki-0.1.0a2/docs/getting-started.md +77 -0
  57. etki-0.1.0a2/docs/index.md +38 -0
  58. etki-0.1.0a2/docs/memory.md +140 -0
  59. etki-0.1.0a2/docs/writing-an-adapter.md +240 -0
  60. etki-0.1.0a2/etki/__init__.py +3 -0
  61. etki-0.1.0a2/etki/adapters/__init__.py +0 -0
  62. etki-0.1.0a2/etki/adapters/ast_code_index.py +131 -0
  63. etki-0.1.0a2/etki/adapters/azure_devops_work_item.py +101 -0
  64. etki-0.1.0a2/etki/adapters/code_index.py +246 -0
  65. etki-0.1.0a2/etki/adapters/composite_document.py +44 -0
  66. etki-0.1.0a2/etki/adapters/confluence_document.py +113 -0
  67. etki-0.1.0a2/etki/adapters/embedding_openai.py +48 -0
  68. etki-0.1.0a2/etki/adapters/fakes/__init__.py +0 -0
  69. etki-0.1.0a2/etki/adapters/fakes/code_repo.py +42 -0
  70. etki-0.1.0a2/etki/adapters/fakes/document.py +30 -0
  71. etki-0.1.0a2/etki/adapters/fakes/seed.py +156 -0
  72. etki-0.1.0a2/etki/adapters/fakes/work_item.py +40 -0
  73. etki-0.1.0a2/etki/adapters/file_work_item.py +65 -0
  74. etki-0.1.0a2/etki/adapters/filesystem_document.py +50 -0
  75. etki-0.1.0a2/etki/adapters/filesystem_wiki.py +438 -0
  76. etki-0.1.0a2/etki/adapters/git_churn.py +60 -0
  77. etki-0.1.0a2/etki/adapters/git_clone.py +80 -0
  78. etki-0.1.0a2/etki/adapters/gitlab_work_item.py +103 -0
  79. etki-0.1.0a2/etki/adapters/glpi_work_item.py +129 -0
  80. etki-0.1.0a2/etki/adapters/graphify_code_repo.py +221 -0
  81. etki-0.1.0a2/etki/adapters/jira_work_item.py +82 -0
  82. etki-0.1.0a2/etki/adapters/joern_code_repo.py +65 -0
  83. etki-0.1.0a2/etki/adapters/linear_work_item.py +108 -0
  84. etki-0.1.0a2/etki/adapters/llm_anthropic.py +61 -0
  85. etki-0.1.0a2/etki/adapters/llm_openai.py +49 -0
  86. etki-0.1.0a2/etki/adapters/manifests.py +237 -0
  87. etki-0.1.0a2/etki/adapters/package_download.py +399 -0
  88. etki-0.1.0a2/etki/adapters/package_registries.py +251 -0
  89. etki-0.1.0a2/etki/adapters/redmine_work_item.py +89 -0
  90. etki-0.1.0a2/etki/adapters/registry.py +269 -0
  91. etki-0.1.0a2/etki/adapters/rerank_tei.py +41 -0
  92. etki-0.1.0a2/etki/adapters/sharepoint_document.py +125 -0
  93. etki-0.1.0a2/etki/agent.py +260 -0
  94. etki-0.1.0a2/etki/api/__init__.py +0 -0
  95. etki-0.1.0a2/etki/api/app.py +296 -0
  96. etki-0.1.0a2/etki/api/context.py +356 -0
  97. etki-0.1.0a2/etki/api/schemas.py +19 -0
  98. etki-0.1.0a2/etki/api/security.py +117 -0
  99. etki-0.1.0a2/etki/api/static/app.css +342 -0
  100. etki-0.1.0a2/etki/api/static/htmx.min.js +1 -0
  101. etki-0.1.0a2/etki/api/static/pmo.css +286 -0
  102. etki-0.1.0a2/etki/api/templates/analyze_results.html +34 -0
  103. etki-0.1.0a2/etki/api/templates/ara.html +29 -0
  104. etki-0.1.0a2/etki/api/templates/ask_llm_result.html +10 -0
  105. etki-0.1.0a2/etki/api/templates/ask_turn.html +55 -0
  106. etki-0.1.0a2/etki/api/templates/ayarlar.html +152 -0
  107. etki-0.1.0a2/etki/api/templates/baseline_timeline.html +52 -0
  108. etki-0.1.0a2/etki/api/templates/cards.html +18 -0
  109. etki-0.1.0a2/etki/api/templates/case_chat.html +6 -0
  110. etki-0.1.0a2/etki/api/templates/case_flow.html +39 -0
  111. etki-0.1.0a2/etki/api/templates/casefile.html +11 -0
  112. etki-0.1.0a2/etki/api/templates/casefile_body.html +88 -0
  113. etki-0.1.0a2/etki/api/templates/clause_detail.html +59 -0
  114. etki-0.1.0a2/etki/api/templates/deps_diff.html +84 -0
  115. etki-0.1.0a2/etki/api/templates/deps_online.html +13 -0
  116. etki-0.1.0a2/etki/api/templates/document_preview.html +13 -0
  117. etki-0.1.0a2/etki/api/templates/index_history.html +13 -0
  118. etki-0.1.0a2/etki/api/templates/login.html +98 -0
  119. etki-0.1.0a2/etki/api/templates/macros.html +159 -0
  120. etki-0.1.0a2/etki/api/templates/pmo_base.html +288 -0
  121. etki-0.1.0a2/etki/api/templates/pool_breakdown.html +16 -0
  122. etki-0.1.0a2/etki/api/templates/pre_analysis_saved.html +2 -0
  123. etki-0.1.0a2/etki/api/templates/project_ask.html +27 -0
  124. etki-0.1.0a2/etki/api/templates/project_detail.html +274 -0
  125. etki-0.1.0a2/etki/api/templates/project_files.html +123 -0
  126. etki-0.1.0a2/etki/api/templates/project_hafiza.html +62 -0
  127. etki-0.1.0a2/etki/api/templates/project_history.html +37 -0
  128. etki-0.1.0a2/etki/api/templates/project_modules.html +57 -0
  129. etki-0.1.0a2/etki/api/templates/project_sankey.html +35 -0
  130. etki-0.1.0a2/etki/api/templates/project_triyaj.html +58 -0
  131. etki-0.1.0a2/etki/api/templates/projects.html +70 -0
  132. etki-0.1.0a2/etki/api/templates/triage_result.html +62 -0
  133. etki-0.1.0a2/etki/api/templates/yeni_proje.html +31 -0
  134. etki-0.1.0a2/etki/api/web.py +2258 -0
  135. etki-0.1.0a2/etki/auth.py +236 -0
  136. etki-0.1.0a2/etki/config.py +303 -0
  137. etki-0.1.0a2/etki/core/__init__.py +0 -0
  138. etki-0.1.0a2/etki/core/enums.py +55 -0
  139. etki-0.1.0a2/etki/core/models.py +269 -0
  140. etki-0.1.0a2/etki/core/ports.py +212 -0
  141. etki-0.1.0a2/etki/core/text.py +140 -0
  142. etki-0.1.0a2/etki/domains.py +69 -0
  143. etki-0.1.0a2/etki/engine/__init__.py +0 -0
  144. etki-0.1.0a2/etki/engine/estimation.py +141 -0
  145. etki-0.1.0a2/etki/engine/triage.py +1316 -0
  146. etki-0.1.0a2/etki/engine/understanding.py +249 -0
  147. etki-0.1.0a2/etki/extraction/__init__.py +0 -0
  148. etki-0.1.0a2/etki/extraction/parsers.py +85 -0
  149. etki-0.1.0a2/etki/extraction/scope_extractor.py +257 -0
  150. etki-0.1.0a2/etki/graphquery.py +382 -0
  151. etki-0.1.0a2/etki/hitl/__init__.py +0 -0
  152. etki-0.1.0a2/etki/hitl/ingest.py +160 -0
  153. etki-0.1.0a2/etki/hitl/service.py +197 -0
  154. etki-0.1.0a2/etki/i18n/__init__.py +67 -0
  155. etki-0.1.0a2/etki/i18n/catalog.py +1907 -0
  156. etki-0.1.0a2/etki/index_tools.py +266 -0
  157. etki-0.1.0a2/etki/indexing/__init__.py +0 -0
  158. etki-0.1.0a2/etki/indexing/__main__.py +45 -0
  159. etki-0.1.0a2/etki/indexing/engine.py +95 -0
  160. etki-0.1.0a2/etki/kpi.py +92 -0
  161. etki-0.1.0a2/etki/llm_profile.py +66 -0
  162. etki-0.1.0a2/etki/llm_settings.py +65 -0
  163. etki-0.1.0a2/etki/logging_config.py +26 -0
  164. etki-0.1.0a2/etki/mcp_server.py +201 -0
  165. etki-0.1.0a2/etki/persistence/__init__.py +0 -0
  166. etki-0.1.0a2/etki/persistence/__main__.py +71 -0
  167. etki-0.1.0a2/etki/persistence/db.py +42 -0
  168. etki-0.1.0a2/etki/persistence/memory_repo.py +62 -0
  169. etki-0.1.0a2/etki/persistence/models.py +79 -0
  170. etki-0.1.0a2/etki/persistence/repository.py +156 -0
  171. etki-0.1.0a2/etki/pilot/__init__.py +0 -0
  172. etki-0.1.0a2/etki/pilot/__main__.py +97 -0
  173. etki-0.1.0a2/etki/pilot/calibration.py +73 -0
  174. etki-0.1.0a2/etki/pilot/shadow.py +77 -0
  175. etki-0.1.0a2/etki/process_log.py +65 -0
  176. etki-0.1.0a2/etki/projects_store.py +220 -0
  177. etki-0.1.0a2/etki/reporting/__init__.py +0 -0
  178. etki-0.1.0a2/etki/reporting/docx_report.py +66 -0
  179. etki-0.1.0a2/etki/wiki/__init__.py +54 -0
  180. etki-0.1.0a2/etki/wiki/__main__.py +75 -0
  181. etki-0.1.0a2/eval/__init__.py +0 -0
  182. etki-0.1.0a2/eval/backtest.py +64 -0
  183. etki-0.1.0a2/eval/datasets/backtest_crs.json +14 -0
  184. etki-0.1.0a2/eval/datasets/dependency_crs.json +86 -0
  185. etki-0.1.0a2/eval/datasets/etkibench/README.md +662 -0
  186. etki-0.1.0a2/eval/datasets/etkibench/etkibench_v0.json +68 -0
  187. etki-0.1.0a2/eval/datasets/etkibench/etkibench_v1_meridian.json +86 -0
  188. etki-0.1.0a2/eval/datasets/etkibench/etkibench_v1_northwind.json +86 -0
  189. etki-0.1.0a2/eval/datasets/etkibench/heldout_v0.json +38 -0
  190. etki-0.1.0a2/eval/datasets/etkibench/heldout_v1_meridian.json +14 -0
  191. etki-0.1.0a2/eval/datasets/etkibench/heldout_v1_northwind.json +14 -0
  192. etki-0.1.0a2/eval/datasets/etkibench/heldout_v2_meridian.json +86 -0
  193. etki-0.1.0a2/eval/datasets/etkibench/heldout_v2_northwind.json +86 -0
  194. etki-0.1.0a2/eval/datasets/frozen/golden_crs.json +675 -0
  195. etki-0.1.0a2/eval/datasets/graph_queries.json +170 -0
  196. etki-0.1.0a2/eval/datasets/graph_queries_shop.json +93 -0
  197. etki-0.1.0a2/eval/datasets/graph_queries_shop_en.json +58 -0
  198. etki-0.1.0a2/eval/datasets/pilot_crs.json +14 -0
  199. etki-0.1.0a2/eval/datasets/retrieval_crs.json +32 -0
  200. etki-0.1.0a2/eval/datasets/sample_crs.json +17 -0
  201. etki-0.1.0a2/eval/datasets/strategy_routing.json +16 -0
  202. etki-0.1.0a2/eval/graph_retrieval.py +220 -0
  203. etki-0.1.0a2/eval/retrieval.py +66 -0
  204. etki-0.1.0a2/eval/runner.py +320 -0
  205. etki-0.1.0a2/eval/stats.py +36 -0
  206. etki-0.1.0a2/mkdocs.yml +56 -0
  207. etki-0.1.0a2/packages/etki-api/CHANGELOG.md +29 -0
  208. etki-0.1.0a2/packages/etki-api/README.md +19 -0
  209. etki-0.1.0a2/packages/etki-api/pyproject.toml +30 -0
  210. etki-0.1.0a2/packages/etki-api/src/etki_api/__init__.py +70 -0
  211. etki-0.1.0a2/packages/etki-api/src/etki_api/manifest.py +69 -0
  212. etki-0.1.0a2/packages/etki-api/src/etki_api/models.py +95 -0
  213. etki-0.1.0a2/packages/etki-api/src/etki_api/plugin.py +73 -0
  214. etki-0.1.0a2/packages/etki-api/src/etki_api/ports.py +107 -0
  215. etki-0.1.0a2/packages/etki-api/tests/test_manifest.py +65 -0
  216. etki-0.1.0a2/packages/etki-plugin-linear/README.md +18 -0
  217. etki-0.1.0a2/packages/etki-plugin-linear/etki-plugin.toml +19 -0
  218. etki-0.1.0a2/packages/etki-plugin-linear/pyproject.toml +24 -0
  219. etki-0.1.0a2/packages/etki-plugin-linear/src/etki_plugin_linear/__init__.py +149 -0
  220. etki-0.1.0a2/packages/etki-plugin-linear/tests/test_linear_plugin.py +66 -0
  221. etki-0.1.0a2/pyproject.toml +104 -0
  222. etki-0.1.0a2/samples/demo_deps/contract.md +11 -0
  223. etki-0.1.0a2/samples/demo_deps/manifests/Cargo.toml +10 -0
  224. etki-0.1.0a2/samples/demo_deps/manifests/go.mod +10 -0
  225. etki-0.1.0a2/samples/demo_deps/manifests/package.json +12 -0
  226. etki-0.1.0a2/samples/demo_deps/manifests/pom.xml +30 -0
  227. etki-0.1.0a2/samples/demo_deps/pyproject.toml +10 -0
  228. etki-0.1.0a2/samples/demo_deps/requirements.txt +5 -0
  229. etki-0.1.0a2/samples/demo_deps/src/api/handlers.py +19 -0
  230. etki-0.1.0a2/samples/demo_deps/src/jobs/report.py +8 -0
  231. etki-0.1.0a2/samples/demo_project/contract.md +35 -0
  232. etki-0.1.0a2/samples/demo_project/src/api_gateway/__init__.py +0 -0
  233. etki-0.1.0a2/samples/demo_project/src/api_gateway/gateway.py +11 -0
  234. etki-0.1.0a2/samples/demo_project/src/auth/__init__.py +0 -0
  235. etki-0.1.0a2/samples/demo_project/src/auth/service.py +27 -0
  236. etki-0.1.0a2/samples/demo_project/src/config/__init__.py +0 -0
  237. etki-0.1.0a2/samples/demo_project/src/config/settings.py +7 -0
  238. etki-0.1.0a2/samples/demo_project/src/db/__init__.py +0 -0
  239. etki-0.1.0a2/samples/demo_project/src/db/store.py +21 -0
  240. etki-0.1.0a2/samples/demo_project/src/reporting/__init__.py +0 -0
  241. etki-0.1.0a2/samples/demo_project/src/reporting/report.py +25 -0
  242. etki-0.1.0a2/samples/demo_project/work_items.json +83 -0
  243. etki-0.1.0a2/samples/demo_project_b/contract.md +26 -0
  244. etki-0.1.0a2/samples/demo_project_b/src/cart/__init__.py +0 -0
  245. etki-0.1.0a2/samples/demo_project_b/src/cart/service.py +23 -0
  246. etki-0.1.0a2/samples/demo_project_b/src/catalog/__init__.py +0 -0
  247. etki-0.1.0a2/samples/demo_project_b/src/catalog/service.py +14 -0
  248. etki-0.1.0a2/samples/demo_project_b/src/db/__init__.py +0 -0
  249. etki-0.1.0a2/samples/demo_project_b/src/db/store.py +17 -0
  250. etki-0.1.0a2/samples/demo_project_b/src/payment/__init__.py +0 -0
  251. etki-0.1.0a2/samples/demo_project_b/src/payment/service.py +27 -0
  252. etki-0.1.0a2/samples/demo_project_b/work_items.json +7 -0
  253. etki-0.1.0a2/samples/demo_project_en/contract.md +35 -0
  254. etki-0.1.0a2/samples/demo_project_en/src/api_gateway/__init__.py +0 -0
  255. etki-0.1.0a2/samples/demo_project_en/src/api_gateway/gateway.py +11 -0
  256. etki-0.1.0a2/samples/demo_project_en/src/auth/__init__.py +0 -0
  257. etki-0.1.0a2/samples/demo_project_en/src/auth/service.py +28 -0
  258. etki-0.1.0a2/samples/demo_project_en/src/config/__init__.py +0 -0
  259. etki-0.1.0a2/samples/demo_project_en/src/config/settings.py +7 -0
  260. etki-0.1.0a2/samples/demo_project_en/src/db/__init__.py +0 -0
  261. etki-0.1.0a2/samples/demo_project_en/src/db/store.py +21 -0
  262. etki-0.1.0a2/samples/demo_project_en/src/reporting/__init__.py +0 -0
  263. etki-0.1.0a2/samples/demo_project_en/src/reporting/report.py +25 -0
  264. etki-0.1.0a2/samples/demo_project_en/work_items.json +83 -0
  265. etki-0.1.0a2/samples/demo_shop_en/contract.md +26 -0
  266. etki-0.1.0a2/samples/demo_shop_en/src/cart/__init__.py +0 -0
  267. etki-0.1.0a2/samples/demo_shop_en/src/cart/service.py +23 -0
  268. etki-0.1.0a2/samples/demo_shop_en/src/catalog/__init__.py +0 -0
  269. etki-0.1.0a2/samples/demo_shop_en/src/catalog/service.py +14 -0
  270. etki-0.1.0a2/samples/demo_shop_en/src/db/__init__.py +0 -0
  271. etki-0.1.0a2/samples/demo_shop_en/src/db/store.py +21 -0
  272. etki-0.1.0a2/samples/demo_shop_en/src/payment/__init__.py +0 -0
  273. etki-0.1.0a2/samples/demo_shop_en/src/payment/service.py +27 -0
  274. etki-0.1.0a2/samples/demo_shop_en/work_items.json +47 -0
  275. etki-0.1.0a2/scripts/export_cpg.sc +33 -0
  276. etki-0.1.0a2/scripts/freeze_guard.py +116 -0
  277. etki-0.1.0a2/scripts/joern_index.sh +26 -0
  278. etki-0.1.0a2/scripts/rerank_server.py +72 -0
  279. etki-0.1.0a2/tests/__init__.py +0 -0
  280. etki-0.1.0a2/tests/conftest.py +134 -0
  281. etki-0.1.0a2/tests/fixtures/__init__.py +0 -0
  282. etki-0.1.0a2/tests/fixtures/graphify_graph.json +20 -0
  283. etki-0.1.0a2/tests/fixtures/joern_code_index.json +1 -0
  284. etki-0.1.0a2/tests/fixtures/sample_request.py +7 -0
  285. etki-0.1.0a2/tests/fixtures/sample_scope.py +26 -0
  286. etki-0.1.0a2/tests/integration/__init__.py +0 -0
  287. etki-0.1.0a2/tests/integration/test_auth.py +97 -0
  288. etki-0.1.0a2/tests/integration/test_baseline_rehydration.py +130 -0
  289. etki-0.1.0a2/tests/integration/test_composite.py +55 -0
  290. etki-0.1.0a2/tests/integration/test_hitl.py +67 -0
  291. etki-0.1.0a2/tests/integration/test_indexing.py +62 -0
  292. etki-0.1.0a2/tests/integration/test_multiproject.py +72 -0
  293. etki-0.1.0a2/tests/integration/test_pilot.py +61 -0
  294. etki-0.1.0a2/tests/integration/test_project_access.py +111 -0
  295. etki-0.1.0a2/tests/integration/test_project_mgmt.py +107 -0
  296. etki-0.1.0a2/tests/integration/test_project_resolution.py +34 -0
  297. etki-0.1.0a2/tests/integration/test_triage_endpoint.py +41 -0
  298. etki-0.1.0a2/tests/integration/test_ui.py +386 -0
  299. etki-0.1.0a2/tests/unit/__init__.py +0 -0
  300. etki-0.1.0a2/tests/unit/test_api_surface.py +110 -0
  301. etki-0.1.0a2/tests/unit/test_code_index.py +34 -0
  302. etki-0.1.0a2/tests/unit/test_decision_tree.py +170 -0
  303. etki-0.1.0a2/tests/unit/test_dependency_impact.py +465 -0
  304. etki-0.1.0a2/tests/unit/test_document_adapters.py +120 -0
  305. etki-0.1.0a2/tests/unit/test_embedding_assist.py +109 -0
  306. etki-0.1.0a2/tests/unit/test_engine.py +45 -0
  307. etki-0.1.0a2/tests/unit/test_estimation.py +105 -0
  308. etki-0.1.0a2/tests/unit/test_eval_dataset_mode.py +70 -0
  309. etki-0.1.0a2/tests/unit/test_eval_stats.py +20 -0
  310. etki-0.1.0a2/tests/unit/test_fakes.py +32 -0
  311. etki-0.1.0a2/tests/unit/test_file_work_item.py +26 -0
  312. etki-0.1.0a2/tests/unit/test_freeze_guard.py +44 -0
  313. etki-0.1.0a2/tests/unit/test_gitlab.py +88 -0
  314. etki-0.1.0a2/tests/unit/test_glpi_search.py +25 -0
  315. etki-0.1.0a2/tests/unit/test_graphify_code_repo.py +160 -0
  316. etki-0.1.0a2/tests/unit/test_graphquery.py +269 -0
  317. etki-0.1.0a2/tests/unit/test_i18n.py +42 -0
  318. etki-0.1.0a2/tests/unit/test_index_tools.py +124 -0
  319. etki-0.1.0a2/tests/unit/test_ingest.py +231 -0
  320. etki-0.1.0a2/tests/unit/test_jira.py +62 -0
  321. etki-0.1.0a2/tests/unit/test_kpi.py +26 -0
  322. etki-0.1.0a2/tests/unit/test_linear.py +54 -0
  323. etki-0.1.0a2/tests/unit/test_llm_anthropic.py +56 -0
  324. etki-0.1.0a2/tests/unit/test_llm_profile.py +76 -0
  325. etki-0.1.0a2/tests/unit/test_llm_triage_assist.py +373 -0
  326. etki-0.1.0a2/tests/unit/test_login_security.py +115 -0
  327. etki-0.1.0a2/tests/unit/test_manifests.py +113 -0
  328. etki-0.1.0a2/tests/unit/test_memory_consumers.py +241 -0
  329. etki-0.1.0a2/tests/unit/test_models.py +24 -0
  330. etki-0.1.0a2/tests/unit/test_package_download.py +328 -0
  331. etki-0.1.0a2/tests/unit/test_package_registries.py +119 -0
  332. etki-0.1.0a2/tests/unit/test_parsers.py +47 -0
  333. etki-0.1.0a2/tests/unit/test_persistence.py +77 -0
  334. etki-0.1.0a2/tests/unit/test_prompt_injection.py +121 -0
  335. etki-0.1.0a2/tests/unit/test_redmine_azure.py +93 -0
  336. etki-0.1.0a2/tests/unit/test_rerank_assist.py +124 -0
  337. etki-0.1.0a2/tests/unit/test_risk_estimation.py +61 -0
  338. etki-0.1.0a2/tests/unit/test_scope_extractor.py +111 -0
  339. etki-0.1.0a2/tests/unit/test_security_validation.py +48 -0
  340. etki-0.1.0a2/tests/unit/test_strategy_routing.py +19 -0
  341. etki-0.1.0a2/tests/unit/test_text.py +47 -0
  342. etki-0.1.0a2/tests/unit/test_understanding.py +78 -0
  343. etki-0.1.0a2/tests/unit/test_user_admin.py +57 -0
  344. etki-0.1.0a2/tests/unit/test_ux.py +34 -0
  345. etki-0.1.0a2/tests/unit/test_wiki.py +192 -0
  346. etki-0.1.0a2/uv.lock +2803 -0
@@ -0,0 +1,14 @@
1
+ {
2
+ "version": "0.0.1",
3
+ "configurations": [
4
+ {
5
+ "name": "etki-preview",
6
+ "runtimeExecutable": "sh",
7
+ "runtimeArgs": [
8
+ "-c",
9
+ "ETKI_SESSION_SECRET=preview-secret-0123456789abcdef ETKI_DEMO_MODE=true ETKI_DEPS_ONLINE=true ETKI_ADMIN_USER=pmo ETKI_ADMIN_PASSWORD=pmo12345 uv run uvicorn etki.api.app:app --host 127.0.0.1 --port 8001"
10
+ ],
11
+ "port": 8001
12
+ }
13
+ ]
14
+ }
@@ -0,0 +1,12 @@
1
+ .git
2
+ .venv
3
+ .etki
4
+ workspace
5
+ **/__pycache__
6
+ *.db
7
+ .mypy_cache
8
+ .ruff_cache
9
+ .pytest_cache
10
+ tests
11
+ docs
12
+ Etki_*.md
@@ -0,0 +1,41 @@
1
+ # Etki ortam ayarları — bu dosyayı `.env` olarak kopyalayıp değerleri doldurun.
2
+ # cp .env.example .env
3
+ # .env .gitignore'dadır; sırlar (API anahtarı) ASLA commit'lenmez.
4
+
5
+ # --- LLM (sohbet + LLM kapsam çıkarımı için; opsiyonel) ---
6
+ # Anthropic Claude API. Anahtar yoksa sistem deterministik/sezgisel çalışır.
7
+ # NOT: LLM sağlayıcısı arayüzden de yönetilebilir (Ayarlar → Yapay Zekâ Asistanı,
8
+ # pmo). Arayüzden kaydedilen değerler .etki/llm.json'da tutulur ve buradaki env
9
+ # değerlerinden ÖNCELİKLİDİR; üretimde sırlar için env önerilir.
10
+ ETKI_LLM_PROVIDER=anthropic
11
+
12
+ # Anthropic Claude API anahtarı (https://console.anthropic.com/ → API Keys).
13
+ # ANAHTAR BURAYA:
14
+ ETKI_ANTHROPIC_API_KEY=sk-ant-...
15
+ # Model (varsayılan claude-opus-4-8):
16
+ # ETKI_ANTHROPIC_MODEL=claude-opus-4-8
17
+
18
+ # --- Kimlik doğrulama / oturum (ÜRETİMDE ZORUNLU) ---
19
+ # Session cookie imzalama secret'ı — uzun, rastgele bir değer (ör. `openssl rand -hex 32`).
20
+ ETKI_SESSION_SECRET=change-me-uzun-rastgele-bir-deger
21
+ # İlk PMO kullanıcısı (yalnızca hiç kullanıcı yoksa, açılışta bir kez oluşturulur):
22
+ ETKI_ADMIN_USER=pmo
23
+ ETKI_ADMIN_PASSWORD=change-me-guclu-parola
24
+
25
+ # --- Veritabanı / Docker Postgres ---
26
+ # Postgres parolası (docker-compose bunu kullanır):
27
+ POSTGRES_PASSWORD=change-me-postgres-parola
28
+ # ETKI_DB_URL=sqlite:///./etki.db
29
+ # Canlı (Docker): postgresql+psycopg://postgres:${POSTGRES_PASSWORD}@db:5432/etki
30
+
31
+ # --- Arka plan tazeleme (opsiyonel; ikisi de varsayılan KAPALI = 0) ---
32
+ # Üretimde önerilen yol cron'dur (docs/RUNBOOK.md); tek-konteyner/pilot kurulumlar için:
33
+ # ETKI_REINDEX_INTERVAL_HOURS=24 # tüm projeleri periyodik tam re-index et
34
+ # ETKI_POOL_REFRESH_MINUTES=15 # efor havuzu tüketimini hafifçe tazele (re-index yok)
35
+
36
+ # --- Diğer (opsiyonel) ---
37
+ # ETKI_DEFAULT_LANGUAGE=tr # varsayılan UI dili (tr|en|de); session/Accept-Language ezer
38
+ # ETKI_MAX_UPLOAD_MB=20 # yükleme boyut sınırı
39
+ # ETKI_DEMO_MODE=true # triyaj ekranında örnek talep çiplerini göster
40
+ # Jira/GLPI token'ları: UI'da `env:JIRA_TOKEN` referansı girip değeri burada verin:
41
+ # JIRA_TOKEN=...
@@ -0,0 +1,41 @@
1
+ name: New adapter proposal
2
+ description: Propose an integration with a work-item tracker, code host, document source or LLM endpoint
3
+ labels: ["adapter", "enhancement"]
4
+ body:
5
+ - type: input
6
+ id: vendor
7
+ attributes:
8
+ label: Vendor / system
9
+ placeholder: e.g. Azure DevOps, GitLab, Linear, Redmine, Confluence
10
+ validations:
11
+ required: true
12
+ - type: dropdown
13
+ id: port
14
+ attributes:
15
+ label: Which port does it implement?
16
+ options:
17
+ - WorkItemProvider (tickets + spent effort)
18
+ - CodeRepositoryProvider (repo access, churn, diff)
19
+ - DocumentSourceProvider (document listing + content)
20
+ - LLMClient (OpenAI-compatible / other LLM endpoint)
21
+ validations:
22
+ required: true
23
+ - type: textarea
24
+ id: capabilities
25
+ attributes:
26
+ label: Capabilities and API notes
27
+ description: |
28
+ Which capabilities can the vendor support (webhooks, real-time, effort tracking,
29
+ incremental diff)? Link the relevant API docs. Adapters must normalize vendor
30
+ quirks internally (e.g. map time-spent to `WorkItem.effort_seconds`) and degrade
31
+ gracefully when the server is unreachable.
32
+ validations:
33
+ required: true
34
+ - type: checkboxes
35
+ id: checks
36
+ attributes:
37
+ label: Checks
38
+ options:
39
+ - label: I read the "Writing an adapter" section in CONTRIBUTING.md
40
+ required: true
41
+ - label: I'd like to implement this myself
@@ -0,0 +1,35 @@
1
+ name: Bug report
2
+ description: Something doesn't work as documented
3
+ labels: ["bug"]
4
+ body:
5
+ - type: textarea
6
+ id: what-happened
7
+ attributes:
8
+ label: What happened?
9
+ description: What did you do, what did you expect, what happened instead?
10
+ placeholder: |
11
+ 1. Started the demo with `docker compose -f docker-compose.demo.yml up`
12
+ 2. Submitted the request "..."
13
+ 3. Expected an OUT_OF_SCOPE decision, got ...
14
+ validations:
15
+ required: true
16
+ - type: textarea
17
+ id: environment
18
+ attributes:
19
+ label: Environment
20
+ description: OS, Python version, how you run Etki (uv / Docker / compose), LLM provider if any.
21
+ placeholder: macOS 15, Python 3.12, docker compose demo profile, no LLM
22
+ validations:
23
+ required: true
24
+ - type: textarea
25
+ id: logs
26
+ attributes:
27
+ label: Relevant logs or output
28
+ render: shell
29
+ - type: checkboxes
30
+ id: checks
31
+ attributes:
32
+ label: Checks
33
+ options:
34
+ - label: I searched existing issues for this problem
35
+ required: true
@@ -0,0 +1,8 @@
1
+ blank_issues_enabled: true
2
+ contact_links:
3
+ - name: Questions & ideas
4
+ url: https://github.com/yasinyaman/etki/discussions
5
+ about: Use Discussions for questions, design conversations and show-and-tell.
6
+ - name: Security reports
7
+ url: https://github.com/yasinyaman/etki/security/advisories/new
8
+ about: Please report vulnerabilities privately, not as public issues.
@@ -0,0 +1,22 @@
1
+ name: Feature request
2
+ description: Propose an improvement or new capability
3
+ labels: ["enhancement"]
4
+ body:
5
+ - type: textarea
6
+ id: problem
7
+ attributes:
8
+ label: Problem
9
+ description: What are you trying to do that Etki doesn't support today?
10
+ validations:
11
+ required: true
12
+ - type: textarea
13
+ id: proposal
14
+ attributes:
15
+ label: Proposed solution
16
+ description: How should it work? If it touches the decision engine, remember the invariants — estimates are ranges, EXCLUDED scope is first-class, every decision carries an evidence chain.
17
+ validations:
18
+ required: true
19
+ - type: textarea
20
+ id: alternatives
21
+ attributes:
22
+ label: Alternatives considered
@@ -0,0 +1,14 @@
1
+ ## What & why
2
+
3
+ <!-- What does this PR change, and what problem does it solve? Link the issue if any. -->
4
+
5
+ ## Checklist
6
+
7
+ - [ ] `uv run pytest` passes
8
+ - [ ] `uv run ruff check .` and `uv run mypy etki` pass
9
+ - [ ] `uv run python -m eval.runner` passes — and this PR does **not** modify
10
+ `eval/datasets/frozen/golden_crs.json` together with engine/matching logic
11
+ (golden-set freeze rule, see CONTRIBUTING.md)
12
+ - [ ] New adapter? Registered in `adapters/registry.py`, no vendor references in core,
13
+ tests use fakes / skip cleanly without a live server
14
+ - [ ] UI strings added through the i18n catalog (tr/en/de)
@@ -0,0 +1,58 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+
7
+ jobs:
8
+ check:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+ with:
13
+ fetch-depth: 0 # freeze guard diffs against the PR base / push range
14
+
15
+ # Answer-key freeze guard: engine/matching changes and eval dataset edits must
16
+ # not land in the same change set (see CONTRIBUTING.md). PRs check the whole
17
+ # range; pushes check each commit individually.
18
+ - name: Freeze guard
19
+ run: |
20
+ if [ "${{ github.event_name }}" = "pull_request" ]; then
21
+ python scripts/freeze_guard.py "origin/${{ github.base_ref }}...HEAD"
22
+ else
23
+ BEFORE="${{ github.event.before }}"
24
+ if [ -z "$BEFORE" ] || ! git cat-file -e "$BEFORE" 2>/dev/null; then
25
+ # Force-push or fresh history: fall back to the parent when it
26
+ # exists, else check all commits (the guard skips root commits).
27
+ BEFORE=$(git rev-parse --verify --quiet HEAD^ || true)
28
+ fi
29
+ if [ -n "$BEFORE" ]; then
30
+ python scripts/freeze_guard.py --per-commit "$BEFORE..HEAD"
31
+ else
32
+ python scripts/freeze_guard.py --per-commit "HEAD"
33
+ fi
34
+ fi
35
+
36
+ - name: Install uv
37
+ uses: astral-sh/setup-uv@v5
38
+ with:
39
+ python-version: "3.12"
40
+ enable-cache: true # cache dependency downloads
41
+
42
+ - name: Sync dependencies
43
+ run: uv sync --frozen --dev # match the lockfile exactly (no version drift)
44
+
45
+ - name: Lint (ruff)
46
+ run: uv run ruff check .
47
+
48
+ - name: Type check (mypy)
49
+ run: uv run mypy etki packages/etki-api/src/etki_api packages/etki-plugin-linear/src/etki_plugin_linear
50
+
51
+ - name: Tests (pytest + coverage)
52
+ run: uv run pytest --cov=etki --cov=etki_api --cov=etki_plugin_linear --cov-report=term-missing --cov-fail-under=70
53
+
54
+ - name: Build workspace packages (etki-api gate)
55
+ run: uv build --all-packages
56
+
57
+ - name: Gate / back-test (eval)
58
+ run: uv run python -m eval.runner
@@ -0,0 +1,26 @@
1
+ # Docs site: mkdocs-material → GitHub Pages, on every push to master that touches docs.
2
+ # One-time setup: repo Settings → Pages → Source: "Deploy from a branch" → branch gh-pages.
3
+ name: Docs
4
+
5
+ on:
6
+ push:
7
+ branches: [master]
8
+ paths:
9
+ - "docs/**"
10
+ - "mkdocs.yml"
11
+ - ".github/workflows/docs.yml"
12
+
13
+ permissions:
14
+ contents: write # gh-pages push
15
+
16
+ jobs:
17
+ deploy:
18
+ runs-on: ubuntu-latest
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+ - uses: astral-sh/setup-uv@v5
22
+ with:
23
+ python-version: "3.12"
24
+ enable-cache: true
25
+ - run: uv sync --frozen --only-group docs
26
+ - run: uv run --no-sync mkdocs gh-deploy --force
@@ -0,0 +1,129 @@
1
+ # Release automation: push a tag like `v0.1.0a1` →
2
+ # 1. re-run the full check suite (same as CI),
3
+ # 2. build + push the Docker image to GHCR (ghcr.io/<owner>/etki),
4
+ # 3. build the sdist/wheel and publish to PyPI (trusted publishing),
5
+ # 4. create a GitHub Release with the matching CHANGELOG section.
6
+ #
7
+ # One-time setup required for PyPI: TWO trusted publishers on pypi.org for this
8
+ # repository (both workflow: release.yml) — project `etki` with environment `pypi`,
9
+ # project `etki-api` with environment `pypi-etki-api`. PyPI refuses two pending
10
+ # publishers with the identical repo+workflow+environment config, hence the split.
11
+ # Until configured the publish jobs fail; the other jobs are independent.
12
+ name: Release
13
+
14
+ on:
15
+ push:
16
+ tags:
17
+ - "v*"
18
+
19
+ permissions:
20
+ contents: write # GitHub Release
21
+ packages: write # GHCR push
22
+ id-token: write # PyPI trusted publishing
23
+
24
+ jobs:
25
+ checks:
26
+ runs-on: ubuntu-latest
27
+ steps:
28
+ - uses: actions/checkout@v4
29
+ - uses: astral-sh/setup-uv@v5
30
+ with:
31
+ python-version: "3.12"
32
+ enable-cache: true
33
+ - run: uv sync --frozen --dev
34
+ - run: uv run ruff check .
35
+ - run: uv run mypy etki packages/etki-api/src/etki_api packages/etki-plugin-linear/src/etki_plugin_linear
36
+ - run: uv run pytest --cov=etki --cov=etki_api --cov-fail-under=70
37
+ - run: uv run python -m eval.runner
38
+
39
+ docker:
40
+ needs: checks
41
+ runs-on: ubuntu-latest
42
+ steps:
43
+ - uses: actions/checkout@v4
44
+ - uses: docker/setup-qemu-action@v3
45
+ - uses: docker/setup-buildx-action@v3
46
+ - uses: docker/login-action@v3
47
+ with:
48
+ registry: ghcr.io
49
+ username: ${{ github.actor }}
50
+ password: ${{ secrets.GITHUB_TOKEN }}
51
+ - id: meta
52
+ uses: docker/metadata-action@v5
53
+ with:
54
+ images: ghcr.io/${{ github.repository_owner }}/etki
55
+ tags: |
56
+ type=pep440,pattern={{version}}
57
+ type=raw,value=latest
58
+ - uses: docker/build-push-action@v6
59
+ with:
60
+ context: .
61
+ platforms: linux/amd64,linux/arm64
62
+ push: true
63
+ tags: ${{ steps.meta.outputs.tags }}
64
+ labels: ${{ steps.meta.outputs.labels }}
65
+ cache-from: type=gha
66
+ cache-to: type=gha,mode=max
67
+
68
+ # PyPI rejects two pending trusted publishers with the IDENTICAL config
69
+ # (repo + workflow + environment) — the environment name is the disambiguator.
70
+ # So each package publishes from its OWN job/environment:
71
+ # project `etki` ← environment `pypi`
72
+ # project `etki-api` ← environment `pypi-etki-api`
73
+ # skip-existing lets a tag re-run without failing on versions already uploaded
74
+ # (etki-api only uploads when its version was actually bumped).
75
+ pypi:
76
+ needs: checks
77
+ runs-on: ubuntu-latest
78
+ environment: pypi
79
+ steps:
80
+ - uses: actions/checkout@v4
81
+ - uses: astral-sh/setup-uv@v5
82
+ with:
83
+ python-version: "3.12"
84
+ - run: uv build # root member only = etki
85
+ - uses: pypa/gh-action-pypi-publish@release/v1
86
+ with:
87
+ skip-existing: true
88
+
89
+ pypi-etki-api:
90
+ needs: checks
91
+ runs-on: ubuntu-latest
92
+ environment: pypi-etki-api
93
+ steps:
94
+ - uses: actions/checkout@v4
95
+ - uses: astral-sh/setup-uv@v5
96
+ with:
97
+ python-version: "3.12"
98
+ - run: uv build --package etki-api
99
+ - uses: pypa/gh-action-pypi-publish@release/v1
100
+ with:
101
+ skip-existing: true
102
+
103
+ github-release:
104
+ # NOT dependent on PyPI: the image + GitHub Release still go out even if the
105
+ # trusted publisher isn't configured yet (the pypi job can fail independently).
106
+ needs: [docker]
107
+ runs-on: ubuntu-latest
108
+ steps:
109
+ - uses: actions/checkout@v4
110
+ - name: Extract changelog section for this version
111
+ run: |
112
+ VERSION="${GITHUB_REF_NAME#v}"
113
+ awk -v ver="$VERSION" '
114
+ $0 ~ "^## \\[" ver "\\]" {found=1; next}
115
+ found && /^## \[/ {exit}
116
+ found {print}
117
+ ' CHANGELOG.md > release-notes.md
118
+ if ! [ -s release-notes.md ]; then
119
+ echo "No CHANGELOG section for $VERSION; using a generic note." >&2
120
+ echo "See CHANGELOG.md for details." > release-notes.md
121
+ fi
122
+ - name: Create GitHub Release
123
+ env:
124
+ GH_TOKEN: ${{ github.token }}
125
+ run: |
126
+ gh release create "$GITHUB_REF_NAME" \
127
+ --title "Etki $GITHUB_REF_NAME" \
128
+ --notes-file release-notes.md \
129
+ $([[ "$GITHUB_REF_NAME" == *a* || "$GITHUB_REF_NAME" == *b* || "$GITHUB_REF_NAME" == *rc* ]] && echo --prerelease)
@@ -0,0 +1,32 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ .venv/
5
+ venv/
6
+ *.egg-info/
7
+ dist/
8
+ build/
9
+
10
+ # Araçlar
11
+ .mypy_cache/
12
+ .ruff_cache/
13
+ .pytest_cache/
14
+
15
+ # Ortam
16
+ .env
17
+ *.local.yaml
18
+ connectors.yaml
19
+
20
+ # İndeks artıkları
21
+ .etki/
22
+ workspace/
23
+
24
+ # Veritabanı (yerel)
25
+ *.db
26
+
27
+ # Test/coverage artıkları
28
+ .coverage
29
+ coverage.xml
30
+
31
+ # MkDocs build output
32
+ site/