mainsequence 8.1.27.dev28__tar.gz → 8.1.27.dev29__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 (98) hide show
  1. {mainsequence-8.1.27.dev28/mainsequence.egg-info → mainsequence-8.1.27.dev29}/PKG-INFO +1 -1
  2. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/cli/cli.py +8 -1
  3. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29/mainsequence.egg-info}/PKG-INFO +1 -1
  4. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/pyproject.toml +1 -1
  5. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_cli_auth_contract.py +26 -0
  6. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/LICENSE +0 -0
  7. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/README.md +0 -0
  8. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/agent_scaffold/AGENTS.md +0 -0
  9. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/agent_scaffold/skills/a2a_sdk_execution/SKILL.md +0 -0
  10. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/agent_scaffold/skills/application_surfaces/api_surfaces/SKILL.md +0 -0
  11. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md +0 -0
  12. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/agent_scaffold/skills/maintenance/code_repository_maintenance/SKILL.md +0 -0
  13. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/agent_scaffold/skills/maintenance/metatables_transition/SKILL.md +0 -0
  14. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/agent_scaffold/skills/platform_operations/access_control_and_sharing/SKILL.md +0 -0
  15. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/agent_scaffold/skills/platform_operations/orchestration_and_releases/SKILL.md +0 -0
  16. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/agent_scaffold/skills/sdk_code_repository_execution/SKILL.md +0 -0
  17. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/__init__.py +0 -0
  18. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/__main__.py +0 -0
  19. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/_request_identity.py +0 -0
  20. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/bootstrap.py +0 -0
  21. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/cli/__init__.py +0 -0
  22. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/cli/api.py +0 -0
  23. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/cli/browser_auth.py +0 -0
  24. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/cli/code_repository_status.py +0 -0
  25. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/cli/config.py +0 -0
  26. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/cli/docker_utils.py +0 -0
  27. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/cli/doctor.py +0 -0
  28. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/cli/local_ops.py +0 -0
  29. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/cli/model_filters.py +0 -0
  30. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/cli/pydantic_cli.py +0 -0
  31. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/cli/sdk_utils.py +0 -0
  32. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/cli/ssh_utils.py +0 -0
  33. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/cli/ui.py +0 -0
  34. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/client/__init__.py +0 -0
  35. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/client/agent_runtime_models.py +0 -0
  36. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/client/base.py +0 -0
  37. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/client/client.py +0 -0
  38. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/client/compute_validation.py +0 -0
  39. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/client/exceptions.py +0 -0
  40. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/client/github_issues.py +0 -0
  41. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/client/models_foundry.py +0 -0
  42. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/client/models_helpers.py +0 -0
  43. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/client/models_user.py +0 -0
  44. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/client/observability.py +0 -0
  45. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/client/utils.py +0 -0
  46. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/client/value_sets.py +0 -0
  47. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/code_repository_context.py +0 -0
  48. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/code_repository_skills.py +0 -0
  49. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/defaults.py +0 -0
  50. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/instrumentation/__init__.py +0 -0
  51. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/instrumentation/utils.py +0 -0
  52. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/logconf.py +0 -0
  53. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/repository_identity_security.py +0 -0
  54. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/runtime_flags.py +0 -0
  55. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/scaffold_skills.py +0 -0
  56. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/server/__init__.py +0 -0
  57. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/server/caller_assertions.py +0 -0
  58. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence/server/fastapi.py +0 -0
  59. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence.egg-info/SOURCES.txt +0 -0
  60. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence.egg-info/dependency_links.txt +0 -0
  61. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence.egg-info/entry_points.txt +0 -0
  62. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence.egg-info/requires.txt +0 -0
  63. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/mainsequence.egg-info/top_level.txt +0 -0
  64. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/setup.cfg +0 -0
  65. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_auth_bootstrap.py +0 -0
  66. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_auth_precedence.py +0 -0
  67. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_caller_assertions.py +0 -0
  68. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_canonical_api_route_contract.py +0 -0
  69. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_cli.py +0 -0
  70. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_cli_browser_auth.py +0 -0
  71. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_cli_secure_storage.py +0 -0
  72. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_client.py +0 -0
  73. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_code_repository_branch_contract.py +0 -0
  74. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_code_repository_documentation_contract.py +0 -0
  75. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_code_repository_runtime_context.py +0 -0
  76. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_code_repository_skills.py +0 -0
  77. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_dependency_extras.py +0 -0
  78. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_dev_release_version.py +0 -0
  79. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_environment_resource_context.py +0 -0
  80. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_environment_response_contracts.py +0 -0
  81. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_fastapi_request_identity.py +0 -0
  82. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_filter_normalization.py +0 -0
  83. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_github_issues_client.py +0 -0
  84. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_independent_context.py +0 -0
  85. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_instrumentation.py +0 -0
  86. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_job_client.py +0 -0
  87. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_local_ops.py +0 -0
  88. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_logconf.py +0 -0
  89. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_models_user_request_bound_auth.py +0 -0
  90. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_notification_uid_contract.py +0 -0
  91. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_observability_client.py +0 -0
  92. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_scaffold_skills.py +0 -0
  93. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_secret_client_model.py +0 -0
  94. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_source_ownership.py +0 -0
  95. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_ssh_utils.py +0 -0
  96. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_tolerant_response_reading.py +0 -0
  97. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_tolerant_value_sets.py +0 -0
  98. {mainsequence-8.1.27.dev28 → mainsequence-8.1.27.dev29}/tests/test_user_application_facts.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 8.1.27.dev28
