ellf-cli 21.0.10__tar.gz → 22.0.2__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 (425) hide show
  1. {ellf_cli-21.0.10/ellf_cli.egg-info → ellf_cli-22.0.2}/PKG-INFO +1 -1
  2. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/README.md +3 -34
  3. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/__main__.py +4 -5
  4. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/auth.py +2 -3
  5. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/cli.py +0 -1
  6. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/__init__.py +0 -2
  7. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/infra/__init__.py +0 -1
  8. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/infra/_helpers.py +30 -1
  9. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/infra/init.py +19 -7
  10. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/infra/register.py +22 -4
  11. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/infra/start.py +2 -22
  12. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/infra/terraform.py +53 -2
  13. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf.json +5 -158
  14. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/interactivity.py +1 -1
  15. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/messages.py +5 -3
  16. ellf_cli-22.0.2/ellf_cli/version/21.0.10_2026-10-30-14-29-34_major_4fd535f6-6e41-4f34-b29c-543e1a9bac51 +3 -0
  17. ellf_cli-22.0.2/ellf_cli/version/22.0.0_2026-10-30-15-25-42_patch_1f39caf4-aadc-4d26-9124-a854d945b32a +3 -0
  18. ellf_cli-22.0.2/ellf_cli/version/22.0.1_2026-10-30-17-30-37_patch_4a6e6cfb-d86e-4f1e-84c5-02d4c071f75b +3 -0
  19. {ellf_cli-21.0.10 → ellf_cli-22.0.2/ellf_cli.egg-info}/PKG-INFO +1 -1
  20. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli.egg-info/SOURCES.txt +4 -2
  21. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_infra_destroy.py +42 -1
  22. ellf_cli-22.0.2/tests/test_infra_register.py +67 -0
  23. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_infra_start_validation.py +1 -1
  24. ellf_cli-21.0.10/ellf_cli/commands/auth.py +0 -122
  25. ellf_cli-21.0.10/ellf_cli/commands/infra/tls.py +0 -453
  26. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/LICENSE +0 -0
  27. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/MANIFEST.in +0 -0
  28. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/__init__.py +0 -0
  29. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/about.json +0 -0
  30. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/about.py +0 -0
  31. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/agents.py +0 -0
  32. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/appdirs.py +0 -0
  33. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/cloud/__init__.py +0 -0
  34. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/cloud/gcp.py +0 -0
  35. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/cluster_config.py +0 -0
  36. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/_cluster_select.py +0 -0
  37. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/_org_select.py +0 -0
  38. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/_project_scope.py +0 -0
  39. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/_recipe_file.py +0 -0
  40. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/_recipe_subcommand.py +0 -0
  41. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/_state.py +0 -0
  42. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/_usage.py +0 -0
  43. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/actions.py +0 -0
  44. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/agents.py +0 -0
  45. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/assets.py +0 -0
  46. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/clusters.py +0 -0
  47. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/config.py +0 -0
  48. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/datasets.py +0 -0
  49. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/files/__init__.py +0 -0
  50. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/files/cp.py +0 -0
  51. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/files/ls.py +0 -0
  52. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/files/rm.py +0 -0
  53. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/files/rsync.py +0 -0
  54. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/files/stats.py +0 -0
  55. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/general.py +0 -0
  56. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/import_export.py +0 -0
  57. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/infra/_config_io.py +0 -0
  58. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/infra/configure.py +0 -0
  59. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/infra/deploy.py +0 -0
  60. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/infra/hibernate.py +0 -0
  61. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/infra/init_values.py +0 -0
  62. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/infra/pause.py +0 -0
  63. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/infra/provision.py +0 -0
  64. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/infra/setup.py +0 -0
  65. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/jobs.py +0 -0
  66. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/mcp.py +0 -0
  67. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/packages.py +0 -0
  68. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/paths.py +0 -0
  69. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/plans.py +0 -0
  70. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/projects.py +0 -0
  71. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/publish_code.py +0 -0
  72. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/publish_data.py +0 -0
  73. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/recipes.py +0 -0
  74. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/secrets.py +0 -0
  75. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/services.py +0 -0
  76. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/sessions.py +0 -0
  77. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/support.py +0 -0
  78. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/tasks.py +0 -0
  79. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/todos.py +0 -0
  80. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/commands/users.py +0 -0
  81. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/config.py +0 -0
  82. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/.gitignore +0 -0
  83. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/render.py +0 -0
  84. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-annotate/SKILL.assistant.md +0 -0
  85. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-annotate/SKILL.coding.md +0 -0
  86. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-annotate/references/annotation_audit.assistant.md +0 -0
  87. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-annotate/references/annotation_audit.coding.md +0 -0
  88. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-annotate/references/builtin_ellf_annotation_recipes.assistant.md +0 -0
  89. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-annotate/references/builtin_ellf_annotation_recipes.coding.md +0 -0
  90. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-annotate/references/builtin_prodigy_recipes.coding.md +0 -0
  91. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-annotate/references/label_schemes.assistant.md +0 -0
  92. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-annotate/references/label_schemes.coding.md +0 -0
  93. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-ask/SKILL.md +0 -0
  94. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-handoff/SKILL.assistant.md +0 -0
  95. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-monitor/SKILL.assistant.md +0 -0
  96. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-monitor/SKILL.coding.md +0 -0
  97. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-monitor/references/annotation_metrics.assistant.md +0 -0
  98. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-monitor/references/annotation_metrics.coding.md +0 -0
  99. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-monitor/references/training_monitoring.assistant.md +0 -0
  100. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-monitor/references/training_monitoring.coding.md +0 -0
  101. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-monitor/scripts.coding/check_training.py +0 -0
  102. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-ops/SKILL.assistant.md +0 -0
  103. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-ops/SKILL.coding.md +0 -0
  104. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-ops/references.coding/data_infra_cli.md +0 -0
  105. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-ops/scripts.coding/run_job.py +0 -0
  106. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-patterns/SKILL.coding.md +0 -0
  107. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-patterns/references/pattern_strategies.md +0 -0
  108. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/SKILL.coding.md +0 -0
  109. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_action_recipe.py +0 -0
  110. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_agent_recipe.py +0 -0
  111. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_blocks_ui.py +0 -0
  112. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_correct.py +0 -0
  113. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_custom_ui.py +0 -0
  114. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_manual.py +0 -0
  115. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_pages_ui.py +0 -0
  116. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_routing.py +0 -0
  117. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_service_recipe.py +0 -0
  118. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_task_recipe.py +0 -0
  119. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_teach.py +0 -0
  120. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/builtin_recipes.md +0 -0
  121. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/ellf_recipe_sdk.md +0 -0
  122. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/lint_recipe.py +0 -0
  123. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/prodigy_recipe_api.md +0 -0
  124. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/template_index.md +0 -0
  125. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-project/SKILL.assistant.md +0 -0
  126. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-project/SKILL.coding.md +0 -0
  127. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-project/references/annotation_agents.md +0 -0
  128. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-project/references/consulting_patterns.md +0 -0
  129. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-project/references/explosion_strategy.md +0 -0
  130. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-project/references/jev.coding.md +0 -0
  131. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-project/references/label_schemes.assistant.md +0 -0
  132. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-project/references/label_schemes.coding.md +0 -0
  133. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-support/SKILL.assistant.md +0 -0
  134. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-support/SKILL.coding.md +0 -0
  135. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-template/SKILL.coding.md +0 -0
  136. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-template/references/template_format.md +0 -0
  137. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-template/scripts/placeholders.py +0 -0
  138. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-todo/SKILL.coding.md +0 -0
  139. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-train/SKILL.assistant.md +0 -0
  140. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-train/SKILL.coding.md +0 -0
  141. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-train/references/config_advanced.coding.md +0 -0
  142. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-train/references/config_architectures.coding.md +0 -0
  143. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-train/references/config_training.coding.md +0 -0
  144. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-train/references/diagnostics.md +0 -0
  145. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-train/references/evaluation_guide.md +0 -0
  146. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-train/references/experiment_patterns.coding.md +0 -0
  147. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-train/references/model_selection.md +0 -0
  148. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-train/references/training_paradigms.md +0 -0
  149. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-train/references/training_troubleshooting.coding.md +0 -0
  150. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-train/references/workflow.assistant.md +0 -0
  151. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-train/references/workflow.coding.md +0 -0
  152. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ellf_skills/skills/ellf-train/scripts.coding/ellf_logger.py +0 -0
  153. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/errors.py +0 -0
  154. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/helm.py +0 -0
  155. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/key_pair.py +0 -0
  156. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/main.py +0 -0
  157. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/mcp_proxy.py +0 -0
  158. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/pypi_auth.py +0 -0
  159. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/query.py +0 -0
  160. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/recipes_cookiecutter/cookiecutter.json +0 -0
  161. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/.gitignore +0 -0
  162. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/README.md.tmpl +0 -0
  163. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/requirements-dev.in +0 -0
  164. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/requirements.in +0 -0
  165. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/setup.py.tmpl +0 -0
  166. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/{{cookiecutter.package_name}}/__init__.py +0 -0
  167. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/{{cookiecutter.package_name}}/about.py +0 -0
  168. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/{{cookiecutter.package_name}}/recipes/__init__.py +0 -0
  169. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/{{cookiecutter.package_name}}/recipes/example_task.py +0 -0
  170. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/testing/__init__.py +0 -0
  171. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ty.py +0 -0
  172. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/ui.py +0 -0
  173. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/url.py +0 -0
  174. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/util.py +0 -0
  175. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.114_2026-08-19-08-36-57__1a4e37c1-471e-4a81-b4d5-1ffe7dec3a61 +0 -0
  176. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.114_2026-08-19-09-25-21_patch_33ff1e26-0e5e-46d8-8052-ab1d032e8b6c +0 -0
  177. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.115_2026-08-19-09-27-13_patch_4ac728c3-0342-4a36-adbc-e28d2d99b1ba +0 -0
  178. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.116_2026-08-19-09-30-47_patch_c706fef6-6813-4183-b268-12e7b00d7d0b +0 -0
  179. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.117_2026-08-19-09-39-14_patch_c6b0495f-2f88-4aa8-9ebf-0a235b4c407e +0 -0
  180. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.118_2026-08-19-09-52-00_patch_b395655a-8d78-4344-9266-6901c20f6517 +0 -0
  181. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.119_2026-08-19-10-22-38_patch_8f95c49d-aedc-41b8-816d-ccb95f048831 +0 -0
  182. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.120_2026-08-19-10-26-58_patch_7fbf35e6-cc01-4b75-8c9a-f5d054bcaf93 +0 -0
  183. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.121_2026-08-19-10-42-02_patch_31a81b02-a886-4dea-84e0-67cc6ca412d5 +0 -0
  184. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.122_2026-08-19-11-16-49_patch_1c4d7307-48d4-493e-936d-80af799d644b +0 -0
  185. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.123_2026-08-19-11-47-32_patch_d3d78d04-9989-45b1-91b1-93b571d8814a +0 -0
  186. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.124_2026-08-20-08-03-17_patch_57f4c389-2d19-41ce-aca4-13b61c62f387 +0 -0
  187. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.125_2026-08-20-08-25-05_patch_7f368148-0d1c-4525-bbdf-c6d257ad861a +0 -0
  188. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.126_2026-08-20-14-51-36_patch_a99abcc8-3371-4c63-a759-bb7ea5b32432 +0 -0
  189. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.127_2026-08-21-05-48-58_patch_34b4ccee-7596-4f57-93e9-774973cca58e +0 -0
  190. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.128_2026-08-21-10-47-20_patch_693112b9-927c-4a8f-8553-b06eef86079d +0 -0
  191. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.129_2026-08-21-11-16-54_patch_7a981666-01d9-4d1b-9ba3-2129744e3bd5 +0 -0
  192. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.130_2026-08-21-13-09-36_patch_b7ad1a76-ce70-4d70-9d1a-7c414eba5bb4 +0 -0
  193. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.131_2026-08-21-14-31-10_patch_9128ef66-193e-4caf-8710-afd86128e638 +0 -0
  194. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.132_2026-08-24-08-59-34_patch_c600fc14-86a5-460f-9c4e-f0177056f756 +0 -0
  195. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.133_2026-08-24-10-28-29_patch_b6ce3e32-9d7b-48ac-981a-270c22c180dd +0 -0
  196. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.134_2026-08-24-11-00-51_patch_a4fc0484-4a64-46a2-94f8-aa805254c7b0 +0 -0
  197. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.135_2026-08-24-12-12-41_patch_a870a56f-9a65-49eb-92da-f572b26667d8 +0 -0
  198. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.136_2026-08-24-12-42-46_patch_9b399356-6482-4291-8da7-e748a99c4b53 +0 -0
  199. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.137_2026-08-24-12-53-57_patch_f7979348-1910-40cd-a535-90299eca84ee +0 -0
  200. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.138_2026-08-24-14-36-30_patch_ed0f8750-f663-498b-85e7-0d3f2213fcfe +0 -0
  201. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.139_2026-08-25-08-37-26_patch_3ba87e19-902b-4f76-b64c-90e5c0ca1fc6 +0 -0
  202. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.140_2026-08-25-09-52-45_patch_abc830f2-df15-4385-b797-cdaf72c10752 +0 -0
  203. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.141_2026-08-25-11-37-20_patch_1d9ec01e-06f6-4c8e-b095-af17d5b62b00 +0 -0
  204. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.142_2026-08-26-07-38-49_patch_3dd23e36-e7df-494c-986f-a412861a8d40 +0 -0
  205. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.143_2026-08-26-09-32-32_patch_7b7ebd34-de27-4b73-98a7-3e1501e16cd5 +0 -0
  206. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.144_2026-08-26-10-56-43_patch_166064f2-2208-4c9b-9e25-25dc4cd32084 +0 -0
  207. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.145_2026-08-26-11-37-29_patch_b997f3ee-d7d3-4408-9f2f-c8b6d08bdb3b +0 -0
  208. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.146_2026-08-26-12-15-20_patch_afbbb893-25db-468c-81db-2663ca373068 +0 -0
  209. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.147_2026-08-26-14-10-50_patch_fd753b1f-2fa1-4ddb-a9e7-de690da85254 +0 -0
  210. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.148_2026-08-27-09-08-35_patch_23814c0b-7f77-489c-b4a8-ceadd18146e3 +0 -0
  211. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.149_2026-08-27-09-40-17_patch_8879d72e-a3d8-4abc-a16a-d9dcf75f0fa1 +0 -0
  212. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.150_2026-08-27-10-57-25_patch_afbe60ed-3e23-4d88-be3c-f800d7002a7d +0 -0
  213. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.151_2026-08-28-09-02-46_patch_1d4ca23b-aeae-4ea8-96b1-8cf57371f29d +0 -0
  214. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.152_2026-08-28-15-37-24_patch_c9d0bdc1-a7e1-432b-92b9-92dc76fe0c78 +0 -0
  215. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.153_2026-08-29-09-03-27_patch_7531573a-1b33-4092-aa9c-0e65f47b201f +0 -0
  216. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.154_2026-08-29-11-56-35_patch_919f5787-39c8-4dc1-ae6a-f27c28380f21 +0 -0
  217. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.155_2026-08-29-15-15-59_patch_822f9ed8-c366-4e5f-9791-dee8467cf3ce +0 -0
  218. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.156_2026-08-29-16-19-01_patch_3ac2bf36-20f7-4c9f-9fdb-295d4466d59e +0 -0
  219. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.157_2026-08-30-17-32-17_patch_4302354c-c9c5-4be7-acd3-542872a748d8 +0 -0
  220. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.158_2026-08-31-09-28-33_patch_3523774f-c25d-4102-8c1a-92fff046a48d +0 -0
  221. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.159_2026-08-31-10-31-01_patch_fe3e6290-2553-4154-a0a0-8b8a418280ed +0 -0
  222. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.160_2026-08-31-11-23-39_patch_e701a085-3d23-4212-b0af-73b1d419a4c1 +0 -0
  223. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.161_2026-08-31-12-41-01_patch_074d7bde-c493-44db-bc15-e81fd91e2921 +0 -0
  224. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.162_2026-08-31-13-58-06_patch_84db1d60-4280-433b-bd3a-22e5611cd315 +0 -0
  225. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.163_2026-08-31-15-25-54_patch_1931c5ba-73df-48cb-8dcb-555ace0af267 +0 -0
  226. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.163_2026-08-31-15-44-37_patch_3962e805-2a92-494a-a87b-b6e6d66c40a0 +0 -0
  227. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.165_2026-08-31-19-48-59_patch_86e5b923-2b99-4b86-b542-469b197614be +0 -0
  228. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.166_2026-09-01-07-39-57_patch_c344892f-d542-4e7b-8f27-02365a411e15 +0 -0
  229. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.167_2026-09-01-08-21-53_patch_e199d419-282a-4dbb-8756-cf98b7037e2b +0 -0
  230. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.168_2026-09-01-09-12-31_patch_235c9fe0-da15-431d-bb56-01e2b9b15f4b +0 -0
  231. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.169_2026-09-01-11-54-19_patch_98b617ab-d130-42b5-93f2-19cae56d4c4c +0 -0
  232. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.170_2026-09-02-09-27-28_patch_e448d2e6-b7ec-4235-96bf-0173b3623c87 +0 -0
  233. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.171_2026-09-02-12-52-44_patch_e6a241c2-1d62-482c-a9eb-9e3373395c50 +0 -0
  234. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.172_2026-09-04-08-47-04_patch_daae079f-c104-4fcd-bb57-7bff68e80ad9 +0 -0
  235. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.173_2026-09-04-12-34-42_patch_399c4cbd-0c28-4dfd-a4ec-e569420a36e4 +0 -0
  236. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.174_2026-09-04-13-08-48_patch_f5cfe3d5-808e-45e4-bafc-00d0554838ee +0 -0
  237. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.175_2026-09-04-17-20-46_patch_1ef542fa-5d8e-4d90-aa15-9fc4cea3dfec +0 -0
  238. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.176_2026-09-05-08-25-05_patch_ced5521f-f9da-4640-a921-95fcb5cd2e6d +0 -0
  239. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.177_2026-09-05-09-00-16_patch_803c1ad4-a9af-4953-92c5-d882dec03ea2 +0 -0
  240. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.178_2026-09-05-09-30-34_patch_012f6259-2e3f-4591-9806-1920fd06cb1f +0 -0
  241. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.179_2026-09-05-09-33-43_patch_f4bdf28c-d584-47a5-b699-8c883330162c +0 -0
  242. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.180_2026-09-05-12-02-21_patch_34a14b01-d22d-44a8-ac63-be0370a61422 +0 -0
  243. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.181_2026-09-05-12-47-46_patch_56b18867-99f6-4d5c-8215-7b9d60d34010 +0 -0
  244. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.182_2026-09-05-13-35-18_patch_61b7d4d1-73c8-4603-9b0c-593e7405587f +0 -0
  245. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.183_2026-09-06-07-27-09_patch_d76331b2-e3a3-4c0b-8412-ecd131b6ac02 +0 -0
  246. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.184_2026-09-06-10-21-47_patch_7680b7a1-49f0-4eef-b12e-4c854407448c +0 -0
  247. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.185_2026-09-06-10-30-40_patch_e56c2183-77f8-44ef-a92e-7377ea6ce8c1 +0 -0
  248. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.186_2026-09-07-10-00-51_patch_67de5683-d208-4bc0-8fb6-7677377908e7 +0 -0
  249. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.187_2026-09-07-10-18-13_patch_2086cee2-276b-48f7-80ce-6a17397b9541 +0 -0
  250. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.188_2026-09-07-12-51-28_patch_d6590822-068f-4a19-814d-34bbf204ba6e +0 -0
  251. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.189_2026-09-07-12-55-23_patch_7e0fb04b-4d40-4490-974f-c74ba2ae55a1 +0 -0
  252. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.190_2026-09-08-08-58-03_patch_15e3ac1e-4475-4272-bdd8-d00bb0db8f17 +0 -0
  253. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.191_2026-09-08-09-55-58_patch_3d350e50-ee53-4282-bc75-d2251142c46e +0 -0
  254. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.192_2026-09-08-11-12-21_patch_0733223b-1ae2-4b5b-897f-dfc57574ff83 +0 -0
  255. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.193_2026-09-08-21-48-17_patch_8d07d4e6-3555-4720-85c9-9452570fae2d +0 -0
  256. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.194_2026-09-09-07-53-43_patch_69559429-aa42-4b62-9bd7-cdfded1c00d0 +0 -0
  257. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.195_2026-09-09-09-55-40_patch_bbf67f1d-3b9a-43a2-b1bc-22df3fed8a34 +0 -0
  258. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.196_2026-09-09-09-59-47_patch_70d76812-7b3c-4192-ad49-fcaccc29b0da +0 -0
  259. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.197_2026-09-09-13-06-06_patch_d455be0b-5421-492a-b952-fab0fd8110f8 +0 -0
  260. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.198_2026-09-09-13-14-34_patch_267f54e5-311e-435e-882f-8e19191325ea +0 -0
  261. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.199_2026-09-09-22-24-18_patch_81e3e453-ca0e-42fa-9c21-8f94d43c05f2 +0 -0
  262. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.200_2026-09-10-07-19-50_patch_911714fa-1fa3-4165-bfe6-d10c650bf5bf +0 -0
  263. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.201_2026-09-10-10-14-19_patch_864015f2-b0b0-4563-a1c8-155629cb9126 +0 -0
  264. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.202_2026-09-10-11-00-05_patch_18270ecf-e770-4e69-8bcf-e5143c39929b +0 -0
  265. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.203_2026-09-10-11-10-41_patch_ff273ab1-44f3-4bc0-b184-3396e943df04 +0 -0
  266. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.204_2026-09-10-13-02-02_patch_d4ee41e2-d13c-4941-8605-3f1a42b56b22 +0 -0
  267. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.205_2026-09-10-13-57-50_patch_284df67e-5957-4b0c-bc64-5581db6ddecc +0 -0
  268. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.206_2026-09-11-10-18-50_patch_1ac7e410-0e62-4eef-bbe4-ebf93c9d0869 +0 -0
  269. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/17.0.207_2026-09-11-15-26-02_major_3f1b3ed7-eaac-41f5-b740-0af3331595d9 +0 -0
  270. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.0_2026-09-12-10-01-10_patch_8995783a-a9fa-4c4e-90b3-6386a4c481eb +0 -0
  271. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.10_2026-09-14-16-09-38_patch_9403d562-eed0-4125-a8b3-09cd92a13298 +0 -0
  272. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.11_2026-09-15-09-05-57_patch_8b22dba2-d931-4c4d-ae60-db3238d5e73d +0 -0
  273. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.12_2026-09-15-11-18-52_patch_81314afa-e70d-4ad8-b45b-3f8d62b983e7 +0 -0
  274. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.13_2026-09-16-08-00-55_patch_bfa30fc0-3281-4de6-bb56-d7290c98d1c3 +0 -0
  275. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.14_2026-09-16-14-38-26_patch_aae6e9b0-88f4-4bcf-b611-3308c7fcd6eb +0 -0
  276. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.15_2026-09-17-07-58-54_patch_43d40582-effd-4925-a8bd-e70fecf1faab +0 -0
  277. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.16_2026-09-17-08-12-37_patch_b4db2d23-88f1-45c1-82d9-78d38014fcb6 +0 -0
  278. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.17_2026-09-18-09-38-19_patch_25697fc3-e9a8-4980-962b-e6cb0a4760c5 +0 -0
  279. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.18_2026-09-18-09-54-33_patch_d37d9c71-c469-4d94-90d7-4898915ee991 +0 -0
  280. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.19_2026-09-18-10-47-33_patch_47607b3c-d1b6-4864-b9b0-00a2a8d2ac32 +0 -0
  281. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.1_2026-09-12-17-33-30_patch_f6ea2c99-a715-4c4d-876a-23ed8c62a83d +0 -0
  282. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.20_2026-09-18-11-07-21_patch_5a336f91-63a6-4877-97ed-da89395cc8f5 +0 -0
  283. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.21_2026-09-18-13-34-52_patch_c56462e1-63d9-498f-a912-c80c5f0171d1 +0 -0
  284. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.22_2026-09-20-08-10-45_patch_6afa2c20-bcef-4b7d-8685-2c9815d8683f +0 -0
  285. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.23_2026-09-20-08-38-35_patch_a7f169e5-37ab-4ec0-bf89-d14770181303 +0 -0
  286. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.24_2026-09-20-15-49-27_patch_c1222081-ff44-4f20-aea2-5840b6d76efd +0 -0
  287. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.25_2026-09-21-06-11-40_patch_6df46dd9-e7d3-4e71-bec4-e5c93b4ac863 +0 -0
  288. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.26_2026-09-21-07-54-11_patch_cc52dd36-5eba-4094-a1b0-d6f79f103441 +0 -0
  289. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.27_2026-09-21-08-36-49_patch_a25fa125-9bcd-4317-8da5-851c1c329631 +0 -0
  290. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.28_2026-09-21-09-44-01_patch_4430a721-0b3c-4f6a-b9bc-a53e667161bb +0 -0
  291. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.29_2026-09-21-10-58-07_patch_83b2b942-60a4-4bef-afd1-99690ba52b69 +0 -0
  292. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.2_2026-09-13-06-36-33_patch_176bb944-1c49-4dd3-a001-8fce908825a0 +0 -0
  293. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.30_2026-09-21-12-51-16_patch_519b9a65-d400-4234-b113-36b46e315507 +0 -0
  294. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.31_2026-09-22-06-53-35_patch_5c45a235-81b6-4d05-801a-07dc7db61400 +0 -0
  295. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.32_2026-09-22-07-42-04_patch_f12c6415-8166-4063-9e5d-26601b929d63 +0 -0
  296. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.33_2026-09-22-08-12-32_patch_cec31bb0-a6cb-43e6-8407-25aba322b54c +0 -0
  297. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.34_2026-09-23-07-09-16_patch_659fccbb-c0a0-4f6f-bc87-e6abaa8815a7 +0 -0
  298. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.35_2026-09-23-09-38-52_patch_023f904d-807a-4833-8a40-570365e8ec06 +0 -0
  299. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.36_2026-09-23-10-05-33_patch_846fb491-2b1b-47ed-ac1f-ba40e744e199 +0 -0
  300. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.37_2026-09-23-13-08-30_patch_8e4b1d24-156e-4ffe-8e4a-b8740ec18588 +0 -0
  301. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.38_2026-09-24-06-41-37_patch_67adb1d6-3f49-4357-a67f-b1d48f23a972 +0 -0
  302. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.39_2026-09-24-15-24-32_patch_e5dd375d-5643-4514-9b65-8d877c4a2bb2 +0 -0
  303. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.3_2026-09-13-12-32-46_patch_58e5ce3a-f2a7-4789-b2cd-5cc75c72b6ec +0 -0
  304. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.40_2026-09-24-19-58-14_patch_ff18824b-be51-4a3d-a621-e96279e53c3e +0 -0
  305. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.41_2026-09-26-09-24-52_patch_b9979267-30f9-440a-a4ce-c611991d4886 +0 -0
  306. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.42_2026-09-28-12-39-34_patch_dda535d9-8922-4eb9-ab51-6ecff0650c10 +0 -0
  307. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.43_2026-09-28-13-35-27_minor_aca1168a-1286-4326-9d0c-2f2587c9fe92 +0 -0
  308. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.4_2026-09-13-12-45-14_patch_b6c79d55-8f85-4f47-a304-df52b122c38c +0 -0
  309. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.5_2026-09-13-14-11-18_patch_9b111116-5e62-472a-b72c-d1bbafa22c97 +0 -0
  310. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.5_2026-09-13-17-01-11_patch_d4bf61c0-83ac-4dd3-b512-a65805d298c8 +0 -0
  311. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.6_2026-09-14-11-31-04_patch_fd2ebda6-22cb-4e7d-9452-2f6f2640e828 +0 -0
  312. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.7_2026-09-13-17-06-08_patch_428af161-0b27-43c2-8751-e5f7874df120 +0 -0
  313. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.0.9_2026-09-14-12-37-42_patch_b2ca0529-4b67-4fa4-8fdc-5f5e9f5d5166 +0 -0
  314. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.1.0_2026-09-28-14-27-54_patch_324444f7-d24e-4189-b21f-1188894a3109 +0 -0
  315. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/18.1.1_2026-09-28-21-03-07_major_e266a14a-7d96-4ece-92a3-8f34e64438a5 +0 -0
  316. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/19.0.0_2026-09-29-11-05-31_patch_77d6f9f8-ead3-4d79-a4b2-b084b2dffc98 +0 -0
  317. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/19.0.10_2026-10-02-12-56-52_patch_14e97576-73ca-44b8-82c9-7dad6f1789ab +0 -0
  318. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/19.0.11_2026-10-04-10-31-19_patch_088eb371-1799-4949-a119-286cf1cd55d1 +0 -0
  319. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/19.0.12_2026-10-06-18-00-25_patch_36554bed-49c5-41cb-9fd4-48cc6af74c09 +0 -0
  320. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/19.0.13_2026-10-07-12-24-08_patch_a540a364-3a0d-4960-b278-06ba2c7cc258 +0 -0
  321. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/19.0.14_2026-10-07-12-52-39_patch_e3a6fc5c-2ee4-414c-a2dd-4910a655a7dd +0 -0
  322. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/19.0.15_2026-10-09-04-15-56_patch_bd7a9b06-867b-4fea-9678-973a05e3022d +0 -0
  323. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/19.0.16_2026-10-09-16-11-56_patch_a1135435-7dea-4f00-8c98-203ba3974382 +0 -0
  324. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/19.0.17_2026-10-09-17-44-55_patch_faeacad8-541a-40f2-ab9c-abcd66fcd00e +0 -0
  325. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/19.0.18_2026-10-10-07-29-38_major_02601a1e-9bdb-45bf-ad67-a07b7dcd0002 +0 -0
  326. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/19.0.1_2026-09-29-11-59-38_patch_bbf4753c-d641-4c2f-ac7c-02be6bd8e7c2 +0 -0
  327. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/19.0.2_2026-09-29-12-44-07_patch_19fdaa94-60dc-464b-93b8-c17607ebc7b6 +0 -0
  328. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/19.0.3_2026-09-29-14-16-00_patch_3cb60272-95cf-4311-8897-721e1b5c2c88 +0 -0
  329. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/19.0.4_2026-09-29-16-24-53_patch_9fe8ad2b-e3ec-4558-a5fc-9c44c5c266dc +0 -0
  330. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/19.0.5_2026-09-29-17-13-16_patch_e48d2dd2-f41a-402e-a441-756b23c01dcb +0 -0
  331. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/19.0.6_2026-09-29-17-22-11_patch_3b1c79e9-9002-4e96-ba78-10668c33be6a +0 -0
  332. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/19.0.7_2026-09-30-07-50-58_patch_e8b1f046-d819-499c-9cd5-3e1a20fc9acf +0 -0
  333. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/19.0.8_2026-10-01-13-41-44_patch_7d63af18-e0af-4127-ab58-aede2407490f +0 -0
  334. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/19.0.9_2026-10-01-15-57-35_patch_143863cb-8f63-4ef7-bd78-c1114fc93a2d +0 -0
  335. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/20.0.0_2026-10-10-09-36-17_patch_d2618f39-cdc9-4d3a-ba40-1a0ad6265f3b +0 -0
  336. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/20.0.1_2026-10-11-10-24-33_patch_e29a8713-eecb-4eb1-9641-789d3cfab21a +0 -0
  337. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/20.0.2_2026-10-12-07-22-24_patch_f4053ad1-8fcd-4591-a68d-bf1e23485ba7 +0 -0
  338. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/20.0.3_2026-10-14-14-29-16_patch_070af1c4-f9d9-4f97-8112-058de90d3ea8 +0 -0
  339. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/20.0.4_2026-10-14-16-20-24_patch_c6672844-8227-4e0a-9fb5-36af7e7141dc +0 -0
  340. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/20.0.5_2026-10-15-08-53-28_patch_10154146-8afd-4632-b250-9b4b9f5bf67c +0 -0
  341. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/20.0.6_2026-10-15-14-17-40_patch_df3a5d3c-f0e0-46cb-aeaf-15b51c8a0f13 +0 -0
  342. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/20.0.7_2026-10-16-07-09-40_major_3e5dfba3-2810-47b4-85a9-938bfff72a04 +0 -0
  343. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/21.0.0_2026-10-16-10-44-29_patch_1058e453-613f-492b-a3c7-f3ca2abe8c2d +0 -0
  344. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/21.0.1_2026-10-16-16-06-10_patch_e20b4ad2-b87f-478e-b4f4-323c8bcc5ea9 +0 -0
  345. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/21.0.2_2026-10-19-13-54-31_patch_bf091df4-00bb-43c8-9117-51047944e305 +0 -0
  346. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/21.0.3_2026-10-19-14-58-29_patch_9b985381-1b1d-4531-b242-b02cea2484c5 +0 -0
  347. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/21.0.4_2026-10-20-17-08-51_patch_38d02583-cb5c-4adc-b5d7-614b483acf19 +0 -0
  348. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/21.0.5_2026-10-21-09-28-47_patch_fabd5cfe-2d04-4215-abf1-58fba226acb7 +0 -0
  349. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/21.0.6_2026-10-22-16-07-37_patch_d2bb27d7-6304-4c99-abbc-46d3dd7e363b +0 -0
  350. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/21.0.7_2026-10-27-11-41-55_patch_6b50567f-209d-42c9-a2cd-d251a2bc8fbf +0 -0
  351. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/21.0.8_2026-10-29-13-48-18_patch_bdab3ee6-fba8-4625-9243-c4cbe839ba32 +0 -0
  352. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/21.0.9_2026-10-29-17-51-00_patch_803a4c70-2e2b-4024-8598-c7d91c9db0d2 +0 -0
  353. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/__init__.py +0 -0
  354. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli/version/read_version.py +0 -0
  355. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli.egg-info/dependency_links.txt +0 -0
  356. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli.egg-info/entry_points.txt +0 -0
  357. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli.egg-info/not-zip-safe +0 -0
  358. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli.egg-info/requires.txt +0 -0
  359. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/ellf_cli.egg-info/top_level.txt +0 -0
  360. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/pyproject.toml +0 -0
  361. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/setup.cfg +0 -0
  362. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/setup.py +0 -0
  363. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_agents.py +0 -0
  364. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_agents_info_stats.py +0 -0
  365. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_appdirs.py +0 -0
  366. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_auth.py +0 -0
  367. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_clusters_info_stats.py +0 -0
  368. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_config.py +0 -0
  369. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_datasets_export.py +0 -0
  370. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_errors.py +0 -0
  371. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_files_cp.py +0 -0
  372. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_files_cp_helpers.py +0 -0
  373. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_helm.py +0 -0
  374. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_import_export.py +0 -0
  375. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_info.py +0 -0
  376. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_infra_config_io.py +0 -0
  377. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_infra_configure.py +0 -0
  378. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_infra_deploy_node_labels.py +0 -0
  379. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_infra_deploy_preflight.py +0 -0
  380. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_infra_deploy_registry_key.py +0 -0
  381. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_infra_get_terraform.py +0 -0
  382. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_infra_hibernate.py +0 -0
  383. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_infra_init.py +0 -0
  384. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_infra_pause.py +0 -0
  385. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_infra_provision.py +0 -0
  386. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_infra_start_fixes.py +0 -0
  387. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_infra_state_bucket.py +0 -0
  388. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_infra_terraform_init.py +0 -0
  389. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_invalid_secrets.py +0 -0
  390. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_job_list_project_filter.py +0 -0
  391. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_jobs_info_hides_creator.py +0 -0
  392. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_jobs_list_unmatched.py +0 -0
  393. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_key_pair.py +0 -0
  394. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_login.py +0 -0
  395. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_logout.py +0 -0
  396. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_main.py +0 -0
  397. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_mcp_proxy.py +0 -0
  398. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_org_select.py +0 -0
  399. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_plans.py +0 -0
  400. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_projects.py +0 -0
  401. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_projects_delete_confirm.py +0 -0
  402. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_publish_build_poll.py +0 -0
  403. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_publish_data.py +0 -0
  404. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_publish_import_root.py +0 -0
  405. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_publish_requirements.py +0 -0
  406. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_publish_versions.py +0 -0
  407. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_pypi_auth.py +0 -0
  408. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_query.py +0 -0
  409. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_recipe_file.py +0 -0
  410. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_recipe_help.py +0 -0
  411. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_recipe_required_args.py +0 -0
  412. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_recipes.py +0 -0
  413. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_recipes_init.py +0 -0
  414. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_sessions.py +0 -0
  415. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_state.py +0 -0
  416. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_support.py +0 -0
  417. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_todos.py +0 -0
  418. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_ty.py +0 -0
  419. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_ui.py +0 -0
  420. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_ui_extras.py +0 -0
  421. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_usage_counts.py +0 -0
  422. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_users_assign.py +0 -0
  423. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_users_info_stats.py +0 -0
  424. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_users_list.py +0 -0
  425. {ellf_cli-21.0.10 → ellf_cli-22.0.2}/tests/test_util.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ellf-cli
3
- Version: 21.0.10
3
+ Version: 22.0.2
4
4
  Summary: Ellf Command Line Interface
5
5
  Home-page: https://prodi.gy
6
6
  Author: ExplosionAI GmbH
@@ -329,23 +329,6 @@ Delete an asset registered with Ellf
329
329
  | `--cluster` | `str` | Name, slug, or ID of the cluster to search for asset name (or the last cluster if not set) | `None` |
330
330
  | `--json` | `bool` | Output the result as JSON | `False` |
331
331
 
332
- ### `ellf auth`
333
-
334
- Manage authentication artifacts (import/push device-flow tokens)
335
-
336
- #### `ellf auth import`
337
-
338
- Read a serialised FileSecrets blob from stdin and write it to the local secrets file. Counterpart to ``ellf auth push``. Existing local auth state is overwritten; the file is written 0600 by FileSecrets.save.
339
-
340
- #### `ellf auth push`
341
-
342
- Push local auth state to a remote machine via SSH. Reads the local FileSecrets, JSON-serialises it, and pipes it to ``<remote_ellf> auth import`` over an SSH connection to *host*. Authentication is delegated to ssh — anything in your ssh config (host aliases, ProxyJump, key-based auth) just works. The pushed blob includes id_token, api_token, and any cached broker_tokens. id_token expiry is dictated by the issuer (typically ~1h), so this is a "give the remote a usable session" operation, not a permanent provisioning. Re-run when the token expires.
343
-
344
- | Argument | Type | Description | Default |
345
- | --- | --- | --- | --- |
346
- | `host` | `str` | SSH host to push the token to | |
347
- | `--remote-ellf` | `str` | Command to run on the remote (default: 'ellf' from PATH). Pass an absolute path or shell-expanded form when ellf isn't on the remote login shell's PATH, e.g. '$HOME/ellf-test/venv/bin/ellf'. | `None` |
348
-
349
332
  ### `ellf clusters`
350
333
 
351
334
  Interact with clusters
@@ -676,12 +659,12 @@ Deploy and manage cluster infrastructure (Kubernetes, TLS, Terraform)
676
659
 
677
660
  #### `ellf infra register`
678
661
 
679
- Register a new cluster with PAM and write credentials to cluster-creds.json. Pass --domain to use your own DNS, or omit it to be allocated a managed subdomain (with base + wildcard A records) under an Explosion-controlled zone.
662
+ Register a new cluster with PAM and write credentials to cluster-creds.json. Pass --domain to use your own DNS, or omit it to be allocated a managed subdomain (with base + wildcard A records) under an Explosion-controlled zone. An org on the free Solo plan has no managed subdomain: omitting --domain registers it at http://localhost.
680
663
 
681
664
  | Argument | Type | Description | Default |
682
665
  | --- | --- | --- | --- |
683
666
  | `--name` | `str` | Human-readable name for the cluster | |
684
- | `--domain` | `str` | Public address the cluster is reached on, host or host:port (e.g. 'cluster.example.com' for a hosted cluster on port 443, or 'localhost:8443' for a workstation cluster behind an SSH tunnel). Stored verbatim as the cluster address; the chart derives the bare hostname for K8s ingress / cert SAN where a port isn't allowed. Omit to get a managed subdomain under an Explosion-controlled zone. | `None` |
667
+ | `--domain` | `str` | Public address the cluster is reached on, host or host:port (e.g. 'cluster.example.com' for a hosted cluster on port 443, or 'http://localhost' for a cluster on this machine, which needs no certificate and is what the free Solo plan uses). Stored verbatim as the cluster address; the chart derives the bare hostname for K8s ingress / cert SAN where a port isn't allowed. Omit to get a managed subdomain under an Explosion-controlled zone. | `None` |
685
668
  | `--subdomain` | `str` | Requested label for a managed subdomain (e.g. 'acme' for acme.<zone>). Only valid without --domain; defaults to a slug derived from your org/cluster name. | `None` |
686
669
  | `--public-ip` | `str` | Cluster ingress IP to point the managed subdomain at. Omit to reserve the name now and re-run with --public-ip once the load balancer IP is known. | `None` |
687
670
  | `--cloud-provider` | `str` | Cloud provider: gcp, k3s, aws, azure | |
@@ -727,7 +710,7 @@ Apply terraform to create or update cluster infrastructure. Returns True when an
727
710
 
728
711
  #### `ellf infra destroy`
729
712
 
730
- Destroy the cluster infrastructure created by 'infra terraform', including every annotation, file and dataset stored on it. The database, data bucket and shared volume are deletion-protected, so this refuses to run without --delete-data. To stop paying for compute while keeping the data, use 'ellf infra pause' instead. With --delete-data, a first apply lifts the protection, then the destroy runs. On AWS the database still leaves a final snapshot behind. Note this never touches the terraform state bucket: the bucket is managed outside the terraform (see 'infra init --state-bucket') and outlives the cluster so the destroy itself has state to work against.
713
+ Destroy the cluster infrastructure created by 'infra terraform', including every annotation, file and dataset stored on it. The database, data bucket and shared volume are deletion-protected, so this refuses to run without --delete-data. To stop paying for compute while keeping the data, use 'ellf infra pause' instead. With --delete-data, a first apply lifts the protection, then the destroy runs, once the broker, its jobs and traefik are removed from the cluster. On AWS the database still leaves a final snapshot behind. Note this never touches the terraform state bucket: the bucket is managed outside the terraform (see 'infra init --state-bucket') and outlives the cluster so the destroy itself has state to work against.
731
714
 
