ellf-cli 10.0.0__tar.gz → 10.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 (185) hide show
  1. {ellf_cli-10.0.0/ellf_cli.egg-info → ellf_cli-10.0.2}/PKG-INFO +1 -1
  2. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/about.json +1 -1
  3. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/actions.py +16 -2
  4. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/agents.py +14 -2
  5. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/general.py +13 -4
  6. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/services.py +16 -2
  7. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/tasks.py +14 -2
  8. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-annotate.coding/SKILL.md +8 -0
  9. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-monitor.coding/SKILL.md +8 -0
  10. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-ops.coding/SKILL.md +8 -0
  11. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/SKILL.md +15 -3
  12. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-project.coding/SKILL.md +12 -1
  13. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-support.coding/SKILL.md +10 -2
  14. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-train.coding/SKILL.md +12 -1
  15. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/errors.py +10 -0
  16. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/messages.py +1 -0
  17. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/query.py +3 -3
  18. {ellf_cli-10.0.0 → ellf_cli-10.0.2/ellf_cli.egg-info}/PKG-INFO +1 -1
  19. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/tests/test_login.py +58 -0
  20. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/LICENSE +0 -0
  21. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/MANIFEST.in +0 -0
  22. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/README.md +0 -0
  23. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/__init__.py +0 -0
  24. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/__main__.py +0 -0
  25. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/about.py +0 -0
  26. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/appdirs.py +0 -0
  27. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/auth.py +0 -0
  28. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/cli.py +0 -0
  29. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/cloud/__init__.py +0 -0
  30. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/cloud/gcp.py +0 -0
  31. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/cluster_config.py +0 -0
  32. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/__init__.py +0 -0
  33. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/_cluster_select.py +0 -0
  34. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/_org_select.py +0 -0
  35. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/_recipe_file.py +0 -0
  36. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/_recipe_subcommand.py +0 -0
  37. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/_state.py +0 -0
  38. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/assets.py +0 -0
  39. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/auth.py +0 -0
  40. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/clusters.py +0 -0
  41. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/config.py +0 -0
  42. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/datasets.py +0 -0
  43. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/files/__init__.py +0 -0
  44. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/files/cp.py +0 -0
  45. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/files/ls.py +0 -0
  46. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/files/rm.py +0 -0
  47. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/files/rsync.py +0 -0
  48. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/files/stats.py +0 -0
  49. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/import_export.py +0 -0
  50. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/infra/__init__.py +0 -0
  51. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/infra/_helpers.py +0 -0
  52. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/infra/deploy.py +0 -0
  53. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/infra/init_values.py +0 -0
  54. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/infra/provision.py +0 -0
  55. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/infra/register.py +0 -0
  56. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/infra/setup.py +0 -0
  57. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/infra/start.py +0 -0
  58. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/infra/terraform.py +0 -0
  59. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/infra/tls.py +0 -0
  60. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/jobs.py +0 -0
  61. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/packages.py +0 -0
  62. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/paths.py +0 -0
  63. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/plans.py +0 -0
  64. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/projects.py +0 -0
  65. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/publish_code.py +0 -0
  66. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/publish_data.py +0 -0
  67. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/recipes.py +0 -0
  68. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/secrets.py +0 -0
  69. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/support.py +0 -0
  70. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/commands/todos.py +0 -0
  71. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/config.py +0 -0
  72. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf.json +0 -0
  73. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/.claude-plugin/plugin.json +0 -0
  74. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/.gitignore +0 -0
  75. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skill_variants.json +0 -0
  76. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-annotate.assistant/SKILL.md +0 -0
  77. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-annotate.assistant/references/annotation_audit.md +0 -0
  78. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-annotate.assistant/references/builtin_ellf_annotation_recipes.md +0 -0
  79. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-annotate.coding/references/annotation_audit.md +0 -0
  80. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-annotate.coding/references/builtin_ellf_annotation_recipes.md +0 -0
  81. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-annotate.coding/references/builtin_prodigy_recipes.md +0 -0
  82. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-ask/SKILL.md +0 -0
  83. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-handoff/SKILL.md +0 -0
  84. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-monitor.assistant/SKILL.md +0 -0
  85. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-monitor.assistant/references/annotation_metrics.md +0 -0
  86. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-monitor.assistant/references/training_monitoring.md +0 -0
  87. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-monitor.coding/references/annotation_metrics.md +0 -0
  88. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-monitor.coding/references/training_monitoring.md +0 -0
  89. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-monitor.coding/scripts/check_training.py +0 -0
  90. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-ops.assistant/SKILL.md +0 -0
  91. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-ops.coding/references/data_infra_cli.md +0 -0
  92. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-ops.coding/scripts/run_job.py +0 -0
  93. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-patterns/SKILL.md +0 -0
  94. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-patterns/references/pattern_strategies.md +0 -0
  95. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_action_recipe.py +0 -0
  96. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_agent_recipe.py +0 -0
  97. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_blocks_ui.py +0 -0
  98. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_correct.py +0 -0
  99. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_custom_ui.py +0 -0
  100. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_manual.py +0 -0
  101. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_pages_ui.py +0 -0
  102. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_routing.py +0 -0
  103. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_task_recipe.py +0 -0
  104. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_teach.py +0 -0
  105. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/builtin_recipes.md +0 -0
  106. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/ellf_recipe_sdk.md +0 -0
  107. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/lint_recipe.py +0 -0
  108. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/prodigy_recipe_api.md +0 -0
  109. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/template_index.md +0 -0
  110. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-project.assistant/SKILL.md +0 -0
  111. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-project.assistant/references/consulting_patterns.md +0 -0
  112. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-project.assistant/references/explosion_strategy.md +0 -0
  113. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-project.assistant/references/prodigy_llm_bot.md +0 -0
  114. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-project.coding/references/consulting_patterns.md +0 -0
  115. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-project.coding/references/explosion_strategy.md +0 -0
  116. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-project.coding/references/prodigy_llm_bot.md +0 -0
  117. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-support.assistant/SKILL.md +0 -0
  118. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-todo/SKILL.md +0 -0
  119. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-train.assistant/SKILL.md +0 -0
  120. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-train.assistant/references/diagnostics.md +0 -0
  121. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-train.assistant/references/evaluation_guide.md +0 -0
  122. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-train.assistant/references/model_selection.md +0 -0
  123. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-train.assistant/references/training_paradigms.md +0 -0
  124. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-train.assistant/references/workflow.md +0 -0
  125. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/config_advanced.md +0 -0
  126. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/config_architectures.md +0 -0
  127. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/config_training.md +0 -0
  128. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/diagnostics.md +0 -0
  129. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/evaluation_guide.md +0 -0
  130. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/experiment_patterns.md +0 -0
  131. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/model_selection.md +0 -0
  132. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/training_paradigms.md +0 -0
  133. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/training_troubleshooting.md +0 -0
  134. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-train.coding/references/workflow.md +0 -0
  135. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ellf_skills/skills/ellf-train.coding/scripts/ellf_logger.py +0 -0
  136. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/helm.py +0 -0
  137. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/key_pair.py +0 -0
  138. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/main.py +0 -0
  139. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/recipes_cookiecutter/cookiecutter.json +0 -0
  140. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/.gitignore +0 -0
  141. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/README.md.tmpl +0 -0
  142. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/requirements-dev.in +0 -0
  143. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/requirements.in +0 -0
  144. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/setup.py.tmpl +0 -0
  145. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/{{cookiecutter.package_name}}/__init__.py +0 -0
  146. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/{{cookiecutter.package_name}}/about.py +0 -0
  147. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/{{cookiecutter.package_name}}/recipes/__init__.py +0 -0
  148. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/{{cookiecutter.package_name}}/recipes/example_task.py +0 -0
  149. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/testing/__init__.py +0 -0
  150. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ty.py +0 -0
  151. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/ui.py +0 -0
  152. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/url.py +0 -0
  153. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli/util.py +0 -0
  154. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli.egg-info/SOURCES.txt +0 -0
  155. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli.egg-info/dependency_links.txt +0 -0
  156. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli.egg-info/entry_points.txt +0 -0
  157. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli.egg-info/not-zip-safe +0 -0
  158. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli.egg-info/requires.txt +0 -0
  159. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/ellf_cli.egg-info/top_level.txt +0 -0
  160. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/pyproject.toml +0 -0
  161. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/setup.cfg +0 -0
  162. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/setup.py +0 -0
  163. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/tests/test_appdirs.py +0 -0
  164. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/tests/test_auth.py +0 -0
  165. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/tests/test_config.py +0 -0
  166. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/tests/test_errors.py +0 -0
  167. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/tests/test_files_cp.py +0 -0
  168. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/tests/test_files_cp_helpers.py +0 -0
  169. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/tests/test_info.py +0 -0
  170. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/tests/test_invalid_secrets.py +0 -0
  171. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/tests/test_key_pair.py +0 -0
  172. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/tests/test_logout.py +0 -0
  173. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/tests/test_main.py +0 -0
  174. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/tests/test_org_select.py +0 -0
  175. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/tests/test_plans.py +0 -0
  176. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/tests/test_projects.py +0 -0
  177. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/tests/test_query.py +0 -0
  178. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/tests/test_recipe_file.py +0 -0
  179. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/tests/test_recipes.py +0 -0
  180. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/tests/test_state.py +0 -0
  181. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/tests/test_support.py +0 -0
  182. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/tests/test_ty.py +0 -0
  183. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/tests/test_ui.py +0 -0
  184. {ellf_cli-10.0.0 → ellf_cli-10.0.2}/tests/test_ui_extras.py +0 -0
  185. {ellf_cli-10.0.0 → ellf_cli-10.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: 10.0.0
3
+ Version: 10.0.2
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": "10.0.0",
4
+ "version": "10.0.2",
5
5
  "summary": "Ellf Command Line Interface",
6
6
  "uri": "https://prodi.gy",
7
7
  "prog": "ellf",
@@ -9,7 +9,13 @@ from wasabi import msg
9
9
  from ellf_pam_sdk.models import ActionDetail, ActionSummary
10
10
 
11
11
  from ..cli import cli
12
- from ..errors import BrokerError, CLIError, EllfError, HTTPXErrors
12
+ from ..errors import (
13
+ BrokerError,
14
+ CLIError,
15
+ EllfError,
16
+ HTTPXErrors,
17
+ JobStartRejectedError,
18
+ )
13
19
  from ..messages import Messages
14
20
  from ..query import delete_job, resolve_action, resolve_recipe, start_job, stop_job
15
21
  from ..ui import (
@@ -108,9 +114,17 @@ def create(
108
114
  if not no_start:
109
115
  try:
110
116
  start(action_id, no_wait=no_wait, as_json=as_json)
111
- except Exception:
117
+ except JobStartRejectedError:
118
+ # The broker rejected the start, so no workload exists and the
119
+ # PAM record can be safely rolled back.
112
120
  auth.client.action.delete(id=action_id)
113
121
  raise
122
+ except Exception:
123
+ # The job may have been submitted, so keep the record.
124
+ msg.warn(
125
+ Messages.E060.format(noun="action", name=action_id, plural="actions")
126
+ )
127
+ raise
114
128
  return action_id
115
129
 
116
130
 
@@ -9,7 +9,13 @@ from wasabi import msg
9
9
  from ellf_pam_sdk.models import AgentDetail, AgentSummary
10
10
 
11
11
  from ..cli import cli
12
- from ..errors import BrokerError, CLIError, EllfError, HTTPXErrors
12
+ from ..errors import (
13
+ BrokerError,
14
+ CLIError,
15
+ EllfError,
16
+ HTTPXErrors,
17
+ JobStartRejectedError,
18
+ )
13
19
  from ..messages import Messages
14
20
  from ..query import (
15
21
  delete_job,
@@ -115,9 +121,15 @@ def create(
115
121
  if not no_start:
116
122
  try:
117
123
  start(agent_id, no_wait=no_wait, as_json=as_json)
118
- except Exception:
124
+ except JobStartRejectedError:
125
+ # The broker rejected the start, so no workload exists and the
126
+ # PAM record can be safely rolled back.
119
127
  auth.client.agent.delete(id=agent_id)
120
128
  raise
129
+ except Exception:
130
+ # The job may have been submitted, so keep the record.
131
+ msg.warn(Messages.E060.format(noun="agent", name=agent_id, plural="agents"))
132
+ raise
121
133
  return agent_id
122
134
 
123
135
 
@@ -128,11 +128,23 @@ def login(
128
128
  # below run against the chosen org's api_token, not whatever org
129
129
  # the device-flow login happened to land in.
130
130
  _select_and_persist_org(auth, org)
131
+ if claude:
132
+ # Claude setup needs only the packaged skill assets and the
133
+ # ellf-core token minted by the device flow above — not the
134
+ # cluster. Run it before cluster selection so cluster failures
135
+ # (token mint errors, unreachable broker, no cluster registered)
136
+ # can't block skill installation.
137
+ _install_claude_skills()
138
+ _configure_claude_mcp(auth)
131
139
  if not no_cluster:
132
140
  try:
133
141
  _select_and_persist_cluster(auth, cluster)
134
142
  auth.get_cluster_token(force_refresh=True)
135
- except EllfError as e:
143
+ except (EllfError, CLIError, httpx.HTTPError) as e:
144
+ # httpx transport errors (broker unreachable) and CLIError
145
+ # (no cluster registered, --cluster not matched) are just as
146
+ # common as EllfError token failures; all of them should get
147
+ # the --no-cluster hint instead of a raw traceback.
136
148
  err = Messages.E116.format(command=f"{cli.prog} login --no-cluster")
137
149
  raise CLIError(err, e)
138
150
  print_mutation_result(
@@ -140,9 +152,6 @@ def login(
140
152
  Messages.T012,
141
153
  as_json=as_json,
142
154
  )
143
- if claude:
144
- _install_claude_skills()
145
- _configure_claude_mcp(auth)
146
155
 
147
156
 
148
157
  @cli.command(
@@ -9,7 +9,13 @@ from wasabi import msg
9
9
  from ellf_pam_sdk.models import ServiceDetail, ServiceSummary
10
10
 
11
11
  from ..cli import cli
12
- from ..errors import BrokerError, CLIError, EllfError, HTTPXErrors
12
+ from ..errors import (
13
+ BrokerError,
14
+ CLIError,
15
+ EllfError,
16
+ HTTPXErrors,
17
+ JobStartRejectedError,
18
+ )
13
19
  from ..messages import Messages
14
20
  from ..query import (
15
21
  delete_job,
@@ -114,9 +120,17 @@ def create(
114
120
  if not no_start:
115
121
  try:
116
122
  start(service_id, no_wait=no_wait, as_json=as_json)
117
- except Exception:
123
+ except JobStartRejectedError:
124
+ # The broker rejected the start, so no workload exists and the
125
+ # PAM record can be safely rolled back.
118
126
  auth.client.service.delete(id=service_id)
119
127
  raise
128
+ except Exception:
129
+ # The job may have been submitted, so keep the record.
130
+ msg.warn(
131
+ Messages.E060.format(noun="service", name=service_id, plural="services")
132
+ )
133
+ raise
120
134
  return service_id
121
135
 
122
136
 
@@ -11,7 +11,13 @@ from wasabi import msg
11
11
  from ellf_pam_sdk.models import TaskDetail, TaskSummary
12
12
 
13
13
  from ..cli import cli
14
- from ..errors import BrokerError, CLIError, EllfError, HTTPXErrors
14
+ from ..errors import (
15
+ BrokerError,
16
+ CLIError,
17
+ EllfError,
18
+ HTTPXErrors,
19
+ JobStartRejectedError,
20
+ )
15
21
  from ..messages import Messages
16
22
  from ..query import delete_job, resolve_recipe, resolve_task, start_job, stop_job
17
23
  from ..ui import (
@@ -116,9 +122,15 @@ def create(
116
122
  if not no_start:
117
123
  try:
118
124
  start(task_id, no_wait=no_wait, as_json=as_json)
119
- except Exception:
125
+ except JobStartRejectedError:
126
+ # The broker rejected the start, so no workload exists and the
127
+ # PAM record can be safely rolled back.
120
128
  auth.client.task.delete(id=task_id)
121
129
  raise
130
+ except Exception:
131
+ # The job may have been submitted, so keep the record.
132
+ msg.warn(Messages.E060.format(noun="task", name=task_id, plural="tasks"))
133
+ raise
122
134
  return task_id
123
135
 
124
136
 
@@ -2,6 +2,7 @@
2
2
  name: ellf-annotate
3
3
  description: "Set up and launch annotation from the coding environment once the methodology, schema, and data are ready. Use when the user wants to start annotation on the Ellf cluster, run a local Prodigy annotation server, choose between built-in Ellf and built-in Prodigy recipes, verify that annotation is ready to launch, preview the annotation setup, or determine whether a new custom recipe is needed. Also trigger on \"I want to annotate\", \"start a local Prodigy server\", \"launch annotation on the cluster\", \"which recipe should I use\", \"can I run this locally\", \"set up review\", or \"help me run annotation\". This skill is the annotation readiness gatekeeper: it applies the audit checklist before launch, prefers built-in workflows when possible, and delegates to `/ellf-prodigy` when a new custom recipe must be implemented."
4
4
  argument-hint: "[describe what you want to annotate]"
5
+ allowed-tools: Bash(ellf info defaults:*)
5
6
  ---
6
7
 
7
8
  # Launch Annotation From Coding
@@ -10,6 +11,13 @@ Help the user get from an annotation-ready plan to a working annotation process.
10
11
 
11
12
  $ARGUMENTS
12
13
 
14
+ ## Current Ellf session context
15
+
16
+ The block below is auto-filled from your local Ellf CLI each time this skill loads. Read it instead of trying to discover the project, cluster, or task yourself. There is **no** `ellf project current` / `ellf projects current` command — these saved defaults are what such a command would return, and most `ellf` commands fall back to them automatically. To change one, run `ellf config <project|task|action|agent|...> <name_or_id>`.
17
+
18
+ Saved CLI defaults:
19
+ !`ellf info defaults`
20
+
13
21
  ## Your role
14
22
 
15
23
  You are responsible for:
@@ -2,6 +2,7 @@
2
2
  name: ellf-monitor
3
3
  description: "Monitors Ellf jobs, local Prodigy servers, training progress, and cluster health — keeps raw logs out of context and produces structured summaries. Includes a structured training check script, alert classification (overfitting, plateau, NaN loss, spikes), annotation metrics, and diagnostic routing. Use proactively after launching any job, not just when the user asks. Also trigger on status checks, log inspection, 'how's the task doing', 'what failed', or training metric questions."
4
4
  argument-hint: "[job name, job type, output dir, or 'cluster']"
5
+ allowed-tools: Bash(ellf info defaults:*)
5
6
  ---
6
7
 
7
8
  # Monitor Jobs From Coding
@@ -10,6 +11,13 @@ You are the monitoring and diagnosis skill for the coding environment.
10
11
 
11
12
  $ARGUMENTS
12
13
 
14
+ ## Current Ellf session context
15
+
16
+ The block below is auto-filled from your local Ellf CLI each time this skill loads. Read it instead of trying to discover the project, cluster, or task yourself. There is **no** `ellf project current` / `ellf projects current` command — these saved defaults are what such a command would return, and most `ellf` commands fall back to them automatically. To change one, run `ellf config <project|task|action|agent|...> <name_or_id>`.
17
+
18
+ Saved CLI defaults:
19
+ !`ellf info defaults`
20
+
13
21
  ## Contents
14
22
  - Scope — what this skill does and doesn't do
15
23
  - Monitoring surfaces — cluster jobs, local runs, Prodigy servers, cluster health
@@ -2,6 +2,7 @@
2
2
  name: ellf-ops
3
3
  description: "Executes Ellf operations from the coding environment: creating, starting, stopping, or inspecting tasks, actions, or agents; managing assets, datasets, files, secrets, or packages; publishing data or code; managing projects, path aliases, or cluster health. Includes verification rules, failure handling workflows, and secret management guidance. Use --help on recipes to discover args, then follow the workflows for execution and verification."
4
4
  argument-hint: "[ready launch spec or job operation]"
5
+ allowed-tools: Bash(ellf info defaults:*)
5
6
  ---
6
7
 
7
8
  # Execute Operations From Coding
@@ -10,6 +11,13 @@ You are the execution skill for operational workflows in the coding environment.
10
11
 
11
12
  $ARGUMENTS
12
13
 
14
+ ## Current Ellf session context
15
+
16
+ The block below is auto-filled from your local Ellf CLI each time this skill loads. Read it instead of trying to discover the project, cluster, task, action, or agent yourself. There is **no** `ellf project current` / `ellf projects current` command — these saved defaults are what such a command would return, and most `ellf` commands fall back to them automatically. To change one, run `ellf config <project|task|action|agent|...> <name_or_id>`.
17
+
18
+ Saved CLI defaults:
19
+ !`ellf info defaults`
20
+
13
21
  ## Scope
14
22
 
15
23
  You execute ready operations. You do not:
@@ -2,6 +2,7 @@
2
2
  name: ellf-prodigy
3
3
  description: Develop and test custom Prodigy annotation recipes — both standalone Prodigy and Ellf. Has templates, API reference, built-in recipe catalog, and a lint script. Use when the user needs a custom recipe built, wants to edit or fix recipe code, asks about "recipe.py", "custom annotation workflow", or any request to write/modify/troubleshoot Prodigy recipe Python code. Also trigger for porting standalone recipes to Ellf or vice versa.
4
4
  argument-hint: "[describe your annotation task or recipe to edit]"
5
+ allowed-tools: Bash(ellf info defaults:*), Bash(ellf plans list:*)
5
6
  ---
6
7
 
7
8
  # Prodigy Recipe Developer
@@ -10,6 +11,16 @@ You develop and test custom Prodigy annotation recipes.
10
11
 
11
12
  $ARGUMENTS
12
13
 
14
+ ## Current Ellf session context
15
+
16
+ The block below is auto-filled from your local Ellf CLI each time this skill loads. Read it instead of trying to discover the project or other defaults yourself. There is **no** `ellf project current` / `ellf projects current` command — these saved defaults are what such a command would return, and most `ellf` commands fall back to them automatically. To change one, run `ellf config <project|task|action|agent|...> <name_or_id>`.
17
+
18
+ Saved CLI defaults:
19
+ !`ellf info defaults`
20
+
21
+ Plans in the saved project (`ellf plans list` and the other `ellf plans` commands default to it):
22
+ !`ellf plans list`
23
+
13
24
  ## Setup
14
25
 
15
26
  This is a coding-only skill. Work from the local coding environment and current
@@ -36,9 +47,10 @@ current codebase, and existing recipe package structure.
36
47
  every task needs a custom recipe. If they still want custom, understand what
37
48
  the built-in is missing.
38
49
 
39
- 2. **Check the shared project plan** using the current local project context.
40
- Extract task type, labels, data source, runtime target, and any recipe
41
- recommendations already agreed elsewhere.
50
+ 2. **Check the shared project plan.** The injected "Current Ellf session context"
51
+ above lists the plans in the saved project read the relevant one with
52
+ `ellf plans read` (it defaults to the saved project). Extract task type, labels,
53
+ data source, runtime target, and any recipe recommendations already agreed elsewhere.
42
54
 
43
55
  3. **Gather requirements** you don't already have: annotation task type, labels,
44
56
  data source, model assistance (manual / model-correct / active learning /
@@ -2,6 +2,7 @@
2
2
  name: ellf-project
3
3
  description: Plan an NLP project end-to-end with an opinionated consultant. Covers problem framing, data strategy, annotation, pipeline design, evaluation, and deployment planning, grounded in spaCy, Prodigy, Ellf workflows and applied NLP best practices. Use whenever the user asks how to approach an NLP task, needs help deciding between rules, ML, and LLMs, wants advice on label scheme design, needs pipeline architecture guidance, asks how to break a vague NLP problem into concrete steps, or says things like "how should I build this", "what's the best approach for", "help me plan", "I need to extract/classify/annotate", "how do I structure this project", or "what should I do next". Also trigger when the user seems unsure about their NLP approach, has a vague requirement that needs scoping, or needs a shared project plan created or updated.
4
4
  argument-hint: "[describe your NLP problem]"
5
+ allowed-tools: Bash(ellf info defaults:*), Bash(ellf plans list:*)
5
6
  ---
6
7
 
7
8
  # NLP Project Consultant
@@ -13,6 +14,16 @@ You do not dump generic questionnaires. You listen, react, recommend, and ask th
13
14
 
14
15
  $ARGUMENTS
15
16
 
17
+ ## Current Ellf session context
18
+
19
+ The block below is auto-filled from your local Ellf CLI each time this skill loads. Read it instead of trying to discover the project or other defaults yourself. There is **no** `ellf project current` / `ellf projects current` command — these saved defaults are what such a command would return, and most `ellf` commands fall back to them automatically. To change one, run `ellf config <project|task|action|agent|...> <name_or_id>`.
20
+
21
+ Saved CLI defaults:
22
+ !`ellf info defaults`
23
+
24
+ Plans in the saved project (`ellf plans list` and the other `ellf plans` commands default to it):
25
+ !`ellf plans list`
26
+
16
27
  ## Contents
17
28
  - Your role — planning, not implementation
18
29
  - Shared project plan — local CLI plan access and lifecycle
@@ -65,7 +76,7 @@ In the coding environment, use the local `ellf plans` workflow. `<project_id>` i
65
76
  - `ellf plans revisions <name_or_id> [<project_id>] [--size N] [--after <cursor>]` — paginated history of one plan, newest first. `name_or_id` is required here (no default).
66
77
  - `ellf plans delete <name_or_id> [<project_id>]` — delete a plan by name or UUID.
67
78
 
68
- If you need to resolve the current project ID first, use the local project context before reading or writing plans. Do not guess the project ID.
79
+ The `ellf plans` commands already default to the saved project when `<project_id>` is omitted, so you usually don't need to resolve it. If you do need the current project ID explicitly, read it from `ellf info defaults` (the `project` field). Do not guess the project ID, and note there is no `ellf project`/`ellf projects current` command — use `ellf info defaults` to read the saved default and `ellf config project <name_or_id>` to change it.
69
80
 
70
81
  Do not ask the user where to store the plan.
71
82
 
@@ -2,6 +2,7 @@
2
2
  name: ellf-support
3
3
  description: Prepare and send a support request from the coding environment when the user wants human help from the Ellf team. Use when the user wants to escalate an issue, asks for human review, wants to contact support, or says things like "I need support", "can someone look at this", "send this to the Ellf team", or "I'm stuck". This skill gathers the issue, summarizes the current state, asks whether to attach the full Claude Code transcript, and sends the request with `ellf support create`.
4
4
  argument-hint: "[describe your issue]"
5
+ allowed-tools: Bash(ellf info defaults:*)
5
6
  ---
6
7
 
7
8
  # Human Support From Coding
@@ -10,6 +11,13 @@ Help the user escalate to human support cleanly and accurately.
10
11
 
11
12
  $ARGUMENTS
12
13
 
14
+ ## Current Ellf session context
15
+
16
+ The block below is auto-filled from your local Ellf CLI each time this skill loads. Use the saved `project` here as the default target for the support request — do not try to discover it with `ellf project current` / `ellf projects current` (no such command). If the saved project looks wrong or stale for this request, fall back to `ellf projects list --json` and confirm with the user (see "Resolve the target project" below).
17
+
18
+ Saved CLI defaults:
19
+ !`ellf info defaults`
20
+
13
21
  ## Scope
14
22
 
15
23
  You are not implementing a fix here. Your job is to:
@@ -57,8 +65,8 @@ Use the current conversation first.
57
65
 
58
66
  Resolve the target project before you submit the request.
59
67
 
60
- - If the current project is explicit from local project context or prior confirmed
61
- state, use it.
68
+ - If the current project is explicit (the saved `project` in the injected session
69
+ context above, or prior confirmed state), use it.
62
70
  - If there is any ambiguity about which project the support request belongs to,
63
71
  use `ellf projects list --json` to gather candidates, then use `AskUserQuestion`
64
72
  to confirm the project with the user before running `ellf support create`.
@@ -2,6 +2,7 @@
2
2
  name: ellf-train
3
3
  description: "Trains spaCy models locally or on the Ellf cluster — from config generation and experiment design through training execution to result interpretation and troubleshooting. Covers architecture selection, model selection, training diagnostics, and evaluation methodology. Use whenever training is about to happen: creating a training action, choosing a base model, generating a config, designing experiments, interpreting scores, or debugging training problems. Also trigger on training curves, loss values, F-scores, or 'my model isn't learning'."
4
4
  argument-hint: "[describe what you want to train, or provide a dataset name]"
5
+ allowed-tools: Bash(ellf info defaults:*), Bash(ellf plans list:*)
5
6
  ---
6
7
 
7
8
  # NLP Model Training
@@ -10,11 +11,21 @@ You help users go from annotated data to a trained spaCy model — locally or on
10
11
 
11
12
  $ARGUMENTS
12
13
 
14
+ ## Current Ellf session context
15
+
16
+ The block below is auto-filled from your local Ellf CLI each time this skill loads. Read it instead of trying to discover the project or other defaults yourself. There is **no** `ellf project current` / `ellf projects current` command — these saved defaults are what such a command would return, and most `ellf` commands fall back to them automatically. To change one, run `ellf config <project|task|action|agent|...> <name_or_id>`.
17
+
18
+ Saved CLI defaults:
19
+ !`ellf info defaults`
20
+
21
+ Plans in the saved project (`ellf plans list` and the other `ellf plans` commands default to it):
22
+ !`ellf plans list`
23
+
13
24
  ## Setup
14
25
 
15
26
  1. **Read `${CLAUDE_SKILL_DIR}/references/workflow.md`** — this is your decision flowchart. It tells you where you are in the training process and what to do next. Read it on every invocation.
16
27
 
17
- 2. **Check for a shared project plan** using the current project context. Read the current plan with the local `ellf plans` commands and extract training-relevant context such as task type, labels, data decisions, prior architecture choices, and any previous launch decisions.
28
+ 2. **Check for a shared project plan.** The injected "Current Ellf session context" above already lists the plans in the saved project — pick the relevant one and read it with `ellf plans read` (it defaults to the saved project, so you don't resolve a project ID first). Extract training-relevant context such as task type, labels, data decisions, prior architecture choices, and any previous launch decisions.
18
29
 
19
30
  3. **Check for `training_history.md`** in the working directory. If found, the Current Status section tells you where things stand. Resume from there.
20
31
 
@@ -61,6 +61,16 @@ class CLIError(Exception):
61
61
  super().__init__(self.message)
62
62
 
63
63
 
64
+ class JobStartRejectedError(CLIError):
65
+ """The broker rejected a job start outright, so no workload was created.
66
+
67
+ Raised only when the broker's start response reports a cluster or
68
+ validation error. Other start failures (e.g. status polling after the
69
+ job was submitted) must not use this class: the workload may be running,
70
+ so it is not safe to roll back the PAM record.
71
+ """
72
+
73
+
64
74
  class EllfParseSecretsError(EllfError):
65
75
  def __init__(
66
76
  self, secrets_file: Path | None, error: Exception | None = None
@@ -63,6 +63,7 @@ ellf secret create my-credentials OPENAI_API_KEY="sk-..." CUSTOM_SECRET=-
63
63
  E057 = "Could not import recipes from {package}"
64
64
  E058 = "Could not get a Prodigy login token from the broker for task {name}"
65
65
  E059 = "Could not fetch questions from the task server for {name}"
66
+ E060 = "Could not confirm that {noun} {name} started. The {noun} was created and still exists: check it with `ellf {plural} info {name}` or start it with `ellf {plural} start {name}`"
66
67
 
67
68
  T001 = "Not creating {noun} {name}: {noun} already exists"
68
69
  T002 = "Successfully created {noun} {name}"
@@ -22,7 +22,7 @@ from ellf_pam_sdk.errors import ELLF_ERRORS, EllfError
22
22
 
23
23
  from .auth import AuthState
24
24
  from .commands._state import get_auth_state, get_root_cfg, get_saved_settings
25
- from .errors import CLIError, EllfErrors
25
+ from .errors import CLIError, EllfErrors, JobStartRejectedError
26
26
  from .messages import Messages
27
27
  from .ty import Page
28
28
  from .util import URL
@@ -603,10 +603,10 @@ class JobOperations:
603
603
  return
604
604
  elif change_response.cluster_error:
605
605
  err = Messages.E025.format(noun=self.job_type.value, name=job_spec.job_id)
606
- raise CLIError(err, change_response.cluster_error)
606
+ raise JobStartRejectedError(err, change_response.cluster_error)
607
607
  elif change_response.validation_error:
608
608
  err = Messages.E044.format(noun=self.job_type.value, name=job_spec.job_id)
609
- raise CLIError(err, change_response.validation_error)
609
+ raise JobStartRejectedError(err, change_response.validation_error)
610
610
  elif not quiet:
611
611
  msg.info(
612
612
  Messages.T006.format(noun=self.job_type.value, name=job_spec.job_id)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ellf-cli
3
- Version: 10.0.0
3
+ Version: 10.0.2
4
4
  Summary: Ellf Command Line Interface
5
5
  Home-page: https://prodi.gy
6
6
  Author: ExplosionAI GmbH
@@ -156,6 +156,64 @@ def test_install_claude_skills_with_packaged_plugin(tmp_path, monkeypatch):
156
156
  assert (dest / "ellf-patterns").is_dir()
157
157
 
158
158
 
159
+ def _patch_login_collaborators(monkeypatch, *, cluster_error=None):
160
+ """Patch login()'s collaborators so it can run without network access.
161
+
162
+ Returns (auth, install_mock, configure_mock). When ``cluster_error``
163
+ is given, cluster selection raises it.
164
+ """
165
+ from ellf_cli.commands import general
166
+
167
+ auth = MagicMock()
168
+ monkeypatch.setattr(general, "get_auth_state", lambda: auth)
169
+ monkeypatch.setattr(general, "_select_and_persist_org", MagicMock())
170
+ cluster_mock = MagicMock(side_effect=cluster_error)
171
+ monkeypatch.setattr(general, "_select_and_persist_cluster", cluster_mock)
172
+ install_mock = MagicMock()
173
+ configure_mock = MagicMock()
174
+ monkeypatch.setattr(general, "_install_claude_skills", install_mock)
175
+ monkeypatch.setattr(general, "_configure_claude_mcp", configure_mock)
176
+ return auth, install_mock, configure_mock
177
+
178
+
179
+ def test_login_claude_installs_skills_despite_cluster_failure(monkeypatch):
180
+ """Regression: cluster auth failure must not block Claude skill setup.
181
+
182
+ Skill install and MCP config only need the device-flow tokens, so
183
+ they run before cluster selection and survive any cluster error.
184
+ """
185
+ import pytest
186
+
187
+ from ellf_cli.commands import general
188
+ from ellf_cli.errors import CLIError, EllfError
189
+
190
+ auth, install_mock, configure_mock = _patch_login_collaborators(
191
+ monkeypatch, cluster_error=EllfError("cluster token mint failed")
192
+ )
193
+
194
+ with pytest.raises(CLIError):
195
+ general.login(claude=True)
196
+
197
+ install_mock.assert_called_once_with()
198
+ configure_mock.assert_called_once_with(auth)
199
+
200
+
201
+ def test_login_wraps_transport_and_cli_errors_with_no_cluster_hint(monkeypatch):
202
+ """Broker-unreachable (httpx) and no-cluster (CLIError) failures get the
203
+ same --no-cluster hint as EllfError instead of a raw traceback."""
204
+ import httpx
205
+ import pytest
206
+
207
+ from ellf_cli.commands import general
208
+ from ellf_cli.errors import CLIError
209
+
210
+ for error in (httpx.ConnectError("connection refused"), CLIError("no clusters")):
211
+ _patch_login_collaborators(monkeypatch, cluster_error=error)
212
+ with pytest.raises(CLIError) as exc_info:
213
+ general.login()
214
+ assert "--no-cluster" in str(exc_info.value)
215
+
216
+
159
217
  def _fake_membership(org_id, org_name="acme"):
160
218
  return SimpleNamespace(
161
219
  org_id=org_id,
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes