zrb 1.0.0a16__py3-none-any.whl → 1.0.0a20__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 (196) hide show
  1. zrb/__init__.py +5 -0
  2. zrb/__main__.py +3 -0
  3. zrb/builtin/__init__.py +2 -2
  4. zrb/builtin/git.py +10 -2
  5. zrb/builtin/git_subtree.py +4 -0
  6. zrb/builtin/llm/tool/rag.py +2 -2
  7. zrb/builtin/project/add/fastapp/fastapp_input.py +16 -0
  8. zrb/builtin/project/add/fastapp/fastapp_task.py +78 -0
  9. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/.flake8 +3 -0
  10. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/column/create_column_task.py +14 -0
  11. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/add_entity_task.py +128 -0
  12. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/add_entity_util.py +213 -0
  13. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/any_client_method.py +27 -0
  14. zrb/builtin/project/add/{fastapp_template/_zrb/entity/module_template → fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module}/service/my_entity/my_entity_usecase.py +9 -10
  15. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module/service/my_entity/repository/factory.py +13 -0
  16. zrb/builtin/project/add/{fastapp_template/_zrb/entity/module_template → fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module}/service/my_entity/repository/my_entity_db_repository.py +14 -9
  17. zrb/builtin/project/add/{fastapp_template/_zrb/entity/module_template → fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module}/service/my_entity/repository/my_entity_repository.py +6 -7
  18. zrb/builtin/project/add/{fastapp_template/_zrb/entity/schema.template.py → fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/schema/my_entity.py} +8 -0
  19. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/format_task.py +17 -0
  20. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/_zrb/input.py +1 -4
  21. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/add_module_task.py +85 -0
  22. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/add_module_util.py +154 -0
  23. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/any_client.py +7 -0
  24. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/api_client.py +6 -0
  25. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/direct_client.py +6 -0
  26. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/factory.py +9 -0
  27. zrb/builtin/project/add/{fastapp_template/_zrb/module/module_template → fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module}/migration/env.py +2 -4
  28. zrb/builtin/project/add/{fastapp_template/module/auth → fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module}/migration/script.py.mako +1 -0
  29. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/route.py +33 -0
  30. zrb/builtin/project/add/{fastapp_template/_zrb/main.py → fastapp/fastapp_template/my_app_name/_zrb/task.py} +12 -14
  31. zrb/builtin/project/add/{fastapp_template/_zrb/helper.py → fastapp/fastapp_template/my_app_name/_zrb/util.py} +1 -1
  32. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/_zrb/venv_task.py +1 -1
  33. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/common/app.py +2 -2
  34. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/common/base_db_repository.py +1 -1
  35. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/common/base_usecase.py +19 -6
  36. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/common/db_engine.py +1 -1
  37. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/config.py +1 -0
  38. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/main.py +7 -0
  39. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/migrate.py +3 -0
  40. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/auth/client/any_client.py +10 -4
  41. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/api_client.py +7 -0
  42. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/direct_client.py +6 -0
  43. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/factory.py +9 -0
  44. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/auth/migration/env.py +2 -4
  45. zrb/builtin/project/add/{fastapp_template/module/gateway → fastapp/fastapp_template/my_app_name/module/auth}/migration/script.py.mako +1 -0
  46. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/auth/migration_metadata.py +1 -1
  47. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/route.py +37 -0
  48. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/auth/service/user/repository/user_db_repository.py +13 -7
  49. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_repository.py +42 -0
  50. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_repository_factory.py +13 -0
  51. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/auth/service/user/user_usecase.py +13 -12
  52. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_usecase_factory.py +6 -0
  53. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/gateway/migration/env.py +2 -4
  54. zrb/builtin/project/add/{fastapp_template/_zrb/module/module_template → fastapp/fastapp_template/my_app_name/module/gateway}/migration/script.py.mako +1 -0
  55. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/route.py +37 -0
  56. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/subroute/auth.py +44 -0
  57. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/requirements.txt +1 -1
  58. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/schema/permission.py +8 -0
  59. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/schema/role.py +8 -0
  60. zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/schema/user.py +8 -0
  61. zrb/builtin/project/add/fastapp/fastapp_util.py +46 -0
  62. zrb/builtin/project/create/{create.py → project_task.py} +1 -1
  63. zrb/builtin/python.py +4 -1
  64. zrb/builtin/setup/asdf/asdf_helper.py +4 -8
  65. zrb/builtin/setup/tmux/tmux.py +7 -12
  66. zrb/builtin/todo.py +42 -26
  67. zrb/callback/callback.py +0 -1
  68. zrb/cmd/cmd_val.py +2 -2
  69. zrb/config.py +18 -0
  70. zrb/content_transformer/content_transformer.py +8 -7
  71. zrb/context/any_context.py +6 -6
  72. zrb/group/group.py +0 -1
  73. zrb/input/any_input.py +4 -0
  74. zrb/input/base_input.py +17 -5
  75. zrb/input/bool_input.py +1 -1
  76. zrb/input/float_input.py +2 -2
  77. zrb/input/int_input.py +1 -1
  78. zrb/input/option_input.py +2 -2
  79. zrb/input/password_input.py +2 -2
  80. zrb/input/text_input.py +6 -6
  81. zrb/runner/cli.py +9 -35
  82. zrb/runner/common_util.py +31 -0
  83. zrb/runner/web_app.py +169 -46
  84. zrb/runner/web_config.py +288 -0
  85. zrb/runner/web_controller/error_page/controller.py +27 -0
  86. zrb/runner/web_controller/error_page/view.html +33 -0
  87. zrb/runner/web_controller/group_info_page/controller.py +40 -0
  88. zrb/runner/web_controller/group_info_page/view.html +36 -0
  89. zrb/runner/web_controller/home_page/controller.py +14 -57
  90. zrb/runner/web_controller/home_page/view.html +29 -20
  91. zrb/runner/web_controller/login_page/controller.py +25 -0
  92. zrb/runner/web_controller/login_page/view.html +50 -0
  93. zrb/runner/web_controller/logout_page/controller.py +26 -0
  94. zrb/runner/web_controller/logout_page/view.html +40 -0
  95. zrb/runner/web_controller/{task_ui → session_page}/controller.py +36 -34
  96. zrb/runner/web_controller/{task_ui → session_page}/partial/input.html +1 -1
  97. zrb/runner/web_controller/session_page/view.html +91 -0
  98. zrb/runner/web_controller/static/common.css +11 -0
  99. zrb/runner/web_controller/static/login/event.js +33 -0
  100. zrb/runner/web_controller/static/logout/event.js +20 -0
  101. zrb/runner/web_controller/static/pico.min.css +1 -1
  102. zrb/runner/web_controller/static/session/common-util.js +63 -0
  103. zrb/runner/web_controller/static/session/current-session.js +164 -0
  104. zrb/runner/web_controller/static/session/event.js +120 -0
  105. zrb/runner/web_controller/static/session/past-session.js +138 -0
  106. zrb/runner/web_util.py +53 -0
  107. zrb/session_state_logger/any_session_state_logger.py +0 -1
  108. zrb/session_state_logger/file_session_state_logger.py +4 -8
  109. zrb/task/base_trigger.py +0 -1
  110. zrb/task/cmd_task.py +1 -1
  111. zrb/task/llm_task.py +3 -6
  112. zrb/task/make_task.py +0 -1
  113. zrb/task/scaffolder.py +18 -4
  114. zrb/task/scheduler.py +0 -1
  115. zrb/util/cmd/command.py +0 -1
  116. zrb/util/codemod/{add_code_to_class.py → append_code_to_class.py} +4 -4
  117. zrb/util/codemod/{add_code_to_function.py → append_code_to_function.py} +5 -3
  118. zrb/util/codemod/{add_code_to_method.py → append_code_to_method.py} +3 -3
  119. zrb/util/codemod/{add_key_to_dict.py → append_key_to_dict.py} +1 -1
  120. zrb/util/codemod/{add_param_to_function_call.py → append_param_to_function_call.py} +1 -1
  121. zrb/util/codemod/{add_code_to_module.py → prepend_code_to_module.py} +2 -2
  122. zrb/util/codemod/{add_parent_to_class.py → prepend_parent_to_class.py} +1 -1
  123. zrb/util/codemod/{add_property_to_class.py → prepend_property_to_class.py} +1 -1
  124. zrb/util/file.py +18 -0
  125. zrb/util/git_subtree.py +3 -4
  126. zrb/util/todo.py +105 -24
  127. zrb/xcom/xcom.py +0 -1
  128. {zrb-1.0.0a16.dist-info → zrb-1.0.0a20.dist-info}/METADATA +3 -2
  129. zrb-1.0.0a20.dist-info/RECORD +243 -0
  130. zrb/builtin/project/add/fastapp.py +0 -87
  131. zrb/builtin/project/add/fastapp_template/_zrb/column/create_column_task.py +0 -11
  132. zrb/builtin/project/add/fastapp_template/_zrb/entity/create_entity_task.py +0 -196
  133. zrb/builtin/project/add/fastapp_template/_zrb/entity/module_template/service/my_entity/repository/factory.py +0 -13
  134. zrb/builtin/project/add/fastapp_template/_zrb/module/create_module_task.py +0 -136
  135. zrb/builtin/project/add/fastapp_template/_zrb/module/module_template/client/any_client.py +0 -27
  136. zrb/builtin/project/add/fastapp_template/_zrb/module/module_template/client/api_client.py +0 -6
  137. zrb/builtin/project/add/fastapp_template/_zrb/module/module_template/client/direct_client.py +0 -6
  138. zrb/builtin/project/add/fastapp_template/_zrb/module/module_template/client/factory.py +0 -9
  139. zrb/builtin/project/add/fastapp_template/_zrb/module/module_template/route.py +0 -19
  140. zrb/builtin/project/add/fastapp_template/main.py +0 -7
  141. zrb/builtin/project/add/fastapp_template/migrate.py +0 -3
  142. zrb/builtin/project/add/fastapp_template/module/auth/client/api_client.py +0 -7
  143. zrb/builtin/project/add/fastapp_template/module/auth/client/direct_client.py +0 -6
  144. zrb/builtin/project/add/fastapp_template/module/auth/client/factory.py +0 -9
  145. zrb/builtin/project/add/fastapp_template/module/auth/migration/versions/3093c7336477_add_user_table.py +0 -37
  146. zrb/builtin/project/add/fastapp_template/module/auth/route.py +0 -22
  147. zrb/builtin/project/add/fastapp_template/module/auth/service/user/repository/factory.py +0 -13
  148. zrb/builtin/project/add/fastapp_template/module/auth/service/user/repository/user_repository.py +0 -34
  149. zrb/builtin/project/add/fastapp_template/module/gateway/route.py +0 -27
  150. zrb/runner/web_controller/group_info_ui/controller.py +0 -91
  151. zrb/runner/web_controller/group_info_ui/partial/group_info.html +0 -2
  152. zrb/runner/web_controller/group_info_ui/partial/group_li.html +0 -1
  153. zrb/runner/web_controller/group_info_ui/partial/task_info.html +0 -2
  154. zrb/runner/web_controller/group_info_ui/partial/task_li.html +0 -1
  155. zrb/runner/web_controller/group_info_ui/view.html +0 -31
  156. zrb/runner/web_controller/home_page/partial/group_info.html +0 -2
  157. zrb/runner/web_controller/home_page/partial/group_li.html +0 -1
  158. zrb/runner/web_controller/home_page/partial/task_info.html +0 -2
  159. zrb/runner/web_controller/home_page/partial/task_li.html +0 -1
  160. zrb/runner/web_controller/task_ui/partial/common-util.js +0 -37
  161. zrb/runner/web_controller/task_ui/partial/main.js +0 -195
  162. zrb/runner/web_controller/task_ui/partial/show-existing-session.js +0 -97
  163. zrb/runner/web_controller/task_ui/partial/visualize-history.js +0 -104
  164. zrb/runner/web_controller/task_ui/view.html +0 -87
  165. zrb-1.0.0a16.dist-info/RECORD +0 -231
  166. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/.gitignore +0 -0
  167. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/README.md +0 -0
  168. /zrb/builtin/project/add/{__init__.py → fastapp/fastapp_template/my_app_name/__init__.py} +0 -0
  169. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/_zrb/config.py +0 -0
  170. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/_zrb/group.py +0 -0
  171. /zrb/builtin/project/add/{fastapp_template/__init__.py → fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/gateway/subroute/my_module.py} +0 -0
  172. /zrb/builtin/project/add/{fastapp_template/_zrb/module/module_template → fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module}/alembic.ini +0 -0
  173. /zrb/builtin/project/add/{fastapp_template/_zrb/module/module_template → fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module}/migration/README +0 -0
  174. /zrb/builtin/project/add/{fastapp_template/module/gateway → fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module}/migration/versions/.gitkeep +0 -0
  175. /zrb/builtin/project/add/{fastapp_template/_zrb/module/module_template → fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module}/migration_metadata.py +0 -0
  176. /zrb/builtin/project/add/{fastapp_template/_zrb/module/module_template → fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module}/service/__init__.py +0 -0
  177. /zrb/builtin/project/add/{fastapp_template/_zrb/module/run_module.template.py → fastapp/fastapp_template/my_app_name/_zrb/module/template/module_task_definition.py} +0 -0
  178. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/common/__init__.py +0 -0
  179. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/common/error.py +0 -0
  180. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/common/schema.py +0 -0
  181. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/__init__.py +0 -0
  182. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/auth/alembic.ini +0 -0
  183. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/auth/migration/README +0 -0
  184. /zrb/builtin/project/add/{fastapp_template/_zrb/module/module_template → fastapp/fastapp_template/my_app_name/module/auth}/migration/versions/3093c7336477_add_user_table.py +0 -0
  185. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/auth/service/__init__.py +0 -0
  186. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/auth/service/user/__init__.py +0 -0
  187. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/gateway/alembic.ini +0 -0
  188. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/gateway/migration/README +0 -0
  189. /zrb/builtin/project/add/{fastapp_template/module/auth/service/user/repository/__init__.py → fastapp/fastapp_template/my_app_name/module/gateway/migration/versions/.gitkeep} +0 -0
  190. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/module/gateway/migration_metadata.py +0 -0
  191. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/schema/__init__.py +0 -0
  192. /zrb/builtin/project/add/{fastapp_template → fastapp/fastapp_template/my_app_name}/template.env +0 -0
  193. /zrb/runner/web_controller/{group_info_ui → group_info_page}/__init__.py +0 -0
  194. /zrb/runner/web_controller/{task_ui → session_page}/__init__.py +0 -0
  195. {zrb-1.0.0a16.dist-info → zrb-1.0.0a20.dist-info}/WHEEL +0 -0
  196. {zrb-1.0.0a16.dist-info → zrb-1.0.0a20.dist-info}/entry_points.txt +0 -0
zrb/builtin/todo.py CHANGED
@@ -4,19 +4,21 @@ import os
4
4
  from typing import Any
5
5
 
6
6
  from zrb.builtin.group import todo_group
7
- from zrb.config import TODO_DIR, TODO_VISUAL_FILTER
7
+ from zrb.config import TODO_DIR, TODO_RETENTION, TODO_VISUAL_FILTER
8
8
  from zrb.context.any_context import AnyContext
9
9
  from zrb.input.str_input import StrInput
10
10
  from zrb.input.text_input import TextInput
11
11
  from zrb.task.make_task import make_task
12
+ from zrb.util.file import read_file, write_file
12
13
  from zrb.util.todo import (
13
14
  TodoTaskModel,
14
- add_durations,
15
+ add_duration,
15
16
  cascade_todo_task,
16
17
  get_visual_todo_card,
17
18
  get_visual_todo_list,
18
19
  line_to_todo_task,
19
20
  load_todo_list,
21
+ parse_duration,
20
22
  save_todo_list,
21
23
  select_todo_task,
22
24
  todo_task_to_line,
@@ -119,8 +121,7 @@ def show_todo(ctx: AnyContext):
119
121
  log_work_path = os.path.join(TODO_DIR, "log-work", f"{task_id}.json")
120
122
  log_work_list = []
121
123
  if os.path.isfile(log_work_path):
122
- with open(log_work_path, "r") as f:
123
- log_work_list = json.loads(f.read())
124
+ log_work_list = json.loads(read_file(log_work_path))
124
125
  return get_visual_todo_card(todo_task, log_work_list)
125
126
 
126
127
 
@@ -165,11 +166,17 @@ def archive_todo(ctx: AnyContext):
165
166
  todo_list: list[TodoTaskModel] = []
166
167
  if os.path.isfile(todo_file_path):
167
168
  todo_list = load_todo_list(todo_file_path)
168
- working_todo_list = [
169
- todo_task for todo_task in todo_list if not todo_task.completed
170
- ]
169
+ retention_duration = datetime.timedelta(seconds=parse_duration(TODO_RETENTION))
170
+ threshold_date = datetime.date.today() - retention_duration
171
171
  new_archived_todo_list = [
172
- todo_task for todo_task in todo_list if todo_task.completed
172
+ todo_task
173
+ for todo_task in todo_list
174
+ if todo_task.completed
175
+ and todo_task.completion_date is not None
176
+ and todo_task.completion_date < threshold_date
177
+ ]
178
+ working_todo_list = [
179
+ todo_task for todo_task in todo_list if todo_task not in new_archived_todo_list
173
180
  ]
174
181
  if len(new_archived_todo_list) == 0:
175
182
  ctx.print("No completed task to archive")
@@ -204,10 +211,10 @@ def archive_todo(ctx: AnyContext):
204
211
  default_str="30m",
205
212
  ),