732
715
  | Argument | Type | Description | Default |
733
716
  | --- | --- | --- | --- |
@@ -893,20 +876,6 @@ Start a cluster on infrastructure configured under your own cloud account.
893
876
  | `--config-key` | `str` | Top-level key for the cluster config. | `None` |
894
877
  | `--offline` | `Path` | Path to a credentials JSON file. Deploys without connecting to PAM. | `None` |
895
878
 
896
- #### `ellf infra tls`
897
-
898
- Manage TLS certificates for local cluster access. Use --self-signed when you have direct kubectl access to the cluster. Use --setup HOST to do everything from your laptop over SSH. Use --trust HOST to fetch and install an existing CA from a remote cluster.
899
-
900
- | Argument | Type | Description | Default |
901
- | --- | --- | --- | --- |
902
- | `--self-signed` | `bool` | Create a self-signed CA and certificate | `False` |
903
- | `--trust` | `str` | SSH host to fetch CA from and install into local trust store | `None` |
904
- | `--setup` | `str` | SSH host: create certs remotely, then fetch and trust the CA locally | `None` |
905
- | `--status` | `bool` | Show current TLS configuration | `False` |
906
- | `--fqdn` | `str` | Certificate FQDN (default: localhost) | `'localhost'` |
907
- | `--namespace` | `str` | Kubernetes namespace | `'ellf'` |
908
- | `--output` | `str` | Output format for trust commands: human, json, shell | `'human'` |
909
-
910
879
  ### `ellf jobs`
911
880
 
912
881
  Run jobs directly on the cluster
@@ -6,11 +6,10 @@ import truststore
6
6
 
7
7
  # Use the OS native trust store (macOS Keychain, /etc/ssl/certs on Linux,
8
8
  # Windows certificate store) for every httpx/urllib/requests call this
9
- # CLI makes — instead of httpx's default certifi bundle. This collapses
10
- # three trust stores into one: a `sudo security add-trusted-cert
11
- # ~/.prodigy-teams/ca.crt` (or the Linux equivalent) makes the browser,
12
- # curl, AND the CLI all trust the cluster's self-signed CA from one
13
- # install. No SSL_CERT_FILE, no combined ca.pem, no per-cluster bundle.
9
+ # CLI makes — instead of httpx's default certifi bundle — so a CA the
10
+ # machine already trusts (a corporate proxy's, or a dev stack's) is
11
+ # trusted by the browser, curl and the CLI alike, with no SSL_CERT_FILE
12
+ # or separate bundle to maintain.
14
13
  # Must run before any code constructs an ssl.SSLContext, so it sits at
15
14
  # module top.
16
15
  truststore.inject_into_ssl()
@@ -560,9 +560,8 @@ class AuthStateImpl:
560
560
  # lookup is brittle: the registered cluster.address (e.g.
561
561
  # 'cluster.example.com' or 'localhost') often doesn't textually
562
562
  # match broker_host (e.g. 'https://localhost:8443'), and even
563
- # canonicalized forms differ when the user includes a port to
564
- # reach the cluster via tunnel that the cluster.address doesn't
565
- # carry. cluster_id is unambiguous.
563
+ # canonicalized forms differ when broker_host carries a port the
564
+ # cluster.address doesn't. cluster_id is unambiguous.
566
565
  body: dict[str, str] = {}
567
566
  if self._cluster_id is not None:
568
567
  body["id"] = str(self._cluster_id)
@@ -106,7 +106,6 @@ cli.placeholder("actions", description=Messages.doc_actions)
106
106
  cli.placeholder("todo", description=Messages.doc_todos)
107
107
  cli.placeholder("agents", description=Messages.doc_agents)
108
108
  cli.placeholder("assets", description=Messages.doc_assets)
109
- cli.placeholder("auth", description=Messages.doc_auth)
110
109
  cli.placeholder("clusters", description=Messages.doc_clusters)
111
110
  cli.placeholder("config", description=Messages.doc_config)
112
111
  cli.placeholder("datasets", description=Messages.doc_datasets)
@@ -2,7 +2,6 @@ from . import (
2
2
  actions,
3
3
  agents,
4
4
  assets,
5
- auth,
6
5
  clusters,
7
6
  config,
8
7
  datasets,
@@ -39,7 +38,6 @@ __all__ = [
39
38
  "todos",
40
39
  "agents",
41
40
  "assets",
42
- "auth",
43
41
  "clusters",
44
42
  "config",
45
43
  "datasets",
@@ -10,5 +10,4 @@ from . import ( # noqa: F401
10
10
  setup,
11
11
  start,
12
12
  terraform,
13
- tls,
14
13
  )
@@ -5,7 +5,7 @@ import json
5
5
  import subprocess
6
6
  import tempfile
7
7
  from pathlib import Path
8
- from typing import Annotated
8
+ from typing import TYPE_CHECKING, Annotated
9
9
  from uuid import UUID
10
10
 
11
11
  from pydantic import AliasChoices, BaseModel, Field, StringConstraints
@@ -14,6 +14,9 @@ from wasabi import msg
14
14
  from ellf_pam_sdk import Client
15
15
  from ellf_pam_sdk.models import ClusterCredentials, ClusterDetail
16
16
 
17
+ if TYPE_CHECKING:
18
+ from ...cluster_config import ClusterConfig
19
+
17
20
  # Matches pam/ellf_pam/config.py's NonEmptyStr convention.
18
21
  NonEmptyStr = Annotated[str, StringConstraints(min_length=1)]
19
22
 
@@ -146,6 +149,32 @@ def get_cluster_credentials(
146
149
  )
147
150
 
148
151
 
152
+ def use_cluster_credentials(config: "ClusterConfig") -> None:
153
+ """Point kubectl at the cluster *config* describes."""
154
+ cluster_name = config.deployment.cluster_name
155
+ cloud_provider = config.deployment.cloud_provider
156
+ if cloud_provider == "aws":
157
+ assert config.deployment.aws
158
+ get_cluster_credentials(
159
+ "aws", cluster_name, region=config.deployment.aws.region
160
+ )
161
+ elif cloud_provider == "azure":
162
+ assert config.deployment.azure
163
+ get_cluster_credentials(
164
+ "azure",
165
+ cluster_name,
166
+ resource_group=config.deployment.azure.resource_group,
167
+ )
168
+ else:
169
+ assert config.deployment.gcp
170
+ get_cluster_credentials(
171
+ "gcp",
172
+ cluster_name,
173
+ project=config.deployment.gcp.project,
174
+ zone=config.deployment.gcp.zone,
175
+ )
176
+
177
+
149
178
  def ensure_cluster_keypair(infra_secret_name: str, namespace: str = "ellf") -> str:
150
179
  """Ensure the infra K8s secret has a cluster RSA keypair, return the public PEM.
151
180
 
@@ -169,13 +169,25 @@ def init(
169
169
  # Stage 1 covers the cloud path; the k3s deployment isn't
170
170
  # representable in ClusterConfig yet, so hand over to the documented
171
171
  # local flow after registration.
172
- msg.info(
173
- "Local (k3s) cluster registered. Continue with the local flow:\n"
174
- " ellf infra setup --cert-manager\n"
175
- " ellf infra init-values --creds cluster-creds.json "
176
- "--cloud-provider k3s --domain <domain>\n"
177
- " ellf infra deploy --values values.yaml --wait"
178
- )
172
+ # A cluster on http://localhost needs no certificate; one on a
173
+ # public domain gets Let's Encrypt through cert-manager.
174
+ if address.startswith("http://"):
175
+ steps = [
176
+ "ellf infra init-values --creds cluster-creds.json "
177
+ f"--cloud-provider k3s --domain {address}",
178
+ ]
179
+ else:
180
+ steps = [
181
+ "ellf infra setup --cert-manager",
182
+ "ellf infra init-values --creds cluster-creds.json "
183
+ f"--cloud-provider k3s --domain {address} --acme-email <email>",
184
+ ]
185
+ steps.append("ellf infra deploy --values values.yaml --wait")
186
+ msg.info("Local (k3s) cluster registered. Continue with the local flow:")
187
+ # Plain prints: wasabi re-wraps its messages, which ran the steps
188
+ # together into one paragraph.
189
+ for step in steps:
190
+ print(f" {step}")
179
191
  return
180
192
 
181
193
  # --- 2. Terraform files -------------------------------------------------
@@ -13,6 +13,7 @@ from ellf_pam_sdk.models import ClusterCreating, ClusterUpdating
13
13
 
14
14
  from ...cli import cli
15
15
  from ...messages import Messages
16
+ from ...util import URL
16
17
  from ._helpers import ClusterCredsFile
17
18
 
18
19
  CLOUD_PROVIDERS = ("gcp", "k3s", "aws", "azure")
@@ -23,6 +24,11 @@ CLOUD_PROVIDERS = ("gcp", "k3s", "aws", "azure")
23
24
  PENDING_ADDRESS = "pending.invalid"
24
25
 
25
26
 
27
+ def _org_is_solo(client, org_id) -> bool:
28
+ """Whether the org is on the free Solo plan, as PAM judges it."""
29
+ return client.org.read(id=org_id).billing_state == "solo"
30
+
31
+
26
32
  class Registration(NamedTuple):
27
33
  """Outcome of ensure_registered, consumed by register and infra init."""
28
34
 
@@ -43,7 +49,8 @@ class Registration(NamedTuple):
43
49
  help=(
44
50
  "Public address the cluster is reached on, host or host:port "
45
51
  "(e.g. 'cluster.example.com' for a hosted cluster on port 443, "
46
- "or 'localhost:8443' for a workstation cluster behind an SSH tunnel). "
52
+ "or 'http://localhost' for a cluster on this machine, which needs "
53
+ "no certificate and is what the free Solo plan uses). "
47
54
  "Stored verbatim as the cluster address; the chart derives the "
48
55
  "bare hostname for K8s ingress / cert SAN where a port isn't allowed. "
49
56
  "Omit to get a managed subdomain under an Explosion-controlled zone."
@@ -101,7 +108,8 @@ def register(
101
108
 
102
109
  Pass --domain to use your own DNS, or omit it to be allocated a managed
103
110
  subdomain (with base + wildcard A records) under an Explosion-controlled
104
- zone.
111
+ zone. An org on the free Solo plan has no managed subdomain: omitting
112
+ --domain registers it at http://localhost.
105
113
  """
106
114
  from .._state import get_auth_state
107
115
 
@@ -175,6 +183,12 @@ def ensure_registered(
175
183
  ),
176
184
  None,
177
185
  )
186
+ # Solo's one cluster is on localhost, and PAM refuses it anything else.
187
+ if domain is None and _org_is_solo(client, org_id):
188
+ msg.info(Messages.T074)
189
+ # Plain http: browsers treat localhost as a secure context, so
190
+ # the cluster needs no certificate.
191
+ domain = "http://localhost"
178
192
  # With no --domain, register under a placeholder first; the managed
179
193
  # subdomain allocation below replaces it with the real FQDN. On
180
194
  # re-registration keep whatever address the cluster already has so an
@@ -255,11 +269,15 @@ def ensure_registered(
255
269
  srsly.write_json(creds_path, creds_data)
256
270
  # Persist the cluster id locally so subsequent `ellf` commands resolve the
257
271
  # cluster identity from saved-defaults instead of looking it up by address
258
- # (which is brittle when the user later sets `broker_host` to a tunnel URL
259
- # like `https://localhost:8443` that doesn't match the registered domain).
272
+ # (which is brittle when `broker_host` is spelled differently from the
273
+ # registered domain, e.g. `https://localhost:8443` against `localhost`).
274
+ # The broker host goes with it, as `clusters use` saves them: a host left
275
+ # over from another cluster would send this cluster's token exchange to
276
+ # that one, which refuses it.
260
277
  settings = get_saved_settings()
261
278
  prior_cluster_id = settings.cluster_id
262
279
  settings.cluster_id = cluster.id
280
+ settings.broker_host = str(URL.parse(allocated_fqdn or address))
263
281
  settings.save(get_root_cfg().saved_settings_path)
264
282
  # Any cached cluster access token from a previous cluster_id is now stale.
265
283
  # The cache is keyed by broker_host; if the cluster behind that host has
@@ -24,10 +24,10 @@ from ._helpers import (
24
24
  ensure_cluster_record,
25
25
  ensure_traefik,
26
26
  get_cluster_auth,
27
- get_cluster_credentials,
28
27
  get_traefik_lb_address,
29
28
  helm_registry_login,
30
29
  point_managed_dns,
30
+ use_cluster_credentials,
31
31
  )
32
32
 
33
33
  DEFAULT_NAMESPACE = "ellf"
@@ -62,28 +62,8 @@ def start(
62
62
  src = Path(src)
63
63
  config = load_cluster_config(src, config_path, config_key)
64
64
  check_deploy_ready(config)
65
- cluster_name = config.deployment.cluster_name
66
65
  cloud_provider = config.deployment.cloud_provider
67
- if cloud_provider == "aws":
68
- assert config.deployment.aws
69
- get_cluster_credentials(
70
- "aws", cluster_name, region=config.deployment.aws.region
71
- )
72
- elif cloud_provider == "azure":
73
- assert config.deployment.azure
74
- get_cluster_credentials(
75
- "azure",
76
- cluster_name,
77
- resource_group=config.deployment.azure.resource_group,
78
- )
79
- else:
80
- assert config.deployment.gcp
81
- get_cluster_credentials(
82
- "gcp",
83
- cluster_name,
84
- project=config.deployment.gcp.project,
85
- zone=config.deployment.gcp.zone,
86
- )
66
+ use_cluster_credentials(config)
87
67
  public_key = ensure_cluster_keypair(config.deployment.infra_secret_name)
88
68
  cluster_detail = None
89
69
  dns_client = None
@@ -7,7 +7,7 @@ import subprocess
7
7
  import sys
8
8
  import tarfile
9
9
  from pathlib import Path
10
- from typing import Optional, Union
10
+ from typing import Callable, Optional, Union
11
11
 
12
12
  from radicli import Arg
13
13
  from wasabi import msg
@@ -495,7 +495,8 @@ def destroy_terraform(
495
495
  The database, data bucket and shared volume are deletion-protected, so
496
496
  this refuses to run without --delete-data. To stop paying for compute
497
497
  while keeping the data, use 'ellf infra pause' instead. With
498
- --delete-data, a first apply lifts the protection, then the destroy runs.
498
+ --delete-data, a first apply lifts the protection, then the destroy runs,
499
+ once the broker, its jobs and traefik are removed from the cluster.
499
500
  On AWS the database still leaves a final snapshot behind.
500
501
 
501
502
  Note this never touches the terraform state bucket: the bucket is managed
@@ -537,6 +538,7 @@ def destroy_terraform(
537
538
  destroy=True,
538
539
  prompt="Destroy all listed resources? 'yes' to accept\n",
539
540
  auto_accept=yes_tf_auto_accept,
541
+ before_apply=lambda: _clear_cluster_workloads(config),
540
542
  ):
541
543
  msg.warn(
542
544
  "Destroy declined, but the deletion protection is lifted. Re-run "
@@ -555,6 +557,7 @@ def _plan_and_apply(
555
557
  destroy: bool,
556
558
  prompt: str,
557
559
  auto_accept: bool,
560
+ before_apply: Optional[Callable[[], None]] = None,
558
561
  ) -> bool:
559
562
  """Plan, confirm, apply. Returns False when the plan was declined."""
560
563
  cmd = ["terraform", "plan"]
@@ -574,11 +577,59 @@ def _plan_and_apply(
574
577
  )
575
578
  if input(prompt).strip() != "yes":
576
579
  return False
580
+ if before_apply is not None:
581
+ before_apply()
577
582
  cmd = ["terraform", "apply", "-auto-approve", plan_file]
578
583
  _ = subprocess.run(cmd, check=True, text=True, cwd=tf_dir)
579
584
  return True
580
585
 
581
586
 
587
+ def _clear_cluster_workloads(config: ClusterConfig) -> None:
588
+ """Remove what 'infra start' and the broker put in the cluster, which
589
+ terraform doesn't manage but its destroy depends on.
590
+
591
+ Every pod in the ellf namespace -- the broker's, and the jobs it runs
592
+ -- mounts the shared volume, and Kubernetes won't delete a PVC that a
593
+ pod still uses, so terraform's destroy of it hangs until it times out.
594
+ Traefik's LoadBalancer Service, deleted along with the cluster, can
595
+ leave its cloud load balancer behind, still billing.
596
+ """
597
+ from ._helpers import use_cluster_credentials
598
+ from .hibernate import _release_load_balancer
599
+ from .pause import _run
600
+
601
+ if config.deployment.hibernated:
602
+ return
603
+ try:
604
+ use_cluster_credentials(config)
605
+ except subprocess.CalledProcessError as err:
606
+ msg.warn(f"Couldn't reach the cluster ({err}); destroying it as it is.")
607
+ return
608
+ if _helm_release_installed("ellf", "ellf"):
609
+ msg.info("Uninstalling the ellf release")
610
+ _run(["helm", "uninstall", "ellf", "-n", "ellf", "--wait"])
611
+ # Jobs the broker started aren't part of the release, and helm's --wait
612
+ # returns before the pods of the workloads it deleted are gone.
613
+ _run(
614
+ ["kubectl", "delete", "deployments,statefulsets,jobs,pods", "--all"]
615
+ + ["-n", "ellf", "--ignore-not-found", "--wait", "--timeout=10m"]
616
+ )
617
+ if config.deployment.cloud_provider == "gcp":
618
+ _release_load_balancer(config)
619
+ elif _helm_release_installed("traefik", "traefik"):
620
+ msg.info("Uninstalling traefik to release the load balancer")
621
+ _run(["helm", "uninstall", "traefik", "-n", "traefik", "--wait"])
622
+
623
+
624
+ def _helm_release_installed(release: str, namespace: str) -> bool:
625
+ status = subprocess.run(
626
+ ["helm", "status", release, "-n", namespace],
627
+ capture_output=True,
628
+ text=True,
629
+ )
630
+ return status.returncode == 0
631
+
632
+
582
633
  def _find_csi_filestore(config: ClusterConfig) -> "tuple[str, str] | None":
583
634
  """The (zone, instance) of the GKE shared volume's CSI-provisioned
584
635
  Filestore, or None when the cluster has none.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "prog": "ellf",
3
3
  "help": "Ellf Command Line Interface.",
4
- "version": "21.0.10",
4
+ "version": "22.0.2",
5
5
  "extra_key": "_extra",
6
6
  "commands": {
7
7
  "actions": {
@@ -36,14 +36,6 @@
36
36
  "parent": null,
37
37
  "is_placeholder": true
38
38
  },
39
- "auth": {
40
- "name": "auth",
41
- "args": [],
42
- "description": "Manage authentication artifacts (import/push device-flow tokens)",
43
- "allow_extra": false,
44
- "parent": null,
45
- "is_placeholder": true
46
- },
47
39
  "clusters": {
48
40
  "name": "clusters",
49
41
  "args": [],
@@ -1968,51 +1960,6 @@
1968
1960
  "is_placeholder": false
1969
1961
  }
1970
1962
  },
1971
- "auth": {
1972
- "import": {
1973
- "name": "import",
1974
- "args": [],
1975
- "description": "Read a serialised FileSecrets blob from stdin and write it to\nthe local secrets file.\n\nCounterpart to ``ellf auth push``. Existing local auth state is\noverwritten; the file is written 0600 by FileSecrets.save.\n",
1976
- "allow_extra": false,
1977
- "parent": "auth",
1978
- "is_placeholder": false
1979
- },
1980
- "push": {
1981
- "name": "push",
1982
- "args": [
1983
- {
1984
- "id": "host",
1985
- "option": null,
1986
- "short": null,
1987
- "orig_help": "SSH host to push the token to",
1988
- "default": "==SUPPRESS==",
1989
- "help": "SSH host to push the token to (str)",
1990
- "action": null,
1991
- "choices": null,
1992
- "has_converter": false,
1993
- "type": "str",
1994
- "orig_type": "str"
1995
- },
1996
- {
1997
- "id": "remote_ellf",
1998
- "option": "--remote-ellf",
1999
- "short": null,
2000
- "orig_help": "Command to run on the remote (default: 'ellf' from PATH). Pass an absolute path or shell-expanded form when ellf isn't on the remote login shell's PATH, e.g. '$HOME/ellf-test/venv/bin/ellf'.",
2001
- "default": null,
2002
- "help": "Command to run on the remote (default: 'ellf' from PATH). Pass an absolute path or shell-expanded form when ellf isn't on the remote login shell's PATH, e.g. '$HOME/ellf-test/venv/bin/ellf'. (str)",
2003
- "action": null,
2004
- "choices": null,
2005
- "has_converter": false,
2006
- "type": "str",
2007
- "orig_type": "str"
2008
- }
2009
- ],
2010
- "description": "Push local auth state to a remote machine via SSH.\n\nReads the local FileSecrets, JSON-serialises it, and pipes it to\n``<remote_ellf> auth import`` over an SSH connection to *host*.\nAuthentication is delegated to ssh \u2014 anything in your ssh config\n(host aliases, ProxyJump, key-based auth) just works.\n\nThe pushed blob includes id_token, api_token, and any cached\nbroker_tokens. id_token expiry is dictated by the issuer (typically\n~1h), so this is a \"give the remote a usable session\" operation,\nnot a permanent provisioning. Re-run when the token expires.\n",
2011
- "allow_extra": false,
2012
- "parent": "auth",
2013
- "is_placeholder": false
2014
- }
2015
- },
2016
1963
  "clusters": {
2017
1964
  "list": {
2018
1965
  "name": "list",
@@ -3616,9 +3563,9 @@
3616
3563
  "id": "domain",
3617
3564
  "option": "--domain",
3618
3565
  "short": null,
3619
- "orig_help": "Public address the cluster is reached on, host or host:port (e.g. 'cluster.example.com' for a hosted cluster on port 443, or 'localhost:8443' for a workstation cluster behind an SSH tunnel). Stored verbatim as the cluster address; the chart derives the bare hostname for K8s ingress / cert SAN where a port isn't allowed. Omit to get a managed subdomain under an Explosion-controlled zone.",
3566
+ "orig_help": "Public address the cluster is reached on, host or host:port (e.g. 'cluster.example.com' for a hosted cluster on port 443, or 'http://localhost' for a cluster on this machine, which needs no certificate and is what the free Solo plan uses). Stored verbatim as the cluster address; the chart derives the bare hostname for K8s ingress / cert SAN where a port isn't allowed. Omit to get a managed subdomain under an Explosion-controlled zone.",
3620
3567
  "default": null,
3621
- "help": "Public address the cluster is reached on, host or host:port (e.g. 'cluster.example.com' for a hosted cluster on port 443, or 'localhost:8443' for a workstation cluster behind an SSH tunnel). Stored verbatim as the cluster address; the chart derives the bare hostname for K8s ingress / cert SAN where a port isn't allowed. Omit to get a managed subdomain under an Explosion-controlled zone. (str)",
3568
+ "help": "Public address the cluster is reached on, host or host:port (e.g. 'cluster.example.com' for a hosted cluster on port 443, or 'http://localhost' for a cluster on this machine, which needs no certificate and is what the free Solo plan uses). Stored verbatim as the cluster address; the chart derives the bare hostname for K8s ingress / cert SAN where a port isn't allowed. Omit to get a managed subdomain under an Explosion-controlled zone. (str)",
3622
3569
  "action": null,
3623
3570
  "choices": null,
3624
3571
  "has_converter": false,
@@ -3704,7 +3651,7 @@
3704
3651
  "orig_type": "bool"
3705
3652
  }
3706
3653
  ],
3707
- "description": "Register a new cluster with PAM and write credentials to cluster-creds.json.\n\nPass --domain to use your own DNS, or omit it to be allocated a managed\nsubdomain (with base + wildcard A records) under an Explosion-controlled\nzone.\n",
3654
+ "description": "Register a new cluster with PAM and write credentials to cluster-creds.json.\n\nPass --domain to use your own DNS, or omit it to be allocated a managed\nsubdomain (with base + wildcard A records) under an Explosion-controlled\nzone. An org on the free Solo plan has no managed subdomain: omitting\n--domain registers it at http://localhost.\n",
3708
3655
  "allow_extra": false,
3709
3656
  "parent": "infra",
3710
3657
  "is_placeholder": false
@@ -4000,7 +3947,7 @@
4000
3947
  "orig_type": "bool"
4001
3948
  }
4002
3949
  ],
4003
- "description": "Destroy the cluster infrastructure created by 'infra terraform',\nincluding every annotation, file and dataset stored on it.\n\nThe database, data bucket and shared volume are deletion-protected, so\nthis refuses to run without --delete-data. To stop paying for compute\nwhile keeping the data, use 'ellf infra pause' instead. With\n--delete-data, a first apply lifts the protection, then the destroy runs.\nOn AWS the database still leaves a final snapshot behind.\n\nNote this never touches the terraform state bucket: the bucket is managed\noutside the terraform (see 'infra init --state-bucket') and outlives the\ncluster so the destroy itself has state to work against.\n",
3950
+ "description": "Destroy the cluster infrastructure created by 'infra terraform',\nincluding every annotation, file and dataset stored on it.\n\nThe database, data bucket and shared volume are deletion-protected, so\nthis refuses to run without --delete-data. To stop paying for compute\nwhile keeping the data, use 'ellf infra pause' instead. With\n--delete-data, a first apply lifts the protection, then the destroy runs,\nonce the broker, its jobs and traefik are removed from the cluster.\nOn AWS the database still leaves a final snapshot behind.\n\nNote this never touches the terraform state bucket: the bucket is managed\noutside the terraform (see 'infra init --state-bucket') and outlives the\ncluster so the destroy itself has state to work against.\n",
4004
3951
  "allow_extra": false,
4005
3952
  "parent": "infra",
4006
3953
  "is_placeholder": false
@@ -5130,106 +5077,6 @@
5130
5077
  "allow_extra": false,
5131
5078
  "parent": "infra",
5132
5079
  "is_placeholder": false
5133
- },
5134
- "tls": {
5135
- "name": "tls",
5136
- "args": [
5137
- {
5138
- "id": "self_signed",
5139
- "option": "--self-signed",
5140
- "short": null,
5141
- "orig_help": "Create a self-signed CA and certificate",
5142
- "default": false,
5143
- "help": "Create a self-signed CA and certificate (bool)",
5144
- "action": "store_true",
5145
- "choices": null,
5146
- "has_converter": false,
5147
- "type": null,
5148
- "orig_type": "bool"
5149
- },
5150
- {
5151
- "id": "trust",
5152
- "option": "--trust",
5153
- "short": null,
5154
- "orig_help": "SSH host to fetch CA from and install into local trust store",
5155
- "default": null,
5156
- "help": "SSH host to fetch CA from and install into local trust store (str)",
5157
- "action": null,
5158
- "choices": null,
5159
- "has_converter": false,
5160
- "type": "str",
5161
- "orig_type": "str"
5162
- },
5163
- {
5164
- "id": "setup",
5165
- "option": "--setup",
5166
- "short": null,
5167
- "orig_help": "SSH host: create certs remotely, then fetch and trust the CA locally",
5168
- "default": null,
5169
- "help": "SSH host: create certs remotely, then fetch and trust the CA locally (str)",
5170
- "action": null,
5171
- "choices": null,
5172
- "has_converter": false,
5173
- "type": "str",
5174
- "orig_type": "str"
5175
- },
5176
- {
5177
- "id": "status",
5178
- "option": "--status",
5179
- "short": null,
5180
- "orig_help": "Show current TLS configuration",
5181
- "default": false,
5182
- "help": "Show current TLS configuration (bool)",
5183
- "action": "store_true",
5184
- "choices": null,
5185
- "has_converter": false,
5186
- "type": null,
5187
- "orig_type": "bool"
5188
- },
5189
- {
5190
- "id": "fqdn",
5191
- "option": "--fqdn",
5192
- "short": null,
5193
- "orig_help": "Certificate FQDN (default: localhost)",
5194
- "default": "localhost",
5195
- "help": "Certificate FQDN (default: localhost) (str)",
5196
- "action": null,
5197
- "choices": null,
5198
- "has_converter": false,
5199
- "type": "str",
5200
- "orig_type": "str"
5201
- },
5202
- {
5203
- "id": "namespace",
5204
- "option": "--namespace",
5205
- "short": null,
5206
- "orig_help": "Kubernetes namespace",
5207
- "default": "ellf",
5208
- "help": "Kubernetes namespace (str)",
5209
- "action": null,
5210
- "choices": null,
5211
- "has_converter": false,
5212
- "type": "str",
5213
- "orig_type": "str"
5214
- },
5215
- {
5216
- "id": "output",
5217
- "option": "--output",
5218
- "short": null,
5219
- "orig_help": "Output format for trust commands: human, json, shell",
5220
- "default": "human",
5221
- "help": "Output format for trust commands: human, json, shell (str)",
5222
- "action": null,
5223
- "choices": null,
5224
- "has_converter": false,
5225
- "type": "str",
5226
- "orig_type": "str"
5227
- }
5228
- ],
5229
- "description": "Manage TLS certificates for local cluster access.\n\nUse --self-signed when you have direct kubectl access to the cluster.\nUse --setup HOST to do everything from your laptop over SSH.\nUse --trust HOST to fetch and install an existing CA from a remote cluster.\n",
5230
- "allow_extra": false,
5231
- "parent": "infra",
5232
- "is_placeholder": false
5233
5080
  }
5234
5081
  },
5235
5082
  "jobs": {