zrb 1.0.0a8__tar.gz → 1.0.0a9__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 (207) hide show
  1. {zrb-1.0.0a8 → zrb-1.0.0a9}/PKG-INFO +2 -1
  2. {zrb-1.0.0a8 → zrb-1.0.0a9}/pyproject.toml +1 -1
  3. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/__init__.py +14 -6
  4. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/group.py +8 -3
  5. zrb-1.0.0a9/src/zrb/builtin/setup/common_input.py +35 -0
  6. zrb-1.0.0a9/src/zrb/builtin/setup/dev/asdf.py +86 -0
  7. zrb-1.0.0a9/src/zrb/builtin/setup/dev/asdf_helper.py +44 -0
  8. zrb-1.0.0a9/src/zrb/builtin/setup/dev/tmux.py +50 -0
  9. zrb-1.0.0a9/src/zrb/builtin/setup/dev/tmux_helper.py +13 -0
  10. zrb-1.0.0a9/src/zrb/builtin/setup/system/latex/ubuntu.py +18 -0
  11. zrb-1.0.0a9/src/zrb/builtin/setup/system/ubuntu.py +28 -0
  12. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/todo.py +5 -5
  13. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/config.py +3 -0
  14. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/task/cmd_task.py +27 -3
  15. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/task/llm_task.py +24 -18
  16. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/task/rsync_task.py +8 -8
  17. zrb-1.0.0a9/src/zrb/util/cmd/command.py +33 -0
  18. zrb-1.0.0a9/src/zrb/util/codemod/add_parent_to_class.py +38 -0
  19. zrb-1.0.0a9/src/zrb/util/string/format.py +19 -0
  20. zrb-1.0.0a9/src/zrb/xcom/__init__.py +0 -0
  21. zrb-1.0.0a8/src/zrb/util/string/format.py +0 -9
  22. {zrb-1.0.0a8 → zrb-1.0.0a9}/README.md +0 -0
  23. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/__init__.py +0 -0
  24. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/__main__.py +0 -0
  25. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/attr/__init__.py +0 -0
  26. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/attr/type.py +0 -0
  27. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/base64.py +0 -0
  28. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/git.py +0 -0
  29. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/git_subtree.py +0 -0
  30. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/llm/llm_chat.py +0 -0
  31. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/llm/tool/cli.py +0 -0
  32. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/llm/tool/rag.py +0 -0
  33. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/llm/tool/web.py +0 -0
  34. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/md5.py +0 -0
  35. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/__init__.py +0 -0
  36. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/__init__.py +0 -0
  37. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp.py +0 -0
  38. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/.gitignore +0 -0
  39. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/README.md +0 -0
  40. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/__init__.py +0 -0
  41. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/_zrb/config.py +0 -0
  42. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/_zrb/group.py +0 -0
  43. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/_zrb/helper.py +0 -0
  44. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/_zrb/main.py +0 -0
  45. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/_zrb/venv_task.py +0 -0
  46. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/common/__init__.py +0 -0
  47. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/common/app.py +0 -0
  48. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/common/db_engine.py +0 -0
  49. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/common/db_repository.py +0 -0
  50. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/common/error.py +0 -0
  51. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/common/schema.py +0 -0
  52. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/common/usecase.py +0 -0
  53. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/config.py +0 -0
  54. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/main.py +0 -0
  55. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/migrate.py +0 -0
  56. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/module/__init__.py +0 -0
  57. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/module/auth/alembic.ini +0 -0
  58. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/module/auth/client/api_client.py +0 -0
  59. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/module/auth/client/base_client.py +0 -0
  60. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/module/auth/client/direct_client.py +0 -0
  61. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/module/auth/client/factory.py +0 -0
  62. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/module/auth/migration/README +0 -0
  63. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/module/auth/migration/env.py +0 -0
  64. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/module/auth/migration/script.py.mako +0 -0
  65. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/module/auth/migration/versions/3093c7336477_add_user_table.py +0 -0
  66. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/module/auth/migration_metadata.py +0 -0
  67. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/module/auth/route.py +0 -0
  68. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/module/auth/service/__init__.py +0 -0
  69. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/module/auth/service/user/__init__.py +0 -0
  70. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/module/auth/service/user/repository/__init__.py +0 -0
  71. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/module/auth/service/user/repository/db_repository.py +0 -0
  72. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/module/auth/service/user/repository/factory.py +0 -0
  73. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/module/auth/service/user/repository/repository.py +0 -0
  74. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/module/auth/service/user/usecase.py +0 -0
  75. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/module/gateway/alembic.ini +0 -0
  76. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/module/gateway/migration/README +0 -0
  77. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/module/gateway/migration/env.py +0 -0
  78. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/module/gateway/migration/script.py.mako +0 -0
  79. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/module/gateway/migration/versions/.gitkeep +0 -0
  80. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/module/gateway/migration_metadata.py +0 -0
  81. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/module/gateway/route.py +0 -0
  82. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/requirements.txt +0 -0
  83. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/schema/__init__.py +0 -0
  84. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/schema/role.py +0 -0
  85. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/schema/user.py +0 -0
  86. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/add/fastapp_template/template.env +0 -0
  87. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/create/__init__.py +0 -0
  88. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/create/create.py +0 -0
  89. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/create/project-template/README.md +0 -0
  90. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/project/create/project-template/zrb_init.py +0 -0
  91. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/python.py +0 -0
  92. /zrb-1.0.0a8/src/zrb/builtin/shell/__init__.py → /zrb-1.0.0a9/src/zrb/builtin/setup/dev/tmux_config.sh +0 -0
  93. {zrb-1.0.0a8/src/zrb/builtin/shell/autocomplete → zrb-1.0.0a9/src/zrb/builtin/shell}/__init__.py +0 -0
  94. {zrb-1.0.0a8/src/zrb/callback → zrb-1.0.0a9/src/zrb/builtin/shell/autocomplete}/__init__.py +0 -0
  95. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/shell/autocomplete/bash.py +0 -0
  96. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/shell/autocomplete/subcmd.py +0 -0
  97. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/builtin/shell/autocomplete/zsh.py +0 -0
  98. {zrb-1.0.0a8/src/zrb/cmd → zrb-1.0.0a9/src/zrb/callback}/__init__.py +0 -0
  99. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/callback/any_callback.py +0 -0
  100. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/callback/callback.py +0 -0
  101. {zrb-1.0.0a8/src/zrb/content_transformer → zrb-1.0.0a9/src/zrb/cmd}/__init__.py +0 -0
  102. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/cmd/cmd_result.py +0 -0
  103. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/cmd/cmd_val.py +0 -0
  104. {zrb-1.0.0a8/src/zrb/context → zrb-1.0.0a9/src/zrb/content_transformer}/__init__.py +0 -0
  105. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/content_transformer/any_content_transformer.py +0 -0
  106. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/content_transformer/content_transformer.py +0 -0
  107. {zrb-1.0.0a8/src/zrb/dot_dict → zrb-1.0.0a9/src/zrb/context}/__init__.py +0 -0
  108. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/context/any_context.py +0 -0
  109. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/context/any_shared_context.py +0 -0
  110. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/context/context.py +0 -0
  111. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/context/shared_context.py +0 -0
  112. {zrb-1.0.0a8/src/zrb/env → zrb-1.0.0a9/src/zrb/dot_dict}/__init__.py +0 -0
  113. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/dot_dict/dot_dict.py +0 -0
  114. {zrb-1.0.0a8/src/zrb/group → zrb-1.0.0a9/src/zrb/env}/__init__.py +0 -0
  115. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/env/any_env.py +0 -0
  116. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/env/env.py +0 -0
  117. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/env/env_file.py +0 -0
  118. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/env/env_map.py +0 -0
  119. {zrb-1.0.0a8/src/zrb/input → zrb-1.0.0a9/src/zrb/group}/__init__.py +0 -0
  120. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/group/any_group.py +0 -0
  121. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/group/group.py +0 -0
  122. {zrb-1.0.0a8/src/zrb/runner → zrb-1.0.0a9/src/zrb/input}/__init__.py +0 -0
  123. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/input/any_input.py +0 -0
  124. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/input/base_input.py +0 -0
  125. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/input/bool_input.py +0 -0
  126. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/input/float_input.py +0 -0
  127. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/input/int_input.py +0 -0
  128. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/input/option_input.py +0 -0
  129. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/input/password_input.py +0 -0
  130. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/input/str_input.py +0 -0
  131. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/input/text_input.py +0 -0
  132. {zrb-1.0.0a8/src/zrb/runner/web_controller → zrb-1.0.0a9/src/zrb/runner}/__init__.py +0 -0
  133. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/runner/cli.py +0 -0
  134. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/runner/web_app.py +0 -0
  135. {zrb-1.0.0a8/src/zrb/runner/web_controller/group_info_ui → zrb-1.0.0a9/src/zrb/runner/web_controller}/__init__.py +0 -0
  136. {zrb-1.0.0a8/src/zrb/runner/web_controller/home_page → zrb-1.0.0a9/src/zrb/runner/web_controller/group_info_ui}/__init__.py +0 -0
  137. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/runner/web_controller/group_info_ui/controller.py +0 -0
  138. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/runner/web_controller/group_info_ui/partial/group_info.html +0 -0
  139. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/runner/web_controller/group_info_ui/partial/group_li.html +0 -0
  140. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/runner/web_controller/group_info_ui/partial/task_info.html +0 -0
  141. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/runner/web_controller/group_info_ui/partial/task_li.html +0 -0
  142. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/runner/web_controller/group_info_ui/view.html +0 -0
  143. {zrb-1.0.0a8/src/zrb/runner/web_controller/task_ui → zrb-1.0.0a9/src/zrb/runner/web_controller/home_page}/__init__.py +0 -0
  144. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/runner/web_controller/home_page/controller.py +0 -0
  145. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/runner/web_controller/home_page/partial/group_info.html +0 -0
  146. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/runner/web_controller/home_page/partial/group_li.html +0 -0
  147. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/runner/web_controller/home_page/partial/task_info.html +0 -0
  148. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/runner/web_controller/home_page/partial/task_li.html +0 -0
  149. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/runner/web_controller/home_page/view.html +0 -0
  150. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/runner/web_controller/static/favicon-32x32.png +0 -0
  151. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/runner/web_controller/static/pico.min.css +0 -0
  152. {zrb-1.0.0a8/src/zrb/session → zrb-1.0.0a9/src/zrb/runner/web_controller/task_ui}/__init__.py +0 -0
  153. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/runner/web_controller/task_ui/controller.py +0 -0
  154. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/runner/web_controller/task_ui/partial/common-util.js +0 -0
  155. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/runner/web_controller/task_ui/partial/input.html +0 -0
  156. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/runner/web_controller/task_ui/partial/main.js +0 -0
  157. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/runner/web_controller/task_ui/partial/show-existing-session.js +0 -0
  158. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/runner/web_controller/task_ui/partial/visualize-history.js +0 -0
  159. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/runner/web_controller/task_ui/view.html +0 -0
  160. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/runner/web_util.py +0 -0
  161. {zrb-1.0.0a8/src/zrb/session_state_log → zrb-1.0.0a9/src/zrb/session}/__init__.py +0 -0
  162. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/session/any_session.py +0 -0
  163. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/session/session.py +0 -0
  164. {zrb-1.0.0a8/src/zrb/session_state_logger → zrb-1.0.0a9/src/zrb/session_state_log}/__init__.py +0 -0
  165. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/session_state_log/session_state_log.py +0 -0
  166. {zrb-1.0.0a8/src/zrb/task → zrb-1.0.0a9/src/zrb/session_state_logger}/__init__.py +0 -0
  167. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/session_state_logger/any_session_state_logger.py +0 -0
  168. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/session_state_logger/default_session_state_logger.py +0 -0
  169. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/session_state_logger/file_session_state_logger.py +0 -0
  170. {zrb-1.0.0a8/src/zrb/task_status → zrb-1.0.0a9/src/zrb/task}/__init__.py +0 -0
  171. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/task/any_task.py +0 -0
  172. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/task/base_task.py +0 -0
  173. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/task/base_trigger.py +0 -0
  174. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/task/http_check.py +0 -0
  175. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/task/make_task.py +0 -0
  176. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/task/scaffolder.py +0 -0
  177. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/task/scheduler.py +0 -0
  178. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/task/task.py +0 -0
  179. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/task/tcp_check.py +0 -0
  180. {zrb-1.0.0a8/src/zrb/util → zrb-1.0.0a9/src/zrb/task_status}/__init__.py +0 -0
  181. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/task_status/task_status.py +0 -0
  182. {zrb-1.0.0a8/src/zrb/util/cli → zrb-1.0.0a9/src/zrb/util}/__init__.py +0 -0
  183. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/util/attr.py +0 -0
  184. {zrb-1.0.0a8/src/zrb/util/cmd → zrb-1.0.0a9/src/zrb/util/cli}/__init__.py +0 -0
  185. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/util/cli/style.py +0 -0
  186. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/util/cli/subcommand.py +0 -0
  187. {zrb-1.0.0a8/src/zrb/util/codemod → zrb-1.0.0a9/src/zrb/util/cmd}/__init__.py +0 -0
  188. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/util/cmd/remote.py +0 -0
  189. {zrb-1.0.0a8/src/zrb/util/string → zrb-1.0.0a9/src/zrb/util/codemod}/__init__.py +0 -0
  190. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/util/codemod/add_code_to_class.py +0 -0
  191. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/util/codemod/add_code_to_function.py +0 -0
  192. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/util/codemod/add_code_to_method.py +0 -0
  193. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/util/codemod/add_key_to_dict.py +0 -0
  194. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/util/codemod/add_param_to_function_call.py +0 -0
  195. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/util/codemod/add_property_to_class.py +0 -0
  196. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/util/cron.py +0 -0
  197. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/util/git.py +0 -0
  198. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/util/git_subtree.py +0 -0
  199. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/util/group.py +0 -0
  200. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/util/llm/tool.py +0 -0
  201. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/util/load.py +0 -0
  202. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/util/run.py +0 -0
  203. {zrb-1.0.0a8/src/zrb/xcom → zrb-1.0.0a9/src/zrb/util/string}/__init__.py +0 -0
  204. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/util/string/conversion.py +0 -0
  205. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/util/string/name.py +0 -0
  206. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/util/todo.py +0 -0
  207. {zrb-1.0.0a8 → zrb-1.0.0a9}/src/zrb/xcom/xcom.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: zrb