206
213
  StrInput(
207
- name="start",
208
- prompt="Working start time (%Y-%m-%d %H:%M:%S)",
209
- description="Working start time",
210
- default_str=lambda _: _get_default_start(),
214
+ name="stop",
215
+ prompt="Working stop time (%Y-%m-%d %H:%M:%S)",
216
+ description="Working stop time",
217
+ default_str=lambda _: _get_default_stop_work_time_str(),
211
218
  ),
212
219
  ],
213
220
  description="🕒 Log work todo",
@@ -226,8 +233,10 @@ def log_todo(ctx: AnyContext):
226
233
  return get_visual_todo_list(todo_list, TODO_VISUAL_FILTER)
227
234
  # Update todo task
228
235
  todo_task = cascade_todo_task(todo_task)
229
- current_duration = todo_task.keyval.get("duration", "0")
230
- todo_task.keyval["duration"] = add_durations(current_duration, ctx.input.duration)
236
+ current_duration_str = todo_task.keyval.get("duration", "0")
237
+ todo_task.keyval["duration"] = add_duration(
238
+ current_duration_str, ctx.input.duration
239
+ )
231
240
  # Save todo list
232
241
  save_todo_list(todo_file_path, todo_list)
233
242
  # Add log work
@@ -237,24 +246,26 @@ def log_todo(ctx: AnyContext):
237
246
  log_work_dir, f"{todo_task.keyval.get('id')}.json"
238
247
  )
239
248
  if os.path.isfile(log_work_file_path):
240
- with open(log_work_file_path, "r") as f:
241
- log_work_json = f.read()
249
+ log_work_json = read_file(log_work_file_path)
242
250
  else:
243
251
  log_work_json = "[]"
244
252
  log_work: list[dict[str, Any]] = json.loads(log_work_json)
253
+ start_work_time_str = _get_start_work_time_str(ctx.input.stop, ctx.input.duration)
245
254
  log_work.append(
246
- {"log": ctx.input.log, "duration": ctx.input.duration, "start": ctx.input.start}
255
+ {
256
+ "log": ctx.input.log,
257
+ "duration": ctx.input.duration,
258
+ "start": start_work_time_str,
259
+ }
247
260
  )
248
261
  # save todo with log work
249
- with open(log_work_file_path, "w") as f:
250
- f.write(json.dumps(log_work, indent=2))
262
+ write_file(log_work_file_path, json.dumps(log_work, indent=2))
251
263
  # get log work list
252
264
  task_id = todo_task.keyval.get("id", "")
253
265
  log_work_path = os.path.join(TODO_DIR, "log-work", f"{task_id}.json")
254
266
  log_work_list = []
255
267
  if os.path.isfile(log_work_path):
256
- with open(log_work_path, "r") as f:
257
- log_work_list = json.loads(f.read())
268
+ log_work_list = json.loads(read_file(log_work_path))
258
269
  return "\n".join(
259
270
  [
260
271
  get_visual_todo_list(todo_list, TODO_VISUAL_FILTER),
@@ -264,7 +275,14 @@ def log_todo(ctx: AnyContext):
264
275
  )
265
276
 
266
277
 
267
- def _get_default_start() -> str:
278
+ def _get_start_work_time_str(stop_work_time_str: str, work_duration_str: str) -> str:
279
+ work_duration = parse_duration(work_duration_str)
280
+ stop_work_time = datetime.datetime.strptime(stop_work_time_str, "%Y-%m-%d %H:%M:%S")
281
+ start_work_time = stop_work_time - datetime.timedelta(seconds=work_duration)
282
+ return start_work_time.strftime("%Y-%m-%d %H:%M:%S")
283
+
284
+
285
+ def _get_default_stop_work_time_str() -> str:
268
286
  return datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
269
287
 
270
288
 
@@ -290,8 +308,7 @@ def edit_todo(ctx: AnyContext):
290
308
  ]
291
309
  new_content = "\n".join(todo_task_to_line(todo_task) for todo_task in todo_list)
292
310
  todo_file_path = os.path.join(TODO_DIR, "todo.txt")
293
- with open(todo_file_path, "w") as f:
294
- f.write(new_content)
311
+ write_file(todo_file_path, new_content)
295
312
  todo_list = load_todo_list(todo_file_path)
296
313
  return get_visual_todo_list(todo_list, TODO_VISUAL_FILTER)
297
314
 
@@ -300,5 +317,4 @@ def _get_todo_txt_content() -> str:
300
317
  todo_file_path = os.path.join(TODO_DIR, "todo.txt")
301
318
  if not os.path.isfile(todo_file_path):
302
319
  return ""
303
- with open(todo_file_path, "r") as f:
304
- return f.read()
320
+ return read_file(todo_file_path)
zrb/callback/callback.py CHANGED
@@ -8,7 +8,6 @@ from zrb.util.attr import get_str_dict_attr
8
8
 
9
9
 
10
10
  class Callback(AnyCallback):
11
-
12
11
  def __init__(
13
12
  self,
14
13
  input_mapping: StrDictAttr,
zrb/cmd/cmd_val.py CHANGED
@@ -3,6 +3,7 @@ from collections.abc import Callable
3
3
 
4
4
  from zrb.attr.type import fstring
5
5
  from zrb.context.context import Context
6
+ from zrb.util.file import read_file
6
7
 
7
8
 
8
9
  class AnyCmdVal(ABC):
@@ -18,8 +19,7 @@ class CmdPath(AnyCmdVal):
18
19
 
19
20
  def to_str(self, ctx: Context) -> str:
20
21
  file_path = ctx.render(self._path) if self._auto_render else self._path
21
- with open(file_path) as file:
22
- return file.read()
22
+ return read_file(file_path)
23
23
 
24
24
 
25
25
  class Cmd(AnyCmdVal):
zrb/config.py CHANGED
@@ -56,8 +56,26 @@ SESSION_LOG_DIR = os.getenv(
56
56
  )
57
57
  TODO_DIR = os.getenv("ZRB_TODO_DIR", os.path.expanduser(os.path.join("~", "todo")))
58
58
  TODO_VISUAL_FILTER = os.getenv("ZRB_TODO_FILTER", "")
59
+ TODO_RETENTION = os.getenv("ZRB_TODO_RETENTION", "2w")
59
60
  VERSION = metadata.version("zrb")
60
61
  WEB_HTTP_PORT = int(os.getenv("ZRB_WEB_HTTP_PORT", "21213"))
62
+ WEB_GUEST_USERNAME = os.getenv("ZRB_WEB_GUEST_USERNAME", "user")
63
+ WEB_SUPER_ADMIN_USERNAME = os.getenv("ZRB_WEB_SUPERADMIN_USERNAME", "admin")
64
+ WEB_SUPER_ADMIN_PASSWORD = os.getenv("ZRB_WEB_SUPERADMIN_PASSWORD", "admin")
65
+ WEB_ACCESS_TOKEN_COOKIE_NAME = os.getenv(
66
+ "ZRB_WEB_ACCESS_TOKEN_COOKIE_NAME", "access_token"
67
+ )
68
+ WEB_REFRESH_TOKEN_COOKIE_NAME = os.getenv(
69
+ "ZRB_WEB_REFRESH_TOKEN_COOKIE_NAME", "refresh_token"
70
+ )
71
+ WEB_SECRET_KEY = os.getenv("ZRB_WEB_SECRET", "zrb")
72
+ WEB_ENABLE_AUTH = to_boolean(os.getenv("ZRB_WEB_ENABLE_AUTH", "0"))
73
+ WEB_AUTH_ACCESS_TOKEN_EXPIRE_MINUTES = int(
74
+ os.getenv("ZRB_WEB_ACCESS_TOKEN_EXPIRE", "30")
75
+ )
76
+ WEB_AUTH_REFRESH_TOKEN_EXPIRE_MINUTES = int(
77
+ os.getenv("ZRB_WEB_ACCESS_TOKEN_EXPIRE", f"{60*24*7}")
78
+ )
61
79
  LLM_MODEL = os.getenv("ZRB_LLM_MODEL", "ollama_chat/llama3.1")
62
80
  LLM_SYSTEM_PROMPT = os.getenv("ZRB_LLM_SYSTEM_PROMPT", "You are a helpful assistant")
63
81
  LLM_HISTORY_FILE = os.getenv(
@@ -4,16 +4,16 @@ from collections.abc import Callable
4
4
 
5
5
  from zrb.content_transformer.any_content_transformer import AnyContentTransformer
6
6
  from zrb.context.any_context import AnyContext
7
+ from zrb.util.file import read_file, write_file
7
8
 
8
9
 
9
10
  class ContentTransformer(AnyContentTransformer):
10
-
11
11
  def __init__(
12
12
  self,
13
13
  match: list[str] | str | Callable[[AnyContext, str], bool],
14
14
  transform: (
15
15
  dict[str, str | Callable[[AnyContext], str]]
16
- | Callable[[AnyContext, str], str]
16
+ | Callable[[AnyContext, str], None]
17
17
  ),
18
18
  auto_render: bool = True,
19
19
  ):
@@ -24,7 +24,10 @@ class ContentTransformer(AnyContentTransformer):
24
24
  def match(self, ctx: AnyContext, file_path: str) -> bool:
25
25
  if callable(self._match):
26
26
  return self._match(ctx, file_path)
27
- patterns = [self._match] if isinstance(self._match, str) else self._match
27
+ if isinstance(self._match, str):
28
+ patterns = [self._match]
29
+ else:
30
+ patterns = self._match
28
31
  for pattern in patterns:
29
32
  try:
30
33
  if re.fullmatch(pattern, file_path):
@@ -40,12 +43,10 @@ class ContentTransformer(AnyContentTransformer):
40
43
  keyword: self._get_str_replacement(ctx, replacement)
41
44
  for keyword, replacement in self._transform_file.items()
42
45
  }
43
- with open(file_path, "r") as f:
44
- content = f.read()
46
+ content = read_file(file_path)
45
47
  for keyword, replacement in transform_map.items():
46
48
  content = content.replace(keyword, replacement)
47
- with open(file_path, "w") as f:
48
- f.write(content)
49
+ write_file(file_path, content)
49
50
 
50
51
  def _get_str_replacement(
51
52
  self, ctx: AnyContext, replacement: str | Callable[[AnyContext], str]
@@ -42,7 +42,7 @@ class AnyContext(AnySharedContext):
42
42
  sep: str | None = " ",
43
43
  end: str | None = "\n",
44
44
  file: TextIO | None = sys.stderr,
45
- flush: bool = True
45
+ flush: bool = True,
46
46
  ):
47
47
  """Prints values to the specified output stream.
48
48
 
@@ -62,7 +62,7 @@ class AnyContext(AnySharedContext):
62
62
  sep: str | None = " ",
63
63
  end: str | None = "\n",
64
64
  file: TextIO | None = sys.stderr,
65
- flush: bool = True
65
+ flush: bool = True,
66
66
  ):
67
67
  """Logs debug-level messages.
68
68
 
@@ -82,7 +82,7 @@ class AnyContext(AnySharedContext):
82
82
  sep: str | None = " ",
83
83
  end: str | None = "\n",
84
84
  file: TextIO | None = sys.stderr,
85
- flush: bool = True
85
+ flush: bool = True,
86
86
  ):
87
87
  """Logs info-level messages.
88
88
 
@@ -102,7 +102,7 @@ class AnyContext(AnySharedContext):
102
102
  sep: str | None = " ",
103
103
  end: str | None = "\n",
104
104
  file: TextIO | None = sys.stderr,
105
- flush: bool = True
105
+ flush: bool = True,
106
106
  ):
107
107
  """Logs warning-level messages.
108
108
 
@@ -122,7 +122,7 @@ class AnyContext(AnySharedContext):
122
122
  sep: str | None = " ",
123
123
  end: str | None = "\n",
124
124
  file: TextIO | None = sys.stderr,
125
- flush: bool = True
125
+ flush: bool = True,
126
126
  ):
127
127
  """Logs error-level messages.
128
128
 
@@ -142,7 +142,7 @@ class AnyContext(AnySharedContext):
142
142
  sep: str | None = " ",
143
143
  end: str | None = "\n",
144
144
  file: TextIO | None = sys.stderr,
145
- flush: bool = True
145
+ flush: bool = True,
146
146
  ):
147
147
  """Logs critical-level messages.
148
148
 
zrb/group/group.py CHANGED
@@ -3,7 +3,6 @@ from zrb.task.any_task import AnyTask
3
3
 
4
4
 
5
5
  class Group(AnyGroup):
6
-
7
6
  def __init__(
8
7
  self, name: str, description: str | None = None, banner: str | None = None
9
8
  ):
zrb/input/any_input.py CHANGED
@@ -32,3 +32,7 @@ class AnyInput(ABC):
32
32
  @abstractmethod
33
33
  def prompt_cli_str(self, shared_ctx: AnySharedContext) -> str:
34
34
  pass
35
+
36
+ @abstractmethod
37
+ def get_default_str(self, shared_ctx: AnySharedContext) -> str:
38
+ pass
zrb/input/base_input.py CHANGED
@@ -4,6 +4,7 @@ from zrb.attr.type import StrAttr
4
4
  from zrb.context.any_shared_context import AnySharedContext
5
5
  from zrb.input.any_input import AnyInput
6
6
  from zrb.util.attr import get_str_attr
7
+ from zrb.util.string.conversion import to_snake_case
7
8
 
8
9
 
9
10
  class BaseInput(AnyInput):
@@ -41,15 +42,26 @@ class BaseInput(AnyInput):
41
42
  def to_html(self, ctx: AnySharedContext) -> str:
42
43
  name = self.name
43
44
  description = self.description
44
- default = self._get_default_str(ctx)
45
+ default = self.get_default_str(ctx)
45
46
  return f'<input name="{name}" placeholder="{description}" value="{default}" />'
46
47
 
47
48
  def update_shared_context(
48
49
  self, shared_ctx: AnySharedContext, str_value: str | None = None
49
50
  ):
50
51
  if str_value is None:
51
- str_value = self._get_default_str(shared_ctx)
52
- shared_ctx.input[self.name] = self._parse_str_value(str_value)
52
+ str_value = self.get_default_str(shared_ctx)
53
+ value = self._parse_str_value(str_value)
54
+ if self.name in shared_ctx.input:
55
+ raise ValueError(f"Input already defined in the context: {self.name}")
56
+ shared_ctx.input[self.name] = value
57
+ # We want to be able to access ctx.input["project-name"] as
58
+ # ctx.input.project_name
59
+ snake_key = to_snake_case(self.name)
60
+ if snake_key == self.name:
61
+ return
62
+ if snake_key in shared_ctx.input:
63
+ raise ValueError("Input already defined in the context: {snake_key}")
64
+ shared_ctx.input[snake_key] = value
53
65
 
54
66
  def _parse_str_value(self, str_value: str) -> Any:
55
67
  """Override this to transform str_value"""
@@ -63,7 +75,7 @@ class BaseInput(AnyInput):
63
75
 
64
76
  def _prompt_cli_str(self, shared_ctx: AnySharedContext) -> str:
65
77
  prompt_message = self.prompt_message
66
- default_value = self._get_default_str(shared_ctx)
78
+ default_value = self.get_default_str(shared_ctx)
67
79
  if default_value != "":
68
80
  prompt_message = f"{prompt_message} [{default_value}]"
69
81
  print(f"{prompt_message}: ", end="")
@@ -72,7 +84,7 @@ class BaseInput(AnyInput):
72
84
  value = default_value
73
85
  return value
74
86
 
75
- def _get_default_str(self, shared_ctx: AnySharedContext) -> str:
87
+ def get_default_str(self, shared_ctx: AnySharedContext) -> str:
76
88
  return get_str_attr(
77
89
  shared_ctx, self._default_str, auto_render=self._auto_render
78
90
  )
zrb/input/bool_input.py CHANGED
@@ -26,7 +26,7 @@ class BoolInput(BaseInput):
26
26
  def to_html(self, ctx: AnySharedContext) -> str:
27
27
  name = self.name
28
28
  description = self.description
29
- default = to_boolean(self._get_default_str(ctx))
29
+ default = to_boolean(self.get_default_str(ctx))
30
30
  selected_true = "selected" if default else ""
31
31
  selected_false = "selected" if not default else ""
32
32
  return "\n".join(
zrb/input/float_input.py CHANGED
@@ -25,8 +25,8 @@ class FloatInput(BaseInput):
25
25
  def to_html(self, ctx: AnySharedContext) -> str:
26
26
  name = self.name
27
27
  description = self.description
28
- default = self._get_default_str(ctx)
29
- return f'<input type="number" name="{name}" placeholder="{description}" value="{default}" />' # noqa
28
+ default = self.get_default_str(ctx)
29
+ return f'<input type="number" name="{name}" placeholder="{description}" value="{default}" step="any" />' # noqa
30
30
 
31
31
  def _parse_str_value(self, str_value: str) -> float:
32
32
  return float(str_value)
zrb/input/int_input.py CHANGED
@@ -25,7 +25,7 @@ class IntInput(BaseInput):
25
25
  def to_html(self, ctx: AnySharedContext) -> str:
26
26
  name = self.name
27
27
  description = self.description
28
- default = self._get_default_str(ctx)
28
+ default = self.get_default_str(ctx)
29
29
  return f'<input type="number" step="1" name="{name}" placeholder="{description}" value="{default}" />' # noqa
30
30
 
31
31
  def _parse_str_value(self, str_value: str) -> int:
zrb/input/option_input.py CHANGED
@@ -28,7 +28,7 @@ class OptionInput(BaseInput):
28
28
  def to_html(self, ctx: AnySharedContext) -> str:
29
29
  name = self.name
30
30
  description = self.description
31
- default = self._get_default_str(ctx)
31
+ default = self.get_default_str(ctx)
32
32
  html = [f'<select name="{name}" placeholder="{description}">']
33
33
  for value in get_str_list_attr(ctx, self._options, self._auto_render):
34
34
  selected = "selected" if value == default else ""
@@ -38,7 +38,7 @@ class OptionInput(BaseInput):
38
38
 
39
39
  def _prompt_cli_str(self, shared_ctx: AnySharedContext) -> str:
40
40
  prompt_message = self.prompt_message
41
- default_value = self._get_default_str(shared_ctx)
41
+ default_value = self.get_default_str(shared_ctx)
42
42
  options = get_str_list_attr(shared_ctx, self._options, self._auto_render)
43
43
  option_str = ", ".join(options)
44
44
  if default_value != "":
@@ -28,12 +28,12 @@ class PasswordInput(BaseInput):
28
28
  def to_html(self, ctx: AnySharedContext) -> str:
29
29
  name = self.name
30
30
  description = self.description
31
- default = self._get_default_str(ctx)
31
+ default = self.get_default_str(ctx)
32
32
  return f'<input type="password" name="{name}" placeholder="{description}" value="{default}" />' # noqa
33
33
 
34
34
  def _prompt_cli_str(self, shared_ctx: AnySharedContext) -> str:
35
35
  prompt_message = self.prompt_message
36
- default_value = self._get_default_str(shared_ctx)
36
+ default_value = self.get_default_str(shared_ctx)
37
37
  value = getpass.getpass(f"{prompt_message}: ")
38
38
  if value.strip() == "":
39
39
  value = default_value
zrb/input/text_input.py CHANGED
@@ -6,6 +6,7 @@ from collections.abc import Callable
6
6
  from zrb.config import DEFAULT_EDITOR
7
7
  from zrb.context.any_shared_context import AnySharedContext
8
8
  from zrb.input.base_input import BaseInput
9
+ from zrb.util.file import read_file
9
10
 
10
11
 
11
12
  class TextInput(BaseInput):
@@ -56,7 +57,7 @@ class TextInput(BaseInput):
56
57
  def to_html(self, ctx: AnySharedContext) -> str:
57
58
  name = self.name
58
59
  description = self.description
59
- default = self._get_default_str(ctx)
60
+ default = self.get_default_str(ctx)
60
61
  return "\n".join(
61
62
  [
62
63
  f'<textarea name="{name}" placeholder="{description}">',
@@ -70,7 +71,7 @@ class TextInput(BaseInput):
70
71
  f"{self.comment_start}{super().prompt_message}{self.comment_end}"
71
72
  )
72
73
  prompt_message_eol = f"{prompt_message}\n"
73
- default_value = self._get_default_str(shared_ctx)
74
+ default_value = self.get_default_str(shared_ctx)
74
75
  with tempfile.NamedTemporaryFile(
75
76
  delete=False, suffix=self._extension
76
77
  ) as temp_file:
@@ -83,9 +84,8 @@ class TextInput(BaseInput):
83
84
  # Open the editor
84
85
  subprocess.call([self._editor, temp_file_name])
85
86
  # Read the edited content
86
- with open(temp_file_name, "r") as temp_file:
87
- edited_content = temp_file.read()
88
- parts = [text.strip() for text in edited_content.split(prompt_message, 1)]
89
- edited_content = "\n".join(parts).lstrip()
87
+ edited_content = read_file(temp_file_name)
88
+ parts = [text.strip() for text in edited_content.split(prompt_message, 1)]
89
+ edited_content = "\n".join(parts).lstrip()
90
90
  os.remove(temp_file_name)
91
91
  return edited_content
zrb/runner/cli.py CHANGED
@@ -5,8 +5,13 @@ from zrb.config import BANNER, WEB_HTTP_PORT
5
5
  from zrb.context.any_context import AnyContext
6
6
  from zrb.context.shared_context import SharedContext
7
7
  from zrb.group.group import Group
8
+ from zrb.runner.common_util import get_run_kwargs
8
9
  from zrb.runner.web_app import create_app
10
+ from zrb.runner.web_config import web_config
9
11
  from zrb.session.session import Session
12
+ from zrb.session_state_logger.default_session_state_logger import (
13
+ default_session_state_logger,
14
+ )
10
15
  from zrb.task.any_task import AnyTask
11
16
  from zrb.task.make_task import make_task
12
17
  from zrb.util.cli.style import (
@@ -20,7 +25,6 @@ from zrb.util.string.conversion import double_quote
20
25
 
21
26
 
22
27
  class Cli(Group):
23
-
24
28
  def run(self, args: list[str] = []):
25
29
  load_zrb_init()
26
30
  kwargs, args = self._extract_kwargs_from_args(args)
@@ -31,7 +35,7 @@ class Cli(Group):
31
35
  if "h" in kwargs or "help" in kwargs:
32
36
  self._show_task_info(node)
33
37
  return
34
- run_kwargs = self._get_run_kwargs(node, args, kwargs)
38
+ run_kwargs = get_run_kwargs(task=node, args=args, kwargs=kwargs, prompt=True)
35
39
  try:
36
40
  result = self._run_task(node, args, run_kwargs)
37
41
  if result is not None:
@@ -73,35 +77,6 @@ class Cli(Group):
73
77
  continue
74
78
  return task.run(Session(shared_ctx=shared_ctx, root_group=self))
75
79
 
76
- def _get_run_kwargs(
77
- self, task: AnyTask, args: list[str], kwargs: dict[str, str]
78
- ) -> tuple[Any]:
79
- arg_index = 0
80
- str_kwargs = {key: val for key, val in kwargs.items()}
81
- run_kwargs = {**str_kwargs}
82
- shared_ctx = SharedContext(args=args)
83
- for task_input in task.inputs:
84
- if task_input.name in str_kwargs:
85
- # Update shared context for next input default value
86
- task_input.update_shared_context(
87
- shared_ctx, str_kwargs[task_input.name]
88
- )
89
- elif arg_index < len(args):
90
- run_kwargs[task_input.name] = args[arg_index]
91
- # Update shared context for next input default value
92
- task_input.update_shared_context(
93
- shared_ctx, run_kwargs[task_input.name]
94
- )
95
- arg_index += 1
96
- else:
97
- str_value = task_input.prompt_cli_str(shared_ctx)
98
- run_kwargs[task_input.name] = str_value
99
- # Update shared context for next input default value
100
- task_input.update_shared_context(
101
- shared_ctx, run_kwargs[task_input.name]
102
- )
103
- return run_kwargs
104
-
105
80
  def _show_task_info(self, task: AnyTask):
106
81
  description = task.description
107
82
  inputs = task.inputs
@@ -189,10 +164,9 @@ server_group = cli.add_group(
189
164
  group=server_group,
190
165
  alias="start",
191
166
  )
192
- async def run(_: AnyContext):
167
+ async def start_server(_: AnyContext):
193
168
  from uvicorn import Config, Server
194
169
 
195
- app = create_app(cli, WEB_HTTP_PORT)
196
- config = Config(app=app, host="0.0.0.0", port=WEB_HTTP_PORT, loop="asyncio")
197
- server = Server(config)
170
+ app = create_app(cli, web_config, default_session_state_logger)
171
+ server = Server(Config(app=app, host="0.0.0.0", port=WEB_HTTP_PORT, loop="asyncio"))
198
172
  await server.serve()
@@ -0,0 +1,31 @@
1
+ from typing import Any
2
+
3
+ from zrb.context.shared_context import SharedContext
4
+ from zrb.task.any_task import AnyTask
5
+
6
+
7
+ def get_run_kwargs(
8
+ task: AnyTask, args: list[str], kwargs: dict[str, str], prompt: bool = True
9
+ ) -> tuple[Any]:
10
+ arg_index = 0
11
+ str_kwargs = {key: val for key, val in kwargs.items()}
12
+ run_kwargs = {**str_kwargs}
13
+ shared_ctx = SharedContext(args=args)
14
+ for task_input in task.inputs:
15
+ if task_input.name in str_kwargs:
16
+ # Update shared context for next input default value
17
+ task_input.update_shared_context(shared_ctx, str_kwargs[task_input.name])
18
+ elif arg_index < len(args):
19
+ run_kwargs[task_input.name] = args[arg_index]
20
+ # Update shared context for next input default value
21
+ task_input.update_shared_context(shared_ctx, run_kwargs[task_input.name])
22
+ arg_index += 1
23
+ else:
24
+ if prompt:
25
+ str_value = task_input.prompt_cli_str(shared_ctx)
26
+ else:
27
+ str_value = task_input.get_default_str(shared_ctx)
28
+ run_kwargs[task_input.name] = str_value
29
+ # Update shared context for next input default value
30
+ task_input.update_shared_context(shared_ctx, run_kwargs[task_input.name])
31
+ return run_kwargs