ellf-cli 4.0.26__tar.gz → 4.0.28__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 (179) hide show
  1. {ellf_cli-4.0.26/ellf_cli.egg-info → ellf_cli-4.0.28}/PKG-INFO +1 -1
  2. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/about.json +1 -1
  3. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/auth.py +17 -2
  4. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/infra/register.py +39 -8
  5. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf.json +1 -1
  6. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/url.py +26 -7
  7. {ellf_cli-4.0.26 → ellf_cli-4.0.28/ellf_cli.egg-info}/PKG-INFO +1 -1
  8. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/LICENSE +0 -0
  9. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/MANIFEST.in +0 -0
  10. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/README.md +0 -0
  11. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/__init__.py +0 -0
  12. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/__main__.py +0 -0
  13. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/about.py +0 -0
  14. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/appdirs.py +0 -0
  15. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/cli.py +0 -0
  16. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/cloud/__init__.py +0 -0
  17. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/cloud/gcp.py +0 -0
  18. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/cluster_config.py +0 -0
  19. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/__init__.py +0 -0
  20. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/_recipe_file.py +0 -0
  21. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/_recipe_subcommand.py +0 -0
  22. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/_state.py +0 -0
  23. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/actions.py +0 -0
  24. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/agents.py +0 -0
  25. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/assets.py +0 -0
  26. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/clusters.py +0 -0
  27. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/config.py +0 -0
  28. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/datasets.py +0 -0
  29. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/files/__init__.py +0 -0
  30. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/files/cp.py +0 -0
  31. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/files/ls.py +0 -0
  32. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/files/rm.py +0 -0
  33. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/files/rsync.py +0 -0
  34. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/files/stats.py +0 -0
  35. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/general.py +0 -0
  36. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/import_export.py +0 -0
  37. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/infra/__init__.py +0 -0
  38. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/infra/_helpers.py +0 -0
  39. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/infra/deploy.py +0 -0
  40. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/infra/init_values.py +0 -0
  41. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/infra/provision.py +0 -0
  42. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/infra/setup.py +0 -0
  43. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/infra/start.py +0 -0
  44. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/infra/terraform.py +0 -0
  45. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/infra/tls.py +0 -0
  46. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/jobs.py +0 -0
  47. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/packages.py +0 -0
  48. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/paths.py +0 -0
  49. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/plans.py +0 -0
  50. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/projects.py +0 -0
  51. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/publish_code.py +0 -0
  52. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/publish_data.py +0 -0
  53. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/recipes.py +0 -0
  54. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/secrets.py +0 -0
  55. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/support.py +0 -0
  56. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/tasks.py +0 -0
  57. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/commands/todos.py +0 -0
  58. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/config.py +0 -0
  59. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/.claude-plugin/plugin.json +0 -0
  60. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/.gitignore +0 -0
  61. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/bin/write-current-session.py +0 -0
  62. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/hooks/hooks.json +0 -0
  63. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skill_variants.json +0 -0
  64. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-annotate.assistant/SKILL.md +0 -0
  65. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-annotate.assistant/references/annotation_audit.md +0 -0
  66. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-annotate.assistant/references/builtin_ellf_annotation_recipes.md +0 -0
  67. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-annotate.coding/SKILL.md +0 -0
  68. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-annotate.coding/references/annotation_audit.md +0 -0
  69. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-annotate.coding/references/builtin_ellf_annotation_recipes.md +0 -0
  70. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-annotate.coding/references/builtin_prodigy_recipes.md +0 -0
  71. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-ask/SKILL.md +0 -0
  72. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-handoff/SKILL.md +0 -0
  73. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-monitor.assistant/SKILL.md +0 -0
  74. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-monitor.assistant/references/annotation_metrics.md +0 -0
  75. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-monitor.assistant/references/training_monitoring.md +0 -0
  76. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-monitor.coding/SKILL.md +0 -0
  77. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-monitor.coding/references/annotation_metrics.md +0 -0
  78. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-monitor.coding/references/training_monitoring.md +0 -0
  79. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-monitor.coding/scripts/check_training.py +0 -0
  80. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-ops.assistant/SKILL.md +0 -0
  81. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-ops.coding/SKILL.md +0 -0
  82. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-ops.coding/scripts/run_job.py +0 -0
  83. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-patterns/SKILL.md +0 -0
  84. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-patterns/references/pattern_strategies.md +0 -0
  85. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-prodigy/SKILL.md +0 -0
  86. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_action_recipe.py +0 -0
  87. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_agent_recipe.py +0 -0
  88. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_blocks_ui.py +0 -0
  89. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_correct.py +0 -0
  90. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_custom_ui.py +0 -0
  91. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_manual.py +0 -0
  92. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_pages_ui.py +0 -0
  93. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_routing.py +0 -0
  94. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_task_recipe.py +0 -0
  95. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_teach.py +0 -0
  96. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/builtin_recipes.md +0 -0
  97. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/ellf_recipe_sdk.md +0 -0
  98. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/lint_recipe.py +0 -0
  99. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/prodigy_recipe_api.md +0 -0
  100. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/template_index.md +0 -0
  101. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-project.assistant/SKILL.md +0 -0
  102. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-project.assistant/references/consulting_patterns.md +0 -0
  103. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-project.assistant/references/explosion_strategy.md +0 -0
  104. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-project.assistant/references/prodigy_llm_bot.md +0 -0
  105. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-project.coding/SKILL.md +0 -0
  106. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-project.coding/references/consulting_patterns.md +0 -0
  107. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-project.coding/references/explosion_strategy.md +0 -0
  108. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-project.coding/references/prodigy_llm_bot.md +0 -0
  109. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-support.assistant/SKILL.md +0 -0
  110. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-support.coding/SKILL.md +0 -0
  111. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-todo/SKILL.md +0 -0
  112. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-train.assistant/SKILL.md +0 -0
  113. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-train.assistant/references/diagnostics.md +0 -0
  114. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-train.assistant/references/evaluation_guide.md +0 -0
  115. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-train.assistant/references/model_selection.md +0 -0
  116. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-train.assistant/references/training_paradigms.md +0 -0
  117. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-train.assistant/references/workflow.md +0 -0
  118. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-train.coding/SKILL.md +0 -0
  119. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/config_advanced.md +0 -0
  120. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/config_architectures.md +0 -0
  121. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/config_training.md +0 -0
  122. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/diagnostics.md +0 -0
  123. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/evaluation_guide.md +0 -0
  124. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/experiment_patterns.md +0 -0
  125. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/model_selection.md +0 -0
  126. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/training_paradigms.md +0 -0
  127. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/training_troubleshooting.md +0 -0
  128. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/workflow.md +0 -0
  129. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ellf_skills/skills/ellf-train.coding/scripts/ellf_logger.py +0 -0
  130. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/errors.py +0 -0
  131. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/helm.py +0 -0
  132. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/key_pair.py +0 -0
  133. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/main.py +0 -0
  134. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/messages.py +0 -0
  135. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/query.py +0 -0
  136. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/recipes_cookiecutter/cookiecutter.json +0 -0
  137. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/.gitignore +0 -0
  138. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/README.md.tmpl +0 -0
  139. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/requirements-dev.in +0 -0
  140. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/requirements.in +0 -0
  141. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/setup.py.tmpl +0 -0
  142. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/{{cookiecutter.package_name}}/__init__.py +0 -0
  143. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/{{cookiecutter.package_name}}/about.py +0 -0
  144. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/{{cookiecutter.package_name}}/recipes/__init__.py +0 -0
  145. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/{{cookiecutter.package_name}}/recipes/example_task.py +0 -0
  146. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/testing/__init__.py +0 -0
  147. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ty.py +0 -0
  148. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/ui.py +0 -0
  149. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli/util.py +0 -0
  150. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli.egg-info/SOURCES.txt +0 -0
  151. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli.egg-info/dependency_links.txt +0 -0
  152. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli.egg-info/entry_points.txt +0 -0
  153. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli.egg-info/not-zip-safe +0 -0
  154. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli.egg-info/requires.txt +0 -0
  155. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/ellf_cli.egg-info/top_level.txt +0 -0
  156. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/pyproject.toml +0 -0
  157. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/setup.cfg +0 -0
  158. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/setup.py +0 -0
  159. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/tests/test_appdirs.py +0 -0
  160. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/tests/test_auth.py +0 -0
  161. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/tests/test_config.py +0 -0
  162. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/tests/test_errors.py +0 -0
  163. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/tests/test_files_cp.py +0 -0
  164. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/tests/test_files_cp_helpers.py +0 -0
  165. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/tests/test_info.py +0 -0
  166. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/tests/test_invalid_secrets.py +0 -0
  167. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/tests/test_key_pair.py +0 -0
  168. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/tests/test_login.py +0 -0
  169. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/tests/test_main.py +0 -0
  170. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/tests/test_projects.py +0 -0
  171. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/tests/test_query.py +0 -0
  172. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/tests/test_recipe_file.py +0 -0
  173. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/tests/test_recipes.py +0 -0
  174. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/tests/test_state.py +0 -0
  175. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/tests/test_support.py +0 -0
  176. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/tests/test_ty.py +0 -0
  177. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/tests/test_ui.py +0 -0
  178. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/tests/test_ui_extras.py +0 -0
  179. {ellf_cli-4.0.26 → ellf_cli-4.0.28}/tests/test_util.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ellf-cli