3
- Version: 1.0.0a8
3
+ Version: 1.0.0a9
4
4
  Summary: Your Automation Powerhouse
5
5
  Home-page: https://github.com/state-alchemists/zrb
6
6
  License: AGPL-3.0-or-later
@@ -13,6 +13,7 @@ Classifier: Programming Language :: Python :: 3
13
13
  Classifier: Programming Language :: Python :: 3.10
14
14
  Classifier: Programming Language :: Python :: 3.11
15
15
  Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
16
17
  Provides-Extra: rag
17
18
  Requires-Dist: autopep8 (>=2.0.4,<3.0.0)
18
19
  Requires-Dist: beautifulsoup4 (>=4.12.3,<5.0.0)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "zrb"
3
- version = "1.0.0a8"
3
+ version = "1.0.0a9"
4
4
  description = "Your Automation Powerhouse"
5
5
  authors = ["Go Frendi Gunawan <gofrendiasgard@gmail.com>"]
6
6
  license = "AGPL-3.0-or-later"
@@ -12,10 +12,14 @@ from zrb.builtin.md5 import hash_md5, sum_md5
12
12
  from zrb.builtin.project.add.fastapp import add_fastapp_to_project
13
13
  from zrb.builtin.project.create.create import create_project
14
14
  from zrb.builtin.python import format_python_code
15
+ from zrb.builtin.setup.dev.asdf import setup_asdf
16
+ from zrb.builtin.setup.dev.tmux import setup_tmux
17
+ from zrb.builtin.setup.system.latex.ubuntu import setup_latex_on_ubuntu
18
+ from zrb.builtin.setup.system.ubuntu import setup_ubuntu
15
19
  from zrb.builtin.shell.autocomplete.bash import make_bash_autocomplete
16
20
  from zrb.builtin.shell.autocomplete.subcmd import get_shell_subcommands
17
21
  from zrb.builtin.shell.autocomplete.zsh import make_zsh_autocomplete
18
- from zrb.builtin.todo import todo_add, todo_complete, todo_edit, todo_list, todo_log
22
+ from zrb.builtin.todo import add_todo, complete_todo, edit_todo, list_todo, log_todo
19
23
 
20
24
  assert create_project
21
25
  assert add_fastapp_to_project
@@ -36,8 +40,12 @@ assert git_push
36
40
  assert git_add_subtree
37
41
  assert git_pull_subtree
38
42
  assert git_push_subtree
39
- assert todo_list
40
- assert todo_add
41
- assert todo_edit
42
- assert todo_complete
43
- assert todo_log
43
+ assert list_todo
44
+ assert add_todo
45
+ assert edit_todo
46
+ assert complete_todo
47
+ assert log_todo
48
+ assert setup_ubuntu
49
+ assert setup_latex_on_ubuntu
50
+ assert setup_asdf
51
+ assert setup_tmux
@@ -33,11 +33,16 @@ add_fastapp_to_project_group = add_to_project_group.add_group(
33
33
  Group(name="fastapp", description="🚀 Add Fastapp resources")
34
34
  )
