ellf-cli 18.0.0__tar.gz → 18.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 (314) hide show
  1. {ellf_cli-18.0.0/ellf_cli.egg-info → ellf_cli-18.0.2}/PKG-INFO +1 -1
  2. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/publish_code.py +104 -24
  3. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf.json +1 -1
  4. ellf_cli-18.0.2/ellf_cli/version/18.0.0_2026-09-12-10-01-10_patch_8995783a-a9fa-4c4e-90b3-6386a4c481eb +3 -0
  5. ellf_cli-18.0.2/ellf_cli/version/18.0.1_2026-09-12-17-33-30_patch_f6ea2c99-a715-4c4d-876a-23ed8c62a83d +3 -0
  6. {ellf_cli-18.0.0 → ellf_cli-18.0.2/ellf_cli.egg-info}/PKG-INFO +1 -1
  7. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli.egg-info/SOURCES.txt +3 -0
  8. ellf_cli-18.0.2/tests/test_publish_import_root.py +120 -0
  9. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/LICENSE +0 -0
  10. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/MANIFEST.in +0 -0
  11. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/README.md +0 -0
  12. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/__init__.py +0 -0
  13. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/__main__.py +0 -0
  14. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/about.json +0 -0
  15. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/about.py +0 -0
  16. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/appdirs.py +0 -0
  17. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/auth.py +0 -0
  18. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/cli.py +0 -0
  19. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/cloud/__init__.py +0 -0
  20. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/cloud/gcp.py +0 -0
  21. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/cluster_config.py +0 -0
  22. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/__init__.py +0 -0
  23. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/_cluster_select.py +0 -0
  24. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/_org_select.py +0 -0
  25. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/_project_scope.py +0 -0
  26. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/_recipe_file.py +0 -0
  27. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/_recipe_subcommand.py +0 -0
  28. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/_state.py +0 -0
  29. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/_usage.py +0 -0
  30. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/actions.py +0 -0
  31. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/agents.py +0 -0
  32. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/assets.py +0 -0
  33. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/auth.py +0 -0
  34. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/clusters.py +0 -0
  35. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/config.py +0 -0
  36. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/datasets.py +0 -0
  37. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/files/__init__.py +0 -0
  38. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/files/cp.py +0 -0
  39. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/files/ls.py +0 -0
  40. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/files/rm.py +0 -0
  41. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/files/rsync.py +0 -0
  42. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/files/stats.py +0 -0
  43. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/general.py +0 -0
  44. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/import_export.py +0 -0
  45. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/infra/__init__.py +0 -0
  46. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/infra/_config_io.py +0 -0
  47. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/infra/_helpers.py +0 -0
  48. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/infra/configure.py +0 -0
  49. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/infra/deploy.py +0 -0
  50. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/infra/init.py +0 -0
  51. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/infra/init_values.py +0 -0
  52. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/infra/provision.py +0 -0
  53. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/infra/register.py +0 -0
  54. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/infra/setup.py +0 -0
  55. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/infra/start.py +0 -0
  56. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/infra/terraform.py +0 -0
  57. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/infra/tls.py +0 -0
  58. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/jobs.py +0 -0
  59. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/packages.py +0 -0
  60. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/paths.py +0 -0
  61. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/plans.py +0 -0
  62. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/projects.py +0 -0
  63. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/publish_data.py +0 -0
  64. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/recipes.py +0 -0
  65. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/secrets.py +0 -0
  66. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/services.py +0 -0
  67. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/support.py +0 -0
  68. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/tasks.py +0 -0
  69. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/todos.py +0 -0
  70. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/commands/users.py +0 -0
  71. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/config.py +0 -0
  72. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/.claude-plugin/plugin.json +0 -0
  73. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/.gitignore +0 -0
  74. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skill_variants.json +0 -0
  75. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-annotate.assistant/SKILL.md +0 -0
  76. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-annotate.assistant/references/annotation_audit.md +0 -0
  77. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-annotate.assistant/references/builtin_ellf_annotation_recipes.md +0 -0
  78. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-annotate.coding/SKILL.md +0 -0
  79. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-annotate.coding/references/annotation_audit.md +0 -0
  80. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-annotate.coding/references/builtin_ellf_annotation_recipes.md +0 -0
  81. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-annotate.coding/references/builtin_prodigy_recipes.md +0 -0
  82. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-ask/SKILL.md +0 -0
  83. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-handoff/SKILL.md +0 -0
  84. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-monitor.assistant/SKILL.md +0 -0
  85. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-monitor.assistant/references/annotation_metrics.md +0 -0
  86. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-monitor.assistant/references/training_monitoring.md +0 -0
  87. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-monitor.coding/SKILL.md +0 -0
  88. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-monitor.coding/references/annotation_metrics.md +0 -0
  89. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-monitor.coding/references/training_monitoring.md +0 -0
  90. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-monitor.coding/scripts/check_training.py +0 -0
  91. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-ops.assistant/SKILL.md +0 -0
  92. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-ops.coding/SKILL.md +0 -0
  93. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-ops.coding/references/data_infra_cli.md +0 -0
  94. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-ops.coding/scripts/run_job.py +0 -0
  95. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-patterns/SKILL.md +0 -0
  96. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-patterns/references/pattern_strategies.md +0 -0
  97. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/SKILL.md +0 -0
  98. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_action_recipe.py +0 -0
  99. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_agent_recipe.py +0 -0
  100. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_blocks_ui.py +0 -0
  101. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_correct.py +0 -0
  102. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_custom_ui.py +0 -0
  103. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_manual.py +0 -0
  104. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_pages_ui.py +0 -0
  105. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_routing.py +0 -0
  106. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_task_recipe.py +0 -0
  107. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_teach.py +0 -0
  108. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/builtin_recipes.md +0 -0
  109. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/ellf_recipe_sdk.md +0 -0
  110. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/lint_recipe.py +0 -0
  111. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/prodigy_recipe_api.md +0 -0
  112. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/template_index.md +0 -0
  113. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-project.assistant/SKILL.md +0 -0
  114. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-project.assistant/references/consulting_patterns.md +0 -0
  115. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-project.assistant/references/explosion_strategy.md +0 -0
  116. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-project.assistant/references/prodigy_llm_bot.md +0 -0
  117. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-project.coding/SKILL.md +0 -0
  118. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-project.coding/references/consulting_patterns.md +0 -0
  119. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-project.coding/references/explosion_strategy.md +0 -0
  120. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-project.coding/references/prodigy_llm_bot.md +0 -0
  121. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-support.assistant/SKILL.md +0 -0
  122. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-support.coding/SKILL.md +0 -0
  123. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-todo/SKILL.md +0 -0
  124. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-train.assistant/SKILL.md +0 -0
  125. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-train.assistant/references/diagnostics.md +0 -0
  126. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-train.assistant/references/evaluation_guide.md +0 -0
  127. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-train.assistant/references/model_selection.md +0 -0
  128. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-train.assistant/references/training_paradigms.md +0 -0
  129. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-train.assistant/references/workflow.md +0 -0
  130. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-train.coding/SKILL.md +0 -0
  131. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/config_advanced.md +0 -0
  132. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/config_architectures.md +0 -0
  133. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/config_training.md +0 -0
  134. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/diagnostics.md +0 -0
  135. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/evaluation_guide.md +0 -0
  136. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/experiment_patterns.md +0 -0
  137. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/model_selection.md +0 -0
  138. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/training_paradigms.md +0 -0
  139. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/training_troubleshooting.md +0 -0
  140. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/workflow.md +0 -0
  141. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ellf_skills/skills/ellf-train.coding/scripts/ellf_logger.py +0 -0
  142. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/errors.py +0 -0
  143. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/helm.py +0 -0
  144. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/interactivity.py +0 -0
  145. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/key_pair.py +0 -0
  146. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/main.py +0 -0
  147. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/messages.py +0 -0
  148. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/pypi_auth.py +0 -0
  149. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/query.py +0 -0
  150. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/recipes_cookiecutter/cookiecutter.json +0 -0
  151. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/.gitignore +0 -0
  152. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/README.md.tmpl +0 -0
  153. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/requirements-dev.in +0 -0
  154. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/requirements.in +0 -0
  155. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/setup.py.tmpl +0 -0
  156. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/{{cookiecutter.package_name}}/__init__.py +0 -0
  157. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/{{cookiecutter.package_name}}/about.py +0 -0
  158. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/{{cookiecutter.package_name}}/recipes/__init__.py +0 -0
  159. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/{{cookiecutter.package_name}}/recipes/example_task.py +0 -0
  160. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/testing/__init__.py +0 -0
  161. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ty.py +0 -0
  162. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/ui.py +0 -0
  163. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/url.py +0 -0
  164. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/util.py +0 -0
  165. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.114_2026-08-19-08-36-57__1a4e37c1-471e-4a81-b4d5-1ffe7dec3a61 +0 -0
  166. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.114_2026-08-19-09-25-21_patch_33ff1e26-0e5e-46d8-8052-ab1d032e8b6c +0 -0
  167. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.115_2026-08-19-09-27-13_patch_4ac728c3-0342-4a36-adbc-e28d2d99b1ba +0 -0
  168. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.116_2026-08-19-09-30-47_patch_c706fef6-6813-4183-b268-12e7b00d7d0b +0 -0
  169. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.117_2026-08-19-09-39-14_patch_c6b0495f-2f88-4aa8-9ebf-0a235b4c407e +0 -0
  170. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.118_2026-08-19-09-52-00_patch_b395655a-8d78-4344-9266-6901c20f6517 +0 -0
  171. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.119_2026-08-19-10-22-38_patch_8f95c49d-aedc-41b8-816d-ccb95f048831 +0 -0
  172. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.120_2026-08-19-10-26-58_patch_7fbf35e6-cc01-4b75-8c9a-f5d054bcaf93 +0 -0
  173. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.121_2026-08-19-10-42-02_patch_31a81b02-a886-4dea-84e0-67cc6ca412d5 +0 -0
  174. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.122_2026-08-19-11-16-49_patch_1c4d7307-48d4-493e-936d-80af799d644b +0 -0
  175. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.123_2026-08-19-11-47-32_patch_d3d78d04-9989-45b1-91b1-93b571d8814a +0 -0
  176. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.124_2026-08-20-08-03-17_patch_57f4c389-2d19-41ce-aca4-13b61c62f387 +0 -0
  177. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.125_2026-08-20-08-25-05_patch_7f368148-0d1c-4525-bbdf-c6d257ad861a +0 -0
  178. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.126_2026-08-20-14-51-36_patch_a99abcc8-3371-4c63-a759-bb7ea5b32432 +0 -0
  179. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.127_2026-08-21-05-48-58_patch_34b4ccee-7596-4f57-93e9-774973cca58e +0 -0
  180. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.128_2026-08-21-10-47-20_patch_693112b9-927c-4a8f-8553-b06eef86079d +0 -0
  181. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.129_2026-08-21-11-16-54_patch_7a981666-01d9-4d1b-9ba3-2129744e3bd5 +0 -0
  182. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.130_2026-08-21-13-09-36_patch_b7ad1a76-ce70-4d70-9d1a-7c414eba5bb4 +0 -0
  183. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.131_2026-08-21-14-31-10_patch_9128ef66-193e-4caf-8710-afd86128e638 +0 -0
  184. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.132_2026-08-24-08-59-34_patch_c600fc14-86a5-460f-9c4e-f0177056f756 +0 -0
  185. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.133_2026-08-24-10-28-29_patch_b6ce3e32-9d7b-48ac-981a-270c22c180dd +0 -0
  186. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.134_2026-08-24-11-00-51_patch_a4fc0484-4a64-46a2-94f8-aa805254c7b0 +0 -0
  187. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.135_2026-08-24-12-12-41_patch_a870a56f-9a65-49eb-92da-f572b26667d8 +0 -0
  188. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.136_2026-08-24-12-42-46_patch_9b399356-6482-4291-8da7-e748a99c4b53 +0 -0
  189. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.137_2026-08-24-12-53-57_patch_f7979348-1910-40cd-a535-90299eca84ee +0 -0
  190. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.138_2026-08-24-14-36-30_patch_ed0f8750-f663-498b-85e7-0d3f2213fcfe +0 -0
  191. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.139_2026-08-25-08-37-26_patch_3ba87e19-902b-4f76-b64c-90e5c0ca1fc6 +0 -0
  192. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.140_2026-08-25-09-52-45_patch_abc830f2-df15-4385-b797-cdaf72c10752 +0 -0
  193. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.141_2026-08-25-11-37-20_patch_1d9ec01e-06f6-4c8e-b095-af17d5b62b00 +0 -0
  194. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.142_2026-08-26-07-38-49_patch_3dd23e36-e7df-494c-986f-a412861a8d40 +0 -0
  195. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.143_2026-08-26-09-32-32_patch_7b7ebd34-de27-4b73-98a7-3e1501e16cd5 +0 -0
  196. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.144_2026-08-26-10-56-43_patch_166064f2-2208-4c9b-9e25-25dc4cd32084 +0 -0
  197. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.145_2026-08-26-11-37-29_patch_b997f3ee-d7d3-4408-9f2f-c8b6d08bdb3b +0 -0
  198. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.146_2026-08-26-12-15-20_patch_afbbb893-25db-468c-81db-2663ca373068 +0 -0
  199. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.147_2026-08-26-14-10-50_patch_fd753b1f-2fa1-4ddb-a9e7-de690da85254 +0 -0
  200. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.148_2026-08-27-09-08-35_patch_23814c0b-7f77-489c-b4a8-ceadd18146e3 +0 -0
  201. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.149_2026-08-27-09-40-17_patch_8879d72e-a3d8-4abc-a16a-d9dcf75f0fa1 +0 -0
  202. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.150_2026-08-27-10-57-25_patch_afbe60ed-3e23-4d88-be3c-f800d7002a7d +0 -0
  203. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.151_2026-08-28-09-02-46_patch_1d4ca23b-aeae-4ea8-96b1-8cf57371f29d +0 -0
  204. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.152_2026-08-28-15-37-24_patch_c9d0bdc1-a7e1-432b-92b9-92dc76fe0c78 +0 -0
  205. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.153_2026-08-29-09-03-27_patch_7531573a-1b33-4092-aa9c-0e65f47b201f +0 -0
  206. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.154_2026-08-29-11-56-35_patch_919f5787-39c8-4dc1-ae6a-f27c28380f21 +0 -0
  207. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.155_2026-08-29-15-15-59_patch_822f9ed8-c366-4e5f-9791-dee8467cf3ce +0 -0
  208. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.156_2026-08-29-16-19-01_patch_3ac2bf36-20f7-4c9f-9fdb-295d4466d59e +0 -0
  209. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.157_2026-08-30-17-32-17_patch_4302354c-c9c5-4be7-acd3-542872a748d8 +0 -0
  210. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.158_2026-08-31-09-28-33_patch_3523774f-c25d-4102-8c1a-92fff046a48d +0 -0
  211. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.159_2026-08-31-10-31-01_patch_fe3e6290-2553-4154-a0a0-8b8a418280ed +0 -0
  212. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.160_2026-08-31-11-23-39_patch_e701a085-3d23-4212-b0af-73b1d419a4c1 +0 -0
  213. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.161_2026-08-31-12-41-01_patch_074d7bde-c493-44db-bc15-e81fd91e2921 +0 -0
  214. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.162_2026-08-31-13-58-06_patch_84db1d60-4280-433b-bd3a-22e5611cd315 +0 -0
  215. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.163_2026-08-31-15-25-54_patch_1931c5ba-73df-48cb-8dcb-555ace0af267 +0 -0
  216. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.163_2026-08-31-15-44-37_patch_3962e805-2a92-494a-a87b-b6e6d66c40a0 +0 -0
  217. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.165_2026-08-31-19-48-59_patch_86e5b923-2b99-4b86-b542-469b197614be +0 -0
  218. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.166_2026-09-01-07-39-57_patch_c344892f-d542-4e7b-8f27-02365a411e15 +0 -0
  219. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.167_2026-09-01-08-21-53_patch_e199d419-282a-4dbb-8756-cf98b7037e2b +0 -0
  220. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.168_2026-09-01-09-12-31_patch_235c9fe0-da15-431d-bb56-01e2b9b15f4b +0 -0
  221. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.169_2026-09-01-11-54-19_patch_98b617ab-d130-42b5-93f2-19cae56d4c4c +0 -0
  222. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.170_2026-09-02-09-27-28_patch_e448d2e6-b7ec-4235-96bf-0173b3623c87 +0 -0
  223. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.171_2026-09-02-12-52-44_patch_e6a241c2-1d62-482c-a9eb-9e3373395c50 +0 -0
  224. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.172_2026-09-04-08-47-04_patch_daae079f-c104-4fcd-bb57-7bff68e80ad9 +0 -0
  225. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.173_2026-09-04-12-34-42_patch_399c4cbd-0c28-4dfd-a4ec-e569420a36e4 +0 -0
  226. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.174_2026-09-04-13-08-48_patch_f5cfe3d5-808e-45e4-bafc-00d0554838ee +0 -0
  227. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.175_2026-09-04-17-20-46_patch_1ef542fa-5d8e-4d90-aa15-9fc4cea3dfec +0 -0
  228. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.176_2026-09-05-08-25-05_patch_ced5521f-f9da-4640-a921-95fcb5cd2e6d +0 -0
  229. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.177_2026-09-05-09-00-16_patch_803c1ad4-a9af-4953-92c5-d882dec03ea2 +0 -0
  230. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.178_2026-09-05-09-30-34_patch_012f6259-2e3f-4591-9806-1920fd06cb1f +0 -0
  231. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.179_2026-09-05-09-33-43_patch_f4bdf28c-d584-47a5-b699-8c883330162c +0 -0
  232. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.180_2026-09-05-12-02-21_patch_34a14b01-d22d-44a8-ac63-be0370a61422 +0 -0
  233. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.181_2026-09-05-12-47-46_patch_56b18867-99f6-4d5c-8215-7b9d60d34010 +0 -0
  234. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.182_2026-09-05-13-35-18_patch_61b7d4d1-73c8-4603-9b0c-593e7405587f +0 -0
  235. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.183_2026-09-06-07-27-09_patch_d76331b2-e3a3-4c0b-8412-ecd131b6ac02 +0 -0
  236. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.184_2026-09-06-10-21-47_patch_7680b7a1-49f0-4eef-b12e-4c854407448c +0 -0
  237. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.185_2026-09-06-10-30-40_patch_e56c2183-77f8-44ef-a92e-7377ea6ce8c1 +0 -0
  238. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.186_2026-09-07-10-00-51_patch_67de5683-d208-4bc0-8fb6-7677377908e7 +0 -0
  239. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.187_2026-09-07-10-18-13_patch_2086cee2-276b-48f7-80ce-6a17397b9541 +0 -0
  240. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.188_2026-09-07-12-51-28_patch_d6590822-068f-4a19-814d-34bbf204ba6e +0 -0
  241. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.189_2026-09-07-12-55-23_patch_7e0fb04b-4d40-4490-974f-c74ba2ae55a1 +0 -0
  242. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.190_2026-09-08-08-58-03_patch_15e3ac1e-4475-4272-bdd8-d00bb0db8f17 +0 -0
  243. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.191_2026-09-08-09-55-58_patch_3d350e50-ee53-4282-bc75-d2251142c46e +0 -0
  244. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.192_2026-09-08-11-12-21_patch_0733223b-1ae2-4b5b-897f-dfc57574ff83 +0 -0
  245. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.193_2026-09-08-21-48-17_patch_8d07d4e6-3555-4720-85c9-9452570fae2d +0 -0
  246. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.194_2026-09-09-07-53-43_patch_69559429-aa42-4b62-9bd7-cdfded1c00d0 +0 -0
  247. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.195_2026-09-09-09-55-40_patch_bbf67f1d-3b9a-43a2-b1bc-22df3fed8a34 +0 -0
  248. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.196_2026-09-09-09-59-47_patch_70d76812-7b3c-4192-ad49-fcaccc29b0da +0 -0
  249. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.197_2026-09-09-13-06-06_patch_d455be0b-5421-492a-b952-fab0fd8110f8 +0 -0
  250. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.198_2026-09-09-13-14-34_patch_267f54e5-311e-435e-882f-8e19191325ea +0 -0
  251. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.199_2026-09-09-22-24-18_patch_81e3e453-ca0e-42fa-9c21-8f94d43c05f2 +0 -0
  252. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.200_2026-09-10-07-19-50_patch_911714fa-1fa3-4165-bfe6-d10c650bf5bf +0 -0
  253. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.201_2026-09-10-10-14-19_patch_864015f2-b0b0-4563-a1c8-155629cb9126 +0 -0
  254. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.202_2026-09-10-11-00-05_patch_18270ecf-e770-4e69-8bcf-e5143c39929b +0 -0
  255. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.203_2026-09-10-11-10-41_patch_ff273ab1-44f3-4bc0-b184-3396e943df04 +0 -0
  256. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.204_2026-09-10-13-02-02_patch_d4ee41e2-d13c-4941-8605-3f1a42b56b22 +0 -0
  257. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.205_2026-09-10-13-57-50_patch_284df67e-5957-4b0c-bc64-5581db6ddecc +0 -0
  258. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.206_2026-09-11-10-18-50_patch_1ac7e410-0e62-4eef-bbe4-ebf93c9d0869 +0 -0
  259. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/17.0.207_2026-09-11-15-26-02_major_3f1b3ed7-eaac-41f5-b740-0af3331595d9 +0 -0
  260. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/__init__.py +0 -0
  261. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli/version/read_version.py +0 -0
  262. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli.egg-info/dependency_links.txt +0 -0
  263. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli.egg-info/entry_points.txt +0 -0
  264. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli.egg-info/not-zip-safe +0 -0
  265. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli.egg-info/requires.txt +0 -0
  266. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/ellf_cli.egg-info/top_level.txt +0 -0
  267. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/pyproject.toml +0 -0
  268. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/setup.cfg +0 -0
  269. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/setup.py +0 -0
  270. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_appdirs.py +0 -0
  271. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_auth.py +0 -0
  272. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_config.py +0 -0
  273. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_errors.py +0 -0
  274. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_files_cp.py +0 -0
  275. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_files_cp_helpers.py +0 -0
  276. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_helm.py +0 -0
  277. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_import_export.py +0 -0
  278. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_info.py +0 -0
  279. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_infra_config_io.py +0 -0
  280. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_infra_configure.py +0 -0
  281. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_infra_deploy_node_labels.py +0 -0
  282. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_infra_get_terraform.py +0 -0
  283. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_infra_init.py +0 -0
  284. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_infra_provision.py +0 -0
  285. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_infra_start_fixes.py +0 -0
  286. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_infra_start_validation.py +0 -0
  287. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_infra_state_bucket.py +0 -0
  288. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_infra_terraform_init.py +0 -0
  289. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_invalid_secrets.py +0 -0
  290. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_job_list_project_filter.py +0 -0
  291. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_jobs_list_unmatched.py +0 -0
  292. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_key_pair.py +0 -0
  293. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_login.py +0 -0
  294. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_logout.py +0 -0
  295. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_main.py +0 -0
  296. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_org_select.py +0 -0
  297. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_plans.py +0 -0
  298. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_projects.py +0 -0
  299. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_publish_build_poll.py +0 -0
  300. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_publish_data.py +0 -0
  301. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_publish_requirements.py +0 -0
  302. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_pypi_auth.py +0 -0
  303. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_query.py +0 -0
  304. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_recipe_file.py +0 -0
  305. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_recipes.py +0 -0
  306. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_state.py +0 -0
  307. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_support.py +0 -0
  308. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_todos.py +0 -0
  309. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_ty.py +0 -0
  310. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_ui.py +0 -0
  311. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_ui_extras.py +0 -0
  312. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_usage_counts.py +0 -0
  313. {ellf_cli-18.0.0 → ellf_cli-18.0.2}/tests/test_users_assign.py +0 -0
  314. {ellf_cli-18.0.0 → ellf_cli-18.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: 18.0.0
3
+ Version: 18.0.2
4
4
  Summary: Ellf Command Line Interface
5
5
  Home-page: https://prodi.gy
6
6
  Author: ExplosionAI GmbH
@@ -6,12 +6,14 @@ import json
6
6
  import os
7
7
  import subprocess
8
8
  import tarfile
9
+ import tempfile
9
10
  import time
10
11
  import zipfile
12
+ from contextlib import contextmanager
11
13
  from dataclasses import dataclass
12
14
  from importlib.metadata import PackageNotFoundError, distribution
13
15
  from pathlib import Path
14
- from typing import Optional, Union
16
+ from typing import Iterator, Optional, Union
15
17
  from uuid import UUID
16
18
 
17
19
  import httpx
@@ -44,7 +46,7 @@ class DistPackage:
44
46
 
45
47
  def __init__(self, path: Path) -> None:
46
48
  if path.suffix == ".whl":
47
- name, version, _, _2 = parse_wheel_filename(path.name)
49
+ name, version, _, _ = parse_wheel_filename(path.name)
48
50
  else:
49
51
  name, version = parse_sdist_filename(path.name)
50
52
 
@@ -93,7 +95,7 @@ class ModulePackage:
93
95
  def __init__(self, name: str, version_arg: str | None = None) -> None:
94
96
  self.name = name
95
97
  if version_arg is None:
96
- utc_now = datetime.datetime.utcnow()
98
+ utc_now = datetime.datetime.now(datetime.timezone.utc)
97
99
  self.version = f"{utc_now.year}.{utc_now.month}.{utc_now.day}-{utc_now.second + 60 * utc_now.minute + 60 * 60 * utc_now.hour}"
98
100
  else:
99
101
  self.version = version_arg
@@ -127,7 +129,7 @@ class FilesPackage:
127
129
  self.path = path
128
130
 
129
131
  if version_arg is None:
130
- utc_now = datetime.datetime.utcnow()
132
+ utc_now = datetime.datetime.now(datetime.timezone.utc)
131
133
  self.version = f"{utc_now.year}.{utc_now.month}.{utc_now.day}-{utc_now.second + 60 * utc_now.minute + 60 * 60 * utc_now.hour}"
132
134
  else:
133
135
  self.version = version_arg
@@ -169,14 +171,62 @@ class FilesPackage:
169
171
  return output
170
172
 
171
173
 
174
+ def _unpack_stripped(tar_data: bytes, root: Path) -> None:
175
+ """Unpack a tar into *root* with its top-level directory removed.
176
+
177
+ This is the same re-rooting the broker applies when it lays the
178
+ package into the image, so what create-meta imports locally is what
179
+ the cluster will import at runtime.
180
+ """
181
+ with tarfile.open(fileobj=io.BytesIO(tar_data), mode="r:*") as tar:
182
+ for member in tar.getmembers():
183
+ parts = member.name.split("/", 1)
184
+ inner = parts[1] if len(parts) > 1 else parts[0]
185
+ if not inner or inner.startswith("/") or ".." in Path(inner).parts:
186
+ continue
187
+ dest = root / inner
188
+ if member.isdir():
189
+ dest.mkdir(parents=True, exist_ok=True)
190
+ elif member.isfile():
191
+ dest.parent.mkdir(parents=True, exist_ok=True)
192
+ fileobj = tar.extractfile(member)
193
+ assert fileobj is not None
194
+ dest.write_bytes(fileobj.read())
195
+
196
+
197
+ @contextmanager
198
+ def _import_root(
199
+ package: Union[DistPackage, ModulePackage, FilesPackage],
200
+ source_dir: Path | None,
201
+ contents: bytes,
202
+ ) -> Iterator[Path | None]:
203
+ """Directory to prepend to PYTHONPATH so create-meta can import the package.
204
+
205
+ The broker never installs the package: it strips the sdist's top-level
206
+ directory and puts the unpacked root on PYTHONPATH. Mirror that here so
207
+ publishing doesn't require the package to be installed locally.
208
+ """
209
+ if isinstance(package, ModulePackage):
210
+ yield None
211
+ elif isinstance(package, FilesPackage):
212
+ yield package.path.resolve().parent
213
+ elif source_dir is not None:
214
+ yield source_dir.resolve()
215
+ else:
216
+ with tempfile.TemporaryDirectory(prefix="ellf-publish-") as tmp:
217
+ root = Path(tmp)
218
+ _unpack_stripped(contents, root)
219
+ yield root
220
+
221
+
172
222
  def _run_create_meta(
173
223
  package_name: str, *, extra_python_path: Path | None = None
174
224
  ) -> str:
175
225
  """Run create-meta locally to produce recipe metadata JSON.
176
226
 
177
227
  If *extra_python_path* is given it is prepended to ``PYTHONPATH`` so
178
- that ``create-meta`` can import loose ``.py`` files that aren't
179
- installed as packages.
228
+ that ``create-meta`` can import the package without it being
229
+ installed.
180
230
  """
181
231
  env = None
182
232
  if extra_python_path is not None:
@@ -200,9 +250,16 @@ def _run_create_meta(
200
250
  env=env,
201
251
  )
202
252
  if result.returncode != 0:
203
- raise CLIError(
204
- f"create-meta failed (exit {result.returncode}):\n{result.stderr}"
205
- )
253
+ message = f"create-meta failed (exit {result.returncode}):\n{result.stderr}"
254
+ if "RecipePackageNotFound" in result.stderr:
255
+ where = f" from {extra_python_path}" if extra_python_path else ""
256
+ message += (
257
+ f"\nCould not import '{package_name}'{where}. The package is "
258
+ "imported by name rather than installed, so the source must "
259
+ f"contain a '{package_name}' package (a directory with "
260
+ f"__init__.py) or a '{package_name}.py' module at its top level."
261
+ )
262
+ raise CLIError(message)
206
263
  return result.stdout.strip()
207
264
 
208
265
 
@@ -425,10 +482,12 @@ def publish_code(
425
482
  if auth.cluster_id is None:
426
483
  raise CLIError(Messages.E036)
427
484
 
485
+ source_dir: Path | None = None
428
486
  if is_path:
429
487
  path = Path(name_or_path)
430
- if path.is_dir() and (path / "setup.py").exists():
488
+ if path.is_dir() and _is_package_dir(path):
431
489
  msg.info(f"Building sdist from {name_or_path}")
490
+ source_dir = path
432
491
  package = DistPackage(_make_sdist_if_dir(path))
433
492
  elif not path.is_file():
434
493
  msg.info(f"Interpreting {name_or_path} as directory of code")
@@ -447,15 +506,13 @@ def publish_code(
447
506
  if package_version is None:
448
507
  msg.info(f"No version specified. Defaulting to {package.version}")
449
508
 
450
- # Generate recipe metadata locally
451
- # For FilesPackage we need to tell the subprocess where to find the source
452
- # so that ``create-meta`` can actually import the module.
453
- extra_python_path: Path | None = None
454
- if isinstance(package, FilesPackage):
455
- src = package.path.resolve()
456
- extra_python_path = src.parent if src.is_file() else src.parent
457
- with loading("Generating recipe metadata"):
458
- meta_json = _run_create_meta(package.name, extra_python_path=extra_python_path)
509
+ # Generate recipe metadata locally, importing the package from its
510
+ # source rather than requiring it to be installed.
511
+ with _import_root(package, source_dir, contents) as extra_python_path:
512
+ with loading("Generating recipe metadata"):
513
+ meta_json = _run_create_meta(
514
+ package.name, extra_python_path=extra_python_path
515
+ )
459
516
 
460
517
  meta_list = json.loads(meta_json)
461
518
  if len(meta_list) == 0:
@@ -524,16 +581,39 @@ def _is_path(name_or_path: str) -> bool:
524
581
  return path.exists()
525
582
 
526
583
 
584
+ def _is_package_dir(path: Path) -> bool:
585
+ return (path / "setup.py").exists() or (path / "pyproject.toml").exists()
586
+
587
+
527
588
  def _make_sdist_if_dir(path: Path) -> Path:
528
589
  if not path.is_dir():
529
590
  return path
530
591
  env = dict(os.environ)
531
592
  env["SKIP_CYTHON"] = "1"
532
- r = subprocess.run(["python", "setup.py", "sdist"], cwd=path, text=True, env=env)
533
- r.check_returncode()
534
- dists = list((path / "dist").iterdir())
593
+ if (path / "setup.py").exists():
594
+ cmd = ["python", "setup.py", "sdist"]
595
+ else:
596
+ # pyproject.toml-only projects have no setup.py to run; `build`
597
+ # is the standard front-end but isn't a CLI dependency.
598
+ cmd = ["python", "-m", "build", "--sdist"]
599
+ probe = subprocess.run(
600
+ ["python", "-c", "import build"], capture_output=True, text=True
601
+ )
602
+ if probe.returncode != 0:
603
+ raise CLIError(
604
+ f"{path} has a pyproject.toml but no setup.py, so building "
605
+ "its sdist needs the 'build' package. Install it with "
606
+ "`pip install build` and re-run the publish command."
607
+ )
608
+ r = subprocess.run(cmd, cwd=path, text=True, env=env)
609
+ if r.returncode != 0:
610
+ raise CLIError(f"Building the sdist in {path} failed (exit {r.returncode})")
611
+ dist_dir = path / "dist"
612
+ if not dist_dir.is_dir():
613
+ raise CLIError(f"sdist not created after building in {path}")
614
+ dists = [p for p in dist_dir.iterdir() if p.is_file()]
535
615
  if len(dists) == 0:
536
- raise ValueError("sdist not created after subprocess in {path / 'dist'}")
616
+ raise CLIError(f"sdist not created after building in {dist_dir}")
537
617
  # Return last modified file
538
618
  return max(dists, key=lambda p: p.stat().st_mtime)
539
619
 
@@ -646,6 +726,6 @@ def _read_record(path: Path) -> list[str]:
646
726
  output = []
647
727
  with path.open("r", encoding="utf8") as file_:
648
728
  for line in file_.read().strip().split("\n"):
649
- subpath, sha, size = line.split(",")
729
+ subpath, _, _ = line.split(",")
650
730
  output.append(subpath)
651
731
  return output
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "prog": "ellf",
3
3
  "help": "Ellf Command Line Interface.",
4
- "version": "17.0.206",
4
+ "version": "18.0.1",
5
5
  "extra_key": "_extra",
6
6
  "commands": {
7
7
  "actions": {
@@ -0,0 +1,3 @@
1
+ 18.0.0
2
+ patch
3
+ 8995783a-a9fa-4c4e-90b3-6386a4c481eb
@@ -0,0 +1,3 @@
1
+ 18.0.1
2
+ patch
3
+ f6ea2c99-a715-4c4d-876a-23ed8c62a83d
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ellf-cli
3
- Version: 18.0.0
3
+ Version: 18.0.2
4
4
  Summary: Ellf Command Line Interface
5
5
  Home-page: https://prodi.gy
6
6
  Author: ExplosionAI GmbH
@@ -261,6 +261,8 @@ ellf_cli/version/17.0.204_2026-09-10-13-02-02_patch_d4ee41e2-d13c-4941-8605-3f1a
261
261
  ellf_cli/version/17.0.205_2026-09-10-13-57-50_patch_284df67e-5957-4b0c-bc64-5581db6ddecc
262
262
  ellf_cli/version/17.0.206_2026-09-11-10-18-50_patch_1ac7e410-0e62-4eef-bbe4-ebf93c9d0869
263
263
  ellf_cli/version/17.0.207_2026-09-11-15-26-02_major_3f1b3ed7-eaac-41f5-b740-0af3331595d9
264
+ ellf_cli/version/18.0.0_2026-09-12-10-01-10_patch_8995783a-a9fa-4c4e-90b3-6386a4c481eb
265
+ ellf_cli/version/18.0.1_2026-09-12-17-33-30_patch_f6ea2c99-a715-4c4d-876a-23ed8c62a83d
264
266
  ellf_cli/version/__init__.py
265
267
  ellf_cli/version/read_version.py
266
268
  tests/test_appdirs.py
@@ -294,6 +296,7 @@ tests/test_plans.py
294
296
  tests/test_projects.py
295
297
  tests/test_publish_build_poll.py
296
298
  tests/test_publish_data.py
299
+ tests/test_publish_import_root.py
297
300
  tests/test_publish_requirements.py
298
301
  tests/test_pypi_auth.py
299
302
  tests/test_query.py
@@ -0,0 +1,120 @@
1
+ """Tests for how `publish code` makes uninstalled packages importable.
2
+
3
+ The broker never installs a published package: it strips the sdist's
4
+ top-level directory and puts the unpacked root on PYTHONPATH. Local
5
+ metadata generation must mirror that, or publishing silently requires
6
+ the package to be installed in the developer's environment.
7
+ """
8
+
9
+ import io
10
+ import subprocess
11
+ import tarfile
12
+ import zipfile
13
+ from pathlib import Path
14
+
15
+ import pytest
16
+
17
+ from ellf_cli.commands.publish_code import (
18
+ DistPackage,
19
+ FilesPackage,
20
+ ModulePackage,
21
+ _import_root,
22
+ _is_package_dir,
23
+ _run_create_meta,
24
+ )
25
+ from ellf_cli.errors import CLIError
26
+
27
+
28
+ def _make_sdist(tmp_path, name="my_pkg-1.0.0"):
29
+ sdist = tmp_path / f"{name}.tar.gz"
30
+ with tarfile.open(sdist, "w:gz") as tar:
31
+ for inner, text in [
32
+ ("PKG-INFO", "Name: my-pkg\nVersion: 1.0.0\n"),
33
+ ("my_pkg/__init__.py", "def recipe(): pass\n"),
34
+ ("../escape.py", "evil = True\n"),
35
+ ]:
36
+ data = text.encode("utf8")
37
+ info = tarfile.TarInfo(name=f"{name}/{inner}")
38
+ info.size = len(data)
39
+ tar.addfile(info, io.BytesIO(data))
40
+ return sdist
41
+
42
+
43
+ def _make_wheel(tmp_path, name="my_pkg-1.0.0"):
44
+ wheel = tmp_path / f"{name}-py3-none-any.whl"
45
+ with zipfile.ZipFile(wheel, "w") as zf:
46
+ zf.writestr("my_pkg/__init__.py", "def recipe(): pass\n")
47
+ zf.writestr(f"{name}.dist-info/METADATA", "Name: my-pkg\nVersion: 1.0.0\n")
48
+ return wheel
49
+
50
+
51
+ def test_setup_py_dir_is_its_own_import_root(tmp_path):
52
+ src = tmp_path / "my_pkg"
53
+ (src / "my_pkg").mkdir(parents=True)
54
+ (src / "setup.py").write_text("", encoding="utf8")
55
+ package = DistPackage(_make_sdist(tmp_path))
56
+ with _import_root(package, src, package.get_bytes()) as root:
57
+ assert root == src.resolve()
58
+
59
+
60
+ def test_files_dir_import_root_is_parent(tmp_path):
61
+ src = tmp_path / "my_recipes"
62
+ src.mkdir()
63
+ package = FilesPackage(path=src, name="my_recipes")
64
+ with _import_root(package, None, b"") as root:
65
+ assert root == tmp_path.resolve()
66
+
67
+
68
+ def test_module_package_has_no_import_root():
69
+ with _import_root(ModulePackage("my_pkg", "1.0.0"), None, b"") as root:
70
+ assert root is None
71
+
72
+
73
+ def test_prebuilt_sdist_is_unpacked_with_top_dir_stripped(tmp_path):
74
+ package = DistPackage(_make_sdist(tmp_path))
75
+ with _import_root(package, None, package.get_bytes()) as root:
76
+ assert root is not None
77
+ assert (root / "my_pkg" / "__init__.py").is_file()
78
+ assert not (root / "my_pkg-1.0.0").exists()
79
+ assert not (root.parent / "escape.py").exists()
80
+ assert not root.exists()
81
+
82
+
83
+ def test_prebuilt_wheel_is_unpacked_with_top_dir_stripped(tmp_path):
84
+ package = DistPackage(_make_wheel(tmp_path))
85
+ with _import_root(package, None, package.get_bytes()) as root:
86
+ assert root is not None
87
+ assert (root / "my_pkg" / "__init__.py").is_file()
88
+
89
+
90
+ def test_is_package_dir_accepts_pyproject_only(tmp_path):
91
+ assert not _is_package_dir(tmp_path)
92
+ (tmp_path / "pyproject.toml").write_text("", encoding="utf8")
93
+ assert _is_package_dir(tmp_path)
94
+
95
+
96
+ def test_create_meta_prepends_import_root_to_pythonpath(monkeypatch, tmp_path):
97
+ seen = {}
98
+
99
+ def fake_run(cmd, **kwargs):
100
+ seen["env"] = kwargs["env"]
101
+ return subprocess.CompletedProcess(cmd, 0, stdout="[]", stderr="")
102
+
103
+ monkeypatch.setenv("PYTHONPATH", "/existing")
104
+ monkeypatch.setattr(subprocess, "run", fake_run)
105
+ assert _run_create_meta("my_pkg", extra_python_path=tmp_path) == "[]"
106
+ assert seen["env"]["PYTHONPATH"].split(":") == [str(tmp_path), "/existing"]
107
+
108
+
109
+ def test_create_meta_explains_unimportable_package(monkeypatch, tmp_path):
110
+ def fake_run(cmd, **_):
111
+ return subprocess.CompletedProcess(
112
+ cmd, 1, stdout="", stderr="...RecipePackageNotFound: my_pkg"
113
+ )
114
+
115
+ monkeypatch.setattr(subprocess, "run", fake_run)
116
+ with pytest.raises(CLIError) as excinfo:
117
+ _run_create_meta("my_pkg", extra_python_path=Path(tmp_path))
118
+ text = str(excinfo.value)
119
+ assert "Could not import 'my_pkg'" in text
120
+ assert str(tmp_path) in text
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes