abstra 3.23.12__py3-none-any.whl → 3.24.1__py3-none-any.whl

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 (266) hide show
  1. abstra/cli.py +16 -5
  2. {abstra-3.23.12.dist-info → abstra-3.24.1.dist-info}/METADATA +1 -1
  3. {abstra-3.23.12.dist-info → abstra-3.24.1.dist-info}/RECORD +200 -190
  4. abstra_internals/cloud_api/__init__.py +17 -8
  5. abstra_internals/consts/filepaths.py +1 -1
  6. abstra_internals/contracts_generated.py +616 -596
  7. abstra_internals/controllers/ai.py +89 -1
  8. abstra_internals/controllers/git.py +307 -0
  9. abstra_internals/controllers/main.py +10 -6
  10. abstra_internals/environment.py +6 -0
  11. abstra_internals/interface/cli/deploy.py +1 -1
  12. abstra_internals/interface/cli/editor.py +2 -2
  13. abstra_internals/interface/sdk/ai.py +1 -0
  14. abstra_internals/repositories/git/__init__.py +25 -0
  15. abstra_internals/repositories/git/git_test.py +362 -0
  16. abstra_internals/repositories/git/native.py +578 -0
  17. abstra_internals/repositories/git/types.py +273 -0
  18. abstra_internals/repositories/linter/rules/env_in_bundle.py +5 -5
  19. abstra_internals/repositories/linter/rules/env_in_bundle_test.py +6 -6
  20. abstra_internals/repositories/linter/rules/venv_in_bundle.py +9 -16
  21. abstra_internals/server/blueprints/editor.py +4 -0
  22. abstra_internals/server/routes/git.py +190 -0
  23. abstra_internals/server/routes/workspace.py +1 -1
  24. abstra_internals/services/file_watcher.py +32 -13
  25. abstra_internals/services/fs.py +4 -4
  26. abstra_internals/services/fs_test.py +4 -6
  27. abstra_internals/templates/__init__.py +0 -11
  28. abstra_statics/dist/assets/{AbstraButton.vue_vue_type_script_setup_true_lang.441fcdfd.js → AbstraButton.vue_vue_type_script_setup_true_lang.aefce2d3.js} +2 -2
  29. abstra_statics/dist/assets/AbstraLogo.vue_vue_type_script_setup_true_lang.28bc9fc9.js +2 -0
  30. abstra_statics/dist/assets/ApiKeys.3c1e70dc.js +2 -0
  31. abstra_statics/dist/assets/App.9d8bd2aa.js +2 -0
  32. abstra_statics/dist/assets/App.vue_vue_type_style_index_0_lang.a64c7cee.js +2 -0
  33. abstra_statics/dist/assets/{BaseLayout.c63dfc2d.js → BaseLayout.72a6c8f2.js} +2 -2
  34. abstra_statics/dist/assets/{Billing.461db3ef.js → Billing.6b07f282.js} +2 -2
  35. abstra_statics/dist/assets/{Breadcrumb.27110ec4.js → Breadcrumb.5c786c09.js} +2 -2
  36. abstra_statics/dist/assets/{Builds.4eecd717.js → Builds.d8c5c61b.js} +2 -2
  37. abstra_statics/dist/assets/{Card.1d1a9fb7.js → Card.fc77085c.js} +2 -2
  38. abstra_statics/dist/assets/{CircularLoading.fc66331b.js → CircularLoading.998b223a.js} +2 -2
  39. abstra_statics/dist/assets/{CloseCircleOutlined.0110bbe2.js → CloseCircleOutlined.9ff269cc.js} +2 -2
  40. abstra_statics/dist/assets/{ConnectorsView.82e74ae4.css → ConnectorsView.33c5380f.css} +1 -1
  41. abstra_statics/dist/assets/ConnectorsView.e670738b.js +2 -0
  42. abstra_statics/dist/assets/ConsoleOmniChat.vue_vue_type_script_setup_true_lang.3ca66327.js +2 -0
  43. abstra_statics/dist/assets/ContentLayout.0db8d7fb.js +2 -0
  44. abstra_statics/dist/assets/{CrudView.c16e2f81.js → CrudView.cc6aeaf0.js} +2 -2
  45. abstra_statics/dist/assets/DocsButton.vue_vue_type_script_setup_true_lang.689d8ce7.js +2 -0
  46. abstra_statics/dist/assets/{EditorLogin.00a3b3d9.js → EditorLogin.691452b4.js} +2 -2
  47. abstra_statics/dist/assets/{EditorsView.f7b2843c.js → EditorsView.fcdf0186.js} +2 -2
  48. abstra_statics/dist/assets/EnvVars.5519b4ce.js +2 -0
  49. abstra_statics/dist/assets/Error.11fd1f21.js +2 -0
  50. abstra_statics/dist/assets/ExclamationCircleOutlined.d0aa47da.js +2 -0
  51. abstra_statics/dist/assets/Files.6ea18d46.js +2 -0
  52. abstra_statics/dist/assets/{Form.8077681f.js → Form.09de384c.js} +2 -2
  53. abstra_statics/dist/assets/{FormRunner.055e2c45.js → FormRunner.15be6fa0.js} +2 -2
  54. abstra_statics/dist/assets/{Home.0ef22910.js → Home.782c5702.js} +2 -2
  55. abstra_statics/dist/assets/Home.7c495aa9.js +2 -0
  56. abstra_statics/dist/assets/{Live.e1261458.js → Live.48c10605.js} +2 -2
  57. abstra_statics/dist/assets/LoadingContainer.82ac3d44.js +2 -0
  58. abstra_statics/dist/assets/LoadingOutlined.66639b08.js +2 -0
  59. abstra_statics/dist/assets/Login.4a05f5c5.js +2 -0
  60. abstra_statics/dist/assets/{Login.041361ea.js → Login.4e852955.js} +2 -2
  61. abstra_statics/dist/assets/{Login.vue_vue_type_script_setup_true_lang.c2eb444c.js → Login.vue_vue_type_script_setup_true_lang.5161f328.js} +2 -2
  62. abstra_statics/dist/assets/Logo.65e0b37c.js +2 -0
  63. abstra_statics/dist/assets/{Logs.f76cde12.js → Logs.7d1acf32.js} +2 -2
  64. abstra_statics/dist/assets/{LogsController.addd81bf.js → LogsController.0eb2eb30.js} +2 -2
  65. abstra_statics/dist/assets/Main.0313f4fc.js +2 -0
  66. abstra_statics/dist/assets/{MockForm.c9441864.js → MockForm.0b819a52.js} +2 -2
  67. abstra_statics/dist/assets/Navbar.ef64aa09.js +2 -0
  68. abstra_statics/dist/assets/NewEditor.b9c410fe.css +1 -0
  69. abstra_statics/dist/assets/NewEditor.c928dbe9.js +8 -0
  70. abstra_statics/dist/assets/OidcLoginCallback.42a7c4f9.js +2 -0
  71. abstra_statics/dist/assets/OidcLogoutCallback.35931a68.js +2 -0
  72. abstra_statics/dist/assets/OmniChat.73d9f6bb.js +6 -0
  73. abstra_statics/dist/assets/OmniChat.a21fec40.css +1 -0
  74. abstra_statics/dist/assets/{OnboardingView.fbc4b6fe.js → OnboardingView.25042384.js} +2 -2
  75. abstra_statics/dist/assets/{Organization.bc495099.js → Organization.66f64939.js} +2 -2
  76. abstra_statics/dist/assets/Organizations.47868beb.js +2 -0
  77. abstra_statics/dist/assets/{PhArrowCounterClockwise.vue.156bcd89.js → PhArrowCounterClockwise.vue.78877a50.js} +2 -2
  78. abstra_statics/dist/assets/{PhArrowSquareOut.vue.d0c95a06.js → PhArrowSquareOut.vue.2ddfc219.js} +2 -2
  79. abstra_statics/dist/assets/{PhBookBookmark.vue.42e49494.js → PhBookBookmark.vue.41108214.js} +2 -2
  80. abstra_statics/dist/assets/{PhChats.vue.54d692e4.js → PhChats.vue.71e5cb89.js} +2 -2
  81. abstra_statics/dist/assets/{PhClockCounterClockwise.vue.d47d66ba.js → PhClockCounterClockwise.vue.854c3cb5.js} +2 -2
  82. abstra_statics/dist/assets/{PhCopy.vue.a0d9b0ec.js → PhCopy.vue.d116ddfb.js} +2 -2
  83. abstra_statics/dist/assets/{PhCopySimple.vue.43c74ebe.js → PhCopySimple.vue.5d0f839d.js} +2 -2
  84. abstra_statics/dist/assets/{PhCube.vue.498c014d.js → PhCube.vue.abf4a034.js} +2 -2
  85. abstra_statics/dist/assets/PhDatabase.vue.a94d95f6.js +2 -0
  86. abstra_statics/dist/assets/{PhDotsThreeVertical.vue.0ea03d82.js → PhDotsThreeVertical.vue.5e8ae2a9.js} +2 -2
  87. abstra_statics/dist/assets/{PhDownloadSimple.vue.c92aeaff.js → PhDownloadSimple.vue.e88f64f1.js} +2 -2
  88. abstra_statics/dist/assets/{PhFolderPlus.vue.0c210f8d.js → PhFolderPlus.vue.21d377a3.js} +2 -2
  89. abstra_statics/dist/assets/{PhGear.vue.86c3014a.js → PhGear.vue.363dd83c.js} +2 -2
  90. abstra_statics/dist/assets/{PhKey.vue.72ce23d3.js → PhKey.vue.23f3a465.js} +2 -2
  91. abstra_statics/dist/assets/{PhPencil.vue.80ed4b2e.js → PhPencil.vue.feb383e2.js} +2 -2
  92. abstra_statics/dist/assets/{PhPencilSimple.vue.0046d784.js → PhPencilSimple.vue.ec0eebb4.js} +2 -2
  93. abstra_statics/dist/assets/{PhRocket.vue.f3302a7e.js → PhRocket.vue.261a42b2.js} +2 -2
  94. abstra_statics/dist/assets/{PhSignOut.vue.c9150da4.js → PhSignOut.vue.d1d6498f.js} +2 -2
  95. abstra_statics/dist/assets/{PhSparkle.vue.84ea95fc.js → PhSparkle.vue.b6712d34.js} +2 -2
  96. abstra_statics/dist/assets/{PhUserList.vue.bce47902.js → PhUserList.vue.e0b8c21b.js} +2 -2
  97. abstra_statics/dist/assets/{PhUsersThree.vue.0a84dfa4.js → PhUsersThree.vue.8889f957.js} +2 -2
  98. abstra_statics/dist/assets/PhWarningCircle.vue.2087be7d.js +2 -0
  99. abstra_statics/dist/assets/{PhWebhooksLogo.vue.a704632d.js → PhWebhooksLogo.vue.d164db1e.js} +2 -2
  100. abstra_statics/dist/assets/{PlayerConfigProvider.26b585a1.js → PlayerConfigProvider.28e29025.js} +2 -2
  101. abstra_statics/dist/assets/{PlayerNavbar.0fa6f760.js → PlayerNavbar.aaad1dfd.js} +2 -2
  102. abstra_statics/dist/assets/Project.2de506d7.js +2 -0
  103. abstra_statics/dist/assets/{ProjectLogin.934271a6.js → ProjectLogin.22c8b093.js} +2 -2
  104. abstra_statics/dist/assets/{ProjectSettings.2bf7e6c8.js → ProjectSettings.d065c292.js} +2 -2
  105. abstra_statics/dist/assets/{ProjectsView.ed31b921.js → ProjectsView.cbd118ac.js} +2 -2
  106. abstra_statics/dist/assets/{SaveButton.fdf70b31.js → SaveButton.428227de.js} +2 -2
  107. abstra_statics/dist/assets/ScrollArea.vue_vue_type_script_setup_true_lang.6d724b05.js +2 -0
  108. abstra_statics/dist/assets/{Sidebar.e69f49bd.css → Sidebar.29baeab0.css} +1 -1
  109. abstra_statics/dist/assets/{Sidebar.781afa0a.js → Sidebar.41173d8e.js} +2 -2
  110. abstra_statics/dist/assets/Sql.90e6e2ba.css +1 -0
  111. abstra_statics/dist/assets/Sql.c070dd2c.js +5 -0
  112. abstra_statics/dist/assets/Steps.dd51a108.js +2 -0
  113. abstra_statics/dist/assets/TableCard.529112b9.css +1 -0
  114. abstra_statics/dist/assets/TableCard.c9a1cf41.js +2 -0
  115. abstra_statics/dist/assets/TableEditor.1bc47a95.js +2 -0
  116. abstra_statics/dist/assets/TableEditor.5853a363.css +1 -0
  117. abstra_statics/dist/assets/Tables.eff119eb.js +2 -0
  118. abstra_statics/dist/assets/TablesDiagram.a588e7ff.css +1 -0
  119. abstra_statics/dist/assets/TablesDiagram.d633acaf.js +15 -0
  120. abstra_statics/dist/assets/TablesTabs.vue_vue_type_script_setup_true_lang.cf7e34c5.js +2 -0
  121. abstra_statics/dist/assets/{Tasks.ee450480.js → Tasks.c311b05f.js} +2 -2
  122. abstra_statics/dist/assets/{UploadOutlined.e3072945.js → UploadOutlined.9aa845de.js} +2 -2
  123. abstra_statics/dist/assets/View.dd7ba25a.js +2 -0
  124. abstra_statics/dist/assets/{View.vue_vue_type_script_setup_true_lang.ee5d447b.js → View.vue_vue_type_script_setup_true_lang.e6563207.js} +2 -2
  125. abstra_statics/dist/assets/{Watermark.891eee9f.js → Watermark.9c9358e3.js} +2 -2
  126. abstra_statics/dist/assets/{WebEditor.7409cd48.js → WebEditor.83f2a960.js} +2 -2
  127. abstra_statics/dist/assets/WidgetPreview.7c6a231c.js +2 -0
  128. abstra_statics/dist/assets/ant-design.42419021.js +2 -0
  129. abstra_statics/dist/assets/apiKey.403049eb.js +2 -0
  130. abstra_statics/dist/assets/asyncComputed.47aec2b5.js +2 -0
  131. abstra_statics/dist/assets/{build.8fa1a961.js → build.45b511b6.js} +2 -2
  132. abstra_statics/dist/assets/colorHelpers.50ced1e9.js +2 -0
  133. abstra_statics/dist/assets/console.f0f09e6f.js +17 -0
  134. abstra_statics/dist/assets/constants.d569f33d.js +2 -0
  135. abstra_statics/dist/assets/{contracts.generated.c4057ed0.js → contracts.generated.aefe8d0a.js} +2 -2
  136. abstra_statics/dist/assets/{cssMode.4c65b876.js → cssMode.23271d4a.js} +2 -2
  137. abstra_statics/dist/assets/{datetime.e5660676.js → datetime.82608dfb.js} +2 -2
  138. abstra_statics/dist/assets/dayjs.7f71c60a.js +2 -0
  139. abstra_statics/dist/assets/editor.02184ced.js +2 -0
  140. abstra_statics/dist/assets/editor.main.0f931e87.js +2 -0
  141. abstra_statics/dist/assets/fetch.1b3d01a0.js +2 -0
  142. abstra_statics/dist/assets/files.8b58ee7e.js +2 -0
  143. abstra_statics/dist/assets/folder.13d3acac.js +2 -0
  144. abstra_statics/dist/assets/{freemarker2.1d872d48.js → freemarker2.f79b510b.js} +2 -2
  145. abstra_statics/dist/assets/{handlebars.41fc6db8.js → handlebars.07d5febe.js} +2 -2
  146. abstra_statics/dist/assets/{html.967e3c6d.js → html.7d6a59b4.js} +3 -3
  147. abstra_statics/dist/assets/{htmlMode.d38ab72a.js → htmlMode.7779ff94.js} +2 -2
  148. abstra_statics/dist/assets/{index.8e871bae.js → index.482df04a.js} +2 -2
  149. abstra_statics/dist/assets/{index.4b93c8ad.js → index.581e2edd.js} +2 -2
  150. abstra_statics/dist/assets/index.966ac1b9.js +2 -0
  151. abstra_statics/dist/assets/{index.9021ba5d.js → index.c7a996a6.js} +2 -2
  152. abstra_statics/dist/assets/{index.03d222dd.js → index.c8a56795.js} +2 -2
  153. abstra_statics/dist/assets/{index.5f3f38ed.js → index.d31da2c3.js} +2 -2
  154. abstra_statics/dist/assets/{index.51dbb698.js → index.d53182ed.js} +2 -2
  155. abstra_statics/dist/assets/{index.b762f5e8.js → index.e71a5f84.js} +2 -2
  156. abstra_statics/dist/assets/{javascript.0935bea2.js → javascript.4c528c2c.js} +3 -3
  157. abstra_statics/dist/assets/{jsonMode.2860b71c.js → jsonMode.d6441e9d.js} +2 -2
  158. abstra_statics/dist/assets/{jwt-decode.esm.7f2ef0df.js → jwt-decode.esm.54a1ea22.js} +8 -8
  159. abstra_statics/dist/assets/linters.a0f2aa84.js +2 -0
  160. abstra_statics/dist/assets/{liquid.1bae5f6b.js → liquid.0c441ad2.js} +2 -2
  161. abstra_statics/dist/assets/member.2260c37e.js +2 -0
  162. abstra_statics/dist/assets/{metadata.39f9b9ba.js → metadata.0098e20c.js} +2 -2
  163. abstra_statics/dist/assets/omniChatStore.dd7a1c46.js +8 -0
  164. abstra_statics/dist/assets/{organization.a877b653.js → organization.668d1b58.js} +2 -2
  165. abstra_statics/dist/assets/player.4ab4aed5.js +2 -0
  166. abstra_statics/dist/assets/{plotly.min.d3f75723.js → plotly.min.2a87d7e2.js} +2 -2
  167. abstra_statics/dist/assets/polling.b5a32c22.js +2 -0
  168. abstra_statics/dist/assets/{project.d22a89ee.js → project.1b8374f4.js} +2 -2
  169. abstra_statics/dist/assets/{python.4c1a1300.js → python.7ac27a56.js} +3 -3
  170. abstra_statics/dist/assets/{razor.ba8bdb33.js → razor.860a0279.js} +2 -2
  171. abstra_statics/dist/assets/{record.4ffc477c.js → record.e83a2eb2.js} +2 -2
  172. abstra_statics/dist/assets/{redirect.ce3c0f65.js → redirect.586749f4.js} +2 -2
  173. abstra_statics/dist/assets/{repository.360feb8f.js → repository.3a331f0f.js} +2 -2
  174. abstra_statics/dist/assets/{repository.ab3036a9.js → repository.66c7567c.js} +2 -2
  175. abstra_statics/dist/assets/router.06ee2b9d.js +2 -0
  176. abstra_statics/dist/assets/router.4dfadf5d.js +18 -0
  177. abstra_statics/dist/assets/string.61e11a30.js +2 -0
  178. abstra_statics/dist/assets/{tables.be1c51f8.js → tables.1bcb1140.js} +2 -2
  179. abstra_statics/dist/assets/{tasksController.bf12e264.js → tasksController.f3adf725.js} +2 -2
  180. abstra_statics/dist/assets/{toggleHighContrast.c4e1b24d.js → toggleHighContrast.9535bf54.js} +7 -7
  181. abstra_statics/dist/assets/{tsMode.da264aae.js → tsMode.c0f9fe1a.js} +2 -2
  182. abstra_statics/dist/assets/{typescript.db5d7517.js → typescript.310eae6d.js} +3 -3
  183. abstra_statics/dist/assets/url.f5664225.js +2 -0
  184. abstra_statics/dist/assets/{useCodebaseEvents.42573b00.js → useCodebaseEvents.276cc8f0.js} +2 -2
  185. abstra_statics/dist/assets/useTables.18fc3efd.js +2 -0
  186. abstra_statics/dist/assets/userStore.6ab1e5ac.js +2 -0
  187. abstra_statics/dist/assets/uuid.5b8ba8af.js +2 -0
  188. abstra_statics/dist/assets/vue-flow-background.af096866.js +2 -0
  189. abstra_statics/dist/assets/vue-flow-core.6cb99d32.js +22 -0
  190. abstra_statics/dist/assets/{vue-quill.esm-bundler.37119951.js → vue-quill.esm-bundler.e3d34d0e.js} +2 -2
  191. abstra_statics/dist/assets/{workspaceStore.50ef2df1.js → workspaceStore.fac1e9a9.js} +2 -2
  192. abstra_statics/dist/assets/{xml.94b88503.js → xml.04864db4.js} +3 -3
  193. abstra_statics/dist/assets/{yaml.73b7d5ce.js → yaml.f30375fe.js} +3 -3
  194. abstra_statics/dist/console.html +14 -15
  195. abstra_statics/dist/editor.html +13 -13
  196. abstra_statics/dist/player.html +9 -9
  197. tests/e2e/test_crud_files.py +1 -0
  198. abstra_internals/templates/abstraignore +0 -8
  199. abstra_statics/dist/assets/AbstraLogo.vue_vue_type_script_setup_true_lang.3f03a3ef.js +0 -2
  200. abstra_statics/dist/assets/ApiKeys.cb561e62.js +0 -2
  201. abstra_statics/dist/assets/App.dc82115f.js +0 -2
  202. abstra_statics/dist/assets/App.vue_vue_type_style_index_0_lang.3640ec1c.js +0 -2
  203. abstra_statics/dist/assets/ConnectorsView.b428e487.js +0 -2
  204. abstra_statics/dist/assets/ConsoleOmniChat.vue_vue_type_script_setup_true_lang.506f28c6.js +0 -2
  205. abstra_statics/dist/assets/ContentLayout.228d2328.js +0 -2
  206. abstra_statics/dist/assets/DocsButton.vue_vue_type_script_setup_true_lang.61381525.js +0 -2
  207. abstra_statics/dist/assets/EnvVars.242b97c2.js +0 -2
  208. abstra_statics/dist/assets/Error.466dbb94.js +0 -2
  209. abstra_statics/dist/assets/ExclamationCircleOutlined.6d10f60b.js +0 -2
  210. abstra_statics/dist/assets/Files.104385dd.js +0 -2
  211. abstra_statics/dist/assets/Home.80c7e349.js +0 -2
  212. abstra_statics/dist/assets/LoadingContainer.6e2b63e4.js +0 -2
  213. abstra_statics/dist/assets/LoadingOutlined.cd84d9c9.js +0 -2
  214. abstra_statics/dist/assets/Login.409f4a11.js +0 -2
  215. abstra_statics/dist/assets/Logo.2de02c4a.js +0 -2
  216. abstra_statics/dist/assets/Main.4370ed68.js +0 -2
  217. abstra_statics/dist/assets/Navbar.07ba9452.js +0 -2
  218. abstra_statics/dist/assets/NewEditor.769f4459.js +0 -8
  219. abstra_statics/dist/assets/NewEditor.d6e41a05.css +0 -1
  220. abstra_statics/dist/assets/OidcLoginCallback.a89857fe.js +0 -2
  221. abstra_statics/dist/assets/OidcLogoutCallback.d151c695.js +0 -2
  222. abstra_statics/dist/assets/OmniChat.0f64dfec.css +0 -1
  223. abstra_statics/dist/assets/OmniChat.d015bfa8.js +0 -6
  224. abstra_statics/dist/assets/Organizations.b630803f.js +0 -2
  225. abstra_statics/dist/assets/PhPencilSimpleLine.vue.34633dfa.js +0 -2
  226. abstra_statics/dist/assets/Project.c03610d3.js +0 -2
  227. abstra_statics/dist/assets/ScrollArea.vue_vue_type_script_setup_true_lang.3bbea426.js +0 -2
  228. abstra_statics/dist/assets/Sql.3cdc910a.css +0 -1
  229. abstra_statics/dist/assets/Sql.b6aa38ca.js +0 -5
  230. abstra_statics/dist/assets/Steps.7c7e4a4a.js +0 -2
  231. abstra_statics/dist/assets/TableEditor.1e680eaf.css +0 -1
  232. abstra_statics/dist/assets/TableEditor.dc1b4a2d.js +0 -2
  233. abstra_statics/dist/assets/Tables.de30953b.js +0 -2
  234. abstra_statics/dist/assets/TablesDiagram.1ec45dd9.css +0 -1
  235. abstra_statics/dist/assets/TablesDiagram.97d6a43f.js +0 -15
  236. abstra_statics/dist/assets/TablesTabs.vue_vue_type_script_setup_true_lang.63aa07d0.js +0 -2
  237. abstra_statics/dist/assets/View.617ad8d8.js +0 -2
  238. abstra_statics/dist/assets/WidgetPreview.99f14714.js +0 -2
  239. abstra_statics/dist/assets/ant-design.4952c8fb.js +0 -2
  240. abstra_statics/dist/assets/apiKey.864dc66b.js +0 -2
  241. abstra_statics/dist/assets/asyncComputed.25309626.js +0 -2
  242. abstra_statics/dist/assets/colorHelpers.71d6d61d.js +0 -2
  243. abstra_statics/dist/assets/console.3d4702c3.js +0 -25
  244. abstra_statics/dist/assets/constants.56e8988f.js +0 -2
  245. abstra_statics/dist/assets/dayjs.c54f8edb.js +0 -2
  246. abstra_statics/dist/assets/editor.6d0baf6f.js +0 -2
  247. abstra_statics/dist/assets/editor.main.65812c73.js +0 -2
  248. abstra_statics/dist/assets/fetch.5136a62d.js +0 -2
  249. abstra_statics/dist/assets/folder.d7d65e5b.js +0 -2
  250. abstra_statics/dist/assets/index.23283fbb.js +0 -2
  251. abstra_statics/dist/assets/index.58e29274.js +0 -2
  252. abstra_statics/dist/assets/linters.640d6098.js +0 -2
  253. abstra_statics/dist/assets/member.b7ac8000.js +0 -2
  254. abstra_statics/dist/assets/omniChatStore.3431c026.js +0 -8
  255. abstra_statics/dist/assets/player.30593e18.js +0 -2
  256. abstra_statics/dist/assets/polling.d1c934c7.js +0 -2
  257. abstra_statics/dist/assets/router.7f571832.js +0 -2
  258. abstra_statics/dist/assets/router.8fd5b2ad.js +0 -10
  259. abstra_statics/dist/assets/string.2ed1cde3.js +0 -2
  260. abstra_statics/dist/assets/url.8583a595.js +0 -2
  261. abstra_statics/dist/assets/userStore.73b89fbb.js +0 -2
  262. abstra_statics/dist/assets/uuid.dadede91.js +0 -2
  263. abstra_statics/dist/assets/vue-flow-background.d2772d9a.js +0 -22
  264. {abstra-3.23.12.dist-info → abstra-3.24.1.dist-info}/WHEEL +0 -0
  265. {abstra-3.23.12.dist-info → abstra-3.24.1.dist-info}/entry_points.txt +0 -0
  266. {abstra-3.23.12.dist-info → abstra-3.24.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,362 @@
1
+ import shutil
2
+ import tempfile
3
+ import unittest
4
+ from pathlib import Path
5
+
6
+ from abstra_internals.repositories.git.native import NativeGitRepository
7
+ from abstra_internals.repositories.git.types import (
8
+ GitStatus,
9
+ )
10
+
11
+
12
+ class NativeGitRepositoryTest(unittest.TestCase):
13
+ """Test suite for NativeGitRepository"""
14
+
15
+ def setUp(self):
16
+ """Set up test environment"""
17
+ super().setUp()
18
+ self.temp_dir = Path(tempfile.mkdtemp())
19
+ self.repo = NativeGitRepository(self.temp_dir)
20
+ self._original_commit_changes = self.repo.commit_changes
21
+ self.repo.commit_changes = self._commit_changes_wrapper
22
+
23
+ def _commit_changes_wrapper(self, message: str, add_all: bool = True) -> bool:
24
+ """Wrapper for commit_changes that ensures git is configured"""
25
+ self.ensure_git_configured()
26
+ return self._original_commit_changes(message, add_all)
27
+
28
+ def tearDown(self):
29
+ """Clean up test environment"""
30
+ super().tearDown()
31
+ if self.temp_dir and self.temp_dir.exists():
32
+ shutil.rmtree(self.temp_dir, ignore_errors=True)
33
+
34
+ def ensure_git_configured(self):
35
+ """Ensure git is configured for commits (required in CI environments)"""
36
+ if self.repo.is_git_repository() and self.repo.is_git_available():
37
+ if not self.repo.get_git_config("user.name"):
38
+ self.repo.set_git_config("user.name", "Test User")
39
+ if not self.repo.get_git_config("user.email"):
40
+ self.repo.set_git_config("user.email", "test@example.com")
41
+
42
+ def create_test_file(self, filename: str, content: str = "test content"):
43
+ """Create a test file in the repository"""
44
+ file_path = self.temp_dir / filename
45
+ file_path.parent.mkdir(parents=True, exist_ok=True)
46
+ file_path.write_text(content)
47
+ return file_path
48
+
49
+ def modify_test_file(self, filename: str, content: str):
50
+ """Modify an existing test file"""
51
+ file_path = self.temp_dir / filename
52
+ file_path.write_text(content)
53
+ return file_path
54
+
55
+ # Test Methods
56
+
57
+ def test_is_git_available(self):
58
+ """Test git availability check"""
59
+ result = self.repo.is_git_available()
60
+ self.assertIsInstance(result, bool)
61
+
62
+ def test_init_repository(self):
63
+ """Test repository initialization"""
64
+ result = self.repo.init_repository()
65
+ self.assertIsInstance(result, bool)
66
+
67
+ def test_is_git_repository_false(self):
68
+ """Test git repository detection on non-repo"""
69
+ result = self.repo.is_git_repository()
70
+ self.assertFalse(result)
71
+
72
+ def test_is_git_repository_true(self):
73
+ """Test git repository detection on repo"""
74
+ self.repo.init_repository()
75
+ result = self.repo.is_git_repository()
76
+ self.assertTrue(result)
77
+
78
+ def test_find_git_root(self):
79
+ """Test finding git root directory"""
80
+ self.repo.init_repository()
81
+ # Create subdirectory and test from there
82
+ sub_dir = self.temp_dir / "subdir"
83
+ sub_dir.mkdir()
84
+ sub_repo = NativeGitRepository(sub_dir)
85
+ root = sub_repo.find_git_root()
86
+ if root:
87
+ # Resolve both paths to handle macOS symlinks (e.g., /var vs /private/var)
88
+ self.assertEqual(root.resolve(), self.temp_dir.resolve())
89
+
90
+ def test_get_current_branch_new_repo(self):
91
+ """Test getting current branch in new repo"""
92
+ self.repo.init_repository()
93
+ branch = self.repo.get_current_branch()
94
+ self.assertIsInstance(branch, (str, type(None)))
95
+
96
+ def test_get_all_branches_empty(self):
97
+ """Test getting all branches in empty repo"""
98
+ self.repo.init_repository()
99
+ branches = self.repo.get_all_branches()
100
+ self.assertIsInstance(branches, list)
101
+
102
+ def test_commit_and_get_last_commit(self):
103
+ """Test committing and getting last commit"""
104
+ self.repo.init_repository()
105
+ self.create_test_file("test.txt", "initial content")
106
+
107
+ # Commit changes
108
+ success = self.repo.commit_changes("Test commit")
109
+ self.assertTrue(success)
110
+
111
+ # Get last commit
112
+ last_commit = self.repo.get_last_commit()
113
+ self.assertIsNotNone(last_commit)
114
+
115
+ assert last_commit is not None
116
+
117
+ self.assertEqual(last_commit.message, "Test commit")
118
+
119
+ def test_get_commit_history(self):
120
+ """Test getting commit history"""
121
+ self.repo.init_repository()
122
+
123
+ # Create multiple commits
124
+ for i in range(3):
125
+ self.create_test_file(f"test{i}.txt", f"content {i}")
126
+ self.repo.commit_changes(f"Commit {i}")
127
+
128
+ history = self.repo.get_commit_history(limit=2)
129
+ self.assertIsInstance(history, list)
130
+ self.assertLessEqual(len(history), 2)
131
+ if history:
132
+ self.assertEqual(history[0].message, "Commit 2")
133
+
134
+ def test_get_changed_files(self):
135
+ """Test getting changed files"""
136
+ self.repo.init_repository()
137
+
138
+ # Create and commit initial file
139
+ self.create_test_file("test.txt", "initial")
140
+ self.repo.commit_changes("Initial commit")
141
+
142
+ # Modify file
143
+ self.modify_test_file("test.txt", "modified")
144
+
145
+ # Create new file
146
+ self.create_test_file("new.txt", "new content")
147
+
148
+ changed_files = self.repo.get_changed_files()
149
+ self.assertIsInstance(changed_files, list)
150
+ self.assertIn("test.txt", changed_files)
151
+ self.assertIn("new.txt", changed_files)
152
+
153
+ def test_get_changed_files_with_status(self):
154
+ """Test getting changed files with status"""
155
+ self.repo.init_repository()
156
+
157
+ # Create and commit initial file
158
+ self.create_test_file("test.txt", "initial")
159
+ self.repo.commit_changes("Initial commit")
160
+
161
+ # Modify file
162
+ self.modify_test_file("test.txt", "modified")
163
+
164
+ # Create new file
165
+ self.create_test_file("new.txt", "new content")
166
+
167
+ changed_files = self.repo.get_changed_files_with_status()
168
+ self.assertIsInstance(changed_files, list)
169
+
170
+ file_paths = [f.path for f in changed_files]
171
+ self.assertIn("test.txt", file_paths)
172
+ self.assertIn("new.txt", file_paths)
173
+
174
+ def test_has_uncommitted_changes(self):
175
+ """Test checking for uncommitted changes"""
176
+ self.repo.init_repository()
177
+
178
+ # Initially should have no changes after init with first commit
179
+ initial_changes = self.repo.has_uncommitted_changes()
180
+ self.assertFalse(initial_changes)
181
+
182
+ # Create file - should have changes
183
+ self.create_test_file("test.txt", "content")
184
+ after_create = self.repo.has_uncommitted_changes()
185
+ self.assertTrue(after_create)
186
+
187
+ # Commit - should have no changes
188
+ self.repo.commit_changes("Test commit")
189
+ after_commit = self.repo.has_uncommitted_changes()
190
+ self.assertFalse(after_commit)
191
+
192
+ def test_get_repository_status(self):
193
+ """Test getting comprehensive repository status"""
194
+ status = self.repo.get_repository_status()
195
+
196
+ self.assertIsInstance(status, GitStatus)
197
+ self.assertIsInstance(status.available, bool)
198
+ self.assertIsInstance(status.branches, list)
199
+ self.assertIsInstance(status.has_changes, bool)
200
+
201
+ def test_config_operations(self):
202
+ """Test git config operations"""
203
+ self.repo.init_repository()
204
+
205
+ # Set config
206
+ set_success = self.repo.set_git_config("user.name", "Test User")
207
+ self.assertTrue(set_success)
208
+
209
+ # Get config
210
+ retrieved_value = self.repo.get_git_config("user.name")
211
+ self.assertEqual(retrieved_value, "Test User")
212
+
213
+ def test_remote_operations(self):
214
+ """Test remote operations"""
215
+ self.repo.init_repository()
216
+
217
+ # Initially no remotes
218
+ initial_remotes = self.repo.get_remotes()
219
+ self.assertIsInstance(initial_remotes, list)
220
+
221
+ # Add remote
222
+ add_success = self.repo.add_remote("origin", "https://example.com/repo.git")
223
+ self.assertTrue(add_success)
224
+
225
+ # Check remote exists
226
+ has_origin = self.repo.has_remote("origin")
227
+ self.assertTrue(has_origin)
228
+
229
+ # Get remotes after adding
230
+ remotes_after = self.repo.get_remotes()
231
+ self.assertIn("origin", remotes_after)
232
+
233
+ def test_stash_changes(self):
234
+ """Test stashing changes"""
235
+ self.repo.init_repository()
236
+
237
+ # Create and commit initial file
238
+ self.create_test_file("test.txt", "initial")
239
+ self.repo.commit_changes("Initial commit")
240
+
241
+ # Modify file
242
+ self.modify_test_file("test.txt", "modified")
243
+
244
+ # Check we have changes
245
+ has_changes_before = self.repo.has_uncommitted_changes()
246
+ self.assertTrue(has_changes_before)
247
+
248
+ # Stash changes
249
+ stash_success = self.repo.stash_changes("Test stash")
250
+ self.assertTrue(stash_success)
251
+
252
+ # Check changes after stash
253
+ has_changes_after = self.repo.has_uncommitted_changes()
254
+ self.assertFalse(has_changes_after)
255
+
256
+ def test_checkout_commit(self):
257
+ """Test checking out specific commit"""
258
+ self.repo.init_repository()
259
+
260
+ # Create commits
261
+ self.create_test_file("test.txt", "version 1")
262
+ self.repo.commit_changes("First commit")
263
+ first_commit = self.repo.get_last_commit()
264
+
265
+ self.modify_test_file("test.txt", "version 2")
266
+ self.repo.commit_changes("Second commit")
267
+
268
+ # Checkout first commit
269
+ self.assertIsNotNone(first_commit)
270
+
271
+ assert first_commit is not None
272
+
273
+ checkout_success = self.repo.checkout_commit(first_commit.hash)
274
+
275
+ if checkout_success:
276
+ # Read file content after checkout
277
+ file_content = (self.temp_dir / "test.txt").read_text()
278
+ self.assertEqual(file_content, "version 1")
279
+
280
+ def test_get_ahead_behind_count(self):
281
+ """Test calculating ahead/behind counts"""
282
+ self.repo.init_repository()
283
+
284
+ # Create two commits
285
+ self.create_test_file("test1.txt", "content 1")
286
+ self.repo.commit_changes("First commit")
287
+ first_commit = self.repo.get_last_commit()
288
+
289
+ self.create_test_file("test2.txt", "content 2")
290
+ self.repo.commit_changes("Second commit")
291
+ second_commit = self.repo.get_last_commit()
292
+
293
+ self.assertIsNotNone(first_commit)
294
+ self.assertIsNotNone(second_commit)
295
+
296
+ assert first_commit is not None
297
+ assert second_commit is not None
298
+
299
+ # Same commits should be 0,0
300
+ same_counts = self.repo.get_ahead_behind_count(
301
+ first_commit.hash, first_commit.hash
302
+ )
303
+ self.assertEqual(same_counts, (0, 0))
304
+
305
+ # Different commits
306
+ diff_counts = self.repo.get_ahead_behind_count(
307
+ second_commit.hash, first_commit.hash
308
+ )
309
+ self.assertIsInstance(diff_counts, tuple)
310
+ self.assertEqual(len(diff_counts), 2)
311
+
312
+ def test_check_merge_conflicts_simple(self):
313
+ """Test merge conflict detection (simple case)"""
314
+ self.repo.init_repository()
315
+
316
+ # Create commit
317
+ self.create_test_file("test.txt", "content")
318
+ self.repo.commit_changes("Test commit")
319
+ commit = self.repo.get_last_commit()
320
+
321
+ self.assertIsNotNone(commit)
322
+
323
+ assert commit is not None
324
+
325
+ # Check conflict with same commit (should be false)
326
+ has_conflicts = self.repo.check_merge_conflicts(commit.hash)
327
+ self.assertIsInstance(has_conflicts, bool)
328
+
329
+ def test_revert_commit(self):
330
+ """Test reverting to previous commit"""
331
+ self.repo.init_repository()
332
+
333
+ # Create first version
334
+ self.create_test_file("test.txt", "version 1")
335
+ self.repo.commit_changes("First commit")
336
+ first_commit = self.repo.get_last_commit()
337
+
338
+ # Create second version
339
+ self.modify_test_file("test.txt", "version 2")
340
+ self.repo.commit_changes("Second commit")
341
+
342
+ # Revert to first commit
343
+ self.assertIsNotNone(first_commit)
344
+
345
+ assert first_commit is not None
346
+
347
+ revert_success = self.repo.revert_commit(first_commit.hash)
348
+
349
+ if revert_success:
350
+ # Check file content
351
+ file_content = (self.temp_dir / "test.txt").read_text()
352
+ self.assertEqual(file_content, "version 1")
353
+
354
+
355
+ if __name__ == "__main__":
356
+ loader = unittest.TestLoader()
357
+ suite = unittest.TestSuite()
358
+
359
+ suite.addTests(loader.loadTestsFromTestCase(NativeGitRepositoryTest))
360
+
361
+ runner = unittest.TextTestRunner(verbosity=2)
362
+ runner.run(suite)