35
35
 
36
- setup_group = cli.add_group(Group(name="setup", description="🛠️ Setup"))
36
+ setup_group = cli.add_group(Group(name="setup", description="🔧 Setup"))
37
37
  setup_system_group = setup_group.add_group(
38
- Group(name="system", description="🛠️ Setup system")
38
+ Group(name="system", description="🔧 Setup system")
39
+ )
40
+ setup_latex_group = setup_system_group.add_group(
41
+ Group(name="latex", description="✍️ Setup LaTeX")
42
+ )
43
+ setup_dev_group = setup_group.add_group(
44
+ Group(name="dev", description="💻 Setup developer tools")
39
45
  )
40
- setup_dev_group = setup_group.add_group(Group(name="dev", description="🧑‍💻 Setup dev"))
41
46
  setup_service_group = setup_group.add_group(
42
47
  Group(name="services", description="🌐 Setup services")
43
48
  )
@@ -0,0 +1,35 @@
1
+ from zrb.input.bool_input import BoolInput
2
+ from zrb.input.option_input import OptionInput
3
+
4
+ package_manager_input = OptionInput(
5
+ name="package-manager",
6
+ description="Your package manager",
7
+ prompt="Your package manager",
8
+ options=["apt", "dnf", "pacman", "zypper", "pkg", "brew", "spack"],
9
+ default_str="apt",
10
+ )
11
+
12
+ use_sudo_input = BoolInput(
13
+ name="use-sudo",
14
+ description="Use sudo or not",
15
+ prompt="Need sudo",
16
+ default_str="yes",
17
+ )
18
+
19
+ setup_bash_input = BoolInput(
20
+ name="setup-bash",
21
+ description="Setup bash",
22
+ prompt="Setup bash",
23
+ default_str="yes",
24
+ )
25
+
26
+ setup_zsh_input = BoolInput(
27
+ name="setup-zsh", description="Setup zsh", prompt="Setup zsh", default_str="yes"
28
+ )
29
+
30
+ setup_powershell_input = BoolInput(
31
+ name="setup-powershell",
32
+ description="Setup powershell",
33
+ prompt="Setup powershell",
34
+ default_str="no",
35
+ )
@@ -0,0 +1,86 @@
1
+ import os
2
+
3
+ from zrb.builtin.group import setup_dev_group
4
+ from zrb.builtin.setup.common_input import (
5
+ package_manager_input,
6
+ setup_bash_input,
7
+ setup_powershell_input,
8
+ setup_zsh_input,
9
+ use_sudo_input,
10
+ )
11
+ from zrb.builtin.setup.dev.asdf_helper import (
12
+ check_inexist_asdf_dir,
13
+ get_install_prerequisites_cmd,
14
+ setup_asdf_ps_config,
15
+ setup_asdf_sh_config,
16
+ )
17
+ from zrb.context.any_context import AnyContext
18
+ from zrb.task.cmd_task import CmdTask
19
+ from zrb.task.make_task import make_task
20
+
21
+ install_asdf_prerequisites = CmdTask(
22
+ name="install-asdf-prerequisites",
23
+ input=[package_manager_input, use_sudo_input],
24
+ cmd=get_install_prerequisites_cmd,
25
+ )
26
+
27
+
28
+ download_asdf = CmdTask(
29
+ name="download-asdf",
30
+ cmd="git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.14.1",
31
+ execute_condition=check_inexist_asdf_dir,
32
+ )
33
+ install_asdf_prerequisites >> download_asdf
34
+
35
+
36
+ @make_task(
37
+ name="setup-asdf-on-bash",
38
+ input=setup_bash_input,
39
+ execute_condition='{ctx.input["setup-bash"]}',
40
+ upstream=download_asdf,
41
+ )
42
+ def setup_asdf_on_bash(ctx: AnyContext):
43
+ ctx.print("Configure asdf for bash")
44
+ setup_asdf_sh_config(os.path.expanduser(os.path.join("~", ".bashrc")))
45
+
46
+
47
+ @make_task(
48
+ name="setup-asdf-on-zsh",
49
+ input=setup_zsh_input,
50
+ execute_condition='{ctx.input["setup-zsh"]}',
51
+ upstream=download_asdf,
52
+ )
53
+ def setup_asdf_on_zsh(ctx: AnyContext):
54
+ ctx.print("Configure asdf for zsh")
55
+ setup_asdf_sh_config(os.path.expanduser(os.path.join("~", ".zshrc")))
56
+
57
+
58
+ @make_task(
59
+ name="setup-asdf-on-powershell",
60
+ input=setup_powershell_input,
61
+ execute_condition='{ctx.input["setup-powershell"]}',
62
+ upstream=download_asdf,
63
+ )
64
+ def setup_asdf_on_powershell(ctx: AnyContext):
65
+ ctx.print("Configure asdf for powershell")
66
+ setup_asdf_ps_config(
67
+ os.path.expanduser(os.path.join("~", ".config", "powershell", "profile.ps1"))
68
+ )
69
+
70
+
71
+ @make_task(
72
+ name="setup-asdf",
73
+ description="🧰 Setup `asdf`.",
74
+ group=setup_dev_group,
75
+ alias="asdf",
76
+ )
77
+ def setup_asdf(ctx: AnyContext):
78
+ ctx.print("Setup complete, restart your terminal to continue")
79
+ ctx.print("Some useful commands:")
80
+ ctx.print("- asdf plugin add python")
81
+ ctx.print("- asdf list all python")
82
+ ctx.print("- asdf install python 3.12.0")
83
+ ctx.print("- asdf global python 3.12.0")
84
+
85
+
86
+ setup_asdf << [setup_asdf_on_bash, setup_asdf_on_zsh, setup_asdf_on_powershell]
@@ -0,0 +1,44 @@
1
+ import os
2
+
3
+ from zrb.context.any_context import AnyContext
4
+
5
+
6
+ def get_install_prerequisites_cmd(ctx: AnyContext) -> str:
7
+ package_manager: str = ctx.input["package-manager"]
8
+ if package_manager in ["brew", "spack"]:
9
+ cmd = f"{package_manager} install coreutils curl git"
10
+ elif package_manager == "pacman":
11
+ cmd = f"{package_manager} -S curl git"
12
+ else:
13
+ cmd = f"{package_manager} install curl git"
14
+ use_sudo: bool = ctx.input["use-sudo"]
15
+ if use_sudo:
16
+ return f"sudo {cmd}"
17
+ return cmd
18
+
19
+
20
+ def check_inexist_asdf_dir(_: AnyContext):
21
+ asdf_dir = os.path.expanduser(os.path.join("~", ".asdf"))
22
+ return not os.path.isdir(asdf_dir)
23
+
24
+
25
+ def setup_asdf_sh_config(file_path: str):
26
+ _setup_asdf_config(file_path, '. "$HOME/.asdf/asdf.sh"')
27
+
28
+
29
+ def setup_asdf_ps_config(file_path: str):
30
+ _setup_asdf_config(file_path, '. "$HOME/.asdf/asdf.ps1"')
31
+
32
+
33
+ def _setup_asdf_config(file_path: str, asdf_config: str):
34
+ dir_path = os.path.dirname(file_path)
35
+ os.makedirs(dir_path, exist_ok=True)
36
+ if not os.path.isfile(file_path):
37
+ with open(file_path, "w") as f:
38
+ f.write("")
39
+ with open(file_path, "r") as f:
40
+ content = f.read()
41
+ if asdf_config in content:
42
+ return
43
+ with open(file_path, "a") as f:
44
+ f.write(f"\n{asdf_config}\n")
@@ -0,0 +1,50 @@
1
+ import os
2
+
3
+ from zrb.builtin.group import setup_dev_group
4
+ from zrb.builtin.setup.common_input import package_manager_input, use_sudo_input
5
+ from zrb.builtin.setup.dev.tmux_helper import get_install_tmux_cmd
6
+ from zrb.context.any_context import AnyContext
7
+ from zrb.input.str_input import StrInput
8
+ from zrb.task.cmd_task import CmdTask
9
+ from zrb.task.make_task import make_task
10
+
11
+ install_tmux = CmdTask(
12
+ name="install-tmux",
13
+ input=[package_manager_input, use_sudo_input],
14
+ cmd=get_install_tmux_cmd,
15
+ )
16
+
17
+
18
+ @make_task(
19
+ name="setup-tmux",
20
+ input=StrInput(
21
+ name="tmux-config",
22
+ description="Tmux config file",
23
+ prompt="Tmux config file",
24
+ default_str="~/.tmux.conf",
25
+ ),
26
+ description="🖥️ Setup `tmux`.",
27
+ group=setup_dev_group,
28
+ alias="tmux",
29
+ )
30
+ def setup_tmux(ctx: AnyContext):
31
+ with open(os.path.join(os.path.dirname(__file__), "tmux_config.sh"), "r") as f:
32
+ tmux_config_template = f.read()
33
+ tmux_config_file = os.path.expanduser(ctx.input["tmux-config"])
34
+ tmux_config_dir = os.path.dirname(tmux_config_file)
35
+ # Make sure config file exists
36
+ os.makedirs(tmux_config_dir, exist_ok=True)
37
+ if not os.path.isfile(tmux_config_file):
38
+ with open(tmux_config_file, "w") as f:
39
+ f.write("")
40
+ with open(tmux_config_file, "r") as f:
41
+ # config file already contain the config
42
+ if tmux_config_template in f.read():
43
+ return
44
+ # Write config
45
+ with open(tmux_config_file, "a") as f:
46
+ f.write(f"\n{tmux_config_template}\n")
47
+ ctx.print("Setup complete, restart your terminal to continue")
48
+
49
+
50
+ install_tmux >> setup_tmux
@@ -0,0 +1,13 @@
1
+ from zrb.context.any_context import AnyContext
2
+
3
+
4
+ def get_install_tmux_cmd(ctx: AnyContext) -> str:
5
+ package_manager: str = ctx.input["package-manager"]
6
+ if package_manager == "pacman":
7
+ cmd = f"{package_manager} -S tmux"
8
+ else:
9
+ cmd = f"{package_manager} install tmux"
10
+ use_sudo: bool = ctx.input["use-sudo"]
11
+ if use_sudo:
12
+ return f"sudo {cmd}"
13
+ return cmd
@@ -0,0 +1,18 @@
1
+ from zrb.builtin.group import setup_latex_group
2
+ from zrb.builtin.setup.system.ubuntu import setup_ubuntu
3
+ from zrb.task.cmd_task import CmdTask
4
+
5
+ setup_latex_on_ubuntu = setup_latex_group.add_task(
6
+ CmdTask(
7
+ name="setup-latex-on-ubuntu",
8
+ description="🐧 Setup LaTeX on Ubuntu",
9
+ cmd=[
10
+ "sudo apt install -y \\",
11
+ "texlive-full texlive-latex-base texlive-fonts-recommended \\",
12
+ "texlive-fonts-extra texlive-latex-extra",
13
+ ],
14
+ render_cmd=False,
15
+ ),
16
+ alias="ubuntu",
17
+ )
18
+ setup_ubuntu >> setup_latex_on_ubuntu
@@ -0,0 +1,28 @@
1
+ from zrb.builtin.group import setup_system_group
2
+ from zrb.task.cmd_task import CmdTask
3
+
4
+ update_ubuntu = CmdTask(name="update-ubuntu", cmd="sudo apt update", render_cmd=False)
5
+
6
+ upgrade_todo = CmdTask(
7
+ name="upgrade-ubuntu", cmd="sudo apt upgrade -y", render_cmd=False
8
+ )
9
+ update_ubuntu >> upgrade_todo
10
+
11
+ setup_ubuntu = setup_system_group.add_task(
12
+ CmdTask(
13
+ name="setup-ubuntu",
14
+ description="🐧 Setup ubuntu",
15
+ cmd=[
16
+ "sudo apt install -y \\",
17
+ "build-essential python3-distutils libssl-dev zlib1g-dev \\"
18
+ "libbz2-dev libreadline-dev libsqlite3-dev libpq-dev python3-dev \\",
19
+ "llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev libffi-dev \\",
20
+ "liblzma-dev python3-openssl libblas-dev liblapack-dev rustc \\",
21
+ "golang gfortran fd-find ripgrep wget curl git ncat zip unzip \\",
22
+ "cmake make tree tmux zsh neovim xdotool xsel",
23
+ ],
24
+ render_cmd=False,
25
+ ),
26
+ alias="ubuntu",
27
+ )
28
+ upgrade_todo >> setup_ubuntu
@@ -51,7 +51,7 @@ from zrb.util.todo import (
51
51
  group=todo_group,
52
52
  alias="add",
53
53
  )