3
+ Version: 8.1.27.dev29
4
4
  Summary: Main Sequence SDK
5
5
  Author-email: Main Sequence GmbH <dev@main-sequence.io>
6
6
  License-Expression: MIT
@@ -44,6 +44,7 @@ from textwrap import dedent
44
44
  from typing import NoReturn
45
45
 
46
46
  import click
47
+ import requests
47
48
  import typer
48
49
  from packaging.specifiers import InvalidSpecifier, SpecifierSet
49
50
  from packaging.version import InvalidVersion, Version
@@ -713,7 +714,8 @@ def _require_login() -> dict:
713
714
  Returns:
714
715
  profile dict
715
716
 
716
- Raises typer.Exit(1) with user-friendly message on failure.
717
+ Raises typer.Exit(1) with user-friendly message on failure: a missing or
718
+ rejected session, or a backend that could not be reached.
717
719
  """
718
720
  try:
719
721
  prof = get_current_user_profile()
@@ -726,6 +728,11 @@ def _require_login() -> dict:
726
728
  except ApiError as e:
727
729
  error("Not logged in. Run: mainsequence login")
728
730
  raise typer.Exit(1) from e
731
+ except (requests.exceptions.ConnectionError, requests.exceptions.Timeout) as e:
732
+ # The backend gave no answer about the session, so this is not "Not logged in".
733
+ # Never echo the exception: a transport error can carry request details.
734
+ error(f"The backend at {cfg.backend_url()} could not be reached ({type(e).__name__}).")
735
+ raise typer.Exit(1) from e
729
736
 
730
737
 
731
738
  def _runtime_credential_mode_enabled() -> bool:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 8.1.27.dev28
3
+ Version: 8.1.27.dev29
4
4
  Summary: Main Sequence SDK
5
5
  Author-email: Main Sequence GmbH <dev@main-sequence.io>
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "mainsequence"
7
- version = "8.1.27.dev28"
7
+ version = "8.1.27.dev29"
8
8
  description = "Main Sequence SDK"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13"
@@ -5,6 +5,7 @@ from __future__ import annotations
5
5
  import json
6
6
 
7
7
  import pytest
8
+ import requests
8
9
  from typer.testing import CliRunner
9
10
 
10
11
  from mainsequence.cli import cli as cli_mod
@@ -364,6 +365,31 @@ def test_auth_status_check_asks_the_backend(monkeypatch):
364
365
  assert json.loads(refused.output)["authenticated"] is False
365
366
 
366
367
 
368
+ @pytest.mark.parametrize(
369
+ "failure", [requests.exceptions.ConnectionError, requests.exceptions.ReadTimeout]
370
+ )
371
+ def test_login_check_says_when_the_backend_could_not_be_reached(monkeypatch, failure):
372
+ def unreachable():
373
+ raise failure(
374
+ "HTTPSConnectionPool(host='backend.example', port=443): Max retries exceeded "
375
+ "with url: /api/v1/users/me/"
376
+ )
377
+
378
+ monkeypatch.setattr(cli_mod.cfg, "backend_url", lambda: "https://backend.example")
379
+ monkeypatch.setattr(cli_mod, "get_current_user_profile", unreachable)
380
+
381
+ result = runner.invoke(cli_mod.app, ["code-repository", "list"])
382
+
383
+ assert result.exit_code == 1
384
+ # The command ended itself; an exception that escapes it is what prints a traceback.
385
+ assert isinstance(result.exception, SystemExit)
386
+ assert "Traceback" not in result.output
387
+ # One line, and no "Not logged in": the backend never judged the session.
388
+ assert result.output == (
389
+ f"The backend at https://backend.example could not be reached ({failure.__name__}).\n"
390
+ )
391
+
392
+
367
393
  def _now() -> int:
368
394
  import time
369
395