3
- Version: 4.0.26
3
+ Version: 4.0.28
4
4
  Summary: Ellf Command Line Interface
5
5
  Home-page: https://prodi.gy
6
6
  Author: ExplosionAI GmbH
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "title": "Ellf CLI",
3
3
  "name": "ellf-cli",
4
- "version": "4.0.26",
4
+ "version": "4.0.28",
5
5
  "summary": "Ellf Command Line Interface",
6
6
  "uri": "https://prodi.gy",
7
7
  "prog": "ellf",
@@ -193,7 +193,10 @@ class AuthStateImpl:
193
193
  self._secrets = None
194
194
  self._broker_url = URL.parse(broker_host) if broker_host is not None else None
195
195
  self._pam_url = URL.parse(pam_host)
196
- self._broker_id = None
196
+ # Seed from saved-defaults so we don't make an unnecessary (and brittle)
197
+ # PAM lookup-by-address every time the user runs an ellf command.
198
+ # `auth.broker_id` falls back to the address lookup only if this is None.
199
+ self._broker_id = settings.broker_id
197
200
  self._org_id = None
198
201
  self._secrets_path = ctx.secrets_path
199
202
  self._saved_settings_path = ctx.saved_settings_path
@@ -407,10 +410,22 @@ class AuthStateImpl:
407
410
  ):