54
- def todo_add(ctx: AnyContext):
54
+ def add_todo(ctx: AnyContext):
55
55
  todo_file_path = os.path.join(TODO_DIR, "todo.txt")
56
56
  todo_list: list[TodoTaskModel] = []
57
57
  if os.path.isfile(todo_file_path):
@@ -81,7 +81,7 @@ def todo_add(ctx: AnyContext):
81
81
 
82
82
 
83
83
  @make_task(name="todo-list", description="📋 List todo", group=todo_group, alias="list")
84
- def todo_list(ctx: AnyContext):
84
+ def list_todo(ctx: AnyContext):
85
85
  todo_file_path = os.path.join(TODO_DIR, "todo.txt")
86
86
  todo_tasks: list[TodoTaskModel] = []
87
87
  if os.path.isfile(todo_file_path):
@@ -96,7 +96,7 @@ def todo_list(ctx: AnyContext):
96
96
  group=todo_group,
97
97
  alias="complete",
98
98
  )
99
- def todo_complete(ctx: AnyContext):
99
+ def complete_todo(ctx: AnyContext):
100
100
  todo_file_path = os.path.join(TODO_DIR, "todo.txt")
101
101
  todo_list: list[TodoTaskModel] = []
102
102
  if os.path.isfile(todo_file_path):
@@ -142,7 +142,7 @@ def todo_complete(ctx: AnyContext):
142
142
  group=todo_group,
143
143
  alias="log",
144
144
  )
145
- def todo_log(ctx: AnyContext):
145
+ def log_todo(ctx: AnyContext):
146
146
  todo_file_path = os.path.join(TODO_DIR, "todo.txt")
147
147
  todo_list: list[TodoTaskModel] = []
148
148
  if os.path.isfile(todo_file_path):
@@ -196,7 +196,7 @@ def _get_default_start() -> str:
196
196
  group=todo_group,
197
197
  alias="edit",
198
198
  )
199
- def todo_edit(ctx: AnyContext):
199
+ def edit_todo(ctx: AnyContext):
200
200
  todo_list = [
201
201
  cascade_todo_task(line_to_todo_task(line))
202
202
  for line in ctx.input.text.split("\n")
@@ -49,6 +49,9 @@ LOGGING_LEVEL = _get_log_level(os.getenv("ZRB_LOGGING_LEVEL", "WARNING"))
49
49
  LOAD_BUILTIN = to_boolean(os.getenv("ZRB_LOAD_BUILTIN", "1"))
50
50
  ENV_PREFIX = os.getenv("ZRB_ENV", "")
51
51
  SHOW_PROMPT = to_boolean(os.getenv("ZRB_SHOW_PROMPT", "1"))
52
+ WARN_UNRECOMMENDED_COMMAND = to_boolean(
53
+ os.getenv("ZRB_WARN_UNRECOMMENDED_COMMAND", "1")
54
+ )
52
55
  SESSION_LOG_DIR = os.getenv(
53
56
  "ZRB_SESSION_LOG_DIR", os.path.expanduser(os.path.join("~", ".zrb-session"))
54
57
  )
@@ -5,13 +5,14 @@ import sys
5
5
  from zrb.attr.type import BoolAttr, IntAttr, StrAttr
6
6
  from zrb.cmd.cmd_result import CmdResult
7
7
  from zrb.cmd.cmd_val import AnyCmdVal, CmdVal, SingleCmdVal
8
- from zrb.config import DEFAULT_SHELL
8
+ from zrb.config import DEFAULT_SHELL, WARN_UNRECOMMENDED_COMMAND
9
9
  from zrb.context.any_context import AnyContext
10
10
  from zrb.env.any_env import AnyEnv
11
11
  from zrb.input.any_input import AnyInput
12
12
  from zrb.task.any_task import AnyTask
13
13
  from zrb.task.base_task import BaseTask
14
14
  from zrb.util.attr import get_int_attr, get_str_attr
15
+ from zrb.util.cmd.command import check_unrecommended_commands
15
16
  from zrb.util.cmd.remote import get_remote_cmd_script
16
17
 
17
18
 
@@ -32,6 +33,7 @@ class CmdTask(BaseTask):
32
33
  remote_host: StrAttr | None = None,
33
34
  render_remote_host: bool = True,
34
35
  remote_port: IntAttr | None = None,
36
+ render_remote_port: bool = True,
35
37
  remote_user: StrAttr | None = None,
36
38
  render_remote_user: bool = True,
37
39
  remote_password: StrAttr | None = None,
@@ -42,6 +44,7 @@ class CmdTask(BaseTask):
42
44
  render_cmd: bool = True,
43
45
  cwd: str | None = None,
44
46
  render_cwd: bool = True,
47
+ warn_unrecommended_command: bool | None = None,
45
48
  max_output_line: int = 1000,
46
49
  max_error_line: int = 1000,
47
50
  execute_condition: BoolAttr = True,
@@ -83,6 +86,7 @@ class CmdTask(BaseTask):
83
86
  self._remote_host = remote_host
84
87
  self._render_remote_host = render_remote_host
85
88
  self._remote_port = remote_port
89
+ self._render_remote_port = render_remote_port
86
90
  self._remote_user = remote_user
87
91
  self._render_remote_user = render_remote_user
88
92
  self._remote_password = remote_password
@@ -95,6 +99,7 @@ class CmdTask(BaseTask):
95
99
  self._render_cwd = render_cwd
96
100
  self._max_output_line = max_output_line
97
101
  self._max_error_line = max_error_line
102
+ self._should_warn_unrecommended_command = warn_unrecommended_command
98
103
 
99
104
  async def _exec_action(self, ctx: AnyContext) -> CmdResult:
100
105
  """Turn _cmd attribute into subprocess.Popen and execute it as task's action.
@@ -105,7 +110,6 @@ class CmdTask(BaseTask):
105
110
  Returns:
106
111
  Any: The result of the action execution.
107
112
  """
108
- ctx.log_info("Running script")
109
113
  cmd_script = self._get_cmd_script(ctx)
110
114
  ctx.log_debug(f"Script: {self.__get_multiline_repr(cmd_script)}")
111
115
  shell = self._get_shell(ctx)
@@ -116,7 +120,10 @@ class CmdTask(BaseTask):
116
120
  env_map = self.__get_env_map(ctx)
117
121
  ctx.log_debug(f"Environment map: {env_map}")
118
122
  cmd_process = None
123
+ if self._get_should_warn_unrecommended_commands():
124
+ self._check_unrecommended_commands(ctx, shell, cmd_script)
119
125
  try:
126
+ ctx.log_info("Running script")
120
127
  cmd_process = await asyncio.create_subprocess_exec(
121
128
  shell,
122
129
  shell_flag,
@@ -150,6 +157,21 @@ class CmdTask(BaseTask):
150
157
  if cmd_process is not None and cmd_process.returncode is None:
151
158
  cmd_process.terminate()
152
159
 
160
+ def _get_should_warn_unrecommended_commands(self):
161
+ if self._should_warn_unrecommended_command is None:
162
+ return WARN_UNRECOMMENDED_COMMAND
163
+ return self._should_warn_unrecommended_command
164
+
165
+ def _check_unrecommended_commands(
166
+ self, ctx: AnyContext, shell: str, cmd_script: str
167
+ ):
168
+ if shell.endswith("bash") or shell.endswith("zsh"):
169
+ unrecommended_commands = check_unrecommended_commands(cmd_script)
170
+ if unrecommended_commands:
171
+ ctx.log_warning("The script contains unrecommended commands")
172
+ for command, reason in unrecommended_commands.items():
173
+ ctx.log_warning(f"- {command}: {reason}")
174
+
153
175
  def __get_env_map(self, ctx: AnyContext) -> dict[str, str]:
154
176
  envs = {key: val for key, val in ctx.env.items()}
155
177
  envs["_ZRB_SSH_PASSWORD"] = self._get_remote_password(ctx)
@@ -195,7 +217,9 @@ class CmdTask(BaseTask):
195
217
  )
196
218
 
197
219
  def _get_remote_port(self, ctx: AnyContext) -> int:
198
- return get_int_attr(ctx, self._remote_port, 22, auto_render=True)
220
+ return get_int_attr(
221
+ ctx, self._remote_port, 22, auto_render=self._render_remote_port
222
+ )
199
223
 
200
224
  def _get_remote_user(self, ctx: AnyContext) -> str:
201
225
  return get_str_attr(
@@ -108,8 +108,13 @@ class LLMTask(BaseTask):
108
108
  )
109
109
 
110
110
  async def _exec_action(self, ctx: AnyContext) -> Any:
111
- from litellm import acompletion
111
+ from litellm import acompletion, supports_function_calling
112
112
 
113
+ model = self._get_model(ctx)
114
+ try:
115
+ allow_function_call = supports_function_calling(model=model)
116
+ except Exception:
117
+ allow_function_call = False
113
118
  model_kwargs = self._get_model_kwargs(ctx)
114
119
  ctx.log_debug("MODEL KWARGS", model_kwargs)
115
120
  system_prompt = self._get_system_prompt(ctx)
@@ -121,27 +126,28 @@ class LLMTask(BaseTask):
121
126
  messages = history + [user_message]
122
127
  available_tools = self._get_tools(ctx)
123
128
  available_tools["scratchpad"] = scratchpad
124
- tool_schema = [
125
- callable_to_tool_schema(tool, name)
126
- for name, tool in available_tools.items()
127
- ]
128
- for additional_tool in self._additional_tools:
129
- fn = additional_tool.fn
130
- tool_name = additional_tool.name or fn.__name__
131
- tool_description = additional_tool.description
132
- available_tools[tool_name] = additional_tool.fn
133
- tool_schema.append(
134
- callable_to_tool_schema(
135
- fn, name=tool_name, description=tool_description
129
+ if allow_function_call:
130
+ tool_schema = [
131
+ callable_to_tool_schema(tool, name)
132
+ for name, tool in available_tools.items()
133
+ ]
134
+ for additional_tool in self._additional_tools:
135
+ fn = additional_tool.fn
136
+ tool_name = additional_tool.name or fn.__name__
137
+ tool_description = additional_tool.description
138
+ available_tools[tool_name] = additional_tool.fn
139
+ tool_schema.append(
140
+ callable_to_tool_schema(
141
+ fn, name=tool_name, description=tool_description
142
+ )
136
143
  )
137
- )
138
- ctx.log_debug("TOOL SCHEMA", tool_schema)
144
+ model_kwargs["tools"] = tool_schema
145
+ ctx.log_debug("TOOL SCHEMA", tool_schema)
139
146
  history_file = self._get_history_file(ctx)
140
147
  while True:
141
148
  response = await acompletion(
142
- model=self._get_model(ctx),
149
+ model=model,
143
150
  messages=[{"role": "system", "content": system_prompt}] + messages,
144
- tools=tool_schema,
145
151
  **model_kwargs,
146
152
  )
147
153
  response_message = response.choices[0].message
@@ -189,7 +195,7 @@ class LLMTask(BaseTask):
189
195
  def _get_model_kwargs(self, ctx: AnyContext) -> dict[str, Callable]:
190
196
  if callable(self._model_kwargs):
191
197
  return self._model_kwargs(ctx)
192
- return self._model_kwargs
198
+ return {**self._model_kwargs}
193
199
 
194
200
  def _get_tools(self, ctx: AnyContext) -> dict[str, Callable]:
195
201
  if callable(self._tools):
@@ -24,13 +24,13 @@ class RsyncTask(CmdTask):
24
24
  remote_host: StrAttr | None = None,
25
25
  auto_render_remote_host: bool = True,
26
26
  remote_port: IntAttr | None = None,
27
- auto_render_remote_port: bool = True,
27
+ render_remote_port: bool = True,
28
28
  remote_user: StrAttr | None = None,
29
- auto_render_remote_user: bool = True,
29
+ render_remote_user: bool = True,
30
30
  remote_password: StrAttr | None = None,
31
- auto_render_remote_password: bool = True,
31
+ render_remote_password: bool = True,
32
32
  remote_ssh_key: StrAttr | None = None,
33
- auto_render_remote_ssh_key: bool = True,
33
+ render_remote_ssh_key: bool = True,
34
34
  remote_source_path: StrAttr | None = None,
35
35
  render_remote_source_path: bool = True,
36
36
  remote_destination_path: StrAttr | None = None,
@@ -63,13 +63,13 @@ class RsyncTask(CmdTask):
63
63
  remote_host=remote_host,
64
64
  render_remote_host=auto_render_remote_host,
65
65
  remote_port=remote_port,
66
- auto_render_remote_port=auto_render_remote_port,
66
+ auto_render_remote_port=render_remote_port,
67
67
  remote_user=remote_user,
68
- render_remote_user=auto_render_remote_user,
68
+ render_remote_user=render_remote_user,
69
69
  remote_password=remote_password,
70
- render_remote_password=auto_render_remote_password,
70
+ render_remote_password=render_remote_password,
71
71
  remote_ssh_key=remote_ssh_key,
72
- render_remote_ssh_key=auto_render_remote_ssh_key,
72
+ render_remote_ssh_key=render_remote_ssh_key,
73
73
  cwd=cwd,
74
74
  render_cwd=auto_render_cwd,
75
75
  max_output_line=max_output_line,
@@ -0,0 +1,33 @@
1
+ import re
2
+
3
+
4
+ def check_unrecommended_commands(cmd_script: str) -> dict[str, str]:
5
+ banned_commands = {
6
+ "<(": "Process substitution isn't POSIX compliant and causes trouble",
7
+ "column": "Command isn't included in Ubuntu packages and is not POSIX compliant",
8
+ "echo": "echo isn't consistent across OS; use printf instead",
9
+ "eval": "Avoid eval as it can accidentally execute arbitrary strings",
10
+ "realpath": "Not available by default on OSX",
11
+ "source": "Not POSIX compliant; use '.' instead",
12
+ " test": "Use '[' instead for consistency",
13
+ "which": "Command in not POSIX compliant, use command -v",
14
+ }
15
+ banned_commands_regex = {
16
+ r"grep.* -y": "grep -y does not work on Alpine; use grep -i",
17
+ r"grep.* -P": "grep -P is not valid on OSX",
18
+ r"grep[^|]+--\w{2,}": "grep long commands do not work on Alpine",
19
+ r'readlink.+-.*f.+["$]': "readlink -f behaves differently on OSX",
20
+ r"sort.*-V": "sort -V is not supported everywhere",
21
+ r"sort.*--sort-versions": "sort --sort-version is not supported everywhere",
22
+ r"\bls ": "Avoid using ls; use shell globs or find instead",
23
+ }
24
+ violations = {}
25
+ # Check banned commands
26
+ for cmd, reason in banned_commands.items():
27
+ if cmd in cmd_script:
28
+ violations[cmd] = reason
29
+ # Check banned regex patterns
30
+ for pattern, reason in banned_commands_regex.items():
31
+ if re.search(pattern, cmd_script):
32
+ violations[pattern] = reason
33
+ return violations