408
411
  self._broker_client = None
409
412
  api_token = self.get_api_token().access_token
413
+ # Prefer looking up the broker by id when we have it. Address
414
+ # lookup is brittle: the registered broker.address (e.g.
415
+ # 'cluster.example.com' or 'localhost') often doesn't textually
416
+ # match broker_host (e.g. 'https://localhost:8443'), and even
417
+ # canonicalized forms differ when the user includes a port to
418
+ # reach the cluster via tunnel that the broker.address doesn't
419
+ # carry. broker_id is unambiguous.
420
+ body: dict[str, str] = {}
421
+ if self._broker_id is not None:
422
+ body["id"] = str(self._broker_id)
423
+ else:
424
+ body["address"] = str(URL.parse(broker_host))
410
425
  res = httpx.post(
411
426
  str(self.pam_url / "api/v1/broker/token"),
412
427
  headers={"authorization": f"Bearer {api_token}"},
413
- json={"address": str(URL.parse(broker_host))},
428
+ json=body,
414
429
  )
415
430
  if res.status_code != 200:
416
431
  err = _format_http_error(res)
@@ -7,7 +7,6 @@ import srsly
7
7
  from radicli import Arg
8
8
  from wasabi import msg
9
9
 
10
- from ellf_pam_sdk.errors import BrokerNotFound
11
10
  from ellf_pam_sdk.models import BrokerCreating, BrokerUpdating
12
11
 
13
12
  from ...cli import cli
@@ -36,7 +35,7 @@ def register(
36
35
  as_json: bool = False,
37
36
  ) -> None:
38
37
  """Register a new cluster with PAM and write credentials to cluster-creds.json."""
39
- from .._state import get_auth_state
38
+ from .._state import get_auth_state, get_root_cfg, get_saved_settings
40
39
 
41
40
  if cloud_provider not in CLOUD_PROVIDERS:
42
41
  msg.fail(
@@ -47,9 +46,23 @@ def register(
47
46
  auth = get_auth_state()
48
47
  client = auth.client
49
48
  org_id = auth.org_id
50
- try:
51
- broker = client.broker.read(address=domain)
52
- except BrokerNotFound:
49
+ # Idempotent on (org_id, name): list and filter client-side rather than
50
+ # `broker.read(name=...)`, which has historically returned the wrong record
51
+ # when the name doesn't disambiguate (no LIMIT 1 / ORDER BY guarantees in
52
+ # the PAM-side query). Address-based lookup also doesn't work as a
53
+ # disambiguator because two clusters with the same human-readable domain
54
+ # are valid (e.g. two `localhost`-served dev clusters in the same org).
55
+ # page_size is capped at 100 server-side; iterate pages so this still
56
+ # works in larger orgs.
57
+ existing = next(
58
+ (
59
+ b
60
+ for b in client.broker.all(page_size=100)
61
+ if b.name == name and b.org_id == org_id
62
+ ),
63
+ None,
64
+ )
65
+ if existing is None:
53
66
  body = BrokerCreating(
54
67
  name=name,
55
68
  org_id=org_id,
@@ -62,14 +75,14 @@ def register(
62
75
  broker = client.broker.create(body)
63
76
  else:
64
77
  update_body = BrokerUpdating(
65
- id=broker.id,
78
+ id=existing.id,
66
79
  name=name,
67
80
  address=domain,
68
81
  cloud_provider=cloud_provider,
69
82
  state="creating",
70
83
  cloud={},
71
84
  )
72
- _ = client.broker.update(update_body)
85
+ broker = client.broker.update(update_body)
73
86
  creds = client.broker.credentials(broker_id=broker.id)
74
87
  creds_data = {
75
88
  "broker_id": str(creds.broker_id),
@@ -81,9 +94,27 @@ def register(
81
94
  }
82
95
  creds_path = Path("cluster-creds.json")
83
96
  srsly.write_json(creds_path, creds_data)
97
+ # Persist the broker id locally so subsequent `ellf` commands resolve the
98
+ # cluster identity from saved-defaults instead of looking it up by address
99
+ # (which is brittle when the user later sets `broker_host` to a tunnel URL
100
+ # like `https://localhost:8443` that doesn't match the registered domain).
101
+ settings = get_saved_settings()
102
+ prior_broker_id = settings.broker_id
103
+ settings.broker_id = broker.id
104
+ settings.save(get_root_cfg().saved_settings_path)
105
+ # Any cached broker access token from a previous broker_id is now stale.
106
+ # The cache is keyed by broker_host; if the broker behind that host has
107
+ # changed identity (re-registered cluster, name reused, tear-down + redeploy),
108
+ # the cached token will be rejected with 401 by the new broker.
109
+ if prior_broker_id is not None and prior_broker_id != broker.id:
110
+ secrets = auth.secrets
111
+ secrets.broker_tokens.clear()
112
+ secrets.save(get_root_cfg().secrets_path)
113
+ msg.info(" Cleared stale broker token cache (broker_id changed)")
84
114
  if as_json:
85
115
  print(json.dumps(creds_data, indent=2))
86
116
  else:
87
- msg.good("Cluster registered with PAM")
117
+ action = "updated existing" if existing else "registered new"
118
+ msg.good(f"Cluster {action} with PAM")
88
119
  msg.info(f" Broker ID: {creds.broker_id}")
89
120
  msg.info(f" Wrote credentials to {creds_path}")
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "prog": "ellf",
3
3
  "help": "Ellf Command Line Interface.",
4
- "version": "4.0.25",
4
+ "version": "4.0.27",
5
5
  "extra_key": "_extra",
6
6
  "commands": {
7
7
  "actions": {
@@ -31,13 +31,22 @@ class URL:
31
31
  'http://broker.internal:8080'
32
32
  """
33
33
 
34
- __slots__ = ("url", "netloc", "port", "scheme")
35
-
36
- def __init__(self, *, url: str, netloc: str, port: int, scheme: str) -> None:
34
+ __slots__ = ("url", "netloc", "port", "scheme", "hostname")
35
+
36
+ def __init__(
37
+ self,
38
+ *,
39
+ url: str,
40
+ netloc: str,
41
+ port: int,
42
+ scheme: str,
43
+ hostname: str,
44
+ ) -> None:
37
45
  object.__setattr__(self, "url", url)
38
46
  object.__setattr__(self, "netloc", netloc)
39
47
  object.__setattr__(self, "port", port)
40
48
  object.__setattr__(self, "scheme", scheme)
49
+ object.__setattr__(self, "hostname", hostname)
41
50
 
42
51
  def __setattr__(self, name: str, value: Any) -> None:
43
52
  raise AttributeError("URL instances are immutable")
@@ -48,20 +57,22 @@ class URL:
48
57
  def __eq__(self, other: object) -> bool:
49
58
  if not isinstance(other, URL):
50
59
  return NotImplemented
51
- return (self.url, self.netloc, self.port, self.scheme) == (
60
+ return (self.url, self.netloc, self.port, self.scheme, self.hostname) == (
52
61
  other.url,
53
62
  other.netloc,
54
63
  other.port,
55
64
  other.scheme,
65
+ other.hostname,
56
66
  )
57
67
 
58
68
  def __hash__(self) -> int:
59
- return hash((self.url, self.netloc, self.port, self.scheme))
69
+ return hash((self.url, self.netloc, self.port, self.scheme, self.hostname))
60
70
 
61
71
  def __repr__(self) -> str:
62
72
  return (
63
73
  f"URL(url={self.url!r}, netloc={self.netloc!r},"
64
- f" port={self.port!r}, scheme={self.scheme!r})"
74
+ f" port={self.port!r}, scheme={self.scheme!r},"
75
+ f" hostname={self.hostname!r})"
65
76
  )
66
77
 
67
78
  @classmethod
@@ -128,6 +139,7 @@ class URL:
128
139
  netloc=parsed.netloc,
129
140
  port=resolved_port,
130
141
  scheme=parsed.scheme,
142
+ hostname=parsed.hostname or "",
131
143
  )
132
144
 
133
145
  @classmethod
@@ -151,6 +163,7 @@ class URL:
151
163
  netloc=self.netloc,
152
164
  port=self.port,
153
165
  scheme=self.scheme,
166
+ hostname=self.hostname,
154
167
  )
155
168
 
156
169
  def with_userinfo(self, username: str, password: str = "") -> URL:
@@ -164,4 +177,10 @@ class URL:
164
177
  if parsed.port:
165
178
  netloc = f"{netloc}:{parsed.port}"
166
179
  new_url = parsed._replace(netloc=netloc).geturl()
167
- return URL(url=new_url, netloc=self.netloc, port=self.port, scheme=self.scheme)
180
+ return URL(
181
+ url=new_url,
182
+ netloc=self.netloc,
183
+ port=self.port,
184
+ scheme=self.scheme,
185
+ hostname=self.hostname,
186
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ellf-cli
3
- Version: 4.0.26
3
+ Version: 4.0.28
4
4
  Summary: Ellf Command Line Interface
5
5
  Home-page: https://prodi.gy
6
6
  Author: ExplosionAI GmbH
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
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
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes